Bundles state that lives OUTSIDE the xenia-rs repo so a fresh clone on
another machine can be brought up to identical configuration via
migration/setup.sh:
- claude-memory/ ~/.claude/projects/-home-fabi-RE-Project-Sylpheed/memory/
(103 files, 1.1 MB - MEMORY.md + every
project_xenia_rs_*.md from audits
addis_signext through audit-058)
- project-root/dot-claude/ <project-root>/.claude/settings.json
(Stop hook + permissions)
- project-root/ppc-manual/ <project-root>/ppc-manual/
(PowerPC reference docs, 397 files, 3.7 MB)
- project-root/run-canary.sh <project-root>/run-canary.sh
- README.md Human-readable setup checklist
- setup.sh Idempotent installer (also reclones
xenia-canary at pinned HEAD 6de80dffe)
- MANIFEST.md Per-file mapping + per-file-not-bundled
restoration recipe
Excluded from bundle (not shippable via git):
- Sylpheed ISO (7.8 GB; copyright; manual copy required)
- sylpheed.db (395 MB; regenerable from XEX via analysis tooling)
- target/ build artifacts (rebuild on target)
- audit-runs probe firehoses (.log/.stdout/.stderr ~11 GB; rerun if needed)
- audit-runs memory dumps (.bin ~4.5 GB; rerun audit-026/027/029 if needed)
- xenia-canary checkout (setup.sh reclones from
git.mc02.dev/fabi/Xenia-Canary.git at HEAD 6de80dffe)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
116 lines
6.3 KiB
Markdown
116 lines
6.3 KiB
Markdown
# PowerPC Instruction Manual (Xenia Xbox 360 Subset)
|
||
|
||
A reference for the **Xenon** PowerPC dialect used by the Xbox 360. Its
|
||
primary audience is an AI agent translating PPC assembly functions into
|
||
equivalent C. The content is derived from the two authoritative sources in
|
||
this repository — **xenia-canary** (C++ emulator) and **xenia-rs** (Rust
|
||
rewrite) — and may be deepened with the IBM AIX PowerPC reference.
|
||
|
||
- **455** distinct XML-level instructions (one page each).
|
||
- **350** instruction family pages (VMX128 siblings folded).
|
||
- **598** assembly mnemonics once runtime `Rc`/`OE`/`LK` variants are expanded — all resolvable through `index.json`.
|
||
|
||
## How to use this manual (translation agent)
|
||
|
||
1. Parse the 32-bit instruction word and identify the mnemonic. Resolve it
|
||
through [`index.json`](index.json): every assembly form (including
|
||
`add.`, `addo.`, `bclrl`, …) is a top-level key pointing at a page.
|
||
2. Open the page referenced by `index.json[mnem].page`. The page is in a
|
||
fixed format — see the "Page anatomy" section below.
|
||
3. Emit a C translation consistent with the page's pseudocode, the
|
||
registers-affected list, and the status-register effects.
|
||
|
||
## Page anatomy
|
||
|
||
Every instruction page has the same sections, in this order:
|
||
|
||
| Section | Purpose |
|
||
| --- | --- |
|
||
| **Assembler Mnemonics** | Table of every runtime variant (Rc/OE/LK) the base XML entry covers, plus VMX128 siblings. |
|
||
| **Syntax** | Canonical assembly template with `[OE]`/`[Rc]`/`[LK]` bracketed-modifier notation. |
|
||
| **Encoding** | Form name, opcode word, primary/extended opcodes, and bit-layout table. |
|
||
| **Operands** | Every bit-field operand, its role per variant, and its meaning. |
|
||
| **Register Effects** | Unconditional vs. conditional reads and writes, per variant. |
|
||
| **Status-Register Effects** | CR0/CR1/CR6, XER[CA/OV/SO], FPSCR, VSCR updates. |
|
||
| **Operation** | PPC-style pseudocode (`RT <- …`, `EXTS(…)`, `MEM(EA, n)`). |
|
||
| **C Translation Example** | Minimal idiomatic C rendering a translator could emit. |
|
||
| **Implementation References** | Direct links into `xenia-canary/` and `xenia-rs/` with line numbers. |
|
||
| **Special Cases & Edge Conditions** | RA=0, alignment, endian byte-reverse, reservation, SPR remapping, VMX128 fusion. |
|
||
| **Related Instructions** | Sibling cross-links. |
|
||
| **IBM Reference** | Optional link to IBM AIX PPC reference for canonical pseudocode. |
|
||
|
||
Sections between the `<!-- GENERATED: BEGIN -->` and `<!-- GENERATED: END -->`
|
||
sentinels are produced by [`generator/generate_manual.py`](generator/generate_manual.py)
|
||
and re-generated on every run. Sections outside the sentinels are
|
||
hand-written and preserved across re-runs.
|
||
|
||
## Conventions
|
||
|
||
- **Bit numbering** follows PowerPC (big-endian, bit 0 = MSB).
|
||
- **GPRs** are 64-bit. 32-bit operations operate on bits `[32:63]` and
|
||
conventionally write the low 32 bits with zero- or sign-extension into
|
||
the high 32 bits. Page pseudocode makes this explicit when it matters.
|
||
- **Vector registers** are 128-bit with **lane 0 at the most-significant
|
||
byte** (big-endian lane indexing). On x86 hosts byte-swap is applied at
|
||
load/store to preserve this invariant.
|
||
- **CR** is 8 × 4-bit fields `CR0..CR7`, each `{LT, GT, EQ, SO}`. The record
|
||
form of arithmetic instructions writes CR0 (integer) or CR1 (FPU); the
|
||
record form of vector compare writes CR6 = `{all-true, 0, all-false, 0}`.
|
||
- **XER** holds `SO`, `OV`, and `CA` at bits 32, 33, 34 respectively
|
||
(PPC bit numbering), plus a 7-bit string length used by `lswi`/`stswi`.
|
||
|
||
## Categories
|
||
|
||
| Category | Families | XML entries | Description |
|
||
| --- | --- | --- | --- |
|
||
| [Integer ALU](categories/alu.md) | 70 | 70 | Fixed-point add/sub/multiply/divide, logical, rotate, shift, compare, count-leading-zeros, sign-extension, trap-on-condition. |
|
||
| [Branch & System](categories/branch.md) | 9 | 9 | Unconditional / conditional branches, branch to LR/CTR, traps, system call. |
|
||
| [Control / CR / SPR](categories/control.md) | 26 | 26 | Condition-register logical ops, CR field moves, mfspr/mtspr/mtcrf, time-base reads, synchronisation (sync, isync, eieio). |
|
||
| [Floating-Point](categories/fpu.md) | 33 | 33 | IEEE-754 add/sub/mul/div/sqrt, fused multiply-add, conversions, compares, FPSCR moves. |
|
||
| [Memory](categories/memory.md) | 56 | 112 | Loads/stores for byte, half, word, doubleword, float, multiple and string; cache management (dcbt, dcbf, dcbz); reservation pair lwarx/stwcx. |
|
||
| [VMX (Altivec)](categories/vmx.md) | 144 | 193 | 128-bit SIMD over 32 registers V0–V31. Integer/float arithmetic, logical, compare, permute/merge, pack/unpack, saturation helpers. |
|
||
| [VMX128](categories/vmx128.md) | 12 | 12 | Xbox-360-specific Altivec extension that widens the vector register file to 128 registers (V0–V127). Register IDs are encoded with bit-fusion across non-contiguous fields. |
|
||
|
||
## Forms
|
||
|
||
| Form | Count | Page |
|
||
| --- | --- | --- |
|
||
| `A` | 21 | [forms/A.md](forms/A.md) |
|
||
| `B` | 1 | [forms/B.md](forms/B.md) |
|
||
| `D` | 40 | [forms/D.md](forms/D.md) |
|
||
| `DCBZ` | 2 | [forms/DCBZ.md](forms/DCBZ.md) |
|
||
| `DS` | 5 | [forms/DS.md](forms/DS.md) |
|
||
| `I` | 1 | [forms/I.md](forms/I.md) |
|
||
| `M` | 3 | [forms/M.md](forms/M.md) |
|
||
| `MD` | 4 | [forms/MD.md](forms/MD.md) |
|
||
| `MDS` | 2 | [forms/MDS.md](forms/MDS.md) |
|
||
| `SC` | 1 | [forms/SC.md](forms/SC.md) |
|
||
| `VA` | 14 | [forms/VA.md](forms/VA.md) |
|
||
| `VC` | 13 | [forms/VC.md](forms/VC.md) |
|
||
| `VX` | 117 | [forms/VX.md](forms/VX.md) |
|
||
| `VX128` | 34 | [forms/VX128.md](forms/VX128.md) |
|
||
| `VX128_1` | 16 | [forms/VX128_1.md](forms/VX128_1.md) |
|
||
| `VX128_2` | 1 | [forms/VX128_2.md](forms/VX128_2.md) |
|
||
| `VX128_3` | 15 | [forms/VX128_3.md](forms/VX128_3.md) |
|
||
| `VX128_4` | 2 | [forms/VX128_4.md](forms/VX128_4.md) |
|
||
| `VX128_5` | 1 | [forms/VX128_5.md](forms/VX128_5.md) |
|
||
| `VX128_P` | 1 | [forms/VX128_P.md](forms/VX128_P.md) |
|
||
| `VX128_R` | 5 | [forms/VX128_R.md](forms/VX128_R.md) |
|
||
| `X` | 117 | [forms/X.md](forms/X.md) |
|
||
| `XFL` | 1 | [forms/XFL.md](forms/XFL.md) |
|
||
| `XFX` | 4 | [forms/XFX.md](forms/XFX.md) |
|
||
| `XL` | 12 | [forms/XL.md](forms/XL.md) |
|
||
| `XO` | 21 | [forms/XO.md](forms/XO.md) |
|
||
| `XS` | 1 | [forms/XS.md](forms/XS.md) |
|
||
|
||
## Regenerating this manual
|
||
|
||
```bash
|
||
python3 generator/generate_manual.py
|
||
```
|
||
|
||
Re-running the generator is safe — it only rewrites sections between
|
||
`<!-- GENERATED: BEGIN -->` / `<!-- GENERATED: END -->` sentinels. Add
|
||
your hand-written content below the `END` marker and it will be
|
||
preserved.
|