From c55b15cdfa02a026235149a0dd8b13bcc0c6443e Mon Sep 17 00:00:00 2001 From: zongor Date: Wed, 7 Jan 2026 23:44:32 -0800 Subject: [PATCH] add function test works, wip fibonacci --- arch/linux/tui/main.c | 57 ++++++++++++----- vm/vm.c | 146 +++++++++++++++++++++++------------------- vm/vm.h | 43 ++++++------- 3 files changed, 140 insertions(+), 106 deletions(-) diff --git a/arch/linux/tui/main.c b/arch/linux/tui/main.c index d42cd6f..26ddc0b 100644 --- a/arch/linux/tui/main.c +++ b/arch/linux/tui/main.c @@ -11,6 +11,7 @@ bool init_vm() { mem = lmem; memset(mem, 0, MEMORY_SIZE*sizeof(u8)); code = lcode; + sp = 0; mp = 0; cp = 0; pc = 0; @@ -30,32 +31,54 @@ u32 syscall(u32 id, u32 args, u32 mem_ptr) { return 1; // generic error } -i32 main() { - init_vm(); - - code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35); +void test_add_two_num() { + i32 main_local_count = 4; + mp += (4 * main_local_count); + code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 1); code[cp++] = ENCODE_B(OP_PUSH, 0, 0); - int fib = cp + 3; - code[cp++] = ENCODE_A(OP_CALL, fib, 7, 1); - code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_DBG_PRINT, 1, 0); + code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 1); + code[cp++] = ENCODE_B(OP_PUSH, 1, 0); + i32 add = cp + 4; + code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, add); + code[cp++] = ENCODE_A(OP_CALL, 2, 3, 3); + code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_DBG_PRINT, 1, 3); code[cp++] = ENCODE_A(OP_HALT, 0, 0, 0); - int base_case_if_false = cp + 2; + /* add */ + code[cp++] = ENCODE_A(OP_ADD_INT, 2, 1, 0); + code[cp++] = ENCODE_B(OP_RETURN, 2, 0); +} + +void test_fibonacci() { + /* fn main() */ + i32 main_local_count = 3; + mp += (4 * main_local_count); + code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35); + code[cp++] = ENCODE_B(OP_PUSH, 0, 0); + i32 fib = cp + 4; + code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, fib); + code[cp++] = ENCODE_A(OP_CALL, 1, 3, 2); + code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_DBG_PRINT, 1, 2); + code[cp++] = ENCODE_A(OP_HALT, 0, 0, 0); + + /* fn fib */ code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 2); - code[cp++] = ENCODE_A(OP_JLT_INT, base_case_if_false, 0, 1); - code[cp++] = ENCODE_B(OP_RETURN, 0, 0); + code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, fib); + code[cp++] = ENCODE_A(OP_JLT_INT, 2, 0, 1); code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 2); code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3); code[cp++] = ENCODE_B(OP_PUSH, 4, 0); - code[cp++] = ENCODE_A(OP_CALL, fib, 7, 5); + code[cp++] = ENCODE_A(OP_CALL, 2, 3, 2); - code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 1); - code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3); - code[cp++] = ENCODE_B(OP_PUSH, 4, 0); - code[cp++] = ENCODE_A(OP_CALL, fib, 7, 6); - code[cp++] = ENCODE_A(OP_ADD_INT, 7, 6, 5); - code[cp++] = ENCODE_B(OP_RETURN, 7, 0); + + code[cp++] = ENCODE_B(OP_RETURN, 0, 0); +} + +i32 main() { + init_vm(); + + test_add_two_num(); while(step_vm()) { // do stuff diff --git a/vm/vm.c b/vm/vm.c index 8c7b426..4d21035 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -1,11 +1,11 @@ #include "vm.h" - #define FRAME_HEADER_SIZE 12 u32 pc; /* program counter */ u32 cp; /* code pointer */ u32 mp; /* memory pointer */ u32 fp; /* frame pointer */ +u8 sp; /* child local count */ u32 flag; /* flag */ u8 interrupt; /* device interrupt */ u32 *code; /* code */ @@ -23,29 +23,27 @@ bool step_vm() { } case OP_CALL: { DECODE_A(instruction) - u32 fn_ptr, local_count, return_ptr; + u32 fn_ptr; - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = src1; u32 r2 = fp + src2; fn_ptr = READ_U32(rd); - local_count = READ_U32(r1); - return_ptr = READ_U32(r2); /* push parents frame value to reset the heap to */ WRITE_U32(mp, fp); mp += 4; /* push return address to child frame */ - WRITE_U32(mp, pc + 1); + WRITE_U32(mp, pc); mp += 4; /* push local address to return the value to */ - WRITE_U32(mp, return_ptr); + WRITE_U32(mp, r2); mp += 4; /* now set the frame pointer, where the locals start */ fp = mp; /* move mp by count many locals */ - mp += (4 * local_count); + mp += (4 * r1); /* jump to dest_ptr */ pc = fn_ptr; return true; @@ -53,17 +51,18 @@ bool step_vm() { case OP_RETURN: { DECODE_B(instruction) u32 i, size = 0; - u32 return_local = fp + dest; + u32 return_local = fp + (dest * 4); u32 return_value = READ_U32(return_local); - bool is_ptr = (((u16)(1)) << 15) & imm; - bool replaces_value = (((u16)(1)) << 14) & imm; + bool is_ptr = (((u32)(1)) << 15) & imm; + bool replaces_value = (((u32)(1)) << 14) & imm; /* reset mp to saved mp, use header size to get "real" start of frame */ u32 frame_start = fp - FRAME_HEADER_SIZE; u32 parent_fp = READ_U32(frame_start); u32 return_address = READ_U32(frame_start + 4); - u32 parent_local_return_address = READ_U32(frame_start + 8); + u32 parent_local_return_address = 4 * READ_U32(frame_start + 8); + USED(replaces_value); /* reset memory to parents end of memory */ mp = fp - FRAME_HEADER_SIZE; /* reset the frame pointer */ @@ -91,21 +90,21 @@ bool step_vm() { } case OP_SYSCALL: { DECODE_A(instruction) - u32 id = fp + dest; - u32 args = fp + src1; - u32 mem_ptr = fp + src2; - flag = syscall(id, args, mem_ptr); + u32 id = dest; + u32 args = src1; + u32 rd = fp + (src2 * 4); + flag = syscall(id, args, rd); return true; } case OP_LOAD_IMM: { DECODE_B(instruction) - u32 rd = fp + dest; + u32 rd = fp + (dest * 4); WRITE_U32(rd, imm); return true; } case OP_LOAD_UPPER_IMM: { DECODE_B(instruction) - u32 rd = fp + dest; + u32 rd = fp + (dest * 4); u32 value = READ_U32(rd); WRITE_U32(rd, (value | (((u32)(imm)) << 16))); return true; @@ -149,8 +148,8 @@ bool step_vm() { case OP_MEM_ALLOC: { DECODE_A(instruction) u32 size, ldest; - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); USED(src2); ldest = READ_U32(rd); WRITE_U32(ldest, mp); @@ -163,9 +162,9 @@ bool step_vm() { DECODE_A(instruction) u32 i, count, mdest, msrc; - u32 rd = fp + dest; - u32 r1 = fp + src1; - u32 r2 = fp + src2; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); + u32 r2 = fp + (src2 * 4); mdest = READ_U32(rd); msrc = READ_U32(r1); @@ -188,9 +187,9 @@ bool step_vm() { DECODE_A(instruction) u32 i, count, mdest, msrc; - u32 rd = fp + dest; - u32 r1 = fp + src1; - u32 r2 = fp + src2; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); + u32 r2 = fp + (src2 * 4); mdest = READ_U32(rd); msrc = READ_U32(r1); @@ -213,9 +212,9 @@ bool step_vm() { DECODE_A(instruction) u32 i, count, mdest, msrc; - u32 rd = fp + dest; - u32 r1 = fp + src1; - u32 r2 = fp + src2; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); + u32 r2 = fp + (src2 * 4); mdest = READ_U32(rd); msrc = READ_U32(r1); @@ -238,9 +237,9 @@ bool step_vm() { DECODE_A(instruction) u32 i, start, end; - u32 rd = fp + dest; - u32 r1 = fp + src1; - u32 r2 = fp + src2; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); + u32 r2 = fp + (src2 * 4); u8 value = (u8)READ_U32(r1); u32 count = READ_U32(r2); @@ -250,7 +249,7 @@ bool step_vm() { return true; } - start = rd; + start = READ_U32(rd); end = start + count; if (start >= mp || r2 > mp || end > mp) { @@ -269,9 +268,9 @@ bool step_vm() { DECODE_A(instruction) u32 i, start, end; - u32 rd = fp + dest; - u32 r1 = fp + src1; - u32 r2 = fp + src2; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); + u32 r2 = fp + (src2 * 4); u16 value = (u16)READ_U32(r1); u32 count = READ_U32(r2); @@ -281,7 +280,7 @@ bool step_vm() { return true; } - start = rd; + start = READ_U32(rd); end = start + count; if (start >= mp || r2 > mp || end > mp) { @@ -300,9 +299,9 @@ bool step_vm() { DECODE_A(instruction) u32 i, start, end; - u32 rd = fp + dest; - u32 r1 = fp + src1; - u32 r2 = fp + src2; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); + u32 r2 = fp + (src2 * 4); u32 value = READ_U32(r1); u32 count = READ_U32(r2); @@ -312,7 +311,7 @@ bool step_vm() { return true; } - start = rd; + start = READ_U32(rd); end = start + count; if (start >= mp || r2 > mp || end > mp) { @@ -329,13 +328,28 @@ bool step_vm() { } case OP_MOV: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); u32 value = READ_U32(r1); USED(src2); WRITE_U32(rd, value); return true; } + case OP_PUSH: { + DECODE_B(instruction) + u32 rd = fp + (dest * 4); + u32 val = READ_U32(rd); + USED(imm); + WRITE_U32((mp + (4 * (sp + 3))), val); + sp++; + return true; + } + case OP_POP: { + DECODE_C(instruction) + USED(imm); + mp -= 4; + return true; + } case OP_ADD_INT: { MATH_OP(i32, +); } @@ -368,9 +382,9 @@ bool step_vm() { } case OP_MUL_REAL: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; - u32 r2 = fp + src2; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); + u32 r2 = fp + (src2 * 4); i32 src1_whole = (i32)READ_U32(r1) >> 16; i32 src2_whole = (i32)READ_U32(r2) >> 16; @@ -389,9 +403,9 @@ bool step_vm() { case OP_DIV_REAL: { DECODE_A(instruction) i32 result; - u32 rd = fp + dest; - u32 r1 = fp + src1; - u32 r2 = fp + src2; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); + u32 r2 = fp + (src2 * 4); i32 src1_val = (i32)READ_U32(r1); i32 src2_val = (i32)READ_U32(r2); @@ -407,8 +421,8 @@ bool step_vm() { } case OP_INT_TO_REAL: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); i32 result = (i32)READ_U32(r1) << 16; USED(src2); WRITE_U32(rd, result); @@ -416,8 +430,8 @@ bool step_vm() { } case OP_INT_TO_NAT: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); u32 result = (u32)READ_U32(r1); USED(src2); WRITE_U32(rd, result); @@ -425,8 +439,8 @@ bool step_vm() { } case OP_NAT_TO_REAL: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); i32 result = ((i32)READ_U32(r1) << 16); USED(src2); WRITE_U32(rd, result); @@ -434,8 +448,8 @@ bool step_vm() { } case OP_NAT_TO_INT: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); i32 result = ((i32)READ_U32(r1)); USED(src2); WRITE_U32(rd, result); @@ -443,8 +457,8 @@ bool step_vm() { } case OP_REAL_TO_INT: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); i32 result = ((i32)READ_U32(r1) >> 16); USED(src2); WRITE_U32(rd, result); @@ -452,8 +466,8 @@ bool step_vm() { } case OP_REAL_TO_NAT: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); u32 result = ((u32)READ_U32(r1) >> 16); USED(src2); WRITE_U32(rd, result); @@ -484,7 +498,7 @@ bool step_vm() { } case OP_JMP_ABS: { DECODE_A(instruction) - u32 rd = fp + dest; + u32 rd = fp + (dest * 4); u32 jmp_dest = READ_U32(rd); if (jmp_dest > cp) { flag = 1; @@ -498,8 +512,8 @@ bool step_vm() { } case OP_JMP_OFF: { DECODE_A(instruction) - u32 rd = fp + dest; - u32 r1 = fp + src1; + u32 rd = fp + (dest * 4); + u32 r1 = fp + (src1 * 4); u32 jmp_dest = READ_U32(rd) + READ_U32(r1); if (jmp_dest > cp) { @@ -514,7 +528,7 @@ bool step_vm() { case OP_JMP_FLAG: { DECODE_A(instruction) u32 mask; - u32 rd = fp + dest; + u32 rd = fp + (dest * 4); u32 jmp_dest = READ_U32(rd); if (jmp_dest > cp) { flag = 1; diff --git a/vm/vm.h b/vm/vm.h index e4f0ecd..daf6e6e 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -67,6 +67,8 @@ typedef enum { OP_MEM_SET_16, /* memset_16 : A : memory[dest..dest+src2] = local[src1] as u16 */ OP_MEM_SET_32, /* memset_32 : A : memory[dest..dest+src2] = local[src1] as u32 */ OP_MOV, /* mov : A : locals[dest] = locals[src1] */ + OP_PUSH, /* push : B : push u32 value onto the childs locals */ + OP_POP, /* pop : C : pop u32 value off the stack (move MP back) */ OP_ADD_INT, /* add_int : A : locals[dest] = locals[src1] + locals[src2] */ OP_SUB_INT, /* sub_int : A : locals[dest] = locals[src1] - locals[src2] */ OP_MUL_INT, /* mul_int : A : locals[dest] = locals[src1] * locals[src2] */ @@ -125,6 +127,7 @@ extern u32 pc; /* program counter */ extern u32 cp; /* code pointer */ extern u32 mp; /* memory pointer */ extern u32 fp; /* frame pointer */ +extern u8 sp; /* child local count */ extern u32 flag; /* flag */ extern u8 interrupt; /* device interrupt */ extern u32 *code; /* code */ @@ -142,35 +145,29 @@ extern u8 *mem; /* memory */ #define WRITE_U8(addr, value) \ do { \ - if ((addr) < sizeof(mem)) { \ - mem[(addr)] = (value) & 0xFF; \ - } \ + mem[addr] = (value) & 0xFF; \ } while (0) #define WRITE_U16(addr, value) \ do { \ - if ((addr) + 1 < sizeof(mem)) { \ - mem[(addr)] = (value) & 0xFF; \ - mem[(addr) + 1] = ((value) >> 8) & 0xFF; \ - } \ + mem[addr] = (value) & 0xFF; \ + mem[addr + 1] = ((value) >> 8) & 0xFF; \ } while (0) #define WRITE_U32(addr, value) \ do { \ - if (addr + 3 < sizeof(mem)) { \ - mem[addr] = (value) & 0xFF; \ - mem[addr + 1] = ((value) >> 8) & 0xFF; \ - mem[addr + 2] = ((value) >> 16) & 0xFF; \ - mem[addr + 3] = ((value) >> 24) & 0xFF; \ - } \ + mem[addr] = (value) & 0xFF; \ + mem[addr + 1] = ((value) >> 8) & 0xFF; \ + mem[addr + 2] = ((value) >> 16) & 0xFF; \ + mem[addr + 3] = ((value) >> 24) & 0xFF; \ } while (0) #define MATH_OP(type, op) \ do { \ DECODE_A(instruction) \ - u32 rd = fp + dest; \ - u32 r1 = fp + src1; \ - u32 r2 = fp + src2; \ + u32 rd = fp + (dest * 4); \ + u32 r1 = fp + (src1 * 4); \ + u32 r2 = fp + (src2 * 4); \ type result = ((type)READ_U32(r1) op (type)READ_U32(r2)); \ mem[(rd)] = (result) & 0xFF; \ mem[(rd) + 1] = ((result) >> 8) & 0xFF; \ @@ -182,10 +179,10 @@ extern u8 *mem; /* memory */ #define MATH_OP_NO_CAST(op) \ do { \ DECODE_A(instruction) \ - u32 rd = fp + dest; \ - u32 r1 = fp + src1; \ - u32 r2 = fp + src2; \ - WRITE_U32(rd, (READ_U32(r1) op READ_U32(r2))); \ + u32 rd = fp + (dest * 4); \ + u32 r1 = fp + (src1 * 4); \ + u32 r2 = fp + (src2 * 4); \ + WRITE_U32(rd, (READ_U32(r1) op READ_U32(r2))); \ return true; \ } while (0) @@ -196,9 +193,9 @@ extern u8 *mem; /* memory */ u32 mask, target; \ type value; \ type value2; \ - u32 rd = fp + dest; \ - u32 r1 = fp + src1; \ - u32 r2 = fp + src2; \ + u32 rd = fp + (dest * 4); \ + u32 r1 = fp + (src1 * 4); \ + u32 r2 = fp + (src2 * 4); \ target = READ_U32(rd); \ value = (type)READ_U32(r1); \ value2 = (type)READ_U32(r2); \