Simplify the OP_POP_* routine by adjusting data_type_t

This simple fix made the routine for OP_POP not require an additional
dispatch step on top of the conditional due to OPCODE_DATA_TYPE,
instead using data_type_t as a map from an opcode's base type to a
specific type.
This commit is contained in:
2024-04-25 01:20:35 +05:30
parent 71b0b793af
commit 122e12e8fd
2 changed files with 14 additions and 18 deletions

View File

@@ -72,7 +72,7 @@ typedef union
*/ */
typedef enum typedef enum
{ {
DATA_TYPE_NIL = 0, DATA_TYPE_NIL = -1,
DATA_TYPE_BYTE, DATA_TYPE_BYTE,
DATA_TYPE_HWORD, DATA_TYPE_HWORD,
DATA_TYPE_WORD, DATA_TYPE_WORD,

View File

@@ -54,6 +54,10 @@ const char *err_as_cstr(err_t err)
} }
} }
static_assert(DATA_TYPE_NIL == -1 && DATA_TYPE_WORD == 2,
"Code using OPCODE_DATA_TYPE for quick same type opcode "
"conversion may be out of date.");
err_t vm_execute(vm_t *vm) err_t vm_execute(vm_t *vm)
{ {
static_assert(NUMBER_OF_OPCODES == 98, "vm_execute: Out of date"); static_assert(NUMBER_OF_OPCODES == 98, "vm_execute: Out of date");
@@ -83,23 +87,15 @@ err_t vm_execute(vm_t *vm)
} }
else if (OPCODE_IS_TYPE(instruction.opcode, OP_POP)) else if (OPCODE_IS_TYPE(instruction.opcode, OP_POP))
{ {
// NOTE: We use the first register to hold the result of this pop // NOTE: We always use the first register to hold the result of
data_type_t type = OPCODE_DATA_TYPE(instruction.opcode, OP_POP); // this pop.
err_t err = ERR_OK;
switch (type) // Here we add OP_MOV_BYTE and the data_type_t of the opcode to
{ // get the right OP_MOV typed opcode.
case DATA_TYPE_NIL: opcode_t mov_opcode =
break; OPCODE_DATA_TYPE(instruction.opcode, OP_POP) + OP_MOV_BYTE;
case DATA_TYPE_BYTE:
err = vm_mov_byte(vm, 0); err_t err = WORD_ROUTINES[mov_opcode](vm, 0);
break;
case DATA_TYPE_HWORD:
err = vm_mov_hword(vm, 0);
break;
case DATA_TYPE_WORD:
err = vm_mov_word(vm, 0);
break;
}
if (err) if (err)
return err; return err;
prog->ptr++; prog->ptr++;