2.8 KiB
2.8 KiB
VM
This is an outline of the VM that drives this language.
Primitives
- Numbers may be big endian (BE) or little endian (LE) at the byte level. This guide will use LE.
- Addresses point to single bytes.
- Signed numbers use two's complement.
| Type | Size (bits) |
|---|---|
| Address | 64 |
| Word | 64 |
| Halfword | 32 |
| Byte | 8 |
Registers
CPU registers are addressed by a value between 0-63 (6 bits). All registers are 64 bits wide.
- IP - Instruction pointer
- SP - Stack pointer
- FP - Frame pointer
- FLAGS - CPU flags
- (10 unused registers)
- R0-R49
CPU Flags
CPU flags are addressed by bit index, going from right to left.
00- Halt flag01- Compare flag
Flag ideas
- "Trace" flag - halts the CPU when certain conditions are met that may be causing undesired
behavior - for debugging
- Overwriting a register without its value being used
- Mixing arithmetic with bit twiddling on the same target
Instructions
Arithmetic
Arithmetic instructions store their result in the first register specified. Overflow is handled by wrapping around to 0.
- Add
- Params: REG1, REG2
REG1 = REG1 + REG2- Unsigned addition
- Mul
- Params: REG1, REG2
REG1 = REG1 * REG2- Unsigned multiplication
- Div
- Params: REG1, REG2
REG1 = REG1 / REG2- Unsigned division
- Mod
- Params: REG1, REG2
REG1 = REG1 % REG2(exact semantics TBD)
- INeg
- Params: REG1
REG1 = REG1 * -1- Signed negative
- And
- Params: REG1, REG2
REG1 = REG1 & REG2
- Or
- Params: REG1, REG2
REG1 = REG1 | REG2
- Xor
- Params: REG1, REG2
REG1 = REG1 ^ REG2
- Shl
- Params: REG1, REG2
REG1 = REG1 << REG2
- Shr
- Params: REG1, REG2
REG1 = REG1 >> REG2
TODO
- Add signed instructions (iadd, imul, etc)
- Overflow flag?
Control flow
- CmpEq
- Params: REG1, REG2
-
if REG1 == REG2 { FLAGS[1] = 1; } else { FLAGS[1] = 0; }
- CmpLt
- Params: REG1, REG2
-
if REG1 < REG2 { FLAGS[1] = 1; } else { FLAGS[1] = 0; }
- Jz
- Params: REG1
-
if FLAGS[0] == 0 { IP = REG1; }
- Jnz
- Params: REG1
-
if FLAGS[0] != 0 { IP = REG1; }
Data movement
- Load
- Params: REG1, REG2
-
- Store
- Params: REG1, REG2
-
- StoreImm32
- Params: REG1, IMM_32
REG1 = IMM_32
- MemCopy
- Params: REG1, REG2
MEM[REG1] = MEM[REG2]
- RegCopy
- Params: REG1, REG2
REG1 = REG2