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;
}
template <bool preserveCause>
bool Cop1::CheckFPUUsable() {
template<>
bool Cop1::CheckFPUUsable<true>() {
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<true>())
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<true>();
template bool Cop1::CheckFPUUsable<false>();
template<>
bool Cop1::CheckFPUUsable<false>() {
if (!CheckFPUUsable<true>()) return false;
fcr31.cause = {};
return true;
}
template <typename T>
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<convert>()) \
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<convert>()) \
return; \
const type res = v##res;
@@ -641,8 +639,7 @@ void Cop1::cvtsw(const Instruction instr) {
return;
const auto fs = FGR_S<s32>(regs.cop0.status, instr.fs());
CHECK_FPE(float, fd, fs)
if (!CheckResult(fd))
return;
if (!CheckResult(fd)) return;
FGR_D<float>(regs.cop0.status, instr.fd()) = fd;
}