#ifndef ZRE_OPCODES_H #define ZRE_OPCODES_H #include "common.h" typedef union { int32_t i; /* Integers */ float f; /* Float */ uint32_t u; /* Unsigned integers, also used for pointer address */ char c[4]; /* 4 Byte char array for string packing */ } Value; typedef struct { uint32_t start; uint32_t end; } Slice; #define MAX_REGS 256 typedef struct { Value registers[MAX_REGS]; /* R0-R[MAX_REGS-1] */ uint32_t rp; /* register pointer (last unused) */ Slice allocated; /* start and end of global allocated block */ } Frame; #define MEMORY_SIZE 65536 #define FRAME_STACK_SIZE 32 #define RETURN_STACK_SIZE 256 typedef struct { uint32_t pc; /* Program counter */ uint32_t fp; /* Frame pointer (last allocated value) */ uint32_t rp; /* Return stack pointer (top of stack) */ uint32_t mp; /* Memory pointer (last allocated value) */ uint32_t frame_stack_size; Frame frame_stack[FRAME_STACK_SIZE]; uint32_t return_stack_size; Value return_stack[RETURN_STACK_SIZE]; uint32_t memory_size; Value memory[MEMORY_SIZE]; /* Memory array */ } VM; typedef enum { OP_HALT, /* halt : terminate execution */ OP_LOADI, /* lodi : dest = next memory location as int */ OP_LOADU, /* lodu : dest = next memory location as uint */ OP_LOADF, /* lodf : dest = next memory location as float */ OP_STOREI, /* stri : next memory location = src1 as int */ OP_STOREU, /* stru : next memory location = src1 as uint */ OP_STOREF, /* strf : next memory location = src1 as float */ OP_ADD_INT, /* addi : dest = src1 + src2 */ OP_SUB_INT, /* subs : dest = src1 - src2 */ OP_MUL_INT, /* mulm : dest = src1 * src2 */ OP_DIV_INT, /* divd : dest = src1 / src2 */ 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_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_JGE_INT, /* jgei : jump to address dest if src1 as int >= src2 as int*/ OP_INT_TO_REAL, /* itor : dest = src1 as f32 */ OP_ADD_UINT, /* addu : dest = src1 + src2 */ OP_SUB_UINT, /* subu : dest = src1 - src2 */ OP_MUL_UINT, /* mulu : dest = src1 * src2 */ OP_DIV_UINT, /* divu : dest = src1 / src2 */ 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_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_JGE_UINT, /* jgeu : jump to address dest if src1 as int >= src2 as uint*/ OP_UINT_TO_REAL, /* utor : dest = src1 as f32 */ OP_ADD_REAL, /* addr : dest = src1 + src2 */ OP_SUB_REAL, /* subr : dest = src1 - src2 */ OP_MUL_REAL, /* mulr : dest = src1 * src2 */ OP_DIV_REAL, /* divr : dest = src1 / src2 */ 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_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_JLE_REAL, /* jger : jump to address dest if src1 as real <= src2 as real */ OP_REAL_TO_INT, /* rtoi : dest = src1 as int */ OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */ OP_MOV, /* move : dest = src1 */ OP_JMP, /* jump : jump to address src1 unconditionally */ OP_CALL, /* creates a new frame */ OP_RETURN, /* returns from a frame to the parent frame */ OP_INT_TO_STRING, /* itos : dest = src1 as str */ OP_UINT_TO_STRING, /* utos : dest = src1 as str */ OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ OP_READ_STRING, /* read : dest = read as str */ OP_PRINT_STRING, /* wrte : write src1 to stdout */ OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */ } Opcode; /* defines a uint32 opcode */ #define OP(opcode, a, b, c) ((opcode << 24) | (a << 16) | (b << 8) | c) #endif