Add opcodes and layout for most instructions
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
113
vm.md
113
vm.md
@@ -48,40 +48,52 @@ CPU flags are addressed by bit index, going from right to left.
|
||||
|
||||
# Instructions
|
||||
|
||||
Instructions attempt to be as small as possible while conforming to 8-bit, 16-bit, 32-bit, or 64-bit
|
||||
alignment. All instructions have 16-bit opcodes.
|
||||
|
||||
## Arithmetic
|
||||
|
||||
Arithmetic instructions store their result in the first register specified. Overflow is handled by
|
||||
wrapping around to 0.
|
||||
|
||||
* Add
|
||||
* Opcode: 0x0000
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 + REG2`
|
||||
* Unsigned addition
|
||||
* Mul
|
||||
* Opcode: 0x0001
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 * REG2`
|
||||
* Unsigned multiplication
|
||||
* Div
|
||||
* Opcode: 0x0002
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 / REG2`
|
||||
* Unsigned division
|
||||
* Mod
|
||||
* Opcode: 0x0003
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 % REG2` (exact semantics TBD)
|
||||
* INeg
|
||||
* Opcode: 0x0004
|
||||
* **Params**: REG1
|
||||
* `REG1 = REG1 * -1`
|
||||
* Signed negative
|
||||
* And
|
||||
* Opcode: 0x0005
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 & REG2`
|
||||
* Or
|
||||
* Opcode: 0x0006
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 | REG2`
|
||||
* Inv
|
||||
* Opcode: 0x0007
|
||||
* **Params**: REG1
|
||||
* `REG1 = ~REG1`
|
||||
* Not
|
||||
* Opcode: 0x0008
|
||||
* **Params**: REG1
|
||||
* ```
|
||||
if REG1 == 0 {
|
||||
@@ -92,12 +104,15 @@ wrapping around to 0.
|
||||
```
|
||||
* Boolean NOT; equivalent of C's `!` unary operator
|
||||
* Xor
|
||||
* Opcode: 0x0009
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 ^ REG2`
|
||||
* Shl
|
||||
* Opcode: 0x000A
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 << REG2`
|
||||
* Shr
|
||||
* Opcode: 0x000B
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG1 >> REG2`
|
||||
* Does not sign extend
|
||||
@@ -111,6 +126,7 @@ wrapping around to 0.
|
||||
## Control flow
|
||||
|
||||
* CmpEq
|
||||
* Opcode: 0x1000
|
||||
* **Params**: REG1, REG2
|
||||
* ```
|
||||
if REG1 == REG2 {
|
||||
@@ -121,6 +137,7 @@ wrapping around to 0.
|
||||
```
|
||||
* Sets the COMPARE flag to 1 if REG1 == REG2
|
||||
* CmpLt
|
||||
* Opcode: 0x1001
|
||||
* **Params**: REG1, REG2
|
||||
* ```
|
||||
if REG1 < REG2 {
|
||||
@@ -131,6 +148,7 @@ wrapping around to 0.
|
||||
```
|
||||
* Sets the COMPARE flag to 1 if REG1 < REG2
|
||||
* Jz
|
||||
* Opcode: 0x1100
|
||||
* **Params**: REG1
|
||||
* ```
|
||||
if FLAGS[1] == 0 {
|
||||
@@ -139,6 +157,7 @@ wrapping around to 0.
|
||||
```
|
||||
* Jumps to the address in REG1 if COMPARE flag is 0.
|
||||
* Jnz
|
||||
* Opcode: 0x1001
|
||||
* **Params**: REG1
|
||||
* ```
|
||||
if FLAGS[1] != 0 {
|
||||
@@ -150,39 +169,108 @@ wrapping around to 0.
|
||||
## Data movement
|
||||
|
||||
* Load
|
||||
* Opcode: 0x2000
|
||||
* **Params**: REG1, REG2
|
||||
* ```
|
||||
REG1 = MEM[REG2];
|
||||
```
|
||||
* Sets REG1 to the value at the memory address in REG2.
|
||||
* ```
|
||||
32 16 10 4 0
|
||||
64 - opcode reg1 reg2 unused
|
||||
/ / / /
|
||||
+-------------------------------------------+
|
||||
| 0010000000000000 | ...... | ...... | XXXX |
|
||||
+-------------------------------------------+
|
||||
```
|
||||
* RegCopy
|
||||
* Opcode: 0x2001
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG2`
|
||||
* Copies the value in REG2 into REG1.
|
||||
* ```
|
||||
32 16 10 4 0
|
||||
opcode reg1 reg2 unused
|
||||
/ / / /
|
||||
+-------------------------------------------+
|
||||
| 0010000000000001 | REG1.. | REG2.. | XXXX |
|
||||
+-------------------------------------------+
|
||||
```
|
||||
* StoreImm64
|
||||
* Opcode: 0x2100
|
||||
* **Params**: REG1, IMM_64
|
||||
* `REG1 = IMM_64`
|
||||
* Sets REG1 to the specified 64-bit number.
|
||||
* StoreImm32
|
||||
* Opcode: 0x2101
|
||||
* **Params**: REG1, IMM_32
|
||||
* `REG1 = IMM_32`
|
||||
* Sets REG1 to the specified 32-bit number.
|
||||
* ```
|
||||
64 48 42 36 32 0
|
||||
opcode reg1 reg2 unused
|
||||
/ / / / immediate 32 bit value
|
||||
/ / / / /
|
||||
+------------------------------------------------------------------------------+
|
||||
| 0010000100000001 | REG1.. | REG2.. | XXXX | IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
|
||||
+------------------------------------------------------------------------------+
|
||||
```
|
||||
* MemCopy
|
||||
* Opcode: 0x2200
|
||||
* **Params**: REG1, REG2
|
||||
* `MEM[REG1] = MEM[REG2]`
|
||||
* Copies the value at the memory address in REG2 to the memory address in REG1.
|
||||
* ```
|
||||
32 16 10 4 0
|
||||
opcode reg1 reg2 unused
|
||||
/ / / /
|
||||
+-------------------------------------------+
|
||||
| 0010001000000000 | REG1.. | REG2.. | XXXX |
|
||||
+-------------------------------------------+
|
||||
```
|
||||
* Store
|
||||
* Opcode: 0x2201
|
||||
* **Params**: REG1, REG2
|
||||
* ```
|
||||
MEM[REG2] = REG1;
|
||||
```
|
||||
* Sets the value at the memory address in REG2 to the value in REG1.
|
||||
* StoreImm32
|
||||
* **Params**: REG1, IMM_32
|
||||
* `REG1 = IMM_32`
|
||||
* Sets REG1 to the specified 32-bit number.
|
||||
* MemCopy
|
||||
* **Params**: REG1, REG2
|
||||
* `MEM[REG1] = MEM[REG2]`
|
||||
* Copies the value at the memory address in REG2 to the memory address in REG1.
|
||||
* RegCopy
|
||||
* **Params**: REG1, REG2
|
||||
* `REG1 = REG2`
|
||||
* Copies the value in REG2 into REG1.
|
||||
* ```
|
||||
32 16 10 4 0
|
||||
opcode reg1 reg2 unused
|
||||
/ / / /
|
||||
+-------------------------------------------+
|
||||
| 0010001000000001 | REG1.. | REG2.. | XXXX |
|
||||
+-------------------------------------------+
|
||||
```
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
* Halt
|
||||
* Opcode: 0xF000
|
||||
* **Params**: (none)
|
||||
* `FLAGS[0] = 1`
|
||||
* Halts the machine
|
||||
* ```
|
||||
16
|
||||
opcode
|
||||
/
|
||||
+------------------+
|
||||
| 0010011000000000 |
|
||||
+------------------+
|
||||
```
|
||||
* Nop
|
||||
* Opcode: 0xF001
|
||||
* **Params**: (none)
|
||||
* Does nothing
|
||||
* ```
|
||||
16
|
||||
opcode
|
||||
/
|
||||
+------------------+
|
||||
| 0010011000000001 |
|
||||
+------------------+
|
||||
```
|
||||
|
||||
## Other instructions TODO
|
||||
|
||||
@@ -194,6 +282,7 @@ wrapping around to 0.
|
||||
* Push
|
||||
* Pop
|
||||
* More immediate stores?
|
||||
* Idea: Store42 (or whatever number of bits) that maximizes the usage of a 64-bit instruction
|
||||
|
||||
# Binary object format
|
||||
|
||||
|
||||
Reference in New Issue
Block a user