Files
psxrecomp/runtime/tests
Matthew Stanley b001e03ce4 sljit: block-local GPR register allocation for overlay shards
Replace the memory-backed GPR model (every instruction loaded operands
from cpu->gpr[] and stored results back) with a block-local cache of MIPS
GPRs in host SAVED registers (S2..). Saved registers are callee-saved, so
they survive the read_/write_ icalls a plain load/store emits; the cache is
only flushed/reset at basic-block boundaries and around helper/call icalls
that touch cpu->gpr[] in memory. Prologue cost scales with register
pressure (saveds sized per-fragment from a distinct-GPR popcount).

Invariants: flush dirty->memory before every control transfer and before a
helper/call that reads gpr; reset (drop mappings) at branch-target labels
(after a preceding flush) and after any helper/call that writes gpr; gpr[0]
never cached.

Validation:
- Standalone emitter harness 66/66 (runtime/tests/sljit_emit_test.c).
- Offline differential (runtime/tests/sljit_offline_diff.c, --dump): the
  new emitter is BYTE-IDENTICAL to the pre-regalloc (HEAD) emitter across
  313 overlay functions, run from identical state + call stub. This is the
  primary correctness proof — stronger than a single live diff.
- sljit_sp_probe.c: $sp-balance probes (prologue/epilogue, branch-delay,
  register-sp, calls, loops).

A regalloc bug can only surface as a same-state differential divergence
(shards run live only after passing it), never a silently-wrong shard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 12:52:30 -07:00
..