Add static frames, no performance gain
This commit is contained in:
parent
7fdd4b66b0
commit
d0f1f52742
|
|
@ -1,20 +1,28 @@
|
||||||
#include "../../../vm/vm.h"
|
#include "../../../vm/vm.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define STACK_SIZE 1024
|
||||||
#define CODE_SIZE 8192
|
#define CODE_SIZE 8192
|
||||||
#define MEMORY_SIZE 65536
|
#define MEMORY_SIZE 65536
|
||||||
u8 lmem[MEMORY_SIZE] = {0};
|
u8 lmem[MEMORY_SIZE] = {0};
|
||||||
u32 lcode[CODE_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() {
|
bool init_vm() {
|
||||||
mem = lmem;
|
mem = lmem;
|
||||||
code = lcode;
|
code = lcode;
|
||||||
lc = 0;
|
frames = lframes;
|
||||||
mp = 0;
|
reset();
|
||||||
cp = 0;
|
|
||||||
pc = 0;
|
|
||||||
interrupt = 0;
|
|
||||||
status = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,7 +68,7 @@ void test_add_two_num() {
|
||||||
i32 add = cp + 5;
|
i32 add = cp + 5;
|
||||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, add);
|
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_INT_TO_STR, 4, 3, 0);
|
||||||
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 4);
|
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 4);
|
||||||
code[cp++] = ENCODE_A(OP_HALT, 0, 0, 0);
|
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_LOAD_IMM, 0, 35);
|
||||||
code[cp++] = ENCODE_B(OP_PARG, 0, 0);
|
code[cp++] = ENCODE_B(OP_PARG, 0, 0);
|
||||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, fib);
|
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 */
|
/* print */
|
||||||
code[cp++] = ENCODE_A(OP_INT_TO_STR, 3, 2, 0);
|
code[cp++] = ENCODE_A(OP_INT_TO_STR, 3, 2, 0);
|
||||||
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 3);
|
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_B(OP_LOAD_IMM, 3, 2);
|
||||||
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
||||||
code[cp++] = ENCODE_B(OP_PARG, 4, 0);
|
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_B(OP_LOAD_IMM, 3, 1);
|
||||||
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
||||||
code[cp++] = ENCODE_B(OP_PARG, 4, 0);
|
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_A(OP_ADD_INT, 7, 6, 5);
|
||||||
code[cp++] = ENCODE_B(OP_RETURN, 7, 0);
|
code[cp++] = ENCODE_B(OP_RETURN, 7, 0);
|
||||||
code[cp++] = ENCODE_B(OP_RETURN, 0, 0);
|
code[cp++] = ENCODE_B(OP_RETURN, 0, 0);
|
||||||
|
|
|
||||||
68
vm/vm.c
68
vm/vm.c
|
|
@ -1,15 +1,17 @@
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#define FRAME_HEADER_SIZE 12
|
#define FRAME_HEADER_SIZE 12
|
||||||
|
|
||||||
u32 pc; /* program counter */
|
u32 *stack; /* stack */
|
||||||
u32 cp; /* code pointer */
|
u32 sp; /* stack pointer */
|
||||||
u32 mp; /* memory pointer */
|
u32 *code; /* code */
|
||||||
u32 fp; /* frame pointer */
|
u32 cp; /* code pointer */
|
||||||
u8 lc; /* child local count */
|
u8 *mem; /* memory */
|
||||||
u8 status; /* status flag */
|
u32 mp; /* memory pointer */
|
||||||
u8 interrupt; /* device interrupt */
|
Frame *frames; /* call frames */
|
||||||
u32 *code; /* code */
|
u32 fp; /* frame pointer */
|
||||||
u8 *mem; /* memory */
|
u32 pc; /* program counter */
|
||||||
|
u8 status; /* status flag */
|
||||||
|
u8 interrupt; /* device interrupt */
|
||||||
|
|
||||||
#define MAX_LEN_INT32 11
|
#define MAX_LEN_INT32 11
|
||||||
const char radix_set[11] = "0123456789";
|
const char radix_set[11] = "0123456789";
|
||||||
|
|
@ -28,7 +30,7 @@ u32 str_alloc(char *str, u32 length) {
|
||||||
bool step_vm() {
|
bool step_vm() {
|
||||||
u32 instruction = code[pc++];
|
u32 instruction = code[pc++];
|
||||||
u8 opcode = DECODE_OP(instruction);
|
u8 opcode = DECODE_OP(instruction);
|
||||||
u32 *locals = (u32*)(&mem[fp]);
|
u32 *locals = frames[fp].locals;
|
||||||
u32 *globals = (u32*)(mem);
|
u32 *globals = (u32*)(mem);
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
|
@ -40,22 +42,10 @@ bool step_vm() {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
/* function to jump to */
|
/* function to jump to */
|
||||||
u32 fn_ptr = locals[dest];
|
u32 fn_ptr = locals[dest];
|
||||||
/* get mp in 'global indexing mode' */
|
frames[fp].return_reg = src1;
|
||||||
u32 *header = &globals[mp / 4];
|
frames[fp].return_pc = pc;
|
||||||
/* reset child locals counter */
|
frames[fp++].start_mp = mp;
|
||||||
lc = 0;
|
USED(src2);
|
||||||
/* 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);
|
|
||||||
/* jump to dest_ptr */
|
/* jump to dest_ptr */
|
||||||
pc = fn_ptr;
|
pc = fn_ptr;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -68,21 +58,18 @@ bool step_vm() {
|
||||||
bool replaces_value = (((u32)(1)) << 14) & imm;
|
bool replaces_value = (((u32)(1)) << 14) & imm;
|
||||||
|
|
||||||
/* reset mp to saved mp, use header size to get "real" start of frame */
|
/* reset mp to saved mp, use header size to get "real" start of frame */
|
||||||
u32 *frame_start = &globals[(fp / 4) - 3];
|
u32 return_pc = frames[--fp].return_pc;
|
||||||
u32 parent_fp = *frame_start++;
|
u32 return_mp = frames[fp].start_mp;
|
||||||
u32 return_address = *frame_start++;
|
u32 parent_local_return_address = frames[fp].return_reg;
|
||||||
u32 parent_local_return_address = *frame_start++;
|
mp = return_mp;
|
||||||
|
pc = return_pc;
|
||||||
|
|
||||||
USED(replaces_value);
|
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 (parent_local_return_address != 255) {
|
||||||
if (is_ptr) {
|
if (is_ptr) {
|
||||||
/* copy value to end of mp if it is a pointer */
|
/* 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];
|
size = globals[return_value/4];
|
||||||
globals[mp/4] = size;
|
globals[mp/4] = size;
|
||||||
mp += 4;
|
mp += 4;
|
||||||
|
|
@ -90,12 +77,10 @@ bool step_vm() {
|
||||||
mp += size;
|
mp += size;
|
||||||
} else {
|
} else {
|
||||||
/* otherwise just write the return value to its location */
|
/* 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;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_SYSCALL: {
|
case OP_SYSCALL: {
|
||||||
|
|
@ -105,10 +90,9 @@ bool step_vm() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_PARG: {
|
case OP_PARG: {
|
||||||
DECODE_B(instruction)
|
DECODE_A(instruction)
|
||||||
USED(imm);
|
USED(src2);
|
||||||
globals[(mp / 4) + lc + 3] = locals[dest];
|
frames[fp + 1].locals[src1] = locals[dest];
|
||||||
lc++;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_IMM: {
|
case OP_LOAD_IMM: {
|
||||||
|
|
|
||||||
29
vm/vm.h
29
vm/vm.h
|
|
@ -122,15 +122,26 @@ typedef enum {
|
||||||
SYSCALL_MAX
|
SYSCALL_MAX
|
||||||
} Syscall;
|
} Syscall;
|
||||||
|
|
||||||
extern u32 pc; /* program counter */
|
typedef struct frame_s Frame;
|
||||||
extern u32 cp; /* code pointer */
|
struct frame_s {
|
||||||
extern u32 mp; /* memory pointer */
|
u32 locals[256];
|
||||||
extern u32 fp; /* frame pointer */
|
u32 return_pc;
|
||||||
extern u8 lc; /* child local count */
|
u32 start_mp;
|
||||||
extern u8 status; /* status flag */
|
u8 return_reg;
|
||||||
extern u8 interrupt; /* device interrupt */
|
};
|
||||||
extern u32 *code; /* code */
|
|
||||||
extern u8 *mem; /* memory */
|
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])
|
#define READ_U8(addr) (mem[addr])
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue