diff options
Diffstat (limited to 'src/runtime.c')
-rw-r--r-- | src/runtime.c | 170 |
1 files changed, 89 insertions, 81 deletions
diff --git a/src/runtime.c b/src/runtime.c index b744530..218bba7 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -24,26 +24,26 @@ void vm_execute(vm_t *vm) return; inst_t instruction = prog->instructions[prog->ptr]; - if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH)) + if (OPCODE_IS_TYPE(instruction.opcode, OP_PUSH)) { PUSH_ROUTINES[instruction.opcode](vm, instruction.operand); vm->registers.ret = instruction.operand.as_word; prog->ptr++; } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH_REGISTER)) + else if (OPCODE_IS_TYPE(instruction.opcode, OP_PUSH_REGISTER)) { PUSH_REG_ROUTINES[instruction.opcode](vm, instruction.operand.as_word); vm->registers.ret = instruction.operand.as_word; prog->ptr++; } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_POP)) + else if (OPCODE_IS_TYPE(instruction.opcode, OP_POP)) { // NOTE: We use the `ret` register for the result of this pop data_t d = POP_ROUTINES[instruction.opcode](vm); vm->registers.ret = d.as_word; prog->ptr++; } - else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_MOV)) + else if (OPCODE_IS_TYPE(instruction.opcode, OP_MOV)) { data_t d = MOV_ROUTINES[instruction.opcode](vm, instruction.operand.as_word); @@ -74,37 +74,21 @@ void vm_load_program(vm_t *vm, inst_t *instructions, size_t size) void vm_print_registers(vm_t *vm, FILE *fp) { struct Registers reg = vm->registers; - fprintf(fp, "Registers.ret = %lX\n", reg.ret); - fprintf(fp, "Registers.b = ["); - for (size_t i = 0; i < VM_BYTE_REGISTERS; ++i) + fprintf(fp, "Registers.ret = 0x%lX\n", reg.ret); + fprintf(fp, "Registers.reg = ["); + for (size_t i = 0; i < VM_REGISTERS; ++i) { - fprintf(fp, "{%lu:%X}", i, reg.b[i]); - if (i != VM_BYTE_REGISTERS - 1) + fprintf(fp, "{%lu:%lX}", i, reg.reg[i]); + if (i != VM_REGISTERS - 1) fprintf(fp, ", "); } fprintf(fp, "]\n"); - fprintf(fp, "Registers.w = ["); - for (size_t i = 0; i < VM_WORD_REGISTERS; ++i) - { - fprintf(fp, "{%lu:%lX}", i, reg.w[i]); - if (i != VM_WORD_REGISTERS - 1) - fprintf(fp, reg.w[i] == 0 ? ", " : ",\n"); - } - fprintf(fp, "]\n"); - fprintf(fp, "Registers.f = ["); - for (size_t i = 0; i < VM_FLOAT_REGISTERS; ++i) - { - fprintf(fp, "{%lu:%f}", i, reg.f[i]); - if (i != VM_FLOAT_REGISTERS - 1) - fprintf(fp, reg.f[i] == 0 ? ", " : ",\n"); - } - fprintf(fp, "]\n"); } void vm_print_stack(vm_t *vm, FILE *fp) { struct Stack stack = vm->stack; - fprintf(fp, "Stack.max = %lu\nStack.ptr = %lu\nStack.data = [", stack.max, + fprintf(fp, "Stack.max = %lu\nStack.ptr = %lu\nStack.data = [", stack.max, stack.ptr); if (stack.ptr == 0) { @@ -127,7 +111,9 @@ void vm_print_stack(vm_t *vm, FILE *fp) void vm_print_program(vm_t *vm, FILE *fp) { struct Program program = vm->program; - fprintf(fp, "Program.max = %lu\nProgram.ptr = %lu\nProgram.instructions = [", + fprintf(fp, + "Program.max = %lu\nProgram.ptr = " + "%lu\nProgram.instructions = [", program.max, program.ptr); if (program.ptr == 0) { @@ -185,6 +171,19 @@ void vm_push_byte(vm_t *vm, data_t b) vm->stack.data[vm->stack.ptr++] = b.as_byte; } +void vm_push_hword(vm_t *vm, data_t f) +{ + if (vm->stack.ptr + HWORD_SIZE >= vm->stack.max) + // TODO: Error STACK_OVERFLOW + return; + for (size_t i = 32; i > 0; i -= 8) + { + const word mask = ((word)0b11111111) << (i - 8); + byte b = (f.as_hword & mask) >> (i - 8); + vm_push_byte(vm, DBYTE(b)); + } +} + void vm_push_word(vm_t *vm, data_t w) { if (vm->stack.ptr + WORD_SIZE >= vm->stack.max) @@ -199,86 +198,94 @@ void vm_push_word(vm_t *vm, data_t w) } } -void vm_push_float(vm_t *vm, data_t f) -{ - if (vm->stack.ptr + FLOAT_SIZE >= vm->stack.max) - // TODO: Error STACK_OVERFLOW - return; - // TODO: Make this machine independent (encode IEEE754 floats - // yourself?) - memcpy(vm->stack.data + vm->stack.ptr, &f.as_float, FLOAT_SIZE); - vm->stack.ptr += FLOAT_SIZE; -} +#define WORD_NTH_BYTE(WORD, N) (((WORD) >> ((N)*8)) & 0b11111111) +#define WORD_NTH_HWORD(WORD, N) \ + (((WORD) >> ((N)*2)) & 0b11111111111111111111111111111111) -void vm_push_byte_register(vm_t *vm, word reg) +void vm_push_byte_register(vm_t *vm, byte reg) { - if (reg >= VM_BYTE_REGISTERS) + if (reg >= VM_REGISTERS * 8) // TODO: Error (reg is not a valid byte register) return; else if (vm->stack.ptr >= vm->stack.max) // TODO: Error STACK_OVERFLOW return; - vm_push_byte(vm, DBYTE(vm->registers.b[reg])); + + // Interpret each word based register as 8 byte registers + word ind = reg / 8; + word nth_byte = reg % 8; + word reg_ptr = vm->registers.reg[ind]; + + byte b = WORD_NTH_BYTE(reg_ptr, nth_byte); + + vm_push_byte(vm, DBYTE(b)); } -void vm_push_word_register(vm_t *vm, word reg) +void vm_push_hword_register(vm_t *vm, byte reg) { - if (reg >= VM_WORD_REGISTERS) - // TODO: Error (reg is not a valid word register) + if (reg >= VM_REGISTERS * 2) + // TODO: Error (reg is not a valid hword register) return; else if (vm->stack.ptr >= vm->stack.max) // TODO: Error STACK_OVERFLOW return; - vm_push_word(vm, DWORD(vm->registers.w[reg])); + // Interpret each word based register as 2 hword registers + word ind = reg / 2; + word nth_hword = reg % 2; + word reg_ptr = vm->registers.reg[ind]; + hword hw = WORD_NTH_HWORD(reg_ptr, nth_hword); + vm_push_hword(vm, DHWORD(hw)); } -void vm_push_float_register(vm_t *vm, word reg) +void vm_push_word_register(vm_t *vm, byte reg) { - if (reg >= VM_FLOAT_REGISTERS) - // TODO: Error (reg is not a valid float register) + if (reg >= VM_REGISTERS) + // TODO: Error (reg is not a valid word register) return; else if (vm->stack.ptr >= vm->stack.max) // TODO: Error STACK_OVERFLOW return; - vm_push_float(vm, DFLOAT(vm->registers.f[reg])); + vm_push_word(vm, DWORD(vm->registers.reg[reg])); } -data_t vm_mov_byte(vm_t *vm, word reg) +data_t vm_mov_byte(vm_t *vm, byte reg) { - if (reg >= VM_BYTE_REGISTERS) + if (reg >= VM_REGISTERS) // TODO: Error (reg is not a valid byte register) 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; + data_t ret = vm_pop_byte(vm); + word *reg_ptr = &vm->registers.reg[reg / 8]; + *reg_ptr = (*reg_ptr) | ((word)ret.as_word) << ((reg % 8) * 8); return ret; } -data_t vm_mov_word(vm_t *vm, word reg) +data_t vm_mov_hword(vm_t *vm, byte reg) { - if (reg >= VM_WORD_REGISTERS) - // TODO: Error (reg is not a valid word register) - return DWORD(0); - else if (vm->stack.ptr < sizeof(word)) + if (reg >= VM_REGISTERS) + // TODO: Error (reg is not a valid hword register) + return DHWORD(0); + else if (vm->stack.ptr < sizeof(f64)) // TODO: Error (STACK UNDERFLOW) - return DWORD(0); - data_t ret = vm_pop_word(vm); - vm->registers.w[reg] = ret.as_word; + return DHWORD(0); + data_t ret = vm_pop_hword(vm); + word *reg_ptr = &vm->registers.reg[reg / 2]; + *reg_ptr = (*reg_ptr) | ((word)ret.as_word) << ((reg % 2) * 2); return ret; } -data_t vm_mov_float(vm_t *vm, word reg) +data_t vm_mov_word(vm_t *vm, byte reg) { - if (reg >= VM_WORD_REGISTERS) - // TODO: Error (reg is not a valid float register) - return DFLOAT(0); - else if (vm->stack.ptr < sizeof(f64)) + if (reg >= VM_REGISTERS) + // TODO: Error (reg is not a valid word register) + return DWORD(0); + else if (vm->stack.ptr < sizeof(word)) // TODO: Error (STACK UNDERFLOW) - return DFLOAT(0); - data_t ret = vm_pop_float(vm); - vm->registers.f[reg] = ret.as_float; + return DWORD(0); + data_t ret = vm_pop_word(vm); + vm->registers.reg[reg] = ret.as_word; return ret; } @@ -290,6 +297,20 @@ data_t vm_pop_byte(vm_t *vm) return DBYTE(vm->stack.data[--vm->stack.ptr]); } +data_t vm_pop_hword(vm_t *vm) +{ + if (vm->stack.ptr < HWORD_SIZE) + // TODO: Error STACK_UNDERFLOW + return DHWORD(0); + hword h = 0; + for (size_t i = 0; i < HWORD_SIZE; ++i) + { + data_t b = vm_pop_byte(vm); + h = h | ((word)(b.as_byte) << (i * 8)); + } + return DWORD(h); +} + data_t vm_pop_word(vm_t *vm) { if (vm->stack.ptr < WORD_SIZE) @@ -303,16 +324,3 @@ data_t vm_pop_word(vm_t *vm) } return DWORD(w); } - -data_t vm_pop_float(vm_t *vm) -{ - if (vm->stack.ptr < FLOAT_SIZE) - // TODO: Error STACK_UNDERFLOW - return DFLOAT(0); - f64 f = 0; - // TODO: Make this machine independent (encode IEEE754 floats - // yourself?) - memcpy(&f, vm->stack.data + vm->stack.ptr - FLOAT_SIZE, FLOAT_SIZE); - vm->stack.ptr -= FLOAT_SIZE; - return DFLOAT(f); -} |