Huge refactor: Make Core a singleton
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
#include <cfenv>
|
||||
#include <cmath>
|
||||
#include <Interpreter.hpp>
|
||||
#include <registers/Cop1.hpp>
|
||||
#include <registers/Registers.hpp>
|
||||
#include <Core.hpp>
|
||||
#include <utils/FloatingPoint.hpp>
|
||||
|
||||
namespace n64 {
|
||||
@@ -134,6 +132,7 @@ bool Cop1::isqnan<double>(const double f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckCVTArg<s32>(const float f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
case FP_INFINITE:
|
||||
@@ -154,6 +153,7 @@ bool Cop1::CheckCVTArg<s32>(const float f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckCVTArg<s32>(const double f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
case FP_INFINITE:
|
||||
@@ -174,6 +174,7 @@ bool Cop1::CheckCVTArg<s32>(const double f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckCVTArg<s64>(const float f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
case FP_INFINITE:
|
||||
@@ -194,6 +195,7 @@ bool Cop1::CheckCVTArg<s64>(const float f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckCVTArg<s64>(const double f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
case FP_INFINITE:
|
||||
@@ -214,6 +216,7 @@ bool Cop1::CheckCVTArg<s64>(const double f) {
|
||||
|
||||
template <typename T>
|
||||
bool Cop1::CheckArg(const T f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
SetCauseUnimplemented();
|
||||
@@ -231,6 +234,7 @@ bool Cop1::CheckArg(const T f) {
|
||||
|
||||
template <typename T>
|
||||
bool Cop1::CheckArgs(const T f1, const T f2) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
auto class1 = std::fpclassify(f1), class2 = std::fpclassify(f2);
|
||||
if ((class1 == FP_NAN && !isqnan(f1)) || (class2 == FP_NAN && !isqnan(f2))) {
|
||||
SetCauseUnimplemented();
|
||||
@@ -256,6 +260,7 @@ bool Cop1::CheckArgs(const T f1, const T f2) {
|
||||
|
||||
template <bool preserveCause>
|
||||
bool Cop1::CheckFPUUsable() {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if constexpr (preserveCause) {
|
||||
if (!regs.cop0.status.cu1) {
|
||||
regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 1, regs.oldPC);
|
||||
@@ -290,6 +295,7 @@ FORCE_INLINE T FlushResult(T f, const u32 round) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckResult<float>(float &f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
if (!fcr31.fs || fcr31.enable.underflow || fcr31.enable.inexact_operation) {
|
||||
@@ -312,6 +318,7 @@ bool Cop1::CheckResult<float>(float &f) {
|
||||
|
||||
template <>
|
||||
bool Cop1::CheckResult<double>(double &f) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
switch (std::fpclassify(f)) {
|
||||
case FP_SUBNORMAL:
|
||||
if (!fcr31.fs || fcr31.enable.underflow || fcr31.enable.inexact_operation) {
|
||||
@@ -334,6 +341,7 @@ bool Cop1::CheckResult<double>(double &f) {
|
||||
|
||||
template <bool cvt>
|
||||
bool Cop1::TestExceptions() {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
const u32 exc = std::fetestexcept(FE_ALL_EXCEPT);
|
||||
|
||||
if (!exc)
|
||||
@@ -437,6 +445,7 @@ bool Cop1::SetCauseInvalid() {
|
||||
#define CHECK_FPE_CONV_CONST(type, res, operation) CHECK_FPE_IMPL_CONST(type, res, operation, true)
|
||||
|
||||
void Cop1::absd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -449,6 +458,7 @@ void Cop1::absd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::abss(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -461,6 +471,7 @@ void Cop1::abss(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::adds(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -474,6 +485,7 @@ void Cop1::adds(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::addd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -487,6 +499,7 @@ void Cop1::addd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ceills(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -497,6 +510,7 @@ void Cop1::ceills(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ceilld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -507,6 +521,7 @@ void Cop1::ceilld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ceilws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -517,6 +532,7 @@ void Cop1::ceilws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ceilwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -527,6 +543,7 @@ void Cop1::ceilwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cfc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
const u8 fd = RD(instr);
|
||||
@@ -545,6 +562,7 @@ void Cop1::cfc1(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::ctc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
const u8 fs = RD(instr);
|
||||
@@ -592,6 +610,7 @@ void Cop1::ctc1(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtds(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -604,6 +623,7 @@ void Cop1::cvtds(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtsd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -616,6 +636,7 @@ void Cop1::cvtsd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtsw(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<s32>(regs.cop0.status, FS(instr));
|
||||
@@ -626,6 +647,7 @@ void Cop1::cvtsw(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtsl(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<s64>(regs.cop0.status, FS(instr));
|
||||
@@ -641,6 +663,7 @@ void Cop1::cvtsl(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -651,6 +674,7 @@ void Cop1::cvtwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -661,6 +685,7 @@ void Cop1::cvtws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -671,6 +696,7 @@ void Cop1::cvtls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtdw(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<s32>(regs.cop0.status, FS(instr));
|
||||
@@ -681,6 +707,7 @@ void Cop1::cvtdw(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtdl(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
|
||||
@@ -698,6 +725,7 @@ void Cop1::cvtdl(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::cvtld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -709,6 +737,7 @@ void Cop1::cvtld(const u32 instr) {
|
||||
|
||||
template <typename T, bool quiet, bool cf>
|
||||
bool Cop1::XORDERED(const T fs, const T ft) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (std::isnan(fs) || std::isnan(ft)) {
|
||||
if (std::isnan(fs) && (!quiet || isqnan(fs)) && SetCauseInvalid()) {
|
||||
regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC);
|
||||
@@ -730,6 +759,7 @@ bool Cop1::XORDERED(const T fs, const T ft) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cf(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
|
||||
@@ -741,6 +771,7 @@ void Cop1::cf(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cun(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -751,6 +782,7 @@ void Cop1::cun(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::ceq(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -762,6 +794,7 @@ void Cop1::ceq(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cueq(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -773,6 +806,7 @@ void Cop1::cueq(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::colt(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -784,6 +818,7 @@ void Cop1::colt(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cult(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -795,6 +830,7 @@ void Cop1::cult(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cole(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -806,6 +842,7 @@ void Cop1::cole(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cule(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -817,6 +854,7 @@ void Cop1::cule(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::csf(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -827,6 +865,7 @@ void Cop1::csf(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cngle(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -837,6 +876,7 @@ void Cop1::cngle(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cseq(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -848,6 +888,7 @@ void Cop1::cseq(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cngl(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -859,6 +900,7 @@ void Cop1::cngl(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::clt(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -870,6 +912,7 @@ void Cop1::clt(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cnge(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -881,6 +924,7 @@ void Cop1::cnge(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cle(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -892,6 +936,7 @@ void Cop1::cle(const u32 instr) {
|
||||
|
||||
template <typename T>
|
||||
void Cop1::cngt(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const T fs = FGR_S<T>(regs.cop0.status, FS(instr));
|
||||
@@ -935,6 +980,7 @@ template void Cop1::cle<double>(u32 instr);
|
||||
template void Cop1::cngt<double>(u32 instr);
|
||||
|
||||
void Cop1::divs(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -948,6 +994,7 @@ void Cop1::divs(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::divd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -961,6 +1008,7 @@ void Cop1::divd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::muls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -974,6 +1022,7 @@ void Cop1::muls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::muld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -987,6 +1036,7 @@ void Cop1::muld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::subs(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1000,6 +1050,7 @@ void Cop1::subs(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::subd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1015,12 +1066,14 @@ void Cop1::subd(const u32 instr) {
|
||||
void Cop1::movs(const u32 instr) { movd(instr); }
|
||||
|
||||
void Cop1::movd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
FGR_D<double>(regs.cop0.status, FD(instr)) = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
}
|
||||
|
||||
void Cop1::negs(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1033,6 +1086,7 @@ void Cop1::negs(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::negd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1045,6 +1099,7 @@ void Cop1::negd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::sqrts(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1057,6 +1112,7 @@ void Cop1::sqrts(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::sqrtd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1069,6 +1125,7 @@ void Cop1::sqrtd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::roundls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1083,6 +1140,7 @@ void Cop1::roundls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::roundld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1097,6 +1155,7 @@ void Cop1::roundld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::roundws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1111,6 +1170,7 @@ void Cop1::roundws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::roundwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1125,6 +1185,7 @@ void Cop1::roundwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::floorls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1135,6 +1196,7 @@ void Cop1::floorls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::floorld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1145,6 +1207,7 @@ void Cop1::floorld(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::floorws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1155,6 +1218,7 @@ void Cop1::floorws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::floorwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1165,6 +1229,7 @@ void Cop1::floorwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::truncws(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1179,6 +1244,7 @@ void Cop1::truncws(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::truncwd(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1193,6 +1259,7 @@ void Cop1::truncwd(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::truncls(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<float>(regs.cop0.status, FS(instr));
|
||||
@@ -1207,6 +1274,7 @@ void Cop1::truncls(const u32 instr) {
|
||||
}
|
||||
|
||||
void Cop1::truncld(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
const auto fs = FGR_S<double>(regs.cop0.status, FS(instr));
|
||||
@@ -1220,53 +1288,62 @@ void Cop1::truncld(const u32 instr) {
|
||||
FGR_D<s64>(regs.cop0.status, FD(instr)) = fd;
|
||||
}
|
||||
|
||||
void Cop1::lwc1(Mem &mem, u32 instr) {
|
||||
void Cop1::lwc1(u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
||||
|
||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) {
|
||||
regs.cop0.HandleTLBException(addr);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC);
|
||||
} else {
|
||||
const u32 data = mem.Read<u32>(regs, physical);
|
||||
const u32 data = mem.Read<u32>(physical);
|
||||
FGR_T<u32>(regs.cop0.status, FT(instr)) = data;
|
||||
}
|
||||
}
|
||||
|
||||
void Cop1::swc1(Mem &mem, u32 instr) {
|
||||
void Cop1::swc1(u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
||||
|
||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) {
|
||||
regs.cop0.HandleTLBException(addr);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
mem.Write<u32>(regs, physical, FGR_T<u32>(regs.cop0.status, FT(instr)));
|
||||
mem.Write<u32>(physical, FGR_T<u32>(regs.cop0.status, FT(instr)));
|
||||
}
|
||||
}
|
||||
|
||||
void Cop1::ldc1(Mem &mem, u32 instr) {
|
||||
void Cop1::ldc1(u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
||||
|
||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) {
|
||||
regs.cop0.HandleTLBException(addr);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC);
|
||||
} else {
|
||||
const u64 data = mem.Read<u64>(regs, physical);
|
||||
const u64 data = mem.Read<u64>(physical);
|
||||
FGR_T<u64>(regs.cop0.status, FT(instr)) = data;
|
||||
}
|
||||
}
|
||||
|
||||
void Cop1::sdc1(Mem &mem, u32 instr) {
|
||||
void Cop1::sdc1(u32 instr) {
|
||||
Mem& mem = Core::GetInstance().cpu->GetMem();
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
||||
|
||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) {
|
||||
regs.cop0.HandleTLBException(addr);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
|
||||
} else {
|
||||
mem.Write(regs, physical, FGR_T<u64>(regs.cop0.status, FT(instr)));
|
||||
mem.Write(physical, FGR_T<u64>(regs.cop0.status, FT(instr)));
|
||||
}
|
||||
}
|
||||
|
||||
void Cop1::unimplemented() {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable())
|
||||
return;
|
||||
SetCauseUnimplemented();
|
||||
@@ -1274,24 +1351,28 @@ void Cop1::unimplemented() {
|
||||
}
|
||||
|
||||
void Cop1::mfc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
regs.Write(RT(instr), FGR_T<s32>(regs.cop0.status, FS(instr)));
|
||||
}
|
||||
|
||||
void Cop1::dmfc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
regs.Write(RT(instr), FGR_S<s64>(regs.cop0.status, FS(instr)));
|
||||
}
|
||||
|
||||
void Cop1::mtc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
FGR_T<s32>(regs.cop0.status, FS(instr)) = regs.Read<s64>(RT(instr));
|
||||
}
|
||||
|
||||
void Cop1::dmtc1(const u32 instr) {
|
||||
Registers& regs = Core::GetInstance().cpu->GetRegs();
|
||||
if (!CheckFPUUsable<true>())
|
||||
return;
|
||||
FGR_S<u64>(regs.cop0.status, FS(instr)) = regs.Read<s64>(RT(instr));
|
||||
|
||||
Reference in New Issue
Block a user