vtlb_Miss raised the exception under the arm64 recompiler and returned,
on the assumption that the rec would pick cpuRegs.pc up at the next
dispatch. Nothing picks it up: the block runs on and its tail writes its
own branch target over the vector PC, while cpuException has already
latched Status.EXL. cpuException leaves EPC alone whenever EXL is
already set, so from the first swallowed miss onward every exception
keeps its predecessor's EPC, and the guest kernel's syscall epilogue
erets to an address belonging to the fault.
Report the miss and continue instead, as the x86 rec already does. The
guest's handler still does not run, so a title that needs demand paging
still cannot work under the rec; a stray miss now stays local to the
instruction. ee_rec_tlb_divert_tests.cpp describes the divert and stays
disabled.
With nothing left to set s_recTlbMissOccurred, the poll after every
interpreter call goes too. It could not have covered the raise anyway:
only the interpreter-call sites had it, so a flag set at an inline
access sat there until an unrelated later recCall consumed it and
diverted on a pc belonging to neither.
This gives up the one case the rec did handle, a miss in a branch delay
slot reaching the vector through the cpuRegs.branch bracket epilogue.
Its recompiler half moves to the disabled file; the interpreter half
stays live, beside a new test pinning the rec's behaviour. The bracket
itself stays: the tlb_fallback_* handlers raise from a delay slot on
their own.
iFPUd widened every operand with ToDoubleFrom: eleven instructions
branching on exponent field 0xff, since a PS2 single with that exponent
is an ordinary large number IEEE reads as Inf or NaN. Against a
relocated slot the widening is one Fmul, and a compare goes from 34.75
host instructions to 8.75. CVT.W loses its NaN fix-up the same way,
leaving Fcvtzs.
Which format the file is in follows the clamp mode, so modes 0-2 keep
the architectural word in the low half. FPRreg's accessors read the
format and the emitters read the mode; the two engines meet at the
boundaries the word is still observable at -- MFC1, MTC1, MOV.S, the two
conversions, LWC1, SWC1 and the allocator's fill and spill.
The unscale factor takes q11 and d10's mask moves to the relocated
layout, so the allocator's callee-saved range is q12-q15.
Merges yaps2/main (github.com/yaps2/yaps2, c16b88cb7) into ARMSX2,
replacing the arm64 recompiler family with the yaps2 JITs and importing
the yaps2 testing, perf, and libretro infrastructure. Common ancestor is
upstream PCSX2 342db5152 (2026-06-19); git auto-merged all but 38 files.
Replaced (deleted in this merge, recoverable from history):
- arm64/aR5900*, aR3000A*, aVU* -> arm64/iR5900*/iR3000A*/microVU*-arm64:
EE static-pin register file with lazy dirty tracking, dual-residence
allocator, IOP block linking, native COP2 macro ops, inline unaligned
fastmem, persisted VU program cache, call-ret shadow ring, VU0 spin
fast-forward.
- MVU_DIFF shadow-run hooks in shared VU interpreter TUs (superseded by
the offline vurunner JIT-vs-interp oracle).
Imported from yaps2:
- tests/ctest/core/recompilers: ~80 gtest suites (EE/IOP/VU differential
harnesses, fuzzers, ABI digest tripwire, capture format pins) plus the
gs_vertex_tests kernel oracle.
- pcsx2-vurunner / pcsx2-eerunner headless capture-replay runners.
- tools/perf counter-based A/B rigs, perf jitdump productionization,
PmuCounters, clang-perf/clang-handheld presets.
- pcsx2-libretro core (ENABLE_LIBRETRO, default OFF; rename pending).
- GS vertex-kick fast path (GV series): TBL-based packed parse,
register-resident kick, scalar-outcode cull, fused draw-rect/FindMinMax.
- Null renderer, VK_KHR_display direct WSI, swapchain PresentStats.
- SPU2 NEON mixer vectorization, EE timer read clamp (NFL 2K5 hang),
IOP ioman signed-compare fix, assorted UB fixes.
Kept from ARMSX2 in the both-touched files:
- iOS dual-map W^X and fastmem-unavailable resilience (Memory, HostSys,
vtlb). The split data/code area model is retained; both areas now take
fixed VA hints so cached VU JIT code stays deterministic on Linux.
- Android thread-affinity model, VMState shutdown early-outs, all
platform frontends, branding, CI, RetroAchievements identity/policy.
- GSDeviceVK: ARMSX2's push-descriptor decision logic (Mali crash gate,
proprietary-vs-turnip Adreno split) merged with yaps2's descriptor-pool
exhaustion recovery (flush + render-pass restart instead of dropped
binds). Vendor feature policy is the union: Mali fbfetch policy with
MediaTek/G57/Xclipse gates from ARMSX2; Adreno stencil/ROV/
test-and-sample-depth hang avoidance and no_ps2_z_quantization from
yaps2.
Build-system notes:
- The Qt debugger is now gated behind ENABLE_QT_DEBUGGER (default off on
arm64) so handheld builds drop the KDDockWidgets dependency.
- GSDeviceNone and remaining yaps2 GS code were ported to the newer
upstream GSTexture Usage-flags API.
The replaced backend's interpreter-fallback glue (intExecuteOneInst,
AndroidEEOpHist) and the EEDiffVerify runtime differ are retained for
now; dead pieces will be removed in a follow-up commit.
OSD now hides via RenderOverlays mirror of EmuConfig.GS->GSConfig + seed-false on first launch. Rumble: forward SetPadVibrationIntensity to Native::onPadRumble on Android (mono core had no call site). Library: bundled PS3 XMB-wave MP4 as default background, drawn edge-to-edge via ArmsBackdrop backgroundLayer (fixes landscape strip). In-app on-screen keyboard for library search; Recently Played shelf selection highlight; settings category tabs reachable via Row+horizontalScroll. Persian (fa) translation; gold RetroAchievements trophy.
- R5900 _cpuEventTest_Shared: bail out early on VMState::Stopping/Shutdown and
on IsExecutionInterrupted() so the EE leaves Execute() promptly on stop
(previously hit the ~5s shutdown timeout).
- native-lib Host::RequestVMShutdown: no-op if already Shutdown. The queued
task could re-set Stopping after the run loop already reached Shutdown,
sticking s_state at Stopping so the next Initialize failed 'already running'
-- kick back to library on the 2nd game boot.
SharedMemoryMappingArea::Create() gains a fixed_base_hint so AllocateMemoryMap can
pin the JIT arena at a constant VA (kArenaBase=4GB, 256MB-stride fallback) on arm64;
the VTLB fastmem backpatch thunk (RecStubs), ArmAddressRecorder relocation hooks
(AsmHelpers), and the cpuTlbMiss rec-vs-interp PC split (R5900) round out the arm64
memory layer. Windows arm64 is a no-op stub.
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>