fix syscall, update opcodes, fix tests
This commit is contained in:
parent
a1266b9008
commit
f6a2cd8de9
|
@ -1,4 +1,4 @@
|
||||||
(lambda (n)
|
(lambda fib (n)
|
||||||
(if (n < 2)
|
(if (n < 2)
|
||||||
(return n))
|
(return n))
|
||||||
(return (+ (fib (- n 2)) (fib (- n 1)))))
|
(return (+ (fib (- n 2)) (fib (- n 1)))))
|
||||||
|
|
|
@ -72,25 +72,22 @@ bool test_simple_compile(VM *vm) {
|
||||||
vm->code[vm->cp++] = 3;
|
vm->code[vm->cp++] = 3;
|
||||||
vm->code[vm->cp++] = 2;
|
vm->code[vm->cp++] = 2;
|
||||||
|
|
||||||
vm->code[vm->cp++] = OP_REAL_TO_STRING;
|
|
||||||
vm->code[vm->cp++] = 3;
|
|
||||||
vm->code[vm->cp++] = 2;
|
|
||||||
|
|
||||||
vm->code[vm->cp++] = OP_LOAD_IMM;
|
|
||||||
vm->code[vm->cp++] = 2;
|
|
||||||
write_u32(vm, code, vm->cp, terminal_path_addr);
|
|
||||||
vm->cp += 4;
|
|
||||||
|
|
||||||
vm->code[vm->cp++] = OP_STRLEN;
|
vm->code[vm->cp++] = OP_STRLEN;
|
||||||
vm->code[vm->cp++] = 4;
|
vm->code[vm->cp++] = 4;
|
||||||
vm->code[vm->cp++] = 3;
|
vm->code[vm->cp++] = 3;
|
||||||
|
|
||||||
|
vm->code[vm->cp++] = OP_LOAD_IMM;
|
||||||
|
vm->code[vm->cp++] = 5;
|
||||||
|
write_u32(vm, code, vm->cp, terminal_path_addr);
|
||||||
|
vm->cp += 4;
|
||||||
|
|
||||||
vm->code[vm->cp++] = OP_SYSCALL;
|
vm->code[vm->cp++] = OP_SYSCALL;
|
||||||
write_u32(vm, code, vm->cp, AS_UINT(SYSCALL_DEVICE_WRITE));
|
write_u32(vm, code, vm->cp, AS_UINT(SYSCALL_DEVICE_WRITE));
|
||||||
vm->cp += 4;
|
vm->cp += 4;
|
||||||
vm->code[vm->cp++] = 3; /* arg_count */
|
vm->code[vm->cp++] = 5;
|
||||||
vm->code[vm->cp++] = 2; /* first_reg */
|
vm->code[vm->cp++] = 3;
|
||||||
/* syscall_id=WRITE, arg_count=2, start_reg=3 ; print(sum.toS()); */
|
vm->code[vm->cp++] = 4;
|
||||||
|
/* syscall_id=WRITE, device-str-ptr=5, ptr, length ; print(sum.toS()); */
|
||||||
vm->code[vm->cp++] = OP_HALT; /* explicit halt */
|
vm->code[vm->cp++] = OP_HALT; /* explicit halt */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -110,8 +107,8 @@ bool test_window_click_compile(VM *vm) {
|
||||||
|
|
||||||
vm->code[vm->cp++] = OP_SYSCALL;
|
vm->code[vm->cp++] = OP_SYSCALL;
|
||||||
vm->code[vm->cp++] = SYSCALL_DEVICE_OPEN;
|
vm->code[vm->cp++] = SYSCALL_DEVICE_OPEN;
|
||||||
vm->code[vm->cp++] = 0; /* first_reg */
|
vm->code[vm->cp++] = 0;
|
||||||
vm->code[vm->cp++] = 2; /* arg_count */
|
vm->code[vm->cp++] = 1;
|
||||||
|
|
||||||
test_pixel_addr = vm->mp;
|
test_pixel_addr = vm->mp;
|
||||||
vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64);
|
vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64);
|
||||||
|
@ -120,8 +117,6 @@ bool test_window_click_compile(VM *vm) {
|
||||||
vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64);
|
vm->memory[vm->mp++] = (char)((255 / 32) << 5) | ((0 / 32) << 2) | (0 / 64);
|
||||||
vm->frames[vm->fp].end += 4;
|
vm->frames[vm->fp].end += 4;
|
||||||
|
|
||||||
loop_start = vm->cp;
|
|
||||||
|
|
||||||
vm->code[vm->cp++] = OP_LOAD;
|
vm->code[vm->cp++] = OP_LOAD;
|
||||||
vm->code[vm->cp++] = 0;
|
vm->code[vm->cp++] = 0;
|
||||||
vm->code[vm->cp++] = nat_alloc(vm, screen_path_addr);
|
vm->code[vm->cp++] = nat_alloc(vm, screen_path_addr);
|
||||||
|
@ -133,15 +128,17 @@ bool test_window_click_compile(VM *vm) {
|
||||||
vm->code[vm->cp++] = OP_LOAD;
|
vm->code[vm->cp++] = OP_LOAD;
|
||||||
vm->code[vm->cp++] = 2;
|
vm->code[vm->cp++] = 2;
|
||||||
vm->code[vm->cp++] = int_alloc(vm, 1);
|
vm->code[vm->cp++] = int_alloc(vm, 1);
|
||||||
|
|
||||||
|
vm->code[vm->cp++] = OP_LOAD;
|
||||||
|
vm->code[vm->cp++] = 3;
|
||||||
|
loop_start = vm->cp + 2; /* here + after alloc */
|
||||||
|
vm->code[vm->cp++] = nat_alloc(vm, loop_start);
|
||||||
|
|
||||||
vm->code[vm->cp++] = OP_SYSCALL;
|
vm->code[vm->cp++] = OP_SYSCALL;
|
||||||
vm->code[vm->cp++] = SYSCALL_DEVICE_WRITE;
|
vm->code[vm->cp++] = SYSCALL_DEVICE_WRITE;
|
||||||
vm->code[vm->cp++] = 0; /* first_reg */
|
vm->code[vm->cp++] = 0;
|
||||||
vm->code[vm->cp++] = 3; /* arg_count */
|
vm->code[vm->cp++] = 1;
|
||||||
|
vm->code[vm->cp++] = 2;
|
||||||
vm->code[vm->cp++] = OP_LOAD;
|
|
||||||
vm->code[vm->cp++] = 3;
|
|
||||||
vm->code[vm->cp++] = nat_alloc(vm, loop_start);
|
|
||||||
|
|
||||||
vm->code[vm->cp++] = OP_JMP;
|
vm->code[vm->cp++] = OP_JMP;
|
||||||
vm->code[vm->cp++] = 3;
|
vm->code[vm->cp++] = 3;
|
||||||
|
|
112
src/vm/opcodes.h
112
src/vm/opcodes.h
|
@ -4,63 +4,61 @@
|
||||||
#include "common.h"
|
#include "common.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_JMPF, /* jmpf : jump to address dest if flag is ne 0 */
|
OP_JMPF, /* jump-if-flag : jump to address dest if flag is ne 0 */
|
||||||
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, /* return : returns from a frame to the parent frame */
|
||||||
OP_LOAD, /* load : dest = &[next memory location] */
|
OP_LOAD, /* load : dest = &[next memory location] */
|
||||||
OP_LOAD_IMM, /* load : dest = &[next memory location] */
|
OP_LOAD_IMM, /* load-immediate : dest = &[next memory location] */
|
||||||
OP_STORE, /* stor : next memory location = src1 as float */
|
OP_STORE, /* store : next memory 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, /* register-move : dest = src1 */
|
||||||
OP_SYSCALL, /* sysc : */
|
OP_SYSCALL, /* syscall : src1 src2 src3 src4 ? does a system call based on args */
|
||||||
OP_ADD_INT, /* addi : dest = src1 + src2 */
|
OP_ADD_INT, /* add-int : dest = src1 + src2 */
|
||||||
OP_SUB_INT, /* subi : dest = src1 - src2 */
|
OP_SUB_INT, /* sub-int : dest = src1 - src2 */
|
||||||
OP_MUL_INT, /* muli : dest = src1 * src2 */
|
OP_MUL_INT, /* mul-int : dest = src1 * src2 */
|
||||||
OP_DIV_INT, /* divi : dest = src1 / src2 */
|
OP_DIV_INT, /* div-int : dest = src1 / src2 */
|
||||||
OP_ADD_UINT, /* addu : dest = src1 + src2 */
|
OP_ADD_UINT, /* add-nat : dest = src1 + src2 */
|
||||||
OP_SUB_UINT, /* subu : dest = src1 - src2 */
|
OP_SUB_UINT, /* sub-nat : dest = src1 - src2 */
|
||||||
OP_MUL_UINT, /* mulu : dest = src1 * src2 */
|
OP_MUL_UINT, /* mul-nat : dest = src1 * src2 */
|
||||||
OP_DIV_UINT, /* divu : dest = src1 / src2 */
|
OP_DIV_UINT, /* div-nat : dest = src1 / src2 */
|
||||||
OP_ADD_REAL, /* addr : dest = src1 + src2 */
|
OP_ADD_REAL, /* add-real : dest = src1 + src2 */
|
||||||
OP_SUB_REAL, /* subr : dest = src1 - src2 */
|
OP_SUB_REAL, /* sub-real : dest = src1 - src2 */
|
||||||
OP_MUL_REAL, /* mulr : dest = src1 * src2 */
|
OP_MUL_REAL, /* mul-real : dest = src1 * src2 */
|
||||||
OP_DIV_REAL, /* divr : dest = src1 / src2 */
|
OP_DIV_REAL, /* div-real : dest = src1 / src2 */
|
||||||
OP_INT_TO_REAL, /* itor : dest = src1 as real */
|
OP_INT_TO_REAL, /* int-to-real : dest = src1 as real */
|
||||||
OP_UINT_TO_REAL, /* utor : dest = src1 as real */
|
OP_UINT_TO_REAL, /* nat-to-real : dest = src1 as real */
|
||||||
OP_REAL_TO_INT, /* rtoi : dest = src1 as int */
|
OP_REAL_TO_INT, /* real-to-int : dest = src1 as int */
|
||||||
OP_REAL_TO_UINT, /* rtou : dest = src1 as uint */
|
OP_REAL_TO_UINT, /* real-to-nat : dest = src1 as uint */
|
||||||
OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */
|
OP_JEQ_INT, /* jump-eq-int : 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, /* jump-gt-int : 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, /* jump-lt-int : 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, /* jump-le-int : 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, /* jump-ge-int : 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, /* jump-eq-nat : 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, /* jump-gt-nat : 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, /* jump-lt-nat : 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, /* jump-le-nat : 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, /* jump-ge-nat : 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, /* jump-eq-real : 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, /* jump-gt-real : 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, /* jump-lt-real : 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, /* jump-le-real : 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, /* jump-ge-real : jump to address dest if src1 as real <= src2 as real */
|
||||||
OP_STRLEN, /* strl : dest = length of str at src1 ptr */
|
OP_STRLEN, /* string-length : dest = length of str at src1 ptr */
|
||||||
OP_STREQ, /* steq : dest = src1 ptr string == src2 ptr string */
|
OP_STREQ, /* string-eq : dest = src1 ptr string == src2 ptr string */
|
||||||
OP_STRCAT, /* scat : dest = ptr of src1 ptr string + src2 ptr string */
|
OP_STRCAT, /* string-concat : dest = ptr of src1 ptr string + src2 ptr string */
|
||||||
OP_STR_GET_CHAR, /* sgch : dest = ptr of src1 ptr string, src2 index of string
|
OP_STR_GET_CHAR, /* string-get-char : dest = ptr of src1 ptr str, src2 index of str */
|
||||||
*/
|
OP_STR_FIND_CHAR, /* string-find-char : dest = ptr of src1 ptr string, src2 uint8 char */
|
||||||
OP_STR_FIND_CHAR, /* sfch : dest = ptr of src1 ptr string, src2 uint8 char */
|
OP_STR_SLICE, /* string-slice : dest = ptr of src1 ptr str, src2 start index, src3 end index */
|
||||||
OP_STR_SLICE, /* ssli : dest = ptr of src1 ptr string, src2 start index, src3
|
OP_INT_TO_STRING, /* int-to-string : dest = src1 as str */
|
||||||
end index */
|
OP_UINT_TO_STRING, /* nat-to-string : dest = src1 as str */
|
||||||
OP_INT_TO_STRING, /* itos : dest = src1 as str */
|
OP_REAL_TO_STRING, /* real-to-string : dest = src1 as str */
|
||||||
OP_UINT_TO_STRING, /* utos : dest = src1 as str */
|
OP_STRING_TO_INT, /* string-to-int : dest = src1 as int */
|
||||||
OP_REAL_TO_STRING, /* rtos : dest = src1 as str */
|
OP_STRING_TO_UINT, /* string-to-nat : dest = src1 as uint */
|
||||||
OP_STRING_TO_INT, /* stoi : dest = src1 as int */
|
OP_STRING_TO_REAL /* string-to-real : dest = src1 as real */
|
||||||
OP_STRING_TO_UINT, /* stou : dest = src1 as uint */
|
|
||||||
OP_STRING_TO_REAL /* stor : dest = src1 as real */
|
|
||||||
} Opcode;
|
} Opcode;
|
||||||
|
|
||||||
#define MAX_REGS 32
|
#define MAX_REGS 32
|
||||||
|
|
242
src/vm/vm.c
242
src/vm/vm.c
|
@ -16,11 +16,11 @@
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
src2 = read_u8(vm, code, vm->pc); \
|
src2 = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
value = frame.registers[src1]; \
|
value = frame->registers[src1]; \
|
||||||
value2 = frame.registers[src2]; \
|
value2 = frame->registers[src2]; \
|
||||||
cond = !!(value op value2); \
|
cond = !!(value op value2); \
|
||||||
mask = -(u32)cond; \
|
mask = -(u32)cond; \
|
||||||
target = frame.registers[dest]; \
|
target = frame->registers[dest]; \
|
||||||
vm->pc = (target & mask) | (vm->pc & ~mask); \
|
vm->pc = (target & mask) | (vm->pc & ~mask); \
|
||||||
return true; \
|
return true; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -33,8 +33,8 @@
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
src2 = read_u8(vm, code, vm->pc); \
|
src2 = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
frame.registers[dest] = \
|
frame->registers[dest] = \
|
||||||
(type)frame.registers[src1] op(type) frame.registers[src2]; \
|
(type)frame->registers[src1] op(type) frame->registers[src2]; \
|
||||||
return true; \
|
return true; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -59,11 +59,11 @@ bool step_vm(VM *vm) {
|
||||||
u8 opcode, dest, src1, src2;
|
u8 opcode, dest, src1, src2;
|
||||||
u32 v, ptr;
|
u32 v, ptr;
|
||||||
i32 value;
|
i32 value;
|
||||||
Frame frame;
|
Frame *frame;
|
||||||
|
|
||||||
/* Get current instruction & Advance to next instruction */
|
/* Get current instruction & Advance to next instruction */
|
||||||
opcode = vm->code[vm->pc++];
|
opcode = vm->code[vm->pc++];
|
||||||
frame = vm->frames[vm->fp];
|
frame = &vm->frames[vm->fp];
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case OP_HALT: {
|
case OP_HALT: {
|
||||||
|
@ -79,7 +79,7 @@ bool step_vm(VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_RETURN: {
|
case OP_RETURN: {
|
||||||
frame.rp = 0; /* reset register ptr */
|
frame->rp = 0; /* reset register ptr */
|
||||||
vm->pc = vm->return_stack[--vm->rp]; /* set pc to return address */
|
vm->pc = vm->return_stack[--vm->rp]; /* set pc to return address */
|
||||||
vm->mp =
|
vm->mp =
|
||||||
vm->frames[vm->fp--].start; /* reset memory pointer to start
|
vm->frames[vm->fp--].start; /* reset memory pointer to start
|
||||||
|
@ -91,7 +91,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
v = read_u32(vm, code, vm->pc);
|
v = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
frame.registers[dest] = v;
|
frame->registers[dest] = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD: {
|
case OP_LOAD: {
|
||||||
|
@ -100,7 +100,7 @@ bool step_vm(VM *vm) {
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = read_u32(vm, memory, ptr);
|
v = read_u32(vm, memory, ptr);
|
||||||
frame.registers[dest] = v;
|
frame->registers[dest] = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STORE: {
|
case OP_STORE: {
|
||||||
|
@ -108,20 +108,20 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = frame.registers[src1];
|
v = frame->registers[src1];
|
||||||
write_u32(vm, memory, ptr, v);
|
write_u32(vm, memory, ptr, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_PUSH: {
|
case OP_PUSH: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
vm->stack[++vm->sp] = frame.registers[dest];
|
vm->stack[++vm->sp] = frame->registers[dest];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_POP: {
|
case OP_POP: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame.registers[dest] = vm->stack[vm->sp--];
|
frame->registers[dest] = vm->stack[vm->sp--];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REG_MOV: {
|
case OP_REG_MOV: {
|
||||||
|
@ -129,13 +129,13 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame.registers[dest] = frame.registers[src1];
|
frame->registers[dest] = frame->registers[src1];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_JMP: {
|
case OP_JMP: {
|
||||||
dest = read_u8(vm, code, vm->pc);
|
dest = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
vm->pc = frame.registers[dest]; /* Jump to address */
|
vm->pc = frame->registers[dest]; /* Jump to address */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_JMPF: { /* error handling for syscall, jump if flag == 0 */
|
case OP_JMPF: { /* error handling for syscall, jump if flag == 0 */
|
||||||
|
@ -147,122 +147,134 @@ bool step_vm(VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_SYSCALL: {
|
case OP_SYSCALL: {
|
||||||
u32 syscall_id, arg_count;
|
u32 syscall_id;
|
||||||
u8 first_reg;
|
|
||||||
|
|
||||||
syscall_id = read_u32(vm, code, vm->pc);
|
syscall_id = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
arg_count = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
first_reg = read_u8(vm, code, vm->pc);
|
|
||||||
vm->pc++;
|
|
||||||
|
|
||||||
switch (syscall_id) {
|
switch (syscall_id) {
|
||||||
case SYSCALL_DEVICE_OPEN: {
|
case SYSCALL_DEVICE_OPEN: {
|
||||||
if (arg_count >= 2) {
|
Device *dev;
|
||||||
Device *dev;
|
u32 path_ptr, mode;
|
||||||
u32 path_ptr, mode;
|
u8 path_reg, mode_reg;
|
||||||
path_ptr = frame.registers[first_reg]; /* R0: path pointer */
|
path_reg = read_u8(vm, code, vm->pc);
|
||||||
mode = frame.registers[first_reg + 1]; /* R1: mode */
|
vm->pc++;
|
||||||
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
mode_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
if (dev) {
|
path_ptr = frame->registers[path_reg];
|
||||||
if (dev->ops->open) {
|
mode = frame->registers[mode_reg];
|
||||||
vm->flag = dev->ops->open(dev->data, mode);
|
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
||||||
} else {
|
if (dev) {
|
||||||
vm->flag = 1; /* success, no open needed */
|
if (dev->ops->open) {
|
||||||
}
|
vm->flag = dev->ops->open(dev->data, mode);
|
||||||
} else {
|
} else {
|
||||||
vm->flag = 0; /* error */
|
vm->flag = 1; /* success, no open needed */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vm->flag = 0; /* error: not enough arguments */
|
vm->flag = 0; /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SYSCALL_DEVICE_READ: {
|
case SYSCALL_DEVICE_READ: {
|
||||||
if (arg_count >= 3) {
|
Device *dev;
|
||||||
Device *dev;
|
u32 path_ptr, buffer_ptr, size;
|
||||||
u32 path_ptr, buffer_ptr, size;
|
u8 path_reg, buffer_reg, size_reg;
|
||||||
|
path_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
buffer_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
size_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
path_ptr = frame.registers[first_reg]; /* R0: path pointer */
|
path_ptr = frame->registers[path_reg]; /* R0: path pointer */
|
||||||
buffer_ptr = frame.registers[first_reg + 1]; /* R1: buffer pointer */
|
buffer_ptr = frame->registers[buffer_reg]; /* R1: buffer pointer */
|
||||||
size = frame.registers[first_reg + 2]; /* R2: size */
|
size = frame->registers[size_reg]; /* R2: size */
|
||||||
|
|
||||||
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
||||||
if (dev && dev->ops->read) {
|
if (dev && dev->ops->read) {
|
||||||
vm->flag =
|
vm->flag =
|
||||||
dev->ops->read(dev->data, (u8 *)&vm->memory[buffer_ptr], size);
|
dev->ops->read(dev->data, (u8 *)&vm->memory[buffer_ptr], size);
|
||||||
} else {
|
|
||||||
vm->flag = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vm->flag = 0; /* error: not enough arguments */
|
vm->flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SYSCALL_DEVICE_WRITE: {
|
case SYSCALL_DEVICE_WRITE: {
|
||||||
if (arg_count >= 3) {
|
Device *dev;
|
||||||
Device *dev;
|
u32 path_ptr, buffer_ptr, size;
|
||||||
u32 path_ptr, buffer_ptr, size;
|
u8 path_reg, buffer_reg, size_reg;
|
||||||
path_ptr = frame.registers[first_reg]; /* R0: path pointer */
|
path_reg = read_u8(vm, code, vm->pc);
|
||||||
buffer_ptr = frame.registers[first_reg + 1]; /* R1: buffer pointer */
|
vm->pc++;
|
||||||
size = frame.registers[first_reg + 2]; /* R2: size */
|
buffer_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
size_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
path_ptr = frame->registers[path_reg]; /* R0: path pointer */
|
||||||
if (dev && dev->ops->write) {
|
buffer_ptr = frame->registers[buffer_reg]; /* R1: buffer pointer */
|
||||||
vm->flag = dev->ops->write(
|
size = frame->registers[size_reg]; /* R2: size */
|
||||||
dev->data, (const u8 *)&vm->memory[buffer_ptr + 4], size);
|
|
||||||
} else {
|
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
||||||
vm->flag = 0;
|
if (dev && dev->ops->write) {
|
||||||
}
|
vm->flag = dev->ops->write(
|
||||||
|
dev->data, (const u8 *)&vm->memory[buffer_ptr + 4], size);
|
||||||
} else {
|
} else {
|
||||||
vm->flag = 0; /* error: not enough arguments */
|
vm->flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SYSCALL_DEVICE_CLOSE: {
|
case SYSCALL_DEVICE_CLOSE: {
|
||||||
if (arg_count >= 1) {
|
Device *dev;
|
||||||
Device *dev;
|
u32 path_ptr;
|
||||||
u32 path_ptr;
|
u8 path_reg;
|
||||||
path_ptr = frame.registers[first_reg]; /* R0: path pointer */
|
path_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
path_ptr = frame->registers[path_reg]; /* R0: path pointer */
|
||||||
|
|
||||||
if (dev && dev->ops->close) {
|
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
||||||
i32 result = dev->ops->close(dev->data);
|
|
||||||
vm->flag = result;
|
if (dev && dev->ops->close) {
|
||||||
} else {
|
i32 result = dev->ops->close(dev->data);
|
||||||
vm->flag = 0;
|
vm->flag = result;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vm->flag = 0; /* error: not enough arguments */
|
vm->flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SYSCALL_DEVICE_IOCTL: {
|
case SYSCALL_DEVICE_IOCTL: {
|
||||||
if (arg_count >= 3) {
|
Device *dev;
|
||||||
Device *dev;
|
u32 path_ptr, args_ptr, cmd;
|
||||||
u32 path_ptr, args_ptr, cmd;
|
u8 path_reg, cmd_reg, args_ptr_reg;
|
||||||
path_ptr = frame.registers[first_reg]; /* R0: device path */
|
path_reg = read_u8(vm, code, vm->pc);
|
||||||
cmd = frame.registers[first_reg + 1]; /* R1: ioctl command */
|
vm->pc++;
|
||||||
args_ptr = frame.registers[first_reg + 2]; /* R2: args pointer */
|
cmd_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
args_ptr_reg = read_u8(vm, code, vm->pc);
|
||||||
|
vm->pc++;
|
||||||
|
|
||||||
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
path_ptr = frame->registers[path_reg]; /* R0: device path */
|
||||||
|
cmd = frame->registers[cmd_reg]; /* R1: ioctl command */
|
||||||
|
args_ptr = frame->registers[args_ptr_reg]; /* R2: args pointer */
|
||||||
|
|
||||||
if (dev && dev->ops && dev->ops->ioctl) {
|
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
||||||
i32 result = dev->ops->ioctl(dev->data, cmd, &vm->memory[args_ptr]);
|
|
||||||
vm->flag = result;
|
if (dev && dev->ops && dev->ops->ioctl) {
|
||||||
} else {
|
i32 result = dev->ops->ioctl(dev->data, cmd, &vm->memory[args_ptr]);
|
||||||
vm->flag = 0; /* error or no ioctl support */
|
vm->flag = result;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vm->flag = 0; /* error: not enough arguments */
|
vm->flag = 0; /* error or no ioctl support */
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,8 +312,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame.registers[dest] =
|
frame->registers[dest] =
|
||||||
(frame.registers[src1] * frame.registers[src2]) >> 16;
|
(frame->registers[src1] * frame->registers[src2]) >> 16;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,8 +324,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame.registers[dest] =
|
frame->registers[dest] =
|
||||||
(frame.registers[src1] << 16) / frame.registers[src2];
|
(frame->registers[src1] << 16) / frame->registers[src2];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +336,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame.registers[dest] = frame.registers[src1] + frame.registers[src2];
|
frame->registers[dest] = frame->registers[src1] + frame->registers[src2];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +347,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame.registers[dest] = frame.registers[src1] - frame.registers[src2];
|
frame->registers[dest] = frame->registers[src1] - frame->registers[src2];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_INT: {
|
case OP_REAL_TO_INT: {
|
||||||
|
@ -343,12 +355,12 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
value = frame.registers[src1];
|
value = frame->registers[src1];
|
||||||
|
|
||||||
if (value >= 0) {
|
if (value >= 0) {
|
||||||
frame.registers[dest] = value >> 16;
|
frame->registers[dest] = value >> 16;
|
||||||
} else {
|
} else {
|
||||||
frame.registers[dest] = -((-value) >> 16);
|
frame->registers[dest] = -((-value) >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -358,7 +370,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame.registers[dest] = (frame.registers[src1] << 16);
|
frame->registers[dest] = (frame->registers[src1] << 16);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_UINT: {
|
case OP_REAL_TO_UINT: {
|
||||||
|
@ -366,11 +378,11 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
value = frame.registers[src1];
|
value = frame->registers[src1];
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
frame.registers[dest] = 0;
|
frame->registers[dest] = 0;
|
||||||
} else {
|
} else {
|
||||||
frame.registers[dest] = AS_UINT(value >> 16);
|
frame->registers[dest] = AS_UINT(value >> 16);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -379,7 +391,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame.registers[dest] = AS_INT(frame.registers[src1] << 16);
|
frame->registers[dest] = AS_INT(frame->registers[src1] << 16);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_JEQ_UINT: {
|
case OP_JEQ_UINT: {
|
||||||
|
@ -433,9 +445,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
int_to_string(AS_INT(frame.registers[src1]), buffer);
|
int_to_string(AS_INT(frame->registers[src1]), buffer);
|
||||||
ptr = str_alloc(vm, &frame, buffer, strlength(buffer));
|
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||||
frame.registers[dest] = ptr;
|
frame->registers[dest] = ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_UINT_TO_STRING: {
|
case OP_UINT_TO_STRING: {
|
||||||
|
@ -444,9 +456,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
uint_to_string(frame.registers[src1], buffer);
|
uint_to_string(frame->registers[src1], buffer);
|
||||||
ptr = str_alloc(vm, &frame, buffer, strlength(buffer));
|
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||||
frame.registers[dest] = ptr;
|
frame->registers[dest] = ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_STRING: {
|
case OP_REAL_TO_STRING: {
|
||||||
|
@ -455,10 +467,10 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
fixed_to_string(AS_INT(frame.registers[src1]), buffer);
|
fixed_to_string(AS_INT(frame->registers[src1]), buffer);
|
||||||
ptr =
|
ptr = str_alloc(vm, frame, buffer,
|
||||||
str_alloc(vm, &frame, buffer, strlength(buffer)); /* copy buffer to dest */
|
strlength(buffer)); /* copy buffer to dest */
|
||||||
frame.registers[dest] = ptr;
|
frame->registers[dest] = ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STRLEN: {
|
case OP_STRLEN: {
|
||||||
|
@ -468,9 +480,9 @@ bool step_vm(VM *vm) {
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
ptr = frame.registers[src1];
|
ptr = frame->registers[src1];
|
||||||
length = read_u32(vm, memory, ptr);
|
length = read_u32(vm, memory, ptr);
|
||||||
frame.registers[dest] = length;
|
frame->registers[dest] = length;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STRING_TO_INT: {
|
case OP_STRING_TO_INT: {
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
((code (
|
((code
|
||||||
(label main)
|
(label main
|
||||||
(load-imm $0 1)
|
(load-immediate $0 1)
|
||||||
(push $0)
|
(push $0)
|
||||||
(load-imm $0 1)
|
(load-immediate $0 1)
|
||||||
(call &add)
|
(call &add)
|
||||||
(pop $0)
|
(pop $0)
|
||||||
(itos $1 $0)
|
(int-to-string $1 $0)
|
||||||
(load $3 &terminal_str)
|
(load $3 &terminal-str)
|
||||||
(strlen $2 $1)
|
(string-length $2 $1)
|
||||||
(syscall DEVICE_WRITE, $3, $1, $2)
|
(syscall DEVICE-WRITE, $3, $1, $2)
|
||||||
(halt)
|
(halt))
|
||||||
(label add)
|
|
||||||
(pop $0)
|
(label add
|
||||||
(pop $1)
|
(pop $0)
|
||||||
(addi $2 $1 $0)
|
(pop $1)
|
||||||
(push $2)
|
(add-int $2 $1 $0)
|
||||||
(return)))
|
(push $2)
|
||||||
(data (label terminal_str "/dev/term/0")))
|
(return)))
|
||||||
|
(data
|
||||||
|
(label terminal-str "/dev/term/0")))
|
||||||
|
|
|
@ -1,33 +1,34 @@
|
||||||
(code (
|
((code
|
||||||
(label main)
|
(label main
|
||||||
(load $0 35)
|
(load-immediate $0 35)
|
||||||
(push $0)
|
(push $0)
|
||||||
(call &fib)
|
(call &fib)
|
||||||
(pop $0)
|
(pop $0)
|
||||||
(itos $1 $0)
|
(int-to-string $1 $0)
|
||||||
(load $2, &terminal_str)
|
(load $2, &terminal-str)
|
||||||
(strlen $4, $3)
|
(strlen $4, $3)
|
||||||
(sysc DEVICE_WRITE, $2, $1, $4)
|
(syscall DEVICE-WRITE, $2, $1, $4)
|
||||||
(halt)
|
(halt))
|
||||||
(label fib)
|
(label fib
|
||||||
(popi $0)
|
(pop $0)
|
||||||
(load $1 2)
|
(load-immediate $1 2)
|
||||||
(lodi $2 &base_case)
|
(load $2 &base-case)
|
||||||
(jlti $2 $0 $1)
|
(jump-lt-int $2 $0 $1)
|
||||||
(load $2 2)
|
(load $2 2)
|
||||||
(subi $4 $0 $3)
|
(sub-int $4 $0 $3)
|
||||||
(push $4)
|
(push $4)
|
||||||
(call &fib)
|
(call &fib)
|
||||||
(load $2 1)
|
(load $2 1)
|
||||||
(subi $4 $0 $3)
|
(sub-int $4 $0 $3)
|
||||||
(push $4)
|
(push $4)
|
||||||
(call &fib)
|
(call &fib)
|
||||||
(pop $4)
|
(pop $4)
|
||||||
(pop $5)
|
(pop $5)
|
||||||
(addi $6 $5 $4)
|
(add-int $6 $5 $4)
|
||||||
(push $6)
|
(push $6)
|
||||||
(return)
|
(return)
|
||||||
(label base_case)
|
(label base-case)
|
||||||
(push $0)
|
(push $0)
|
||||||
(return))
|
(return)))
|
||||||
(data (terminal_str: "/dev/term/0")))
|
(data
|
||||||
|
(label terminal-str "/dev/term/0")))
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
((code (
|
((code
|
||||||
(label main)
|
(label main
|
||||||
(load $0 &terminal_str)
|
(load $0 &terminal-str)
|
||||||
(load $1 &hello_str)
|
(load $1 &hello-str)
|
||||||
(strlen $2 $1)
|
(strlen $2 $1)
|
||||||
(syscall DEVICE_WRITE $0 $1 $2)
|
(syscall DEVICE_WRITE $0 $1 $2)
|
||||||
(halt)))
|
(halt)))
|
||||||
(data (label terminal_str "/dev/term/0")
|
(data
|
||||||
(label hello_str "nuqneH 'u'?")))
|
(label terminal-str "/dev/term/0")
|
||||||
|
(label hello-str "nuqneH 'u'?")))
|
||||||
|
|
|
@ -1,30 +1,31 @@
|
||||||
((code (
|
((code
|
||||||
(label main)
|
(label main
|
||||||
(load-imm $0 5.0)
|
(load-immediate $0 5.0)
|
||||||
(load-imm $1 5000)
|
(load-immediate $1 5000)
|
||||||
(load-imm $2 0)
|
(load-immediate $2 0)
|
||||||
(load-imm $3 -1)
|
(load-immediate $3 -1)
|
||||||
(label loop-body)
|
(label loop-body)
|
||||||
(load $4 &loop-body)
|
(load $4 &loop-body)
|
||||||
(load-imm $5 5.0)
|
(load-immediate $5 5.0)
|
||||||
(addr $0 $0 $5)
|
(add-real $0 $0 $5)
|
||||||
(addi $1 $1 $3)
|
(add-int $1 $1 $3)
|
||||||
(jgei $4 $1 $2)
|
(jump-gt-eq-int $4 $1 $2)
|
||||||
(rtou $1 $0)
|
(real-to-nat $1 $0)
|
||||||
(load $6 &terminal_str)
|
(load $6 &terminal-str)
|
||||||
(load $7 &help)
|
(load $7 &help)
|
||||||
(strlen $8 $7)
|
(string-length $8 $7)
|
||||||
(syscall DEVICE_WRITE $6 $7 $8)
|
(syscall DEVICE-WRITE $6 $7 $8)
|
||||||
(syscall DEVICE_READ $7 $2)
|
(syscall DEVICE-READ $7 $2)
|
||||||
(strlen $3 $2)
|
(string-length $3 $2)
|
||||||
(utos $4 $1)
|
(nat-to-string $4 $1)
|
||||||
(strlen $5 $4)
|
(string-length $5 $4)
|
||||||
(syscall DEVICE_WRITE $6 $4 $5)
|
(syscall DEVICE-WRITE $6 $4 $5)
|
||||||
(rtos $9 $0)
|
(real-to-string $9 $0)
|
||||||
(strlen $10 $9)
|
(string-length $10 $9)
|
||||||
(syscall DEVICE_WRITE $6 $9 $10)
|
(syscall DEVICE-WRITE $6 $9 $10)
|
||||||
(strlen $8 $7)
|
(string-length $8 $7)
|
||||||
(syscall DEVICE_WRITE $6 $7 $8)
|
(syscall DEVICE-WRITE $6 $7 $8)
|
||||||
(halt)))
|
(halt)))
|
||||||
(data (label terminal-str "/dev/term/0")
|
(data
|
||||||
(label help "Enter a string:")))
|
(label terminal-str "/dev/term/0")
|
||||||
|
(label help "Enter a string:")))
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
((code (
|
((code
|
||||||
(label main)
|
(label main
|
||||||
(load-imm $0 1.0)
|
(load $0 &x)
|
||||||
(load-imm $0 2.0)
|
(load $1 &y)
|
||||||
(addf $2 $1 $0)
|
(add-real $2 $1 $0)
|
||||||
(ftos $3 $2)
|
(real-to-string $3 $2)
|
||||||
(strlen $4 $3)
|
(string-length $4 $3)
|
||||||
(load $5 &terminal_str)
|
(load $5 &terminal-str)
|
||||||
(syscall DEVICE_WRITE, $5, $3, $4)
|
(syscall DEVICE-WRITE, $5, $3, $4)
|
||||||
(halt)))
|
(halt)))
|
||||||
(data (label terminal_str "/dev/term/0")))
|
(data (label terminal-str "/dev/term/0")
|
||||||
|
(label x 1.0)
|
||||||
|
(label y 2.0)))
|
||||||
|
|
Loading…
Reference in New Issue