CPUSim64 Instruction Set

The CPUSim64 instruction set has 32 instructions that operate on the 29 general purpose integer registers, 32 floating point registers, stack frame pointer, stack pointer, program counter and status register. Each instruction can have multiple numbers and types of operands as described in this document.

In the Operation columns below the description of the operation will use the operands in the same order that they appear in the Operands column. The <- or -> symbols show the direction of data movement. For all but the STORE instructions the direction is into the first argument. If a register is listed such as A it means that the value in the register is used. If a register is listed in square brackets such as [A] it means that the value of A is taken as an address and the contents in that address are used. This is known as a memory reference. You will only see this in the Register Load/Store Instructions.

Because some instructions operate on integer registers or floating point registers and because some instructions support integer literals of differing sizes, the following table lists the symbols used in the Operands and Operation columns

Register Refernce Symbols
SymbolDescription
RInteger in r0-r28
AAddress in r0-r28, SF, SP or PC
FFloat in f0-f31
XR or F
YA or F
OR or C
QA, F or C
SFStack Frame
SPStack Pointer
PCProgram Counter
SRStatus Register (PZSO)
Integer Literal Symbols
SymbolDescription
Z4-bit condition code used for JUMP
or CALL or port number 0-15 for IN and OUT
B8-bit signed integer
C156-bit signed integer
C242-bit signed integer
C40-bit signed integer
K64-bit signed integer
E64-bit IEEE float
P64-bit Absolute unsigned address

No-op/Debug

Does nothing but take up a CPU cycle. If debugging is turn on for the virtual CPU, then debugging information is printed.

OpcodePneumonicOperandsOperation
0NOPNDoes nothing
0DEBUGY
YY
Prints contents of 1-4 registers if debugging is enabled.
0DEBUGAC
CC
Dump memory from starting address for number of words (walk heap if operand 2 is neg)

Register Load/Store Instructions

Clear

Used to move zero into registers.

OpcodePneumonicOperandsOperation
1CLEARN
X
XX
XXX
XXXX
Clear all registers or 1-4 specific registers.

Move (Register-to-Register)

MOVE is used to move data between registers. Conditional version moves the third operand into the destination register if the condition is met otherwise it moves the fourth operand.

OpcodePneumonicOperandsOperation
2MOVEYY
YC
AAR
AAC
ACA
ZYQQ
Y1 <- Y2
Y <- C
A1 <- A2 + R
A1 <- A2 + C
A1 <- C + A2
if Z, Y <- Q1 else Y <- Q2

Load (Memory-to-Register)

LOAD is used to move data from memory into registers.

OpcodePneumonicOperandsOperation
3LOADYC
YA
YAC
YCA
YCC
YAR
Y <- [C]
Y <- [A]
Y <- [A + C]
Y <- [C + A]
Y <- [C + C]
Y <- [A + R]

Store (Register-to-Memory)

STORE is used to move data from registers into memory.

OpcodePneumonicOperandsOperation
4STOREQC
QA
QAC
QCA
QCC
QAR
Q -> [C]
Q -> [A]
Q -> [A + C]
Q -> [C + A]
Q -> [C + C]
Q -> [A + R]

Pop

This instruction moves the SP register up by one and then pulls the value now pointed to by the SP.

OpcodePneumonicOperandsOperation
5POPN
Y
SP = SP + 1; discard <- [SP]
SP = SP + 1; Y <- [SP]

Push

This instruction pushes the operand onto the stack at the current value of the SP. It then moves the SP down by one.

OpcodePneumonicOperandsOperation
6PUSHY
C
Y -> [SP]; SP = SP - 1
C -> [SP]; SP = SP - 1

Control Instructions

Jump

The JUMP instruction branches control to the address specified by the operands. The conditional forms only branch if the SR condition specified is true.

OpcodePneumonicOperandsOperation
7JUMPA
C
ZA
ZC
ZAC
ZCA
ZCC
ZAR
PC <- A
PC <- C
if Z, PC <- A
if Z, PC <- C
if Z, PC <- A + C
if Z, PC <- C + A
if Z, PC <- C + C
if Z, PC <- A + R

Call

Before the operation listed in the table, all CALL instructions first perform the following actions: Push SP + 1 (Return Address), Push SF (Old Stack Frame) then set SF to SP.

PC + 1 -> [SP]; SP = SP - 1
SF -> [SP]; SP = SP - 1
SF <- SP
OpcodePneumonicOperandsOperation
8CALLA
C
ZA
ZC
ZAC
ZCA
ZCC
ZAR
PC <- A
PC <- C
if Z, PC <- A
if Z, PC <- C
if Z, PC <- A + C
if Z, PC <- C + A
if Z, PC <- C + C
if Z, PC <- A + R

Return

Returns from a CALL. RETURN resets the SP back to the SF which is where the SP was when the CALL started. Then pops the SF off the stack. Then pops the return address off the stack.

OpcodePneumonicOperandsOperation
9RETURNNSP <- SF
SP = SP + 1; SF <- [SP]
SP = SP + 1; PC <- [SP]

Interrupt

The INTERRUPT instruction invokes the software interrupt specified by its integer argument. This effectively calls the operating system function associated with the interrupt and then returns.

OpcodePneumonicOperandsOperation
10INTERRUPTR
C
See List of Software Interrupts

Stop

STOP halts execution of the virtual CPU.

OpcodePneumonicOperandsOperation
11STOPN

Arithmetic Instructions

Negate

OpcodePneumonicOperandsOperation
12NEGXX <- -X

Addition

OpcodePneumonicOperandsOperation
13ADDAR
FX
YC
AAR
FFX
AAC
FFC
ACA
FCF
A1 <- A1 + R
F1 <- F1 + X
Y1 <- Y1 + C
A1 <- A2 + R
F1 <- F2 + X
A1 <- A2 + C
F1 <- F2 + C
A1 <- C + A2
F1 <- C + F2

Subtraction

OpcodePneumonicOperandsOperation
14SUBAR
FX
YC
AAR
FFX
AAC
FFC
ACA
FCF
A1 <- A1 - R
F1 <- F1 - X
Y1 <- Y1 - C
A1 <- A2 - R
F1 <- F2 - X
A1 <- A2 - C
F1 <- F2 - C
A1 <- C - A2
F1 <- C - F2

Multiplication

OpcodePneumonicOperandsOperation
15MULTAR
FX
YC
AAR
FFX
AAC
FFC
ACA
FCF
A1 <- A1 * R
F1 <- F1 * X
Y1 <- Y1 * C
A1 <- A2 * R
F1 <- F2 * X
A1 <- A2 * C
F1 <- F2 * C
A1 <- C * A2
F1 <- C * F2

Division

OpcodePneumonicOperandsOperation
16DIVAR
FX
YC
AAR
FFX
AAC
FFC
ACA
FCF
RRRR
RRRC
A1 <- A1 / R
F1 <- F1 / X
Y1 <- Y1 / C
A1 <- A2 / R
F1 <- F2 / X
A1 <- A2 / C
F1 <- F2 / C
A1 <- C / A2
F1 <- C / F2
R1 <- R3 / R4; R2 <- R3 % R4
R1 <- R3 / C; R2 <- R3 % C
16RECIPFF <- 1 / F

Logical and Conditional Instructions

Complement

OpcodePneumonicOperandsOperation
17COMPLRR <- ~R

Bitwise AND

OpcodePneumonicOperandsOperation
18ANDRR
RC
RRR
RRC
R1 <- R1 & R2
R1 <- R1 & C
R1 <- R2 & R3
R1 <- R2 & C

Bitwise OR

OpcodePneumonicOperandsOperation
19ORRR
RC
RRR
RRC
R1 <- R1 | R2
R1 <- R1 | C
R1 <- R2 | R3
R1 <- R2 | C

Bitwise XOR

OpcodePneumonicOperandsOperation
20XORRR
RC
RRR
RRC
R1 <- R1 ^ R2
R1 <- R1 ^ C
R1 <- R2 ^ R3
R1 <- R2 ^ C

Test

OpcodePneumonicOperandsOperation
21TESTXSets SR based on X

Compare

OpcodePneumonicOperandsOperation
22CMPAA
AC
FF
Sets SR based on A1 - A2
Sets SR based on A - C
Sets SR based on F1 - F2

Shift Instructions

Logical & Arithmetic Left Shift

Shifts the bits in the integer register to the left. Zero bit(s) is always shifted in on the right. These can be used for either logical or arithmetic left shift. Arithmetic left shift is equivalent to multiplying by powers of 2, i.e x << 1 is equivalent to x * 2, x << 2 is equivalent to x * 4, x << 3 is equivalent to x * 8, etc.

OpcodePneumonicOperandsOperation
23LSHIFTRR
RC
RRR
RRC
R1 <- R1 << R2
R1 <- R1 << C
R1 <- R2 << R3
R1 <- R2 << C

Logical Right Shift

Shifts the bits in the integer register to the right. Zero bit(s) is always shifted in on the left.

OpcodePneumonicOperandsOperation
24RSHIFTRR
RC
RRR
RRC
R1 <- R1 >> R2
R1 <- R1 >> C
R1 <- R2 >> R3
R1 <- R2 >> C

Arithmetic Right Shift

Shifts the bits in the integer register to the right. Sign bit(s) is always shifted in on the right. This results in the equivalent of dividing a signed integer by powers of 2.

OpcodePneumonicOperandsOperation
25ARSHIFTRR
RC
RRR
RRC
R1 <- R1 >> R2
R1 <- R1 >> C
R1 <- R2 >> R3
R1 <- R2 >> C

Left Rotate

Shifts the bits in the integer register to the left. The high bit that is shifted off is shifted in on the right.

OpcodePneumonicOperandsOperation
26LROTATERR
RC
RRR
RRC
R1 <- R1 << R2
R1 <- R1 << C
R1 <- R2 << R3
R1 <- R2 << C

Right Rotate

Shifts the bits in the integer register to the right. The low bit that is shifted off is shifted in on the left.

OpcodePneumonicOperandsOperation
27RROTATERR
RC
RRR
RRC
R1 <- R1 >> R2
R1 <- R1 >> C
R1 <- R2 >> R3
R1 <- R2 >> C

I/O Instructions

Input and output instructions read/write a specified number of bytes to a port which can be a stream to the console if STDIN, STDOUT or STDERR are used for the port or to a file that has been opened.

I/O sizes are specified in <system/io.def> using the following symbols.

SymbolSize
CHAR 0
BYTE 1
SHORT 2
WORD 4
SINGLE 4
DWORD 8
LONG 8
DOUBLE 8

Input

OpcodePneumonicOperandsOperation
28INXZZ
XRR
XRZ
XZR
X <- Read Z1 bytes from port Z2
X <- Read R1 bytes from port R2
X <- Read R bytes from port Z
X <- Read Z bytes from port R

Output

OpcodePneumonicOperandsOperation
29OUTZZQ
RRQ
RZQ
ZRQ
Write Z1 bytes to port Z2 <- Q
Write R1 bytes to port R2 <- Q
Write R bytes to port Z <- Q
Write Z bytes to port R <- Q

Pack

OpcodePneumonicOperandsOperation
30PACKRR
RRR
RRRR

Pack64

OpcodePneumonicOperandsOperation
30PACK64RR
RRR
RRRR

Unpack

OpcodePneumonicOperandsOperation
31UNPACKRR
RRR
RRRR

Unpack64

OpcodePneumonicOperandsOperation
31UNPACK64RR
RRR
RRRR

Compare and Swap

OpcodePneumonicOperandsOperation
32CASRRAO
CCAO
RCAO
CRAO
Atomic compare and swap
First operand is old value
Second operand is new value
Remaining arguments are address + offset

Endian Mode

OpcodePneumonicOperandsOperation
33ENDIANRR
RC
CR
CC
Sets I/O Port endian mode to big-endian or little-endian
First operand is port [0-15]
Second operand is mode (TRUE for big-endian, FALSE for little-endian)