Files
xenia-rs/migration/claude-memory/project_xenia_rs_disasm_unify_phase1.md
MechaCat02 e6d43a23ac chore: add migration/ bundle for cross-machine setup
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>
2026-05-10 21:38:38 +02:00

5.6 KiB
Raw Blame History

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 } — all String / Option<String> / Option<u32>. Owns its strings.
    • pub fn format(&DecodedInstr) -> DisasmText — the canonical formatter. Dispatches via match on PpcOpcode to ~70 per-class helpers.
    • pub fn disassemble(&DecodedInstr) -> String — back-compat: returns format(...).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::format directly. The split_disasm helper at the bottom is deletedDisasmText exposes mnemonic/operands separately.

  • crates/xenia-analysis/src/formatter.rs unchanged — uses the crate::ppc::disasm shim's display() method.

  • crates/xenia-analysis/Cargo.toml now depends on xenia-cpu.

Constraint #1 honored: DecodedInstr unchanged

  • DecodedInstr is 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.
  • DisasmText is the new struct that owns the formatted strings, allocated only when format() 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

  1. 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.
  2. VMX128 register names printed in .asm and DB are now correct (silent bug fix).
  3. MD-form rotate sh value 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 --workspace clean (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 --db end-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_disasm in 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|both flag. 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-gated disasm_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).