Real RSP hardware retains GPRs across task switches. rspboot only
writes $1/$2/$3/$4/$7 before jumping to the loaded ucode; everything
else is whatever the previous task left. The previous emit zero-init'd
all 32 GPRs at every entry, breaking any ucode that depends on
inherited state — e.g. Pokemon Stadium's libultra aspMain reads $29
on its first dispatch iteration expecting it from a prior run.
RSPRecomp/src/rsp_recomp.cpp:
* All GPRs (and dma_*, jump_target, rsp) are now emitted as C++
references into *ctx — writes auto-persist through to the backing
RspContext, no manual store-back at exit points.
* No-overlay case (Stadium aspMain shape) emits an `_impl(rdram,
ctx)` function plus a legacy-ABI wrapper `(rdram, ucode_addr)`
that owns a `static thread_local RspContext`. The wrapper preserves
the runtime ABI (no librecomp change needed) while the static
thread_local delivers cross-run_task GPR retention.
* Overlay-swap function's stack-local `RspContext ctx{}` promoted to
`static thread_local` for the same reason.
* write_overlay_swap_return reduced from 9 lines of manual store-back
to just `return RspExitReason::SwapOverlay` — references handle it.
(NOTE: original local commit 5c6c654 also bundled per-register cop0
dispatch + cop0_regs[32] storage. That portion is split out for a
separate follow-up PR — it depends on a runtime API not yet in
upstream N64ModernRuntime.)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Implement function hook insertion
* Fix recompiled code indentation
* Add _matherr to renamed_funcs
* Replace after_vram by before_vram
* Emit dummy value if relocatable_sections_ordered is empty