This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Last revision Both sides next revision | ||
r4300 [2019/02/08 20:41] shygoo more specific rcp interrupt descriptions |
r4300 [2019/02/12 18:11] shygoo better information on rcp interrupt masking |
||
---|---|---|---|
Line 8: | Line 8: | ||
Information on this page that is specifically related to the Nintendo 64 is <color lightgreen>highlighted in green</color>. | Information on this page that is specifically related to the Nintendo 64 is <color lightgreen>highlighted in green</color>. | ||
+ | ... | ||
+ | |||
+ | ... | ||
+ | |||
+ | ... | ||
===== Commands ===== | ===== 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(("immediate" = 16-bit signed immediate value)) | 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 21: | 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(("sa" = 5-bit immediate shift amount)) | 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 34: | 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 | %%rt = (rs < immediate) ? 1 : 0 %% | | + | | DADDI rt, rs, immediate | Doubleword Add Immediate | %%rd = rs + immediate %% | |
- | | SLTIU rt, rs, immediate | Set On Less Than Immediate Unsigned | %%rt = (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 62: | 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(rs) | Load Byte | %%rt = *(int8*)(rs + offset) %% | | + | | LB rt, offset(rs) | Load Byte | %%rt = *(int8*)(rs + offset) %% | |
- | | LBU rt, offset(rs) | Load Byte Unsigned | %%rt = *(uint8*)(rs + offset) %% | | + | | LBU rt, offset(rs) | Load Byte Unsigned | %%rt = *(uint8*)(rs + offset) %% | |
- | | LH rt, offset(rs) | Load Halfword | %%rt = *(int16*)(rs + offset) %% | | + | | LH rt, offset(rs) | Load Halfword | %%rt = *(int16*)(rs + offset) %% | |
- | | LHU rt, offset(rs) | Load Halfword Unsigned | %%rt = *(uint16*)(rs + offset)%% | | + | | LHU rt, offset(rs) | Load Halfword Unsigned | %%rt = *(uint16*)(rs + offset)%% | |
- | | LW rt, offset(rs) | Load Word | %%rt = *(int32*)(rs + offset) %% | | + | | LW rt, offset(rs) | Load Word | %%rt = *(int32*)(rs + offset) %% | |
- | | LWU rt, offset(rs) | Load Word Unsigned | %%rt = *(uint32*)(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) %% | | + | | LWC1 ft, offset(rs) | Load Word To FPU(("FPU": Floating-point unit, another name for Coprocessor 1)) | %%ft = *(float*)(rs + offset) %% | |
- | | LWL rt, offset(rs) | Load Word Left | %% %% | | + | | LWL rt, offset(rs) | Load Word Left | %% %% | |
- | | LWR rt, offset(rs) | Load Word Right | %% %% | | + | | LWR rt, offset(rs) | Load Word Right | %% %% | |
- | | LD rt, offset(rs) | Load Doubleword | %%rt = *(uint64*)(rs + offset)%% | | + | | LD rt, offset(rs) | Load Doubleword | %%rt = *(uint64*)(rs + offset)%% | |
- | | LDC1 ft, offset(rs) | Load Doubleword To FPU (Coprocessor 1) | %%ft = *(double*)(rs + offset)%% | | + | | LDC1 ft, offset(rs) | Load Doubleword To FPU | %%ft = *(double*)(rs + offset)%% | |
- | | LDL rt, offset(rs) | Load Doubleword Left | %% %% | | + | | LDL rt, offset(rs) | Load Doubleword Left | %% %% | |
- | | LDR rt, offset(rs) | Load Doubleword Right | %% %% | | + | | LDR rt, offset(rs) | Load Doubleword Right | %% %% | |
- | | LL rt, offset(rs) | Load Linked | %% %% | | + | | LL rt, offset(rs) | Load Linked | %% %% | |
- | | LLD rt, offset(rs) | Load Linked Doubleword | %% %% | | + | | LLD rt, offset(rs) | Load Linked Doubleword | %% %% | |
- | | SB rt, offset(rs) | Store Byte | %%*(int8*)(rs + offset) = rt %% | | + | | SB rt, offset(rs) | Store Byte | %%*(int8*)(rs + offset) = rt %% | |
- | | SH rt, offset(rs) | Store Halfword | %%*(int16*)(rs + offset) = rt %% | | + | | SH rt, offset(rs) | Store Halfword | %%*(int16*)(rs + offset) = rt %% | |
- | | SW rt, offset(rs) | Store Word | %%*(int32*)(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 %% | | + | | SWC1 ft, offset(rs) | Store Word From FPU | %%*(float*)(rs + offset) = ft %% | |
- | | SWL rt, offset(rs) | Store Word Left | %% %% | | + | | SWL rt, offset(rs) | Store Word Left | %% %% | |
- | | SWR rt, offset(rs) | Store Word Right | %% %% | | + | | SWR rt, offset(rs) | Store Word Right | %% %% | |
- | | SD rt, offset(rs) | Store Doubleword | %%*(int64*)(rs + offset) = rt %% | | + | | SD rt, offset(rs) | Store Doubleword | %%*(int64*)(rs + offset) = rt %% | |
- | | SDC1 ft, offset(rs) | Store Doubleword From FPU (Coprocessor 1) | %% %% | | + | | SDC1 ft, offset(rs) | Store Doubleword From FPU | %%*(double*)(rs + offset) = rt %% | |
- | | SDL rt, offset(rs) | Store Doubleword Left | %% %% | | + | | SDL rt, offset(rs) | Store Doubleword Left | %% %% | |
- | | SDR rt, offset(rs) | Store Doubleword Right | %% %% | | + | | SDR rt, offset(rs) | Store Doubleword Right | %% %% | |
- | | SC rt, offset(rs) | Store Conditional | %% %% | | + | | SC rt, offset(rs) | Store Conditional | %% %% | |
- | | SCD rt, offset(rs) | Store Conditional Doubleword | %% %% | | + | | SCD rt, offset(rs) | Store Conditional Doubleword | %% %% | |
| J target | Jump | %% PC = target %% | | | J target | Jump | %% PC = target %% | | ||
| JR rs | Jump Register | %% PC = rs %% | | | JR rs | Jump Register | %% PC = rs %% | | ||
Line 94: | Line 99: | ||
| 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 %% | |
- | | BNE rs, rt, offset | Branch On Not Equal | %% if(rs != rt) PC = offset %% | | + | | BNE rs, rt, target | Branch On Not Equal | %% if(rs != rt) PC = target %% | |
- | | BNEL rs, rt, offset | Branch On Not Equal Likely | %% if(rs != rt) PC = offset %% | | + | | BNEL rs, rt, target | Branch On Not Equal Likely | %% if(rs != rt) PC = target %% | |
- | | BGTZ rs, offset | Branch On Greater Than Zero | %% if(rs > 0) PC = offset %% | | + | | BGTZ rs, target | Branch On Greater Than Zero | %% if(rs > 0) PC = target %% | |
- | | BGTZL rs, offset | Branch On Greater Than Zero Likely | %% if(rs > 0) PC = offset %% | | + | | BGTZL rs, target | Branch On Greater Than Zero Likely | %% if(rs > 0) PC = target %% | |
- | | BLEZ rs, offset | Branch On Less 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 %% | |
- | | BLEZL rs, offset | Branch On Less 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 %% | |
- | | BGEZ rs, offset | Branch On Greater Than Or Equal To Zero | %% if(rs >= 0) PC = offset %% | | + | | BGEZ rs, target | Branch On Greater 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 %% | | + | | BGEZL rs, target | Branch On Greater 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\\ } | | + | | BGEZAL rs, target | Branch On Greater Than Or Equal To Zero\\ And Link | if(rs %%>=%% 0) {\\ RA = PC + 8; PC = target\\ } | |
- | | BGEZALL rs, offset | Branch On Greater Than Or Equal To Zero And Link Likely | if(rs %%>=%% 0) {\\ RA = PC + 8; PC = offset\\ } | | + | | BGEZALL rs, target | Branch On Greater Than Or Equal To Zero\\ And Link Likely | if(rs %%>=%% 0) {\\ RA = PC + 8; PC = target\\ } | |
- | | BLTZ rs, offset | Branch On Less Than Zero | %% if(rs < 0) PC = offset %% | | + | | BLTZ rs, target | Branch On Less Than Zero | %% if(rs < 0) PC = target %% | |
- | | BLTZL rs, offset | Branch On Less Than Zero Likely | %% if(rs < 0) PC = offset %% | | + | | BLTZL rs, target | Branch On Less Than Zero Likely | %% if(rs < 0) PC = target %% | |
- | | BLTZAL rs, offset | Branch On Less Than Zero And Link | if(rs < 0) {\\ RA = PC + 8; PC = offset\\ } | | + | | BLTZAL rs, target | Branch On Less Than Zero And Link | if(rs < 0) {\\ RA = PC + 8; PC = target\\ } | |
- | | BLTZALL rs, offset | Branch On Less Than Zero And Link Likely | if(rs < 0) {\\ RA = PC + 8; PC = offset\\ } | | + | | 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 ===== | ===== General Purpose Registers ===== | ||
- | ^ Number ^ Name ^ Preserved ^ Usage ^ | + | ^ Number ^ Name ^ Preserved ^ Purpose ^ |
- | | 0 | R0 | n/a | Hardwired zero | | + | | 0 | R0 | n/a | Hardwired zero | |
- | | 1 | AT | no | Assembler temporary value | | + | | 1 | AT | no | Assembler temporary value | |
- | | 2:3 | V0:V1 | no | Subroutine return value(s) | | + | | 2:3 | V0:V1 | no | Subroutine return value | |
- | | 4:7 | A0:A3 | no | Subroutine arguments | | + | | 4:7 | A0:A3 | no | Subroutine arguments | |
- | | 8:15 | T0:T7 | no | Temporary values | | + | | 8:15 | T0:T7 | no | Temporary values | |
- | | 16:23 | S0:S7 | yes | Saved values | | + | | 16:23 | S0:S7 | yes | Saved values | |
- | | 24:25 | T8:T9 | no | Temporary values | | + | | 24:25 | T8:T9 | no | Temporary values | |
- | | 26:27 | K0:K1 | n/a | Reserved by the kernel | | + | | 26:27 | K0:K1 | n/a | Reserved by the kernel | |
- | | 28 | GP | yes | Global pointer | | + | | 28 | GP | yes | Global pointer | |
- | | 29 | SP | yes | Stack pointer | | + | | 29 | SP | yes | Stack pointer | |
| 30 | S8 or FP | yes | Saved value or frame pointer | | | 30 | S8 or FP | yes | Saved value or frame pointer | | ||
- | | 31 | RA | yes | Return address | | + | | 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. | ||
---- | ---- | ||
- | ===== Memory Segments (32-bit) ===== | + | ===== Floating-point Registers (COP1) ===== |
- | ^ Virtual address range ^ Segment ^ Description ^ | + | ^ Number ^ Name ^ Preserved ^ Purpose ^ |
- | | 00000000:7FFFFFFF | useg | TLB mapped to physical memory\\ Accessible in all operating modes^ | + | | 0:2 | F0:F2 | no | Subroutine return value | |
- | | 80000000:9FFFFFFF | kseg0 | Cached, translated to physical address by subtracting 80000000\\ Accessible in kernel mode^ | + | | 4:10 | F4:F10 | no | Temporary values | |
- | | A0000000:BFFFFFFF | kseg1 | Uncached, translated to physical address by subtracting A0000000\\ Accessible in kernel mode^ | + | | 12:14 | F12:F14 | no | Subroutine arguments | |
- | | C0000000:DFFFFFFF | sseg | TLB mapped to physical memory\\ Accessible in kernel and supervisor mode^ | + | | 16:18 | F16:F18 | no | Temporary values | |
- | | E0000000:FFFFFFFF | kseg3 | TLB mapped to physical memory\\ Accessible in kernel mode^ | + | | 20:30 | F20:F30 | yes | Saved values | |
- | <color lightgreen>Note: Commercial Nintendo 64 games operate in kernel mode at all times.</color> | + | * 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 | | ||
---- | ---- | ||
Line 226: | Line 314: | ||
|RE |Reverse Endian in User mode (0: Disabled, 1: Reversed)| | |RE |Reverse Endian in User mode (0: Disabled, 1: Reversed)| | ||
|ITS |Enable instruction trace support (0: False, 1: True)| | |ITS |Enable instruction trace support (0: False, 1: True)| | ||
- | |BEV |Controls exception vector locations (0: Normal, 1: Bootstrap)| | + | |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.| | |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)| | |SR |Soft reset or NMI has occurred (0: False, 1: True)| | ||
Line 240: | Line 328: | ||
|EXL |Exception level (0: Normal, 1: Exception)| | |EXL |Exception level (0: Normal, 1: Exception)| | ||
|%%IE%% |Global interrupt enable (0: Disabled, 1: Enabled)| | |%%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 | | ||
---- | ---- | ||
Line 253: | Line 348: | ||
|BD |Branch delay (1: Last exception occurred in delay slot, 0: Normal)| | |BD |Branch delay (1: Last exception occurred in delay slot, 0: Normal)| | ||
|CE |Coprocessor number for coprocessor unusable exception| | |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| | + | |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| | |EXC |Exception code| | ||
- | ---- | + | ==== Exception Codes ==== |
- | ===== Exception Codes ===== | + | |
^Code ^Mnemonic ^Description^Generated...^ | ^Code ^Mnemonic ^Description^Generated...^ | ||
- | |0 |Int |Interrupt|- When one of the eight interrupt conditions are asserted| | + | |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)| | |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| | |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| | ||
Line 281: | Line 375: | ||
|24:31 |- |(Reserved)|| | |24:31 |- |(Reserved)|| | ||
- | ---- | + | ==== Interrupts ==== |
- | ===== Interrupts ===== | + | ^Cause bit^Source ^ |
- | ^Cause bit^Source ^<color lightgreen>N64 Implementation</color> ^ | + | |IP7 |Timer interrupt| |
- | |IP7 |Timer interrupt|<color lightgreen>n/a </color>| | + | |IP6 |Int4 pin <color lightgreen>(N64: RDB Write)</color>| |
- | |IP6 |Int4 pin |<color lightgreen>RDB Write </color>| | + | |IP5 |Int3 pin <color lightgreen>(N64: RDB Read)</color>| |
- | |IP5 |Int3 pin |<color lightgreen>RDB Read </color>| | + | |IP4 |Int2 pin <color lightgreen>(N64: Pre-NMI (Reset button))</color>| |
- | |IP4 |Int2 pin |<color lightgreen>Pre-NMI (Reset button)</color>| | + | |IP3 |Int1 pin <color lightgreen>(N64: Cartridge)</color>| |
- | |IP3 |Int1 pin |<color lightgreen>Cartridge </color>| | + | |IP2 |Int0 pin <color lightgreen>(N64: RCP)</color>| |
- | |IP2 |Int0 pin |<color lightgreen>RCP </color>| | + | |IP1 |Set by software| |
- | |IP1 |Set by software|<color lightgreen>n/a </color>| | + | |IP0 |Set by software| |
- | |IP0 |Set by software|<color lightgreen>n/a </color>| | + | |
+ | * The Timer interrupt (IP7) is generated when the Count and Compare registers are equal. | ||
+ | * Software interrupts (IP1:IP0) are generated when software manually sets the Cause register's IP1 or IP0 bit to 1 using an MTC0 instruction. | ||
+ | * Interrupts may be masked by setting the corresponding IM bits of the Status register to 0. | ||
- | 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. | ||
<color lightgreen> | <color lightgreen> | ||
- | 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). | + | On the Nintendo 64, IP2 represents an RCP (Reality Coprocessor) interrupt. When an RCP interrupt occurs, a flag representing the specific RCP interface is written to MI_INTR_REG (0x04300008). |
</color> | </color> | ||
^<color lightgreen>Bit</color>^<color lightgreen>Name</color>^<color lightgreen>Description</color>^ | ^<color lightgreen>Bit</color>^<color lightgreen>Name</color>^<color lightgreen>Description</color>^ | ||
Line 306: | Line 401: | ||
|<color lightgreen>0x10</color>|<color lightgreen>MI_INTR_PI</color>|<color lightgreen>Peripheral Interface - ROM to RAM DMA done</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>0x20</color>|<color lightgreen>MI_INTR_DP</color>|<color lightgreen>Display Processor - RDP processing done (gDPFullSync)</color>| | ||
+ | |||
<color lightgreen> | <color lightgreen> | ||
- | RCP-specific interrupts may be masked by setting the corresponding bits in MI_INTR_MASK_REG (0x0430000C) to 0. | + | RCP-specific interrupts may be masked or unmasked by writing one or more of the following values to MI_INTR_MASK_REG (0x0430000C). |
</color> | </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>Clear SP mask</color>| | ||
+ | |<color lightgreen>0x0002</color>|<color lightgreen>MI_INTR_MASK_SET_SP</color>|<color lightgreen>Set SP mask</color>| | ||
+ | |<color lightgreen>0x0004</color>|<color lightgreen>MI_INTR_MASK_CLR_SI</color>|<color lightgreen>Clear SI mask</color>| | ||
+ | |<color lightgreen>0x0008</color>|<color lightgreen>MI_INTR_MASK_SET_SI</color>|<color lightgreen>Set SI mask</color>| | ||
+ | |<color lightgreen>0x0010</color>|<color lightgreen>MI_INTR_MASK_CLR_AI</color>|<color lightgreen>Clear AI mask</color>| | ||
+ | |<color lightgreen>0x0020</color>|<color lightgreen>MI_INTR_MASK_SET_AI</color>|<color lightgreen>Set AI mask</color>| | ||
+ | |<color lightgreen>0x0040</color>|<color lightgreen>MI_INTR_MASK_CLR_VI</color>|<color lightgreen>Clear VI mask</color>| | ||
+ | |<color lightgreen>0x0080</color>|<color lightgreen>MI_INTR_MASK_SET_VI</color>|<color lightgreen>Set VI mask</color>| | ||
+ | |<color lightgreen>0x0100</color>|<color lightgreen>MI_INTR_MASK_CLR_PI</color>|<color lightgreen>Clear PI mask</color>| | ||
+ | |<color lightgreen>0x0200</color>|<color lightgreen>MI_INTR_MASK_SET_PI</color>|<color lightgreen>Set PI mask</color>| | ||
+ | |<color lightgreen>0x0400</color>|<color lightgreen>MI_INTR_MASK_CLR_DP</color>|<color lightgreen>Clear DP mask</color>| | ||
+ | |<color lightgreen>0x0800</color>|<color lightgreen>MI_INTR_MASK_SET_DP</color>|<color lightgreen>Set DP mask</color>| | ||
---- | ---- | ||
- | ===== Exception Vector Addresses ===== | + | ===== Memory Segments (32-bit) ===== |
- | ^Exception ^Base (BEV=0) ^Base (BEV=1) ^Offset^ | + | ^ Virtual address range ^ Segment ^ Description ^ |
- | |Reset & NMI |n/a |0xBFC000000 |0x000 | | + | | 00000000:7FFFFFFF | useg | TLB mapped to physical memory\\ Accessible in all operating modes^ |
- | |TLB Miss |0x80000000 |0xBFC000200 |0x000 | | + | | 80000000:9FFFFFFF | kseg0 | Cached, translated to physical address by subtracting 80000000\\ Accessible in kernel mode^ |
- | |XTLB Miss |0x80000000 |0xBFC000200 |0x080 | | + | | A0000000:BFFFFFFF | kseg1 | Uncached, translated to physical address by subtracting A0000000\\ Accessible in kernel mode^ |
- | |Other |0x80000000 |0xBFC000200 |0x180 | | + | | 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 ===== | ===== References ===== | ||
Line 324: | Line 437: | ||
* https://level42.ca/projects/ultra64/Documentation/man/pro-man/pro07/index7.8.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/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 | * https://github.com/n64dev/cen64/blob/72c778c3bfb25262498af6a21e8dec828a28be19/vr4300/interface.h#L16 | ||
+ | * http://ti.ira.uka.de/TI-2/Mips/Befehlssatz.pdf | ||