What a PSP Static Recompiler Must Model
Status: COURSE CHAPTER 1 · Evidence class: DERIVED TEACHING MODEL · Chapter ID: CH-PSP-MODEL-001 · Last reviewed: 2026-08-11
A PSP static recompiler is not just an instruction-to-C translator. It must preserve the guest contracts that later code can observe. Before writing a decoder, make those contracts explicit and mark which ones are platform facts, implementation facts, or still open.
The seven contracts
- Guest machine state. Model the 32 GPRs, HI/LO, COP1 registers and condition state, VFPU registers and control prefixes, COP0 state needed by the fixture, and the program-control state used by branches and delay slots. The exact fields are an ABI between generated code and the runtime; a field-order change can invalidate every translation unit.
- Guest memory and aliases. Define address width, alignment, endianness, RAM/VRAM/scratchpad regions, cached and uncached aliases, and whole-span validation. A starting-address check is not proof that a multi-byte access is safe.
- Control flow. Preserve delay-slot execution, branch-likely annulment where relevant, indirect targets, returns, and the difference between a callable function boundary and a resumable interior entry. A graph edge is not automatically a function.
- Executable identity. ELF/PRX headers, load segments, BSS, GP, relocations, module metadata, imports, exports, NIDs, and load-base changes must remain traceable to the source fixture.
- Runtime boundaries. An HLE call is a contract boundary with return values, errors, memory side effects, callback behavior, and wake/scheduling consequences. “The handler returned” is not enough evidence.
- Concurrency and time. Guest threads, priorities, waits, callbacks, VBLANK, timers, and interrupt masking can be observable even when the host implementation is cooperative. Choose a scope and name the simplifications.
- Media and display. GE command ordering, framebuffer ownership, audio buffering, and codec state are separate semantic surfaces; do not hide them behind “the frame rendered.”
What is deliberately outside this chapter
A host window, a title’s proprietary assets, private traces, and an emulator’s undocumented shortcut are not PSP contracts. They can be implementation context, but they must not silently become public platform facts.
Case-study anchors
Compare this model with the public PSP Executable Model and Static Recompilation Architecture. In the current public Nakagawa source, src/rt/recomp.h defines the shared CpuState and guest-memory boundary, tools/codegen.py records callable/resumable entry roles, and src/rt/sched.c describes the cooperative scheduler. These are implementation evidence, not hardware measurements.
Exercise: write a contract table
Choose a tiny source-owned function and make one row for each contract: guest observable, translator responsibility, runtime responsibility, test fixture, evidence class, and unknowns. If you cannot name a fixture or a failure assertion, leave the row OPEN instead of filling it with an emulator assumption.
Continue with CH-ELF-PRX-001 — Parse an ELF/PRX Safely, then return to the course landing page.