Update specification.

This commit is contained in:
zongor 2026-01-05 22:20:48 -08:00
parent 4635c83e42
commit f9dc374430
2 changed files with 82 additions and 88 deletions

View File

@ -33,95 +33,89 @@ During compilation constants and local variables are put onto 'mem'
*** All 32 bit instructions (registers are all 32 bit values)
**** Type A: [8:opcode][8:dest][8:src1][8:src2]
- call : dest num-of-args ptr-to-function
- return : dest return-arg 0
- syscall : id num-of-args ptr-to-memory
- load-indirect-8 : dest src1 0
- load-indirect-16 : dest src1 0
- load-indirect-32 : dest src1 0
- load-absolute-8 : dest src1 0
- load-absolute-16 : dest src1 0
- load-absolute-32 : dest src1 0
- load-offset-8 : dest src1 src2
- load-offset-16 : dest src1 src2
- load-offset-32 : dest src1 src2
- store-absolute-8 : dest src1 0
- store-indirect-8 : dest src1 0
- store-offset-8 : dest src1 src2
- store-absolute-16 : dest src1 0
- store-indirect-16 : dest src1 0
- store-offset-16 : dest src1 src2
- store-absolute-32 : dest src1 0
- store-indirect-32 : dest src1 0
- store-offset-32 : dest src1 src2
- alloc : dest size 0
- memset-8 : dest src1 count
- memset-16 : dest src1 count
- memset-32 : dest src1 count
- memcpy-8 : dest src1 count
- memcpy-16 : dest src1 count
- memcpy-32 : dest src1 count
- mov : dest src1 0
- add-int : dest src1 src2
- sub-int : dest src1 src2
- mul-int : dest src1 src2
- div-int : dest src1 src2
- neg-int : dest src1 src2
- abs-int : dest src1 src2
- add-nat : dest src1 src2
- sub-nat : dest src1 src2
- mul-nat : dest src1 src2
- div-nat : dest src1 src2
- neg-nat : dest src1 src2
- abs-nat : dest src1 src2
- add-real : dest src1 src2
- sub-real : dest src1 src2
- mul-real : dest src1 src2
- div-real : dest src1 src2
- neg-real : dest src1 src2
- abs-real : dest src1 src2
- int-to-real : dest src1 src2
- int-to-nat : dest src1 src2
- nat-to-real : dest src1 src2
- nat-to-int : dest src1 src2
- real-to-int : dest src1 src2
- real-to-nat : dest src1 src2
- shift-left : dest src1 src2
- shift-right : dest src1 src2
- shift-right-extend : dest src1 src2
- and : dest src1 src2
- or : dest src1 src2
- xor : dest src1 src2
- jump-absolute : dest 0 0
- jump-offset : dest src1 0
- jmp-flag : dest 0 0 | jump if flag > 0
- jeq-int : dest src1 src2
- jne-int : dest src1 src2
- jgt-int : dest src1 src2
- jlt-int : dest src1 src2
- jle-int : dest src1 src2
- jge-int : dest src1 src2
- jeq-nat : dest src1 src2
- jne-nat : dest src1 src2
- jgt-nat : dest src1 src2
- jlt-nat : dest src1 src2
- jle-nat : dest src1 src2
- jge-nat : dest src1 src2
- jeq-real : dest src1 src2
- jne-real : dest src1 src2
- jgt-real : dest src1 src2
- jlt-real : dest src1 src2
- jle-real : dest src1 src2
- jge-real : dest src1 src2
**** Type B: [8:opcode][8:dest][16:immediate]
- load-immediate : dest imm : for small 16 bit consts, and lower part of 32 bit consts
- load-upper-immediate : dest imm : for large 32 bit consts
**** Type C: [8:opcode][24:immediate]
- halt : immediate is unused (all zeros)
- jump-immediate : immediate jump
| Instruction | Opcode type | opcode arguments | notes |
|--------------------+-------------+----------------------------------------------------------------------+------------------------------------------|
| halt | A | all zeros | halt execution |
| call | A | dest args return | creates a new frame |
| return | B | dest return_flags | returns from a frame to the parent frame |
| syscall | A | id args mem_ptr | does a system call based on id with args |
| load_immediate | B | locals[dest] = const as u16 | |
| load_upper_immediate | B | locals[dest] = const as u32 << 16 & 16 | |
| load_indirect_8 | A | locals[dest] = memory[locals[src1]] as u8 | |
| load_indirect_16 | A | locals[dest] = memory[locals[src1]] as u16 | |
| load_indirect_32 | A | locals[dest] = memory[locals[src1]] as u32 | |
| load_absolute_8 | A | locals[dest] = memory[src1] as u8 | |
| load_absolute_16 | A | locals[dest] = memory[src1] as u16 | |
| load_absolute_32 | A | locals[dest] = memory[src1] as u32 | |
| load_offset_8 | A | locals[dest] = memory[locals[src1] + src2] as u8 | |
| load_offset_16 | A | locals[dest] = memory[locals[src1] + src2] as u16 | |
| load_offset_32 | A | locals[dest] = memory[locals[src1] + src2] as u32 | |
| store_absolute_8 | A | memory[dest] = src1 && 0xFF | |
| store_absolute_16 | A | memory[dest] = src1 && 0xFFFF | |
| store_absolute_32 | A | memory[dest] = src1 | |
| store_indirect_8 | A | memory[dest] = locals[src1] && 0xFF | |
| store_indirect_16 | A | memory[dest] = locals[src1] && 0xFFFF | |
| store_indirect_32 | A | memory[dest] = locals[src1] | |
| store_offset_8 | A | memory[locals[dest] + src2] = locals[src1] && 0xFF | |
| store_offset_16 | A | memory[locals[dest] + src2] = locals[src1] && 0xFFFF | |
| store_offset_32 | A | memory[locals[dest] + src2] = locals[src1] | |
| alloc | A | memory[dest] = [locals[src1] as size + 4] | |
| memcpy_8 | A | memory[src1..src1+src2] = memory[dest..dest+src2] | |
| memcpy_16 | A | memory[src1..src1+src2] = memory[dest..dest+src2] | |
| memcpy_32 | A | memory[src1..src1+src2] = memory[dest..dest+src2] | |
| memset_8 | A | memory[dest..dest+src2] = local[src1] as u8 | |
| memset_16 | A | memory[dest..dest+src2] = local[src1] as u16 | |
| memset_32 | A | memory[dest..dest+src2] = local[src1] as u32 | |
| mov | A | locals[dest] = locals[src1] | |
| add_int | A | locals[dest] = locals[src1] + locals[src2] | |
| sub_int | A | locals[dest] = locals[src1] - locals[src2] | |
| mul_int | A | locals[dest] = locals[src1] * locals[src2] | |
| div_int | A | locals[dest] = locals[src1] / locals[src2] | |
| add_nat | A | locals[dest] = locals[src1] + locals[src2] | |
| sub_nat | A | locals[dest] = locals[src1] - locals[src2] | |
| mul_nat | A | locals[dest] = locals[src1] * locals[src2] | |
| div_nat | A | locals[dest] = locals[src1] / locals[src2] | |
| add_real | A | locals[dest] = locals[src1] + locals[src2] | |
| sub_real | A | locals[dest] = locals[src1] - locals[src2] | |
| mul_real | A | locals[dest] = locals[src1] * locals[src2] | |
| div_real | A | locals[dest] = locals[src1] / locals[src2] | |
| int_to_real | A | locals[dest] = locals[src1] as real | |
| int_to_nat | A | locals[dest] = locals[src1] as nat | |
| nat_to_real | A | locals[dest] = locals[src1] as real | |
| nat_to_int | A | locals[dest] = locals[src1] as int | |
| real_to_int | A | locals[dest] = locals[src1] as int | |
| real_to_nat | A | locals[dest] = locals[src1] as nat | |
| bit_shift_left | A | locals[dest] = locals[src1] << locals[src2] | |
| bit_shift_right | A | locals[dest] = locals[src1] >> locals[src2] | |
| bit_shift_r_ext | A | locals[dest] as i32 = locals[src1] >> locals[src2] | |
| bit_and | A | locals[dest] = locals[src1] & locals[src2] | |
| bit_or | A | locals[dest] = locals[src1] | locals[src2] |
| bit_xor | A | locals[dest] = locals[src1] ^ locals[src2] | |
| jump_immediate | C | jump to imm unconditionally | |
| jump_absolute | A | jump to locals[dest] unconditionally | |
| jump_offset | A | jump to locals[dest] + locals[src1] unconditionally | |
| jump_if_flag | A | jump to locals[dest] if flag > 0 | |
| jump_eq_int | A | jump to locals[dest] if locals[src1] as int == locals[src2] as int | |
| jump_neq_int | A | jump to locals[dest] if locals[src1] as int != locals[src2] as int | |
| jump_gt_int | A | jump to locals[dest] if locals[src1] as int > locals[src2] as int | |
| jump_lt_int | A | jump to locals[dest] if locals[src1] as int < locals[src2] as int | |
| jump_le_int | A | jump to locals[dest] if locals[src1] as int <= locals[src2] as int | |
| jump_ge_int | A | jump to locals[dest] if locals[src1] as int >= locals[src2] as int | |
| jump_eq_nat | A | jump to locals[dest] if locals[src1] as nat == locals[src2] as nat | |
| jump_neq_nat | A | jump to locals[dest] if locals[src1] as nat != locals[src2] as nat | |
| jump_gt_nat | A | jump to locals[dest] if locals[src1] as nat > locals[src2] as nat | |
| jump_lt_nat | A | jump to locals[dest] if locals[src1] as nat < locals[src2] as nat | |
| jump_le_nat | A | jump to locals[dest] if locals[src1] as nat <= locals[src2] as nat | |
| jump_ge_nat | A | jump to locals[dest] if locals[src1] as nat >= locals[src2] as nat | |
| jump_eq_real | A | jump to locals[dest] if locals[src1] as real == locals[src2] as real | |
| jump_neq_real | A | jump to locals[dest] if locals[src1] as real != locals[src2] as real | |
| jump_ge_real | A | jump to locals[dest] if locals[src1] as real >= locals[src2] as real | |
| jump_gt_real | A | jump to locals[dest] if locals[src1] as real > locals[src2] as real | |
| jump_lt_real | A | jump to locals[dest] if locals[src1] as real < locals[src2] as real | |
| jump_le_real | A | jump to locals[dest] if locals[src1] as real <= locals[src2] as real | |
** Maybe more flexible calling convention?
@ -157,4 +151,3 @@ Copy the new sized value and put it at the current end of the heap.
Update the new pointers local position.
Add the new size to the mp.
Repeat for each returned value that is a replaced heap value.

View File

@ -55,7 +55,8 @@ bool step_vm() {
u32 i, size = 0;
u32 return_local = fp + dest;
u32 return_value = READ_U32(return_local);
bool is_ptr = imm >> 31;
bool is_ptr = (((u16)(1)) << 15) & imm;
bool replaces_value = (((u16)(1)) << 14) & imm;
/* reset mp to saved mp, use header size to get "real" start of frame */
u32 frame_start = fp - FRAME_HEADER_SIZE;