Table of Contents
The instructions are 16 bit words. Most instructions use a single word, however, some of them use a second word to store an immediate 16-bit value.
The general format is as follows:
Bits | 15-12 | 11-9 | 8-6 | 5-3 | 2-0 |
---|---|---|---|---|---|
Contents | Opcode0 | Operand A | Opcode1 | OPN | Operand B |
Contents | Opcode0 | Operand A | Opcode1 | 6-bit Immediate |
Summary
Opcode 0\1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
Addressing mode | [BP+Imm6] | #Imm6 | [Rs] | Rs,#Imm16,[Addr16], Rs ASR | Rs LSL/LSR | Rs ROL/ROR | [Addr6] | |
0 | ADD, JB, JNAE, JCC | ADD | ||||||
1 | ADC, JAE, JNB, JCS | ADC | ||||||
2 | SUB, JGE, JNL, JSC | SUB | ||||||
3 | SBC, JL, JNGE, JSS | SBC | ||||||
4 | CMP, JNE, JNZ | CMP | ||||||
5 | JE, JZ | |||||||
6 | NEG, JPL | NEG | ||||||
7 | JMI | |||||||
8 | XOR, JBE, JNA | XOR | ||||||
9 | LD, JA, JNBE | POP,RETF,RETI | LD | |||||
A | OR, JLE, JNG | OR | ||||||
B | AND, JG, JNLE | AND | ||||||
C | TEST, JVC | TEST | ||||||
D | ST, JVS | PUSH | ST | |||||
E | JMP | |||||||
F | MUL.us | CALL | MAC.us,GOTO | MAC.us | MUL.ss | INT,IRQ,FIR_MOV,BREAK | MAC.ss |
- Instructions in bold: uses the addressing mode listed on the first line
- Instructions in italics: only if operand A (destination register) is PC
Special instructions
“Special” instructions are identified by Opcode0 = 0xF
Multiplication
Instruction | Opcode0 | Operand A | Opcode1 | OPN | Operand B |
---|---|---|---|---|---|
MAC (unsigned*signed) | F | Op.A | 2 + (N ≥ 8) | N & 7 | Op.B |
MAC (signed*signed) | F | Op.A | 6 + (N ≥ 8) | N & 7 | Op.B |
MUL (unsigned*signed) | F | Op.A | 0 | 1 | Op.B |
MUL (signed*signed) | F | Op.A | 4 | 1 | Op.B |
Note: Operand A and Operand B cannot be 0, 6 or 7 (it is not possible to multiply SP, SR or PC with something). They also can not be 3 or 4 in MAC (MR is used for intermediate results). If the size of the MAC operation is exactly 16, it will be encoded as N=0.
CALL and GOTO
Instruction | Opcode0 | Operand A | Opcode1 | 6-bit Immediate | Second word | |
---|---|---|---|---|---|---|
CALL | F | ? | 1 | CS: value | PC value | |
GOTO | F | 7 | 2 | CS: value | PC value |
The target address is formed by the immediate6 value (for CS:) and another word after the instruction (for PC)
Interrupts
Instruction | Opcode0 | Operand A | Opcode1 | 6-bit Immediate |
---|---|---|---|---|
INT OFF | F | ? | 5 | 00 |
INT IRQ | F | ? | 5 | 01 |
INT FIQ | F | ? | 5 | 02 |
INT IRQ,FIQ | F | ? | 5 | 03 |
FIR_MOV ON | F | ? | 5 | 04 |
FIR_MOV OFF | F | ? | 5 | 05 |
IRQ OFF | F | ? | 5 | 08 |
IRQ ON | F | ? | 5 | 09 |
FIQ OFF | F | ? | 5 | 0C |
FIQ ON | F | ? | 5 | 0E |
BREAK | F | ? | 5 | 20 |
probably other instructions (FRACTION, …) fit in here
Jump instructions
Jump instructions are identified by Operand A = 7 (makes sense, because they change the PC which is register 7)
Instruction | Opcode0 | Operand A | Opcode1 | 6-bit Immediate | Condition |
---|---|---|---|---|---|
JB, JNAE, JCC | 0 | 7 | Direction | Jump offset | C = 0 |
JAE, JNB, JCS | 1 | 7 | Direction | Jump offset | C = 1 |
JGE, JNL, JSC | 2 | 7 | Direction | Jump offset | S = 0 |
JL, JNGE, JSS | 3 | 7 | Direction | Jump offset | S = 1 |
JNE, JNZ | 4 | 7 | Direction | Jump offset | Z = 0 |
JE, JZ | 5 | 7 | Direction | Jump offset | Z = 1 |
JPL | 6 | 7 | Direction | Jump offset | N = 0 |
JMI | 7 | 7 | Direction | Jump offset | N = 1 |
JBE, JNA | 8 | 7 | Direction | Jump offset | !(Z=0&C=1) |
JA, JNBE | 9 | 7 | Direction | Jump offset | Z=0 & C=1 |
JLE, JNG | A | 7 | Direction | Jump offset | !(Z=0&S=0) |
JG, JNLE | B | 7 | Direction | Jump offset | Z=0 & S=0 |
JVC | C | 7 | Direction | Jump offset | N = S |
JVS | D | 7 | Direction | Jump offset | N != S |
JMP | E | 7 | Direction | Jump offset | Always |
F | 7 | Reserved for special instructions |
Opcode1 indicates the jump direction, and can be 0 (jump forward) or 1 (jump backward). The offset is counted from the opcode following the jump instruction, so an offset of 0 would jump to the next instruction (basically a NOP) while a offset of -1 (1 backwards) would be an infinite loop and a offset of (+1) would skip a single instruction.
ALU instructions
Instruction | Opcode0 | Operand A | Opcode1 | OPN | Operand B |
---|---|---|---|---|---|
ADD | 0 | Op. A | Addr Mode | Param | Op. B |
ADC | 1 | Op. A | Addr Mode | Param | Op. B |
SUB | 2 | Op. A | Addr Mode | Param | Op. B |
SBC | 3 | Op. A | Addr Mode | Param | Op. B |
CMP | 4 | Op. A | Addr Mode | Param | Op. B |
NEG | 6 | Op. A | Addr Mode | Param | Op. B |
XOR | 8 | Op. A | Addr Mode | Param | Op. B |
LD | 9 | Op. A | Addr Mode | Param | Op. B |
POP | 9 | First reg - 1 | 2 | Register count | Stack pointer reg |
RETF | 9 | 5 (SR) | 2 | 2 (SR, PC) | 0 (SP) |
RETI | 9 | 5 (SR) | 2 | 3 (SR, PC, FR) | 0 (SP) |
OR | A | Op. A | Addr Mode | Param | Op. B |
AND | B | Op. A | Addr Mode | Param | Op. B |
TEST | C | Op. A | Addr Mode | Param | Op. B |
ST | D | Op. A | Addr Mode | Param | Op. B |
PUSH | D | Last reg -1 | 2 | Register count | Stack pointer reg |
F | Reserved for special instructions |
Depending on opcode1, various addressing modes can be used:
Addressing mode | Opcode0 | Operand A | Opcode1 | OPN | Operand B | Notes | |
---|---|---|---|---|---|---|---|
[BP+Imm6] | ALU op | Op. A | 0 | 6-bit immediate | Op. A ≠ PC | ||
#Imm6 | ALU op | Op. A | 1 | 6-bit immediate | Op. A ≠ PC | ||
Special (POP, PUSH) | 2 | ||||||
[Rs] | ALU op | Op. A | 3 | 0 | Rs | ||
[Rs--] | ALU op | Op. A | 3 | 1 | Rs | ||
[Rs++] | ALU op | Op. A | 3 | 2 | Rs | ||
[++Rs] | ALU op | Op. A | 3 | 3 | Rs | ||
D:[Rs] | ALU op | Op. A | 3 | 4 | Rs | ||
D:[Rs--] | ALU op | Op. A | 3 | 5 | Rs | ||
D:[Rs++] | ALU op | Op. A | 3 | 6 | Rs | ||
D:[++Rs] | ALU op | Op. A | 3 | 7 | Rs | ||
Rs | ALU op | Op. A | 4 | 0 | Rs | ||
#Imm16 | ALU op | Op. A | 4 | 1 | Rs* | 16-bit immediate in next word, Rs is first operand | |
From [Addr16] | ALU op | Op. A | 4 | 2 | Rs* | 16-bit address in next word, Rs is first operand | |
To [Addr16] | ALU op | Op. A | 4 | 3 | Rs* | 16-bit address in next word, Rs is first operand | |
Rs ASR shift | ALU op | Op. A | 4 | 4 + (shift - 1) | Rs | ||
Rs LSL shift | ALU op | Op. A | 5 | shift - 1 | Rs | ||
Rs LSR shift | ALU op | Op. A | 5 | 4 + (shift - 1) | Rs | ||
Rs ROL shift | ALU op | Op. A | 6 | shift - 1 | Rs | ||
Rs ROR shift | ALU op | Op. A | 6 | 4 + (shift - 1) | Rs | ||
[Addr6] | ALU op | Op. A | 7 | 6-bit address |
The instructions using Imm16 or Addr16 are 3-operand instructions, for example:
R3 = R2 + Imm16
naken_asm syntax:
ADD R3, R2, #Imm16
All other forms are 2-operand: operand A is always a register and used as both source and destination.
The LD operation uses operand A only as a target.
The ST operation uses the second source operand (Rs, address, …) as the target, and operand A (always a register) as the source.
Other operations can use both forms, so the “From [Addr16]” would be something like this:
R3 = R2 + [Addr16]
and the “To [Addr16]” corresponds to:
[Addr16] = R2 + R3
(so in this case the register encoded in OPA is used as a source, not a destination).
The LD and ST operations with the 16-bit addressing mode ignore the value of Rs, they use only Ra and the 16-bit value.