From 9da31398baa93e8485aa70fc09cbca66daa0fa40 Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Sun, 22 Oct 2023 20:30:05 +0100 Subject: Implemented vm_* routines for OP_DUP and vm_execute code --- src/runtime.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/runtime.h | 10 ++++++++++ 2 files changed, 58 insertions(+) (limited to 'src') diff --git a/src/runtime.c b/src/runtime.c index a5ffd09..241d664 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -67,6 +67,14 @@ void vm_execute(vm_t *vm) vm->registers.ret = d.as_word; prog->ptr++; } + else if (OPCODE_IS_TYPE(instruction.opcode, OP_DUP)) + { + DUP_ROUTINES[instruction.opcode](vm, instruction.operand.as_word); + data_type_t type = OPCODE_DATA_TYPE(instruction.opcode, OP_DUP); + data_t datum = vm_peek(vm, type); + vm->registers.ret = datum.as_word; + prog->ptr++; + } else if (OPCODE_IS_TYPE(instruction.opcode, OP_NOT)) { NOT_ROUTINES[instruction.opcode](vm); @@ -426,6 +434,46 @@ data_t vm_mov_word(vm_t *vm, byte reg) return ret; } +void vm_dup_byte(vm_t *vm, word w) +{ + if (vm->stack.ptr < w + 1) + // TODO: Error STACK_UNDERFLOW + return; + else if (vm->stack.ptr >= vm->stack.max) + // TODO: Error STACK_OVERFLOW + return; + vm_push_byte(vm, DBYTE(vm->stack.data[vm->stack.ptr - 1 - w])); +} + +void vm_dup_hword(vm_t *vm, word w) +{ + if (vm->stack.ptr < HWORD_SIZE * (w + 1)) + // TODO: Error STACK_UNDERFLOW + return; + else if (vm->stack.ptr + HWORD_SIZE >= vm->stack.max) + // TODO: Error STACK_OVERFLOW + return; + byte bytes[HWORD_SIZE] = {0}; + for (size_t i = 0; i < HWORD_SIZE; ++i) + bytes[HWORD_SIZE - i - 1] = + vm->stack.data[vm->stack.ptr - (HWORD_SIZE * (w + 1)) + i]; + vm_push_hword(vm, DHWORD(convert_bytes_to_hword(bytes))); +} + +void vm_dup_word(vm_t *vm, word w) +{ + if (vm->stack.ptr < WORD_SIZE * (w + 1)) + // TODO: Error STACK_UNDERFLOW + return; + else if (vm->stack.ptr + WORD_SIZE >= vm->stack.max) + // TODO: Error STACK_OVERFLOW + return; + byte bytes[WORD_SIZE] = {0}; + for (size_t i = 0; i < WORD_SIZE; ++i) + bytes[i] = vm->stack.data[vm->stack.ptr - 1 - (WORD_SIZE * (w + 1)) + i]; + vm_push_word(vm, DWORD(convert_bytes_to_word(bytes))); +} + data_t vm_pop_byte(vm_t *vm) { if (vm->stack.ptr == 0) diff --git a/src/runtime.h b/src/runtime.h index 5ee5f9b..b13654e 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -98,6 +98,16 @@ static const mov_f MOV_ROUTINES[] = { [OP_MOV_WORD] = vm_mov_word, }; +void vm_dup_byte(vm_t *, word); +void vm_dup_hword(vm_t *, word); +void vm_dup_word(vm_t *, word); + +typedef void (*dup_f)(vm_t *, word); +static const dup_f DUP_ROUTINES[] = { + [OP_DUP_BYTE] = vm_dup_byte, + [OP_DUP_HWORD] = vm_dup_hword, + [OP_DUP_WORD] = vm_dup_word, +}; void vm_not_byte(vm_t *); void vm_not_hword(vm_t *); -- cgit v1.2.3-13-gbd6f