Finally passing every FPU test in Lemmy's suite
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user