mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-03 03:05:18 +02:00
The ARM64 IR JIT crashed on any load/store to a constant address with the top bit set and an offset too large for an immediate - the kernel RAM mirror at 0x88000000, for instance. PrepareSrc1Address is careful about this: a constant address like 0x89100010 arrives sign-extended as a negative int64_t, and the (imm & 0xC0000000) == 0x80000000 check turns it back into the positive value it should be. But when the offset doesn't fit an immediate we fall back to loading it into a register and using the register-offset addressing mode, which only takes the W half of that register plus an extend - and we asked for SXTW, undoing the fix and pointing the access ~2GB below the memory view. Sign extension is still right when the offset is genuinely negative, which happens when the base is a pointerified register and the displacement is a negative one from the MIPS instruction. So extend based on the sign of imm. Found by the Jit unit test, which stores to 0x89100000 and segfaults in the JIT_IR phase - only reproducible on an actual ARM64 CPU, which is why it never showed up on CI. The RISC-V and LoongArch backends get this case right already.