Make push opcodes a specific bit set and add a NOOP opcode

By default, a zero initialised set of instructions are NOOPs, which is
great.

Last two bits of a push opcode is always 01.  Rest of the bits are
used to distinguish between differing types of push.  This makes it
easier to inspect on the byte level what type of opcode we have.
This commit is contained in:
2023-10-15 20:56:02 +01:00
parent 40dfa5c255
commit 7a820290f9
2 changed files with 14 additions and 9 deletions

View File

@@ -17,14 +17,20 @@
typedef enum typedef enum
{ {
OP_PUSH_BYTE = 1, OP_NOOP = 0,
OP_PUSH_WORD,
OP_PUSH_FLOAT, OP_PUSH_BYTE = 0b0001,
} op_t; OP_PUSH_WORD = 0b0101,
OP_PUSH_FLOAT = 0b1001,
OP_HALT,
} opcode_t;
#define OPCODE_IS_PUSH(OPCODE) (((OPCODE)&1) == 1)
typedef struct typedef struct
{ {
op_t opcode; opcode_t opcode;
data_t operand; data_t operand;
} inst_t; } inst_t;

View File

@@ -121,11 +121,10 @@ void vm_execute(vm_t *vm)
// TODO: Error (Went past end of program) // TODO: Error (Went past end of program)
return; return;
inst_t instruction = prog->instructions[prog->ptr]; inst_t instruction = prog->instructions[prog->ptr];
// NOTE: This is ballsy; I'm essentially saying I will never use the
// last 2 bits unless it's a push routine // Check if opcode is PUSH_LIKE
if ((instruction.opcode & 0b11) != 0) if (OPCODE_IS_PUSH(instruction.opcode))
{ {
// Possible push routines
typedef void (*push_f)(vm_t *, data_t); typedef void (*push_f)(vm_t *, data_t);
const push_f routines[] = {[OP_PUSH_BYTE] = vm_push_byte, const push_f routines[] = {[OP_PUSH_BYTE] = vm_push_byte,
[OP_PUSH_WORD] = vm_push_word, [OP_PUSH_WORD] = vm_push_word,