LD wrote cpuRegs.GPR.r[_Rt_].UD[0] unconditionally, so `ld $0, ...`
followed by a read of $0 returned the loaded doubleword instead of zero.
All eleven of its neighbours already guard: LB/LBU/LH/LHU/LW/LWU/LWL/LWR/
LDL/LDR early-out on !_Rt_, and LQ routes through gpr_GetWritePtr, whose
reason for existing is the dummy zero slot. Both recompilers were already
correct.
Shape matches LW/LDL/LDR: perform the read first so its side effects
still happen, then drop the result if the destination is $0.
EeLsuConsoleConformance.DISABLED_AllLoadsMatchConsole recorded this as
the one divergence from the console capture; the case now passes on both
engines, so the divergence table is gone and the always-on
LoadsMatchConsole scores every case against silicon directly.
Idea by pstef.
A probe was built with the ps2dev toolchain, run on a PS2, and streamed
its results back over ps2link's `host:` channel. Its two records are the
oracle behind autocases_sa.h.
SA is four bits wide. `mtsa 0x10` leaves SA at 0, `mtsa 0xFFFFFFFF` at
0xF, and MFSA reads the masked value back, so the mask belongs at the
write. PCSX2 stored the raw 32 bits, which was the root cause of three
different QFSRV behaviors for sa >= 16: UB in the interpreter, a
guest-controlled out-of-bounds host read in the x86 recompiler, and a
defensive mask in the arm64 one - and upstream recMTSA masks on its
const path but not its runtime path, so x86 disagrees with itself too.
Masking at MTSA makes all of it unreachable at once.
Leaving it would mean permanently suppressing a JIT-vs-interp diff.
EeRecTraps.MtsaCopiesFullRegister and MtsaConstFoldsAtCompile asserted
the old behavior and were updated to the console's value.
Two defects found and recorded
1, link branches with rs == $31 judge the condition on the pre-link
value on console: `bltzal $ra` with $ra = -1 is taken. Their no-link
twins agree on all six probe values, so the link write does not feed the
comparison. PCSX2 links first in six functions (EE BGEZAL / BLTZAL /
BGEZALL / BLTZALL, IOP psxBGEZAL/psxBLTZAL); 12 rows x 2 engines
diverge. This settles the question
IopLsuBranchConsoleConformance.LinkBranchesWithRaAsSourceArePinned left
open. The assembler refuses to encode these at all, which is why no
capture had them - they went in as raw .words, each verified by
disassembling it back. `jalr $31,$31` rode along as a positive control
and passed: the console jumps to the OLD $ra, corroborating the psxJALR
ordering fix on a second CPU.
2, PCCR's writable mask is 0x800FFBFE - exactly the layout R5900.h
documents, with pad0, pad1 and the eleven Reserved bits reading back as
zero. PCSX2 stores it verbatim; 14 rows x 2 engines diverge. PCR0/PCR1
are fully 32-bit writable, so PCSX2 is already right there.
DISABLED_AllSaPerfMatchesConsole is the graduation tripwire for both.
DiffJitVsInterp harness (EE/IOP/VU synthetic JIT-vs-interpreter tests) plus the
shared capture/divergence-localizer infrastructure (vu_capture, ee_divtrace,
microVU_Divtrace, VU1Trace) and the test hooks they install in interp/GIF/COP2 paths.
All hook sites are guarded by PCSX2_RECOMPILER_TESTS and compile out of release builds.
Co-Authored-By: Ryan Walklin <ryan@testtoast.com>
Co-Authored-By: Brian Degenhardt <bmd@bmdhacks.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
And associated cleanup.
On most compilers these days, it'll either inline the memset with vector
fills or rep stosq, or outline with a call to memset.
I trust the compiler is probably going to make a better decision here,
than manual SSE intrinsics.
Ends up a couple of percent faster in FMV decoding.
[SAVEVERSION+] VM struct changes.
- Serial/title is now linked to disc, instead of running ELF.
- Save states can be created during BIOS boot.
- Patches now apply based on the executing CRC, and only after the
entry point starts executing (fixes multi-game discs).
- Add "Fast Forward Boot" option.
- Split achievements download and activation, downloads occur on
initialization, but are not activated until after the ELF loads.
- Prevent HostFS access while in PS1 mode.
- Remove multiple sources of truth for ELF/CRC/etc.
- Move ELF state from global scope to VMManager.
- Prevent game fixes and hw fixes being active while booting game.
- Simplify game update.
- Flush recompilers after ELF loads. No point keeping boot code around
which gets overwritten.