From dcedb70a5ccead41574cf857b369d264c87dd7e0 Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Sat, 21 Oct 2023 22:57:43 +0100 Subject: Switched from floats to halfword Registers are now just words, with pushing from and moving to registers with specified subtypes just pushing those types into the word registers. That means there are 8 word registers which can act as 16 half word registers, which themselves can act as 64 byte registers. --- src/runtime.c | 170 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 89 insertions(+), 81 deletions(-) (limited to 'src/runtime.c') 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); -} -- cgit v1.2.3-13-gbd6f