This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
r4300 [2019/02/07 09:40] shygoo created (wip) |
r4300 [2019/05/06 17:54] shygoo [Interrupts] clarify MI_INTR_MASK_REG usage |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== MIPS R4300i CPU ====== | ====== MIPS R4300i CPU ====== | ||
+ | The main processor used by the Nintendo 64. | ||
+ | |||
+ | * R43XX User manual: https://hack64.net/docs/VR43XX.pdf | ||
+ | * R4300i Product info: http://datasheets.chipdb.org/MIPS/R4300i_datasheet.pdf | ||
+ | |||
+ | Information on this page that is specifically related to the Nintendo 64 is <color lightgreen>highlighted in green</color>. | ||
+ | |||
+ | ... | ||
+ | |||
+ | ... | ||
+ | |||
+ | ... | ||
+ | |||
+ | ===== Commands ===== | ||
^ Command ^ Definition ^ Pseudo code ^ | ^ Command ^ Definition ^ Pseudo code ^ | ||
+ | | 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) %% | | ||
+ | | 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 %% | | ||
| ADD rd, rs, rt | Add | %%rd = rs + rt %% | | | ADD rd, rs, rt | Add | %%rd = rs + rt %% | | ||
| ADDU rd, rs, rt | Add Unsigned | %%rd = rs + rt %% | | | ADDU rd, rs, rt | Add Unsigned | %%rd = rs + rt %% | | ||
- | | ADDI rt, rs, immediate | Add Immediate | %%rd = rs + immediate %% | | + | | ADDI rt, rs, immediate(("immediate": 16-bit signed immediate value)) | Add Immediate | %%rd = rs + immediate %% | |
| ADDIU rt, rs, immediate | Add Immediate Unsigned | %%rd = rs + immediate %% | | | ADDIU rt, rs, immediate | Add Immediate Unsigned | %%rd = rs + immediate %% | | ||
| SUB rd, rs, rt | Subtract | %%rd = rs - rt %% | | | SUB rd, rs, rt | Subtract | %%rd = rs - rt %% | | ||
Line 12: | Line 37: | ||
| DIV rs, rt | Divide | %%lo = rs / rt; hi = rs % rt %% | | | DIV rs, rt | Divide | %%lo = rs / rt; hi = rs % rt %% | | ||
| DIVU rs, rt | Divide Unsigned | %%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 %% | | + | | SLL rd, rt, sa(("sa": 5-bit immediate shift amount))| Shift Left Logical | %%rd = rt << sa %% | |
- | | 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, sa | Shift Left Logical | %%rd = rt << sa %% | | + | |
| SLLV rd, rt, rs | Shift Left Logical Variable | %%rd = rt << rs %% | | | SLLV rd, rt, rs | Shift Left Logical Variable | %%rd = rt << rs %% | | ||
| SRA rd, rt, sa | Shift Right Arithmetic | %%rd = (int32)rt >> sa %% | | | SRA rd, rt, sa | Shift Right Arithmetic | %%rd = (int32)rt >> sa %% | | ||
Line 25: | Line 43: | ||
| SRL rd, rt, sa | Shift Right Logical | %%rd = (uint32)rt >> sa %% | | | SRL rd, rt, sa | Shift Right Logical | %%rd = (uint32)rt >> sa %% | | ||
| SRLV rd, rt, rs | Shift Right Logical Variable | %%rd = (uint32)rt >> rs %% | | | 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 %% | | + | | DADD rd, rs, rt | Doubleword Add | %%rd = rs + rt %% | |
- | | SLTU rd, rs, rt | Set On Less Than Unsigned | %%rd = (rs < rt) ? 1 : 0 %% | | + | | DADDU rd, rs, rt | Doubleword Add Unsigned | %%rd = rs + rt %% | |
- | | SLTI rt, rs, immediate | Set On Less Than Immediate | %%rd = (rs < immediate) ? 1 : 0 %% | | + | | DADDI rt, rs, immediate | Doubleword Add Immediate | %%rd = rs + immediate %% | |
- | | SLTIU rt, rs, immediate | Set On Less Than Immediate Unsigned | %%rd = (rs < immediate) ? 1 : 0 %% | | + | | DADDIU rt, rs, immediate | Doubleword Add Immediate Unsigned | %%rd = rs + immediate %% | |
- | | DADD rd, rs, rt | Doubleword Add | %% %% | | + | | DSUB rd, rs, rt | Doubleword Subtract | %%rd = rs - rt %% | |
- | | DADDU rd, rs, rt | Doubleword Add Unsigned | %% %% | | + | | DSUBU rd, rs, rt | Doubleword Subtract Unsigned | %%rd = rs - rt %% | |
- | | DADDI rt, rs, immediate | Doubleword Add Immediate | %% %% | | + | | DMULT rs, rt | Doubleword Multiply | %%lo = rs * rt %% | |
- | | DADDIU rt, rs, immediate | Doubleword Add Immediate Unsigned | %% %% | | + | | DMULTU rs, rt | Doubleword Multiply Unsigned | %%lo = rs * rt %% | |
- | | DSUB rd, rs, rt | Doubleword Subtract | %% %% | | + | | DDIV rs, rt | Doubleword Divide | %%lo = rs / rt; hi = rs % rt %% | |
- | | DSUBU rd, rs, rt | Doubleword Subtract Unsigned | %% %% | | + | | DDIVU rs, rt | Doubleword Divide Unsigned | %%lo = rs / rt; hi = rs % rt %% | |
- | | DMULT rs, rt | Doubleword Multiply | %% %% | | + | | DSLL rd, rt, sa | Doubleword Shift Left Logical | %%rd = rt << sa %% | |
- | | DMULTU rs, rt | Doubleword Multiply Unsigned | %% %% | | + | | DSLL32 rd, rt, sa | Doubleword Shift Left Logical + 32 | %%rd = rt << (sa + 32) %% | |
- | | DDIV rs, rt | Doubleword Divide | %% %% | | + | | DSLLV rd, rt, rs | Doubleword Shift Left Logical Variable | %%rd = rt << rs %% | |
- | | DDIVU rs, rt | Doubleword Divide Unsigned | %% %% | | + | | DSRA rd, rt, sa | Doubleword Shift Right Arithmetic | %%rd = (int64)rt >> sa %% | |
- | | DSLL rd, rt, sa | Doubleword Shift Left Logical | %% %% | | + | | DSRA32 rd, rt, sa | Doubleword Shift Right Arithmetic + 32 | %%rd = (int64)rt >> (sa + 32) %% | |
- | | DSLL32 rd, rt, sa | Doubleword Shift Left Logical + 32 | %% %% | | + | | DSRAV rd, rt, rs | Doubleword Shift Right Arithmetic Variable | %%rd = (int64)rt >> rs %% | |
- | | DSLLV rd, rt, rs | Doubleword Shift Left Logical Variable | %% %% | | + | | DSRL rd, rt, sa | Doubleword Shift Right Logical | %%rd = (uint64)rt >> sa %% | |
- | | DSRA rd, rt, sa | Doubleword Shift Right Arithmetic | %% %% | | + | | DSRL32 rd, rt, sa | Doubleword Shift Right Logical + 32 | %%rd = (uint64)rd >> (sa + 32) %% | |
- | | DSRA32 rd, rt, sa | Doubleword Shift Right Arithmetic + 32 | %% %% | | + | | DSRLV rd, rt, rs | Doubleword Shift Right Logical Variable | %%rd = (uint64)rd >> rs %% | |
- | | 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 %% | | | MFHI rd | Move From HI | %%rd = hi %% | | ||
| MFLO rd | Move From LO | %%rd = lo %% | | | MFLO rd | Move From LO | %%rd = lo %% | | ||
Line 53: | Line 67: | ||
| MTLO rs | Move To LO | %%lo = rs %% | | | MTLO rs | Move To LO | %%lo = rs %% | | ||
| LUI rt, immediate | Load Upper Immediate | %%rt = immediate << 16 %% | | | LUI rt, immediate | Load Upper Immediate | %%rt = immediate << 16 %% | | ||
- | | LB rt, offset(base) | Load Byte | %%rt = *(int8*)(base + offset) %% | | + | | LB rt, offset(rs) | Load Byte | %%rt = *(int8*)(rs + offset) %% | |
- | | LBU rt, offset(base) | Load Byte Unsigned | %%rt = *(uint8*)(base + offset) %% | | + | | LBU rt, offset(rs) | Load Byte Unsigned | %%rt = *(uint8*)(rs + offset) %% | |
- | | LH rt, offset(base) | Load Halfword | %%rt = *(int16*)(base + offset) %% | | + | | LH rt, offset(rs) | Load Halfword | %%rt = *(int16*)(rs + offset) %% | |
- | | LHU rt, offset(base) | Load Halfword Unsigned | %%rt = *(uint16*)(base + offset)%% | | + | | LHU rt, offset(rs) | Load Halfword Unsigned | %%rt = *(uint16*)(rs + offset)%% | |
- | | LW rt, offset(base) | Load Word | %%rt = *(int32*)(base + offset) %% | | + | | LW rt, offset(rs) | Load Word | %%rt = *(int32*)(rs + offset) %% | |
- | | LWU rt, offset(base) | Load Word Unsigned | %%rt = *(uint32*)(base + offset)%% | | + | | LWU rt, offset(rs) | Load Word Unsigned | %%rt = *(uint32*)(rs + offset)%% | |
- | | LWC1 ft, offset(base) | Load Word To FPU (Coprocessor 1) | %%ft = *(float*)(base + offset) %% | | + | | LWC1 ft, offset(rs) | Load Word To FPU(("FPU": Floating-point unit, another name for Coprocessor 1)) | %%ft = *(float*)(rs + offset) %% | |
- | | LWL rt, offset(base) | Load Word Left | %% %% | | + | | LWL rt, offset(rs) | Load Word Left | %% %% | |
- | | LWR rt, offset(base) | Load Word Right | %% %% | | + | | LWR rt, offset(rs) | Load Word Right | %% %% | |
- | | LD rt, offset(base) | Load Doubleword | %%rt = *(uint64*)(base + offset)%% | | + | | LD rt, offset(rs) | Load Doubleword | %%rt = *(uint64*)(rs + offset)%% | |
- | | LDC1 ft, offset(base) | Load Doubleword To FPU (Coprocessor 1) | %%ft = *(double*)(base + offset)%% | | + | | LDC1 ft, offset(rs) | Load Doubleword To FPU | %%ft = *(double*)(rs + offset)%% | |
- | | LDL rt, offset(base) | Load Doubleword Left | %% %% | | + | | LDL rt, offset(rs) | Load Doubleword Left | %% %% | |
- | | LDR rt, offset(base) | Load Doubleword Right | %% %% | | + | | LDR rt, offset(rs) | Load Doubleword Right | %% %% | |
- | | LL rt, offset(base) | Load Linked | %% %% | | + | | LL rt, offset(rs) | Load Linked | %% %% | |
- | | LLD rt, offset(base) | Load Linked Doubleword | %% %% | | + | | LLD rt, offset(rs) | Load Linked Doubleword | %% %% | |
- | | SB rt, offset(base) | Store Byte | %%*(int8*)(base + offset) = rt %% | | + | | SB rt, offset(rs) | Store Byte | %%*(int8*)(rs + offset) = rt %% | |
- | | SH rt, offset(base) | Store Halfword | %%*(int16*)(base + offset) = rt %% | | + | | SH rt, offset(rs) | Store Halfword | %%*(int16*)(rs + offset) = rt %% | |
- | | SW rt, offset(base) | Store Word | %%*(int32*)(base + offset) = rt %% | | + | | SW rt, offset(rs) | Store Word | %%*(int32*)(rs + offset) = rt %% | |
- | | SWC1 ft, offset(base) | Store Word From FPU (Coprocessor 1) | %%*(float*)(base + offset) = ft %% | | + | | SWC1 ft, offset(rs) | Store Word From FPU | %%*(float*)(rs + offset) = ft %% | |
- | | SWL rt, offset(base) | Store Word Left | %% %% | | + | | SWL rt, offset(rs) | Store Word Left | %% %% | |
- | | SWR rt, offset(base) | Store Word Right | %% %% | | + | | SWR rt, offset(rs) | Store Word Right | %% %% | |
- | | SD rt, offset(base) | Store Doubleword | %%*(int64*)(base + offset) = rt %% | | + | | SD rt, offset(rs) | Store Doubleword | %%*(int64*)(rs + offset) = rt %% | |
- | | SDC1 ft, offset(base) | Store Doubleword From FPU (Coprocessor 1) | %% %% | | + | | SDC1 ft, offset(rs) | Store Doubleword From FPU | %%*(double*)(rs + offset) = rt %% | |
- | | SDL rt, offset(base) | Store Doubleword Left | %% %% | | + | | SDL rt, offset(rs) | Store Doubleword Left | %% %% | |
- | | SDR rt, offset(base) | Store Doubleword Right | %% %% | | + | | SDR rt, offset(rs) | Store Doubleword Right | %% %% | |
- | | SC rt, offset(base) | Store Conditional | %% %% | | + | | SC rt, offset(rs) | Store Conditional | %% %% | |
- | | SCD rt, offset(base) | Store Conditional Doubleword | %% %% | | + | | SCD rt, offset(rs) | Store Conditional Doubleword | %% %% | |
- | | J target | Jump | %% RA = target %% | | + | | J target | Jump | %% PC = target %% | |
| JR rs | Jump Register | %% PC = rs %% | | | JR rs | Jump Register | %% PC = rs %% | | ||
| JAL target | Jump And Link | %% RA = PC + 8; PC = target %% | | | JAL target | Jump And Link | %% RA = PC + 8; PC = target %% | | ||
| JALR rs | Jump And Link Register | %% rd = PC + 8; PC = rs %% | | | JALR rs | Jump And Link Register | %% rd = PC + 8; PC = rs %% | | ||
| JALR rd, 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 %% | | + | | BEQ rs, rt, target | Branch On Equal | %% if(rs == rt) PC = target %% | |
- | | BEQL rs, rt, offset | Branch On Equal Likely | %% if(rs == rt) PC = offset %% | | + | | BEQL rs, rt, target | Branch On Equal Likely | %% if(rs == rt) PC = target %% | |
- | | BGTZ rs, offset | Branch On Greater Than Zero | %% if(rs > 0) PC = offset %% | | + | | BNE rs, rt, target | Branch On Not Equal | %% if(rs != rt) PC = target %% | |
- | | BGTZL rs, offset | Branch On Greater Than Zero Likely | %% if(rs > 0) PC = offset %% | | + | | BNEL rs, rt, target | Branch On Not Equal Likely | %% if(rs != rt) PC = target %% | |
- | | BLEZ rs, offset | Branch On Less Than Or Equal To Zero | %% if(rs <= 0) PC = offset %% | | + | | BGTZ rs, target | Branch On Greater Than Zero | %% if(rs > 0) PC = target %% | |
- | | BLEZL rs, offset | Branch On Less Than Or Equal To Zero Likely | %% if(rs <= 0) PC = offset %% | | + | | BGTZL rs, target | Branch On Greater Than Zero Likely | %% if(rs > 0) PC = target %% | |
- | | BGEZ rs, offset | Branch On Greater Than Or Equal To Zero | %% if(rs >= 0) PC = offset %% | | + | | BLEZ rs, target | Branch On Less Than Or Equal To Zero | %% if(rs <= 0) PC = target %% | |
- | | BGEZL rs, offset | Branch On Greater Than Or Equal To Zero Likely | %% if(rs >= 0) PC = offset %% | | + | | BLEZL rs, target | Branch On Less Than Or Equal To Zero Likely | %% if(rs <= 0) PC = target %% | |
- | | BGEZAL rs, offset | Branch On Greater Than Or Equal To Zero And Link | if(rs %%>=%% 0) {\\ RA = PC + 8; PC = offset\\ } | | + | | BGEZ rs, target | Branch On Greater Than Or Equal To Zero | %% if(rs >= 0) PC = target %% | |
- | | BGEZALL rs, offset | Branch On Greater Than Or Equal To Zero And Link Likely | if(rs %%>=%% 0) {\\ RA = PC + 8; PC = offset\\ } | | + | | BGEZL rs, target | Branch On Greater Than Or Equal To Zero\\ Likely | %% if(rs >= 0) PC = target %% | |
- | | BLTZ rs, offset | Branch On Less Than Zero | %% if(rs < 0) PC = offset %% | | + | | BGEZAL rs, target | Branch On Greater Than Or Equal To Zero\\ And Link | if(rs %%>=%% 0) {\\ RA = PC + 8; PC = target\\ } | |
- | | BLTZL rs, offset | Branch On Less Than Zero Likely | %% if(rs < 0) PC = offset %% | | + | | BGEZALL rs, target | Branch On Greater Than Or Equal To Zero\\ And Link Likely | if(rs %%>=%% 0) {\\ RA = PC + 8; PC = target\\ } | |
- | | BLTZAL rs, offset | Branch On Less Than Zero And Link | if(rs < 0) {\\ RA = PC + 8; PC = offset\\ } | | + | | BLTZ rs, target | Branch On Less Than Zero | %% if(rs < 0) PC = target %% | |
- | | BLTZALL rs, offset | Branch On Less Than Zero And Link Likely | if(rs < 0) {\\ RA = PC + 8; PC = offset\\ } | | + | | BLTZL rs, target | Branch On Less Than Zero Likely | %% if(rs < 0) PC = target %% | |
- | | BNE rs, rt, offset | Branch On Not Equal | %% %% | | + | | BLTZAL rs, target | Branch On Less Than Zero And Link | if(rs < 0) {\\ RA = PC + 8; PC = target\\ } | |
- | | BNEL rs, rt, offset | Branch On Not Equal Likely | %% %% | | + | | BLTZALL rs, target | Branch On Less Than Zero And Link Likely | if(rs < 0) {\\ RA = PC + 8; PC = target\\ } | |
- | | MFC1 rt, fs | Move Word From FPU (Coprocessor 1) | %% %% | | + | | MFC1 rt, fs | Move Word From FPU | %% rt = fs %% | |
- | | DMFC1 rt, fs | Doubleword Move From FPU (Coprocessor 1) | %% %% | | + | | DMFC1 rt, fs | Doubleword Move From FPU | %% rt = fs %% | |
- | | MTC1 rt, fs | Move To FPU (Coprocessor 1) | %% %% | | + | | MTC1 rt, fs | Move To FPU | %% fs = rt %% | |
- | | DMTC1 rt, fs | Doubleword Move To FPU (Coprocessor 1) | %% %% | | + | | DMTC1 rt, fs | Doubleword Move To FPU | %% fs = rt %% | |
- | | CFC1 rt, fs | Move Control Word From FPU (Coprocessor 1) | %% %% | | + | | CFC1 rt, fcr | Move Control Word From FPU | %% rt = fcr %% | |
- | | CTC1 rt, fs | Move Control Word To FPU (Coprocessor 1) | %% %% | | + | | CTC1 rt, fcr | Move Control Word To FPU | %% rt = fcr %% | |
- | | MOV.fmt fd, fs | Floating-point Move | %% %% | | + | | MOV.S fd, fs | FPU Move Float | %% fd = fs %% | |
- | | ABS.fmt fd, fs | Floating-point Absolute Value | %% %% | | + | | ABS.S fd, fs | FPU Absolute Value Float | %% fd = abs(fs) %% | |
- | | NEG.fmt fd, fs | Floating-point Negate | %% %% | | + | | NEG.S fd, fs | FPU Negate Float | %% fd = -fs %% | |
- | | SQRT.fmt fd, fs | Floating-point Square Root | %% %% | | + | | SQRT.S fd, fs | FPU Square Root Float | %% fd = sqrt(fs) %% | |
- | | ADD.fmt fd, fs, ft | Floating-point Add | %% %% | | + | | ADD.S fd, fs, ft | FPU Add Floats | %% fd = fs + ft %% | |
- | | SUB.fmt fd, fs, ft | Floating-point Subtract | %% %% | | + | | SUB.S fd, fs, ft | FPU Subtract Floats | %% fd = fs - ft %% | |
- | | MUL.fmt fd, fs, ft | Floating-point Multiply | %% %% | | + | | MUL.S fd, fs, ft | FPU Multiply Floats | %% fd = fs * ft %% | |
- | | DIV.fmt fd, fs, ft | Floating-point Divide | %% %% | | + | | DIV.S fd, fs, ft | FPU Divide Floats | %% fd = fs / ft %% | |
- | | CVT.S.fmt fd, fs | Floating-point Convert To Single Floating-point Format | %% %% | | + | | MOV.D fd, fs | FPU Move Double | %% fd = fs %% | |
- | | CVT.D.fmt fd, fs | Floating-point Convert To Double Floating-point Format | %% %% | | + | | ABS.D fd, fs | FPU Absolute Value Double | %% fd = abs(fs) %% | |
- | | CVT.W.fmt fd, fs | Floating-point Convert To Single Fixed-point Format | %% %% | | + | | NEG.D fd, fs | FPU Negate Double | %% fd = -fs %% | |
- | | CVT.L.fmt fd, fs | Floating-point Convert To Long Fixed-point Format | %% %% | | + | | SQRT.D fd, fs | FPU Square Root Double | %% fd = sqrt(fs) %% | |
- | | FLOOR.L.fmt fd, fs | Floating-point Floor To Long Fixed-point Format | %% %% | | + | | ADD.D fd, fs, ft | FPU Add Doubles | %% fd = fs + ft %% | |
- | | FLOOR.W.fmt fd, fs | Floating-point Floor To Single Fixed-point Format | %% %% | | + | | SUB.D fd, fs, ft | FPU Subtract Doubles | %% fd = fs - ft %% | |
- | | ROUND.L.fmt fd, fs | Floating-point Round To Long Fixed-point Format | %% %% | | + | | MUL.D fd, fs, ft | FPU Multiply Doubles | %% fd = fs * ft %% | |
- | | ROUND.W.fmt fd, fs | Floating-point Round To Single Fixed-point Format | %% %% | | + | | DIV.D fd, fs, ft | FPU Divide Doubles | %% fd = fs / ft %% | |
- | | TRUNC.L.fmt fd, fs | Floating-point Truncate To Long Fixed-point Format | %% %% | | + | | FLOOR.L.S fd, fs | FPU Floor Float To Fixed-point Long | %% fd = (int64)floor(fs) %% | |
- | | TRUNC.W.fmt fd, fs | Floating-point Truncate To Single Fixed-point Format | %% %% | | + | | FLOOR.W.S fd, fs | FPU Floor Float To Fixed-point Word | %% fd = (int32)floor(fs) %% | |
- | | CEIL.L.fmt fd, fs | Floating-point Ceiling To Long Fixed-point Format | %% %% | | + | | ROUND.L.S fd, fs | FPU Round Float To Fixed-point Long | %% fd = (int64)round(fs) %% | |
- | | CEIL.W.fmt fd, fs | Floating-point Ceiling To Single Fixed-point Format | %% %% | | + | | ROUND.W.S fd, fs | FPU Round Float To Fixed-point Word | %% fd = (int32)round(fs) %% | |
- | | C.F.fmt fs, ft | Floating-point Compare False | %% %% | | + | | TRUNC.L.S fd, fs | FPU Truncate Float To Fixed-point Long | %% fd = (int64)trunc(fs) %% | |
- | | C.UN.fmt fs, ft | Floating-point Compare Unordered | %% %% | | + | | TRUNC.W.S fd, fs | FPU Truncate Float To Fixed-point Word | %% fd = (int32)trunc(fs) %% | |
- | | C.EQ.fmt fs, ft | Floating-point Compare Equal | %% %% | | + | | CEIL.L.S fd, fs | FPU Ceiling Float To Fixed-point Long | %% fd = (int64)ceil(fs) %% | |
- | | C.UEQ.fmt fs, ft | Floating-point Compare Unordered or Equal | %% %% | | + | | CEIL.W.S fd, fs | FPU Ceiling Float To Fixed-point Word | %% fd = (int32)ceil(fs) %% | |
- | | C.OLT.fmt fs, ft | Floating-point Compare Ordered Less Than | %% %% | | + | | FLOOR.L.D fd, fs | FPU Floor Double To Fixed-point Long | %% fd = (int64)floor(fs) %% | |
- | | C.ULT.fmt fs, ft | Floating-point Compare Unordered Less Than | %% %% | | + | | FLOOR.W.D fd, fs | FPU Floor Double To Fixed-point Word | %% fd = (int32)floor(fs) %% | |
- | | C.OLE.fmt fs, ft | Floating-point Compare Unordered or Less Than | %% %% | | + | | ROUND.L.D fd, fs | FPU Round Double To Fixed-point Long | %% fd = (int64)round(fs) %% | |
- | | C.ULE.fmt fs, ft | Floating-point Compare Unordered or Less Than or Equal | %% %% | | + | | ROUND.W.D fd, fs | FPU Round Double To Fixed-point Word | %% fd = (int32)round(fs) %% | |
- | | C.SF.fmt fs, ft | Floating-point Compare Signaling False | %% %% | | + | | TRUNC.L.D fd, fs | FPU Truncate Double To Fixed-point Long | %% fd = (int64)trunc(fs) %% | |
- | | C.NGLE.fmt fs, ft | Floating-point Compare Not Greater Than or Less Than or Equal | %% %% | | + | | TRUNC.W.D fd, fs | FPU Truncate Double To Fixed-point Word | %% fd = (int32)trunc(fs) %% | |
- | | C.SEQ.fmt fs, ft | Floating-point Compare Signaling Equal | %% %% | | + | | CEIL.L.D fd, fs | FPU Ceiling Double To Fixed-point Long | %% fd = (int64)ceil(fs) %% | |
- | | C.NGL.fmt fs, ft | Floating-point Compare Not Greater Than or Less Than | %% %% | | + | | CEIL.W.D fd, fs | FPU Ceiling Double To Fixed-point Word | %% fd = (int32)ceil(fs) %% | |
- | | C.LT.fmt fs, ft | Floating-point Compare Less Than | %% %% | | + | | CVT.D.S fd, fs | FPU Convert Float To Double | %% fd = (double)fs %% | |
- | | C.NGE.fmt fs, ft | Floating-point Compare Not Greater Than or Equal | %% %% | | + | | CVT.W.S fd, fs | FPU Convert Float To Fixed-point Word | %% fd = (int32)fs %% | |
- | | C.LE.fmt fs, ft | Floating-point Compare Less Than or Equal | %% %% | | + | | CVT.L.S fd, fs | FPU Convert Float To Fixed-Point Long | %% fd = (int64)fs %% | |
- | | C.NGT.fmt fs, ft | Floating-point Compare Not Greater Than | %% %% | | + | | CVT.S.D fd, fs | FPU Convert Double To Float | %% fd = (float)fs %% | |
- | | BC1F offset | Branch On FPU False (Coprocessor 1) | %% %% | | + | | CVT.W.D fd, fs | FPU Convert Double To Fixed-point Word | %% fd = (int32)fs %% | |
- | | BC1FL offset | Branch On FPU False Likely (Coprocessor 1) | %% %% | | + | | CVT.L.D fd, fs | FPU Convert Double To Fixed-Point Long | %% fd = (int64)fs %% | |
- | | BC1T offset | Branch On FPU True (Coprocessor 1) | %% %% | | + | | CVT.S.W fd, fs | FPU Convert Fixed-Point Word To Float | %% fd = (float)fs %% | |
- | | BC1TL offset | Branch On FPU True Likely (Coprocessor 1) | %% %% | | + | | CVT.S.L fd, fs | FPU Convert Fixed-Point Long To Float | %% fd = (float)fs %% | |
- | | MFC0 rt, rd | Move From Coprocessor 0 | %% %% | | + | | CVT.D.W fd, fs | FPU Convert Fixed-Point Word To Double | %% fd = (double)fs %% | |
- | | MTC0 rt, rd | Move To Coprocessor 0 | %% %% | | + | | CVT.D.L fd, fs | FPU Convert Fixed-Point Long To Double | %% fd = (double)fs %% | |
+ | | C.EQ.S fs, ft | FPU Compare Equal Float | %% FCR31.C = (fs == ft) %% | | ||
+ | | C.LT.S fs, ft | FPU Compare Less Than Float | %% FCR31.C = (fs < ft) %% | | ||
+ | | C.LE.S fs, ft | FPU Compare Less Than or Equal Float | %% FCR31.C = (fs <= ft) %% | | ||
+ | | C.EQ.D fs, ft | FPU Compare Equal Double | %% FCR31.C = (fs == ft) %% | | ||
+ | | C.LT.D fs, ft | FPU Compare Less Than Double | %% FCR31.C = (fs < ft) %% | | ||
+ | | C.LE.D fs, ft | FPU Compare Less Than or Equal Double | %% FCR31.C = (fs <= ft) %% | | ||
+ | | C.F.S fs, ft | FPU Compare False Float | %% FCR31.C = FALSE %% | | ||
+ | | C.UN.S fs, ft | FPU Compare Unordered Float | %% FCR31.C = (isNaN(fs) || isNaN(ft)) %% | | ||
+ | | C.UEQ.S fs, ft | FPU Compare Unordered or Equal Float | %% FCR31.C = (isNaN(fs) || isNaN(ft) || (fs == ft)) %% | | ||
+ | | C.OLT.S fs, ft | FPU Compare Ordered Less Than Float | %% FCR31.C = (!isNaN(fs) && !isNaN(ft) && (fs < ft)) %% | | ||
+ | | C.ULT.S fs, ft | FPU Compare Unordered or Less Than Float | %% FCR31.C = (isNaN(fs) || isNaN(ft) || (fs < ft)) %% | | ||
+ | | C.OLE.S fs, ft | FPU Compare Ordered Less Than\\ Or Equal Float | %% FCR31.C = (!isNaN(fs) && !isNaN(ft) && (fs <= ft)) %% | | ||
+ | | C.ULE.S fs, ft | FPU Compare Unordered or Less Than\\ or Equal Float | %% FCR31.C = (isNaN(fs) || isNaN(ft) || (fs <= ft)) %% | | ||
+ | | C.SF.S fs, ft | FPU Compare Signaling False Float | %% FCR31.C = FALSE %% | | ||
+ | | C.NGLE.S fs, ft | FPU Compare Not Greater\\ Or Less Than or Equal Float | %% FCR31.C = (isNaN(fs) || isNaN(ft)) %% | | ||
+ | | C.SEQ.S fs, ft | FPU Compare Signaling Equal Float | %% FCR31.C = (fs == ft) %% | | ||
+ | | C.NGL.S fs, ft | FPU Compare Not Greater Or Less Than Float | %% FCR31.C = !((fs > ft) || (fs < ft)) %% | | ||
+ | | C.NGE.S fs, ft | FPU Compare Not Greater Than or Equal Float | %% FCR31.C = !(fs >= ft) %% | | ||
+ | | C.NGT.S fs, ft | FPU Compare Not Greater Than Float | %% FCR31.C = !(fs > ft) %% | | ||
+ | | C.F.D fs, ft | FPU Compare False Double | %% FCR31.C = FALSE %% | | ||
+ | | C.UN.D fs, ft | FPU Compare Unordered Double | %% FCR31.C = (isNaN(fs) || isNaN(ft)) %% | | ||
+ | | C.UEQ.D fs, ft | FPU Compare Unordered or Equal Double | %% FCR31.C = (isNaN(fs) || isNaN(ft) || (fs == ft)) %% | | ||
+ | | C.OLT.D fs, ft | FPU Compare Ordered Less Than Double | %% FCR31.C = (!isNaN(fs) && !isNaN(ft) && (fs < ft)) %% | | ||
+ | | C.ULT.D fs, ft | FPU Compare Unordered or Less Than Double | %% FCR31.C = (isNaN(fs) || isNaN(ft) || (fs < ft)) %% | | ||
+ | | C.OLE.D fs, ft | FPU Compare Ordered Less Than Or Equal Double | %% FCR31.C = (!isNaN(fs) && !isNaN(ft) && (fs <= ft)) %% | | ||
+ | | C.ULE.D fs, ft | FPU Compare Unordered\\ or Less Than or Equal Double | %% FCR31.C = (isNaN(fs) || isNaN(ft) || (fs <= ft)) %% | | ||
+ | | C.SF.D fs, ft | FPU Compare Signaling False Double | %% FCR31.C = FALSE %% | | ||
+ | | C.NGLE.D fs, ft | FPU Compare Not Greater\\ Or Less Than or Equal Double | %% FCR31.C = (isNaN(fs) || isNaN(ft)) %% | | ||
+ | | C.SEQ.D fs, ft | FPU Compare Signaling Equal Double | %% FCR31.C = (fs == ft) %% | | ||
+ | | C.NGL.D fs, ft | FPU Compare Not Greater Or Less Than Double | %% FCR31.C = !((fs > ft) || (fs < ft)) %% | | ||
+ | | C.NGE.D fs, ft | FPU Compare Not Greater Than or Equal Double | %% FCR31.C = !(fs >= ft) %% | | ||
+ | | C.NGT.D fs, ft | FPU Compare Not Greater Than Double | %% FCR31.C = !(fs > ft) %% | | ||
+ | | BC1F offset | Branch On FPU False | %% if(FCR31.C == 0) PC = offset %% | | ||
+ | | BC1FL offset | Branch On FPU False Likely | %% if(FCR31.C == 0) PC = offset %% | | ||
+ | | BC1T offset | Branch On FPU True | %% if(FCR31.C == 1) PC = offset %% | | ||
+ | | BC1TL offset | Branch On FPU True Likely | %% if(FCR31.C == 1) PC = offset %% | | ||
+ | | MFC0 rt, rd | Move From Coprocessor 0 | %% rt = rd %% | | ||
+ | | MTC0 rt, rd | Move To Coprocessor 0 | %% rd = rt %% | | ||
| CACHE op, offset(base) | Cache Operation | %% %% | | | CACHE op, offset(base) | Cache Operation | %% %% | | ||
- | | TEQ rs, rt | Trap If Equal | %% %% | | + | | TEQ rs, rt | Trap If Equal | if(rs == rt) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TEQI rs, immediate | Trap If Equal Immediate | %% %% | | + | | TEQI rs, immediate | Trap If Equal Immediate | if(rs == immediate) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TGE rs, rt | Trap If Greater Than Or Equal | %% %% | | + | | TGE rs, rt | Trap If Greater Than Or Equal | if(rs >= rt) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TGEI rs, immediate | Trap If Greater Than Or Equal | %% %% | | + | | TGEI rs, immediate | Trap If Greater Than Or Equal Immedate | if(rs >= immediate) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TGEIU rs, immediate | Trap If Greater Than Or Equal | %% %% | | + | | TGEIU rs, immediate | Trap If Greater Than Or Equal Immediate Unsigned | if(rs >= immediate) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TGEU rs, rt | Trap If Greater Than Or Equal Unsigned | %% %% | | + | | TGEU rs, rt | Trap If Greater Than Or Equal Unsigned | if(rs >= rt) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TLT rs, rt | Trap If Less Than | %% %% | | + | | TLT rs, rt | Trap If Less Than | if(rs < rt) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TLTI rs, immediate | Trap If Less Than Immediate | %% %% | | + | | TLTI rs, immediate | Trap If Less Than Immediate | if(rs < immediate) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TLTIU rs, immediate | Trap If Less Than Immediate Unsigned | %% %% | | + | | TLTIU rs, immediate | Trap If Less Than Immediate Unsigned | if(rs < immediate) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TLTU rs, rt | Trap If Less Than Unsigned | %% %% | | + | | TLTU rs, rt | Trap If Less Than Unsigned | if(rs < rt) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TNE rs, rt | Trap If Not Equal | %% %% | | + | | TNE rs, rt | Trap If Not Equal | if(rs != rt) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
- | | TNEI rs, immediate | Trap If Not Equal Immediate | %% %% | | + | | TNEI rs, immediate | Trap If Not Equal Immediate | if(rs != immediate) {\\ COP0_CAUSE %%|=%% (13 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180\\ } | |
| SYNC | Synchronize | (No operation on R4300) | | | SYNC | Synchronize | (No operation on R4300) | | ||
- | | SYSCALL | System Call | %%COP0_CAUSE |= (8 << 2);%%\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180 | | + | | 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 | | + | | BREAK | Breakpoint | COP0_CAUSE %%|=%% (9 %%<<%% 2);\\ COP0_EPC = PC;\\ PC = exc_vector_base + 0x180 | |
- | | ERET | Return From Exception | PC = COP0_EPC (or COP0_ERROREPC) | | + | | ERET | Return From Exception | PC = COP0_EPC (or COP0_ERROREPC)\\ LLBit = 0 | |
| TLBP | Probe TLB For Matching Entry | %% %% | | | TLBP | Probe TLB For Matching Entry | %% %% | | ||
| TLBR | Read Indexed TLB Entry | %% %% | | | TLBR | Read Indexed TLB Entry | %% %% | | ||
| TLBWI | Write Indexed TLB Entry | %% %% | | | TLBWI | Write Indexed TLB Entry | %% %% | | ||
| TLBWR | Write Random TLB Entry | %% %% | | | TLBWR | Write Random TLB Entry | %% %% | | ||
+ | |||
+ | ---- | ||
+ | ===== General Purpose Registers ===== | ||
+ | ^ Number ^ Name ^ Preserved ^ Purpose ^ | ||
+ | | 0 | R0 | n/a | Hardwired zero | | ||
+ | | 1 | AT | no | Assembler temporary value | | ||
+ | | 2:3 | V0:V1 | no | Subroutine return value | | ||
+ | | 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 | | ||
+ | |||
+ | * Excluding R0 and RA, the register purposes noted above are conventional; they are not enforced by the processor. | ||
+ | * By convention if a subroutine uses a "preserved" register, the subroutine must restore that register to its original value before returning. | ||
+ | |||
+ | ---- | ||
+ | ===== Floating-point Registers (COP1) ===== | ||
+ | ^ Number ^ Name ^ Preserved ^ Purpose ^ | ||
+ | | 0:2 | F0:F2 | no | Subroutine return value | | ||
+ | | 4:10 | F4:F10 | no | Temporary values | | ||
+ | | 12:14 | F12:F14 | no | Subroutine arguments | | ||
+ | | 16:18 | F16:F18 | no | Temporary values | | ||
+ | | 20:30 | F20:F30 | yes | Saved values | | ||
+ | |||
+ | * When the [[r4300#COP0 Status Register]]'s FR bit is 0, only even numbered registers should be used. | ||
+ | * All register purposes noted above are conventional; they are not enforced by the processor. | ||
+ | * By convention if a subroutine uses a “preserved” register, the subroutine must restore that register to its original value before returning. | ||
+ | |||
+ | ---- | ||
+ | ===== Floating-point FCR31 (Control/Status) Register (COP1) ===== | ||
+ | <code> | ||
+ | | 25|24|23| 18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 0| | ||
+ | |0000000| .| .|00000| .| .| .| .| .| .| .| .| .| .| .| .| .| .| .| .|..| | ||
+ | |-------|FS|C |-----|CE|CV|CZ|CO|CU|CI|EV|EZ|EO|EU|EI|FV|FZ|FO|FU|FI|RM| | ||
+ | | 7 |1 |1 | 5 | 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1| 1|2 | | ||
+ | </code> | ||
+ | |||
+ | ^ Field ^ Description ^ | ||
+ | | FS | Enables flashing of denormalized numbers \\ (See [[https://hack64.net/docs/VR43XX.pdf#page=213|Page 213 of the manual]]) | | ||
+ | | C | Compare bit (1: TRUE, 0: FALSE)\\ Result of the last compare (C.COND.FMT) operation | | ||
+ | | CE | Cause bit: Unimplemented operation | | ||
+ | | CV | Cause bit: Invalid operation | | ||
+ | | CZ | Cause bit: Division by Zero | | ||
+ | | CO | Cause bit: Overflow | | ||
+ | | CU | Cause bit: Underflow | | ||
+ | | CI | Cause bit: Inexact operation | | ||
+ | | EV | Enable bit: Invalid operation | | ||
+ | | EZ | Enable bit: Division by Zero | | ||
+ | | EO | Enable bit: Overflow | | ||
+ | | EU | Enable bit: Underflow | | ||
+ | | EI | Enable bit: Inexact operation | | ||
+ | | FV | Flag bit: Invalid operation | | ||
+ | | FZ | Flag bit: Division by Zero | | ||
+ | | FO | Flag bit: Overflow | | ||
+ | | FU | Flag bit: Underflow | | ||
+ | | FI | Flag bit: Inexact operation | | ||
+ | | RM | [[r4300#Rounding Mode]] | | ||
+ | |||
+ | * Cause bits indicate the last exception - more than one may be set at a time. | ||
+ | * Enable bits mask exceptions when set to 0. | ||
+ | * Like the Cause bits, the Flag bits indicate the last exceptions, however they can only be cleared by writing a new value to FCR31 using the CTC1 instruction. | ||
+ | |||
+ | ==== Rounding modes ==== | ||
+ | ^ Value ^ Mnemonic ^ Description ^ | ||
+ | | 0 | RN | Round to nearest representable value | | ||
+ | | 1 | RZ | Round towards zero | | ||
+ | | 2 | RP | Round towards positive infinity | | ||
+ | | 3 | RM | Round towards negative infinity | | ||
+ | |||
+ | ---- | ||
+ | ===== COP0 Status Register ===== | ||
+ | <code> | ||
+ | | 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 | | ||
+ | </code> | ||
+ | |||
+ | ^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 |Bootstrap exception vector (0: Normal, 1: Bootstrap)\\ Controls [[r4300#Exception Vector locations]] | | ||
+ | |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)| | ||
+ | |||
+ | ==== Exception Vector Locations ==== | ||
+ | ^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 | | ||
+ | |||
+ | ---- | ||
+ | ===== COP0 Cause Register ===== | ||
+ | <code> | ||
+ | |31|30|28| 16| 8|7| 2| 0| | ||
+ | | .| 0|..|............|........|0|.....|00| | ||
+ | |BD| -|CE|------------| IP |-| EXC |--| | ||
+ | |1 |1 |2 | 12 | 8 |1| 5 |2 | | ||
+ | </code> | ||
+ | |||
+ | ^Field ^Description^ | ||
+ | |BD |Branch delay (1: Last exception occurred in delay slot, 0: Normal)| | ||
+ | |CE |Coprocessor number for coprocessor unusable exception| | ||
+ | |IP |[[r4300#Interrupts|Interrupt]] pending (1: Interrupt, 0: No Interrupt)\\ IP7 Timer interrupt\\ IP6:2 External normal interrupts\\ IP1:0 Software interrupt| | ||
+ | |EXC |Exception code| | ||
+ | |||
+ | ==== Exception Codes ==== | ||
+ | ^Code ^Mnemonic ^Description^Generated...^ | ||
+ | |0 |Int |[[r4300#Interrupts|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)|| | ||
+ | |||
+ | ==== Interrupts ==== | ||
+ | ^Cause bit^Source ^ | ||
+ | |IP0 |Set by software| | ||
+ | |IP1 |Set by software| | ||
+ | |IP2 |Int0 pin <color lightgreen>(N64: RCP)</color>| | ||
+ | |IP3 |Int1 pin <color lightgreen>(N64: Cartridge)</color>| | ||
+ | |IP4 |Int2 pin <color lightgreen>(N64: Pre-NMI (Reset button))</color>| | ||
+ | |IP5 |Int3 pin <color lightgreen>(N64: RDB Read)</color>| | ||
+ | |IP6 |Int4 pin <color lightgreen>(N64: RDB Write)</color>| | ||
+ | |IP7 |Timer interrupt| | ||
+ | |||
+ | * Software interrupts (IP1:IP0) are generated when software manually sets the Cause register's IP1 or IP0 bit to 1 using an MTC0 instruction. | ||
+ | * The Timer interrupt (IP7) is generated when the Count and Compare registers are equal. | ||
+ | * Interrupts may be masked by setting the respective IM bits of the Status register to 0. | ||
+ | |||
+ | |||
+ | <color lightgreen> | ||
+ | On the Nintendo 64, IP2 represents an RCP (Reality Coprocessor) interrupt. When an RCP interrupt occurs, a flag representing the specific RCP interface may be read from MI_INTR_REG (0x04300008). | ||
+ | </color> | ||
+ | ^<color lightgreen>Bit</color>^<color lightgreen>Name</color>^<color lightgreen>Description</color>^ | ||
+ | |<color lightgreen>0x01</color>|<color lightgreen>MI_INTR_SP</color>|<color lightgreen>Signal Processor - Task Done/Task Yield</color>| | ||
+ | |<color lightgreen>0x02</color>|<color lightgreen>MI_INTR_SI</color>|<color lightgreen>Serial Interface - Controller input available</color>| | ||
+ | |<color lightgreen>0x04</color>|<color lightgreen>MI_INTR_AI</color>|<color lightgreen>Audio Interface - Audio buffer swap</color>| | ||
+ | |<color lightgreen>0x08</color>|<color lightgreen>MI_INTR_VI</color>|<color lightgreen>Video Interface - Vertical retrace</color>| | ||
+ | |<color lightgreen>0x10</color>|<color lightgreen>MI_INTR_PI</color>|<color lightgreen>Peripheral Interface - ROM to RAM DMA done</color>| | ||
+ | |<color lightgreen>0x20</color>|<color lightgreen>MI_INTR_DP</color>|<color lightgreen>Display Processor - RDP processing done (gDPFullSync)</color>| | ||
+ | |||
+ | <color lightgreen> | ||
+ | RCP-specific interrupts may be enabled or disabled by writing one or more of the following values to MI_INTR_MASK_REG (0x0430000C). | ||
+ | </color> | ||
+ | ^<color lightgreen>Bit</color>^<color lightgreen>Name</color>^<color lightgreen>Description</color>^ | ||
+ | |<color lightgreen>0x0001</color>|<color lightgreen>MI_INTR_MASK_CLR_SP</color>|<color lightgreen>Disable SP interrupts</color>| | ||
+ | |<color lightgreen>0x0002</color>|<color lightgreen>MI_INTR_MASK_SET_SP</color>|<color lightgreen>Enable SP interrupts</color>| | ||
+ | |<color lightgreen>0x0004</color>|<color lightgreen>MI_INTR_MASK_CLR_SI</color>|<color lightgreen>Disable SI interrupts</color>| | ||
+ | |<color lightgreen>0x0008</color>|<color lightgreen>MI_INTR_MASK_SET_SI</color>|<color lightgreen>Enable SI interrupts</color>| | ||
+ | |<color lightgreen>0x0010</color>|<color lightgreen>MI_INTR_MASK_CLR_AI</color>|<color lightgreen>Disable AI interrupts</color>| | ||
+ | |<color lightgreen>0x0020</color>|<color lightgreen>MI_INTR_MASK_SET_AI</color>|<color lightgreen>Enable AI interrupts</color>| | ||
+ | |<color lightgreen>0x0040</color>|<color lightgreen>MI_INTR_MASK_CLR_VI</color>|<color lightgreen>Disable VI interrupts</color>| | ||
+ | |<color lightgreen>0x0080</color>|<color lightgreen>MI_INTR_MASK_SET_VI</color>|<color lightgreen>Enable VI interrupts</color>| | ||
+ | |<color lightgreen>0x0100</color>|<color lightgreen>MI_INTR_MASK_CLR_PI</color>|<color lightgreen>Disable PI interrupts</color>| | ||
+ | |<color lightgreen>0x0200</color>|<color lightgreen>MI_INTR_MASK_SET_PI</color>|<color lightgreen>Enable PI interrupts</color>| | ||
+ | |<color lightgreen>0x0400</color>|<color lightgreen>MI_INTR_MASK_CLR_DP</color>|<color lightgreen>Disable DP interrupts</color>| | ||
+ | |<color lightgreen>0x0800</color>|<color lightgreen>MI_INTR_MASK_SET_DP</color>|<color lightgreen>Enable DP interrupts</color>| | ||
+ | |||
+ | ---- | ||
+ | ===== Memory Segments (32-bit) ===== | ||
+ | ^ 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^ | ||
+ | |||
+ | <color lightgreen>Note: Commercial Nintendo 64 games operate in kernel mode at all times.</color> | ||
+ | |||
+ | |||
+ | ===== References ===== | ||
+ | * http://hack64.net/docs/VR43XX.pdf | ||
+ | * http://datasheets.chipdb.org/MIPS/R4300i_datasheet.pdf | ||
+ | * https://level42.ca/projects/ultra64/Documentation/man/pro-man/pro07/index7.7.html | ||
+ | * https://level42.ca/projects/ultra64/Documentation/man/pro-man/pro07/index7.8.html | ||
+ | * https://level42.ca/projects/ultra64/Documentation/man/n64man/u64/u64.html | ||
+ | * https://level42.ca/projects/ultra64/Documentation/man/header/rcp.htm | ||
+ | * https://github.com/n64dev/cen64/blob/72c778c3bfb25262498af6a21e8dec828a28be19/vr4300/interface.h#L16 | ||
+ | * http://ti.ira.uka.de/TI-2/Mips/Befehlssatz.pdf | ||
+ | |||
+ |