fix(interp): scope load-delay values to BIOS-owned code

This commit is contained in:
Matthew Stanley
2026-07-25 17:02:33 -07:00
parent 986d8be94c
commit a162aa7fb1
2 changed files with 20 additions and 1 deletions
+12 -1
View File
@@ -1339,7 +1339,18 @@ static int exec_one_fetched(CPUState *cpu, uint32_t pc, uint32_t insn,
* register, not a GPR, so it needs no deferral here. */
const uint32_t ld_op = op_field(insn);
const uint32_t ld_rt = rt_field(insn);
const int is_ld = (ld_op >= 0x20u && ld_op <= 0x26u) && (ld_rt != 0u);
const uint32_t pc_phys = pc & 0x1FFFFFFFu;
/* OpenBIOS executes cardfasttrack both from ROM and from its low-RAM
* kernel copy (for example 0x3554..0x36D4). Its hand-written dependent
* load requires the real R3000A value delay. Game-owned dirty RAM crosses
* mixed compiled/interpreted boundaries that do not carry this pending
* writeback yet, so preserve the historical eager-value contract there. */
const int in_bios_rom =
pc_phys >= 0x1FC00000u && pc_phys < 0x1FC80000u;
const int in_bios_kernel_ram = pc_phys < 0x00010000u;
const int is_ld = (in_bios_rom || in_bios_kernel_ram) &&
(ld_op >= 0x20u && ld_op <= 0x26u) &&
(ld_rt != 0u);
const uint32_t ld_before = is_ld ? cpu->gpr[ld_rt] : 0u;
const int rv = exec_one_fetched_inner(cpu, pc, insn, next_pc_out);
@@ -97,6 +97,14 @@ def main():
dispatch_inner = body(interp, "dirty_ram_dispatch_inner")
if "(!current_page_dirty || next_page != current_page)" not in dispatch_inner:
raise AssertionError("page fast path does not preserve clean-miss behavior")
exec_one = body(interp, "exec_one_fetched")
for scope_guard in (
"pc_phys >= 0x1FC00000u && pc_phys < 0x1FC80000u",
"pc_phys < 0x00010000u",
"(in_bios_rom || in_bios_kernel_ram)"):
if scope_guard not in exec_one:
raise AssertionError(
f"load-delay value semantics lost BIOS ownership guard: {scope_guard}")
# RFE backend-contract parity: the recompiled rfe and every overlay shard
# (ABI v12) call psx_rfe_mark_escape after popping SR, and the generated
# trampoline runs psx_rfe_escape_check after each return. The interpreter