diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-22 22:01:14 +0100 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2023-10-22 22:02:53 +0100 |
commit | 7243ac253398708c79ed3883fe83d31037b4ce93 (patch) | |
tree | 6ec3bbe7cec9be7243fad727127f31eb3498e59a /src/runtime.c | |
parent | 1962aabdf5d5aa69e52afdeead360ccb4c0c9a49 (diff) | |
download | ovm-7243ac253398708c79ed3883fe83d31037b4ce93.tar.gz ovm-7243ac253398708c79ed3883fe83d31037b4ce93.tar.bz2 ovm-7243ac253398708c79ed3883fe83d31037b4ce93.zip |
Coupled some routines together, implemented OP_PLUS_*, -vm_peek
Routines that use the stack for their operands i.e. aren't supplied
operands directly all have the same signature. We may as well stick
them all together in one array and one conditional, just reduces the
number of branches. Also looks nicer.
Implemented OP_PLUS_*. Pretty simple to implement.
Deleted vm_peek as it was only necessary to update the `ret` register.
Diffstat (limited to 'src/runtime.c')
-rw-r--r-- | src/runtime.c | 120 |
1 files changed, 47 insertions, 73 deletions
diff --git a/src/runtime.c b/src/runtime.c index fde22f3..df2a460 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -54,7 +54,7 @@ const char *err_as_cstr(err_t err) err_t vm_execute(vm_t *vm) { - static_assert(NUMBER_OF_OPCODES == 34, "vm_execute: Out of date"); + static_assert(NUMBER_OF_OPCODES == 37, "vm_execute: Out of date"); struct Program *prog = &vm->program; if (prog->ptr >= prog->max) return ERR_END_OF_PROGRAM; @@ -65,11 +65,11 @@ err_t vm_execute(vm_t *vm) prog->ptr++; return PUSH_ROUTINES[instruction.opcode](vm, instruction.operand); } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_PUSH_REGISTER)) + else if (OPCODE_IS_TYPE(instruction.opcode, OP_MOV) || + OPCODE_IS_TYPE(instruction.opcode, OP_PUSH_REGISTER)) { prog->ptr++; - return PUSH_REG_ROUTINES[instruction.opcode](vm, - instruction.operand.as_word); + return REG_ROUTINES[instruction.opcode](vm, instruction.operand.as_byte); } else if (OPCODE_IS_TYPE(instruction.opcode, OP_POP)) { @@ -92,40 +92,20 @@ err_t vm_execute(vm_t *vm) } return ERR_OK; } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_MOV)) - { - prog->ptr++; - return MOV_ROUTINES[instruction.opcode](vm, instruction.operand.as_byte); - } else if (OPCODE_IS_TYPE(instruction.opcode, OP_DUP)) { prog->ptr++; return DUP_ROUTINES[instruction.opcode](vm, instruction.operand.as_word); } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_NOT)) - { - prog->ptr++; - return NOT_ROUTINES[instruction.opcode](vm); - } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_OR)) - { - prog->ptr++; - return OR_ROUTINES[instruction.opcode](vm); - } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_AND)) - { - prog->ptr++; - return AND_ROUTINES[instruction.opcode](vm); - } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_XOR)) + else if (OPCODE_IS_TYPE(instruction.opcode, OP_NOT) || + OPCODE_IS_TYPE(instruction.opcode, OP_OR) || + OPCODE_IS_TYPE(instruction.opcode, OP_AND) || + OPCODE_IS_TYPE(instruction.opcode, OP_XOR) || + OPCODE_IS_TYPE(instruction.opcode, OP_EQ) || + OPCODE_IS_TYPE(instruction.opcode, OP_PLUS)) { prog->ptr++; - return XOR_ROUTINES[instruction.opcode](vm); - } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_EQ)) - { - prog->ptr++; - return EQ_ROUTINES[instruction.opcode](vm); + return STACK_ROUTINES[instruction.opcode](vm); } else if (instruction.opcode == OP_JUMP_ABS) { @@ -316,48 +296,6 @@ void vm_print_all(vm_t *vm, FILE *fp) fp); } -data_t vm_peek(vm_t *vm, data_type_t type) -{ - switch (type) - { - case DATA_TYPE_NIL: - return DBYTE(0); - break; - case DATA_TYPE_BYTE: - if (vm->stack.ptr == 0) - return DBYTE(0); - return DBYTE(vm->stack.data[vm->stack.ptr - 1]); - break; - case DATA_TYPE_HWORD: { - if (vm->stack.ptr < HWORD_SIZE) - return DHWORD(0); - byte bytes[HWORD_SIZE] = {0}; - for (size_t i = 0; i < HWORD_SIZE; ++i) - { - byte b = vm->stack.data[vm->stack.ptr - i - 1]; - bytes[HWORD_SIZE - 1 - i] = b; - } - return DWORD(convert_bytes_to_hword(bytes)); - break; - } - case DATA_TYPE_WORD: { - if (vm->stack.ptr < WORD_SIZE) - return DWORD(0); - byte bytes[WORD_SIZE] = {0}; - for (size_t i = 0; i < WORD_SIZE; ++i) - { - byte b = vm->stack.data[vm->stack.ptr - i - 1]; - bytes[WORD_SIZE - 1 - i] = b; - } - return DWORD(convert_bytes_to_hword(bytes)); - break; - } - default: - return DBYTE(0); - break; - } -} - err_t vm_push_byte(vm_t *vm, data_t b) { if (vm->stack.ptr >= vm->stack.max) @@ -707,3 +645,39 @@ err_t vm_eq_word(vm_t *vm) return err; return vm_push_word(vm, DWORD(a.as_word == b.as_word)); } + +err_t vm_plus_byte(vm_t *vm) +{ + data_t a = {0}, b = {0}; + err_t err = vm_pop_byte(vm, &a); + if (err) + return err; + err = vm_pop_byte(vm, &b); + if (err) + return err; + return vm_push_byte(vm, DBYTE(a.as_byte + b.as_byte)); +} + +err_t vm_plus_hword(vm_t *vm) +{ + data_t a = {0}, b = {0}; + err_t err = vm_pop_hword(vm, &a); + if (err) + return err; + err = vm_pop_hword(vm, &b); + if (err) + return err; + return vm_push_hword(vm, DHWORD(a.as_hword + b.as_hword)); +} + +err_t vm_plus_word(vm_t *vm) +{ + data_t a = {0}, b = {0}; + err_t err = vm_pop_word(vm, &a); + if (err) + return err; + err = vm_pop_word(vm, &b); + if (err) + return err; + return vm_push_word(vm, DWORD(a.as_word + b.as_word)); +} |