From 5865a560eb6c98368d627e758041f2971c373d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2026 10:47:39 -0600 Subject: [PATCH] ARM JITs: Mask what ctc1 writes to fcr31 Only the rounding mode, flags, enables, cause, FCC and FS bits can be written (0x0181FFFF, pspautotests cpu/fpu/fcr), as the interpreter, IR and x86 already have it. Both ARM JITs stored the whole value. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/MIPS/ARM/ArmCompFPU.cpp | 6 +++--- Core/MIPS/ARM64/Arm64CompFPU.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompFPU.cpp b/Core/MIPS/ARM/ArmCompFPU.cpp index 463f9719a0..1f386e9d18 100644 --- a/Core/MIPS/ARM/ArmCompFPU.cpp +++ b/Core/MIPS/ARM/ArmCompFPU.cpp @@ -431,9 +431,9 @@ void ArmJit::Comp_mxc1(MIPSOpcode op) gpr.MapDirtyIn(MIPS_REG_FPCOND, rt); } - // Update MIPS state - // TODO: Technically, should mask by 0x0181FFFF. Maybe just put all of FCR31 in the reg? - STR(gpr.R(rt), CTXREG, offsetof(MIPSState, fcr31)); + // Update MIPS state. Only these bits can be written (pspautotests cpu/fpu/fcr). + ANDI2R(SCRATCHREG1, gpr.R(rt), 0x0181FFFF, SCRATCHREG2); + STR(SCRATCHREG1, CTXREG, offsetof(MIPSState, fcr31)); if (!wasImm) { #if PPSSPP_ARCH(ARMV7) UBFX(gpr.R(MIPS_REG_FPCOND), gpr.R(rt), 23, 1); diff --git a/Core/MIPS/ARM64/Arm64CompFPU.cpp b/Core/MIPS/ARM64/Arm64CompFPU.cpp index 5f858eeebd..b2bc9083cf 100644 --- a/Core/MIPS/ARM64/Arm64CompFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompFPU.cpp @@ -396,9 +396,9 @@ void Arm64Jit::Comp_mxc1(MIPSOpcode op) gpr.MapDirtyIn(MIPS_REG_FPCOND, rt); } - // Update MIPS state - // TODO: Technically, should mask by 0x0181FFFF. Maybe just put all of FCR31 in the reg? - STR(INDEX_UNSIGNED, gpr.R(rt), CTXREG, offsetof(MIPSState, fcr31)); + // Update MIPS state. Only these bits can be written (pspautotests cpu/fpu/fcr). + ANDI2R(SCRATCH1, gpr.R(rt), 0x0181FFFF, SCRATCH2); + STR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, fcr31)); if (!wasImm) { UBFX(gpr.R(MIPS_REG_FPCOND), gpr.R(rt), 23, 1); // TODO: We do have the fcr31 value in a register here, could use that in UpdateRoundingMode to avoid reloading it.