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>
This commit is contained in:
MechaCat02
2026-05-10 21:38:38 +02:00
parent 8e709b0a24
commit e6d43a23ac
505 changed files with 86028 additions and 0 deletions

View File

@@ -0,0 +1,266 @@
"""
Canonical bit layout per PPC instruction form.
Tables derived from xenia-canary/src/xenia/cpu/ppc/ppc_instr.h (struct
PPCOpcodeBits union). In PPC notation bit 0 is the MSB of the 32-bit
word (big-endian bit numbering).
Each entry is a list of (bit_start, bit_end_inclusive, field_name,
notes) tuples laid out from MSB (bit 0) to LSB (bit 31).
"""
# NOTE: bit ranges use PPC big-endian numbering (0 = MSB, 31 = LSB).
FORM_LAYOUTS: dict[str, list[tuple[int, int, str, str]]] = {
"I": [
(0, 5, "OPCD", "primary opcode"),
(6, 29, "LI", "signed 24-bit word-offset target"),
(30, 30, "AA", "absolute-address flag"),
(31, 31, "LK", "link flag (bl/ba/bla)"),
],
"B": [
(0, 5, "OPCD", "primary opcode"),
(6, 10, "BO", "branch options"),
(11, 15, "BI", "CR bit to test"),
(16, 29, "BD", "signed 14-bit word-offset target"),
(30, 30, "AA", "absolute-address flag"),
(31, 31, "LK", "link flag"),
],
"SC": [
(0, 5, "OPCD", "primary opcode (17)"),
(6, 19, "", "reserved"),
(20, 26, "LEV", "exception level"),
(27, 29, "", "reserved"),
(30, 30, "1", "fixed 1"),
(31, 31, "", "reserved"),
],
"D": [
(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"),
],
"DS": [
(0, 5, "OPCD", "primary opcode"),
(6, 10, "RT", "destination GPR (or RS)"),
(11, 15, "RA", "source GPR (0 ⇒ literal 0)"),
(16, 29, "DS", "14-bit signed word-scaled displacement"),
(30, 31, "XO", "extended opcode"),
],
"X": [
(0, 5, "OPCD", "primary opcode"),
(6, 10, "RT/FRT/VRT", "destination"),
(11, 15, "RA/FRA/VRA", "source A"),
(16, 20, "RB/FRB/VRB", "source B"),
(21, 30, "XO", "extended opcode (10 bits)"),
(31, 31, "Rc", "record-form flag"),
],
"XL": [
(0, 5, "OPCD", "primary opcode (19)"),
(6, 10, "BT/BO", "target / branch options"),
(11, 15, "BA/BI", "source A / CR bit to test"),
(16, 20, "BB", "source B"),
(21, 30, "XO", "extended opcode (10 bits)"),
(31, 31, "LK", "link flag"),
],
"XFX": [
(0, 5, "OPCD", "primary opcode (31)"),
(6, 10, "RT", "destination / source GPR"),
(11, 20, "spr/tbr/FXM", "SPR/TBR number (byte-swapped halves) or CR field mask"),
(21, 30, "XO", "extended opcode"),
(31, 31, "", "reserved"),
],
"XFL": [
(0, 5, "OPCD", "primary opcode (63)"),
(6, 6, "L", "field-select behaviour"),
(7, 14, "FM", "FPSCR field mask"),
(15, 15, "W", "immediate-value flag"),
(16, 20, "FRB", "source FPR"),
(21, 30, "XO", "extended opcode"),
(31, 31, "Rc", "record-form flag (updates CR1)"),
],
"XS": [
(0, 5, "OPCD", "primary opcode (31)"),
(6, 10, "RS", "source GPR"),
(11, 15, "RA", "destination GPR"),
(16, 20, "sh", "shift amount low 5 bits"),
(21, 29, "XO", "extended opcode (9 bits)"),
(30, 30, "sh5", "shift amount high bit"),
(31, 31, "Rc", "record-form flag"),
],
"XO": [
(0, 5, "OPCD", "primary opcode (31)"),
(6, 10, "RT", "destination GPR"),
(11, 15, "RA", "source A"),
(16, 20, "RB", "source B"),
(21, 21, "OE", "overflow-enable flag"),
(22, 30, "XO", "extended opcode (9 bits)"),
(31, 31, "Rc", "record-form flag"),
],
"A": [
(0, 5, "OPCD", "primary opcode (59 or 63)"),
(6, 10, "FRT", "destination FPR"),
(11, 15, "FRA", "source A FPR"),
(16, 20, "FRB", "source B FPR"),
(21, 25, "FRC", "source C FPR (multiplier for madd-style ops)"),
(26, 30, "XO", "extended opcode (5 bits)"),
(31, 31, "Rc", "record-form flag (updates CR1)"),
],
"M": [
(0, 5, "OPCD", "primary opcode"),
(6, 10, "RS", "source GPR"),
(11, 15, "RA", "destination GPR"),
(16, 20, "SH/RB", "shift amount or source B"),
(21, 25, "MB", "mask begin"),
(26, 30, "ME", "mask end"),
(31, 31, "Rc", "record-form flag"),
],
"MD": [
(0, 5, "OPCD", "primary opcode (30)"),
(6, 10, "RS", "source GPR"),
(11, 15, "RA", "destination GPR"),
(16, 20, "sh", "shift amount low 5 bits"),
(21, 26, "mb/me", "6-bit mask field (swapped halves)"),
(27, 29, "XO", "extended opcode"),
(30, 30, "sh5", "shift amount high bit"),
(31, 31, "Rc", "record-form flag"),
],
"MDS": [
(0, 5, "OPCD", "primary opcode (30)"),
(6, 10, "RS", "source GPR"),
(11, 15, "RA", "destination GPR"),
(16, 20, "RB", "source B GPR"),
(21, 26, "mb/me", "6-bit mask field (swapped halves)"),
(27, 30, "XO", "extended opcode"),
(31, 31, "Rc", "record-form flag"),
],
"DCBZ": [
(0, 5, "OPCD", "primary opcode (31)"),
(6, 10, "", "reserved"),
(11, 15, "RA", "base register (0 ⇒ literal 0)"),
(16, 20, "RB", "offset register"),
(21, 30, "XO", "extended opcode (1014 for dcbz / 1010 for dcbz128)"),
(31, 31, "", "reserved"),
],
"VX": [
(0, 5, "OPCD", "primary opcode (4)"),
(6, 10, "VRT/VD", "destination vector register"),
(11, 15, "VRA/VA", "source A vector register"),
(16, 20, "VRB/VB", "source B vector register"),
(21, 31, "XO", "extended opcode (11 bits)"),
],
"VA": [
(0, 5, "OPCD", "primary opcode (4)"),
(6, 10, "VRT", "destination vector register"),
(11, 15, "VRA", "source A"),
(16, 20, "VRB", "source B"),
(21, 25, "VRC", "source C / shift"),
(26, 31, "XO", "extended opcode (6 bits)"),
],
"VC": [
(0, 5, "OPCD", "primary opcode (4)"),
(6, 10, "VRT", "destination vector register"),
(11, 15, "VRA", "source A"),
(16, 20, "VRB", "source B"),
(21, 21, "Rc", "record-form flag (updates CR6)"),
(22, 31, "XO", "extended opcode (10 bits)"),
],
"VX128": [
(0, 5, "OPCD", "primary opcode (4 or 5)"),
(6, 10, "VD128l", "destination low 5 bits"),
(11, 15, "VA128l", "source A low 5 bits"),
(16, 20, "VB128l", "source B low 5 bits"),
(21, 21, "VA128H", "source A high bit"),
(22, 22, "", "reserved"),
(23, 25, "VC", "optional VC / XO sub-field"),
(26, 26, "VA128h", "source A middle bit"),
(27, 27, "", "reserved"),
(28, 29, "VD128h", "destination high 2 bits"),
(30, 31, "VB128h", "source B high 2 bits"),
],
"VX128_1": [
(0, 5, "OPCD", "primary opcode (4)"),
(6, 10, "VD128l", "destination low 5 bits"),
(11, 15, "RA", "address register"),
(16, 20, "RB", "offset register"),
(21, 27, "XO", "extended opcode"),
(28, 29, "VD128h", "destination high 2 bits"),
(30, 31, "", "reserved"),
],
"VX128_2": [
(0, 5, "OPCD", "primary opcode (5)"),
(6, 10, "VD128l", "destination low 5 bits"),
(11, 15, "VA128l", "source A low 5 bits"),
(16, 20, "VB128l", "source B low 5 bits"),
(21, 21, "VA128H", "source A high bit"),
(23, 25, "VC", "source C 3-bit field"),
(26, 26, "VA128h", "source A middle bit"),
(28, 29, "VD128h", "destination high 2 bits"),
(30, 31, "VB128h", "source B high 2 bits"),
],
"VX128_3": [
(0, 5, "OPCD", "primary opcode (6)"),
(6, 10, "VD128l", "destination low 5 bits"),
(11, 15, "IMM", "5-bit immediate"),
(16, 20, "VB128l", "source B low 5 bits"),
(21, 27, "XO", "extended opcode"),
(28, 29, "VD128h", "destination high 2 bits"),
(30, 31, "VB128h", "source B high 2 bits"),
],
"VX128_4": [
(0, 5, "OPCD", "primary opcode (6)"),
(6, 10, "VD128l", "destination low 5 bits"),
(11, 15, "IMM", "5-bit immediate"),
(16, 20, "VB128l", "source B low 5 bits"),
(21, 23, "XO", "extended opcode"),
(24, 25, "z", "sub-operation selector"),
(28, 29, "VD128h", "destination high 2 bits"),
(30, 31, "VB128h", "source B high 2 bits"),
],
"VX128_5": [
(0, 5, "OPCD", "primary opcode (4)"),
(6, 10, "VD128l", "destination low 5 bits"),
(11, 15, "VA128l", "source A low 5 bits"),
(16, 20, "VB128l", "source B low 5 bits"),
(21, 21, "VA128H", "source A high bit"),
(22, 25, "SH", "4-bit shift amount"),
(26, 26, "VA128h", "source A middle bit"),
(28, 29, "VD128h", "destination high 2 bits"),
(30, 31, "VB128h", "source B high 2 bits"),
],
"VX128_P": [
(0, 5, "OPCD", "primary opcode (6)"),
(6, 10, "VD128l", "destination low 5 bits"),
(11, 15, "PERMl", "permute selector low 5 bits"),
(16, 20, "VB128l", "source B low 5 bits"),
(21, 22, "", "reserved"),
(23, 25, "PERMh", "permute selector high 3 bits"),
(28, 29, "VD128h", "destination high 2 bits"),
(30, 31, "VB128h", "source B high 2 bits"),
],
"VX128_R": [
(0, 5, "OPCD", "primary opcode (4)"),
(6, 10, "VD128l", "destination low 5 bits"),
(11, 15, "VA128l", "source A low 5 bits"),
(16, 20, "VB128l", "source B low 5 bits"),
(21, 21, "VA128H", "source A high bit"),
(22, 25, "XO", "extended opcode (compare)"),
(26, 26, "VA128h", "source A middle bit"),
(27, 27, "Rc", "record-form flag (updates CR6)"),
(28, 29, "VD128h", "destination high 2 bits"),
(30, 31, "VB128h", "source B high 2 bits"),
],
}
def render_bit_table(form: str) -> str:
"""Return a markdown table of the form's bit layout."""
layout = FORM_LAYOUTS.get(form)
if not layout:
return f"_Unknown form_ `{form}` _— see `forms/` for details._"
rows = ["| Bits | Field | Meaning |", "| --- | --- | --- |"]
for start, end, name, notes in layout:
span = f"{start}" if start == end else f"{start}{end}"
rows.append(f"| {span} | `{name}` | {notes} |")
return "\n".join(rows)