Hack64 Wiki
Other Titles
Hack64 Wiki
Other Titles
This is an old revision of the document!
The main processor used by the Nintendo 64.
Information on this page that is specifically related to the Nintendo 64 is highlighted in green.
Command | Definition | Pseudo code |
---|---|---|
ADD rd, rs, rt | Add | rd = rs + rt |
ADDU rd, rs, rt | Add Unsigned | rd = rs + rt |
ADDI rt, rs, immediate1) | Add Immediate | rd = rs + immediate |
ADDIU rt, rs, immediate | Add Immediate Unsigned | rd = rs + immediate |
SUB rd, rs, rt | Subtract | rd = rs - rt |
SUBU rd, rs, rt | Subtract Unsigned | rd = rs - rt |
MULT rs, rt | Multiply | lo = rs * rt |
MULTU rs, rt | Multiply Unsigned | lo = rs * rt |
DIV rs, rt | Divide | lo = rs / rt; hi = rs % rt |
DIVU rs, rt | Divide Unsigned | lo = rs / rt; hi = rs % rt |
AND rd, rs, rt | And | rd = rs & rt |
ANDI rt, rs, immediate | And Immediate | rt = rs & immediate |
OR rd, rs, rt | Or | rd = rs | rt |
ORI rt, rs, immediate | Or Immediate | rt = rs | immediate |
XOR rd, rs, rt | Exclusive Or | rd = rs ^ rt |
XORI rt, rs, immediate | Exclusive Or Immediate | rd = rs ^ immediate |
NOR rd, rs, rt | Nor | rd = ~(rs | rt) |
SLL rd, rt, sa2) | Shift Left Logical | rd = rt << sa |
SLLV rd, rt, rs | Shift Left Logical Variable | rd = rt << rs |
SRA rd, rt, sa | Shift Right Arithmetic | rd = (int32)rt >> sa |
SRAV rd, rt, rs | Shift Right Arithmetic Variable | rd = (int32)rt >> rs |
SRL rd, rt, sa | Shift Right Logical | rd = (uint32)rt >> sa |
SRLV rd, rt, rs | Shift Right Logical Variable | rd = (uint32)rt >> rs |
SLT rd, rs, rt | Set On Less Than | rd = (rs < rt) ? 1 : 0 |
SLTU rd, rs, rt | Set On Less Than Unsigned | rd = (rs < rt) ? 1 : 0 |
SLTI rt, rs, immediate | Set On Less Than Immediate | rt = (rs < immediate) ? 1 : 0 |
SLTIU rt, rs, immediate | Set On Less Than Immediate Unsigned | rt = (rs < immediate) ? 1 : 0 |
DADD rd, rs, rt | Doubleword Add | |
DADDU rd, rs, rt | Doubleword Add Unsigned | |
DADDI rt, rs, immediate | Doubleword Add Immediate | |
DADDIU rt, rs, immediate | Doubleword Add Immediate Unsigned | |
DSUB rd, rs, rt | Doubleword Subtract | |
DSUBU rd, rs, rt | Doubleword Subtract Unsigned | |
DMULT rs, rt | Doubleword Multiply | |
DMULTU rs, rt | Doubleword Multiply Unsigned | |
DDIV rs, rt | Doubleword Divide | |
DDIVU rs, rt | Doubleword Divide Unsigned | |
DSLL rd, rt, sa | Doubleword Shift Left Logical | |
DSLL32 rd, rt, sa | Doubleword Shift Left Logical + 32 | |
DSLLV rd, rt, rs | Doubleword Shift Left Logical Variable | |
DSRA rd, rt, sa | Doubleword Shift Right Arithmetic | |
DSRA32 rd, rt, sa | Doubleword Shift Right Arithmetic + 32 | |
DSRAV rd, rt, rs | Doubleword Shift Right Arithmetic Variable | |
DSRL rd, rt, sa | Doubleword Shift Right Logical | |
DSRL32 rd, rt, sa | Doubleword Shift Right Logical + 32 | |
DSRLV rd, rt, rs | Doubleword Shift Right Logical Variable | |
MFHI rd | Move From HI | rd = hi |
MFLO rd | Move From LO | rd = lo |
MTHI rs | Move To HI | hi = rs |
MTLO rs | Move To LO | lo = rs |
LUI rt, immediate | Load Upper Immediate | rt = immediate << 16 |
LB rt, offset(rs) | Load Byte | rt = *(int8*)(rs + offset) |
LBU rt, offset(rs) | Load Byte Unsigned | rt = *(uint8*)(rs + offset) |
LH rt, offset(rs) | Load Halfword | rt = *(int16*)(rs + offset) |
LHU rt, offset(rs) | Load Halfword Unsigned | rt = *(uint16*)(rs + offset) |
LW rt, offset(rs) | Load Word | rt = *(int32*)(rs + offset) |
LWU rt, offset(rs) | Load Word Unsigned | rt = *(uint32*)(rs + offset) |
LWC1 ft, offset(rs) | Load Word To FPU (Coprocessor 1) | ft = *(float*)(rs + offset) |
LWL rt, offset(rs) | Load Word Left | |
LWR rt, offset(rs) | Load Word Right | |
LD rt, offset(rs) | Load Doubleword | rt = *(uint64*)(rs + offset) |
LDC1 ft, offset(rs) | Load Doubleword To FPU (Coprocessor 1) | ft = *(double*)(rs + offset) |
LDL rt, offset(rs) | Load Doubleword Left | |
LDR rt, offset(rs) | Load Doubleword Right | |
LL rt, offset(rs) | Load Linked | |
LLD rt, offset(rs) | Load Linked Doubleword | |
SB rt, offset(rs) | Store Byte | *(int8*)(rs + offset) = rt |
SH rt, offset(rs) | Store Halfword | *(int16*)(rs + offset) = rt |
SW rt, offset(rs) | Store Word | *(int32*)(rs + offset) = rt |
SWC1 ft, offset(rs) | Store Word From FPU (Coprocessor 1) | *(float*)(rs + offset) = ft |
SWL rt, offset(rs) | Store Word Left | |
SWR rt, offset(rs) | Store Word Right | |
SD rt, offset(rs) | Store Doubleword | *(int64*)(rs + offset) = rt |
SDC1 ft, offset(rs) | Store Doubleword From FPU (Coprocessor 1) | |
SDL rt, offset(rs) | Store Doubleword Left | |
SDR rt, offset(rs) | Store Doubleword Right | |
SC rt, offset(rs) | Store Conditional | |
SCD rt, offset(rs) | Store Conditional Doubleword | |
J target | Jump | PC = target |
JR rs | Jump Register | PC = rs |
JAL target | Jump And Link | RA = PC + 8; PC = target |
JALR rs | Jump And Link Register | rd = PC + 8; PC = rs |
JALR rd, rs | Jump And Link Register | rd = PC + 8; PC = rs |
BEQ rs, rt, offset | Branch On Equal | if(rs == rt) PC = offset |
BEQL rs, rt, offset | Branch On Equal Likely | if(rs == rt) PC = offset |
BNE rs, rt, offset | Branch On Not Equal | if(rs != rt) PC = offset |
BNEL rs, rt, offset | Branch On Not Equal Likely | if(rs != rt) PC = offset |
BGTZ rs, offset | Branch On Greater Than Zero | if(rs > 0) PC = offset |
BGTZL rs, offset | Branch On Greater Than Zero Likely | if(rs > 0) PC = offset |
BLEZ rs, offset | Branch On Less Than Or Equal To Zero | if(rs <= 0) PC = offset |
BLEZL rs, offset | Branch On Less Than Or Equal To Zero Likely | if(rs <= 0) PC = offset |
BGEZ rs, offset | Branch On Greater Than Or Equal To Zero | if(rs >= 0) PC = offset |
BGEZL rs, offset | Branch On Greater Than Or Equal To Zero Likely | if(rs >= 0) PC = offset |
BGEZAL rs, offset | Branch On Greater Than Or Equal To Zero And Link | if(rs >= 0) { RA = PC + 8; PC = offset } |
BGEZALL rs, offset | Branch On Greater Than Or Equal To Zero And Link Likely | if(rs >= 0) { RA = PC + 8; PC = offset } |
BLTZ rs, offset | Branch On Less Than Zero | if(rs < 0) PC = offset |
BLTZL rs, offset | Branch On Less Than Zero Likely | if(rs < 0) PC = offset |
BLTZAL rs, offset | Branch On Less Than Zero And Link | if(rs < 0) { RA = PC + 8; PC = offset } |
BLTZALL rs, offset | Branch On Less Than Zero And Link Likely | if(rs < 0) { RA = PC + 8; PC = offset } |
MFC1 rt, fs | Move Word From FPU (Coprocessor 1) | |
DMFC1 rt, fs | Doubleword Move From FPU (Coprocessor 1) | |
MTC1 rt, fs | Move To FPU (Coprocessor 1) | |
DMTC1 rt, fs | Doubleword Move To FPU (Coprocessor 1) | |
CFC1 rt, fs | Move Control Word From FPU (Coprocessor 1) | |
CTC1 rt, fs | Move Control Word To FPU (Coprocessor 1) | |
MOV.fmt fd, fs | Floating-point Move | |
ABS.fmt fd, fs | Floating-point Absolute Value | |
NEG.fmt fd, fs | Floating-point Negate | |
SQRT.fmt fd, fs | Floating-point Square Root | |
ADD.fmt fd, fs, ft | Floating-point Add | |
SUB.fmt fd, fs, ft | Floating-point Subtract | |
MUL.fmt fd, fs, ft | Floating-point Multiply | |
DIV.fmt fd, fs, ft | Floating-point Divide | |
CVT.S.fmt fd, fs | Floating-point Convert To Single Floating-point Format | |
CVT.D.fmt fd, fs | Floating-point Convert To Double Floating-point Format | |
CVT.W.fmt fd, fs | Floating-point Convert To Single Fixed-point Format | |
CVT.L.fmt fd, fs | Floating-point Convert To Long Fixed-point Format | |
FLOOR.L.fmt fd, fs | Floating-point Floor To Long Fixed-point Format | |
FLOOR.W.fmt fd, fs | Floating-point Floor To Single Fixed-point Format | |
ROUND.L.fmt fd, fs | Floating-point Round To Long Fixed-point Format | |
ROUND.W.fmt fd, fs | Floating-point Round To Single Fixed-point Format | |
TRUNC.L.fmt fd, fs | Floating-point Truncate To Long Fixed-point Format | |
TRUNC.W.fmt fd, fs | Floating-point Truncate To Single Fixed-point Format | |
CEIL.L.fmt fd, fs | Floating-point Ceiling To Long Fixed-point Format | |
CEIL.W.fmt fd, fs | Floating-point Ceiling To Single Fixed-point Format | |
C.F.fmt fs, ft | Floating-point Compare False | |
C.UN.fmt fs, ft | Floating-point Compare Unordered | |
C.EQ.fmt fs, ft | Floating-point Compare Equal | |
C.UEQ.fmt fs, ft | Floating-point Compare Unordered or Equal | |
C.OLT.fmt fs, ft | Floating-point Compare Ordered Less Than | |
C.ULT.fmt fs, ft | Floating-point Compare Unordered Less Than | |
C.OLE.fmt fs, ft | Floating-point Compare Unordered or Less Than | |
C.ULE.fmt fs, ft | Floating-point Compare Unordered or Less Than or Equal | |
C.SF.fmt fs, ft | Floating-point Compare Signaling False | |
C.NGLE.fmt fs, ft | Floating-point Compare Not Greater Than or Less Than or Equal | |
C.SEQ.fmt fs, ft | Floating-point Compare Signaling Equal | |
C.NGL.fmt fs, ft | Floating-point Compare Not Greater Than or Less Than | |
C.LT.fmt fs, ft | Floating-point Compare Less Than | |
C.NGE.fmt fs, ft | Floating-point Compare Not Greater Than or Equal | |
C.LE.fmt fs, ft | Floating-point Compare Less Than or Equal | |
C.NGT.fmt fs, ft | Floating-point Compare Not Greater Than | |
BC1F offset | Branch On FPU False (Coprocessor 1) | |
BC1FL offset | Branch On FPU False Likely (Coprocessor 1) | |
BC1T offset | Branch On FPU True (Coprocessor 1) | |
BC1TL offset | Branch On FPU True Likely (Coprocessor 1) | |
MFC0 rt, rd | Move From Coprocessor 0 | |
MTC0 rt, rd | Move To Coprocessor 0 | |
CACHE op, offset(base) | Cache Operation | |
TEQ rs, rt | Trap If Equal | |
TEQI rs, immediate | Trap If Equal Immediate | |
TGE rs, rt | Trap If Greater Than Or Equal | |
TGEI rs, immediate | Trap If Greater Than Or Equal | |
TGEIU rs, immediate | Trap If Greater Than Or Equal | |
TGEU rs, rt | Trap If Greater Than Or Equal Unsigned | |
TLT rs, rt | Trap If Less Than | |
TLTI rs, immediate | Trap If Less Than Immediate | |
TLTIU rs, immediate | Trap If Less Than Immediate Unsigned | |
TLTU rs, rt | Trap If Less Than Unsigned | |
TNE rs, rt | Trap If Not Equal | |
TNEI rs, immediate | Trap If Not Equal Immediate | |
SYNC | Synchronize | (No operation on R4300) |
SYSCALL | System Call | COP0_CAUSE |= (8 << 2); COP0_EPC = PC; PC = exc_vector_base + 0x180 |
BREAK | Breakpoint | COP0_CAUSE |= (9 << 2); COP0_EPC = PC; PC = exc_vector_base + 0x180 |
ERET | Return From Exception | PC = COP0_EPC (or COP0_ERROREPC) |
TLBP | Probe TLB For Matching Entry | |
TLBR | Read Indexed TLB Entry | |
TLBWI | Write Indexed TLB Entry | |
TLBWR | Write Random TLB Entry | |
……………………………………… | . | . |
Number | Name | Preserved | Usage |
---|---|---|---|
0 | R0 | n/a | Hardwired zero |
1 | AT | no | Assembler temporary value |
2:3 | V0:V1 | no | Subroutine return value(s) |
4:7 | A0:A3 | no | Subroutine arguments |
8:15 | T0:T7 | no | Temporary values |
16:23 | S0:S7 | yes | Saved values |
24:25 | T8:T9 | no | Temporary values |
26:27 | K0:K1 | n/a | Reserved by the kernel |
28 | GP | yes | Global pointer |
29 | SP | yes | Stack pointer |
30 | S8 or FP | yes | Saved value or frame pointer |
31 | RA | yes | Return address |
Virtual address range | Segment | Description |
---|---|---|
00000000:7FFFFFFF | useg | TLB mapped to physical memory Accessible in all operating modes |
80000000:9FFFFFFF | kseg0 | Cached, translated to physical address by subtracting 80000000 Accessible in kernel mode |
A0000000:BFFFFFFF | kseg1 | Uncached, translated to physical address by subtracting A0000000 Accessible in kernel mode |
C0000000:DFFFFFFF | sseg | TLB mapped to physical memory Accessible in kernel and supervisor mode |
E0000000:FFFFFFFF | kseg3 | TLB mapped to physical memory Accessible in kernel mode |
Note: Commercial Nintendo 64 games operate in kernel mode at all times.
| 31| 30| 29| 28|27|26|25| 24|23| 22|21|20|19|18|17|16| 8| 7| 6| 5| 4| 2| 1| 0| | .| .| .| .| .| .| .| .| 0| .| .| .| .| .| 0| 1|........| .| .| .| ..| .| .| .| |CU3|CU2|CU1|CU0|RP|FR|RE|ITS| -|BEV|TS|SR| -|CH|CE|DE| IM |KX|SX|UX|KSU|ERL|EXL|IE| | 1 | 1 | 1 | 1 |1 |1 |1 |1 | 1|1 |1 |1 | 1|1 |1 |1 | 8 |1 |1 |1 |2 |1 |1 |1 |
Field | Description |
---|---|
CU3 | (Reserved) |
CU2 | (Reserved) |
CU1 | Coprocessor 1 (FPU) Usability (1: Usable, 0: Unusable) |
CU0 | Coprocessor 0 Usability (1: Usable, 0: Unusable) COP0 is always usable while in kernel mode, regardless of setting |
RP | Reduce Power (0: Normal, 1: Low Power Mode) Clock frequency is reduced to one-quarter speed when enabled |
FR | Additional floating point registers (0: 16 registers, 1: 32 registers) |
RE | Reverse Endian in User mode (0: Disabled, 1: Reversed) |
ITS | Enable instruction trace support (0: False, 1: True) |
BEV | Controls exception vector locations (0: Normal, 1: Bootstrap) |
TS | TLB shutdown has occurred (0: False, 1: True) On R4300i, the TLB does not shutdown and the processor will continue execution, but the TS bit is still set. |
SR | Soft reset or NMI has occurred (0: False, 1: True) |
CH | CP0 Condition bit (0: False, 1: True) |
CE | (Unused on R4300i) |
DE | (Unused on R4300i) |
IM | Interrupt Mask (0: Disabled, 1: Enabled) |
KX | Enable 64-bit addressing in Kernel mode (0: Disabled, 1: Enabled) |
SX | Enable 64-bit addressing and operations in Supervisor mode (0: Disabled, 1: Enabled) |
UX | Enable 64-bit addressing and operations in User mode (0: Disabled, 1: Enabled) |
KSU | Mode (10: User, 01: Supervisor, 00: Kernel) |
ERL | Error level (0: Normal, 1: Error) |
EXL | Exception level (0: Normal, 1: Exception) |
IE | Global interrupt enable (0: Disabled, 1: Enabled) |
|31|30|28| 16| 8|7| 2| 0| | .| 0|..|............|........|0|.....|00| |BD| -|CE|------------| IP |-| EXC |--| |1 |1 |2 | 12 | 8 |1| 5 |2 |
Field | Description |
---|---|
BD | Branch delay (1: Last exception occurred in delay slot, 0: Normal) |
CE | Coprocessor number for coprocessor unusable exception |
IP | Interrupt pending (1: Interrupt, 0: No Interrupt) IP7 Timer interrupt IP6:2 External normal interrupts IP1:0 Software interrupt |
EXC | Exception code |
Code | Mnemonic | Description | Generated… |
---|---|---|---|
0 | Int | Interrupt | - When one of the eight interrupt conditions are asserted |
1 | Mod | TLB Modification exception | - When the TLB entry that matches the the virtual address referenced by the store instruction is marked as read-only (the D bit = 0) |
2 | TLBL | TLB Invalid exception (load or instruction fetch) | - When an attempt is made to read from an mapped area in a TLB segment that is marked invalid |
3 | TLBS | TLB Invalid exception (store) | - When an attempt is made to write to a mapped area in a TLB segment that is marked invalid |
2 | TLBL | TLB Miss exception (load or instruction fetch) | - When an attempt is made to read from an unmapped area in a TLB segment (Uses special TLB miss exception vector) |
3 | TLBS | TLB Miss exception (store) | - When an attempt is made to write to an unmapped area in a TLB segment (Uses special TLB miss exception vector) |
4 | AdEL | Address Error exception (load or instruction fetch) | - When an attempt is made to read from an address whose boundary alignment is incompatible with the instruction - When an attempt is made to read from an address that is not accessible in the current operating mode |
5 | AdES | Address Error exception (store) | - When an attempt is made to write to an address whose boundary alignment is incompatible with the opcode - When an attempt is made to write to an address that is not accessible in the current operating mode |
6 | IBE | Bus Error exception (instruction fetch) | |
7 | DBE | Bus Error exception (data reference: load or store) | |
8 | Sys | Syscall exception | - When a SYSCALL instruction is executed |
9 | Bp | Breakpoint exception | - When a BREAK instruction is executed |
10 | RI | Reserved instruction exception | - When an attempt is made to execute a reserved/nonexistant command |
11 | CpU | Coprocessor unusable exception | - When an attempt is made to use a coprocessor instruction and the corresponding coprocessor is marked unusable (Status CU bit = 0) - When an attempt is made to use a COP0 instruction while operating in user or supervisor mode |
12 | Ov | Arithmetic overflow exception | - When an ADD, ADDI, SUB, DADD, DADDI or DSUB instruction results in a 2's complement overflow |
13 | Tr | Trap exception | - When a trap instruction results in a TRUE condition |
14 | - | (Reserved) | |
15 | FPE | Floating-point exception | (Generated by the floating-point coprocessor (COP1); contents of the Floating-Point Control/Status register (FCSR31) indicate the cause of the exception) |
16:22 | - | (Reserved) | |
23 | WATCH | Watch exception | - When a load/store instruction references the address specified in the WatchLo/WatchHi registers |
24:31 | - | (Reserved) |
Cause bit | Source | N64 Implementation |
---|---|---|
IP7 | Timer interrupt | n/a |
IP6 | Int4 pin | RDB Write |
IP5 | Int3 pin | RDB Read |
IP4 | Int2 pin | Pre-NMI (Reset button) |
IP3 | Int1 pin | Cartridge |
IP2 | Int0 pin | RCP |
IP1 | Set by software | n/a |
IP0 | Set by software | n/a |
Any of these may be masked by setting the corresponding IM bit of the Status register to 0. The Timer interrupt is generated when the Count and Compare register are equal.
On the Nintendo 64, IP2 represents an RCP interrupt. When an RCP interrupt occurs, a flag representing the specific RCP interface is written to MI_INTR_REG (0x04300008).
Bit | Name | Description |
---|---|---|
0x01 | MI_INTR_SP | Signal Processor - Task Done/Task Yield |
0x02 | MI_INTR_SI | Serial Interface - Controller input available |
0x04 | MI_INTR_AI | Audio Interface - Audio buffer swap |
0x08 | MI_INTR_VI | Video Interface - Vertical retrace |
0x10 | MI_INTR_PI | Peripheral Interface - ROM to RAM DMA done |
0x20 | MI_INTR_DP | Display Processor - RDP processing done (gDPFullSync) |
RCP-specific interrupts may be masked by setting the corresponding bits in MI_INTR_MASK_REG (0x0430000C) to 0.
Exception | Base (BEV=0) | Base (BEV=1) | Offset |
---|---|---|---|
Reset & NMI | n/a | 0xBFC000000 | 0x000 |
TLB Miss | 0x80000000 | 0xBFC000200 | 0x000 |
XTLB Miss | 0x80000000 | 0xBFC000200 | 0x080 |
Other | 0x80000000 | 0xBFC000200 | 0x180 |