Finally passing every FPU test in Lemmy's suite

This commit is contained in:
irisz64
2025-09-03 12:11:38 +02:00
parent 7de697ab64
commit 6737977183

View File

@@ -258,25 +258,23 @@ bool Cop1::CheckArgs(const T f1, const T f2) {
return true; return true;
} }
template <bool preserveCause> template<>
bool Cop1::CheckFPUUsable() { bool Cop1::CheckFPUUsable<true>() {
Registers& regs = Core::GetRegs(); Registers& regs = Core::GetRegs();
if constexpr (preserveCause) { if (!regs.cop0.status.cu1) {
if (!regs.cop0.status.cu1) { regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 1, regs.oldPC);
regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 1, regs.oldPC); return false;
return false;
}
} else {
if (!CheckFPUUsable<true>())
return false;
fcr31.cause = {};
} }
return true; return true;
} }
template bool Cop1::CheckFPUUsable<true>(); template<>
template bool Cop1::CheckFPUUsable<false>(); bool Cop1::CheckFPUUsable<false>() {
if (!CheckFPUUsable<true>()) return false;
fcr31.cause = {};
return true;
}
template <typename T> template <typename T>
FORCE_INLINE T FlushResult(T f, const u32 round) { FORCE_INLINE T FlushResult(T f, const u32 round) {
@@ -427,14 +425,14 @@ bool Cop1::SetCauseInvalid() {
#define CHECK_FPE_IMPL(type, res, operation, convert) \ #define CHECK_FPE_IMPL(type, res, operation, convert) \
feclearexcept(FE_ALL_EXCEPT); \ feclearexcept(FE_ALL_EXCEPT); \
volatile type v##res = [&]() -> type { return operation; }(); \ volatile type v##res = [&]() __attribute__((noinline)) -> type { return operation; }(); \
if (TestExceptions<convert>()) \ if (TestExceptions<convert>()) \
return; \ return; \
type res = v##res; type res = v##res;
#define CHECK_FPE_IMPL_CONST(type, res, operation, convert) \ #define CHECK_FPE_IMPL_CONST(type, res, operation, convert) \
feclearexcept(FE_ALL_EXCEPT); \ feclearexcept(FE_ALL_EXCEPT); \
volatile type v##res = [&]() -> type { return operation; }(); \ volatile type v##res = [&]() __attribute__((noinline)) -> type { return operation; }(); \
if (TestExceptions<convert>()) \ if (TestExceptions<convert>()) \
return; \ return; \
const type res = v##res; const type res = v##res;
@@ -641,8 +639,7 @@ void Cop1::cvtsw(const Instruction instr) {
return; return;
const auto fs = FGR_S<s32>(regs.cop0.status, instr.fs()); const auto fs = FGR_S<s32>(regs.cop0.status, instr.fs());
CHECK_FPE(float, fd, fs) CHECK_FPE(float, fd, fs)
if (!CheckResult(fd)) if (!CheckResult(fd)) return;
return;
FGR_D<float>(regs.cop0.status, instr.fd()) = fd; FGR_D<float>(regs.cop0.status, instr.fd()) = fd;
} }