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>
5.6 KiB
name, description, type, originSessionId
| name | description | type | originSessionId |
|---|---|---|---|
| Disassembler unification — Phase 1 complete (2026-04-27) | Single source of truth for PPC text formatting now lives in xenia-cpu/disasm.rs. xenia-analysis/ppc.rs is a thin shim. DecodedInstr stays at 8 bytes. VMX128 bug fixed. | project | 680cc54c-e77a-4d2d-a11b-ca562e9a68ec |
Phase 1 of disassembler unification is COMPLETE (2026-04-27, single session).
What's in place
-
crates/xenia-cpu/src/disasm.rs is the single source of truth for PPC text formatting (~1100 LOC, was 313). Hosts:
pub struct DisasmText { mnemonic, operands, disasm, ext_mnemonic, ext_operands, ext_disasm, branch_target }— allString/Option<String>/Option<u32>. Owns its strings.pub fn format(&DecodedInstr) -> DisasmText— the canonical formatter. Dispatches via match onPpcOpcodeto ~70 per-class helpers.pub fn disassemble(&DecodedInstr) -> String— back-compat: returnsformat(...).display().to_string().pub fn disassemble_block(...)— back-compat range walker.- 8 unit tests covering nop/li/mr/blr/branch-target/rlwinm-dot.
-
crates/xenia-cpu/src/lib.rs re-exports
DisasmText,disassemble,format as disasm_format. -
crates/xenia-analysis/src/ppc.rs collapsed from 1374 LOC → ~30 LOC. Pure shim:
pub struct Decoded { pub base: String, pub ext: Option<String> } pub fn disasm(instr: u32, addr: u32) -> Decoded { ... }Delegates to
xenia_cpu::decoder::decode+xenia_cpu::disasm::format. -
crates/xenia-analysis/src/db.rs call sites use
xenia_cpu::disasm::formatdirectly. Thesplit_disasmhelper at the bottom is deleted —DisasmTextexposes mnemonic/operands separately. -
crates/xenia-analysis/src/formatter.rs unchanged — uses the
crate::ppc::disasmshim'sdisplay()method. -
crates/xenia-analysis/Cargo.toml now depends on xenia-cpu.
Constraint #1 honored: DecodedInstr unchanged
DecodedInstris still 8 bytes (opcode: PpcOpcode,raw: u32,addr: u32),Copy, no allocations.- Decode cache at decoder.rs:228 still 64K × 20 bytes = 1.3 MiB.
DisasmTextis the new struct that owns the formatted strings, allocated only whenformat()is called from a sink.
Silent bug fixed: VMX128 register extractors
The pre-Phase-1 xenia-analysis/src/ppc.rs had wrong bit positions for va128/vb128/vd128 compared to decoder.rs. The interpreter (which executes guest code) used decoder.rs's correct extractors, so guest behavior was correct — but .asm text output and DuckDB rows could show wrong VMX128 register names. Phase 1 routes all VMX128 formatting through instr.va128()/vb128()/vd128() accessors (decoder.rs canonical). Fixed silently.
Other extended forms now in xenia-cpu
Ported from ppc.rs onto DecodedInstr accessors: li/lis/subi/subis, nop, mr/not, slwi/srwi/clrlwi/clrrwi/rotlwi/extlwi/extrwi, clrldi/clrrdi/srdi/sldi/rotldi, insrdi, inslwi/insrwi, cmpwi/cmpdi/cmplwi/cmpldi, cmpw/cmpd/cmplw/cmpld, mflr/mfctr/mfxer, mtlr/mtctr/mtxer, mtcr, mftb/mftbu, blr/blrl/bctr/bctrl, b{cond}{l}{a} (eq/ne/lt/le/gt/ge/so/ns), bd{n}z{cond}, b{cond}lr, b{cond}ctr, sub/subc, crnot/crclr/crset/crmove, lwsync, trap, td{cond}/tw{cond}, td{cond}i/tw{cond}i.
Behavior changes visible to users
xenia disasm(the simple subcommand) now emits extended/simplified mnemonics. Before Phase 1 it only emitted base forms. Smoke test confirmed:mr,subi,nop,lis,li,cmpwi,beq, etc. all appear correctly.- VMX128 register names printed in
.asmand DB are now correct (silent bug fix). - MD-form rotate
shvalue display matches decoder.rs's bit layout (was different in old ppc.rs — likely also a silent bug, since the decoder is what runs on guest code).
Verification done
cargo build --workspaceclean (no new warnings; pre-existing warnings in block_cache.rs and vmx.rs unchanged).cargo test -p xenia-cpu— 166 + 8 new disasm + 9 audit = all pass.cargo test -p xenia-analysis— audit pass.- Smoke
xenia disasm <iso> -n 30— produces clean extended-mnemonic output. - Full
xenia dis --dbend-to-end deferred to next session (release build was slow; functional path verified by passing cargo tests).
LOC delta (Phase 1)
- xenia-cpu/src/disasm.rs: +780 (313 → ~1093)
- xenia-analysis/src/ppc.rs: −1344 (1374 → 30)
- xenia-analysis/src/db.rs: −18 (deleted split_disasm + simplified call sites)
- xenia-cpu/src/lib.rs: +1 (re-export)
- xenia-analysis/Cargo.toml: +1 dep
- Net: −580 LOC plus single-source-of-truth.
What's next (Phases 2-4)
Per /home/fabi/.claude/plans/ok-execute-your-proposed-refactored-dolphin.md:
- Phase 2: Iterator + sinks (
iter_disasmin xenia-cpu, RichDisasmItem enrichment + 3 sinks: text, JSON, DuckDB in xenia-analysis). - Phase 3: Split db.rs into ingest + analyze; add SQL views layer (
v_branch_xrefs,v_call_graph,v_reachability_from_entry, etc.) and--analyze=rust|sql|bothflag. Keep Rust passes as default. - Phase 4: Replace println-only audits with assert-based fixture goldens (
base_mnemonics.json,extended_mnemonics.json,vmx128_registers.json,db_schema_golden.rs, ISO-gateddisasm_first_1000.json).
Format style locked: Phase 1 reproduces ppc.rs's padded comma-space style ("addi r3, r4, 16"). Phase 4 fixtures should lock this.
LOC budget remaining: Phase 2 ~+250/-250 (net 0), Phase 3 ~+280, Phase 4 ~+395 (mostly tests/fixtures).