[iterate-4A] jit M0: recompiler seam + in-process differential harness

Foundation for a staged PPC block-recompiler (plan: closure-threaded ->
Cranelift -> block-linking). No codegen yet — proves the integration seam and
the correctness harness before any lowering exists.

New crates/xenia-cpu/src/recompiler.rs:
- run_block: executes a DecodedBlock; M0 falls back to the interpreter's
  execute() for every opcode, so it is bit-identical to step_block. Later
  stages dispatch lowered ops here and fall back only for uncompiled opcodes.
- gates jit_enabled()/diff_enabled() (XENIA_JIT / XENIA_JIT_DIFF, cached).
- In-process differential harness (diff_step): the interpreter is AUTHORITATIVE
  (drives real ctx+mem, so a JIT bug can never corrupt a run); the JIT runs
  SPECULATIVELY on a ctx clone against OverlayMemory (writes buffered in a byte
  HashMap, reads fall through to real pre-block memory), then registers are
  compared. Blocks touching MMIO or sync_sensitive (reservation/barrier) are
  skipped — a device callback can't be run twice and reservation state is
  shared cross-thread. report_diff_summary() prints checked/skipped/mismatch.

Why in-process: the guest is only COARSELY deterministic — coord_idle_advance
ticks vsync from wall-clock when idle, so two separate runs are not bit-exact
and a cross-run signature compare would measure jitter, not JIT divergence.

Supporting changes: PpcContext #[derive(Clone)] (harness clears the speculative
clone's reservation_table Arc); is_mmio() on the MemoryAccess trait (default
false) + GuestMemory impl via find_mmio; execute() made pub(crate); run_superblock
routes the block body (DIFF->diff_step, JIT->run_block, else step_block).

Validated: full boot+movie XENIA_JIT_DIFF=1 run = checked 218.4M blocks,
skipped(mmio/sync) 511.6K (0.23%), MISMATCHES=0 CLEAN; movie plays (ADVreads=30,
tid25 resumes); diff-mode ~2x slower (test-only path).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-07-06 20:25:18 +02:00
parent e07f93ed0a
commit ac289bca5e
7 changed files with 368 additions and 2 deletions

View File

@@ -62,6 +62,11 @@ pub const VSCR_SAT_MASK: u32 = 0x0000_0001;
/// PowerPC processor context. Holds all register state for one guest thread.
/// Mirrors PPCContext from ppc_context.h, minus JIT-specific fields.
// `Clone` supports the recompiler's differential harness, which snapshots a
// context to run the JIT speculatively against the interpreter. Cloning shares
// the `reservation_table` Arc; the harness clears it on the speculative copy so
// a speculative lwarx/stwcx cannot perturb the authoritative reservation state.
#[derive(Clone)]
#[repr(C, align(64))]
pub struct PpcContext {
// General purpose registers (R0-R31)