add function test works, wip fibonacci
This commit is contained in:
parent
2334212952
commit
c55b15cdfa
|
|
@ -11,6 +11,7 @@ bool init_vm() {
|
||||||
mem = lmem;
|
mem = lmem;
|
||||||
memset(mem, 0, MEMORY_SIZE*sizeof(u8));
|
memset(mem, 0, MEMORY_SIZE*sizeof(u8));
|
||||||
code = lcode;
|
code = lcode;
|
||||||
|
sp = 0;
|
||||||
mp = 0;
|
mp = 0;
|
||||||
cp = 0;
|
cp = 0;
|
||||||
pc = 0;
|
pc = 0;
|
||||||
|
|
@ -30,32 +31,54 @@ u32 syscall(u32 id, u32 args, u32 mem_ptr) {
|
||||||
return 1; // generic error
|
return 1; // generic error
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 main() {
|
void test_add_two_num() {
|
||||||
init_vm();
|
i32 main_local_count = 4;
|
||||||
|
mp += (4 * main_local_count);
|
||||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35);
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 1);
|
||||||
code[cp++] = ENCODE_B(OP_PUSH, 0, 0);
|
code[cp++] = ENCODE_B(OP_PUSH, 0, 0);
|
||||||
int fib = cp + 3;
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 1);
|
||||||
code[cp++] = ENCODE_A(OP_CALL, fib, 7, 1);
|
code[cp++] = ENCODE_B(OP_PUSH, 1, 0);
|
||||||
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_DBG_PRINT, 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);
|
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_B(OP_LOAD_IMM, 1, 2);
|
||||||
code[cp++] = ENCODE_A(OP_JLT_INT, base_case_if_false, 0, 1);
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, fib);
|
||||||
code[cp++] = ENCODE_B(OP_RETURN, 0, 0);
|
code[cp++] = ENCODE_A(OP_JLT_INT, 2, 0, 1);
|
||||||
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_PUSH, 4, 0);
|
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()) {
|
while(step_vm()) {
|
||||||
// do stuff
|
// do stuff
|
||||||
|
|
|
||||||
146
vm/vm.c
146
vm/vm.c
|
|
@ -1,11 +1,11 @@
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
#define FRAME_HEADER_SIZE 12
|
#define FRAME_HEADER_SIZE 12
|
||||||
|
|
||||||
u32 pc; /* program counter */
|
u32 pc; /* program counter */
|
||||||
u32 cp; /* code pointer */
|
u32 cp; /* code pointer */
|
||||||
u32 mp; /* memory pointer */
|
u32 mp; /* memory pointer */
|
||||||
u32 fp; /* frame pointer */
|
u32 fp; /* frame pointer */
|
||||||
|
u8 sp; /* child local count */
|
||||||
u32 flag; /* flag */
|
u32 flag; /* flag */
|
||||||
u8 interrupt; /* device interrupt */
|
u8 interrupt; /* device interrupt */
|
||||||
u32 *code; /* code */
|
u32 *code; /* code */
|
||||||
|
|
@ -23,29 +23,27 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_CALL: {
|
case OP_CALL: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 fn_ptr, local_count, return_ptr;
|
u32 fn_ptr;
|
||||||
|
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = src1;
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + src2;
|
||||||
|
|
||||||
fn_ptr = READ_U32(rd);
|
fn_ptr = READ_U32(rd);
|
||||||
local_count = READ_U32(r1);
|
|
||||||
return_ptr = READ_U32(r2);
|
|
||||||
|
|
||||||
/* push parents frame value to reset the heap to */
|
/* push parents frame value to reset the heap to */
|
||||||
WRITE_U32(mp, fp);
|
WRITE_U32(mp, fp);
|
||||||
mp += 4;
|
mp += 4;
|
||||||
/* push return address to child frame */
|
/* push return address to child frame */
|
||||||
WRITE_U32(mp, pc + 1);
|
WRITE_U32(mp, pc);
|
||||||
mp += 4;
|
mp += 4;
|
||||||
/* push local address to return the value to */
|
/* push local address to return the value to */
|
||||||
WRITE_U32(mp, return_ptr);
|
WRITE_U32(mp, r2);
|
||||||
mp += 4;
|
mp += 4;
|
||||||
/* now set the frame pointer, where the locals start */
|
/* now set the frame pointer, where the locals start */
|
||||||
fp = mp;
|
fp = mp;
|
||||||
/* move mp by count many locals */
|
/* move mp by count many locals */
|
||||||
mp += (4 * local_count);
|
mp += (4 * r1);
|
||||||
/* jump to dest_ptr */
|
/* jump to dest_ptr */
|
||||||
pc = fn_ptr;
|
pc = fn_ptr;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -53,17 +51,18 @@ bool step_vm() {
|
||||||
case OP_RETURN: {
|
case OP_RETURN: {
|
||||||
DECODE_B(instruction)
|
DECODE_B(instruction)
|
||||||
u32 i, size = 0;
|
u32 i, size = 0;
|
||||||
u32 return_local = fp + dest;
|
u32 return_local = fp + (dest * 4);
|
||||||
u32 return_value = READ_U32(return_local);
|
u32 return_value = READ_U32(return_local);
|
||||||
bool is_ptr = (((u16)(1)) << 15) & imm;
|
bool is_ptr = (((u32)(1)) << 15) & imm;
|
||||||
bool replaces_value = (((u16)(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 = fp - FRAME_HEADER_SIZE;
|
u32 frame_start = fp - FRAME_HEADER_SIZE;
|
||||||
u32 parent_fp = READ_U32(frame_start);
|
u32 parent_fp = READ_U32(frame_start);
|
||||||
u32 return_address = READ_U32(frame_start + 4);
|
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 */
|
/* reset memory to parents end of memory */
|
||||||
mp = fp - FRAME_HEADER_SIZE;
|
mp = fp - FRAME_HEADER_SIZE;
|
||||||
/* reset the frame pointer */
|
/* reset the frame pointer */
|
||||||
|
|
@ -91,21 +90,21 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_SYSCALL: {
|
case OP_SYSCALL: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 id = fp + dest;
|
u32 id = dest;
|
||||||
u32 args = fp + src1;
|
u32 args = src1;
|
||||||
u32 mem_ptr = fp + src2;
|
u32 rd = fp + (src2 * 4);
|
||||||
flag = syscall(id, args, mem_ptr);
|
flag = syscall(id, args, rd);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_IMM: {
|
case OP_LOAD_IMM: {
|
||||||
DECODE_B(instruction)
|
DECODE_B(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
WRITE_U32(rd, imm);
|
WRITE_U32(rd, imm);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_UPPER_IMM: {
|
case OP_LOAD_UPPER_IMM: {
|
||||||
DECODE_B(instruction)
|
DECODE_B(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 value = READ_U32(rd);
|
u32 value = READ_U32(rd);
|
||||||
WRITE_U32(rd, (value | (((u32)(imm)) << 16)));
|
WRITE_U32(rd, (value | (((u32)(imm)) << 16)));
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -149,8 +148,8 @@ bool step_vm() {
|
||||||
case OP_MEM_ALLOC: {
|
case OP_MEM_ALLOC: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 size, ldest;
|
u32 size, ldest;
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
USED(src2);
|
USED(src2);
|
||||||
ldest = READ_U32(rd);
|
ldest = READ_U32(rd);
|
||||||
WRITE_U32(ldest, mp);
|
WRITE_U32(ldest, mp);
|
||||||
|
|
@ -163,9 +162,9 @@ bool step_vm() {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 i, count, mdest, msrc;
|
u32 i, count, mdest, msrc;
|
||||||
|
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + (src2 * 4);
|
||||||
|
|
||||||
mdest = READ_U32(rd);
|
mdest = READ_U32(rd);
|
||||||
msrc = READ_U32(r1);
|
msrc = READ_U32(r1);
|
||||||
|
|
@ -188,9 +187,9 @@ bool step_vm() {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 i, count, mdest, msrc;
|
u32 i, count, mdest, msrc;
|
||||||
|
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + (src2 * 4);
|
||||||
|
|
||||||
mdest = READ_U32(rd);
|
mdest = READ_U32(rd);
|
||||||
msrc = READ_U32(r1);
|
msrc = READ_U32(r1);
|
||||||
|
|
@ -213,9 +212,9 @@ bool step_vm() {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 i, count, mdest, msrc;
|
u32 i, count, mdest, msrc;
|
||||||
|
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + (src2 * 4);
|
||||||
|
|
||||||
mdest = READ_U32(rd);
|
mdest = READ_U32(rd);
|
||||||
msrc = READ_U32(r1);
|
msrc = READ_U32(r1);
|
||||||
|
|
@ -238,9 +237,9 @@ bool step_vm() {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 i, start, end;
|
u32 i, start, end;
|
||||||
|
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + (src2 * 4);
|
||||||
|
|
||||||
u8 value = (u8)READ_U32(r1);
|
u8 value = (u8)READ_U32(r1);
|
||||||
u32 count = READ_U32(r2);
|
u32 count = READ_U32(r2);
|
||||||
|
|
@ -250,7 +249,7 @@ bool step_vm() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
start = rd;
|
start = READ_U32(rd);
|
||||||
end = start + count;
|
end = start + count;
|
||||||
|
|
||||||
if (start >= mp || r2 > mp || end > mp) {
|
if (start >= mp || r2 > mp || end > mp) {
|
||||||
|
|
@ -269,9 +268,9 @@ bool step_vm() {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 i, start, end;
|
u32 i, start, end;
|
||||||
|
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + (src2 * 4);
|
||||||
|
|
||||||
u16 value = (u16)READ_U32(r1);
|
u16 value = (u16)READ_U32(r1);
|
||||||
u32 count = READ_U32(r2);
|
u32 count = READ_U32(r2);
|
||||||
|
|
@ -281,7 +280,7 @@ bool step_vm() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
start = rd;
|
start = READ_U32(rd);
|
||||||
end = start + count;
|
end = start + count;
|
||||||
|
|
||||||
if (start >= mp || r2 > mp || end > mp) {
|
if (start >= mp || r2 > mp || end > mp) {
|
||||||
|
|
@ -300,9 +299,9 @@ bool step_vm() {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 i, start, end;
|
u32 i, start, end;
|
||||||
|
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + (src2 * 4);
|
||||||
|
|
||||||
u32 value = READ_U32(r1);
|
u32 value = READ_U32(r1);
|
||||||
u32 count = READ_U32(r2);
|
u32 count = READ_U32(r2);
|
||||||
|
|
@ -312,7 +311,7 @@ bool step_vm() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
start = rd;
|
start = READ_U32(rd);
|
||||||
end = start + count;
|
end = start + count;
|
||||||
|
|
||||||
if (start >= mp || r2 > mp || end > mp) {
|
if (start >= mp || r2 > mp || end > mp) {
|
||||||
|
|
@ -329,13 +328,28 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_MOV: {
|
case OP_MOV: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 value = READ_U32(r1);
|
u32 value = READ_U32(r1);
|
||||||
USED(src2);
|
USED(src2);
|
||||||
WRITE_U32(rd, value);
|
WRITE_U32(rd, value);
|
||||||
return true;
|
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: {
|
case OP_ADD_INT: {
|
||||||
MATH_OP(i32, +);
|
MATH_OP(i32, +);
|
||||||
}
|
}
|
||||||
|
|
@ -368,9 +382,9 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_MUL_REAL: {
|
case OP_MUL_REAL: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + (src2 * 4);
|
||||||
|
|
||||||
i32 src1_whole = (i32)READ_U32(r1) >> 16;
|
i32 src1_whole = (i32)READ_U32(r1) >> 16;
|
||||||
i32 src2_whole = (i32)READ_U32(r2) >> 16;
|
i32 src2_whole = (i32)READ_U32(r2) >> 16;
|
||||||
|
|
@ -389,9 +403,9 @@ bool step_vm() {
|
||||||
case OP_DIV_REAL: {
|
case OP_DIV_REAL: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
i32 result;
|
i32 result;
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 r2 = fp + src2;
|
u32 r2 = fp + (src2 * 4);
|
||||||
|
|
||||||
i32 src1_val = (i32)READ_U32(r1);
|
i32 src1_val = (i32)READ_U32(r1);
|
||||||
i32 src2_val = (i32)READ_U32(r2);
|
i32 src2_val = (i32)READ_U32(r2);
|
||||||
|
|
@ -407,8 +421,8 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_INT_TO_REAL: {
|
case OP_INT_TO_REAL: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
i32 result = (i32)READ_U32(r1) << 16;
|
i32 result = (i32)READ_U32(r1) << 16;
|
||||||
USED(src2);
|
USED(src2);
|
||||||
WRITE_U32(rd, result);
|
WRITE_U32(rd, result);
|
||||||
|
|
@ -416,8 +430,8 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_INT_TO_NAT: {
|
case OP_INT_TO_NAT: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 result = (u32)READ_U32(r1);
|
u32 result = (u32)READ_U32(r1);
|
||||||
USED(src2);
|
USED(src2);
|
||||||
WRITE_U32(rd, result);
|
WRITE_U32(rd, result);
|
||||||
|
|
@ -425,8 +439,8 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_NAT_TO_REAL: {
|
case OP_NAT_TO_REAL: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
i32 result = ((i32)READ_U32(r1) << 16);
|
i32 result = ((i32)READ_U32(r1) << 16);
|
||||||
USED(src2);
|
USED(src2);
|
||||||
WRITE_U32(rd, result);
|
WRITE_U32(rd, result);
|
||||||
|
|
@ -434,8 +448,8 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_NAT_TO_INT: {
|
case OP_NAT_TO_INT: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
i32 result = ((i32)READ_U32(r1));
|
i32 result = ((i32)READ_U32(r1));
|
||||||
USED(src2);
|
USED(src2);
|
||||||
WRITE_U32(rd, result);
|
WRITE_U32(rd, result);
|
||||||
|
|
@ -443,8 +457,8 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_INT: {
|
case OP_REAL_TO_INT: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
i32 result = ((i32)READ_U32(r1) >> 16);
|
i32 result = ((i32)READ_U32(r1) >> 16);
|
||||||
USED(src2);
|
USED(src2);
|
||||||
WRITE_U32(rd, result);
|
WRITE_U32(rd, result);
|
||||||
|
|
@ -452,8 +466,8 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_NAT: {
|
case OP_REAL_TO_NAT: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
u32 result = ((u32)READ_U32(r1) >> 16);
|
u32 result = ((u32)READ_U32(r1) >> 16);
|
||||||
USED(src2);
|
USED(src2);
|
||||||
WRITE_U32(rd, result);
|
WRITE_U32(rd, result);
|
||||||
|
|
@ -484,7 +498,7 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_JMP_ABS: {
|
case OP_JMP_ABS: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 jmp_dest = READ_U32(rd);
|
u32 jmp_dest = READ_U32(rd);
|
||||||
if (jmp_dest > cp) {
|
if (jmp_dest > cp) {
|
||||||
flag = 1;
|
flag = 1;
|
||||||
|
|
@ -498,8 +512,8 @@ bool step_vm() {
|
||||||
}
|
}
|
||||||
case OP_JMP_OFF: {
|
case OP_JMP_OFF: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 r1 = fp + src1;
|
u32 r1 = fp + (src1 * 4);
|
||||||
|
|
||||||
u32 jmp_dest = READ_U32(rd) + READ_U32(r1);
|
u32 jmp_dest = READ_U32(rd) + READ_U32(r1);
|
||||||
if (jmp_dest > cp) {
|
if (jmp_dest > cp) {
|
||||||
|
|
@ -514,7 +528,7 @@ bool step_vm() {
|
||||||
case OP_JMP_FLAG: {
|
case OP_JMP_FLAG: {
|
||||||
DECODE_A(instruction)
|
DECODE_A(instruction)
|
||||||
u32 mask;
|
u32 mask;
|
||||||
u32 rd = fp + dest;
|
u32 rd = fp + (dest * 4);
|
||||||
u32 jmp_dest = READ_U32(rd);
|
u32 jmp_dest = READ_U32(rd);
|
||||||
if (jmp_dest > cp) {
|
if (jmp_dest > cp) {
|
||||||
flag = 1;
|
flag = 1;
|
||||||
|
|
|
||||||
43
vm/vm.h
43
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_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_MEM_SET_32, /* memset_32 : A : memory[dest..dest+src2] = local[src1] as u32 */
|
||||||
OP_MOV, /* mov : A : locals[dest] = locals[src1] */
|
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_ADD_INT, /* add_int : A : locals[dest] = locals[src1] + locals[src2] */
|
||||||
OP_SUB_INT, /* sub_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] */
|
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 cp; /* code pointer */
|
||||||
extern u32 mp; /* memory pointer */
|
extern u32 mp; /* memory pointer */
|
||||||
extern u32 fp; /* frame pointer */
|
extern u32 fp; /* frame pointer */
|
||||||
|
extern u8 sp; /* child local count */
|
||||||
extern u32 flag; /* flag */
|
extern u32 flag; /* flag */
|
||||||
extern u8 interrupt; /* device interrupt */
|
extern u8 interrupt; /* device interrupt */
|
||||||
extern u32 *code; /* code */
|
extern u32 *code; /* code */
|
||||||
|
|
@ -142,35 +145,29 @@ extern u8 *mem; /* memory */
|
||||||
|
|
||||||
#define WRITE_U8(addr, value) \
|
#define WRITE_U8(addr, value) \
|
||||||
do { \
|
do { \
|
||||||
if ((addr) < sizeof(mem)) { \
|
mem[addr] = (value) & 0xFF; \
|
||||||
mem[(addr)] = (value) & 0xFF; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define WRITE_U16(addr, value) \
|
#define WRITE_U16(addr, value) \
|
||||||
do { \
|
do { \
|
||||||
if ((addr) + 1 < sizeof(mem)) { \
|
mem[addr] = (value) & 0xFF; \
|
||||||
mem[(addr)] = (value) & 0xFF; \
|
mem[addr + 1] = ((value) >> 8) & 0xFF; \
|
||||||
mem[(addr) + 1] = ((value) >> 8) & 0xFF; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define WRITE_U32(addr, value) \
|
#define WRITE_U32(addr, value) \
|
||||||
do { \
|
do { \
|
||||||
if (addr + 3 < sizeof(mem)) { \
|
mem[addr] = (value) & 0xFF; \
|
||||||
mem[addr] = (value) & 0xFF; \
|
mem[addr + 1] = ((value) >> 8) & 0xFF; \
|
||||||
mem[addr + 1] = ((value) >> 8) & 0xFF; \
|
mem[addr + 2] = ((value) >> 16) & 0xFF; \
|
||||||
mem[addr + 2] = ((value) >> 16) & 0xFF; \
|
mem[addr + 3] = ((value) >> 24) & 0xFF; \
|
||||||
mem[addr + 3] = ((value) >> 24) & 0xFF; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define MATH_OP(type, op) \
|
#define MATH_OP(type, op) \
|
||||||
do { \
|
do { \
|
||||||
DECODE_A(instruction) \
|
DECODE_A(instruction) \
|
||||||
u32 rd = fp + dest; \
|
u32 rd = fp + (dest * 4); \
|
||||||
u32 r1 = fp + src1; \
|
u32 r1 = fp + (src1 * 4); \
|
||||||
u32 r2 = fp + src2; \
|
u32 r2 = fp + (src2 * 4); \
|
||||||
type result = ((type)READ_U32(r1) op (type)READ_U32(r2)); \
|
type result = ((type)READ_U32(r1) op (type)READ_U32(r2)); \
|
||||||
mem[(rd)] = (result) & 0xFF; \
|
mem[(rd)] = (result) & 0xFF; \
|
||||||
mem[(rd) + 1] = ((result) >> 8) & 0xFF; \
|
mem[(rd) + 1] = ((result) >> 8) & 0xFF; \
|
||||||
|
|
@ -182,10 +179,10 @@ extern u8 *mem; /* memory */
|
||||||
#define MATH_OP_NO_CAST(op) \
|
#define MATH_OP_NO_CAST(op) \
|
||||||
do { \
|
do { \
|
||||||
DECODE_A(instruction) \
|
DECODE_A(instruction) \
|
||||||
u32 rd = fp + dest; \
|
u32 rd = fp + (dest * 4); \
|
||||||
u32 r1 = fp + src1; \
|
u32 r1 = fp + (src1 * 4); \
|
||||||
u32 r2 = fp + src2; \
|
u32 r2 = fp + (src2 * 4); \
|
||||||
WRITE_U32(rd, (READ_U32(r1) op READ_U32(r2))); \
|
WRITE_U32(rd, (READ_U32(r1) op READ_U32(r2))); \
|
||||||
return true; \
|
return true; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
@ -196,9 +193,9 @@ extern u8 *mem; /* memory */
|
||||||
u32 mask, target; \
|
u32 mask, target; \
|
||||||
type value; \
|
type value; \
|
||||||
type value2; \
|
type value2; \
|
||||||
u32 rd = fp + dest; \
|
u32 rd = fp + (dest * 4); \
|
||||||
u32 r1 = fp + src1; \
|
u32 r1 = fp + (src1 * 4); \
|
||||||
u32 r2 = fp + src2; \
|
u32 r2 = fp + (src2 * 4); \
|
||||||
target = READ_U32(rd); \
|
target = READ_U32(rd); \
|
||||||
value = (type)READ_U32(r1); \
|
value = (type)READ_U32(r1); \
|
||||||
value2 = (type)READ_U32(r2); \
|
value2 = (type)READ_U32(r2); \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue