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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.