WIP Code generation, 'simple' works
This commit is contained in:
parent
2e5eb03227
commit
f901dafa2b
|
|
@ -1,4 +0,0 @@
|
||||||
(lambda add-two (a b)
|
|
||||||
(return (+ a b)))
|
|
||||||
|
|
||||||
(print (to-string (add-two 1 1)))
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
(lambda fib (n)
|
|
||||||
(if (n < 2)
|
|
||||||
(return n))
|
|
||||||
(return (+ (fib (- n 2)) (fib (- n 1)))))
|
|
||||||
|
|
||||||
(print (fib 36))
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
(print "nuqneH 'u'?")
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
(print (+ 1.0 2.0))
|
|
||||||
|
|
@ -163,25 +163,6 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init_vm(VM *vm) {
|
|
||||||
vm->memory = (u8 *)malloc(MEMORY_SIZE * sizeof(u8));
|
|
||||||
vm->memory_size = MEMORY_SIZE;
|
|
||||||
|
|
||||||
vm->code = (u8 *)malloc(CODE_SIZE * sizeof(u8));
|
|
||||||
vm->code_size = CODE_SIZE;
|
|
||||||
|
|
||||||
vm->frames = (Frame *)malloc(FRAMES_SIZE * sizeof(Frame));
|
|
||||||
vm->frames_size = FRAMES_SIZE;
|
|
||||||
|
|
||||||
vm->stack = (u32 *)malloc(STACK_SIZE * sizeof(u32));
|
|
||||||
vm->stack_size = STACK_SIZE;
|
|
||||||
|
|
||||||
vm->devices = (Device *)malloc(DEVICES_SIZE * sizeof(Device));
|
|
||||||
vm->device_size = DEVICES_SIZE;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 main(i32 argc, char *argv[]) {
|
i32 main(i32 argc, char *argv[]) {
|
||||||
bool dump_rom = false;
|
bool dump_rom = false;
|
||||||
char *input_file = nil;
|
char *input_file = nil;
|
||||||
|
|
@ -212,11 +193,6 @@ i32 main(i32 argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VM vm = {0};
|
VM vm = {0};
|
||||||
if (!init_vm(&vm)) {
|
|
||||||
printf("vm did not initialize for some reason.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool compilation_success = true;
|
bool compilation_success = true;
|
||||||
if (input_file) {
|
if (input_file) {
|
||||||
if (is_rom) {
|
if (is_rom) {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -30,6 +30,7 @@ typedef struct symbol_tab_s SymbolTable;
|
||||||
#define MAX_SYMBOL_NAME_LENGTH 64
|
#define MAX_SYMBOL_NAME_LENGTH 64
|
||||||
struct symbol_s {
|
struct symbol_s {
|
||||||
char name[MAX_SYMBOL_NAME_LENGTH];
|
char name[MAX_SYMBOL_NAME_LENGTH];
|
||||||
|
u8 name_length;
|
||||||
SymbolType type;
|
SymbolType type;
|
||||||
ScopeType scope;
|
ScopeType scope;
|
||||||
u32 ref; // vm->mp if global, vm->pc local, register if var
|
u32 ref; // vm->mp if global, vm->pc local, register if var
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,16 @@ static TokenType identifierType() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
if (lexer.current - lexer.start > 1) {
|
||||||
|
switch (lexer.start[1]) {
|
||||||
|
case 'y':
|
||||||
|
return check_keyword(2, 2, "te", TOKEN_TYPE_U8);
|
||||||
|
case 'o':
|
||||||
|
return check_keyword(2, 2, "ol", TOKEN_TYPE_U8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
return check_keyword(1, 5, "lobal", TOKEN_KEYWORD_GLOBAL);
|
return check_keyword(1, 5, "lobal", TOKEN_KEYWORD_GLOBAL);
|
||||||
case 'l':
|
case 'l':
|
||||||
|
|
|
||||||
|
|
@ -150,16 +150,11 @@ typedef struct vm_s {
|
||||||
u32 mp; /* memory pointer (last allocated value) */
|
u32 mp; /* memory pointer (last allocated value) */
|
||||||
u32 dc; /* device count */
|
u32 dc; /* device count */
|
||||||
i32 flag; /* flag (temporary results like SYSCALL status) */
|
i32 flag; /* flag (temporary results like SYSCALL status) */
|
||||||
Frame *frames; /* function call frames */
|
Frame frames[FRAMES_SIZE]; /* function call frames */
|
||||||
u32 frames_size; /* max frames */
|
u32 stack[STACK_SIZE]; /* main stack */
|
||||||
u32 *stack; /* main stack */
|
Device devices[DEVICES_SIZE]; /* device definitions */
|
||||||
u32 stack_size; /* max stack */
|
u8 code[CODE_SIZE]; /* code block */
|
||||||
Device *devices; /* device definitions */
|
u8 memory[MEMORY_SIZE]; /* memory block */
|
||||||
u32 device_size; /* max devices */
|
|
||||||
u8 *code; /* code block */
|
|
||||||
u32 code_size; /* max code size */
|
|
||||||
u8 *memory; /* memory block */
|
|
||||||
u32 memory_size; /* max memory size */
|
|
||||||
} VM;
|
} VM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
576
src/vm/vm.c
576
src/vm/vm.c
|
|
@ -27,26 +27,28 @@
|
||||||
|
|
||||||
#define MATH_OP(type, op) \
|
#define MATH_OP(type, op) \
|
||||||
do { \
|
do { \
|
||||||
|
u8 src1, src2, dest; \
|
||||||
u32 *regs = frame->locals; \
|
u32 *regs = frame->locals; \
|
||||||
dest = read_u8(vm, code, vm->pc); \
|
|
||||||
vm->pc++; \
|
|
||||||
src1 = read_u8(vm, code, vm->pc); \
|
src1 = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
src2 = read_u8(vm, code, vm->pc); \
|
src2 = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
|
dest = read_u8(vm, code, vm->pc); \
|
||||||
|
vm->pc++; \
|
||||||
regs[dest] = (type)regs[src1] op(type) regs[src2]; \
|
regs[dest] = (type)regs[src1] op(type) regs[src2]; \
|
||||||
return true; \
|
return true; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define BIT_OP(op) \
|
#define BIT_OP(op) \
|
||||||
do { \
|
do { \
|
||||||
|
u8 src1, src2, dest; \
|
||||||
u32 *regs = frame->locals; \
|
u32 *regs = frame->locals; \
|
||||||
dest = read_u8(vm, code, vm->pc); \
|
|
||||||
vm->pc++; \
|
|
||||||
src1 = read_u8(vm, code, vm->pc); \
|
src1 = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
src2 = read_u8(vm, code, vm->pc); \
|
src2 = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
|
dest = read_u8(vm, code, vm->pc); \
|
||||||
|
vm->pc++; \
|
||||||
regs[dest] = regs[src1] op regs[src2]; \
|
regs[dest] = regs[src1] op regs[src2]; \
|
||||||
return true; \
|
return true; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
@ -83,14 +85,9 @@ u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length) {
|
||||||
* Step to the next opcode in the vm.
|
* Step to the next opcode in the vm.
|
||||||
*/
|
*/
|
||||||
bool step_vm(VM *vm) {
|
bool step_vm(VM *vm) {
|
||||||
u16 opcode, dest, src1, src2;
|
|
||||||
u32 v, ptr;
|
|
||||||
i32 value;
|
|
||||||
Frame *frame;
|
|
||||||
|
|
||||||
/* Get current instruction & Advance to next instruction */
|
/* Get current instruction & Advance to next instruction */
|
||||||
opcode = vm->code[vm->pc++];
|
u8 opcode = vm->code[vm->pc++];
|
||||||
frame = &vm->frames[vm->fp];
|
Frame *frame = &vm->frames[vm->fp];
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case OP_EXIT: {
|
case OP_EXIT: {
|
||||||
|
|
@ -177,12 +174,23 @@ bool step_vm(VM *vm) {
|
||||||
vm->fp--;
|
vm->fp--;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_MALLOC: {
|
case OP_LOAD_IMM: {
|
||||||
u32 size;
|
u32 v;
|
||||||
|
u8 dest;
|
||||||
|
v = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
frame->locals[dest] = v;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_MALLOC: {
|
||||||
|
u8 src1, dest;
|
||||||
|
u32 size;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
frame->locals[dest] = vm->mp;
|
frame->locals[dest] = vm->mp;
|
||||||
size = frame->locals[src1];
|
size = frame->locals[src1];
|
||||||
write_u32(vm, memory, vm->mp, size);
|
write_u32(vm, memory, vm->mp, size);
|
||||||
|
|
@ -192,9 +200,9 @@ bool step_vm(VM *vm) {
|
||||||
}
|
}
|
||||||
case OP_MEMSET_32: {
|
case OP_MEMSET_32: {
|
||||||
u32 i, start, end;
|
u32 i, start, end;
|
||||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
|
||||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
|
||||||
u32 dest = frame->locals[dest_reg];
|
u32 dest = frame->locals[dest_reg];
|
||||||
u32 value = frame->locals[value_reg];
|
u32 value = frame->locals[value_reg];
|
||||||
|
|
@ -221,11 +229,250 @@ bool step_vm(VM *vm) {
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case OP_LOAD_ABS_32: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest;
|
||||||
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
v = read_u32(vm, memory, ptr);
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
frame->locals[dest] = v;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_LOAD_ABS_16: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest;
|
||||||
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
v = read_u16(vm, memory, ptr);
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
frame->locals[dest] = v;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_LOAD_ABS_8: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest;
|
||||||
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
v = read_u8(vm, memory, ptr);
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
frame->locals[dest] = v;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_LOAD_IND_32: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
ptr = read_u32(vm, memory, v);
|
||||||
|
frame->locals[dest] = ptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_LOAD_IND_16: {
|
||||||
|
u32 v;
|
||||||
|
u8 dest, src1;
|
||||||
|
u16 v16;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
v16 = read_u16(vm, memory, v);
|
||||||
|
frame->locals[dest] = v16;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_LOAD_IND_8: {
|
||||||
|
u32 v;
|
||||||
|
u8 dest, src1;
|
||||||
|
u8 v8;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
v8 = read_u8(vm, memory, v);
|
||||||
|
frame->locals[dest] = v8;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_LOAD_OFF_8: {
|
||||||
|
u32 v;
|
||||||
|
u8 dest, src1;
|
||||||
|
u32 offset;
|
||||||
|
u8 v8;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
offset = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
v8 = read_u8(vm, memory, (v + offset));
|
||||||
|
frame->locals[dest] = v8;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_LOAD_OFF_16: {
|
||||||
|
u32 v;
|
||||||
|
u8 dest, src1;
|
||||||
|
u32 offset;
|
||||||
|
u16 v16;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
offset = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
v16 = read_u16(vm, memory, (v + offset));
|
||||||
|
frame->locals[dest] = v16;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_LOAD_OFF_32: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
u32 offset;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
offset = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
ptr = read_u32(vm, memory, (v + offset));
|
||||||
|
frame->locals[dest] = ptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_ABS_32: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
write_u32(vm, memory, ptr, v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_ABS_16: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
write_u16(vm, memory, ptr, v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_ABS_8: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
v = frame->locals[src1];
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
write_u8(vm, memory, ptr, v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_IND_32: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
v = frame->locals[src1];
|
||||||
|
write_u32(vm, memory, ptr, v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_IND_16: {
|
||||||
|
u32 ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
u16 v16;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
v16 = frame->locals[src1];
|
||||||
|
write_u16(vm, memory, ptr, v16);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_IND_8: {
|
||||||
|
u32 ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
u8 v8;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
v8 = frame->locals[src1];
|
||||||
|
write_u8(vm, memory, ptr, v8);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_OFF_8: {
|
||||||
|
u32 ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
u32 offset;
|
||||||
|
u8 v8;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
offset = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
v8 = frame->locals[src1];
|
||||||
|
write_u8(vm, memory, (ptr + offset), v8);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_OFF_16: {
|
||||||
|
u32 ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
u32 offset;
|
||||||
|
u16 v16;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
offset = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
v16 = frame->locals[src1];
|
||||||
|
write_u16(vm, memory, (ptr + offset), v16);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case OP_STORE_OFF_32: {
|
||||||
|
u32 v, ptr;
|
||||||
|
u8 dest, src1;
|
||||||
|
u32 offset;
|
||||||
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
offset = read_u32(vm, code, vm->pc);
|
||||||
|
vm->pc += 4;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
ptr = frame->locals[dest];
|
||||||
|
v = frame->locals[src1];
|
||||||
|
write_u32(vm, memory, (ptr + offset), v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
case OP_MEMSET_16: {
|
case OP_MEMSET_16: {
|
||||||
u32 i, start, end;
|
u32 i, start, end;
|
||||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
|
||||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
|
||||||
u32 dest = frame->locals[dest_reg];
|
u32 dest = frame->locals[dest_reg];
|
||||||
u16 value = (u16)(frame->locals[value_reg]);
|
u16 value = (u16)(frame->locals[value_reg]);
|
||||||
|
|
@ -254,9 +501,9 @@ bool step_vm(VM *vm) {
|
||||||
}
|
}
|
||||||
case OP_MEMSET_8: {
|
case OP_MEMSET_8: {
|
||||||
u32 i, start, end;
|
u32 i, start, end;
|
||||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
|
||||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
|
||||||
u32 dest = frame->locals[dest_reg];
|
u32 dest = frame->locals[dest_reg];
|
||||||
u8 value = (u8)(frame->locals[value_reg]);
|
u8 value = (u8)(frame->locals[value_reg]);
|
||||||
|
|
@ -283,222 +530,12 @@ bool step_vm(VM *vm) {
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_IMM: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
v = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
frame->locals[dest] = v;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_ABS_32: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
v = read_u32(vm, memory, ptr);
|
|
||||||
frame->locals[dest] = v;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_ABS_16: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
v = read_u16(vm, memory, ptr);
|
|
||||||
frame->locals[dest] = v;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_ABS_8: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
v = read_u8(vm, memory, ptr);
|
|
||||||
frame->locals[dest] = v;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_IND_32: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
ptr = read_u32(vm, memory, v);
|
|
||||||
frame->locals[dest] = ptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_IND_16: {
|
|
||||||
u16 v16;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
v16 = read_u16(vm, memory, v);
|
|
||||||
frame->locals[dest] = v16;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_IND_8: {
|
|
||||||
u8 v8;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
v8 = read_u8(vm, memory, v);
|
|
||||||
frame->locals[dest] = v8;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_OFF_8: {
|
|
||||||
u32 offset;
|
|
||||||
u8 v8;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
offset = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
v8 = read_u8(vm, memory, (v + offset));
|
|
||||||
frame->locals[dest] = v8;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_OFF_16: {
|
|
||||||
u32 offset;
|
|
||||||
u16 v16;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
offset = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
v16 = read_u16(vm, memory, (v + offset));
|
|
||||||
frame->locals[dest] = v16;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_LOAD_OFF_32: {
|
|
||||||
u32 offset;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
offset = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
ptr = read_u32(vm, memory, (v + offset));
|
|
||||||
frame->locals[dest] = ptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_ABS_32: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
write_u32(vm, memory, ptr, v);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_ABS_16: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
write_u16(vm, memory, ptr, v);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_ABS_8: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
v = frame->locals[src1];
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
write_u8(vm, memory, ptr, v);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_IND_32: {
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
v = frame->locals[src1];
|
|
||||||
write_u32(vm, memory, ptr, v);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_IND_16: {
|
|
||||||
u16 v16;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
v16 = frame->locals[src1];
|
|
||||||
write_u16(vm, memory, ptr, v16);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_IND_8: {
|
|
||||||
u8 v8;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
v8 = frame->locals[src1];
|
|
||||||
write_u8(vm, memory, ptr, v8);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_OFF_8: {
|
|
||||||
u32 offset;
|
|
||||||
u8 v8;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
offset = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
v8 = frame->locals[src1];
|
|
||||||
write_u8(vm, memory, (ptr + offset), v8);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_OFF_16: {
|
|
||||||
u32 offset;
|
|
||||||
u16 v16;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
offset = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
v16 = frame->locals[src1];
|
|
||||||
write_u16(vm, memory, (ptr + offset), v16);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_STORE_OFF_32: {
|
|
||||||
u32 offset;
|
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
offset = read_u32(vm, code, vm->pc);
|
|
||||||
vm->pc += 4;
|
|
||||||
ptr = frame->locals[dest];
|
|
||||||
v = frame->locals[src1];
|
|
||||||
write_u32(vm, memory, (ptr + offset), v);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OP_REG_MOV: {
|
case OP_REG_MOV: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1;
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
frame->locals[dest] = frame->locals[src1];
|
frame->locals[dest] = frame->locals[src1];
|
||||||
|
|
||||||
if (is_heap_value(vm, src1)) {
|
if (is_heap_value(vm, src1)) {
|
||||||
|
|
@ -532,12 +569,12 @@ bool step_vm(VM *vm) {
|
||||||
Device *dev;
|
Device *dev;
|
||||||
u32 path_ptr, mode, device_ptr;
|
u32 path_ptr, mode, device_ptr;
|
||||||
u8 path_reg, mode_reg, dest_reg;
|
u8 path_reg, mode_reg, dest_reg;
|
||||||
dest_reg = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
path_reg = read_u8(vm, code, vm->pc);
|
path_reg = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
mode_reg = read_u8(vm, code, vm->pc);
|
mode_reg = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
path_ptr = frame->locals[path_reg];
|
path_ptr = frame->locals[path_reg];
|
||||||
mode = frame->locals[mode_reg];
|
mode = frame->locals[mode_reg];
|
||||||
|
|
@ -715,10 +752,12 @@ bool step_vm(VM *vm) {
|
||||||
case OP_DIV_INT:
|
case OP_DIV_INT:
|
||||||
MATH_OP(i32, /);
|
MATH_OP(i32, /);
|
||||||
case OP_ABS_INT: {
|
case OP_ABS_INT: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1;
|
||||||
vm->pc++;
|
i32 value;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
value = frame->locals[src1];
|
value = frame->locals[src1];
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
|
|
@ -729,10 +768,12 @@ bool step_vm(VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_NEG_INT: {
|
case OP_NEG_INT: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1;
|
||||||
vm->pc++;
|
i32 value;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
value = frame->locals[src1];
|
value = frame->locals[src1];
|
||||||
frame->locals[dest] = -value;
|
frame->locals[dest] = -value;
|
||||||
|
|
@ -747,53 +788,59 @@ bool step_vm(VM *vm) {
|
||||||
case OP_DIV_NAT:
|
case OP_DIV_NAT:
|
||||||
MATH_OP(u32, /);
|
MATH_OP(u32, /);
|
||||||
case OP_MUL_REAL: {
|
case OP_MUL_REAL: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1, src2;
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
frame->locals[dest] = fixed_mul(frame->locals[src1], frame->locals[src2]);
|
frame->locals[dest] = fixed_mul(frame->locals[src1], frame->locals[src2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_DIV_REAL: {
|
case OP_DIV_REAL: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1, src2;
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
frame->locals[dest] = fixed_div(frame->locals[src1], frame->locals[src2]);
|
frame->locals[dest] = fixed_div(frame->locals[src1], frame->locals[src2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_ADD_REAL: {
|
case OP_ADD_REAL: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1, src2;
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
frame->locals[dest] = fixed_add(frame->locals[src1], frame->locals[src2]);
|
frame->locals[dest] = fixed_add(frame->locals[src1], frame->locals[src2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OP_SUB_REAL: {
|
case OP_SUB_REAL: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1, src2;
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
frame->locals[dest] = fixed_sub(frame->locals[src1], frame->locals[src2]);
|
frame->locals[dest] = fixed_sub(frame->locals[src1], frame->locals[src2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_INT: {
|
case OP_REAL_TO_INT: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1;
|
||||||
vm->pc++;
|
i32 value;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
value = frame->locals[src1];
|
value = frame->locals[src1];
|
||||||
|
|
||||||
frame->locals[dest] = fixed_to_int(value);
|
frame->locals[dest] = fixed_to_int(value);
|
||||||
|
|
@ -801,27 +848,31 @@ bool step_vm(VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_INT_TO_REAL: {
|
case OP_INT_TO_REAL: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1;
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_NAT: {
|
case OP_REAL_TO_NAT: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1;
|
||||||
vm->pc++;
|
u32 value;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
value = frame->locals[src1];
|
value = frame->locals[src1];
|
||||||
frame->locals[dest] = fixed_to_int(value);
|
frame->locals[dest] = fixed_to_int(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_NAT_TO_REAL: {
|
case OP_NAT_TO_REAL: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
u8 dest, src1;
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -880,11 +931,13 @@ bool step_vm(VM *vm) {
|
||||||
COMPARE_AND_JUMP(i32, <=);
|
COMPARE_AND_JUMP(i32, <=);
|
||||||
}
|
}
|
||||||
case OP_INT_TO_STRING: {
|
case OP_INT_TO_STRING: {
|
||||||
|
u32 ptr;
|
||||||
|
u8 dest, src1;
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
int_to_string(AS_INT(frame->locals[src1]), buffer);
|
int_to_string(AS_INT(frame->locals[src1]), buffer);
|
||||||
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||||
frame->locals[dest] = ptr;
|
frame->locals[dest] = ptr;
|
||||||
|
|
@ -892,11 +945,13 @@ bool step_vm(VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_NAT_TO_STRING: {
|
case OP_NAT_TO_STRING: {
|
||||||
|
u32 ptr;
|
||||||
|
u8 dest, src1;
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
nat_to_string(frame->locals[src1], buffer);
|
nat_to_string(frame->locals[src1], buffer);
|
||||||
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||||
frame->locals[dest] = ptr;
|
frame->locals[dest] = ptr;
|
||||||
|
|
@ -904,11 +959,13 @@ bool step_vm(VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_STRING: {
|
case OP_REAL_TO_STRING: {
|
||||||
|
u32 ptr;
|
||||||
|
u8 dest, src1;
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
fixed_to_string(AS_INT(frame->locals[src1]), buffer);
|
fixed_to_string(AS_INT(frame->locals[src1]), buffer);
|
||||||
ptr = str_alloc(vm, frame, buffer,
|
ptr = str_alloc(vm, frame, buffer,
|
||||||
strlength(buffer)); /* copy buffer to dest */
|
strlength(buffer)); /* copy buffer to dest */
|
||||||
|
|
@ -917,11 +974,12 @@ bool step_vm(VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STRLEN: {
|
case OP_STRLEN: {
|
||||||
|
u8 dest, src1;
|
||||||
u32 ptr, length;
|
u32 ptr, length;
|
||||||
dest = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
dest = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
ptr = frame->locals[src1];
|
ptr = frame->locals[src1];
|
||||||
length = read_u32(vm, memory, ptr);
|
length = read_u32(vm, memory, ptr);
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,11 @@ global int x = 1;
|
||||||
global int y = 1;
|
global int y = 1;
|
||||||
|
|
||||||
function main ()
|
function main ()
|
||||||
int ans $2;
|
|
||||||
str ans_string $3;
|
|
||||||
|
|
||||||
load_absolute_32 x -> $0;
|
load_absolute_32 x -> $0;
|
||||||
load_absolute_32 y -> $1;
|
load_absolute_32 y -> $1;
|
||||||
call add $0 $1 -> ans;
|
call add $0 $1 -> $2;
|
||||||
int_to_string ans -> ans_string;
|
int_to_string $2 -> $3;
|
||||||
call pln ans_string -> void;
|
call pln $3;
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function add (int a $0, int b $1)
|
function add (int a $0, int b $1)
|
||||||
|
|
@ -20,16 +17,19 @@ function add (int a $0, int b $1)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
str term $1;
|
plex term $1;
|
||||||
int msg_length $2;
|
int msg_length $2;
|
||||||
str nl $3;
|
str nl $3;
|
||||||
int nl_length $4;
|
int nl_length $4;
|
||||||
int mode $5;
|
int mode $5;
|
||||||
|
str term_ns $6;
|
||||||
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN terminal_namespace mode -> term;
|
load_address terminal_namespace -> term_ns;
|
||||||
|
syscall OPEN term_ns mode -> term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
string_length new_line -> nl_length;
|
load_address new_line -> nl;
|
||||||
|
string_length nl -> nl_length;
|
||||||
syscall WRITE term nl nl_length;
|
syscall WRITE term nl nl_length;
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -31,19 +31,20 @@ function fib (int n $0)
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
str ts $1;
|
plex term $1;
|
||||||
int mode $5;
|
|
||||||
int msg_length $2;
|
int msg_length $2;
|
||||||
str nl $3;
|
str nl $3;
|
||||||
int nl_length $4;
|
int nl_length $4;
|
||||||
|
int mode $5;
|
||||||
|
str term_ns $6;
|
||||||
|
|
||||||
load_immediate terminal_namespace -> ts;
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN ts mode -> ts;
|
load_address terminal_namespace -> term_ns;
|
||||||
|
syscall OPEN term_ns mode -> term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE ts message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_immediate new_line -> nl;
|
load_address new_line -> nl;
|
||||||
string_length nl -> nl_length;
|
string_length nl -> nl_length;
|
||||||
syscall WRITE ts nl nl_length;
|
syscall WRITE term nl nl_length;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1,27 +1,28 @@
|
||||||
global str terminal_namespace = "/dev/term/0"
|
global str terminal_namespace = "/dev/term/0";
|
||||||
global str new_line = "\n"
|
global str new_line = "\n";
|
||||||
global str message = "nuqneH 'u'?"
|
global str message = "nuqneH 'u'?";
|
||||||
|
|
||||||
function main ()
|
function main ()
|
||||||
str hello $0;
|
str hello $0;
|
||||||
|
|
||||||
load_immediate message -> hello;
|
load_address message -> hello;
|
||||||
call pln hello -> void;
|
call pln hello;
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
str ts $1;
|
plex term $1;
|
||||||
int mode $5;
|
|
||||||
int msg_length $2;
|
int msg_length $2;
|
||||||
str nl $3;
|
str nl $3;
|
||||||
int nl_length $4;
|
int nl_length $4;
|
||||||
|
int mode $5;
|
||||||
|
str term_ns $6;
|
||||||
|
|
||||||
load_immediate terminal_namespace -> ts;
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN ts mode -> ts;
|
load_address terminal_namespace -> term_ns;
|
||||||
|
syscall OPEN term_ns mode -> term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE ts message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_immediate new_line -> nl;
|
load_address new_line -> nl;
|
||||||
string_length nl -> nl_length;
|
string_length nl -> nl_length;
|
||||||
syscall WRITE ts nl nl_length;
|
syscall WRITE term nl nl_length;
|
||||||
return;
|
return;
|
||||||
|
|
@ -18,41 +18,41 @@ function main ()
|
||||||
add_int i $3 -> i;
|
add_int i $3 -> i;
|
||||||
jump_ge_int loop_body i $2;
|
jump_ge_int loop_body i $2;
|
||||||
|
|
||||||
load_immediate terminal_namespace -> term;
|
load_address terminal_namespace -> term;
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN term mode -> term; // Terminal term = open("/dev/term/0", 0);
|
syscall OPEN term mode -> term; // Terminal term = open("/dev/term/0", 0);
|
||||||
|
|
||||||
nat b $1;
|
nat b $1;
|
||||||
real_to_nat a -> b;
|
real_to_nat a -> b;
|
||||||
load_immediate prompt -> $7;
|
load_address prompt -> $7;
|
||||||
string_length $7 -> $8;
|
string_length $7 -> $8;
|
||||||
syscall WRITE term $7 $8; // print prompt
|
syscall WRITE term $7 $8; // print prompt
|
||||||
|
|
||||||
str user_string $9;
|
str user_string $9;
|
||||||
load_immediate 32 -> $8;
|
load_immediate 32 -> $8;
|
||||||
malloc $8 -> user_string;
|
malloc $8 -> user_string;
|
||||||
syscall READ term user_string; $8 // read in max 32 byte string
|
syscall READ term user_string $8; // read in max 32 byte string
|
||||||
|
|
||||||
call pln user_string -> void;
|
call pln user_string;
|
||||||
nat_to_string b -> $4;
|
nat_to_string b -> $4;
|
||||||
call pln $4 -> void;
|
call pln $4;
|
||||||
real_to_string a -> $3;
|
real_to_string a -> $3;
|
||||||
call pln $3 -> void;
|
call pln $3;
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0);
|
function pln (str message $0)
|
||||||
str ts $1;
|
plex term $1;
|
||||||
int mode $5;
|
|
||||||
int msg_length $2;
|
int msg_length $2;
|
||||||
str nl $3;
|
str nl $3;
|
||||||
int nl_length $4;
|
int nl_length $4;
|
||||||
|
int mode $5;
|
||||||
|
|
||||||
load_immediate terminal_namespace -> ts;
|
load_address terminal_namespace -> term;
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN ts mode -> ts;
|
syscall OPEN term mode -> term; // Terminal term = open("/dev/term/0", 0);
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE ts message msg_length ;
|
syscall WRITE term message msg_length;
|
||||||
load_immediate new_line -> nl;
|
load_address new_line -> nl;
|
||||||
string_length nl -> nl_length;
|
string_length nl -> nl_length;
|
||||||
syscall WRITE ts nl nl_length;
|
syscall WRITE term nl nl_length;
|
||||||
return;
|
return;
|
||||||
|
|
@ -23,18 +23,19 @@ function main ()
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
str ts $1;
|
plex term $1;
|
||||||
int mode $5;
|
|
||||||
int msg_length $2;
|
int msg_length $2;
|
||||||
str nl $3;
|
str nl $3;
|
||||||
int nl_length $4;
|
int nl_length $4;
|
||||||
|
int mode $5;
|
||||||
|
str term_ns $6;
|
||||||
|
|
||||||
load_immediate terminal_namespace -> ts;
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN ts mode -> ts;
|
load_address terminal_namespace -> term_ns;
|
||||||
|
syscall OPEN term_ns mode -> term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE ts message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_immediate new_line -> nl;
|
load_address new_line -> nl;
|
||||||
string_length nl -> nl_length;
|
string_length nl -> nl_length;
|
||||||
syscall WRITE ts nl nl_length;
|
syscall WRITE term nl nl_length;
|
||||||
return;
|
return;
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
* Constants
|
* Constants
|
||||||
*/
|
*/
|
||||||
const str nl = "\n";
|
const str nl = "\n";
|
||||||
const real x = 1.0;
|
|
||||||
const real y = 1.0;
|
|
||||||
|
|
||||||
plex Terminal {
|
plex Terminal {
|
||||||
nat handle;
|
nat handle;
|
||||||
|
|
@ -13,7 +11,8 @@ plex Terminal {
|
||||||
* Main function
|
* Main function
|
||||||
*/
|
*/
|
||||||
function main() {
|
function main() {
|
||||||
pln((x + y).str);
|
pln((1.0 + 1.0) as str);
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,25 @@
|
||||||
global str terminal_namespace = "/dev/term/0";
|
global str terminal_namespace = "/dev/term/0";
|
||||||
global real x = 1.0;
|
global str new_line = "\n";
|
||||||
global real y = 1.0;
|
|
||||||
|
|
||||||
function main ()
|
function main ()
|
||||||
real a $0;
|
load_immediate 1.0 -> $0;
|
||||||
load_absolute_32 x -> a;
|
load_immediate 1.0 -> $1;
|
||||||
real b $1;
|
add_real $0 $1 -> $0;
|
||||||
load_absolute_32 y -> b;
|
real_to_string $0 -> $0;
|
||||||
real result $2;
|
call pln $0;
|
||||||
add_real a b -> result;
|
|
||||||
str result_str $3;
|
|
||||||
real_to_string result -> result_str;
|
|
||||||
call pln result_str -> void;
|
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
str term $1;
|
plex term $1;
|
||||||
int msg_length $2;
|
int msg_length $2;
|
||||||
str nl $3;
|
str nl $3;
|
||||||
int nl_length $4;
|
int nl_length $4;
|
||||||
int mode $5;
|
int mode $5;
|
||||||
|
str term_ns $6;
|
||||||
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN terminal_namespace mode -> term;
|
load_address terminal_namespace -> term_ns;
|
||||||
|
syscall OPEN term_ns mode -> term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_address new_line -> nl;
|
load_address new_line -> nl;
|
||||||
|
|
|
||||||
|
|
@ -72,18 +72,19 @@ function main ()
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
str ts $1;
|
plex term $1;
|
||||||
int mode $5;
|
|
||||||
int msg_length $2;
|
int msg_length $2;
|
||||||
str nl $3;
|
str nl $3;
|
||||||
int nl_length $4;
|
int nl_length $4;
|
||||||
|
int mode $5;
|
||||||
|
str term_ns $6;
|
||||||
|
|
||||||
load_immediate terminal_namespace -> ts;
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN ts mode -> ts;
|
load_address terminal_namespace -> term_ns;
|
||||||
|
syscall OPEN term_ns mode -> term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE ts message msg_length ;
|
syscall WRITE term message msg_length;
|
||||||
load_immediate new_line -> nl;
|
load_address new_line -> nl;
|
||||||
string_length nl -> nl_length;
|
string_length nl -> nl_length;
|
||||||
syscall WRITE ts nl nl_length;
|
syscall WRITE term nl nl_length;
|
||||||
return;
|
return;
|
||||||
Loading…
Reference in New Issue