MOV now uses the stack, removed register member in inst_t

Instead of taking an operand and a register, mov just uses the stack
for the operand.  Therefore, there's no need for a register member in
inst_t.

As a result, PUSH_*_REGISTER now uses the operand for the register.
This commit is contained in:
2023-10-16 00:59:30 +01:00
parent cd19f1e1d3
commit 0f37a59940
3 changed files with 39 additions and 27 deletions

View File

@@ -54,7 +54,6 @@ typedef struct
{ {
opcode_t opcode; opcode_t opcode;
data_t operand; data_t operand;
byte reg; // At most 255 registers
} inst_t; } inst_t;
#define INST_BPUSH(BYTE) \ #define INST_BPUSH(BYTE) \
@@ -66,14 +65,11 @@ typedef struct
#define INST_FPUSH(FLOAT) \ #define INST_FPUSH(FLOAT) \
((inst_t){.opcode = OP_PUSH_FLOAT, .operand = DFLOAT(FLOAT)}) ((inst_t){.opcode = OP_PUSH_FLOAT, .operand = DFLOAT(FLOAT)})
#define INST_BMOV(BYTE, REG) \ #define INST_BMOV(REG) ((inst_t){.opcode = OP_MOV_BYTE, .operand = DWORD(REG)})
((inst_t){.opcode = OP_MOV_BYTE, .operand = DBYTE(BYTE), .reg = (REG)})
#define INST_WMOV(WORD, REG) \ #define INST_WMOV(REG) ((inst_t){.opcode = OP_MOV_WORD, .operand = DWORD(REG)})
((inst_t){.opcode = OP_MOV_WORD, .operand = DWORD(WORD), .reg = (REG)})
#define INST_FMOV(FLOAT, REG) \ #define INST_FMOV(REG) ((inst_t){.opcode = OP_MOV_FLOAT, .operand = DWORD(REG)})
((inst_t){.opcode = OP_MOV_FLOAT, .operand = DFLOAT(FLOAT), .reg = (REG)})
#define INST_BPOP ((inst_t){.opcode = OP_POP_BYTE}) #define INST_BPOP ((inst_t){.opcode = OP_POP_BYTE})
@@ -82,12 +78,12 @@ typedef struct
#define INST_FPOP ((inst_t){.opcode = OP_POP_FLOAT}) #define INST_FPOP ((inst_t){.opcode = OP_POP_FLOAT})
#define INST_BPUSH_REG(REG) \ #define INST_BPUSH_REG(REG) \
((inst_t){.opcode = OP_PUSH_BYTE_REGISTER, .reg = (REG)}) ((inst_t){.opcode = OP_PUSH_BYTE_REGISTER, .operand = DWORD(REG)})
#define INST_WPUSH_REG(REG) \ #define INST_WPUSH_REG(REG) \
((inst_t){.opcode = OP_PUSH_WORD_REGISTER, .reg = (REG)}) ((inst_t){.opcode = OP_PUSH_WORD_REGISTER, .operand = DWORD(REG)})
#define INST_FPUSH_REG(REG) \ #define INST_FPUSH_REG(REG) \
((inst_t){.opcode = OP_PUSH_FLOAT_REGISTER, .reg = (REG)}) ((inst_t){.opcode = OP_PUSH_FLOAT_REGISTER, .operand = DWORD(REG)})
#endif #endif

View File

@@ -31,7 +31,7 @@ void vm_execute(vm_t *vm)
} }
else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH_REGISTER)) else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_PUSH_REGISTER))
{ {
PUSH_REG_ROUTINES[instruction.opcode](vm, instruction.reg); PUSH_REG_ROUTINES[instruction.opcode](vm, instruction.operand.as_word);
vm->registers.ret = instruction.operand.as_word; vm->registers.ret = instruction.operand.as_word;
prog->ptr++; prog->ptr++;
} }
@@ -44,8 +44,9 @@ void vm_execute(vm_t *vm)
} }
else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_MOV)) else if (OPCODE_IS_TYPE(instruction.opcode, OP_TYPE_MOV))
{ {
MOV_ROUTINES[instruction.opcode](vm, instruction.operand, instruction.reg); data_t d =
vm->registers.ret = instruction.operand.as_word; MOV_ROUTINES[instruction.opcode](vm, instruction.operand.as_word);
vm->registers.ret = d.as_word; // will do type punning for me
prog->ptr++; prog->ptr++;
} }
else else
@@ -135,28 +136,43 @@ void vm_push_float_register(vm_t *vm, word reg)
vm_push_float(vm, DFLOAT(vm->registers.f[reg])); vm_push_float(vm, DFLOAT(vm->registers.f[reg]));
} }
void vm_mov_byte(vm_t *vm, data_t b, word reg) data_t vm_mov_byte(vm_t *vm, word reg)
{ {
if (reg >= VM_BYTE_REGISTERS) if (reg >= VM_BYTE_REGISTERS)
// TODO: Error (reg is not a valid byte register) // TODO: Error (reg is not a valid byte register)
return; return DBYTE(0);
vm->registers.b[reg] = b.as_byte; 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;
return ret;
} }
void vm_mov_word(vm_t *vm, data_t w, word reg) data_t vm_mov_word(vm_t *vm, word reg)
{ {
if (reg >= VM_WORD_REGISTERS) if (reg >= VM_WORD_REGISTERS)
// TODO: Error (reg is not a valid word register) // TODO: Error (reg is not a valid word register)
return; return DWORD(0);
vm->registers.w[reg] = w.as_word; else if (vm->stack.ptr < sizeof(word))
// TODO: Error (STACK UNDERFLOW)
return DWORD(0);
data_t ret = vm_pop_word(vm);
vm->registers.w[reg] = ret.as_word;
return ret;
} }
void vm_mov_float(vm_t *vm, data_t f, word reg) data_t vm_mov_float(vm_t *vm, word reg)
{ {
if (reg >= VM_FLOAT_REGISTERS) if (reg >= VM_WORD_REGISTERS)
// TODO: Error (reg is not a valid float register) // TODO: Error (reg is not a valid float register)
return; return DFLOAT(0);
vm->registers.f[reg] = f.as_float; else if (vm->stack.ptr < sizeof(f64))
// TODO: Error (STACK UNDERFLOW)
return DFLOAT(0);
data_t ret = vm_pop_float(vm);
vm->registers.f[reg] = ret.as_float;
return ret;
} }
data_t vm_pop_byte(vm_t *vm) data_t vm_pop_byte(vm_t *vm)

View File

@@ -69,11 +69,11 @@ static const push_reg_f PUSH_REG_ROUTINES[] = {
[OP_PUSH_FLOAT_REGISTER] = vm_push_float_register, [OP_PUSH_FLOAT_REGISTER] = vm_push_float_register,
}; };
void vm_mov_byte(vm_t *, data_t, word); data_t vm_mov_byte(vm_t *, word);
void vm_mov_word(vm_t *, data_t, word); data_t vm_mov_word(vm_t *, word);
void vm_mov_float(vm_t *, data_t, word); data_t vm_mov_float(vm_t *, word);
typedef void (*mov_f)(vm_t *, data_t, word); typedef data_t (*mov_f)(vm_t *, word);
static const mov_f MOV_ROUTINES[] = { static const mov_f MOV_ROUTINES[] = {
[OP_MOV_BYTE] = vm_mov_byte, [OP_MOV_BYTE] = vm_mov_byte,
[OP_MOV_WORD] = vm_mov_word, [OP_MOV_WORD] = vm_mov_word,