Files
ARMSX2/tests
Brian Degenhardt 71248899ba IOP: probe the SMC coverage array by HWADDR in the store stubs
The out-of-line RAM-store fast path computed its g_iopCodeCov index from the
mirror-collapsed RAM offset (addr & (ExposedIopRam-1)), while iopCovAdjust and
psxRecClearMem key that same array by HWADDR -- which strips the KSEG base but
does not collapse the RAM mirrors, because recLUT_SetPage writes
psxhwLUT[page] = -(pagebase << 16) and pagebase is 0 across the whole 0x00-0x7f
RAM window.

In the default 2MB configuration the two disagree. A block compiled at
0x00214000 registers coverage at granule 0x2140; a store to that same address
probed granule 0x140, read zero, and returned without clearing. The C path
would have cleared it -- psxRecClearMem's own O(1) reject and its recBlocks
lookup both use HWADDR, so store and block agree there. So this was a real
regression introduced with the stubs, not the pre-existing blindness the
in-file comment claimed.

Above the region gate every reachable address satisfies
HWADDR == addr & (kIopCovSpan-1): bits 23-28 are zero, and the psxhwLUT
subtraction for a KSEG mirror is exactly the removal of bits 29-31. So the fix
is one extra AND, and none at all in the 8MB configuration where the RAM mask
already spans the coverage window.

The stub is now exactly as blind as the C path it replaces, no more: a store
to a *different* mirror of a block's page still misses, because recBlocks is
itself keyed by HWADDR. Rewrote the comment that asserted this was all
harmless, since it would have stopped the next reader from looking.

New test compiles a block at the 2MB RAM mirror and JIT-stores to it; red
before this change (JIT 0x0BAD vs interpreter 0x1337). The two existing mirror
tests use KSEG mirrors, where every domain agrees and the bug cannot show.

recompiler_tests 1443/1443.
2026-07-26 15:01:08 -07:00
..