mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 10:19:47 -04:00
b001e03ce4
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>