diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-16 00:59:30 +0100 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-16 01:05:42 +0100 |
commit | 0f37a5994046a06cf086b6ac4af62620c5881fc7 (patch) | |
tree | c1ce6a8704a746fdac104c75e5b95e69d32b3380 | |
parent | cd19f1e1d30f52c073b6871c436e770ce2ffdda0 (diff) | |
download | ovm-0f37a5994046a06cf086b6ac4af62620c5881fc7.tar.gz ovm-0f37a5994046a06cf086b6ac4af62620c5881fc7.tar.bz2 ovm-0f37a5994046a06cf086b6ac4af62620c5881fc7.zip |
MOV now uses the stack, removed register member in inst_t
Instead of taking an operand and a register, mov just uses the stack
for the operand. Therefore, there's no need for a register member in
inst_t.
As a result, PUSH_*_REGISTER now uses the operand for the register.
-rw-r--r-- | src/inst.h | 16 | ||||
-rw-r--r-- | src/runtime.c | 42 | ||||
-rw-r--r-- | src/runtime.h | 8 |
3 files changed, 39 insertions, 27 deletions
@@ -54,7 +54,6 @@ typedef struct { opcode_t opcode; data_t operand; - byte reg; // At most 255 registers } inst_t; #define INST_BPUSH(BYTE) \ @@ -66,14 +65,11 @@ typedef struct #define INST_FPUSH(FLOAT) \ ((inst_t){.opcode = OP_PUSH_FLOAT, .operand = DFLOAT(FLOAT)}) -#define INST_BMOV(BYTE, REG) \ - ((inst_t){.opcode = OP_MOV_BYTE, .operand = DBYTE(BYTE), .reg = (REG)}) +#define INST_BMOV(REG) ((inst_t){.opcode = OP_MOV_BYTE, .operand = DWORD(REG)}) -#define INST_WMOV(WORD, REG) \ - ((inst_t){.opcode = OP_MOV_WORD, .operand = DWORD(WORD), .reg = (REG)}) +#define INST_WMOV(REG) ((inst_t){.opcode = OP_MOV_WORD, .operand = DWORD(REG)}) -#define INST_FMOV(FLOAT, REG) \ - ((inst_t){.opcode = OP_MOV_FLOAT, .operand = DFLOAT(FLOAT), .reg = (REG)}) +#define INST_FMOV(REG) ((inst_t){.opcode = OP_MOV_FLOAT, .operand = DWORD(REG)}) #define INST_BPOP ((inst_t){.opcode = OP_POP_BYTE}) @@ -82,12 +78,12 @@ typedef struct #define INST_FPOP ((inst_t){.opcode = OP_POP_FLOAT}) #define INST_BPUSH_REG(REG) \ - ((inst_t){.opcode = OP_PUSH_BYTE_REGISTER, .reg = (REG)}) + ((inst_t){.opcode = OP_PUSH_BYTE_REGISTER, .operand = DWORD(REG)}) #define INST_WPUSH_REG(REG) \ - ((inst_t){.opcode = OP_PUSH_WORD_REGISTER, .reg = (REG)}) + ((inst_t){.opcode = OP_PUSH_WORD_REGISTER, .operand = DWORD(REG)}) #define INST_FPUSH_REG(REG) \ - ((inst_t){.opcode = OP_PUSH_FLOAT_REGISTER, .reg = (REG)}) + ((inst_t){.opcode = OP_PUSH_FLOAT_REGISTER, .operand = DWORD(REG)}) #endif diff --git a/src/runtime.c b/src/runtime.c index 9d78b09..cb4ed99 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -31,7 +31,7 @@ void vm_execute(vm_t *vm) } else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH_REGISTER)) { - PUSH_REG_ROUTINES[instruction.opcode](vm, instruction.reg); + PUSH_REG_ROUTINES[instruction.opcode](vm, instruction.operand.as_word); vm->registers.ret = instruction.operand.as_word; prog->ptr++; } @@ -44,8 +44,9 @@ void vm_execute(vm_t *vm) } 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; + data_t d = + MOV_ROUTINES[instruction.opcode](vm, instruction.operand.as_word); + vm->registers.ret = d.as_word; // will do type punning for me prog->ptr++; } else @@ -135,28 +136,43 @@ void vm_push_float_register(vm_t *vm, word reg) vm_push_float(vm, DFLOAT(vm->registers.f[reg])); } -void vm_mov_byte(vm_t *vm, data_t b, word reg) +data_t vm_mov_byte(vm_t *vm, word reg) { if (reg >= VM_BYTE_REGISTERS) // TODO: Error (reg is not a valid byte register) - return; - vm->registers.b[reg] = b.as_byte; + return DBYTE(0); + else if (vm->stack.ptr == 0) + // TODO: Error (STACK UNDERFLOW) + return DBYTE(0); + data_t ret = vm_pop_byte(vm); + vm->registers.b[reg] = ret.as_byte; + return ret; } -void vm_mov_word(vm_t *vm, data_t w, word reg) +data_t vm_mov_word(vm_t *vm, word reg) { if (reg >= VM_WORD_REGISTERS) // TODO: Error (reg is not a valid word register) - return; - vm->registers.w[reg] = w.as_word; + return DWORD(0); + else if (vm->stack.ptr < sizeof(word)) + // TODO: Error (STACK UNDERFLOW) + return DWORD(0); + data_t ret = vm_pop_word(vm); + vm->registers.w[reg] = ret.as_word; + return ret; } -void vm_mov_float(vm_t *vm, data_t f, word reg) +data_t vm_mov_float(vm_t *vm, word reg) { - if (reg >= VM_FLOAT_REGISTERS) + if (reg >= VM_WORD_REGISTERS) // TODO: Error (reg is not a valid float register) - return; - vm->registers.f[reg] = f.as_float; + return DFLOAT(0); + else if (vm->stack.ptr < sizeof(f64)) + // TODO: Error (STACK UNDERFLOW) + return DFLOAT(0); + data_t ret = vm_pop_float(vm); + vm->registers.f[reg] = ret.as_float; + return ret; } data_t vm_pop_byte(vm_t *vm) diff --git a/src/runtime.h b/src/runtime.h index 4efe074..5505fc0 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -69,11 +69,11 @@ static const push_reg_f PUSH_REG_ROUTINES[] = { [OP_PUSH_FLOAT_REGISTER] = vm_push_float_register, }; -void vm_mov_byte(vm_t *, data_t, word); -void vm_mov_word(vm_t *, data_t, word); -void vm_mov_float(vm_t *, data_t, word); +data_t vm_mov_byte(vm_t *, word); +data_t vm_mov_word(vm_t *, word); +data_t vm_mov_float(vm_t *, word); -typedef void (*mov_f)(vm_t *, data_t, word); +typedef data_t (*mov_f)(vm_t *, word); static const mov_f MOV_ROUTINES[] = { [OP_MOV_BYTE] = vm_mov_byte, [OP_MOV_WORD] = vm_mov_word, |