Originally, arithmetic instructions were in the form of
REG2 = REG1 (OP) REG2
but then I started storing the result in REG1 (both in implementation,
and later defs of the arth instructions). So I'm updating it to match
what was actually in my head.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2.6 KiB
2.6 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.
| 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.
- Add
- Params: REG1, REG2
REG1 = REG1 + REG2
- Mul
- Params: REG1, REG2
REG1 = REG1 * REG2
- Div
- Params: REG1, REG2
REG1 = REG1 / REG2
- Mod
- Params: REG1, REG2
REG1 = REG1 % REG2(exact semantics TBD)
- Neg
- Params: REG1
REG1 = REG1 * -1
- 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
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