From 89c8109823e34c4e996e7c6c10a00308e289b694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 21 Sep 2026 15:36:49 -0600 Subject: [PATCH] Honor the guest FPU rounding mode outside x86 and arm64 ApplyHostRoundingMode and RestoreHostRoundingMode only had SSE2 and ARM64 branches, so everywhere else the guest's rounding mode was silently ignored and ceil and floor rounded to nearest. Fall back to fesetround, which covers riscv64 and loongarch64 and whatever comes next. That clears both rounding mismatches in cpu/fpu/fpu on those two. What's left there is flush-to-zero, which neither ISA has any control for, so the test still fails - a denormal result survives where the PSP would have flushed it. Co-Authored-By: Claude Opus 5 (1M context) --- Core/MIPS/MIPS.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 8ba3733d0d..828d52170d 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include #include #include @@ -105,6 +106,13 @@ void ApplyHostRoundingMode(const MIPSState *mips) { } ARM64WriteFPCR(fpcr); +#else + // No control register access written for this architecture, so go through the standard + // call. Rounding is all it can do: there is no portable flush-to-zero, and neither + // riscv64 nor loongarch64 has one in the base ISA either, so denormals stay as they are. + static const int roundLookup[4] = { FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD, FE_DOWNWARD }; + fesetround(roundLookup[rmode]); + (void)ftz; #endif } } @@ -121,6 +129,8 @@ void RestoreHostRoundingMode() { fpcr &= ~(7 << 22); // Clear bits [23:22] for rounding, 24 for FTZ // Write back the modified FPCR ARM64WriteFPCR(fpcr); +#else + fesetround(FE_TONEAREST); #endif }