This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| 
                    r4300 [2019/02/07 20:38] shygoo add cop0 status/cause info, exception info  | 
                
                    r4300 [2019/05/06 17:54] (current) shygoo [Interrupts] clarify MI_INTR_MASK_REG usage  | 
            ||
|---|---|---|---|
| Line 5: | Line 5: | ||
| * R43XX User manual: https://hack64.net/docs/VR43XX.pdf | * R43XX User manual: https://hack64.net/docs/VR43XX.pdf | ||
| * R4300i Product info: http://datasheets.chipdb.org/MIPS/R4300i_datasheet.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 ===== | ===== 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 23: | 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 36: | 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 64: | 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 | %% 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  %% | | 
| - | | 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  | | 
| + | |||
| + | * 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]] | | ||
| - | Note: Commercial Nintendo 64 games operate in kernel mode at all times. | + | * 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 228: | 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 242: | 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 255: | 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^ | + | |0 |Int  |[[r4300#Interrupts|Interrupt]]|- When one of the eight interrupt conditions are asserted| | 
| - | |0 |Int  |Interrupt| | + | |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| | + | |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 Miss exception (load or instruction fetch)| | + | |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| | 
| - | |3 |TLBS  |TLB Miss exception (store)| | + | |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)| | 
| - | |4 |AdEl |Address Error exception (load or instruction fetch)| | + | |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)| | 
| - | |5 |AdES  |Address Error exception (store)| | + | |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| | 
| - | |6 |IBE  |Bus Error exception (instruction fetch)| | + | |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| | 
| - | |7 |DBE  |Bus Error exception (data reference: load or store)| | + | |6 |IBE  |Bus Error exception (instruction fetch)|| | 
| - | |8 |Sys  |Syscall exception| | + | |7 |DBE  |Bus Error exception (data reference: load or store)|| | 
| - | |9 |Bp  |Breakpoint exception| | + | |8 |Sys  |Syscall exception|- When a SYSCALL instruction is executed| | 
| - | |10 |RI |Reserved instruction exception| | + | |9 |Bp  |Breakpoint exception|- When a BREAK instruction is executed| | 
| - | |11 |CpU |Coprocessor unusable exception| | + | |10 |RI |Reserved instruction exception|- When an attempt is made to execute a reserved/nonexistant command| | 
| - | |12 |Ov |Arithmetic overflow exception| | + | |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| | 
| - | |13 |Tr |Trap exception| | + | |12 |Ov |Arithmetic overflow exception|- When an ADD, ADDI, SUB, DADD, DADDI or DSUB instruction results in a 2's complement overflow| | 
| - | |14 |- |(Reserved)| | + | |13 |Tr |Trap exception|- When a trap instruction results in a TRUE condition| | 
| - | |15 |FPE |Floating-point exception| | + | |14 |- |(Reserved)|| | 
| - | |16:22 |- |(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)| | 
| - | |23 |WATCH  |Watch exception| | + | |16:22 |- |(Reserved)|| | 
| - | |24:31 |- |(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>| | ||
| ---- | ---- | ||
| - | ===== 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 ===== | ||
| * http://hack64.net/docs/VR43XX.pdf | * http://hack64.net/docs/VR43XX.pdf | ||
| * http://datasheets.chipdb.org/MIPS/R4300i_datasheet.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 | ||