add load/store, add hello example. fix syscall for terminal, fix str alloc
This commit is contained in:
parent
634e1ed4eb
commit
ee8f9b63b0
|
|
@ -24,13 +24,11 @@ u32 syscall(u32 id, u32 size, u32 mem_ptr) {
|
|||
USED(size);
|
||||
switch(id) {
|
||||
case SYSCALL_CONSOLE_WRITE: {
|
||||
u32 size_ptr = mem[mem_ptr];
|
||||
u32 size = mem[size_ptr];
|
||||
u8 *ptr = &mem[size_ptr + 4];
|
||||
u32 size = *(u32*)&mem[mem_ptr];
|
||||
u8 *ptr = &mem[mem_ptr + 4];
|
||||
for (u32 i = 0; i < size; i++) {
|
||||
putchar(*(ptr++));
|
||||
}
|
||||
putchar('\n');
|
||||
return 0;
|
||||
}
|
||||
case SYSCALL_CONSOLE_READ: {
|
||||
|
|
@ -107,16 +105,27 @@ void test_fibonacci() {
|
|||
code[cp++] = ENCODE_B(OP_RETURN, 0, 0);
|
||||
}
|
||||
|
||||
void test_hello() {
|
||||
u32 hello =str_alloc("nuqneH 'u'?", 12);
|
||||
u32 new_line = str_alloc("\n", 1);
|
||||
fp = mp;
|
||||
/* function main() */
|
||||
i32 main_local_count = 3;
|
||||
mp += (4 * main_local_count);
|
||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, hello);
|
||||
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 12, 0);
|
||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, new_line);
|
||||
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 0);
|
||||
code[cp++] = ENCODE_A(OP_HALT, 0, 0, 0);
|
||||
}
|
||||
|
||||
i32 main() {
|
||||
init_vm();
|
||||
|
||||
/* test_add_two_num(); */
|
||||
test_fibonacci();
|
||||
test_hello();
|
||||
|
||||
while(step_vm()) {
|
||||
// do stuff
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
65
vm/vm.c
65
vm/vm.c
|
|
@ -23,12 +23,11 @@ u32 str_alloc(char *str, u32 length) {
|
|||
ptr += 4;
|
||||
mcpy(ptr, str, length);
|
||||
ptr[length] = '\0';
|
||||
mp += 4 + length + 1;
|
||||
mp += 4 + length;
|
||||
return str_addr;
|
||||
}
|
||||
|
||||
bool step_vm() {
|
||||
|
||||
u32 instruction = code[pc++];
|
||||
u8 opcode = DECODE_OP(instruction);
|
||||
u32 *locals = (u32*)(&mem[fp]);
|
||||
|
|
@ -103,7 +102,7 @@ bool step_vm() {
|
|||
DECODE_A(instruction)
|
||||
u32 id = dest; /* syscall id */
|
||||
u32 size = src1; /* size of heap at that pointer */
|
||||
u32 rd = fp + (src2 * 4); /* the pointer */
|
||||
u32 rd = locals[src2]; /* the pointer */
|
||||
status = syscall(id, size, rd);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -134,40 +133,100 @@ bool step_vm() {
|
|||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_8: {
|
||||
DECODE_A(instruction)
|
||||
USED(src2);
|
||||
locals[dest] = READ_U8(locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_16: {
|
||||
DECODE_A(instruction)
|
||||
USED(src2);
|
||||
locals[dest] = READ_U16(locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_IND_32: {
|
||||
DECODE_A(instruction)
|
||||
USED(src2);
|
||||
locals[dest] = READ_U32(locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_ABS_8: {
|
||||
/* need multibyte for this, ignore for now */
|
||||
status = 250;
|
||||
return false;
|
||||
}
|
||||
case OP_LOAD_ABS_16: {
|
||||
/* need multibyte for this, ignore for now */
|
||||
status = 250;
|
||||
return false;
|
||||
}
|
||||
case OP_LOAD_ABS_32: {
|
||||
/* need multibyte for this, ignore for now */
|
||||
status = 250;
|
||||
return false;
|
||||
}
|
||||
case OP_LOAD_OFF_8: {
|
||||
DECODE_A(instruction)
|
||||
locals[dest] = READ_U8((locals[src1] + locals[src2]));
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_OFF_16: {
|
||||
DECODE_A(instruction)
|
||||
locals[dest] = READ_U16((locals[src1] + locals[src2]));
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_OFF_32: {
|
||||
DECODE_A(instruction)
|
||||
locals[dest] = READ_U32((locals[src1] + locals[src2]));
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_ABS_8: {
|
||||
/* need multibyte for this, ignore for now */
|
||||
status = 250;
|
||||
return false;
|
||||
}
|
||||
case OP_STORE_ABS_16: {
|
||||
/* need multibyte for this, ignore for now */
|
||||
status = 250;
|
||||
return false;
|
||||
}
|
||||
case OP_STORE_ABS_32: {
|
||||
/* need multibyte for this, ignore for now */
|
||||
status = 250;
|
||||
return false;
|
||||
}
|
||||
case OP_STORE_IND_8: {
|
||||
DECODE_A(instruction)
|
||||
USED(src2);
|
||||
WRITE_U8(locals[dest], locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_IND_16: {
|
||||
DECODE_A(instruction)
|
||||
USED(src2);
|
||||
WRITE_U16(locals[dest], locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_IND_32: {
|
||||
DECODE_A(instruction)
|
||||
USED(src2);
|
||||
WRITE_U32(locals[dest], locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_8: {
|
||||
DECODE_A(instruction)
|
||||
WRITE_U8((locals[dest] + locals[src2]), locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_16: {
|
||||
DECODE_A(instruction)
|
||||
WRITE_U16((locals[dest] + locals[src2]), locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_STORE_OFF_32: {
|
||||
DECODE_A(instruction)
|
||||
WRITE_U32((locals[dest] + locals[src2]), locals[src1]);
|
||||
return true;
|
||||
}
|
||||
case OP_MEM_ALLOC: {
|
||||
DECODE_A(instruction)
|
||||
|
|
|
|||
39
vm/vm.h
39
vm/vm.h
|
|
@ -44,21 +44,21 @@ typedef enum {
|
|||
OP_LOAD_IND_8, /* load_indirect_8 : A : locals[dest] = memory[locals[src1]] as u8 */
|
||||
OP_LOAD_IND_16, /* load_indirect_16 : A : locals[dest] = memory[locals[src1]] as u16 */
|
||||
OP_LOAD_IND_32, /* load_indirect_32 : A : locals[dest] = memory[locals[src1]] as u32 */
|
||||
OP_LOAD_ABS_8, /* load_absolute_8 : A : locals[dest] = memory[src1] as u8 */
|
||||
OP_LOAD_ABS_16, /* load_absolute_16 : A : locals[dest] = memory[src1] as u16 */
|
||||
OP_LOAD_ABS_32, /* load_absolute_32 : A : locals[dest] = memory[src1] as u32 */
|
||||
OP_LOAD_OFF_8, /* load_offset_8 : A : locals[dest] = memory[locals[src1] + src2] as u8 */
|
||||
OP_LOAD_OFF_16, /* load_offset_16 : A : locals[dest] = memory[locals[src1] + src2] as u16 */
|
||||
OP_LOAD_OFF_32, /* load_offset_32 : A : locals[dest] = memory[locals[src1] + src2] as u32 */
|
||||
OP_STORE_ABS_8, /* store_absolute_8 : A : memory[dest] = src1 && 0xFF */
|
||||
OP_STORE_ABS_16, /* store_absolute_16 : A : memory[dest] = src1 && 0xFFFF */
|
||||
OP_STORE_ABS_32, /* store_absolute_32 : A : memory[dest] = src1 */
|
||||
OP_STORE_IND_8, /* store_indirect_8 : A : memory[dest] = locals[src1] && 0xFF */
|
||||
OP_STORE_IND_16, /* store_indirect_16 : A : memory[dest] = locals[src1] && 0xFFFF*/
|
||||
OP_STORE_IND_32, /* store_indirect_32 : A : memory[dest] = locals[src1] */
|
||||
OP_STORE_OFF_8, /* store_offset_8 : A : memory[locals[dest] + src2] = locals[src1] && 0xFF */
|
||||
OP_STORE_OFF_16, /* store_offset_16 : A : memory[locals[dest] + src2] = locals[src1] && 0xFFFF */
|
||||
OP_STORE_OFF_32, /* store_offset_32 : A : memory[locals[dest] + src2] = locals[src1] */
|
||||
OP_LOAD_ABS_8, /* load_absolute_8 : E : locals[dest] = memory[src1:u32] as u8 */
|
||||
OP_LOAD_ABS_16, /* load_absolute_16 : E : locals[dest] = memory[src1:u32] as u16 */
|
||||
OP_LOAD_ABS_32, /* load_absolute_32 : E : locals[dest] = memory[src1:u32] as u32 */
|
||||
OP_LOAD_OFF_8, /* load_offset_8 : A : locals[dest] = memory[locals[src1] + locals[src2]] as u8 */
|
||||
OP_LOAD_OFF_16, /* load_offset_16 : A : locals[dest] = memory[locals[src1] + locals[src2]] as u16 */
|
||||
OP_LOAD_OFF_32, /* load_offset_32 : A : locals[dest] = memory[locals[src1] + locals[src2]] as u32 */
|
||||
OP_STORE_ABS_8, /* store_absolute_8 : E : memory[dest] = src1 && 0xFF */
|
||||
OP_STORE_ABS_16, /* store_absolute_16 : E : memory[dest] = src1 && 0xFFFF */
|
||||
OP_STORE_ABS_32, /* store_absolute_32 : E : memory[dest] = src1 */
|
||||
OP_STORE_IND_8, /* store_indirect_8 : A : memory[locals[dest]] = locals[src1] && 0xFF */
|
||||
OP_STORE_IND_16, /* store_indirect_16 : A : memory[locals[dest]] = locals[src1] && 0xFFFF*/
|
||||
OP_STORE_IND_32, /* store_indirect_32 : A : memory[locals[dest]] = locals[src1] */
|
||||
OP_STORE_OFF_8, /* store_offset_8 : A : memory[locals[dest] + locals[src2]] = locals[src1] && 0xFF */
|
||||
OP_STORE_OFF_16, /* store_offset_16 : A : memory[locals[dest] + locals[src2]] = locals[src1] && 0xFFFF */
|
||||
OP_STORE_OFF_32, /* store_offset_32 : A : memory[locals[dest] + locals[src2]] = locals[src1] */
|
||||
OP_MEM_ALLOC, /* alloc : A : memory[dest] = [locals[src1] as size + 4] */
|
||||
OP_MEM_CPY_8, /* memcpy_8 : A : memory[src1..src1+src2] = memory[dest..dest+src2] */
|
||||
OP_MEM_CPY_16, /* memcpy_16 : A : memory[src1..src1+src2] = memory[dest..dest+src2] */
|
||||
|
|
@ -93,7 +93,7 @@ typedef enum {
|
|||
OP_BIT_AND, /* bit_and : A : locals[dest] = locals[src1] & locals[src2] */
|
||||
OP_BIT_OR, /* bit_or : A : locals[dest] = locals[src1] | locals[src2] */
|
||||
OP_BIT_XOR, /* bit_xor : A : locals[dest] = locals[src1] ^ locals[src2] */
|
||||
OP_JMP_IMM, /* jump_immediate : C : jump to imm unconditionally */
|
||||
OP_JMP_IMM, /* jump_immediate : E : jump to imm unconditionally */
|
||||
OP_JMP_ABS, /* jump_absolute : A : jump to locals[dest] unconditionally */
|
||||
OP_JMP_OFF, /* jump_offset : A : jump to locals[dest] + locals[src1] unconditionally */
|
||||
OP_JMP_FLAG, /* jump_if_flag : A : jump to locals[dest] if flag > 0 */
|
||||
|
|
@ -115,9 +115,9 @@ typedef enum {
|
|||
OP_JGT_REAL, /* jump_gt_real : A : jump to locals[dest] if locals[src1] as real > locals[src2] as real */
|
||||
OP_JLT_REAL, /* jump_lt_real : A : jump to locals[dest] if locals[src1] as real < locals[src2] as real */
|
||||
OP_JLE_REAL, /* jump_le_real : A : jump to locals[dest] if locals[src1] as real <= locals[src2] as real */
|
||||
OP_INT_TO_STR,
|
||||
OP_NAT_TO_STR,
|
||||
OP_REAL_TO_STR,
|
||||
OP_INT_TO_STR, /* int_to_str : A : locals[dest] = &mem[mp..] locals[src1] as str */
|
||||
OP_NAT_TO_STR, /* nat_to_str : A : locals[dest] = &mem[mp..] locals[src1] as str */
|
||||
OP_REAL_TO_STR, /* real_to_str : A : locals[dest] = &mem[mp..] locals[src1] as str */
|
||||
OP_MAX_OPCODE /* not an opcode count of instructions */
|
||||
} Opcode;
|
||||
|
||||
|
|
@ -197,5 +197,6 @@ extern u8 *mem; /* memory */
|
|||
extern bool init_vm();
|
||||
extern u32 syscall(u32 id, u32 args, u32 mem_ptr);
|
||||
bool step_vm();
|
||||
u32 str_alloc(char *str, u32 length);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue