Introduction
The Nintendo GameCube's Gekko and the Wii's Broadway are PowerPC 750 cores with an added set of paired-single instructions and a locked
cache. A paired single treats a 64-bit floating-point register as two 32-bit single-precision values, slot 0 (ps0, the same value an ordinary
floating-point instruction sees) and slot 1 (ps1). One instruction then does two single-precision operations, which is how these consoles do
their vertex and matrix arithmetic. The quantized loads and stores (psq_l, psq_st) convert between pairs of integers or singles in memory and
the registers, under the control of the eight graphics quantization registers. Broadway runs the same instruction set as Gekko at a higher clock.
These instructions use primary opcode 4, which is also the AltiVec opcode, and opcodes 56, 57, 60 and 61, which the later Power ISA gives to other instructions.
A processor has one set or the other, so the explorer decodes the paired singles only for the Gekko and Broadway models. Every record form (a dotted mnemonic, such as
ps_add.) copies the floating-point exception summary bits to CR1, as the other floating-point instructions do.
The paired singles need the paired single enable and the quantized load and store enable bits of HID2 to be set; the bit positions are not described here.
The graphics quantization registers
The eight registers GQR0 to GQR7 are the special-purpose registers 912 to 919, supervisor registers read and written with mfspr and
mtspr. The I field of a quantized load or store picks one. Each register has four fields (bits numbered from the most significant end, as in the manual):
| Field | Bits | Meaning |
|---|---|---|
LD_SCALE | 2 to 7 | Scale of a load: the loaded integers are multiplied by 2 to the power of minus the (signed) scale. |
LD_TYPE | 13 to 15 | Type of a load. |
ST_SCALE | 18 to 23 | Scale of a store: the values are multiplied by 2 to the power of the (signed) scale before they are converted. |
ST_TYPE | 29 to 31 | Type of a store. |
The types: 0 is a single-precision float (the scale is ignored), 4 is an unsigned 8-bit integer, 5 an unsigned 16-bit integer, 6 a signed 8-bit integer and 7 a signed
16-bit integer. The other values are reserved. The W bit of the instruction chooses between a pair (W = 0) and a single value (W = 1;
a load then sets ps1 to 1.0). The registers HID2 (920), WPAR (921), DMA_U (922) and DMA_L (923) belong to the same
extension: the write-gather pipe address and the direct memory access to and from the locked cache.
The instructions
Slots are written ps0 and ps1. The “form” of the quantized loads and stores is the D form with a 12-bit displacement, with the W bit and
the 3-bit I field in the place of the low bits of a 16-bit displacement.
Quantized loads and stores
| Mnemonic | Operands | Form and opcode | Available in | What it does |
|---|---|---|---|---|
psq_l | frt, d(ra), w, i | D-like 56 | Gekko, Broadway | Paired-single quantized load: two values, converted from the format the graphics quantization register GQR[I] says. |
psq_lu | frt, d(ra), w, i | D-like 57 | Gekko, Broadway | Paired-single quantized load with update. |
psq_st | frs, d(ra), w, i | D-like 60 | Gekko, Broadway | Paired-single quantized store: convert to the format GQR[I] says and store. |
psq_stu | frs, d(ra), w, i | D-like 61 | Gekko, Broadway | Paired-single quantized store with update. |
psq_lx | frt, ra, rb, w, i | X-like 4/6 | Gekko, Broadway | Paired-single quantized load indexed. |
psq_stx | frs, ra, rb, w, i | X-like 4/7 | Gekko, Broadway | Paired-single quantized store indexed. |
psq_lux | frt, ra, rb, w, i | X-like 4/38 | Gekko, Broadway | Paired-single quantized load with update indexed. |
psq_stux | frs, ra, rb, w, i | X-like 4/39 | Gekko, Broadway | Paired-single quantized store with update indexed. |
Arithmetic
| Mnemonic | Operands | Form and opcode | Available in | What it does |
|---|---|---|---|---|
ps_div, ps_div. | frt, fra, frb | A 4/18 | Gekko, Broadway | Paired-single divide. |
ps_sub, ps_sub. | frt, fra, frb | A 4/20 | Gekko, Broadway | Paired-single subtract. |
ps_add, ps_add. | frt, fra, frb | A 4/21 | Gekko, Broadway | Paired-single add. |
ps_sel, ps_sel. | frt, fra, frc, frb | A 4/23 | Gekko, Broadway | Paired-single select: frc where fra >= 0, else frb, in each slot. |
ps_res, ps_res. | frt, frb | A 4/24 | Gekko, Broadway | Paired-single reciprocal estimate. |
ps_mul, ps_mul. | frt, fra, frc | A 4/25 | Gekko, Broadway | Paired-single multiply. |
ps_rsqrte, ps_rsqrte. | frt, frb | A 4/26 | Gekko, Broadway | Paired-single reciprocal square root estimate. |
ps_msub, ps_msub. | frt, fra, frc, frb | A 4/28 | Gekko, Broadway | Paired-single multiply-subtract. |
ps_madd, ps_madd. | frt, fra, frc, frb | A 4/29 | Gekko, Broadway | Paired-single multiply-add. |
ps_nmsub, ps_nmsub. | frt, fra, frc, frb | A 4/30 | Gekko, Broadway | Paired-single negative multiply-subtract. |
ps_nmadd, ps_nmadd. | frt, fra, frc, frb | A 4/31 | Gekko, Broadway | Paired-single negative multiply-add. |
ps_sum0, ps_sum0. | frt, fra, frc, frb | A 4/10 | Gekko, Broadway | Paired-single vector sum high: slot 0 = fra[0] + frb[1], slot 1 = frc[1]. |
ps_sum1, ps_sum1. | frt, fra, frc, frb | A 4/11 | Gekko, Broadway | Paired-single vector sum low: slot 0 = frc[0], slot 1 = fra[0] + frb[1]. |
ps_muls0, ps_muls0. | frt, fra, frc | A 4/12 | Gekko, Broadway | Paired-single multiply scalar high: both slots times frc[0]. |
ps_muls1, ps_muls1. | frt, fra, frc | A 4/13 | Gekko, Broadway | Paired-single multiply scalar low: both slots times frc[1]. |
ps_madds0, ps_madds0. | frt, fra, frc, frb | A 4/14 | Gekko, Broadway | Paired-single multiply-add scalar high. |
ps_madds1, ps_madds1. | frt, fra, frc, frb | A 4/15 | Gekko, Broadway | Paired-single multiply-add scalar low. |
Compare, move and merge
| Mnemonic | Operands | Form and opcode | Available in | What it does |
|---|---|---|---|---|
ps_cmpu0 | bf, fra, frb | X 4/0 | Gekko, Broadway | Paired-single compare unordered high. |
ps_cmpo0 | bf, fra, frb | X 4/32 | Gekko, Broadway | Paired-single compare ordered high. |
ps_cmpu1 | bf, fra, frb | X 4/64 | Gekko, Broadway | Paired-single compare unordered low. |
ps_cmpo1 | bf, fra, frb | X 4/96 | Gekko, Broadway | Paired-single compare ordered low. |
ps_neg, ps_neg. | frt, frb | X 4/40 | Gekko, Broadway | Paired-single negate. |
ps_mr, ps_mr. | frt, frb | X 4/72 | Gekko, Broadway | Paired-single move register. |
ps_nabs, ps_nabs. | frt, frb | X 4/136 | Gekko, Broadway | Paired-single negative absolute value. |
ps_abs, ps_abs. | frt, frb | X 4/264 | Gekko, Broadway | Paired-single absolute value. |
ps_merge00, ps_merge00. | frt, fra, frb | X 4/528 | Gekko, Broadway | Paired-single merge high: (fra[0], frb[0]). |
ps_merge01, ps_merge01. | frt, fra, frb | X 4/560 | Gekko, Broadway | Paired-single merge direct: (fra[0], frb[1]). |
ps_merge10, ps_merge10. | frt, fra, frb | X 4/592 | Gekko, Broadway | Paired-single merge swapped: (fra[1], frb[0]). |
ps_merge11, ps_merge11. | frt, fra, frb | X 4/624 | Gekko, Broadway | Paired-single merge low: (fra[1], frb[1]). |
Locked cache
| Mnemonic | Operands | Form and opcode | Available in | What it does |
|---|---|---|---|---|
dcbz_l | ra, rb | X 4/1014 | Gekko, Broadway | Data cache block set to zero locked: allocate a line of the locked cache (the Gekko scratchpad) and zero it. |
How it was checked
llvm has no support for the paired singles, so these instructions have no llvm check. The encodings and the operations were checked against the
PowerPC 750CL user's manual and the Gekko user's manual, and against the instruction tables of the Dolphin emulator's interpreter
(Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp), which lists each paired-single opcode with its extended opcode number.
Not described
Known, not yet covered
- Reference: the bit positions of the
HID2enable bits, the layout ofWPAR,DMA_UandDMA_L, and the locked cache configuration. - Reference: the exact rounding and exception behaviour of each paired-single operation (the table gives the operation only).
- Viewer: showing the quantization type of a
psq_lfrom the value of the register.
Unknown
- Reference: the paired singles have no second implementation to compare with other than Dolphin's tables; there is no llvm decoding for them.