diff options
Diffstat (limited to 'src/inst.c')
-rw-r--r-- | src/inst.c | 134 |
1 files changed, 54 insertions, 80 deletions
@@ -29,17 +29,17 @@ const char *opcode_as_cstr(opcode_t code) case OP_PUSH_WORD: return "PUSH_WORD"; break; - case OP_PUSH_FLOAT: - return "PUSH_FLOAT"; + case OP_PUSH_HWORD: + return "PUSH_HWORD"; break; - case OP_PUSH_BYTE_REGISTER: - return "PUSH_BYTE_REGISTER"; + case OP_PUSH_REGISTER_BYTE: + return "PUSH_REGISTER_BYTE"; break; - case OP_PUSH_WORD_REGISTER: - return "PUSH_WORD_REGISTER"; + case OP_PUSH_REGISTER_WORD: + return "PUSH_REGISTER_WORD"; break; - case OP_PUSH_FLOAT_REGISTER: - return "PUSH_FLOAT_REGISTER"; + case OP_PUSH_REGISTER_HWORD: + return "PUSH_REGISTER_HWORD"; break; case OP_POP_BYTE: return "POP_BYTE"; @@ -47,8 +47,8 @@ const char *opcode_as_cstr(opcode_t code) case OP_POP_WORD: return "POP_WORD"; break; - case OP_POP_FLOAT: - return "POP_FLOAT"; + case OP_POP_HWORD: + return "POP_HWORD"; break; case OP_MOV_BYTE: return "MOV_BYTE"; @@ -56,8 +56,8 @@ const char *opcode_as_cstr(opcode_t code) case OP_MOV_WORD: return "MOV_WORD"; break; - case OP_MOV_FLOAT: - return "MOV_FLOAT"; + case OP_MOV_HWORD: + return "MOV_HWORD"; break; case OP_HALT: return "HALT"; @@ -66,24 +66,6 @@ const char *opcode_as_cstr(opcode_t code) 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) @@ -93,25 +75,25 @@ void data_print(data_t datum, data_type_t type, FILE *fp) case DATA_TYPE_BYTE: fprintf(fp, "%X", datum.as_byte); break; + case DATA_TYPE_HWORD: + fprintf(fp, "%d", datum.as_hword); + 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; - if (OPCODE_IS_TYPE(opcode, OP_TYPE_PUSH)) + if (OPCODE_IS_TYPE(opcode, OP_PUSH)) type = (data_type_t)opcode; - else if (OPCODE_IS_TYPE(opcode, OP_TYPE_PUSH_REGISTER)) + else if (OPCODE_IS_TYPE(opcode, OP_PUSH_REGISTER)) type = opcode >> 1; - else if (OPCODE_IS_TYPE(opcode, OP_TYPE_POP)) + else if (OPCODE_IS_TYPE(opcode, OP_POP)) type = opcode >> 2; - else if (OPCODE_IS_TYPE(opcode, OP_TYPE_MOV)) + else if (OPCODE_IS_TYPE(opcode, OP_MOV)) type = opcode >> 3; return type; } @@ -119,16 +101,16 @@ data_type_t get_opcode_data_type(opcode_t opcode) 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)) + if (OPCODE_IS_TYPE(instruction.opcode, OP_PUSH)) { data_type_t type = get_opcode_data_type(instruction.opcode); - fprintf(fp, ", datum="); + fprintf(fp, ", datum=0x"); 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)) + else if (OPCODE_IS_TYPE(instruction.opcode, OP_PUSH_REGISTER) || + OPCODE_IS_TYPE(instruction.opcode, OP_MOV)) { - fprintf(fp, ", reg="); + fprintf(fp, ", reg=0x"); data_print(instruction.operand, DATA_TYPE_BYTE, fp); } fprintf(fp, ")"); @@ -137,32 +119,22 @@ void inst_print(inst_t instruction, FILE *fp) size_t inst_bytecode_size(inst_t inst) { size_t size = 1; // for opcode - if (OPCODE_IS_TYPE(inst.opcode, OP_TYPE_PUSH)) + if (OPCODE_IS_TYPE(inst.opcode, OP_PUSH)) { if (inst.opcode == OP_PUSH_BYTE) ++size; + else if (inst.opcode == OP_PUSH_HWORD) + size += sizeof(i32); else if (inst.opcode == OP_PUSH_WORD) size += sizeof(word); - else if (inst.opcode == OP_PUSH_FLOAT) - size += sizeof(f64); } - else if (OPCODE_IS_TYPE(inst.opcode, OP_TYPE_PUSH_REGISTER)) + else if (OPCODE_IS_TYPE(inst.opcode, OP_PUSH_REGISTER) || + OPCODE_IS_TYPE(inst.opcode, OP_MOV)) + // Only need a byte for the register ++size; - else if (OPCODE_IS_TYPE(inst.opcode, OP_TYPE_POP)) - { - // No operand or register so leave as is - } - else if (OPCODE_IS_TYPE(inst.opcode, OP_TYPE_MOV)) - { - if (inst.opcode == OP_MOV_BYTE) - ++size; - else if (inst.opcode == OP_MOV_WORD) - size += sizeof(word); - else if (inst.opcode == OP_MOV_FLOAT) - size += sizeof(f64); - // For the register - ++size; - } + else if (OPCODE_IS_TYPE(inst.opcode, OP_POP)) + // No operand or register so leave as is + {} return size; } @@ -172,10 +144,10 @@ void inst_write_bytecode(inst_t inst, darr_t *darr) darr_append_byte(darr, inst.opcode); // Then append 0 or more operands data_type_t to_append = DATA_TYPE_NIL; - if (OPCODE_IS_TYPE(inst.opcode, OP_TYPE_PUSH)) + if (OPCODE_IS_TYPE(inst.opcode, OP_PUSH)) to_append = (data_type_t)inst.opcode; - else if (OPCODE_IS_TYPE(inst.opcode, OP_TYPE_PUSH_REGISTER) || - OPCODE_IS_TYPE(inst.opcode, OP_TYPE_MOV)) + else if (OPCODE_IS_TYPE(inst.opcode, OP_PUSH_REGISTER) || + OPCODE_IS_TYPE(inst.opcode, OP_MOV)) to_append = DATA_TYPE_BYTE; switch (to_append) @@ -185,11 +157,13 @@ void inst_write_bytecode(inst_t inst, darr_t *darr) case DATA_TYPE_BYTE: darr_append_byte(darr, inst.operand.as_byte); break; - case DATA_TYPE_WORD: - darr_append_bytes(darr, (byte *)&inst.operand.as_word, sizeof(word)); + case DATA_TYPE_HWORD: + darr_append_bytes(darr, (byte *)&inst.operand.as_hword, + sizeof(inst.operand.as_hword)); break; - case DATA_TYPE_FLOAT: - darr_append_bytes(darr, (byte *)&inst.operand.as_float, sizeof(f64)); + case DATA_TYPE_WORD: + darr_append_bytes(darr, (byte *)&inst.operand.as_word, + sizeof(inst.operand.as_word)); break; } } @@ -206,6 +180,15 @@ data_t read_type_from_darr(darr_t *darr, data_type_t type) return DBYTE(0); return DBYTE(darr->data[darr->used++]); break; + case DATA_TYPE_HWORD: + if (darr->used + HWORD_SIZE >= darr->available) + // TODO: Error (darr has no space left) + return DWORD(0); + hword u = 0; + memcpy(&u, darr->data + darr->used, sizeof(u)); + darr->used += sizeof(u); + return DHWORD(u); + break; case DATA_TYPE_WORD: if (darr->used + sizeof(word) >= darr->available) // TODO: Error (darr has no space left) @@ -215,15 +198,6 @@ data_t read_type_from_darr(darr_t *darr, data_type_t type) darr->used += sizeof(w); return DWORD(w); break; - case DATA_TYPE_FLOAT: - if (darr->used + sizeof(word) >= darr->available) - // TODO: Error (darr has no space left) - return DWORD(0); - f64 f = 0; - memcpy(&f, darr->data + darr->used, sizeof(f)); - darr->used += sizeof(f); - return DFLOAT(f); - break; } // TODO: Error (unrecognised type) return DBYTE(0); @@ -239,11 +213,11 @@ inst_t inst_read_bytecode(darr_t *darr) // Translate to NOOP return inst; // Read operands - if (OPCODE_IS_TYPE(opcode, OP_TYPE_PUSH)) + if (OPCODE_IS_TYPE(opcode, OP_PUSH)) inst.operand = read_type_from_darr(darr, get_opcode_data_type(opcode)); // Read register (as a byte) - else if (OPCODE_IS_TYPE(opcode, OP_TYPE_PUSH_REGISTER) || - OPCODE_IS_TYPE(opcode, OP_TYPE_MOV)) + else if (OPCODE_IS_TYPE(opcode, OP_PUSH_REGISTER) || + OPCODE_IS_TYPE(opcode, OP_MOV)) inst.operand = read_type_from_darr(darr, DATA_TYPE_BYTE); // Otherwise opcode doesn't take operands |