- Category pages linked each family as `<slug>.md`, relative to categories/, where no family page lives. They now link `../<category>/<slug>.md`. - Form pages linked a member into its *own* category directory, so every VMX128 sibling (`vsldoi128`) pointed at vmx128/ although its family page is under vmx/. They now link into the family's directory. - Hand-written "Related" and sibling mentions linked other categories' pages as if they were in the same directory. 109 are retargeted through the page index; 29 that pointed a family page at itself (`vrefp128` on vrefp.md) and 6 naming instructions the manual has no page for are plain text now. Regenerated at the existing Canary pin (f21ebd49e): upstream has moved on, and re-pinning belongs in its own change. The generator reports 0 family pages changed and is idempotent; the only dead links left are TEMPLATE.md's placeholders. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.3 KiB
8.3 KiB
dcbz — Data Cache Block Clear to Zero
Assembler Mnemonics
| Mnemonic | XML entry | Flags | Description |
|---|---|---|---|
dcbz |
dcbz |
— | Data Cache Block Clear to Zero |
dcbz128 |
dcbz128 |
— | Data Cache Block Clear to Zero 128 |
Syntax
dcbz [RA0], [RB]
dcbz128 [RA0], [RB]
Encoding
dcbz — form DCBZ
- Opcode word:
0x7c0007ec - Primary opcode (bits 0–5):
31 - Extended opcode:
1014 - Synchronising: no
| Bits | Field | Meaning |
|---|---|---|
| 0–5 | OPCD |
primary opcode (31) |
| 6–10 | — |
reserved |
| 11–15 | RA |
base register (0 ⇒ literal 0) |
| 16–20 | RB |
offset register |
| 21–30 | XO |
extended opcode (1014 for dcbz / 1010 for dcbz128) |
| 31 | — |
reserved |
dcbz128 — form DCBZ
- Opcode word:
0x7c2007ec - Primary opcode (bits 0–5):
31 - Extended opcode:
1014 - Synchronising: no
| Bits | Field | Meaning |
|---|---|---|
| 0–5 | OPCD |
primary opcode (31) |
| 6–10 | — |
reserved |
| 11–15 | RA |
base register (0 ⇒ literal 0) |
| 16–20 | RB |
offset register |
| 21–30 | XO |
extended opcode (1014 for dcbz / 1010 for dcbz128) |
| 31 | — |
reserved |
Operands
| Field | Role | Description |
|---|---|---|
RA0 |
dcbz: read; dcbz128: read | Source GPR; when the encoded register number is 0 the operand is the literal 64-bit zero, not r0. |
RB |
dcbz: read; dcbz128: read | Source GPR. |
Register Effects
dcbz
- Reads (always):
RA0,RB - Reads (conditional): none
- Writes (always): none
- Writes (conditional): none
dcbz128
- Reads (always):
RA0,RB - Reads (conditional): none
- Writes (always): none
- Writes (conditional): none
Status-Register Effects
No condition-register or status-register effects.
Operation (pseudocode)
; No hand-written pseudocode for this instruction yet.
; The authoritative semantics are the Canary emitter snapshot under
; Implementation References; about half of Canary's emitters open
; with the PPC-style definition as a comment (`RD <- (RA) + (RB)`).
; Every side effect is also enumerated in the Register Effects and
; Status-Register Effects tables above.
C Translation Example
/* No hand-written C yet. Translate the Canary emitter snapshot */
/* under Implementation References; its HIR maps directly: */
/* f.LoadGPR(n) / f.StoreGPR(n, v) -> r[n] / r[n] = v */
/* f.LoadFPR / StoreFPR, f.LoadVR / StoreVR -> f[n], v[n] */
/* f.Load(ea, T), f.Store(ea, v) -> raw read / write; emitters */
/* wrap them in f.ByteSwap for the big-endian guest value */
/* f.UpdateCR(n, v) -> CR field n from v's LOW 32 BITS vs 0 */
/* f.LoadCA / f.StoreCA -> xer.CA; f.StoreSAT -> vscr.SAT */
/* i.XO.RA, i.D.DS, ... -> the bit-fields listed under Operands */
/* The Register Effects and Status-Register Effects tables above */
/* enumerate every side effect a faithful translation must emit. */
Implementation References
dcbz
- Canary XML:
tools/ppc-instructions.xml— search formnem="dcbz" - Canary emitter:
src/xenia/cpu/ppc/ppc_emit_memory.cc:1171 - Sylpheed opcode:
crates/sylpheed-ppc/src/opcode.rs:49 - Sylpheed decoder:
crates/sylpheed-ppc/src/decoder.rs:1001
Canary emitter (frozen snapshot @ f21ebd49e9)
int InstrEmit_dcbz(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// memset(EA & ~31, 0, 32)
// On Xbox360 there is no short cache line. Normal dcbz always clears 128
// bytes.
return InstrEmit_dcbz128(f, i);
}
// ── delegates to (src/xenia/cpu/ppc/ppc_emit_memory.cc:1159) ──
int InstrEmit_dcbz128(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// memset(EA & ~31, 0, 32)
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
// dcbz128 - 128 byte set
int block_size = 128;
int address_mask = ~127;
f.Memset(f.And(ea, f.LoadConstantInt64(address_mask)), f.LoadZeroInt8(),
f.LoadConstantInt64(block_size));
return 0;
}
dcbz128
- Canary XML:
tools/ppc-instructions.xml— search formnem="dcbz128" - Canary emitter:
src/xenia/cpu/ppc/ppc_emit_memory.cc:1159 - Sylpheed opcode:
crates/sylpheed-ppc/src/opcode.rs:50 - Sylpheed decoder:
crates/sylpheed-ppc/src/decoder.rs:1002
Canary emitter (frozen snapshot @ f21ebd49e9)
int InstrEmit_dcbz128(PPCHIRBuilder& f, const InstrData& i) {
// EA <- (RA) + (RB)
// memset(EA & ~31, 0, 32)
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
// dcbz128 - 128 byte set
int block_size = 128;
int address_mask = ~127;
f.Memset(f.And(ea, f.LoadConstantInt64(address_mask)), f.LoadZeroInt8(),
f.LoadConstantInt64(block_size));
return 0;
}
Special Cases & Edge Conditions
- Cache-line size mismatch. Stock PowerPC
dcbzzeroes one architectural cache line — 32 bytes on classic POWER, but the Xenon's L1 line is 128 bytes. Microsoft addeddcbz128(encoded with bit-9 set soRTfield reads as1) to clear a true Xenon line in one instruction. Most Xbox 360 code therefore emitsdcbz128; a straydcbzonly zeroes 32 bytes and silently leaves the rest of the line uncleared. - Alignment is forced via mask. The effective address is masked by
~31(dcbz) or~127(dcbz128) before writing — the low bits are dropped, not validated. Callingdcbz r0, r3withr3 = 0x10037writes zeros to0x10000..0x1007F, not0x10037..0x100B6. - No memory read; pure write. Real hardware allocates the line in cache and may skip a read-from-memory fill ("cache-line zero" optimisation). Canary simulates the architectural effect without modelling cache state, and always clears 128 bytes at
EA & ~127— its comment: "On Xbox360 there is no short cache line." RA0semantics.RA = 0selects literal zero as the base, sodcbz128 0, RBzeros the line containing addressRB. The update form does not exist for cache-control instructions.- Block-fill idiom. Compilers and hand-written copy loops pair
dcbz128withstvx/stwsequences to avoid the cache-line read-allocate that a cold store would trigger. Skipping the read is the entire point. - Privilege.
dcbzis unprivileged (problem-state); does not require supervisor mode. It can fault on protection or unmapped memory like an ordinary store. - Sequencing. Not synchronising. Pair with
sync/lwsyncwhen the zeros must be visible before subsequent loads on another thread.
Related Instructions
dcbf— flush a line back to memory.dcbst— store-through (write-back without invalidate).dcbi— invalidate (privileged on most cores).dcbt,dcbtst— touch / touch-for-store hints.icbi— instruction-cache invalidate (companion to data-cache control).stvx,stw— typical pair-mates in block-fill loops.
IBM Reference
- AIX 7.3 —
dcbz(Data Cache Block Set to Zero) - Microsoft Xbox 360 XDK /
Xenon Programming Guide— fordcbz128specifics;PowerISA v2.07B Book II§ "Storage Control Instructions" for the architectural baseline.