Skip to content

MIPS

Paper Mario runs on the Nintendo 64’s NEC VR4300 CPU. This page lists the native CPU, COP0, and COP1 instructions accepted by Star Rod Classic. It does not include pseudo-instructions or other Star Rod extensions; those are covered by the Assembly reference.

Instruction and register names are case-insensitive. The operand forms below use rd for a destination register, rs and rt for source registers, fd, fs, and ft for COP1 registers, sa for a shift amount, and offset(base) for a signed 16-bit displacement from a CPU register.

The VR4300 has 32 general-purpose 64-bit registers. Paper Mario normally uses 32-bit values and follows the usual MIPS calling convention.

NumberNameConventional use
0R0Constant read-only zero.
1ATAssembler temporary, do not use. Reserved for pseudo-instructions.
2–3V0, V1Function return values and temporary values.
4–7A0A3Function arguments.
8–15T0T7Caller-saved temporary values.
16–23S0S7Callee-saved values.
24–25T8, T9Caller-saved temporary values.
26–27K0, K1Reserved for exception handling.
28GPGlobal pointer. Do not use.
29SPStack pointer.
30S8 / FPCallee-saved value or frame pointer. FP is an alias accepted by Classic.
31RAReturn address written by link instructions.

HI and LO are separate result registers used by integer multiplication and division. Access them with MFHI, MFLO, MTHI, and MTLO.

COP1 provides 32 floating-point registers named F0 through F31. Single-precision operations use one register. Double-precision values use an even-numbered register together with the following odd-numbered register.

The calling convention uses F0 and F2 for results, F12 and F14 for arguments, F20 through F31 as callee-saved registers, and the remaining registers as temporaries. Native functions must preserve the saved registers they modify.

Every jump and branch has one delay slot. The instruction following an ordinary branch executes whether or not the branch is taken. A branch-likely instruction ending in L executes its delay slot only when the branch is taken.

InstructionMeaning
BEQ rs, rt, labelBranch if the registers are equal.
BNE rs, rt, labelBranch if the registers are not equal.
BLEZ rs, labelBranch if rs is less than or equal to zero.
BGTZ rs, labelBranch if rs is greater than zero.
BLTZ rs, labelBranch if rs is less than zero.
BGEZ rs, labelBranch if rs is greater than or equal to zero.
BEQL, BNEL, BLEZL, BGTZL, BLTZL, BGEZLBranch-likely forms of the corresponding instructions.
BLTZAL rs, labelBranch if negative and place the return address in RA.
BGEZAL rs, labelBranch if nonnegative and place the return address in RA.
BLTZALL, BGEZALLBranch-likely forms of the corresponding link instructions.
J targetJump to an address in the current 256 MB region.
JAL targetJump and place the return address in RA.
JR rsJump to the address in rs.
JALR rs, rdJump to the address in rs and place the return address in rd. This is Classic’s operand order.

The instructions beginning with D operate on 64-bit values. ADD, SUB, and their immediate forms trap on signed overflow; the instructions ending in U do not.

InstructionMeaning
ADD rd, rs, rtSigned 32-bit addition.
ADDU rd, rs, rt32-bit addition without an overflow trap.
SUB rd, rs, rtSigned 32-bit subtraction.
SUBU rd, rs, rt32-bit subtraction without an overflow trap.
DADD rd, rs, rtSigned 64-bit addition.
DADDU rd, rs, rt64-bit addition without an overflow trap.
DSUB rd, rs, rtSigned 64-bit subtraction.
DSUBU rd, rs, rt64-bit subtraction without an overflow trap.
ADDI rt, rs, immediateAdd a sign-extended 16-bit immediate with overflow checking.
ADDIU rt, rs, immediateAdd a sign-extended 16-bit immediate without an overflow trap.
DADDI rt, rs, immediate64-bit immediate addition with overflow checking.
DADDIU rt, rs, immediate64-bit immediate addition without an overflow trap.
AND rd, rs, rtBitwise AND.
OR rd, rs, rtBitwise OR.
XOR rd, rs, rtBitwise exclusive OR.
NOR rd, rs, rtBitwise NOR.
ANDI rt, rs, immediateAND with a zero-extended 16-bit immediate.
ORI rt, rs, immediateOR with a zero-extended 16-bit immediate.
XORI rt, rs, immediateExclusive OR with a zero-extended 16-bit immediate.
LUI rt, immediatePlace a 16-bit immediate in bits 16–31 and clear the low half.
SLT rd, rs, rtSet rd to one if signed rs < rt; otherwise set it to zero.
SLTU rd, rs, rtUnsigned form of SLT.
SLTI rt, rs, immediateCompare rs with a sign-extended immediate as signed values.
SLTIU rt, rs, immediateCompare as unsigned values after sign-extending the immediate.
InstructionMeaning
SLL rd, rt, saShift a 32-bit value left by sa.
SRL rd, rt, saLogical 32-bit right shift.
SRA rd, rt, saArithmetic 32-bit right shift.
SLLV rd, rt, rsShift left by the low five bits of rs.
SRLV rd, rt, rsLogical right shift by the low five bits of rs.
SRAV rd, rt, rsArithmetic right shift by the low five bits of rs.
DSLL rd, rt, saShift a 64-bit value left by sa.
DSRL rd, rt, saLogical 64-bit right shift.
DSRA rd, rt, saArithmetic 64-bit right shift.
DSLL32 rd, rt, saShift a 64-bit value left by sa + 32.
DSRL32 rd, rt, saLogical 64-bit right shift by sa + 32.
DSRA32 rd, rt, saArithmetic 64-bit right shift by sa + 32.
DSLLV rd, rt, rsShift left by the low six bits of rs.
DSRLV rd, rt, rsLogical right shift by the low six bits of rs.
DSRAV rd, rt, rsArithmetic right shift by the low six bits of rs.

These instructions write HI and LO. Division places the quotient in LO and the remainder in HI.

InstructionOperandsMeaning
MULTrs, rtSigned 32-bit multiplication.
MULTUrs, rtUnsigned 32-bit multiplication.
DMULTrs, rtSigned 64-bit multiplication.
DMULTUrs, rtUnsigned 64-bit multiplication.
DIVrs, rtSigned 32-bit division.
DIVUrs, rtUnsigned 32-bit division.
DDIVrs, rtSigned 64-bit division.
DDIVUrs, rtUnsigned 64-bit division.
MFHIrdCopy HI to a CPU register.
MFLOrdCopy LO to a CPU register.
MTHIrsCopy a CPU register to HI.
MTLOrsCopy a CPU register to LO.

Multiplication and division can take several cycles. If MFHI or MFLO is reached before the operation is complete, the processor stalls until the result is ready; no manual delay is required before reading it. However, two intervening instructions are required after reading HI or LO before that register may be written again. After MFHI, place at least two other instructions before another multiply or divide or an MTHI. After MFLO, do the same before another multiply or divide or an MTLO.

InstructionMeaning
LB rt, offset(base)Load and sign-extend a byte.
LBU rt, offset(base)Load and zero-extend a byte.
LH rt, offset(base)Load and sign-extend a half-word.
LHU rt, offset(base)Load and zero-extend a half-word.
LW rt, offset(base)Load and sign-extend a word.
LWU rt, offset(base)Load and zero-extend a word.
LD rt, offset(base)Load a doubleword.
SB rt, offset(base)Store a byte.
SH rt, offset(base)Store a half-word.
SW rt, offset(base)Store a word.
SD rt, offset(base)Store a doubleword.
LWL, LWRMerge the left or right part of an unaligned word into rt.
SWL, SWRStore the left or right part of an unaligned word.
LDL, LDRMerge the left or right part of an unaligned doubleword into rt.
SDL, SDRStore the left or right part of an unaligned doubleword.
LL rt, offset(base)Load-linked word.
SC rt, offset(base)Store-conditional word and write its success result to rt.
LLD rt, offset(base)Load-linked doubleword.
SCD rt, offset(base)Store-conditional doubleword and write its success result to rt.
LWC1 ft, offset(base)Load a word into a COP1 register.
LDC1 ft, offset(base)Load a doubleword into a COP1 register pair.
SWC1 ft, offset(base)Store a word from a COP1 register.
SDC1 ft, offset(base)Store a doubleword from a COP1 register pair.

The suffix describes the operand format: .S is a single-precision float, .D is a double, .W is a signed 32-bit integer, and .L is a signed 64-bit integer held in COP1 registers.

FormMeaning
ADD.S fd, fs, ft / ADD.D fd, fs, ftFloating-point addition.
SUB.S fd, fs, ft / SUB.D fd, fs, ftFloating-point subtraction.
MUL.S fd, fs, ft / MUL.D fd, fs, ftFloating-point multiplication.
DIV.S fd, fs, ft / DIV.D fd, fs, ftFloating-point division.
SQRT.S fd, fs / SQRT.D fd, fsSquare root.
ABS.S fd, fs / ABS.D fd, fsAbsolute value.
MOV.S fd, fs / MOV.D fd, fsCopy a floating-point value.
NEG.S fd, fs / NEG.D fd, fsNegate a floating-point value.
ROUND.W.S fd, fs / ROUND.W.D fd, fsRound to a 32-bit integer.
TRUNC.W.S fd, fs / TRUNC.W.D fd, fsTruncate to a 32-bit integer.
CEIL.W.S fd, fs / CEIL.W.D fd, fsRound upward to a 32-bit integer.
FLOOR.W.S fd, fs / FLOOR.W.D fd, fsRound downward to a 32-bit integer.
ROUND.L.S fd, fs / ROUND.L.D fd, fsRound to a 64-bit integer.
TRUNC.L.S fd, fs / TRUNC.L.D fd, fsTruncate to a 64-bit integer.
CEIL.L.S fd, fs / CEIL.L.D fd, fsRound upward to a 64-bit integer.
FLOOR.L.S fd, fs / FLOOR.L.D fd, fsRound downward to a 64-bit integer.
CVT.S.D/W/L fd, fsConvert a double, word, or long to single precision.
CVT.D.S/W/L fd, fsConvert a single, word, or long to double precision.
CVT.W.S/D fd, fsConvert a float or double to a 32-bit integer using the current rounding mode.
CVT.L.S/D fd, fsConvert a float or double to a 64-bit integer using the current rounding mode.
InstructionMeaning
MFC1 rt, fsMove a 32-bit word from COP1 to a CPU register.
MTC1 rt, fsMove a 32-bit word from a CPU register to COP1.
DMFC1 rt, fsMove a 64-bit value from a COP1 register pair.
DMTC1 rt, fsMove a 64-bit value to a COP1 register pair.
CFC1 rt, fsMove a COP1 control register to a CPU register.
CTC1 rt, fsMove a CPU register to a COP1 control register.
BC1F labelBranch when floating-point condition 0 is false.
BC1T labelBranch when floating-point condition 0 is true.
BC1FL labelBranch-likely when the condition is false.
BC1TL labelBranch-likely when the condition is true.

Comparisons use C.condition.S fs, ft or C.condition.D fs, ft and write floating-point condition 0.

ConditionTest
FFalse.
UNUnordered.
EQEqual.
UEQUnordered or equal.
OLTOrdered and less than.
ULTUnordered or less than.
OLEOrdered and less than or equal.
ULEUnordered or less than or equal.
SF, NGLE, SEQ, NGL, LT, NGE, LE, NGTSignaling forms of the corresponding false, unordered, equal, less-than, and less-than-or-equal tests.