From 673797718385500ee2aed3cee882a53ee2d2630b Mon Sep 17 00:00:00 2001 From: irisz64 Date: Wed, 3 Sep 2025 12:11:38 +0200 Subject: [PATCH] Finally passing every FPU test in Lemmy's suite --- .../core/interpreter/cop1instructions.cpp | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/backend/core/interpreter/cop1instructions.cpp b/src/backend/core/interpreter/cop1instructions.cpp index 1f7dff88..3f0f891f 100644 --- a/src/backend/core/interpreter/cop1instructions.cpp +++ b/src/backend/core/interpreter/cop1instructions.cpp @@ -258,25 +258,23 @@ bool Cop1::CheckArgs(const T f1, const T f2) { return true; } -template -bool Cop1::CheckFPUUsable() { +template<> +bool Cop1::CheckFPUUsable() { Registers& regs = Core::GetRegs(); - if constexpr (preserveCause) { - if (!regs.cop0.status.cu1) { - regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 1, regs.oldPC); - return false; - } - } else { - if (!CheckFPUUsable()) - return false; - fcr31.cause = {}; + if (!regs.cop0.status.cu1) { + regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 1, regs.oldPC); + return false; } return true; } -template bool Cop1::CheckFPUUsable(); -template bool Cop1::CheckFPUUsable(); +template<> +bool Cop1::CheckFPUUsable() { + if (!CheckFPUUsable()) return false; + fcr31.cause = {}; + return true; +} template FORCE_INLINE T FlushResult(T f, const u32 round) { @@ -427,14 +425,14 @@ bool Cop1::SetCauseInvalid() { #define CHECK_FPE_IMPL(type, res, operation, convert) \ feclearexcept(FE_ALL_EXCEPT); \ - volatile type v##res = [&]() -> type { return operation; }(); \ + volatile type v##res = [&]() __attribute__((noinline)) -> type { return operation; }(); \ if (TestExceptions()) \ return; \ type res = v##res; #define CHECK_FPE_IMPL_CONST(type, res, operation, convert) \ feclearexcept(FE_ALL_EXCEPT); \ - volatile type v##res = [&]() -> type { return operation; }(); \ + volatile type v##res = [&]() __attribute__((noinline)) -> type { return operation; }(); \ if (TestExceptions()) \ return; \ const type res = v##res; @@ -641,8 +639,7 @@ void Cop1::cvtsw(const Instruction instr) { return; const auto fs = FGR_S(regs.cop0.status, instr.fs()); CHECK_FPE(float, fd, fs) - if (!CheckResult(fd)) - return; + if (!CheckResult(fd)) return; FGR_D(regs.cop0.status, instr.fd()) = fd; }