Compare commits

...

1 Commits

Author SHA1 Message Date
zongor f476b74c3f add initial stuff, is very broken because of overflows 2025-09-07 09:57:57 -07:00
3 changed files with 277 additions and 126 deletions

View File

@ -2,69 +2,70 @@
#define ZRL_OPCODES_H #define ZRL_OPCODES_H
#include "common.h" #include "common.h"
#include "fixed.h"
#include <stdint.h> #include <stdint.h>
typedef enum { typedef enum {
OP_HALT, /* halt : terminate execution */ OP_HALT, /* halt : terminate execution */
OP_JMP, /* jump : jump to address dest unconditionally */ OP_JMP, /* jump : jump to address dest unconditionally */
OP_GET_PC, /* pc : dest = current program counter */ OP_GET_PC, /* pc : dest = current program counter */
OP_CALL, /* call : creates a new frame */ OP_CALL, /* call : creates a new frame */
OP_RETURN, /* retn : returns from a frame to the parent frame */ OP_RETURN, /* retn : returns from a frame to the parent frame */
OP_LOAD, /* load : dest = &[next memory location] */ OP_LOAD, /* load : dest = &[next code location] */
OP_STORE, /* stor : next memory location = src1 as float */ OP_STORE, /* stor : next code location = src1 as float */
OP_PUSH, /* push : push str ref from register onto the stack and copy str */ OP_PUSH, /* push : push str ref from register onto the stack and copy str */
OP_POP, /* pop : pop int from stack onto the register */ OP_POP, /* pop : pop int from stack onto the register */
OP_REG_MOV, /* rmov : dest = src1 */ OP_REG_MOV, /* rmov : dest = src1 */
OP_REG_SWAP, /* rswp : dest = src1, src1 = dest */ OP_REG_SWAP, /* rswp : dest = src1, src1 = dest */
OP_GET_ACC, /* gacc : dest = accumulator */ OP_GET_ACC, /* gacc : dest = accumulator */
OP_MEM_SWAP, /* mswp : &dest = &src1, &src1 = &dest */ OP_MEM_SWAP, /* mswp : &dest = &src1, &src1 = &dest */
OP_MEM_MOV, /* mmov : &dest = &src1 */ OP_MEM_MOV, /* mmov : &dest = &src1 */
OP_MEM_ALLOC, /* aloc : dest [next memory location as size] */ OP_MEM_ALLOC, /* aloc : dest [next memory location as size] */
OP_GET, /* get : dest = ptr : dest = memory[ptr] */ OP_GET, /* get : dest = ptr : dest = memory[ptr] */
OP_PUT, /* put : ptr = src1 : memory[ptr] = src */ OP_PUT, /* put : ptr = src1 : memory[ptr] = src */
OP_OFFSET, /* offs : dest = ptr + src1 : dest = p + o */ OP_OFFSET, /* offs : dest = ptr + src1 : dest = p + o */
OP_SYSCALL, /* sysc : */ OP_SYSCALL, /* sysc : */
OP_ADD_INT, /* addi : dest = src1 + src2 */ OP_ADD_INT, /* addi : dest = src1 + src2 */
OP_SUB_INT, /* subi : dest = src1 - src2 */ OP_SUB_INT, /* subi : dest = src1 - src2 */
OP_MUL_INT, /* muli : dest = src1 * src2 */ OP_MUL_INT, /* muli : dest = src1 * src2 */
OP_DIV_INT, /* divi : dest = src1 / src2 */ OP_DIV_INT, /* divi : dest = src1 / src2 */
OP_ADD_UINT, /* addu : dest = src1 + src2 */ OP_ADD_UINT, /* addu : dest = src1 + src2 */
OP_SUB_UINT, /* subu : dest = src1 - src2 */ OP_SUB_UINT, /* subu : dest = src1 - src2 */
OP_MUL_UINT, /* mulu : dest = src1 * src2 */ OP_MUL_UINT, /* mulu : dest = src1 * src2 */
OP_DIV_UINT, /* divu : dest = src1 / src2 */ OP_DIV_UINT, /* divu : dest = src1 / src2 */
OP_ADD_REAL, /* addr : dest = src1 + src2 */ OP_ADD_REAL, /* addr : dest = src1 + src2 */
OP_SUB_REAL, /* subr : dest = src1 - src2 */ OP_SUB_REAL, /* subr : dest = src1 - src2 */
OP_MUL_REAL, /* mulr : dest = src1 * src2 */ OP_MUL_REAL, /* mulr : dest = src1 * src2 */
OP_DIV_REAL, /* divr : dest = src1 / src2 */ OP_DIV_REAL, /* divr : dest = src1 / src2 */
OP_INT_TO_REAL, /* itor : dest = src1 as real */ OP_INT_TO_REAL, /* itor : dest = src1 as real */
OP_UINT_TO_REAL, /* utor : dest = src1 as real */ OP_UINT_TO_REAL, /* utor : dest = src1 as real */
OP_REAL_TO_INT, /* rtoi : dest = src1 as int */ OP_REAL_TO_INT, /* rtoi : dest = src1 as int */
OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */ OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */
OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */ OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */
OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/ OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/
OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */ OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */
OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */ OP_JLE_INT, /* jlei : jump to address dest if src1 as int <= src2 as int */
OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/ OP_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/
OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */ OP_JEQ_UINT, /* jequ : jump to address dest if src1 as int == src2 as uint */
OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/ OP_JGT_UINT, /* jgtu : jump to address dest if src1 as int > src2 as uint*/
OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */ OP_JLT_UINT, /* jltu : jump to address dest if src1 as int < src2 as uint */
OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */ OP_JLE_UINT, /* jleu : jump to address dest if src1 as int <= src2 as uint */
OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/ OP_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/
OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */ OP_JEQ_REAL, /* jeqr : jump to address dest if src1 as real == src2 as real */
OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */ OP_JGE_REAL, /* jgtr : jump to address dest if src1 as real >= src2 as real */
OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */ OP_JGT_REAL, /* jltr : jump to address dest if src1 as real > src2 as real */
OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */ OP_JLT_REAL, /* jler : jump to address dest if src1 as real < src2 as real */
OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */ OP_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */
OP_INT_TO_STRING, /* itos : dest = src1 as str */ OP_INT_TO_STRING, /* itos : dest = src1 as str */
OP_UINT_TO_STRING, /* utos : dest = src1 as str */ OP_UINT_TO_STRING,/* utos : dest = src1 as str */
OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ OP_REAL_TO_STRING,/* rtos : dest = src1 as str */
OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */ OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */
OP_STRING_TO_INT, /* stoi : dest = src1 as int */ OP_STRING_TO_INT, /* stoi : dest = src1 as int */
OP_STRING_TO_UINT, /* stou : dest = src1 as uint */ OP_STRING_TO_UINT,/* stou : dest = src1 as uint */
OP_STRING_TO_REAL, /* stor : dest = src1 as real */ OP_STRING_TO_REAL,/* stor : dest = src1 as real */
/* to remove (replace with device), just for testing for now */ /* to remove (replace with device), just for testing for now */
OP_DBG_PRINT_STRING, OP_DBG_PRINT_STRING,/* puts : write src1 as str to stdout */
OP_DBG_READ_STRING, OP_DBG_READ_STRING, /* gets : read to dest as str from stdin */
} Opcode; } Opcode;
/* defines a uint32 opcode */ /* defines a uint32 opcode */
@ -76,7 +77,7 @@ typedef enum {
typedef union value_u { typedef union value_u {
int32_t i; /* Integers */ int32_t i; /* Integers */
float f; /* Float */ fixed_t f; /* Fixed point */
uint32_t u; /* Unsigned integers, also used for pointer address */ uint32_t u; /* Unsigned integers, also used for pointer address */
char c[4]; /* 4 Byte char array for string packing */ char c[4]; /* 4 Byte char array for string packing */
} Value; } Value;
@ -123,7 +124,7 @@ typedef struct device_s {
uint32_t flags; /* permissions, status, etc. */ uint32_t flags; /* permissions, status, etc. */
} Device; } Device;
#define MEMORY_SIZE (640 * 480 + 65536) #define MEMORY_SIZE ((640 * 480) + 65536)
#define CODE_SIZE 8192 #define CODE_SIZE 8192
#define FRAMES_SIZE 128 #define FRAMES_SIZE 128
#define STACK_SIZE 256 #define STACK_SIZE 256

277
src/vm.c
View File

@ -1,6 +1,8 @@
#include "vm.h" #include "vm.h"
#include "device.h" #include "device.h"
#include <string.h> #include "fixed.h"
#include "opcodes.h"
#include <stdint.h>
/* no inline fn in ANSI C :( */ /* no inline fn in ANSI C :( */
#define COMPARE_AND_JUMP(type, accessor, op) \ #define COMPARE_AND_JUMP(type, accessor, op) \
@ -12,17 +14,6 @@
return true; \ return true; \
} while (0) } while (0)
#define MATH_OP(accessor, op) \
do { \
vm->frames[vm->fp].registers[dest].accessor = \
vm->frames[vm->fp] \
.registers[src1] \
.accessor op vm->frames[vm->fp] \
.registers[src2] \
.accessor; \
return true; \
} while (0)
/** /**
* Embeds a string into the VM * Embeds a string into the VM
*/ */
@ -49,11 +40,17 @@ uint32_t str_alloc(VM *vm, const char *str, uint32_t length) {
vm->memory[str_addr].u = length; vm->memory[str_addr].u = length;
vm->frames[vm->fp].allocated.end = vm->mp; vm->frames[vm->fp].allocated.end = vm->mp;
return str_addr; return str_addr;
} }
uint32_t real_alloc(VM *vm, float v) { uint32_t float_as_real_alloc(VM *vm, float v) {
uint32_t addr = vm->mp;
vm->memory[vm->mp++].f = float_to_fixed(v);
vm->frames[vm->fp].allocated.end++;
return addr;
}
uint32_t real_alloc(VM *vm, fixed_t v) {
uint32_t addr = vm->mp; uint32_t addr = vm->mp;
vm->memory[vm->mp++].f = v; vm->memory[vm->mp++].f = v;
vm->frames[vm->fp].allocated.end++; vm->frames[vm->fp].allocated.end++;
@ -74,6 +71,94 @@ uint32_t int_alloc(VM *vm, int32_t v) {
return addr; return addr;
} }
#define MAX_LEN_INT32 12 /* -2147483648 plus null terminator */
#define MAX_LEN_UINT32 11 /* 4294967295 plus null terminator */
#define MAX_LEN_FIXED 20 /* Enough for fixed-point representation */
const char radix_set[11] = "0123456789";
/* Convert int32 to string */
uint32_t int_to_string(VM *vm, int32_t v) {
char buffer[MAX_LEN_INT32] = {0};
int32_t n = v;
bool neg = n < 0;
if (neg)
n = -n;
int i = MAX_LEN_INT32;
do {
buffer[--i] = radix_set[n % 10];
n /= 10;
} while (n > 0);
if (neg)
buffer[--i] = '-';
/* Ensure at least one digit is written for 0 */
if (v == 0)
buffer[--i] = '0';
uint32_t len = MAX_LEN_INT32 - i;
return str_alloc(vm, buffer + i, len);
}
/* Convert uint32 to string */
uint32_t nat_to_string(VM *vm, uint32_t v) {
char buffer[MAX_LEN_INT32] = {0};
uint32_t n = v;
int i = MAX_LEN_INT32;
do {
buffer[--i] = radix_set[n % 10];
n /= 10;
} while (n > 0);
/* Ensure at least one digit is written for 0 */
if (v == 0)
buffer[--i] = '0';
uint32_t len = MAX_LEN_INT32 - i;
return str_alloc(vm, buffer + i, len);
}
/* Convert fixed-point to string */
uint32_t real_to_string(VM *vm, fixed_t q) {
char buffer[MAX_LEN_FIXED] = {0};
/* Extract integer part (top 16 bits) */
int32_t int_part = q >> 16;
/* Extract fractional part (bottom 16 bits) */
int32_t frac_part = q & 0xFFFF;
int32_t n = frac_part;
bool neg = n < 0;
if (neg)
n = -n;
int i = MAX_LEN_FIXED;
do {
buffer[--i] = radix_set[n % 10];
n /= 10;
} while (n > 0);
if (neg)
buffer[--i] = '-';
/* Ensure at least one digit is written for 0 */
if (frac_part == 0)
buffer[--i] = '0';
/* Convert integer part to string (reverse order) */
do {
buffer[--i] = radix_set[int_part % 10];
int_part /= 10;
} while (int_part > 0);
/* Ensure at least one digit is written for 0 */
if (int_part == 0)
buffer[--i] = '0';
/* Null-terminate */
buffer[i] = '\0';
int32_t len = (MAX_LEN_INT32 - i);
printf("i=%d, len=%d", i, len);
return str_alloc(vm, buffer + i, len);
}
/** /**
* Step to the next opcode in the vm. * Step to the next opcode in the vm.
*/ */
@ -108,7 +193,9 @@ bool step_vm(VM *vm) {
return true; return true;
} }
case OP_LOAD: { case OP_LOAD: {
vm->frames[vm->fp].registers[dest].u = vm->code[vm->pc++].u; uint32_t ptr = vm->code[vm->pc++].u;
Value v = vm->memory[ptr];
vm->frames[vm->fp].registers[dest] = v;
return true; return true;
} }
case OP_STORE: { case OP_STORE: {
@ -134,11 +221,13 @@ bool step_vm(VM *vm) {
return true; return true;
} }
case OP_PUSH: { case OP_PUSH: {
vm->stack[++vm->sp] = vm->frames[vm->fp].registers[dest]; Value v = vm->frames[vm->fp].registers[dest];
vm->stack[++vm->sp] = v;
return true; return true;
} }
case OP_POP: { case OP_POP: {
vm->frames[vm->fp].registers[dest] = vm->stack[vm->sp--]; Value v = vm->stack[vm->sp--];
vm->frames[vm->fp].registers[dest] = v;
return true; return true;
} }
case OP_MEM_ALLOC: { case OP_MEM_ALLOC: {
@ -317,48 +406,98 @@ bool step_vm(VM *vm) {
} }
return true; return true;
} }
case OP_ADD_INT: case OP_ADD_INT: {
MATH_OP(i, +); vm->frames[vm->fp].registers[dest].i =
case OP_SUB_INT: vm->frames[vm->fp].registers[src1].i +
MATH_OP(i, -); vm->frames[vm->fp].registers[src2].i;
case OP_MUL_INT: return true;
MATH_OP(i, *); }
case OP_DIV_INT: case OP_SUB_INT:{
MATH_OP(i, /); vm->frames[vm->fp].registers[dest].i =
case OP_ADD_UINT: vm->frames[vm->fp].registers[src1].i -
MATH_OP(u, +); vm->frames[vm->fp].registers[src2].i;
case OP_SUB_UINT: return true;
MATH_OP(u, -); }
case OP_MUL_UINT: case OP_MUL_INT:{
MATH_OP(u, *); vm->frames[vm->fp].registers[dest].i =
case OP_DIV_UINT: vm->frames[vm->fp].registers[src1].i *
MATH_OP(u, /); vm->frames[vm->fp].registers[src2].i;
case OP_ADD_REAL: return true;
MATH_OP(f, +); }
case OP_SUB_REAL: case OP_DIV_INT:{
MATH_OP(f, -); vm->frames[vm->fp].registers[dest].i =
case OP_MUL_REAL: vm->frames[vm->fp].registers[src1].i /
MATH_OP(f, *); vm->frames[vm->fp].registers[src2].i;
case OP_DIV_REAL: return true;
MATH_OP(f, /); }
case OP_ADD_UINT:{
vm->frames[vm->fp].registers[dest].u =
vm->frames[vm->fp].registers[src1].u +
vm->frames[vm->fp].registers[src2].u;
return true;
}
case OP_SUB_UINT:{
vm->frames[vm->fp].registers[dest].u =
vm->frames[vm->fp].registers[src1].u -
vm->frames[vm->fp].registers[src2].u;
return true;
}
case OP_MUL_UINT:{
vm->frames[vm->fp].registers[dest].u =
vm->frames[vm->fp].registers[src1].u *
vm->frames[vm->fp].registers[src2].u;
return true;
}
case OP_DIV_UINT:{
vm->frames[vm->fp].registers[dest].u =
vm->frames[vm->fp].registers[src1].u /
vm->frames[vm->fp].registers[src2].u;
return true;
}
case OP_ADD_REAL:{
vm->frames[vm->fp].registers[dest].f =
fixed_add(vm->frames[vm->fp].registers[src1].f,
vm->frames[vm->fp].registers[src2].f);
return true;
}
case OP_SUB_REAL:{
vm->frames[vm->fp].registers[dest].f =
fixed_sub(vm->frames[vm->fp].registers[src1].f,
vm->frames[vm->fp].registers[src2].f);
return true;
}
case OP_MUL_REAL: {
vm->frames[vm->fp].registers[dest].f =
fixed_mul(vm->frames[vm->fp].registers[src1].f,
vm->frames[vm->fp].registers[src2].f);
return true;
}
case OP_DIV_REAL: {
vm->frames[vm->fp].registers[dest].f =
fixed_div(vm->frames[vm->fp].registers[src1].f,
vm->frames[vm->fp].registers[src2].f);
return true;
}
case OP_REAL_TO_INT: { case OP_REAL_TO_INT: {
vm->frames[vm->fp].registers[dest].i = vm->frames[vm->fp].registers[dest].i =
(int32_t)(vm->frames[vm->fp].registers[src1].f); fixed_to_int(vm->frames[vm->fp].registers[src1].f);
return true; return true;
} }
case OP_INT_TO_REAL: { case OP_INT_TO_REAL: {
vm->frames[vm->fp].registers[dest].f = vm->frames[vm->fp].registers[dest].f =
(float)(vm->frames[vm->fp].registers[src1].i); int_to_fixed(vm->frames[vm->fp].registers[src1].i);
return true; return true;
} }
case OP_REAL_TO_UINT: { case OP_REAL_TO_UINT: {
fixed_t f = vm->frames[vm->fp].registers[src1].f;
int32_t i = fixed_to_int(f);
vm->frames[vm->fp].registers[dest].u = vm->frames[vm->fp].registers[dest].u =
(uint32_t)(vm->frames[vm->fp].registers[src1].f); (uint32_t)i;
return true; return true;
} }
case OP_UINT_TO_REAL: { case OP_UINT_TO_REAL: {
vm->frames[vm->fp].registers[dest].f = vm->frames[vm->fp].registers[dest].f =
(float)(vm->frames[vm->fp].registers[src1].u); int_to_fixed(vm->frames[vm->fp].registers[src1].u);
return true; return true;
} }
case OP_REG_SWAP: { case OP_REG_SWAP: {
@ -420,38 +559,48 @@ bool step_vm(VM *vm) {
COMPARE_AND_JUMP(int32_t, i, ==); COMPARE_AND_JUMP(int32_t, i, ==);
} }
case OP_JGT_REAL: { case OP_JGT_REAL: {
COMPARE_AND_JUMP(float, u, >); fixed_t value = vm->frames[vm->fp].registers[src1].f;
fixed_t value2 = vm->frames[vm->fp].registers[src2].f;
vm->pc =
fixed_gt(value, value2) ? vm->frames[vm->fp].registers[dest].u : vm->pc;
return true;
} }
case OP_JLT_REAL: { case OP_JLT_REAL: {
COMPARE_AND_JUMP(float, u, <); fixed_t value = vm->frames[vm->fp].registers[src1].f;
fixed_t value2 = vm->frames[vm->fp].registers[src2].f;
vm->pc =
fixed_lt(value, value2) ? vm->frames[vm->fp].registers[dest].u : vm->pc;
return true;
} }
case OP_JGE_REAL: { case OP_JGE_REAL: {
COMPARE_AND_JUMP(float, u, >=); fixed_t value = vm->frames[vm->fp].registers[src1].f;
fixed_t value2 = vm->frames[vm->fp].registers[src2].f;
vm->pc =
fixed_ge(value, value2) ? vm->frames[vm->fp].registers[dest].u : vm->pc;
return true;
} }
case OP_JLE_REAL: { case OP_JLE_REAL: {
COMPARE_AND_JUMP(float, u, <=); fixed_t value = vm->frames[vm->fp].registers[src1].f;
fixed_t value2 = vm->frames[vm->fp].registers[src2].f;
vm->pc =
fixed_le(value, value2) ? vm->frames[vm->fp].registers[dest].u : vm->pc;
return true;
} }
case OP_INT_TO_STRING: { case OP_INT_TO_STRING: {
int32_t a = (int32_t)vm->frames[vm->fp].registers[src1].i; /* get value */ int32_t a = vm->frames[vm->fp].registers[src1].i;
char buffer[32]; uint32_t ptr = int_to_string(vm, a);
int len = sprintf(buffer, "%d", a);
uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */
vm->frames[vm->fp].registers[dest].u = ptr; vm->frames[vm->fp].registers[dest].u = ptr;
return true; return true;
} }
case OP_UINT_TO_STRING: { case OP_UINT_TO_STRING: {
uint32_t a = (uint32_t)vm->frames[vm->fp].registers[src1].u; /* get value */ uint32_t a = vm->frames[vm->fp].registers[src1].u;
char buffer[32]; uint32_t ptr = nat_to_string(vm, a);
int len = sprintf(buffer, "%d", a);
uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */
vm->frames[vm->fp].registers[dest].u = ptr; vm->frames[vm->fp].registers[dest].u = ptr;
return true; return true;
} }
case OP_REAL_TO_STRING: { case OP_REAL_TO_STRING: {
float a = (float)vm->frames[vm->fp].registers[src1].f; /* get value */ fixed_t a = vm->frames[vm->fp].registers[src1].f;
char buffer[32]; uint32_t ptr = real_to_string(vm, a);
int len = sprintf(buffer, "%f", a);
uint32_t ptr = str_alloc(vm, buffer, len); /* copy buffer to dest */
vm->frames[vm->fp].registers[dest].u = ptr; vm->frames[vm->fp].registers[dest].u = ptr;
return true; return true;
} }
@ -484,7 +633,7 @@ bool step_vm(VM *vm) {
return true; return true;
} }
case OP_DBG_PRINT_STRING: { case OP_DBG_PRINT_STRING: {
uint32_t ptr = (uint32_t)vm->frames[vm->fp].registers[src1].u; uint32_t ptr = vm->frames[vm->fp].registers[src1].u;
uint32_t length = vm->memory[ptr].u; uint32_t length = vm->memory[ptr].u;
uint32_t str_src = ptr + 1; uint32_t str_src = ptr + 1;
uint32_t i; uint32_t i;
@ -498,8 +647,8 @@ bool step_vm(VM *vm) {
return true; return true;
} }
case OP_CMP_STRING: { case OP_CMP_STRING: {
uint32_t addr1 = (uint32_t)vm->frames[vm->fp].registers[src1].u; uint32_t addr1 = vm->frames[vm->fp].registers[src1].u;
uint32_t addr2 = (uint32_t)vm->frames[vm->fp].registers[src2].u; uint32_t addr2 = vm->frames[vm->fp].registers[src2].u;
uint32_t length1 = vm->memory[addr1 - 1].u; uint32_t length1 = vm->memory[addr1 - 1].u;
uint32_t length2 = vm->memory[addr2 - 1].u; uint32_t length2 = vm->memory[addr2 - 1].u;
uint32_t equal = uint32_t equal =

View File

@ -6,7 +6,8 @@
VM* init_vm(); VM* init_vm();
bool step_vm(VM *vm); bool step_vm(VM *vm);
uint32_t str_alloc(VM *vm, const char *str, uint32_t length); uint32_t str_alloc(VM *vm, const char *str, uint32_t length);
uint32_t real_alloc(VM *vm, float v); uint32_t float_as_real_alloc(VM *vm, float v);
uint32_t real_alloc(VM *vm, fixed_t v);
uint32_t nat_alloc(VM *vm, uint32_t v); uint32_t nat_alloc(VM *vm, uint32_t v);
uint32_t int_alloc(VM *vm, int32_t v); uint32_t int_alloc(VM *vm, int32_t v);