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 | |
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.
-rw-r--r-- | src/runtime.c | 120 | ||||
-rw-r--r-- | src/runtime.h | 84 |
2 files changed, 83 insertions, 121 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)); +} diff --git a/src/runtime.h b/src/runtime.h index cba9728..ab5abd7 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -70,9 +70,11 @@ void vm_print_stack(vm_t *, FILE *); void vm_print_program(vm_t *, FILE *); void vm_print_all(vm_t *, FILE *); -data_t vm_peek(vm_t *, data_type_t); - // Execution routines +err_t vm_pop_byte(vm_t *, data_t *); +err_t vm_pop_hword(vm_t *, data_t *); +err_t vm_pop_word(vm_t *, data_t *); + err_t vm_push_byte(vm_t *, data_t); err_t vm_push_hword(vm_t *, data_t); err_t vm_push_word(vm_t *, data_t); @@ -88,26 +90,18 @@ err_t vm_push_byte_register(vm_t *, byte); err_t vm_push_hword_register(vm_t *, byte); err_t vm_push_word_register(vm_t *, byte); -typedef err_t (*push_reg_f)(vm_t *, byte); -static const push_reg_f PUSH_REG_ROUTINES[] = { - [OP_PUSH_REGISTER_BYTE] = vm_push_byte_register, - [OP_PUSH_REGISTER_HWORD] = vm_push_hword_register, - [OP_PUSH_REGISTER_WORD] = vm_push_word_register, -}; - -err_t vm_pop_byte(vm_t *, data_t *); -err_t vm_pop_hword(vm_t *, data_t *); -err_t vm_pop_word(vm_t *, data_t *); - err_t vm_mov_byte(vm_t *, byte); err_t vm_mov_hword(vm_t *, byte); err_t vm_mov_word(vm_t *, byte); -typedef err_t (*mov_f)(vm_t *, byte); -static const mov_f MOV_ROUTINES[] = { - [OP_MOV_BYTE] = vm_mov_byte, - [OP_MOV_HWORD] = vm_mov_hword, - [OP_MOV_WORD] = vm_mov_word, +typedef err_t (*reg_f)(vm_t *, byte); +static const reg_f REG_ROUTINES[] = { + [OP_PUSH_REGISTER_BYTE] = vm_push_byte_register, + [OP_PUSH_REGISTER_HWORD] = vm_push_hword_register, + [OP_PUSH_REGISTER_WORD] = vm_push_word_register, + [OP_MOV_BYTE] = vm_mov_byte, + [OP_MOV_HWORD] = vm_mov_hword, + [OP_MOV_WORD] = vm_mov_word, }; err_t vm_dup_byte(vm_t *, word); @@ -125,51 +119,45 @@ err_t vm_not_byte(vm_t *); err_t vm_not_hword(vm_t *); err_t vm_not_word(vm_t *); -typedef err_t (*not_f)(vm_t *); -static const not_f NOT_ROUTINES[] = { - [OP_NOT_BYTE] = vm_not_byte, - [OP_NOT_HWORD] = vm_not_hword, - [OP_NOT_WORD] = vm_not_word, -}; - err_t vm_or_byte(vm_t *); err_t vm_or_hword(vm_t *); err_t vm_or_word(vm_t *); -typedef err_t (*or_f)(vm_t *); -static const or_f OR_ROUTINES[] = { - [OP_OR_BYTE] = vm_or_byte, - [OP_OR_HWORD] = vm_or_hword, - [OP_OR_WORD] = vm_or_word, -}; err_t vm_and_byte(vm_t *); err_t vm_and_hword(vm_t *); err_t vm_and_word(vm_t *); -typedef err_t (*and_f)(vm_t *); -static const and_f AND_ROUTINES[] = { - [OP_AND_BYTE] = vm_and_byte, - [OP_AND_HWORD] = vm_and_hword, - [OP_AND_WORD] = vm_and_word, -}; err_t vm_xor_byte(vm_t *); err_t vm_xor_hword(vm_t *); err_t vm_xor_word(vm_t *); -typedef err_t (*xor_f)(vm_t *); -static const xor_f XOR_ROUTINES[] = { - [OP_XOR_BYTE] = vm_xor_byte, - [OP_XOR_HWORD] = vm_xor_hword, - [OP_XOR_WORD] = vm_xor_word, -}; err_t vm_eq_byte(vm_t *); err_t vm_eq_hword(vm_t *); err_t vm_eq_word(vm_t *); -typedef err_t (*eq_f)(vm_t *); -static const eq_f EQ_ROUTINES[] = { - [OP_EQ_BYTE] = vm_eq_byte, - [OP_EQ_HWORD] = vm_eq_hword, - [OP_EQ_WORD] = vm_eq_word, + +err_t vm_plus_byte(vm_t *); +err_t vm_plus_hword(vm_t *); +err_t vm_plus_word(vm_t *); + +typedef err_t (*stack_f)(vm_t *); +static const stack_f STACK_ROUTINES[] = { + [OP_NOT_BYTE] = vm_not_byte, [OP_NOT_HWORD] = vm_not_hword, + [OP_NOT_WORD] = vm_not_word, + + [OP_OR_BYTE] = vm_or_byte, [OP_OR_HWORD] = vm_or_hword, + [OP_OR_WORD] = vm_or_word, + + [OP_AND_BYTE] = vm_and_byte, [OP_AND_HWORD] = vm_and_hword, + [OP_AND_WORD] = vm_and_word, + + [OP_XOR_BYTE] = vm_xor_byte, [OP_XOR_HWORD] = vm_xor_hword, + [OP_XOR_WORD] = vm_xor_word, + + [OP_EQ_BYTE] = vm_eq_byte, [OP_EQ_HWORD] = vm_eq_hword, + [OP_EQ_WORD] = vm_eq_word, + + [OP_PLUS_BYTE] = vm_plus_byte, [OP_PLUS_HWORD] = vm_plus_hword, + [OP_PLUS_WORD] = vm_plus_word, }; #endif |