- 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.0 KiB
5.0 KiB
addic — Add Immediate Carrying
Category: Integer ALU · Form: D · Opcode:
0x30000000
Assembler Mnemonics
| Mnemonic | XML entry | Flags | Description |
|---|---|---|---|
addic |
addic |
— | Add Immediate Carrying |
Syntax
addic [RD], [RA], [SIMM]
Encoding
addic — form D
- Opcode word:
0x30000000 - Primary opcode (bits 0–5):
12 - 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. |
Register Effects
addic
- Reads (always):
RA,SIMM - Reads (conditional): none
- Writes (always):
RD,CA - Writes (conditional): none
Status-Register Effects
addic: XER[CA] ← carry-out of the add / borrow-in of the subtract (always).
Operation (pseudocode)
RT <- (RA) + EXTS(SIMM)
CA <- carry_out
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:117 - Sylpheed opcode:
crates/sylpheed-ppc/src/opcode.rs:11 - Sylpheed decoder:
crates/sylpheed-ppc/src/decoder.rs:451
Canary emitter (frozen snapshot @ f21ebd49e9)
int InstrEmit_addic(PPCHIRBuilder& f, const InstrData& i) {
// RT <- (RA) + EXTS(SI)
// CA <- carry bit
Value* ra = f.LoadGPR(i.D.RA);
Value* v = f.Add(ra, f.LoadConstantInt64(XEEXTS16(i.D.DS)));
f.StoreGPR(i.D.RT, v);
f.StoreCA(AddDidCarry(f, ra, f.LoadConstantInt64(XEEXTS16(i.D.DS))));
return 0;
}
Special Cases & Edge Conditions
- Immediate is sign-extended.
SIMMis a 16-bit signed value extended to 64 bits before the add. Soaddic r3, r4, -1adds0xFFFFFFFFFFFFFFFFtor4— it does not zero-extend. XER[CA]always written. Unlikeaddi, this instruction exists to seed a multi-word add chain with an immediate. Carry-out is computed with the sameresult < raunsigned-overflow check asaddcx.- No
Rcbit available. This is the non-record form. For a record-form variant that also updatesCR0, useaddicx(addic.). - No
OEbit either.addiccannot raise / observe signed overflow — only the carry. If you needXER[OV]you must use the XO-formaddcxwithOE=1. RA = 0reads register r0. Unlikeaddi,addicdoes not treat theRAfield of zero as a literal zero. The PowerISA gives this instruction the regularRAsemantics, notRA0.- Subtract immediate carrying via negation. There is no
subicmnemonic; assemblers synthesisesubic RT, RA, valueasaddic RT, RA, -value(whenvaluefits in 16 bits signed).
Related Instructions
addicx— same operation plusRc=1CR0 update.addi— D-form add immediate withoutXER[CA].addis— shifted form (immediate << 16).addcx— XO-form: register operands, setsXER[CA].subfic— D-form:RT ← SIMM − RAwithXER[CA].