aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/runtime.c120
-rw-r--r--src/runtime.h84
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