refinement of vm, idea for new locals

This commit is contained in:
zongor 2026-02-07 11:35:13 -08:00
parent f7a4fb5f7f
commit 8bde10d5b8
12 changed files with 158 additions and 109 deletions

View File

@ -53,9 +53,9 @@ void test_add_two_num() {
i32 main_local_count = 5; i32 main_local_count = 5;
mp += (4 * main_local_count); mp += (4 * main_local_count);
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 1); code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 1);
code[cp++] = ENCODE_B(OP_PUSH, 0, 0); code[cp++] = ENCODE_B(OP_PARG, 0, 0);
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 1); code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 1);
code[cp++] = ENCODE_B(OP_PUSH, 1, 0); code[cp++] = ENCODE_B(OP_PARG, 1, 0);
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);
@ -77,7 +77,7 @@ void test_fibonacci() {
mp += (4 * main_local_count); mp += (4 * main_local_count);
/* fib(35) */ /* fib(35) */
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35); code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35);
code[cp++] = ENCODE_B(OP_PUSH, 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, 9, 2);
/* print */ /* print */
@ -88,14 +88,14 @@ void test_fibonacci() {
code[cp++] = ENCODE_B(OP_LOAD_IMM, 8, fib); code[cp++] = ENCODE_B(OP_LOAD_IMM, 8, fib);
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 2); code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, 2);
code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, base_case); code[cp++] = ENCODE_B(OP_LOAD_IMM, 2, base_case);
code[cp++] = ENCODE_A(OP_JLT_INT, 2, 0, 1); code[cp++] = ENCODE_A(OP_JLTS, 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_PARG, 4, 0);
code[cp++] = ENCODE_A(OP_CALL, 8, 9, 5); code[cp++] = ENCODE_A(OP_CALL, 8, 9, 5);
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_PUSH, 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, 9, 6);
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);
@ -119,7 +119,7 @@ void test_hello() {
i32 main() { i32 main() {
init_vm(); init_vm();
test_hello(); test_fibonacci();
while(step_vm()) { while(step_vm()) {
// do stuff // do stuff

View File

@ -23,7 +23,7 @@ function add(int a, int b) int {
* Print with a newline * Print with a newline
*/ */
function pln(str message) { function pln(str message) {
Terminal term = open("/dev/term/0", 0); Terminal term = open("term:///0", 0);
term.write(message); term.write(message);
term.write("\n"); term.write("\n");
} }

View File

@ -24,7 +24,7 @@ function fib(int n) int {
* Print with a newline * Print with a newline
*/ */
function pln(str message) { function pln(str message) {
Terminal term = open("/dev/term/0", 0); Terminal term = open("term:///0", 0);
term.write(message); term.write(message);
term.write("\n"); term.write("\n");
} }

View File

@ -16,7 +16,7 @@ function main() {
* Print with a newline * Print with a newline
*/ */
function pln(str message) { function pln(str message) {
Terminal term = open("/dev/term/0", 0); Terminal term = open("term:///0", 0);
term.write(message); term.write(message);
term.write("\n"); term.write("\n");
} }

View File

@ -10,7 +10,7 @@ plex Terminal {
* Main function * Main function
*/ */
function main() { function main() {
Terminal term = open("/dev/term/0", 0); Terminal term = open("term:///0", 0);
pln("Enter a string: "); pln("Enter a string: ");
pln(term.read(32) as str); pln(term.read(32) as str);
return 0; return 0;
@ -20,7 +20,7 @@ function main() {
* Print with a newline * Print with a newline
*/ */
function pln(str message) { function pln(str message) {
Terminal term = open("/dev/term/0", 0); Terminal term = open("term:///0", 0);
term.write(message); term.write(message);
term.write("\n"); term.write("\n");
} }

View File

@ -38,8 +38,8 @@ plex Mouse implements Device {
* Main function * Main function
*/ */
function main() { function main() {
Screen screen = open("/dev/screen/0", 0); Screen screen = open("screen:///0", 0);
Mouse mouse = open("/dev/mouse/0", 0); Mouse mouse = open("mouse:///0", 0);
outline_swatch(screen, BLACK, 1, 1); outline_swatch(screen, BLACK, 1, 1);
outline_swatch(screen, WHITE, 21, 1); outline_swatch(screen, WHITE, 21, 1);

View File

@ -19,7 +19,7 @@ function main() {
* Print with a newline * Print with a newline
*/ */
function pln(str message) { function pln(str message) {
Terminal term = open("/dev/term/0", 0); Terminal term = open("term:///0", 0);
write(term, message, message.length); write(term, message, message.length);
write(term, nl, nl.length); write(term, nl, nl.length);
} }

View File

@ -1,9 +1,9 @@
/** /**
* Constants * Constants
*/ */
const str screen_namespace = "/dev/screen/0" const str screen_namespace = "screen:///0"
const str mouse_namespace = "/dev/mouse/0" const str mouse_namespace = "mouse:///0"
const str terminal_namespace = "/dev/term/0" const str terminal_namespace = "term:///0"
const str new_line = "\n" const str new_line = "\n"
const byte WHITE = 255 const byte WHITE = 255

View File

@ -82,6 +82,25 @@ struct scope_tab_s {
i32 scope_ref; i32 scope_ref;
}; };
#define EMIT_U8(value) \
do { \
code[cp++] = (value) & 0xFF; \
} while (0)
#define EMIT_U16(value) \
do { \
code[cp++] = (value) & 0xFF; \
code[cp++] = ((value) >> 8) & 0xFF; \
} while (0)
#define EMIT_U32(value) \
do { \
code[cp++] = (value) & 0xFF; \
code[cp++] = ((value) >> 8) & 0xFF; \
code[cp++] = ((value) >> 16) & 0xFF; \
code[cp++] = ((value) >> 24) & 0xFF; \
} while (0)
bool compile(ScopeTable *st, char *source); bool compile(ScopeTable *st, char *source);
extern bool table_realloc(ScopeTable *table);/* implement this in arch/ not here */ extern bool table_realloc(ScopeTable *table);/* implement this in arch/ not here */

View File

@ -26,6 +26,18 @@ typedef float f32;
#define FLOAT_TO_REAL(v) (((i32)(v)) * 65536.0f) #define FLOAT_TO_REAL(v) (((i32)(v)) * 65536.0f)
#define REAL_TO_FLOAT(v) (((f32)(v)) / 65536.0f) #define REAL_TO_FLOAT(v) (((f32)(v)) / 65536.0f)
#define I8_MIN -128
#define I8_MAX 127
#define U8_MAX 255
#define I16_MIN -32768
#define I16_MAX 32767
#define U16_MAX 65535
#define I32_MIN -2147483648
#define I32_MAX 2147483647
#define U32_MAX 4294967295
void mcpy(void *dest, void *src, u32 n); void mcpy(void *dest, void *src, u32 n);
i32 scpy(char* to, const char *from, u32 length); i32 scpy(char* to, const char *from, u32 length);
bool seq(const char *s1, const char *s2); bool seq(const char *s1, const char *s2);

82
vm/vm.c
View File

@ -106,24 +106,16 @@ bool step_vm() {
status = syscall(id, size, rd); status = syscall(id, size, rd);
return true; return true;
} }
case OP_PUSH: { case OP_PARG: {
DECODE_B(instruction) DECODE_B(instruction)
USED(imm); USED(imm);
globals[(mp / 4) + lc + 3] = locals[dest]; globals[(mp / 4) + lc + 3] = locals[dest];
lc++; lc++;
return true; return true;
} }
case OP_POP: {
DECODE_B(instruction)
USED(dest);
USED(imm);
mp -= 4;
lc--;
return true;
}
case OP_LOAD_IMM: { case OP_LOAD_IMM: {
DECODE_B(instruction) DECODE_B(instruction)
locals[dest] = imm; locals[dest] = ((u32)(imm));
return true; return true;
} }
case OP_LOAD_UPPER_IMM: { case OP_LOAD_UPPER_IMM: {
@ -456,11 +448,6 @@ bool step_vm() {
case OP_BIT_XOR: { case OP_BIT_XOR: {
MATH_OP_NO_CAST(^); MATH_OP_NO_CAST(^);
} }
case OP_JMP_IMM: {
DECODE_C(instruction)
pc = imm;
return true;
}
case OP_JMP_ABS: { case OP_JMP_ABS: {
DECODE_A(instruction) DECODE_A(instruction)
u32 jmp_dest = locals[dest]; u32 jmp_dest = locals[dest];
@ -501,59 +488,74 @@ bool step_vm() {
pc = (jmp_dest & mask) | (pc & ~mask); pc = (jmp_dest & mask) | (pc & ~mask);
return true; return true;
} }
case OP_JEQ_INT: { case OP_JEQS: {
COMPARE_AND_JUMP(i32, ==); COMPARE_AND_JUMP(i32, ==);
} }
case OP_JNE_INT: { case OP_JNES: {
COMPARE_AND_JUMP(i32, !=); COMPARE_AND_JUMP(i32, !=);
} }
case OP_JGT_INT: { case OP_JGTS: {
COMPARE_AND_JUMP(i32, >); COMPARE_AND_JUMP(i32, >);
} }
case OP_JLT_INT: { case OP_JLTS: {
COMPARE_AND_JUMP(i32, <); COMPARE_AND_JUMP(i32, <);
} }
case OP_JLE_INT: { case OP_JLES: {
COMPARE_AND_JUMP(i32, <=); COMPARE_AND_JUMP(i32, <=);
} }
case OP_JGE_INT: { case OP_JGES: {
COMPARE_AND_JUMP(i32, >=); COMPARE_AND_JUMP(i32, >=);
} }
case OP_JEQ_NAT: { case OP_JEQU: {
COMPARE_AND_JUMP(u32, ==); COMPARE_AND_JUMP(u32, ==);
} }
case OP_JNE_NAT: { case OP_JNEU: {
COMPARE_AND_JUMP(u32, !=); COMPARE_AND_JUMP(u32, !=);
} }
case OP_JGT_NAT: { case OP_JGTU: {
COMPARE_AND_JUMP(u32, >); COMPARE_AND_JUMP(u32, >);
} }
case OP_JLT_NAT: { case OP_JLTU: {
COMPARE_AND_JUMP(u32, <); COMPARE_AND_JUMP(u32, <);
} }
case OP_JLE_NAT: { case OP_JLEU: {
COMPARE_AND_JUMP(u32, <=); COMPARE_AND_JUMP(u32, <=);
}
case OP_EQS: {
MATH_OP(i32, ==);
} }
case OP_JGE_NAT: { case OP_NES: {
COMPARE_AND_JUMP(u32, >=); MATH_OP(i32, !=);
} }
case OP_JEQ_REAL: { case OP_GTS: {
COMPARE_AND_JUMP(i32, ==); MATH_OP(i32, >);
} }
case OP_JNE_REAL: { case OP_LTS: {
COMPARE_AND_JUMP(i32, !=); MATH_OP(i32, <);
} }
case OP_JGE_REAL: { case OP_LES: {
COMPARE_AND_JUMP(i32, >=); MATH_OP(i32, <=);
} }
case OP_JGT_REAL: { case OP_GES: {
COMPARE_AND_JUMP(i32, >); MATH_OP(i32, >=);
} }
case OP_JLT_REAL: { case OP_EQU: {
COMPARE_AND_JUMP(i32, <); MATH_OP(u32, ==);
} }
case OP_JLE_REAL: { case OP_NEU: {
COMPARE_AND_JUMP(i32, <=); MATH_OP(u32, !=);
}
case OP_GTU: {
MATH_OP(u32, >);
}
case OP_LTU: {
MATH_OP(u32, <);
}
case OP_LEU: {
MATH_OP(u32, <=);
}
case OP_GEU: {
MATH_OP(u32, >=);
} }
case OP_INT_TO_STR: { case OP_INT_TO_STR: {
DECODE_A(instruction) DECODE_A(instruction)

118
vm/vm.h
View File

@ -3,12 +3,32 @@
#include "libc.h" #include "libc.h"
/*
* Locals
* one 32bit value
* [lllll|tt|p]
* 5 bits -> local position (up to 32 per scope)
* 2 bits -> type
* 1 bit -> is pointer?
*
* 1 -> ptr,
* 00 -> 8
* 10 -> 16
* 01 -> 32
* 11 -> string
*
* 0 -> value
* 00 -> bool?
* 10 -> nat
* 01 -> int
* 11 -> real
*/
/** /**
* Instruction Types * Instruction Types
* *
* A : [8:opcode][8:dest][8:src1][8:src2] * A : [8:opcode][8:dest][8:src1][8:src2]
* B : [8:opcode][8:dest][16:immediate] * B : [8:opcode][8:dest][16:immediate]
* C : [8:opcode][24:immediate]
*/ */
#define DECODE_OP(instruction) ((((u32)(instruction)) >> 24) & 0xFF) #define DECODE_OP(instruction) ((((u32)(instruction)) >> 24) & 0xFF)
@ -29,16 +49,11 @@
u8 dest = (((u32)(instruction)) >> 16) & 0xFF; \ u8 dest = (((u32)(instruction)) >> 16) & 0xFF; \
u16 imm = ((u32)(instruction)) & 0xFFFF; u16 imm = ((u32)(instruction)) & 0xFFFF;
#define ENCODE_C(opcode, imm) ((((u32)(opcode) & 0xFF) << 24) | \
(((u32)(imm)) & 0xFFFFFF))
#define DECODE_C(instruction) \
u32 imm = ((u32)(instruction)) & 0xFFFFFF;
typedef enum { typedef enum {
OP_HALT, /* halt : A : all zeros : halt execution */ OP_HALT, /* halt : B : all zeros : halt execution */
OP_CALL, /* call : A : dest args return : creates a new frame */ OP_CALL, /* call : A : dest args return : creates a new frame */
OP_RETURN, /* return : B : dest return_flags: returns from a frame to the parent frame */ OP_RETURN, /* return : B : dest return_flags : returns from a frame to the parent frame */
OP_SYSCALL, /* syscall : A : id args mem_ptr : does a system call based on id with args */ OP_SYSCALL, /* syscall : A : id args mem_ptr : does a system call based on id with args */
OP_LOAD_IMM, /* load_immediate : B : locals[dest] = const as u16 */ OP_LOAD_IMM, /* load_immediate : B : locals[dest] = const as u16 */
OP_LOAD_UPPER_IMM, /* load_upper_immediate : B : locals[dest] = const as u32 << 16 | u16 */ OP_LOAD_UPPER_IMM, /* load_upper_immediate : B : locals[dest] = const as u32 << 16 | u16 */
OP_LOAD_IND_8, /* load_indirect_8 : A : locals[dest] = memory[locals[src1]] as u8 */ OP_LOAD_IND_8, /* load_indirect_8 : A : locals[dest] = memory[locals[src1]] as u8 */
@ -61,8 +76,7 @@ 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_PARG, /* push_arg : 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] */
@ -75,44 +89,52 @@ typedef enum {
OP_SUB_REAL, /* sub_real : A : locals[dest] = locals[src1] - locals[src2] */ OP_SUB_REAL, /* sub_real : A : locals[dest] = locals[src1] - locals[src2] */
OP_MUL_REAL, /* mul_real : A : locals[dest] = locals[src1] * locals[src2] */ OP_MUL_REAL, /* mul_real : A : locals[dest] = locals[src1] * locals[src2] */
OP_DIV_REAL, /* div_real : A : locals[dest] = locals[src1] / locals[src2] */ OP_DIV_REAL, /* div_real : A : locals[dest] = locals[src1] / locals[src2] */
OP_INT_TO_REAL, /* int_to_real : A : locals[dest] = locals[src1] as real */
OP_INT_TO_NAT, /* int_to_nat : A : locals[dest] = locals[src1] as nat */
OP_NAT_TO_REAL, /* nat_to_real : A : locals[dest] = locals[src1] as real */
OP_NAT_TO_INT, /* nat_to_int : A : locals[dest] = locals[src1] as int */
OP_REAL_TO_INT, /* real_to_int : A : locals[dest] = locals[src1] as int */
OP_REAL_TO_NAT, /* real_to_nat : A : locals[dest] = locals[src1] as nat */
OP_BIT_SHIFT_LEFT, /* bit_shift_left : A : locals[dest] = locals[src1] << locals[src2] */ OP_BIT_SHIFT_LEFT, /* bit_shift_left : A : locals[dest] = locals[src1] << locals[src2] */
OP_BIT_SHIFT_RIGHT,/* bit_shift_right : A : locals[dest] = locals[src1] >> locals[src2] */ OP_BIT_SHIFT_RIGHT,/* bit_shift_right : A : locals[dest] = locals[src1] >> locals[src2] */
OP_BIT_SHIFT_R_EXT,/* bit_shift_r_ext : A : locals[dest] as i32 = locals[src1] >> locals[src2] */ OP_BIT_SHIFT_R_EXT,/* bit_shift_r_ext : A : locals[dest] as i32 = locals[src1] >> locals[src2] */
OP_BIT_AND, /* bit_and : A : locals[dest] = locals[src1] & locals[src2] */ OP_BIT_AND, /* bit_and : A : locals[dest] = locals[src1] & locals[src2] */
OP_BIT_OR, /* bit_or : A : locals[dest] = locals[src1] | locals[src2] */ OP_BIT_OR, /* bit_or : A : locals[dest] = locals[src1] | locals[src2] */
OP_BIT_XOR, /* bit_xor : A : locals[dest] = locals[src1] ^ locals[src2] */ OP_BIT_XOR, /* bit_xor : A : locals[dest] = locals[src1] ^ locals[src2] */
OP_JMP_IMM, /* jump_immediate : E : jump to imm unconditionally */ OP_EQS, /* eq_signed : A : locals[dest] = locals[src1] == locals[src2] */
OP_JMP_ABS, /* jump_absolute : A : jump to locals[dest] unconditionally */ OP_NES, /* ne_signed : A : locals[dest] = locals[src1] != locals[src2] */
OP_JMP_OFF, /* jump_offset : A : jump to locals[dest] + locals[src1] unconditionally */ OP_GTS, /* gt_signed : A : locals[dest] = locals[src1] > locals[src2] */
OP_LTS, /* lt_signed : A : locals[dest] = locals[src1] < locals[src2] */
OP_LES, /* le_signed : A : locals[dest] = locals[src1] <= locals[src2] */
OP_GES, /* ge_signed : A : locals[dest] = locals[src1] >= locals[src2] */
OP_EQU, /* eq_unsigned : A : locals[dest] = locals[src1] == locals[src2] */
OP_NEU, /* ne_unsigned : A : locals[dest] = locals[src1] != locals[src2] */
OP_GTU, /* gt_unsigned : A : locals[dest] = locals[src1] > locals[src2] */
OP_LTU, /* lt_unsigned : A : locals[dest] = locals[src1] < locals[src2] */
OP_LEU, /* le_unsigned : A : locals[dest] = locals[src1] <= locals[src2] */
OP_GEU, /* ge_unsigned : A : locals[dest] = locals[src1] >= locals[src2] */
OP_JMP_FLAG, /* jump_if_flag : A : jump to locals[dest] if flag > 0 */ OP_JMP_FLAG, /* jump_if_flag : A : jump to locals[dest] if flag > 0 */
OP_JEQ_INT, /* jump_eq_int : A : jump to locals[dest] if locals[src1] as int == locals[src2] as int */ OP_JMP_ABS, /* jump_absolute : A : jump to locals[dest] if locals[src1] != 0 */
OP_JNE_INT, /* jump_neq_int : A : jump to locals[dest] if locals[src1] as int != locals[src2] as int */ OP_JMP_OFF, /* jump_offset : A : jump to locals[dest] + locals[src2] if locals[src1] != 0 */
OP_JGT_INT, /* jump_gt_int : A : jump to locals[dest] if locals[src1] as int > locals[src2] as int */ OP_JEQS, /* jump_eq_signed : A : jump to locals[dest] if locals[src1] as i32 == locals[src2] as i32 */
OP_JLT_INT, /* jump_lt_int : A : jump to locals[dest] if locals[src1] as int < locals[src2] as int */ OP_JNES, /* jump_neq_signed : A : jump to locals[dest] if locals[src1] as i32 != locals[src2] as i32 */
OP_JLE_INT, /* jump_le_int : A : jump to locals[dest] if locals[src1] as int <= locals[src2] as int */ OP_JGTS, /* jump_gt_signed : A : jump to locals[dest] if locals[src1] as i32 > locals[src2] as i32 */
OP_JGE_INT, /* jump_ge_int : A : jump to locals[dest] if locals[src1] as int >= locals[src2] as int */ OP_JLTS, /* jump_lt_signed : A : jump to locals[dest] if locals[src1] as i32 < locals[src2] as i32 */
OP_JEQ_NAT, /* jump_eq_nat : A : jump to locals[dest] if locals[src1] as nat == locals[src2] as nat */ OP_JLES, /* jump_le_signed : A : jump to locals[dest] if locals[src1] as i32 <= locals[src2] as i32 */
OP_JNE_NAT, /* jump_neq_nat : A : jump to locals[dest] if locals[src1] as nat != locals[src2] as nat */ OP_JGES, /* jump_ge_signed : A : jump to locals[dest] if locals[src1] as i32 >= locals[src2] as i32 */
OP_JGT_NAT, /* jump_gt_nat : A : jump to locals[dest] if locals[src1] as nat > locals[src2] as nat */ OP_JEQU, /* jump_eq_unsigned : A : jump to locals[dest] if locals[src1] as u32 == locals[src2] as u32 */
OP_JLT_NAT, /* jump_lt_nat : A : jump to locals[dest] if locals[src1] as nat < locals[src2] as nat */ OP_JNEU, /* jump_neq_unsigned : A : jump to locals[dest] if locals[src1] as u32 != locals[src2] as u32 */
OP_JLE_NAT, /* jump_le_nat : A : jump to locals[dest] if locals[src1] as nat <= locals[src2] as nat */ OP_JGTU, /* jump_gt_unsigned : A : jump to locals[dest] if locals[src1] as u32 > locals[src2] as u32 */
OP_JGE_NAT, /* jump_ge_nat : A : jump to locals[dest] if locals[src1] as nat >= locals[src2] as nat */ OP_JLTU, /* jump_lt_unsigned : A : jump to locals[dest] if locals[src1] as u32 < locals[src2] as u32 */
OP_JEQ_REAL, /* jump_eq_real : A : jump to locals[dest] if locals[src1] as real == locals[src2] as real */ OP_JLEU, /* jump_le_unsigned : A : jump to locals[dest] if locals[src1] as u32 <= locals[src2] as u32 */
OP_JNE_REAL, /* jump_neq_real : A : jump to locals[dest] if locals[src1] as real != locals[src2] as real */ OP_JGEU, /* jump_ge_unsigned : A : jump to locals[dest] if locals[src1] as u32 >= locals[src2] as u32 */
OP_JGE_REAL, /* jump_ge_real : A : jump to locals[dest] if locals[src1] as real >= locals[src2] as real */ OP_INT_TO_REAL, /* int_to_real : A : locals[dest] = locals[src1] as real */
OP_JGT_REAL, /* jump_gt_real : A : jump to locals[dest] if locals[src1] as real > locals[src2] as real */ OP_INT_TO_NAT, /* int_to_nat : A : locals[dest] = locals[src1] as nat */
OP_JLT_REAL, /* jump_lt_real : A : jump to locals[dest] if locals[src1] as real < locals[src2] as real */ OP_NAT_TO_REAL, /* nat_to_real : A : locals[dest] = locals[src1] as real */
OP_JLE_REAL, /* jump_le_real : A : jump to locals[dest] if locals[src1] as real <= locals[src2] as real */ OP_NAT_TO_INT, /* nat_to_int : A : locals[dest] = locals[src1] as int */
OP_INT_TO_STR, /* int_to_str : A : locals[dest] = &mem[mp..] locals[src1] as str */ OP_REAL_TO_INT, /* real_to_int : A : locals[dest] = locals[src1] as int */
OP_NAT_TO_STR, /* nat_to_str : A : locals[dest] = &mem[mp..] locals[src1] as str */ OP_REAL_TO_NAT, /* real_to_nat : A : locals[dest] = locals[src1] as nat */
OP_REAL_TO_STR, /* real_to_str : A : locals[dest] = &mem[mp..] locals[src1] as str */ OP_INT_TO_STR, /* int_to_str : A : locals[dest] = &mem[mp..] <~ locals[src1] as str */
OP_MAX_OPCODE /* not an opcode count of instructions */ OP_NAT_TO_STR, /* nat_to_str : A : locals[dest] = &mem[mp..] <~ locals[src1] as str */
OP_REAL_TO_STR, /* real_to_str : A : locals[dest] = &mem[mp..] <~ locals[src1] as str */
OP_STR_TO_INT, /* str_to_int : A : locals[dest] = mem[locals[src1]..] ~> int */
OP_STR_TO_NAT, /* str_to_nat : A : locals[dest] = mem[locals[src1]..] ~> nat */
OP_STR_TO_REAL, /* str_to_real : A : locals[dest] = mem[locals[src1]..] ~> real */
OP_MAX_OPCODE /* not an opcode just a count of instructions */
} Opcode; } Opcode;
typedef enum { typedef enum {
@ -136,10 +158,7 @@ extern u8 *mem; /* memory */
#define READ_U16(addr) \ #define READ_U16(addr) \
(((u16)mem[(addr) + 1] << 8) | ((u16)mem[(addr)])) (((u16)mem[(addr) + 1] << 8) | ((u16)mem[(addr)]))
#define READ_U32(addr) \ #define READ_U32(addr) (globals[(addr / 4)])
(((u32)mem[(addr) + 3] << 24) | \
((u32)mem[(addr) + 2] << 16) | \
((u32)mem[(addr) + 1] << 8) | ((u32)mem[(addr)]))
#define WRITE_U8(addr, value) \ #define WRITE_U8(addr, value) \
do { \ do { \
@ -154,10 +173,7 @@ extern u8 *mem; /* memory */
#define WRITE_U32(addr, value) \ #define WRITE_U32(addr, value) \
do { \ do { \
mem[addr] = (value) & 0xFF; \ globals[(addr / 4)] = value; \
mem[addr + 1] = ((value) >> 8) & 0xFF; \
mem[addr + 2] = ((value) >> 16) & 0xFF; \
mem[addr + 3] = ((value) >> 24) & 0xFF; \
} while (0) } while (0)
#define MATH_OP(type, op) \ #define MATH_OP(type, op) \