From d0f1f5274281b976a911e5cb694ccbf31fb2147c Mon Sep 17 00:00:00 2001 From: zongor Date: Wed, 11 Feb 2026 23:19:26 -0800 Subject: [PATCH] Add static frames, no performance gain --- arch/linux/tui/main.c | 28 +++++++++++------- vm/vm.c | 68 +++++++++++++++++-------------------------- vm/vm.h | 29 ++++++++++++------ 3 files changed, 64 insertions(+), 61 deletions(-) diff --git a/arch/linux/tui/main.c b/arch/linux/tui/main.c index 7be250f..0350bea 100644 --- a/arch/linux/tui/main.c +++ b/arch/linux/tui/main.c @@ -1,20 +1,28 @@ #include "../../../vm/vm.h" #include +#define STACK_SIZE 1024 #define CODE_SIZE 8192 #define MEMORY_SIZE 65536 u8 lmem[MEMORY_SIZE] = {0}; u32 lcode[CODE_SIZE] = {0}; +Frame lframes[STACK_SIZE] = {0}; + +void reset() { + pc = 0; + cp = 0; + mp = 0; + fp = 0; + sp = 0; + interrupt = 0; + status = 0; +} bool init_vm() { mem = lmem; code = lcode; - lc = 0; - mp = 0; - cp = 0; - pc = 0; - interrupt = 0; - status = 0; + frames = lframes; + reset(); return true; } @@ -60,7 +68,7 @@ void test_add_two_num() { i32 add = cp + 5; code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, add); - code[cp++] = ENCODE_A(OP_CALL, 2, 3, 0); + code[cp++] = ENCODE_A(OP_CALL, 2, 0, 0); code[cp++] = ENCODE_A(OP_INT_TO_STR, 4, 3, 0); code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 4); code[cp++] = ENCODE_A(OP_HALT, 0, 0, 0); @@ -80,7 +88,7 @@ void test_fibonacci() { code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35); code[cp++] = ENCODE_B(OP_PARG, 0, 0); code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, fib); - code[cp++] = ENCODE_A(OP_CALL, 1, 9, 2); + code[cp++] = ENCODE_A(OP_CALL, 1, 2, 0); /* print */ code[cp++] = ENCODE_A(OP_INT_TO_STR, 3, 2, 0); code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 3); @@ -93,11 +101,11 @@ void test_fibonacci() { code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 2); code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3); code[cp++] = ENCODE_B(OP_PARG, 4, 0); - code[cp++] = ENCODE_A(OP_CALL, 8, 9, 5); + code[cp++] = ENCODE_A(OP_CALL, 8, 5, 0); code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 1); code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3); code[cp++] = ENCODE_B(OP_PARG, 4, 0); - code[cp++] = ENCODE_A(OP_CALL, 8, 9, 6); + code[cp++] = ENCODE_A(OP_CALL, 8, 6, 0); 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); diff --git a/vm/vm.c b/vm/vm.c index e371ceb..d17a4e2 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -1,15 +1,17 @@ #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 lc; /* child local count */ -u8 status; /* status flag */ -u8 interrupt; /* device interrupt */ -u32 *code; /* code */ -u8 *mem; /* memory */ +u32 *stack; /* stack */ +u32 sp; /* stack pointer */ +u32 *code; /* code */ +u32 cp; /* code pointer */ +u8 *mem; /* memory */ +u32 mp; /* memory pointer */ +Frame *frames; /* call frames */ +u32 fp; /* frame pointer */ +u32 pc; /* program counter */ +u8 status; /* status flag */ +u8 interrupt; /* device interrupt */ #define MAX_LEN_INT32 11 const char radix_set[11] = "0123456789"; @@ -28,7 +30,7 @@ u32 str_alloc(char *str, u32 length) { bool step_vm() { u32 instruction = code[pc++]; u8 opcode = DECODE_OP(instruction); - u32 *locals = (u32*)(&mem[fp]); + u32 *locals = frames[fp].locals; u32 *globals = (u32*)(mem); switch (opcode) { @@ -40,22 +42,10 @@ bool step_vm() { DECODE_A(instruction) /* function to jump to */ u32 fn_ptr = locals[dest]; - /* get mp in 'global indexing mode' */ - u32 *header = &globals[mp / 4]; - /* reset child locals counter */ - lc = 0; - /* push parents frame value to reset the heap to */ - (*header++) = fp; - /* push return address to child frame */ - (*header++) = pc; - /* push local address to return the value to */ - (*header++) = fp + (src2 * 4); - /* increase the mp to new size */ - mp += FRAME_HEADER_SIZE; - /* now set the frame pointer, where the locals start */ - fp = mp; - /* move mp forward by count many locals */ - mp += (src1 * 4); + frames[fp].return_reg = src1; + frames[fp].return_pc = pc; + frames[fp++].start_mp = mp; + USED(src2); /* jump to dest_ptr */ pc = fn_ptr; return true; @@ -68,21 +58,18 @@ bool step_vm() { bool replaces_value = (((u32)(1)) << 14) & imm; /* reset mp to saved mp, use header size to get "real" start of frame */ - u32 *frame_start = &globals[(fp / 4) - 3]; - u32 parent_fp = *frame_start++; - u32 return_address = *frame_start++; - u32 parent_local_return_address = *frame_start++; + u32 return_pc = frames[--fp].return_pc; + u32 return_mp = frames[fp].start_mp; + u32 parent_local_return_address = frames[fp].return_reg; + mp = return_mp; + pc = return_pc; USED(replaces_value); - /* reset memory to parents end of memory */ - mp = fp - FRAME_HEADER_SIZE; - /* reset the frame pointer */ - fp = parent_fp; if (parent_local_return_address != 255) { if (is_ptr) { /* copy value to end of mp if it is a pointer */ - globals[parent_local_return_address/4] = mp; + frames[fp].locals[parent_local_return_address] = mp; size = globals[return_value/4]; globals[mp/4] = size; mp += 4; @@ -90,12 +77,10 @@ bool step_vm() { mp += size; } else { /* otherwise just write the return value to its location */ - globals[(parent_local_return_address / 4)] = return_value; + frames[fp].locals[parent_local_return_address] = return_value; } } - /* jump to parent frame */ - pc = return_address; return true; } case OP_SYSCALL: { @@ -105,10 +90,9 @@ bool step_vm() { return true; } case OP_PARG: { - DECODE_B(instruction) - USED(imm); - globals[(mp / 4) + lc + 3] = locals[dest]; - lc++; + DECODE_A(instruction) + USED(src2); + frames[fp + 1].locals[src1] = locals[dest]; return true; } case OP_LOAD_IMM: { diff --git a/vm/vm.h b/vm/vm.h index 18e50d7..0572c24 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -122,15 +122,26 @@ typedef enum { SYSCALL_MAX } Syscall; -extern u32 pc; /* program counter */ -extern u32 cp; /* code pointer */ -extern u32 mp; /* memory pointer */ -extern u32 fp; /* frame pointer */ -extern u8 lc; /* child local count */ -extern u8 status; /* status flag */ -extern u8 interrupt; /* device interrupt */ -extern u32 *code; /* code */ -extern u8 *mem; /* memory */ +typedef struct frame_s Frame; +struct frame_s { + u32 locals[256]; + u32 return_pc; + u32 start_mp; + u8 return_reg; +}; + +extern u32 *code; /* code */ +extern u32 cp; /* code pointer */ +extern u8 *mem; /* memory */ +extern u32 mp; /* memory pointer */ +extern u32 *stack; /* stack */ +extern u32 sp; /* stack pointer */ +extern Frame *frames; /* call frames */ +extern u32 fp; /* frame pointer */ +extern u32 pc; /* program counter */ +extern u8 status; /* status flag */ +extern u8 interrupt; /* device interrupt */ + #define READ_U8(addr) (mem[addr])