diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-16 12:45:04 +0100 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-16 12:55:15 +0100 |
commit | 44f8c81efeabb4576be427e7d53e982848cb5be9 (patch) | |
tree | c11e8b1e7675bc8ea5173380816b08128e184f8e | |
parent | d01b39d1bb08687077309eb00704461c228c6a3e (diff) | |
download | ovm-44f8c81efeabb4576be427e7d53e982848cb5be9.tar.gz ovm-44f8c81efeabb4576be427e7d53e982848cb5be9.tar.bz2 ovm-44f8c81efeabb4576be427e7d53e982848cb5be9.zip |
Added opcode_as_cstr, opcode_type_as_cstr and inst_print
Pretty self explanatory, helps with logging.
-rw-r--r-- | src/inst.c | 104 | ||||
-rw-r--r-- | src/inst.h | 7 |
2 files changed, 111 insertions, 0 deletions
@@ -16,6 +16,92 @@ #include "./inst.h" +const char *opcode_as_cstr(opcode_t code) +{ + switch (code) + { + case OP_NOOP: + return "NOOP"; + break; + case OP_PUSH_BYTE: + return "PUSH_BYTE"; + break; + case OP_PUSH_WORD: + return "PUSH_WORD"; + break; + case OP_PUSH_FLOAT: + return "PUSH_FLOAT"; + break; + case OP_PUSH_BYTE_REGISTER: + return "PUSH_BYTE_REGISTER"; + break; + case OP_PUSH_WORD_REGISTER: + return "PUSH_WORD_REGISTER"; + break; + case OP_PUSH_FLOAT_REGISTER: + return "PUSH_FLOAT_REGISTER"; + break; + case OP_POP_BYTE: + return "POP_BYTE"; + break; + case OP_POP_WORD: + return "POP_WORD"; + break; + case OP_POP_FLOAT: + return "POP_FLOAT"; + break; + case OP_MOV_BYTE: + return "MOV_BYTE"; + break; + case OP_MOV_WORD: + return "MOV_WORD"; + break; + case OP_MOV_FLOAT: + return "MOV_FLOAT"; + break; + case OP_HALT: + return "HALT"; + break; + } + return ""; +} + +const char *opcode_type_as_cstr(opcode_type_t type) +{ + switch (type) + { + case OP_TYPE_PUSH: + return "TYPE_PUSH"; + case OP_TYPE_PUSH_REGISTER: + return "TYPE_PUSH_REGISTER"; + case OP_TYPE_POP: + return "TYPE_POP"; + case OP_TYPE_MOV: + return "TYPE_MOV"; + case OP_TYPE_HALT: + return "TYPE_HALT"; + } + return ""; +} + +void data_print(data_t datum, data_type_t type, FILE *fp) +{ + switch (type) + { + case DATA_TYPE_NIL: + break; + case DATA_TYPE_BYTE: + fprintf(fp, "%X", datum.as_byte); + break; + case DATA_TYPE_WORD: + fprintf(fp, "%lX", datum.as_word); + break; + case DATA_TYPE_FLOAT: + fprintf(fp, "%f", datum.as_float); + break; + } +} + data_type_t get_opcode_data_type(opcode_t opcode) { data_type_t type = DATA_TYPE_NIL; @@ -30,6 +116,24 @@ data_type_t get_opcode_data_type(opcode_t opcode) return type; } +void inst_print(inst_t instruction, FILE *fp) +{ + fprintf(fp, "(%s", opcode_as_cstr(instruction.opcode)); + if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH)) + { + data_type_t type = get_opcode_data_type(instruction.opcode); + fprintf(fp, ", datum="); + data_print(instruction.operand, type, fp); + } + else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH_REGISTER) || + OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_MOV)) + { + fprintf(fp, ", reg="); + data_print(instruction.operand, DATA_TYPE_BYTE, fp); + } + fprintf(fp, ")"); +} + size_t inst_bytecode_size(inst_t inst) { size_t size = 1; // for opcode @@ -13,6 +13,7 @@ #ifndef INST_H #define INST_H +#include <stdio.h> #include <stdlib.h> #include "./base.h" @@ -42,6 +43,8 @@ typedef enum OP_HALT = 0b10000000, // top of the byte is a HALT } opcode_t; +const char *opcode_as_cstr(opcode_t); + // Masks and values to check if an opcode is of a type typedef enum { @@ -52,6 +55,8 @@ typedef enum OP_TYPE_HALT = 0b10000000, } opcode_type_t; +const char *opcode_type_as_cstr(opcode_type_t); + #define OPCODE_IS_TYPE(OPCODE, OP_TYPE) (((OPCODE) & (OP_TYPE)) == (OP_TYPE)) typedef struct @@ -60,6 +65,8 @@ typedef struct data_t operand; } inst_t; +void inst_print(inst_t, FILE *); + size_t inst_bytecode_size(inst_t); void inst_write_bytecode(inst_t, darr_t *); // Here the dynamic array is a preloaded buffer of bytes, where |