aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2023-10-15 22:16:31 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2023-10-15 22:16:31 +0100
commitcd19f1e1d30f52c073b6871c436e770ce2ffdda0 (patch)
treee91d680d6f7cc52d790e5fe708fb09551206d3bf
parent1cb54dc9949f80ce1bc8c54a806ebea920c70ec5 (diff)
downloadovm-cd19f1e1d30f52c073b6871c436e770ce2ffdda0.tar.gz
ovm-cd19f1e1d30f52c073b6871c436e770ce2ffdda0.tar.bz2
ovm-cd19f1e1d30f52c073b6871c436e770ce2ffdda0.zip
Better checking of opcode types
Introduced an enum (opcode_type_t) for the masks and values of each opcode, which allows defining a single enum which checks an opcode by a opcode_type_t.
-rw-r--r--src/inst.h14
-rw-r--r--src/runtime.c8
2 files changed, 14 insertions, 8 deletions
diff --git a/src/inst.h b/src/inst.h
index d8feb09..4ef26ac 100644
--- a/src/inst.h
+++ b/src/inst.h
@@ -39,10 +39,16 @@ typedef enum
OP_HALT,
} opcode_t;
-#define OPCODE_IS_PUSH(OPCODE) (((OPCODE)&0b1) == 0b1)
-#define OPCODE_IS_PUSH_REG(OPCODE) (((OPCODE)&0b10) == 0b10)
-#define OPCODE_IS_POP(OPCODE) (((OPCODE)&0b100) == 0b100)
-#define OPCODE_IS_MOV(OPCODE) (((OPCODE)&0b1000) == 0b1000)
+// Masks and values to check if an opcode is of a type
+typedef enum
+{
+ OP_TYPE_PUSH = 0b1,
+ OP_TYPE_PUSH_REGISTER = 0b10,
+ OP_TYPE_POP = 0b100,
+ OP_TYPE_MOV = 0b1000,
+} opcode_type_t;
+
+#define OPCODE_IS_TYPE(OPCODE, TYPE) ((OPCODE & TYPE) == TYPE)
typedef struct
{
diff --git a/src/runtime.c b/src/runtime.c
index b9870de..9d78b09 100644
--- a/src/runtime.c
+++ b/src/runtime.c
@@ -23,26 +23,26 @@ void vm_execute(vm_t *vm)
return;
inst_t instruction = prog->instructions[prog->ptr];
- if (OPCODE_IS_PUSH(instruction.opcode))
+ if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH))
{
PUSH_ROUTINES[instruction.opcode](vm, instruction.operand);
vm->registers.ret = instruction.operand.as_word;
prog->ptr++;
}
- else if (OPCODE_IS_PUSH_REG(instruction.opcode))
+ else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH_REGISTER))
{
PUSH_REG_ROUTINES[instruction.opcode](vm, instruction.reg);
vm->registers.ret = instruction.operand.as_word;
prog->ptr++;
}
- else if (OPCODE_IS_POP(instruction.opcode))
+ else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_POP))
{
// NOTE: We use the `ret` register for the result of this pop
data_t d = POP_ROUTINES[instruction.opcode](vm);
vm->registers.ret = d.as_word;
prog->ptr++;
}
- else if (OPCODE_IS_MOV(instruction.opcode))
+ else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_MOV))
{
MOV_ROUTINES[instruction.opcode](vm, instruction.operand, instruction.reg);
vm->registers.ret = instruction.operand.as_word;