add load/store, add hello example. fix syscall for terminal, fix str alloc

This commit is contained in:
zongor 2026-01-14 20:02:52 -08:00
parent 634e1ed4eb
commit ee8f9b63b0
3 changed files with 99 additions and 30 deletions

View File

@ -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
View File

@ -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
View File

@ -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