General registers
There are 32 general registers, $0 to $31. They are 32 bits wide in MIPS I, II and
MIPS32 and 64 bits wide from MIPS III and in MIPS64. $0 always reads as zero and ignores writes. The
assembler names depend on the ABI; the explorer's register-name option picks numbers, the o32 names, or the n32 and n64 names.
| Number | o32 | n32, n64 | Use by convention |
|---|---|---|---|
$0 | $zero | $zero | Always zero. |
$1 | $at | $at | Reserved for the assembler, which uses it to build pseudo-instructions. |
$2, $3 | $v0, $v1 | $v0, $v1 | Function results. |
$4 to $7 | $a0 to $a3 | $a0 to $a3 | The first four arguments. |
$8 to $11 | $t0 to $t3 | $a4 to $a7 | o32: temporaries. n32 and n64: arguments five to eight. |
$12 to $15 | $t4 to $t7 | $t0 to $t3 | Temporaries (not preserved by a call). |
$16 to $23 | $s0 to $s7 | $s0 to $s7 | Saved registers (preserved by a call). |
$24, $25 | $t8, $t9 | $t8, $t9 | Temporaries; $t9 holds the address of the called function in position-independent code (also written $pic). |
$26, $27 | $k0, $k1 | $k0, $k1 | Reserved for the operating system kernel (exception handlers). |
$28 | $gp | $gp | The global pointer. |
$29 | $sp | $sp | The stack pointer. |
$30 | $fp (or $s8) | $fp (or $s8) | The frame pointer, or a ninth saved register. |
$31 | $ra | $ra | The return address: JAL, BAL and JALR write it. |
The ABIs: o32 is the original 32-bit ABI, which passes four arguments in registers; n32 and
n64 pass eight and use 64-bit registers (n32 with 32-bit pointers); o64 and EABI are rarer.
An ELF file says which it uses in e_flags.
HI and LO
Two more registers receive the result of multiplication and division before Release 6: mult and
multu put the 64-bit product in HI:LO, and div and divu put the quotient in LO and the
remainder in HI. mfhi, mflo, mthi and mtlo move them. On MIPS I a
second multiply or divide must not start while one is running (the manual says the result is undefined if HI or LO is read
too early; the PlayStation CPU stalls instead). Release 6 removes HI and LO: mul, muh,
div and mod write a general register.
Floating-point registers
Coprocessor 1 has 32 floating-point registers $f0 to $f31. In MIPS I and II they are 32 bits wide, and a double
uses an even-odd pair. From MIPS III, and in MIPS32 and MIPS64 when the status bit FR is set, they are 64 bits wide and each holds
a double. The control registers are read with cfc1 and written with ctc1:
$0 the implementation and revision, $25 the condition codes (FCCR), $26 the exception bits (FEXR),
$28 the enables (FENR) and $31 the control and status register (FCSR) with the rounding mode, flags and the
condition codes. The condition bit tested by bc1t and bc1f is bit 23 of FCSR, with seven more in bits 25 to 31
from MIPS IV. A register number that an instruction field holds is shown as $f0 to $f31, the condition code as
$fcc0 to $fcc7.
Coprocessor 0 registers
Coprocessor 0 registers are numbered 0 to 31 with a select value 0 to 7 from MIPS32. The explorer writes
mfc0 $v0, $12, 0; its detail line names the register. The common ones are on the system control page.
The PlayStation's coprocessor 0 has different registers; they are listed there too.
Not described
Known, not yet covered
- Reference: the full call sequences of each ABI (stack frame layout, the argument registers for floating-point and structure arguments, and the o32 FP64 variants), which belong to a compiler reference, not to an instruction set.
- Reference: the shadow register sets of MIPS32 Release 2 (
rdpgprandwrpgprare decoded).
Unknown
- Reference: none known.