Introduction
Coprocessor 1 is the floating-point unit: opcode 17 (COP1) plus the loads and stores in Loads and stores. The PlayStation's R3000A has none (a COP1 word is not in this ISA there); the Nintendo 64's VR4300 has one with single and double precision. The register file is 32 bits wide in MIPS I and II and 64 bits from MIPS III.
Most operations name a format after the mnemonic: .s single, .d double,
.w a 32-bit integer, .l a 64-bit integer, .ps a pair of singles. The format is the
fmt field, bits 25–21: 16 s, 17 d, 20 w, 21 l, 22 ps. Each row below stands for the formats it lists, and
each of them has an entry in the explorer's links.
Nintendo 64 notes. The VR4300's FPU is a MIPS III FPU, so it has the single and double formats and the .w and .l conversions, and no paired single or multiply-add. As on other MIPS FPUs, a denormal operand or result can raise the unimplemented-operation exception for software to handle. The status bit FR picks 16 or 32 double registers. The VR4300 user's manual was not read for this page, so the chip's own exception rules are not described.
Moves between the register files
| Instruction | Encoding | ISA | What it does |
|---|---|---|---|
mfc1 rt, fs | 010001 00000 rt fs 0 | MIPS I | Copy the low 32 bits of fs to rt (a load delay slot on MIPS I). |
dmfc1 rt, fs | 010001 00001 rt fs 0 | MIPS III | Copy all 64 bits. |
cfc1 rt, fs | 010001 00010 rt fs 0 | MIPS I | Copy a control register ($0 revision, $31 status, and the others) to rt. |
mfhc1 rt, fs | 010001 00011 rt fs 0 | Release 2 | Copy the high 32 bits of fs (the upper half of a double in a 32-bit register file view). |
mtc1 rt, fs | 010001 00100 rt fs 0 | MIPS I | Copy rt to the low half of fs. mtc1 $0, $f0 clears a float. |
dmtc1 rt, fs | 010001 00101 rt fs 0 | MIPS III | Copy all 64 bits. |
ctc1 rt, fs | 010001 00110 rt fs 0 | MIPS I | Write a control register, for example the rounding mode in $31. |
mthc1 rt, fs | 010001 00111 rt fs 0 | Release 2 | Write the high half. |
Arithmetic and moves
Encoding: 010001 fmt ft fs fd function.
| Instruction | Function | Formats | ISA | What it does |
|---|---|---|---|---|
add.fmt fd, fs, ft | 000000 | s d ps | MIPS I | Add. |
sub.fmt fd, fs, ft | 000001 | s d ps | MIPS I | Subtract. |
mul.fmt fd, fs, ft | 000010 | s d ps | MIPS I | Multiply. |
div.fmt fd, fs, ft | 000011 | s d | MIPS I | Divide. |
sqrt.fmt fd, fs | 000100 | s d | MIPS II | Square root. |
abs.fmt fd, fs | 000101 | s d ps | MIPS I | Absolute value. |
mov.fmt fd, fs | 000110 | s d ps | MIPS I | Copy. |
neg.fmt fd, fs | 000111 | s d ps | MIPS I | Negate. |
recip.fmt fd, fs | 010101 | s d | MIPS IV, Release 2 | Reciprocal (approximate precision). |
rsqrt.fmt fd, fs | 010110 | s d | MIPS IV, Release 2 | Reciprocal square root. |
movf.fmt fd, fs, cc | 010001, bit 16 = 0 | s d ps | MIPS IV (not R6) | Move if condition code cc is false. |
movt.fmt fd, fs, cc | 010001, bit 16 = 1 | s d ps | MIPS IV (not R6) | Move if condition code cc is true. |
movz.fmt fd, fs, rt | 010010 | s d ps | MIPS IV (not R6) | Move if the integer register rt is zero. |
movn.fmt fd, fs, rt | 010011 | s d ps | MIPS IV (not R6) | Move if rt is not zero. |
Conversions and rounding
The .w and .l results are integers held in a floating-point register. cvt uses the rounding mode in the control register;
round, trunc, ceil and floor force one: to nearest even, toward zero, up, down.
| Instruction | Function | Source formats | ISA | What it does |
|---|---|---|---|---|
round.w.fmt fd, fs | 001100 | s d | MIPS II | To a 32-bit integer, nearest even. |
trunc.w.fmt fd, fs | 001101 | s d | MIPS II | To a 32-bit integer, toward zero (what a C cast does). |
ceil.w.fmt fd, fs | 001110 | s d | MIPS II | To a 32-bit integer, up. |
floor.w.fmt fd, fs | 001111 | s d | MIPS II | To a 32-bit integer, down. |
round.l.fmt fd, fs | 001000 | s d | MIPS III | To a 64-bit integer, nearest even. |
trunc.l.fmt fd, fs | 001001 | s d | MIPS III | To a 64-bit integer, toward zero. |
ceil.l.fmt fd, fs | 001010 | s d | MIPS III | To a 64-bit integer, up. |
floor.l.fmt fd, fs | 001011 | s d | MIPS III | To a 64-bit integer, down. |
cvt.s.fmt fd, fs | 100000 | d w l | MIPS I (l: MIPS III) | Convert to single. |
cvt.d.fmt fd, fs | 100001 | s w l | MIPS I (l: MIPS III) | Convert to double. |
cvt.w.fmt fd, fs | 100100 | s d | MIPS I | To a 32-bit integer in the current rounding mode. |
cvt.l.fmt fd, fs | 100101 | s d | MIPS III | To a 64-bit integer in the current rounding mode. |
Comparisons
c.cond.fmt [cc,] fs, ft compares and sets one bit, the condition flag (MIPS IV: one of eight condition codes $fcc0 to $fcc7), which
bc1t, bc1f and the conditional moves test. Encoding: 010001 fmt ft fs cc 0 0 11 cond. The sixteen conditions: bit 3 of
cond says whether an unordered operand (a NaN) also raises an invalid-operation exception.
| cond | 0 f | 1 un | 2 eq | 3 ueq | 4 olt | 5 ult | 6 ole | 7 ule |
|---|---|---|---|---|---|---|---|---|
| true if | never | unordered | equal | unordered or equal | less than (ordered) | unordered or less than | less or equal (ordered) | unordered or less or equal |
| cond + 8 | 8 sf | 9 ngle | 10 seq | 11 ngl | 12 lt | 13 nge | 14 le | 15 ngt |
| Instruction | Formats | ISA | What it does |
|---|---|---|---|
c.cond.fmt [cc,] fs, ft | s d ps | MIPS I (cc: MIPS IV) (not R6) | The 16 comparisons above, 3 formats: 48 mnemonics such as c.eq.s, c.lt.d, c.ule.s. |
Paired single
A register holds two singles. These exist in MIPS V, MIPS64 and MIPS32 Release 2 with a 64-bit FPU. llvm has none of them, so they have no second check.
| Instruction | Encoding | What it does |
|---|---|---|
cvt.ps.s fd, fs, ft | 010001 s ft fs fd 100110 | Pack fs (upper) and ft (lower) into a pair. |
cvt.s.pu fd, fs | 010001 ps 0 fs fd 100000 | The upper single of a pair. |
cvt.s.pl fd, fs | 010001 ps 0 fs fd 101000 | The lower single of a pair. |
pll.ps fd, fs, ft | 010001 ps ft fs fd 101100 | Lower of fs, lower of ft. |
plu.ps fd, fs, ft | 010001 ps ft fs fd 101101 | Lower of fs, upper of ft. |
pul.ps fd, fs, ft | 010001 ps ft fs fd 101110 | Upper of fs, lower of ft. |
puu.ps fd, fs, ft | 010001 ps ft fs fd 101111 | Upper of fs, upper of ft. |
alnv.ps fd, fs, ft, rs | 010011 rs ft fs fd 011110 | Align a variable pair: select two adjacent singles from fs:ft by the low bits of rs. |
COP1X: multiply-add and prefetch
Opcode 19 (MIPS IV and MIPS32 Release 2, removed in Release 6, which has maddf and msubf instead). Encoding: 010011 fr ft fs fd function, function = operation (100 madd, 101 msub, 110 nmadd, 111 nmsub) and a three-bit format (000 s, 001 d, 110 ps).
The indexed loads and stores are on the loads and stores page.
| Instruction | What it does |
|---|---|
madd.s fd, fr, fs, ft | fd = fs × ft + fr, with a single rounding. |
madd.d | The same in double. |
madd.ps | The same on both halves. |
msub.s fd, fr, fs, ft | fd = fs × ft − fr. |
msub.d | Double. |
msub.ps | Paired single. |
nmadd.s fd, fr, fs, ft | fd = −(fs × ft + fr). |
nmadd.d | Double. |
nmadd.ps | Paired single. |
nmsub.s fd, fr, fs, ft | fd = −(fs × ft − fr). |
nmsub.d | Double. |
nmsub.ps | Paired single. |
prefx hint, index(base) | Prefetch hint with a register index (010011 base index hint 0 001111). llvm does not decode it. |
Release 6
Release 6 removes the condition flag, the conditional moves and the multiply-adds above (and the paired single) and replaces them. It requires a 64-bit FPU and has the .l formats.
| Instruction | Function | Formats | What it does |
|---|---|---|---|
cmp.cond.fmt fd, fs, ft | 0 cond5 with fmt 20 (s) or 21 (d) | s d | Compare into fd as all ones or all zeros. The conditions: af, un, eq, ueq, lt, ult, le, ule, saf, sun, seq, sueq, slt, sult, sle, sule (0 to 15) and or, une, ne (17 to 19), sor, sune, sne (25 to 27). llvm lacks the last six. |
sel.fmt fd, fs, ft | 010000 | s d | fd = bit 0 of fd ? ft : fs. |
seleqz.fmt fd, fs, ft | 010100 | s d | fd = bit 0 of ft ? 0 : fs. |
selnez.fmt fd, fs, ft | 010111 | s d | fd = bit 0 of ft ? fs : 0. |
maddf.fmt fd, fs, ft | 011000 | s d | Fused fd = fd + fs × ft. |
msubf.fmt fd, fs, ft | 011001 | s d | Fused fd = fd − fs × ft. |
rint.fmt fd, fs | 011010 | s d | Round to an integral value in the current rounding mode. |
class.fmt fd, fs | 011011 | s d | A mask of the classes (NaN, infinity, zero, normal, subnormal, signs) of fs. |
min.fmt fd, fs, ft | 011100 | s d | The smaller. |
mina.fmt fd, fs, ft | 011101 | s d | The one with the smaller absolute value. |
max.fmt fd, fs, ft | 011110 | s d | The larger. |
maxa.fmt fd, fs, ft | 011111 | s d | The one with the larger absolute value. |
Not described
Known, not yet covered
- Reference: the FCSR bit layout in full (cause, enable and flag bits per exception), the 2008 NaN and abs modes (
NAN2008,ABS2008), and the FPXX and FP64A ABI details. - Reference: the MIPS-3D ASE instructions (
addr.psand others) and the exact precision ofrecipandrsqrt.
Unknown
- Reference: which operations the VR4300 FPU leaves to the software emulator beyond denormals, as the data sheet is the only source and it was not read for this page.