- 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>
5.7 KiB
5.7 KiB
addic. — Add Immediate Carrying and Record
Category: Integer ALU · Form: D · Opcode:
0x34000000
Assembler Mnemonics
| Mnemonic | XML entry | Flags | Description |
|---|---|---|---|
addic. |
addic. |
— | Add Immediate Carrying and Record |
Syntax
addic. [RD], [RA], [SIMM]
Encoding
addic. — form D
- Opcode word:
0x34000000 - Primary opcode (bits 0–5):
13 - Extended opcode: —
- Synchronising: no
| Bits | Field | Meaning |
|---|---|---|
| 0–5 | OPCD |
primary opcode |
| 6–10 | RT |
destination GPR (or RS when storing) |
| 11–15 | RA |
source GPR (0 ⇒ literal 0 for RA0 forms) |
| 16–31 | D/SI/UI |
16-bit signed or unsigned immediate |
Operands
| Field | Role | Description |
|---|---|---|
RA |
addic.: read | Source GPR (r0–r31). |
SIMM |
addic.: read | 16-bit signed immediate. Sign-extended to 64 bits before use. |
RD |
addic.: write | Destination GPR. |
CA |
addic.: write | XER[CA] carry bit. Read by add-with-carry/subtract-with-borrow instructions, written by carrying instructions. |
CR |
addic.: write | Condition-register update. When Rc=1, CR field 0 (or CR6 for vector compares, CR1 for FPU) is updated from the result. |
Register Effects
addic.
- Reads (always):
RA,SIMM - Reads (conditional): none
- Writes (always):
RD,CA,CR - Writes (conditional): none
Status-Register Effects
addic.: CR0 ← signed-compare(result, 0) withSO ← XER[SO](always).; XER[CA] ← carry-out of the add / borrow-in of the subtract (always).
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
addic.
- Canary XML:
tools/ppc-instructions.xml— search formnem="addic." - Canary emitter:
src/xenia/cpu/ppc/ppc_emit_alu.cc:127 - Sylpheed opcode:
crates/sylpheed-ppc/src/opcode.rs:12 - Sylpheed decoder:
crates/sylpheed-ppc/src/decoder.rs:452
Canary emitter (frozen snapshot @ f21ebd49e9)
int InstrEmit_addicx(PPCHIRBuilder& f, const InstrData& i) {
// RT <- (RA) + EXTS(SI)
// CA <- carry bit
Value* ra = f.LoadGPR(i.D.RA);
Value* v = f.Add(f.LoadGPR(i.D.RA), f.LoadConstantInt64(XEEXTS16(i.D.DS)));
f.StoreGPR(i.D.RT, v);
f.StoreCA(AddDidCarry(f, ra, f.LoadConstantInt64(XEEXTS16(i.D.DS))));
f.UpdateCR(0, v);
return 0;
}
Special Cases & Edge Conditions
Rcbit is implicit, not encoded.addic.has its own primary opcode (13) distinct fromaddic's (12); there is noRcfield to set. The two forms are sibling D-form instructions, not flag variants of one encoding.- CR0 update is unconditional. Unlike XO-form
Rc=1instructions,addic.always updatesCR0from the result; the.is part of the mnemonic itself. - Common idiom:
addic. rN, rN, -1— decrementsrNand setsCR0[EQ]when it reaches zero, in a single instruction. Frequently used as a loop counter (often paired withbne+ loop). XER[CA]written same asaddic. The carry-out from the unsigned 64-bit add is recorded; the.only adds the CR update on top.- 64-bit CR update on Xenon, 32-bit in Canary.
f.UpdateCR(0, v)truncatesvtoINT32before the signed compare with zero; the spec demands a full 64-bit compare-to-zero. The same truncation applies across the carrying-add family. SIMMis sign-extended to 64 bits before the add —addic. r3, r4, -1adds~0and never setsCR0[EQ]unlessr4 == 1.
Related Instructions
addic— same op without the CR0 update.addi,addis— immediate adds withoutXER[CA].addcx— XO-form register equivalent.subfic—RT ← SIMM − RAwithXER[CA](no record form exists).cmpi— explicit immediate compare when the carry side-effect would be unwanted.