Image format is not specified, though ELF is recommended
All numbers are encoded little-endian
There is 256 registers, they are represented by a byte
Immediate values are 8, 16, 32 or 64 bit
Instruction encoding
Instruction operands are packed (no alignment)
[opcode, operand 0, operand 1, …]
Instruction parameter types
R: Register (8 bits)
Relative program-counter offset immediates:
O: 32 bit (Si32)
P: 16 bit (Si16)
Immediates:
B: Byte, 8 bit (Xi8)
H: Half-word, 16 bit (Xi16)
W: Word, 32 bit (Xi32)
D: Double-word, 64 bit (Xi64)
A: Absolute address immediate, 64 bit (Ui64)
Types
Sin: Signed integer of size n bits (Si8, Si16, Si32, Si64)
Uin: Unsigned integer of size n bits (Ui8, Ui16, Ui32, Ui64)
Xin: Sign-agnostic integer of size n bits (Xi8, Xi16, Xi32, Xi64)
Fln: Floating point number of size n bits (Fl32, Fl64)
Behaviour
There is only one type of register, a general-purpose one.
Used for both integers and floats.
Integer operations are wrapping, including signed numbers
Bitshifts are truncating
Two's complement
Floats as specified by IEEE 754
Execution model is implementation defined as long all observable
effects are performed in correct order
Relative addressing
Relative addresses are computed from address of the first byte
of offset in the code. Not from the beginning of current or following instruction.
Zero register
Register 0
Cannot be clobbered
Write is no-op
Load always yields 0
Rounding modes
Rounding mode
Value
To nearest, ties to even
0b00
Towards 0 (truncate)
0b01
Towards +∞ (up)
0b10
Towards -∞ (down)
0b11
Remaining values in the byte traps with invalid operand exception
Memory
Memory implementation is implementation-defined
Zero address (0x0) is considered invalid
Traps
Environment call
Environment breakpoint
Program counter goes to the following instruction
Exceptions
Memory access fault
Invalid operand
Unknown opcode
Program counter stays on the currently executed instruction
Instructions
#n: register in parameter n
$n: for immediate in parameter n
#P ← V: Set register P to value V
[x]: Address x
XY: X bytes from location Y
pc: Program counter
<XYZ>: Placeholder
Type(X): Cast
Program execution control
Type N
Opcode
Mnemonic
Action
0x00
UN
Throw unreachable code exception
0x01
TX
Terminate execution (eg. on end of program)
0x02
NOP
Do nothing
Binary register-register ops
Type RRR
Action: #0 ← #1 <OP> #2
Addition (+)
Opcode
Mnemonic
Type
0x03
ADD8
Xi8
0x04
ADD16
Xi16
0x05
ADD32
Xi32
0x06
ADD64
Xi64
Subtraction (-)
Opcode
Mnemonic
Type
0x07
SUB8
Xi8
0x08
SUB16
Xi16
0x09
SUB32
Xi32
0x0A
SUB64
Xi64
Multiplication (*)
Opcode
Mnemonic
Type
0x0B
MUL8
Xi8
0x0C
MUL16
Xi16
0x0D
MUL32
Xi32
0x0E
MUL64
Xi64
Bitwise ops (type: Xi64)
Opcode
Mnemonic
Operation
0x0F
AND
Conjunction (&)
0x10
OR
Disjunction (|)
0x11
XOR
Non-equivalence (^)
Unsigned left bitshift (<<)
Opcode
Mnemonic
Type
0x12
SLU8
Ui8
0x13
SLU16
Ui16
0x14
SLU32
Ui32
0x15
SLU64
Ui64
Unsigned right bitshift (>>)
Opcode
Mnemonic
Type
0x16
SRU8
Ui8
0x17
SRU16
Ui16
0x18
SRU32
Ui32
0x19
SRU64
Ui64
Signed right bitshift (>>)
Opcode
Mnemonic
Type
0x1A
SRS8
Si8
0x1B
SRS16
Si16
0x1C
SRS32
Si32
0x1D
SRS64
Si64
Comparsion
Compares two numbers, saves result to register
Operation: #0 ← #1 <=> #2
Ordering
Number
<
-1
=
0
>
1
Opcode
Mnemonic
Type
0x1E
CMPU
Ui64
0x1F
CMPS
Si64
Merged divide-remainder
Type RRRR
Operation:
#0 ← #2 / #3
#1 ← #2 % #3
If dividing by zero:
#0 ← Ui64(-1)
#1 ← #2
Opcode
Mnemonic
Type
0x20
DIRU8
Ui8
0x21
DIRU16
Ui16
0x22
DIRU32
Ui32
0x23
DIRU64
Ui64
0x24
DIRS8
Si8
0x25
DIRS16
Si16
0x26
DIRS32
Si32
0x27
DIRS64
Si64
Unary register operations (type: Xi64)
Type: RR
Operation: #0 ← <OP> #1
Opcode
Mnemonic
Operation
0x28
NEG
Bitwise complement (~)
0x29
NOT
Logical negation (!)
Sign extensions
Operation: #0 ← Si64(#1)
Opcode
Mnemonic
Source type
0x2A
SXT8
Si8
0x2B
SXT16
Si16
0x2C
SXT32
Si32
Binary register-immediate operations
Type: RR<IMM>
Operation: #0 ← #1 <OP> $2
Addition (+)
Opcode
Mnemonic
Type
0x2D
ADDI8
Xi8
0x2E
ADDI16
Xi16
0x2F
ADDI32
Xi32
0x30
ADDI64
Xi64
Multiplication (*)
Opcode
Mnemonic
Type
0x31
MULI8
Xi8
0x32
MULI16
Xi16
0x33
MULI32
Xi32
0x34
MULI64
Xi64
Bitwise ops (type: Xi64)
Opcode
Mnemonic
Operation
0x35
ANDI
Conjunction (&)
0x36
ORI
Disjunction (|)
0x37
XORI
Non-equivalence (^)
Register-immediate bitshifts
Type: RRB
Operation: #0 ← #1 <OP> $2
Unsigned left bitshift (<<)
Opcode
Mnemonic
Type
0x38
SLUI8
Ui8
0x39
SLUI16
Ui16
0x3A
SLUI32
Ui32
0x3B
SLUI64
Ui64
Unsigned right bitshift (>>)
Opcode
Mnemonic
Type
0x3C
SRUI8
Ui8
0x3D
SRUI16
Ui16
0x3E
SRUI32
Ui32
0x3F
SRUI64
Ui64
Signed right bitshift (>>)
Opcode
Mnemonic
Type
0x40
SRSI8
Si8
0x41
SRSI16
Si16
0x42
SRSI32
Si32
0x43
SRSI64
Si64
Comparsion
Compares two numbers, saves result to register
Operation: #0 ← #1 <=> $2
Comparsion table same for register-register one
Opcode
Mnemonic
Type
0x44
CMPUI
Ui64
0x45
CMPSI
Si64
Register copies
Type: RR
Opcode
Mnemonic
Operation
0x46
CP
Copy register value (#0 ← #1)
0x47
SWA
Swap register values (#0 ⇆ #1)
Load immediate
Load immediate value from code to register
Type: R<IMM>
Operation: #0 ← $1
Opcode
Mnemonic
Type
0x48
LI8
Xi8
0x49
LI16
Xi16
0x4A
Li32
Xi32
0x4B
Li64
Xi64
Load relative address
Compute value from program counter, register value and offset
Type: RRO
Operation: #0 ← pc + #1 + $2
Opcode
Mnemonic
0x4C
LRA
Memory access operations
Immediate $3 specifies size
If size is greater than register size,
it overflows to adjecent register
(eg. copying 16 bytes to register r1 copies first 8 bytes to it
and the remaining to r2)
Absolute addressing
Type: RRAH
Computes address from base register and absolute offset
Opcode
Mnemonic
Operation
0x4D
LD
#0 ← $3[#1 + $2]
0x4E
ST
$3[#1 + $2] ← #0
Relative addressing
Type: RROH
Computes address from register and offset from program counter
Opcode
Mnemonic
Operation
0x4F
LDR
#0 ← $3[pc + #1 + $2]
0x50
STR
$3[pc + #1 + $2] ← #0
Block memory copy
Type: RRH
Copies block of $3 bytes from memory location on address on #0 to #1
Opcode
Mnemonic
Operation
0x51
BMC
$3[#1] ← $3[x0]
Block register copy
Type: RRB
Copy block of $3 registers starting with #0 to #1
Copying over the 256 registers causes an exception
Opcode
Mnemonic
Operation
0x52
BRC
$3#1 ← $3#0
Relative jump
Type: O
Opcode
Mnemonic
Operation
0x53
JMP
pc ← pc + $0
Linking jump
Operation:
Save address of following instruction to #0
#0 ← pc+<instruction size>
Jump to specified address
Opcode
Mnemonic
Instruction type
Address
0x54
JAL
RRO (size = 6 B)
Relative, pc + #1 + $2
0x55
JALA
RRA (size = 10 B)
Absolute, #1 + $2
Conditional jump
Perform comparsion, if operation met, jump to relative address
Type: RRP
Operation: if #0 <CMP> #1 { pc ← pc + $2 }
Opcode
Mnemonic
Condition
Type
0x56
JEQ
Equals (=)
Xi64
0x57
JNE
Not-equals (≠)
Xi64
0x58
JLTU
Less-than (<)
Ui64
0x59
JGTU
Greater-than (>)
Ui64
0x5A
JLTS
Less-than (<)
Si64
0x5B
JGTS
Greater-than (>)
Si64
Environment traps
Traps to the environment
Type: N
Opcode
Mnemonic
Trap type
0x5C
ECA
Environment call
0x5D
EBP
Breakpoint
Floating point binary operations
Type: RRR
Operation: #0 ← #1 <OP> #2
Opcode
Mnemonic
Operation
Type
0x5E
FADD32
Addition (+)
Fl32
0x5F
FADD64
Addition (+)
Fl64
0x60
FSUB32
Subtraction (-)
Fl32
0x61
FSUB64
Subtraction (-)
Fl64
0x62
FMUL32
Multiplication (*)
Fl32
0x63
FMUL64
Multiplication (*)
Fl64
0x64
FDIV32
Division (/)
Fl32
0x65
FDIV64
Division (/)
Fl64
Fused multiply-add
Type: RRRR
Operation: #0 ← (#1 * #2) + #3
Opcode
Mnemonic
Type
0x66
FMA32
Fl32
0x67
FMA64
Fl64
Comparsions
Type: RRR
Operation: #0 ← #1 <=> #2
Comparsion table same as for CMPx/CMPxI
NaN is less-than/greater-than depends on variant
Opcode
Mnemonic
Type
NaN is
0x6A
FCMPLT32
Fl32
<
0x6B
FCMPLT64
Fl64
<
0x6C
FCMPGT32
Fl32
>
0x6D
FCMPGT64
Fl64
>
Int to float
Type: RR
Converts from Si64
Operation: #0 ← Fl<SIZE>(#1)
Opcode
Mnemonic
Type
0x6E
ITF32
Fl32
0x6F
ITF64
Fl64
Float to int
Type: RRB
Operation: #0 ← Si64(#1)
Immediate $2 specifies rounding mode
Opcode
Mnemonic
Type
0x70
FTI32
Fl32
0x71
FTI64
Fl64
Fl32 to Fl64
Type: RR
Operation: #0 ← Fl64(#1)
Opcode
Mnemonic
0x72
FC32T64
Fl64 to Fl32
Type: RRB
Operation: #0 ← Fl32(#1)
Immediate $2 specified rounding mode
Opcode
Mnemonic
0x73
FC64T32
16-bit relative address instruction variants
Opcode
Mnemonic
Type
Variant of
0x74
LRA16
RRP
LRA
0x75
LDR16
RRPH
LDR
0x76
STR16
RRPH
STR
0x77
JMP16
P
JMP
psABI
C datatypes and alignment
One byte is 8 bits
C Type
Description
Byte sizes
char
Character / byte
1
short
Short integer
2
int
Integer
4
long
Long integer
8
long long
Long long integer
8
float
Single-precision float
4
double
Double-precision float
8
long double
Extended-precision float
8
Bikeshedding note: long double is now 8 bytes as
the base ISA does not support f128. an extension
for that should be made.
Call convention
Registers r1 – r31 are caller saved
Registers r32 – r255 are callee saved
Register
Description
Saver
r0
Hard-wired zero
N/A
r1 - r2
Return values
Caller
r2 - r11
Function parameters
Caller
r12 - r30
General purpose
Caller
r31
Return address
Caller
r32 - r253
General purpose
Callee
r254
Stack pointer
Callee
r255
Thread pointer
N/A
If return value is too big to fit r1, r2 is also used.
Values larger than two double-words are passed by reference