From 89ef3948881362e88907ab94037ef0d5d20b630e Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 18 Oct 2025 14:54:13 -0700 Subject: [PATCH] normalize naming, add memory offset opcodes --- docs/paint.ul | 32 +++---- src/arch/emscripten/devices.c | 2 - src/arch/linux/devices.c | 2 - src/arch/linux/main.c | 85 ----------------- src/tools/assembler.c | 155 ++++++++++++++++++++---------- src/vm/common.h | 2 +- src/vm/opcodes.h | 174 ++++++++++++++++++---------------- src/vm/str.c | 6 +- src/vm/str.h | 2 +- src/vm/vm.c | 138 +++++++++++++++++++++------ src/vm/vm.h | 2 +- test/paint-bw.asm.lisp | 49 ++++------ test/paint.asm.lisp | 65 +++++-------- test/window.asm.lisp | 35 +++---- 14 files changed, 377 insertions(+), 372 deletions(-) diff --git a/docs/paint.ul b/docs/paint.ul index b7e2269..0365d05 100755 --- a/docs/paint.ul +++ b/docs/paint.ul @@ -53,23 +53,23 @@ function main() { screen.draw(); loop { - mouse.read(); - if (not mouse.left) continue; + mouse.read(); + if (not mouse.left) continue; - int box_size = 20; - int x = 1; - int y = 1; - byte color = BLACK; - outlined_swatch(screen, color, x, y); - set_color(box_size, x, y, mouse.x, mouse.y, color); + int box_size = 20; + int x = 1; + int y = 1; + byte color = BLACK; + outlined_swatch(screen, color, x, y); + set_color(box_size, x, y, mouse.x, mouse.y, color); - color = WHITE; - x = 21; - outlined_swatch(screen, color, x, y); - set_color(box_size, x, y, mouse.x, mouse.y, color); - screen.draw(); + color = WHITE; + x = 21; + outlined_swatch(screen, color, x, y); + set_color(box_size, x, y, mouse.x, mouse.y, color); + screen.draw(); - rectangle(screen, selected_color, x, y, 5, 5); + rectangle(screen, selected_color, x, y, 5, 5); } exit(0); } @@ -97,7 +97,7 @@ function set_color(int box_size, int bx, int by, int mx, int my, byte color) { function outline_swatch(ref Device screen, byte color, int x, int y) { byte bg_color = GRAY; if (selected_color == color) { - bg_color = DARK_GRAY; + bg_color = DARK_GRAY; } rectangle(screen, bg_color, x, y, 20, 20); @@ -109,7 +109,7 @@ function outline_swatch(ref Device screen, byte color, int x, int y) { * Draw a rectanlge */ function rectangle(ref Device screen, byte color, int x, int y, int width, int height) { - int pixel = y * width + x + &screen.buffer + 4; + int pixel = y * width + x + screen.buffer.ptr + 4; do (int i = height; i > 0; i--) { int row = pixel + width; screen.set(row, color, width); diff --git a/src/arch/emscripten/devices.c b/src/arch/emscripten/devices.c index 84ef507..2d58703 100644 --- a/src/arch/emscripten/devices.c +++ b/src/arch/emscripten/devices.c @@ -55,8 +55,6 @@ i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) { ScreenDeviceData *screen = (ScreenDeviceData *)data; screen->handle = handle; - printf("handle=%d, size=%d\n", handle, size); - u8 *info = (u8 *)buffer; memcpy(&info[0], &screen->handle, sizeof(u32)); memcpy(&info[4], &screen->width, sizeof(u32)); diff --git a/src/arch/linux/devices.c b/src/arch/linux/devices.c index 877ef32..fb85cb8 100644 --- a/src/arch/linux/devices.c +++ b/src/arch/linux/devices.c @@ -54,8 +54,6 @@ i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) { ScreenDeviceData *screen = (ScreenDeviceData *)data; screen->handle = handle; - printf("handle=%d, size=%d\n", handle, size); - u8 *info = (u8 *)buffer; memcpy(&info[0], &screen->handle, sizeof(u32)); memcpy(&info[4], &screen->width, sizeof(u32)); diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index d4e0a7d..04eb012 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -147,9 +147,6 @@ bool compileAndSave(const char *source_file, const char *output_file, VM *vm) { printf("Parse failed.\n"); return false; } else { -#ifdef ASM_DEBUG - expr_print(ast, 0); -#endif assemble(vm, ast); expr_free(ast); @@ -237,88 +234,6 @@ void repl(VM *vm) { exit(0); } -#ifdef ASM_DEBUG -const char *opcode_to_string(Opcode op) { - static const char *names[] = {[OP_HALT] = "halt", - [OP_JMP] = "jump", - [OP_JMPF] = "jump-if-flag", - [OP_CALL] = "call", - [OP_RETURN] = "return", - [OP_LOAD] = "load", - [OP_LOAD_REG] = "get", - [OP_LOAD_REG8] = "get-8", - [OP_LOADI8] = "load-i8", - [OP_LOADU8] = "load-u8", - [OP_LOADI16] = "load-i16", - [OP_LOADU16] = "load-u16", - [OP_LOAD_IMM] = "load-immediate", - [OP_MALLOC] = "malloc", - [OP_STORE] = "store", - [OP_STORE8] = "store-8", - [OP_STORE16] = "store-16", - [OP_PUSH] = "push", - [OP_POP] = "pop", - [OP_REG_MOV] = "register-move", - [OP_SYSCALL] = "syscall", - [OP_SLL] = "bit-shift-left", - [OP_SRL] = "bit-shift-right", - [OP_SRE] = "bit-shift-right-extend", - [OP_BAND] = "bit-and", - [OP_BOR] = "bit-or", - [OP_BXOR] = "bit-xor", - [OP_ADD_INT] = "add-int", - [OP_SUB_INT] = "sub-int", - [OP_MUL_INT] = "mul-int", - [OP_DIV_INT] = "div-int", - [OP_ADD_UINT] = "add-nat", - [OP_SUB_UINT] = "sub-nat", - [OP_MUL_UINT] = "mul-nat", - [OP_DIV_UINT] = "div-nat", - [OP_ADD_REAL] = "add-real", - [OP_SUB_REAL] = "sub-real", - [OP_MUL_REAL] = "mul-real", - [OP_DIV_REAL] = "div-real", - [OP_INT_TO_REAL] = "int-to-real", - [OP_UINT_TO_REAL] = "nat-to-real", - [OP_REAL_TO_INT] = "real-to-int", - [OP_REAL_TO_UINT] = "real-to-nat", - [OP_JEQ_INT] = "jump-eq-int", - [OP_JGT_INT] = "jump-gt-int", - [OP_JLT_INT] = "jump-lt-int", - [OP_JLE_INT] = "jump-le-int", - [OP_JGE_INT] = "jump-ge-int", - [OP_JEQ_UINT] = "jump-eq-nat", - [OP_JGT_UINT] = "jump-gt-nat", - [OP_JLT_UINT] = "jump-lt-nat", - [OP_JLE_UINT] = "jump-le-nat", - [OP_JGE_UINT] = "jump-ge-nat", - [OP_JEQ_REAL] = "jump-eq-real", - [OP_JGE_REAL] = "jump-ge-real", - [OP_JGT_REAL] = "jump-gt-real", - [OP_JLT_REAL] = "jump-lt-real", - [OP_JLE_REAL] = "jump-le-real", - [OP_STRLEN] = "string-length", - [OP_STREQ] = "string-eq", - [OP_STRCAT] = "string-concat", - [OP_STR_GET_CHAR] = "string-get-char", - [OP_STR_FIND_CHAR] = "string-find-char", - [OP_STR_SLICE] = "string-slice", - [OP_INT_TO_STRING] = "int-to-string", - [OP_UINT_TO_STRING] = "nat-to-string", - [OP_REAL_TO_STRING] = "real-to-string", - [OP_STRING_TO_INT] = "string-to-int", - [OP_STRING_TO_UINT] = "string-to-nat", - [OP_STRING_TO_REAL] = "string-to-real"}; - - if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) { - return ""; - } - - const char *name = names[op]; - return name ? name : ""; -} -#endif - i32 main(i32 argc, char *argv[]) { bool gui_mode = false; bool dump_rom = false; diff --git a/src/tools/assembler.c b/src/tools/assembler.c index e659ccc..c9b5305 100644 --- a/src/tools/assembler.c +++ b/src/tools/assembler.c @@ -79,16 +79,16 @@ int get_instruction_byte_size(ExprNode *node) { return 2; } - if (strcmp(opname, "int-to-string") == 0 || strcmp(opname, "get-8") == 0 || - strcmp(opname, "nat-to-string") == 0 || strcmp(opname, "get-16") == 0 || - strcmp(opname, "real-to-string") == 0 || strcmp(opname, "get") == 0 || - strcmp(opname, "int-to-real") == 0 || strcmp(opname, "put-8") == 0 || - strcmp(opname, "nat-to-real") == 0 || strcmp(opname, "put-16") == 0 || - strcmp(opname, "real-to-int") == 0 || strcmp(opname, "put") == 0 || + if (strcmp(opname, "int-to-string") == 0 || strcmp(opname, "load-indirect-8") == 0 || + strcmp(opname, "nat-to-string") == 0 || strcmp(opname, "load-indirect-16") == 0 || + strcmp(opname, "real-to-string") == 0 || strcmp(opname, "load-indirect-32") == 0 || + strcmp(opname, "int-to-real") == 0 || strcmp(opname, "store-indirect-8") == 0 || + strcmp(opname, "nat-to-real") == 0 || strcmp(opname, "store-indirect-16") == 0 || + strcmp(opname, "real-to-int") == 0 || strcmp(opname, "store-indirect-32") == 0 || strcmp(opname, "real-to-nat") == 0 || strcmp(opname, "nat-to-int") == 0 || strcmp(opname, "int-to-nat") == 0 || - strcmp(opname, "string-length") == 0 || strcmp(opname, "store") == 0 || - strcmp(opname, "store-8") == 0 || strcmp(opname, "store-16") == 0 || + strcmp(opname, "string-length") == 0 || strcmp(opname, "store-absolute-32") == 0 || + strcmp(opname, "store-absolute-8") == 0 || strcmp(opname, "store-absolute-16") == 0 || strcmp(opname, "memset") == 0 || strcmp(opname, "memset") == 0 || strcmp(opname, "memset-8") == 0 || strcmp(opname, "memset-16") == 0 || strcmp(opname, "register-move") == 0 || strcmp(opname, "malloc") == 0) { @@ -101,8 +101,7 @@ int get_instruction_byte_size(ExprNode *node) { strcmp(opname, "add-nat") == 0 || strcmp(opname, "sub-nat") == 0 || strcmp(opname, "mul-nat") == 0 || strcmp(opname, "div-nat") == 0 || strcmp(opname, "add-real") == 0 || strcmp(opname, "sub-real") == 0 || - strcmp(opname, "bit-shift-left") == 0 || - strcmp(opname, "bit-shift-right") == 0 || + strcmp(opname, "bit-shift-left") == 0 || strcmp(opname, "bit-shift-right") == 0 || strcmp(opname, "bit-and") == 0 || strcmp(opname, "bit-or") == 0 || strcmp(opname, "bit-xor") == 0 || strcmp(opname, "mul-real") == 0 || strcmp(opname, "div-real") == 0) { @@ -116,8 +115,8 @@ int get_instruction_byte_size(ExprNode *node) { } // Load, Load-immediate (6 bytes: 1 + 1 + 4) - if (strcmp(opname, "load") == 0 || strcmp(opname, "load-immediate") == 0 || - strcmp(opname, "load-16") == 0 || strcmp(opname, "load-8") == 0) { + if (strcmp(opname, "load-absolute-32") == 0 || strcmp(opname, "load-immediate") == 0 || + strcmp(opname, "load-absolute-16") == 0 || strcmp(opname, "load-absolute-8") == 0) { return 6; } @@ -139,7 +138,13 @@ int get_instruction_byte_size(ExprNode *node) { strcmp(opname, "jump-gt-real") == 0 || strcmp(opname, "jump-lt-real") == 0 || strcmp(opname, "jump-le-real") == 0 || - strcmp(opname, "jump-ge-real") == 0) { + strcmp(opname, "jump-ge-real") == 0 || + strcmp(opname, "store-offset-8") == 0 || + strcmp(opname, "store-offset-16") == 0 || + strcmp(opname, "store-offset-32") == 0 || + strcmp(opname, "load-offset-8") == 0 || + strcmp(opname, "load-offset-16") == 0 || + strcmp(opname, "load-offset-32") == 0) { return 7; } @@ -440,38 +445,38 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { u32 addr = resolve_symbol(table, node->children[1]->token); emit_byte(vm, reg); emit_u32(vm, addr); - } else if (strcmp(opname, "load-8") == 0) { - emit_opcode(vm, OP_LOAD_8); + } else if (strcmp(opname, "load-absolute-8") == 0) { + emit_opcode(vm, OP_LOAD_ABS_8); int dest = parse_register(node->children[0]->token); u32 addr = resolve_symbol(table, node->children[1]->token); emit_byte(vm, dest); emit_u32(vm, addr); - } else if (strcmp(opname, "load-16") == 0) { - emit_opcode(vm, OP_LOAD_8); + } else if (strcmp(opname, "load-absolute-16") == 0) { + emit_opcode(vm, OP_LOAD_ABS_16); int dest = parse_register(node->children[0]->token); u32 addr = resolve_symbol(table, node->children[1]->token); emit_byte(vm, dest); emit_u32(vm, addr); - } else if (strcmp(opname, "load") == 0) { - emit_opcode(vm, OP_LOAD_8); + } else if (strcmp(opname, "load-absolute-32") == 0) { + emit_opcode(vm, OP_LOAD_ABS_32); int dest = parse_register(node->children[0]->token); u32 addr = resolve_symbol(table, node->children[1]->token); emit_byte(vm, dest); emit_u32(vm, addr); - } else if (strcmp(opname, "get-8") == 0) { - emit_opcode(vm, OP_GET_8); + } else if (strcmp(opname, "load-indirect-8") == 0) { + emit_opcode(vm, OP_LOAD_IND_8); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); - } else if (strcmp(opname, "get-16") == 0) { - emit_opcode(vm, OP_GET_16); + } else if (strcmp(opname, "load-indirect-16") == 0) { + emit_opcode(vm, OP_LOAD_IND_16); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); - } else if (strcmp(opname, "get") == 0) { - emit_opcode(vm, OP_GET_32); + } else if (strcmp(opname, "load-indirect-32") == 0) { + emit_opcode(vm, OP_LOAD_IND_32); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); @@ -506,42 +511,90 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, dest); emit_byte(vm, value); emit_byte(vm, count); - } else if (strcmp(opname, "store-8") == 0) { - emit_opcode(vm, OP_STORE_8); + } else if (strcmp(opname, "store-absolute-8") == 0) { + emit_opcode(vm, OP_STORE_ABS_8); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); - } else if (strcmp(opname, "store-16") == 0) { - emit_opcode(vm, OP_STORE_16); + } else if (strcmp(opname, "store-absolute-16") == 0) { + emit_opcode(vm, OP_STORE_ABS_16); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); - } else if (strcmp(opname, "store") == 0) { - emit_opcode(vm, OP_STORE_32); + } else if (strcmp(opname, "store-absolute-32") == 0) { + emit_opcode(vm, OP_STORE_ABS_32); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); - } else if (strcmp(opname, "put-8") == 0) { - emit_opcode(vm, OP_PUT_8); + } else if (strcmp(opname, "store-indirect-8") == 0) { + emit_opcode(vm, OP_STORE_IND_8); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); - } else if (strcmp(opname, "put-16") == 0) { - emit_opcode(vm, OP_PUT_16); + } else if (strcmp(opname, "store-indirect-16") == 0) { + emit_opcode(vm, OP_STORE_IND_16); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); - } else if (strcmp(opname, "put") == 0) { - emit_opcode(vm, OP_PUT_32); + } else if (strcmp(opname, "store-indirect-32") == 0) { + emit_opcode(vm, OP_STORE_IND_32); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); emit_byte(vm, dest); emit_byte(vm, src1); + } else if (strcmp(opname, "store-offset-8") == 0) { + emit_opcode(vm, OP_STORE_OFF_8); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + u32 addr = resolve_symbol(table, node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_u32(vm, addr); + } else if (strcmp(opname, "store-offset-16") == 0) { + emit_opcode(vm, OP_STORE_OFF_16); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + u32 addr = resolve_symbol(table, node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_u32(vm, addr); + } else if (strcmp(opname, "store-offset-32") == 0) { + emit_opcode(vm, OP_STORE_OFF_32); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + u32 addr = resolve_symbol(table, node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_u32(vm, addr); + } else if (strcmp(opname, "load-offset-8") == 0) { + emit_opcode(vm, OP_LOAD_OFF_8); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + u32 addr = resolve_symbol(table, node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_u32(vm, addr); + } else if (strcmp(opname, "load-offset-16") == 0) { + emit_opcode(vm, OP_LOAD_OFF_16); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + u32 addr = resolve_symbol(table, node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_u32(vm, addr); + } else if (strcmp(opname, "load-offset-32") == 0) { + emit_opcode(vm, OP_LOAD_OFF_32); + int dest = parse_register(node->children[0]->token); + int src1 = parse_register(node->children[1]->token); + u32 addr = resolve_symbol(table, node->children[2]->token); + emit_byte(vm, dest); + emit_byte(vm, src1); + emit_u32(vm, addr); } else if (strcmp(opname, "push") == 0) { emit_opcode(vm, OP_PUSH); int reg = parse_register(node->children[0]->token); @@ -663,7 +716,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "add-nat") == 0) { - emit_opcode(vm, OP_ADD_UINT); + emit_opcode(vm, OP_ADD_NAT); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -671,7 +724,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "sub-nat") == 0) { - emit_opcode(vm, OP_SUB_UINT); + emit_opcode(vm, OP_SUB_NAT); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -679,7 +732,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "mul-nat") == 0) { - emit_opcode(vm, OP_MUL_UINT); + emit_opcode(vm, OP_MUL_NAT); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -687,7 +740,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "div-nat") == 0) { - emit_opcode(vm, OP_DIV_UINT); + emit_opcode(vm, OP_DIV_NAT); int dest = parse_register(node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -733,7 +786,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, dest); emit_byte(vm, src); } else if (strcmp(opname, "nat-to-real") == 0) { - emit_opcode(vm, OP_UINT_TO_REAL); + emit_opcode(vm, OP_NAT_TO_REAL); int dest = parse_register(node->children[0]->token); int src = parse_register(node->children[1]->token); emit_byte(vm, dest); @@ -745,7 +798,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, dest); emit_byte(vm, src); } else if (strcmp(opname, "real-to-nat") == 0) { - emit_opcode(vm, OP_REAL_TO_UINT); + emit_opcode(vm, OP_REAL_TO_NAT); int dest = parse_register(node->children[0]->token); int src = parse_register(node->children[1]->token); emit_byte(vm, dest); @@ -799,7 +852,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "jump-eq-nat") == 0) { - emit_opcode(vm, OP_JEQ_UINT); + emit_opcode(vm, OP_JEQ_NAT); u32 addr = resolve_symbol(table, node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -807,7 +860,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "jump-neq-nat") == 0) { - emit_opcode(vm, OP_JNEQ_UINT); + emit_opcode(vm, OP_JNEQ_NAT); u32 addr = resolve_symbol(table, node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -815,7 +868,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "jump-gt-nat") == 0) { - emit_opcode(vm, OP_JGT_UINT); + emit_opcode(vm, OP_JGT_NAT); u32 addr = resolve_symbol(table, node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -823,7 +876,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "jump-lt-nat") == 0) { - emit_opcode(vm, OP_JLT_UINT); + emit_opcode(vm, OP_JLT_NAT); u32 addr = resolve_symbol(table, node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -831,7 +884,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "jump-le-nat") == 0) { - emit_opcode(vm, OP_JLE_UINT); + emit_opcode(vm, OP_JLE_NAT); u32 addr = resolve_symbol(table, node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -839,7 +892,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, src1); emit_byte(vm, src2); } else if (strcmp(opname, "jump-ge-nat") == 0) { - emit_opcode(vm, OP_JGE_UINT); + emit_opcode(vm, OP_JGE_NAT); u32 addr = resolve_symbol(table, node->children[0]->token); int src1 = parse_register(node->children[1]->token); int src2 = parse_register(node->children[2]->token); @@ -949,7 +1002,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, dest); emit_byte(vm, src); } else if (strcmp(opname, "nat-to-string") == 0) { - emit_opcode(vm, OP_UINT_TO_STRING); + emit_opcode(vm, OP_NAT_TO_STRING); int dest = parse_register(node->children[0]->token); int src = parse_register(node->children[1]->token); emit_byte(vm, dest); @@ -967,7 +1020,7 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) { emit_byte(vm, dest); emit_byte(vm, src); } else if (strcmp(opname, "string-to-nat") == 0) { - emit_opcode(vm, OP_STRING_TO_UINT); + emit_opcode(vm, OP_STRING_TO_NAT); int dest = parse_register(node->children[0]->token); int src = parse_register(node->children[1]->token); emit_byte(vm, dest); diff --git a/src/vm/common.h b/src/vm/common.h index 3a3d579..14750d3 100644 --- a/src/vm/common.h +++ b/src/vm/common.h @@ -20,6 +20,6 @@ typedef int32_t i32; #define USED(x) ((void)(x)) #define AS_INT(v) ((i32)(v)) -#define AS_UINT(v) ((u32)(v)) +#define AS_NAT(v) ((u32)(v)) #endif diff --git a/src/vm/opcodes.h b/src/vm/opcodes.h index a589c30..71838d7 100644 --- a/src/vm/opcodes.h +++ b/src/vm/opcodes.h @@ -4,84 +4,90 @@ #include "common.h" typedef enum { - OP_HALT, /* halt : terminate execution with code [src1] */ - OP_JMP, /* jump : jump to address dest unconditionally */ - OP_JMPF, /* jump-if-flag : jump to address dest if flag is ne 0 */ - OP_CALL, /* call : creates a new frame */ - OP_RETURN, /* return : returns from a frame to the parent frame */ - OP_LOAD_IMM, /* load-immediate : dest = constant */ - OP_GET_8, /* get-8 : dest = memory[registers[src1]] as u8 */ - OP_GET_16, /* get-16 : dest = memory[registers[src1]] as u8 */ - OP_GET_32, /* get : dest = memory[registers[src1]] as u32 */ - OP_LOAD_8, /* load-8 : dest = memory[src1 as u32] */ - OP_LOAD_16, /* load-16 : dest = memory[src1 as u32] */ - OP_LOAD_32, /* load : dest = memory[src1 as u32] */ - OP_STORE_8, /* store-8 : memory[dest] = src1 << 8 */ - OP_STORE_16, /* store-16 : memory[dest] = src1 << 16 */ - OP_STORE_32, /* store : memory[dest] = src1 */ - OP_PUT_8, /* put-8 : memory[dest] = registers[src1] << 8 */ - OP_PUT_16, /* put-16 : memory[dest] = registers[src1] << 16*/ - OP_PUT_32, /* put : memory[dest] = registers[src1] */ - OP_MALLOC, /* malloc : dest = fat ptr to memory of ((src1 as size) + 4) */ - OP_MEMSET_8, /* memset-8 : dest <-> dest+count = src1 as u8 */ - OP_MEMSET_16, /* memset-16 : dest <-> dest+count = src1 as u8 */ - OP_MEMSET_32, /* memset-32 : dest <-> dest+count = src1 as u32 */ - OP_PUSH, /* push : push const of ref */ - OP_POP, /* pop : pop cosnt or ref */ - OP_REG_MOV, /* register-move : dest = src1 */ - OP_SYSCALL, /* syscall : src1 src2 src3 src4 more? does a system call based on args */ - OP_SLL, /* bit-shift-left : dest = src1 << src2 */ - OP_SRL, /* bit-shift-right : dest = src1 >> src2 */ - OP_SRE, /* bit-shift-re : dest as i32 = src1 >> src2 */ - OP_BAND, /* bit-and : dest = src1 & src2 */ - OP_BOR, /* bit-or : dest = src1 | src2 */ - OP_BXOR, /* bit-xor : dest = src1 ^ src2 */ - OP_ADD_INT, /* add-int : dest = src1 + src2 */ - OP_SUB_INT, /* sub-int : dest = src1 - src2 */ - OP_MUL_INT, /* mul-int : dest = src1 * src2 */ - OP_DIV_INT, /* div-int : dest = src1 / src2 */ - OP_ADD_UINT, /* add-nat : dest = src1 + src2 */ - OP_SUB_UINT, /* sub-nat : dest = src1 - src2 */ - OP_MUL_UINT, /* mul-nat : dest = src1 * src2 */ - OP_DIV_UINT, /* div-nat : dest = src1 / src2 */ - OP_ADD_REAL, /* add-real : dest = src1 + src2 */ - OP_SUB_REAL, /* sub-real : dest = src1 - src2 */ - OP_MUL_REAL, /* mul-real : dest = src1 * src2 */ - OP_DIV_REAL, /* div-real : dest = src1 / src2 */ - OP_INT_TO_REAL, /* int-to-real : dest = src1 as real */ - OP_UINT_TO_REAL, /* nat-to-real : dest = src1 as real */ - OP_REAL_TO_INT, /* real-to-int : dest = src1 as int */ - OP_REAL_TO_UINT, /* real-to-nat : dest = src1 as uint */ - OP_JEQ_INT, /* jump-eq-int : jump to address dest if src1 as int == src2 as int */ - OP_JNEQ_INT, /* jump-neq-int : jump to address dest if src1 as int != src2 as int */ - OP_JGT_INT, /* jump-gt-int : jump to address dest if src1 as int > src2 as int */ - OP_JLT_INT, /* jump-lt-int : jump to address dest if src1 as int < src2 as int */ - OP_JLE_INT, /* jump-le-int : jump to address dest if src1 as int <= src2 as int */ - OP_JGE_INT, /* jump-ge-int : jump to address dest if src1 as int >= src2 as int */ - OP_JEQ_UINT, /* jump-eq-nat : jump to address dest if src1 as uint == src2 as uint */ - OP_JNEQ_UINT, /* jump-neq-nat : jump to address dest if src1 as uint != src2 as uint */ - OP_JGT_UINT, /* jump-gt-nat : jump to address dest if src1 as uint > src2 as uint */ - OP_JLT_UINT, /* jump-lt-nat : jump to address dest if src1 as uint < src2 as uint */ - OP_JLE_UINT, /* jump-le-nat : jump to address dest if src1 as uint <= src2 as uint */ - OP_JGE_UINT, /* jump-ge-nat : jump to address dest if src1 as uint >= src2 as uint */ - OP_JEQ_REAL, /* jump-eq-real : jump to address dest if src1 as real == src2 as real */ - OP_JNEQ_REAL, /* jump-neq-real : jump to address dest if src1 as real != src2 as real */ - OP_JGE_REAL, /* jump-ge-real : jump to address dest if src1 as real >= src2 as real */ - OP_JGT_REAL, /* jump-gt-real : jump to address dest if src1 as real > src2 as real */ - OP_JLT_REAL, /* jump-lt-real : jump to address dest if src1 as real < src2 as real */ - OP_JLE_REAL, /* jump-le-real : jump to address dest if src1 as real <= src2 as real */ - OP_STRLEN, /* string-length : dest = length of str at src1 ptr */ - OP_STREQ, /* string-eq : dest = src1 ptr string == src2 ptr string */ - OP_STRCAT, /* string-concat : dest = ptr of src1 ptr string + src2 ptr string */ - OP_STR_GET_CHAR, /* string-get-char : dest = ptr of src1 ptr str, src2 index of str */ - OP_STR_FIND_CHAR, /* string-find-char : dest = ptr of src1 ptr string, src2 uint8 char */ - OP_STR_SLICE, /* string-slice : dest = ptr of src1 ptr str, src2 start index, src3 end index */ - OP_INT_TO_STRING, /* int-to-string : dest = src1 as str */ - OP_UINT_TO_STRING, /* nat-to-string : dest = src1 as str */ - OP_REAL_TO_STRING, /* real-to-string : dest = src1 as str */ - OP_STRING_TO_INT, /* string-to-int : dest = src1 as int */ - OP_STRING_TO_UINT, /* string-to-nat : dest = src1 as uint */ - OP_STRING_TO_REAL /* string-to-real : dest = src1 as real */ + OP_HALT, /* halt : terminate execution with code [src1] */ + OP_JMP, /* jump : jump to address dest unconditionally */ + OP_JMPF, /* jump-if-flag : jump to address dest if flag is ne 0 */ + OP_CALL, /* call : creates a new frame */ + OP_RETURN, /* return : returns from a frame to the parent frame */ + OP_LOAD_IMM, /* load-immediate : registers[dest] = constant */ + OP_LOAD_IND_8, /* load-indirect-8 : registers[dest] = memory[registers[src1]] as u8 */ + OP_LOAD_IND_16, /* load-indirect-16 : registers[dest] = memory[registers[src1]] as u8 */ + OP_LOAD_IND_32, /* load-indirect-32 : registers[dest] = memory[registers[src1]] as u32 */ + OP_LOAD_ABS_8, /* load-absolute-8 : registers[dest] = memory[src1 as u32] */ + OP_LOAD_ABS_16, /* load-absolute-16 : registers[dest] = memory[src1 as u32] */ + OP_LOAD_ABS_32, /* load-absolute-32 : registers[dest] = memory[src1 as u32] */ + OP_LOAD_OFF_8, /* load-offset-8 : registers[dest] = memory[registers[src1] + offset] as u8 */ + OP_LOAD_OFF_16, /* load-offset-16 : registers[dest] = memory[registers[src1] + offset] as u16 */ + OP_LOAD_OFF_32, /* load-offset-32 : registers[dest] = memory[registers[src1] + offset] as u32 */ + OP_STORE_ABS_8, /* store-absolute-8 : memory[dest] = src1 && 0xFF */ + OP_STORE_ABS_16, /* store-absolute-16 : memory[dest] = src1 && 0xFFFF */ + OP_STORE_ABS_32, /* store-absolute-32 : memory[dest] = src1 */ + OP_STORE_IND_8, /* store-indirect-8 : memory[dest] = registers[src1] && 0xFF */ + OP_STORE_IND_16, /* store-indirect-16 : memory[dest] = registers[src1] && 0xFFFF*/ + OP_STORE_IND_32, /* store-indirect-32 : memory[dest] = registers[src1] */ + OP_STORE_OFF_8, /* store-offset-8 : memory[registers[dest] + offset] = registers[src1] && 0xFF */ + OP_STORE_OFF_16, /* store-offset-16 : memory[registers[dest] + offset] = registers[src1] && 0xFFFF */ + OP_STORE_OFF_32, /* store-offset-32 : memory[registers[dest] + offset] = registers[src1] */ + OP_MALLOC, /* malloc : dest = fat ptr to memory of ((src1 as size) + 4) */ + OP_MEMSET_8, /* memset-8 : dest <-> dest+count = src1 as u8 */ + OP_MEMSET_16, /* memset-16 : dest <-> dest+count = src1 as u8 */ + OP_MEMSET_32, /* memset-32 : dest <-> dest+count = src1 as u32 */ + OP_PUSH, /* push : push const or ref */ + OP_POP, /* pop : pop cosnt or ref */ + OP_REG_MOV, /* register-move : dest = src1 */ + OP_SYSCALL, /* syscall : src1 src2 src3 src4 more? does a system call based on args */ + OP_SLL, /* bit-shift-left : registers[dest] = registers[src1] << registers[src2] */ + OP_SRL, /* bit-shift-right : registers[dest] = registers[src1] >> registers[src2] */ + OP_SRE, /* bit-shift-re : registers[dest] as i32 = registers[src1] >> registers[src2] */ + OP_BAND, /* bit-and : registers[dest] = registers[src1] & registers[src2] */ + OP_BOR, /* bit-or : registers[dest] = registers[src1] | registers[src2] */ + OP_BXOR, /* bit-xor : registers[dest] = registers[src1] ^ registers[src2] */ + OP_ADD_INT, /* add-int : registers[dest] = registers[src1] + registers[src2] */ + OP_SUB_INT, /* sub-int : registers[dest] = registers[src1] - registers[src2] */ + OP_MUL_INT, /* mul-int : registers[dest] = registers[src1] * registers[src2] */ + OP_DIV_INT, /* div-int : registers[dest] = registers[src1] / registers[src2] */ + OP_ADD_NAT, /* add-nat : registers[dest] = registers[src1] + registers[src2] */ + OP_SUB_NAT, /* sub-nat : registers[dest] = registers[src1] - registers[src2] */ + OP_MUL_NAT, /* mul-nat : registers[dest] = registers[src1] * registers[src2] */ + OP_DIV_NAT, /* div-nat : registers[dest] = registers[src1] / registers[src2] */ + OP_ADD_REAL, /* add-real : registers[dest] = registers[src1] + registers[src2] */ + OP_SUB_REAL, /* sub-real : registers[dest] = registers[src1] - registers[src2] */ + OP_MUL_REAL, /* mul-real : registers[dest] = registers[src1] * registers[src2] */ + OP_DIV_REAL, /* div-real : registers[dest] = registers[src1] / registers[src2] */ + OP_INT_TO_REAL, /* int-to-real : registers[dest] = registers[src1] as real */ + OP_NAT_TO_REAL, /* nat-to-real : registers[dest] = registers[src1] as real */ + OP_REAL_TO_INT, /* real-to-int : registers[dest] = registers[src1] as int */ + OP_REAL_TO_NAT, /* real-to-nat : registers[dest] = registers[src1] as nat */ + OP_JEQ_INT, /* jump-eq-int : jump to address dest if registers[src1] as int == registers[src2] as int */ + OP_JNEQ_INT, /* jump-neq-int : jump to address dest if registers[src1] as int != registers[src2] as int */ + OP_JGT_INT, /* jump-gt-int : jump to address dest if registers[src1] as int > registers[src2] as int */ + OP_JLT_INT, /* jump-lt-int : jump to address dest if registers[src1] as int < registers[src2] as int */ + OP_JLE_INT, /* jump-le-int : jump to address dest if registers[src1] as int <= registers[src2] as int */ + OP_JGE_INT, /* jump-ge-int : jump to address dest if registers[src1] as int >= registers[src2] as int */ + OP_JEQ_NAT, /* jump-eq-nat : jump to address dest if registers[src1] as nat == registers[src2] as nat */ + OP_JNEQ_NAT, /* jump-neq-nat : jump to address dest if registers[src1] as nat != registers[src2] as nat */ + OP_JGT_NAT, /* jump-gt-nat : jump to address dest if registers[src1] as nat > registers[src2] as nat */ + OP_JLT_NAT, /* jump-lt-nat : jump to address dest if registers[src1] as nat < registers[src2] as nat */ + OP_JLE_NAT, /* jump-le-nat : jump to address dest if registers[src1] as nat <= registers[src2] as nat */ + OP_JGE_NAT, /* jump-ge-nat : jump to address dest if registers[src1] as nat >= registers[src2] as nat */ + OP_JEQ_REAL, /* jump-eq-real : jump to address dest if registers[src1] as real == registers[src2] as real */ + OP_JNEQ_REAL, /* jump-neq-real : jump to address dest if registers[src1] as real != registers[src2] as real */ + OP_JGE_REAL, /* jump-ge-real : jump to address dest if registers[src1] as real >= registers[src2] as real */ + OP_JGT_REAL, /* jump-gt-real : jump to address dest if registers[src1] as real > registers[src2] as real */ + OP_JLT_REAL, /* jump-lt-real : jump to address dest if registers[src1] as real < registers[src2] as real */ + OP_JLE_REAL, /* jump-le-real : jump to address dest if registers[src1] as real <= registers[src2] as real */ + OP_STRLEN, /* string-length : registers[dest] = length of str at src1 ptr */ + OP_STREQ, /* string-eq : registers[dest] = src1 ptr string == src2 ptr string */ + OP_STRCAT, /* string-concat : registers[dest] = ptr of src1 ptr string + src2 ptr string */ + OP_STR_GET_CHAR, /* string-get-char : registers[dest] = ptr of src1 ptr str, src2 index of str */ + OP_STR_FIND_CHAR, /* string-find-char : registers[dest] = ptr of src1 ptr string, src2 nat8 char */ + OP_STR_SLICE, /* string-slice : registers[dest] = ptr of src1 ptr str, src2 start index, src3 end index */ + OP_INT_TO_STRING, /* int-to-string : registers[dest] = src1 as str */ + OP_NAT_TO_STRING, /* nat-to-string : registers[dest] = src1 as str */ + OP_REAL_TO_STRING, /* real-to-string : registers[dest] = src1 as str */ + OP_STRING_TO_INT, /* string-to-int : registers[dest] = src1 as int */ + OP_STRING_TO_NAT, /* string-to-nat : registers[dest] = src1 as nat */ + OP_STRING_TO_REAL /* string-to-real : registers[dest] = src1 as real */ } Opcode; #define MAX_REGS 32 @@ -94,11 +100,11 @@ typedef struct frame_s { typedef enum { SYSCALL_EXIT = 0, - SYSCALL_DEVICE_OPEN, /* */ - SYSCALL_DEVICE_READ, /* */ - SYSCALL_DEVICE_WRITE, /* */ - SYSCALL_DEVICE_CLOSE, /* */ - SYSCALL_DEVICE_IOCTL /* */ + SYSCALL_DEVICE_OPEN, + SYSCALL_DEVICE_READ, + SYSCALL_DEVICE_WRITE, + SYSCALL_DEVICE_CLOSE, + SYSCALL_DEVICE_IOCTL } SyscallID; typedef struct device_ops_s { @@ -121,7 +127,7 @@ typedef struct device_s { DeviceOps *ops; /* operations vtable */ u32 flags; /* permissions, status, etc. */ u32 handle; /* id for fast access in VM */ - u32 size; /* id for fast access in VM */ + u32 size; /* id for fast access in VM */ } Device; #define MEMORY_SIZE (640 * 480 + 65536) diff --git a/src/vm/str.c b/src/vm/str.c index 8dc736e..5f5173d 100644 --- a/src/vm/str.c +++ b/src/vm/str.c @@ -63,7 +63,7 @@ char *write_digits_backwards(u32 value, char *buf_end, char *buf_start) { return p; } -void uint_to_string(u32 value, char *buffer) { +void nat_to_string(u32 value, char *buffer) { char temp[16]; char *start; char *end = temp + sizeof(temp) - 1; @@ -118,8 +118,8 @@ void fixed_to_string(i32 value, char *buffer) { value = -value; } - int_part = AS_UINT(value >> 16); - frac_part = AS_UINT(value & 0xFFFF); + int_part = AS_NAT(value >> 16); + frac_part = AS_NAT(value & 0xFFFF); /* Convert fractional part to 5 decimal digits */ frac_digits = (frac_part * 100000U) / 65536U; diff --git a/src/vm/str.h b/src/vm/str.h index 684756c..ccd9db3 100644 --- a/src/vm/str.h +++ b/src/vm/str.h @@ -7,7 +7,7 @@ bool streq(const char *s1, const char *s2); i32 strcopy(char* to, const char *from, u32 length); u32 strlength(const char *str); u32 strnlength(const char *str, u32 max_len); -void uint_to_string(u32 value, char *buffer); +void nat_to_string(u32 value, char *buffer); void int_to_string(i32 value, char *buffer); void fixed_to_string(i32 value, char *buffer); diff --git a/src/vm/vm.c b/src/vm/vm.c index bb12524..a24e80f 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -213,7 +213,7 @@ bool step_vm(VM *vm) { frame->registers[dest] = v; return true; } - case OP_LOAD_32: { + case OP_LOAD_ABS_32: { dest = read_u8(vm, code, vm->pc); vm->pc++; ptr = read_u32(vm, code, vm->pc); @@ -222,7 +222,7 @@ bool step_vm(VM *vm) { frame->registers[dest] = v; return true; } - case OP_LOAD_16: { + case OP_LOAD_ABS_16: { dest = read_u8(vm, code, vm->pc); vm->pc++; ptr = read_u32(vm, code, vm->pc); @@ -231,7 +231,7 @@ bool step_vm(VM *vm) { frame->registers[dest] = v; return true; } - case OP_LOAD_8: { + case OP_LOAD_ABS_8: { dest = read_u8(vm, code, vm->pc); vm->pc++; ptr = read_u32(vm, code, vm->pc); @@ -240,7 +240,7 @@ bool step_vm(VM *vm) { frame->registers[dest] = v; return true; } - case OP_GET_32: { + case OP_LOAD_IND_32: { dest = read_u8(vm, code, vm->pc); vm->pc++; src1 = read_u8(vm, code, vm->pc); @@ -250,7 +250,7 @@ bool step_vm(VM *vm) { frame->registers[dest] = ptr; return true; } - case OP_GET_16: { + case OP_LOAD_IND_16: { u16 v16; dest = read_u8(vm, code, vm->pc); vm->pc++; @@ -261,7 +261,7 @@ bool step_vm(VM *vm) { frame->registers[dest] = v16; return true; } - case OP_GET_8: { + case OP_LOAD_IND_8: { u8 v8; dest = read_u8(vm, code, vm->pc); vm->pc++; @@ -272,7 +272,48 @@ bool step_vm(VM *vm) { frame->registers[dest] = v8; return true; } - case OP_STORE_32: { + case OP_LOAD_OFF_8: { + u32 offset; + u8 v8; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + offset = read_u32(vm, code, vm->pc); + vm->pc += 4; + v = frame->registers[src1]; + v8 = read_u8(vm, memory, (v + offset)); + frame->registers[dest] = v8; + return true; + } + case OP_LOAD_OFF_16: { + u32 offset; + u16 v16; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + offset = read_u32(vm, code, vm->pc); + vm->pc += 4; + v = frame->registers[src1]; + v16 = read_u16(vm, memory, (v + offset)); + frame->registers[dest] = v16; + return true; + } + case OP_LOAD_OFF_32: { + u32 offset; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + offset = read_u32(vm, code, vm->pc); + vm->pc += 4; + v = frame->registers[src1]; + ptr = read_u32(vm, memory, (v + offset)); + frame->registers[dest] = ptr; + return true; + } + case OP_STORE_ABS_32: { dest = read_u8(vm, code, vm->pc); vm->pc++; src1 = read_u8(vm, code, vm->pc); @@ -282,7 +323,7 @@ bool step_vm(VM *vm) { write_u32(vm, memory, ptr, v); return true; } - case OP_STORE_16: { + case OP_STORE_ABS_16: { dest = read_u8(vm, code, vm->pc); vm->pc++; src1 = read_u8(vm, code, vm->pc); @@ -292,7 +333,7 @@ bool step_vm(VM *vm) { write_u16(vm, memory, ptr, v); return true; } - case OP_STORE_8: { + case OP_STORE_ABS_8: { dest = read_u8(vm, code, vm->pc); vm->pc++; src1 = read_u8(vm, code, vm->pc); @@ -302,7 +343,7 @@ bool step_vm(VM *vm) { write_u8(vm, memory, ptr, v); return true; } - case OP_PUT_32: { + case OP_STORE_IND_32: { dest = read_u8(vm, code, vm->pc); vm->pc++; src1 = read_u8(vm, code, vm->pc); @@ -312,7 +353,7 @@ bool step_vm(VM *vm) { write_u32(vm, memory, ptr, v); return true; } - case OP_PUT_16: { + case OP_STORE_IND_16: { u16 v16; dest = read_u8(vm, code, vm->pc); vm->pc++; @@ -323,7 +364,7 @@ bool step_vm(VM *vm) { write_u16(vm, memory, ptr, v16); return true; } - case OP_PUT_8: { + case OP_STORE_IND_8: { u8 v8; dest = read_u8(vm, code, vm->pc); vm->pc++; @@ -334,6 +375,47 @@ bool step_vm(VM *vm) { write_u8(vm, memory, ptr, v8); return true; } + case OP_STORE_OFF_8: { + u32 offset; + u8 v8; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + offset = read_u32(vm, code, vm->pc); + vm->pc += 4; + ptr = frame->registers[dest]; + v8 = frame->registers[src1]; + write_u8(vm, memory, (ptr + offset), v8); + return true; + } + case OP_STORE_OFF_16: { + u32 offset; + u16 v16; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + offset = read_u32(vm, code, vm->pc); + vm->pc += 4; + ptr = frame->registers[dest]; + v16 = frame->registers[src1]; + write_u16(vm, memory, (ptr + offset), v16); + return true; + } + case OP_STORE_OFF_32: { + u32 offset; + dest = read_u8(vm, code, vm->pc); + vm->pc++; + src1 = read_u8(vm, code, vm->pc); + vm->pc++; + offset = read_u32(vm, code, vm->pc); + vm->pc += 4; + ptr = frame->registers[dest]; + v = frame->registers[src1]; + write_u32(vm, memory, (ptr + offset), v); + return true; + } case OP_PUSH: { dest = read_u8(vm, code, vm->pc); vm->pc++; @@ -538,13 +620,13 @@ bool step_vm(VM *vm) { MATH_OP(i32, *); case OP_DIV_INT: MATH_OP(i32, /); - case OP_ADD_UINT: + case OP_ADD_NAT: MATH_OP(u32, +); - case OP_SUB_UINT: + case OP_SUB_NAT: MATH_OP(u32, -); - case OP_MUL_UINT: + case OP_MUL_NAT: MATH_OP(u32, *); - case OP_DIV_UINT: + case OP_DIV_NAT: MATH_OP(u32, /); case OP_MUL_REAL: { dest = read_u8(vm, code, vm->pc); @@ -614,7 +696,7 @@ bool step_vm(VM *vm) { frame->registers[dest] = (frame->registers[src1] << 16); return true; } - case OP_REAL_TO_UINT: { + case OP_REAL_TO_NAT: { dest = read_u8(vm, code, vm->pc); vm->pc++; src1 = read_u8(vm, code, vm->pc); @@ -623,11 +705,11 @@ bool step_vm(VM *vm) { if (value < 0) { frame->registers[dest] = 0; } else { - frame->registers[dest] = AS_UINT(value >> 16); + frame->registers[dest] = AS_NAT(value >> 16); } return true; } - case OP_UINT_TO_REAL: { + case OP_NAT_TO_REAL: { dest = read_u8(vm, code, vm->pc); vm->pc++; src1 = read_u8(vm, code, vm->pc); @@ -635,22 +717,22 @@ bool step_vm(VM *vm) { frame->registers[dest] = AS_INT(frame->registers[src1] << 16); return true; } - case OP_JEQ_UINT: { + case OP_JEQ_NAT: { COMPARE_AND_JUMP(u32, ==); } - case OP_JNEQ_UINT: { + case OP_JNEQ_NAT: { COMPARE_AND_JUMP(u32, !=); } - case OP_JGT_UINT: { + case OP_JGT_NAT: { COMPARE_AND_JUMP(u32, >); } - case OP_JLT_UINT: { + case OP_JLT_NAT: { COMPARE_AND_JUMP(u32, <); } - case OP_JLE_UINT: { + case OP_JLE_NAT: { COMPARE_AND_JUMP(u32, <=); } - case OP_JGE_UINT: { + case OP_JGE_NAT: { COMPARE_AND_JUMP(u32, >=); } case OP_JEQ_INT: { @@ -700,13 +782,13 @@ bool step_vm(VM *vm) { frame->registers[dest] = ptr; return true; } - case OP_UINT_TO_STRING: { + case OP_NAT_TO_STRING: { char buffer[32]; dest = read_u8(vm, code, vm->pc); vm->pc++; src1 = read_u8(vm, code, vm->pc); vm->pc++; - uint_to_string(frame->registers[src1], buffer); + nat_to_string(frame->registers[src1], buffer); ptr = str_alloc(vm, frame, buffer, strlength(buffer)); frame->registers[dest] = ptr; return true; @@ -755,7 +837,7 @@ bool step_vm(VM *vm) { /* not implemented yet */ return false; } - case OP_STRING_TO_UINT: { + case OP_STRING_TO_NAT: { /* not implemented yet */ return false; } diff --git a/src/vm/vm.h b/src/vm/vm.h index 45462f1..2898ed0 100644 --- a/src/vm/vm.h +++ b/src/vm/vm.h @@ -7,6 +7,6 @@ bool step_vm(VM *vm); u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length); void fixed_to_string(i32 value, char *buffer); void int_to_string(i32 value, char *buffer); -void uint_to_string(u32 value, char *buffer); +void nat_to_string(u32 value, char *buffer); #endif diff --git a/test/paint-bw.asm.lisp b/test/paint-bw.asm.lisp index 91e0298..57cf5d9 100644 --- a/test/paint-bw.asm.lisp +++ b/test/paint-bw.asm.lisp @@ -6,18 +6,9 @@ (load-immediate $11 0) (syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags) - (load-immediate $1 4) ; offset for handle - (add-nat $19 $18 $1) - (get $0 $19) ; load handle - - (load-immediate $1 8) ; offset for width - (add-nat $19 $18 $1) - (get $20 $19) ; load width - - (load-immediate $1 12) ; offset for size - (add-nat $19 $18 $1) - (get $22 $19) ; load size - + (load-offset-32 $0 $18 4) ; load handle + (load-offset-32 $20 $18 8) ; load width + (load-offset-32 $22 $18 12) ; load size (load-immediate $1 16) ; offset for screen buffer (add-nat $21 $18 $1) @@ -25,14 +16,12 @@ (load-immediate $16 &mouse-namespace) (syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags) - (load-immediate $1 4) ; offset for handle - (add-nat $19 $15 $1) - (get $16 $19) ; load handle + (load-offset-32 $16 $15 4) ; load handle ; outline_swatch(screen, BLACK, 1, 1); (push $21) (push $20) - (load $1 &BLACK) + (load-absolute-32 $1 &BLACK) (push $1) (load-immediate $12 1) (push $12) @@ -43,7 +32,7 @@ ; outline_swatch(screen, WHITE, 1, 1); (push $21) (push $20) - (load $1 &WHITE) + (load-absolute-32 $1 &WHITE) (push $1) (load-immediate $12 21) (push $12) @@ -58,25 +47,19 @@ (label draw-loop ; load mouse click data (syscall READ $16 $2 $3 $15) - (load-immediate $5 16) ; offset for btn1 - (add-nat $6 $15 $5) - (get-8 $9 $6) ; load btn1 pressed + (load-offset-8 $9 $15 16) ; load btn1 pressed (jump-eq-nat &draw-loop $9 $11) - (load-immediate $5 8) ; offset for x - (add-nat $6 $5 $2) - (get $7 $6) ; load x - (load-immediate $5 12) ; offset for y - (add-nat $6 $5 $2) - (get $8 $6) ; load y + (load-offset-32 $7 $2 8) ; load x + (load-offset-32 $8 $2 12) ; load y (load-immediate $14 20) ; box size ; first row (push $21) (push $20) - (load $1 &BLACK) + (load-absolute-32 $1 &BLACK) (push $1) (load-immediate $12 1) (push $12) @@ -94,7 +77,7 @@ (push $21) (push $20) - (load $1 &WHITE) + (load-absolute-32 $1 &WHITE) (push $1) (load-immediate $12 21) (push $12) @@ -112,7 +95,7 @@ (syscall WRITE $0 $21 $22) - (load $22 &SELECTED-COLOR) ; color + (load-absolute-32 $22 &SELECTED-COLOR) ; color (load-immediate $1 5) ; size of brush (push $21) ;base @@ -151,7 +134,7 @@ (jump-gt-int &fail $1 $7) (load-immediate $10 &SELECTED-COLOR) - (store-8 $10 $11) + (store-absolute-8 $10 $11) (label fail) (return)) @@ -164,12 +147,12 @@ (pop $21) ; Constants - (load $4 &GRAY) - (load $10 &SELECTED-COLOR) + (load-absolute-32 $4 &GRAY) + (load-absolute-32 $10 &SELECTED-COLOR) (jump-eq-int &set-selected $10 $1) (jump-eq-int &end-set-selected $4 $4) (label set-selected) - (load $4 &DARK-GRAY) + (load-absolute-32 $4 &DARK-GRAY) (label end-set-selected) (load-immediate $5 20) ; outline size diff --git a/test/paint.asm.lisp b/test/paint.asm.lisp index 06c772b..c49938d 100644 --- a/test/paint.asm.lisp +++ b/test/paint.asm.lisp @@ -6,18 +6,9 @@ (load-immediate $11 0) (syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags) - (load-immediate $1 4) ; offset for handle - (add-nat $19 $18 $1) - (get $0 $19) ; load handle - - (load-immediate $1 8) ; offset for width - (add-nat $19 $18 $1) - (get $20 $19) ; load width - - (load-immediate $1 12) ; offset for size - (add-nat $19 $18 $1) - (get $22 $19) ; load size - + (load-offset-32 $0 $18 4) ; load handle + (load-offset-32 $20 $18 8) ; load width + (load-offset-32 $22 $18 12) ; load size (load-immediate $1 16) ; offset for screen buffer (add-nat $21 $18 $1) @@ -25,14 +16,12 @@ (load-immediate $16 &mouse-namespace) (syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags) - (load-immediate $1 4) ; offset for handle - (add-nat $19 $15 $1) - (get $16 $19) ; load handle + (load-offset-32 $16 $15 4) ; load handle ; outline_swatch(screen, BLACK, 1, 1); (push $21) (push $20) - (load $1 &BLACK) + (load-absolute-32 $1 &BLACK) (push $1) (load-immediate $12 1) (push $12) @@ -43,7 +32,7 @@ ; outline_swatch(screen, WHITE, 1, 1); (push $21) (push $20) - (load $1 &WHITE) + (load-absolute-32 $1 &WHITE) (push $1) (load-immediate $12 21) (push $12) @@ -58,25 +47,19 @@ (label draw-loop ; load mouse click data (syscall READ $16 $2 $3 $15) - (load-immediate $5 16) ; offset for btn1 - (add-nat $6 $15 $5) - (get-8 $9 $6) ; load btn1 pressed + (load-offset-8 $9 $15 16) ; load btn1 pressed (jump-eq-nat &draw-loop $9 $11) - (load-immediate $5 8) ; offset for x - (add-nat $6 $5 $2) - (get $7 $6) ; load x - (load-immediate $5 12) ; offset for y - (add-nat $6 $5 $2) - (get $8 $6) ; load y + (load-offset-32 $7 $2 8) ; load x + (load-offset-32 $8 $2 12) ; load y (load-immediate $14 20) ; box size ; first row (push $21) (push $20) - (load $1 &BLACK) + (load-absolute-32 $1 &BLACK) (push $1) (load-immediate $12 1) (push $12) @@ -94,7 +77,7 @@ (push $21) (push $20) - (load $1 &WHITE) + (load-absolute-32 $1 &WHITE) (push $1) (load-immediate $12 21) (push $12) @@ -113,7 +96,7 @@ ; row 2 (push $21) (push $20) - (load $1 &CHARCOAL) + (load-absolute-32 $1 &CHARCOAL) (push $1) (load-immediate $12 1) (push $12) @@ -131,7 +114,7 @@ (push $21) (push $20) - (load $1 &DARK-GRAY) + (load-absolute-32 $1 &DARK-GRAY) (push $1) (load-immediate $12 21) (push $12) @@ -150,7 +133,7 @@ ; row 3 (push $21) (push $20) - (load $1 &RED) + (load-absolute-32 $1 &RED) (push $1) (load-immediate $12 1) (push $12) @@ -168,7 +151,7 @@ (push $21) (push $20) - (load $1 &ORANGE) + (load-absolute-32 $1 &ORANGE) (push $1) (load-immediate $12 21) (push $12) @@ -187,7 +170,7 @@ ; row 3 (push $21) (push $20) - (load $1 &YELLOW) + (load-absolute-32 $1 &YELLOW) (push $1) (load-immediate $12 1) (push $12) @@ -205,7 +188,7 @@ (push $21) (push $20) - (load $1 &GREEN) + (load-absolute-32 $1 &GREEN) (push $1) (load-immediate $12 21) (push $12) @@ -224,7 +207,7 @@ ; row 4 (push $21) (push $20) - (load $1 &BLUE) + (load-absolute-32 $1 &BLUE) (push $1) (load-immediate $12 1) (push $12) @@ -242,7 +225,7 @@ (push $21) (push $20) - (load $1 &PURPLE) + (load-absolute-32 $1 &PURPLE) (push $1) (load-immediate $12 21) (push $12) @@ -260,7 +243,7 @@ (syscall WRITE $0 $21 $22) - (load $22 &SELECTED-COLOR) ; color + (load-absolute-32 $22 &SELECTED-COLOR) ; color (load-immediate $1 5) ; size of brush (push $21) ;base @@ -299,7 +282,7 @@ (jump-gt-int &fail $1 $7) (load-immediate $10 &SELECTED-COLOR) - (store-8 $10 $11) + (store-absolute-8 $10 $11) (label fail) (return)) @@ -312,12 +295,12 @@ (pop $21) ; Constants - (load $4 &GRAY) - (load $10 &SELECTED-COLOR) + (load-absolute-32 $4 &GRAY) + (load-absolute-32 $10 &SELECTED-COLOR) (jump-eq-int &set-selected $10 $1) (jump-eq-int &end-set-selected $4 $4) (label set-selected) - (load $4 &DARK-GRAY) + (load-absolute-32 $4 &DARK-GRAY) (label end-set-selected) (load-immediate $5 20) ; outline size diff --git a/test/window.asm.lisp b/test/window.asm.lisp index 350b98a..53c81e4 100644 --- a/test/window.asm.lisp +++ b/test/window.asm.lisp @@ -10,27 +10,21 @@ (load-immediate $0 &screen-namespace) (syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags) - (load-immediate $1 4) ; offset for handle - (add-nat $19 $18 $1) - (get $0 $19) ; load handle + (load-offset-32 $0 $18 4) ; load handle (nat-to-string $5 $0) (push $32) (push $5) (call &pln) - (load-immediate $1 8) ; offset for width - (add-nat $19 $18 $1) - (get $20 $19) ; load width + (load-offset-32 $20 $18 8) ; load width (nat-to-string $5 $20) (push $32) (push $5) (call &pln) - (load-immediate $1 12) ; offset for size - (add-nat $19 $18 $1) - (get $22 $19) ; load size + (load-offset-32 $22 $18 12) ; load size (nat-to-string $5 $22) (push $32) @@ -56,7 +50,7 @@ (push $32) (push $5) (call &pln) - (get $16 $19) ; load handle + (load-indirect-32 $16 $19) ; load handle (syscall WRITE $0 $21 $22) ; redraw @@ -64,18 +58,13 @@ (label draw-loop ; load mouse click data (syscall READ $16 $2 $3 $15) - (load-immediate $5 16) ; offset for btn1 - (add-nat $6 $15 $5) - (get-8 $9 $6) ; load btn1 pressed + + (load-offset-8 $9 $15 16) ; load btn1 pressed (jump-eq-nat &draw-loop $9 $11) - (load-immediate $5 8) ; offset for x - (add-nat $6 $5 $2) - (get $7 $6) ; load x - (load-immediate $5 12) ; offset for y - (add-nat $6 $5 $2) - (get $8 $6) ; load y + (load-offset-32 $7 $2 8) ; load x + (load-offset-32 $8 $2 12) ; load y ; Compute start address: y*width + x (mul-nat $30 $8 $20) ; $15 = y * width @@ -84,8 +73,8 @@ (load-immediate $1 4) ; need to add offset for fat pointer size (add-nat $30 $30 $1) - (load $3 &WHITE) ; color - (store-8 $30 $3) ; draw color at screen [x,y] + (load-absolute-32 $3 &WHITE) ; color + (store-absolute-8 $30 $3) ; draw color at screen [x,y] (syscall WRITE $0 $21 $22) ; redraw (jump &draw-loop)) @@ -95,9 +84,7 @@ (pop $1) (pop $0) - (load-immediate $5 4) ; offset for handle - (add-nat $6 $0 $5) - (get $7 $6) ; load handle + (load-offset-32 $7 $0 4) ; load handle (string-length $2 $1) (syscall WRITE $7 $1 $2)