Interpreter: Remove remaining System::GetInstance() and global ppcState.

This commit is contained in:
Admiral H. Curtiss 2023-03-24 21:58:41 +01:00
parent 7de01597c6
commit b568cf5268
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
10 changed files with 201 additions and 211 deletions

View File

@ -15,20 +15,20 @@ enum class ProgramExceptionCause : u32
Trap = 1 << (31 - 14), Trap = 1 << (31 - 14),
}; };
inline void GenerateAlignmentException(u32 address) inline void GenerateAlignmentException(PowerPC::PowerPCState& ppc_state, u32 address)
{ {
PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT; ppc_state.Exceptions |= EXCEPTION_ALIGNMENT;
PowerPC::ppcState.spr[SPR_DAR] = address; ppc_state.spr[SPR_DAR] = address;
} }
inline void GenerateDSIException(u32 address) inline void GenerateDSIException(PowerPC::PowerPCState& ppc_state, u32 address)
{ {
PowerPC::ppcState.Exceptions |= EXCEPTION_DSI; ppc_state.Exceptions |= EXCEPTION_DSI;
PowerPC::ppcState.spr[SPR_DAR] = address; ppc_state.spr[SPR_DAR] = address;
} }
inline void GenerateProgramException(ProgramExceptionCause cause) inline void GenerateProgramException(PowerPC::PowerPCState& ppc_state, ProgramExceptionCause cause)
{ {
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM; ppc_state.Exceptions |= EXCEPTION_PROGRAM;
PowerPC::ppcState.spr[SPR_SRR1] = static_cast<u32>(cause); ppc_state.spr[SPR_SRR1] = static_cast<u32>(cause);
} }

View File

@ -148,7 +148,7 @@ int Interpreter::SingleStepInner()
{ {
if (IsInvalidPairedSingleExecution(m_prev_inst)) if (IsInvalidPairedSingleExecution(m_prev_inst))
{ {
GenerateProgramException(ProgramExceptionCause::IllegalInstruction); GenerateProgramException(m_ppc_state, ProgramExceptionCause::IllegalInstruction);
CheckExceptions(); CheckExceptions();
} }
else if (m_ppc_state.msr.FP) else if (m_ppc_state.msr.FP)

View File

@ -117,7 +117,7 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst)
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }

View File

@ -25,29 +25,29 @@ enum class FPCC
FU = 1, // ? FU = 1, // ?
}; };
inline void CheckFPExceptions(UReg_FPSCR fpscr) inline void CheckFPExceptions(PowerPC::PowerPCState& ppc_state)
{ {
if (fpscr.FEX && (PowerPC::ppcState.msr.FE0 || PowerPC::ppcState.msr.FE1)) if (ppc_state.fpscr.FEX && (ppc_state.msr.FE0 || ppc_state.msr.FE1))
GenerateProgramException(ProgramExceptionCause::FloatingPoint); GenerateProgramException(ppc_state, ProgramExceptionCause::FloatingPoint);
} }
inline void UpdateFPExceptionSummary(UReg_FPSCR* fpscr) inline void UpdateFPExceptionSummary(PowerPC::PowerPCState& ppc_state)
{ {
fpscr->VX = (fpscr->Hex & FPSCR_VX_ANY) != 0; ppc_state.fpscr.VX = (ppc_state.fpscr.Hex & FPSCR_VX_ANY) != 0;
fpscr->FEX = ((fpscr->Hex >> 22) & (fpscr->Hex & FPSCR_ANY_E)) != 0; ppc_state.fpscr.FEX = ((ppc_state.fpscr.Hex >> 22) & (ppc_state.fpscr.Hex & FPSCR_ANY_E)) != 0;
CheckFPExceptions(*fpscr); CheckFPExceptions(ppc_state);
} }
inline void SetFPException(UReg_FPSCR* fpscr, u32 mask) inline void SetFPException(PowerPC::PowerPCState& ppc_state, u32 mask)
{ {
if ((fpscr->Hex & mask) != mask) if ((ppc_state.fpscr.Hex & mask) != mask)
{ {
fpscr->FX = 1; ppc_state.fpscr.FX = 1;
} }
fpscr->Hex |= mask; ppc_state.fpscr.Hex |= mask;
UpdateFPExceptionSummary(fpscr); UpdateFPExceptionSummary(ppc_state);
} }
inline float ForceSingle(const UReg_FPSCR& fpscr, double value) inline float ForceSingle(const UReg_FPSCR& fpscr, double value)
@ -111,17 +111,17 @@ struct FPResult
{ {
bool HasNoInvalidExceptions() const { return (exception & FPSCR_VX_ANY) == 0; } bool HasNoInvalidExceptions() const { return (exception & FPSCR_VX_ANY) == 0; }
void SetException(UReg_FPSCR* fpscr, FPSCRExceptionFlag flag) void SetException(PowerPC::PowerPCState& ppc_state, FPSCRExceptionFlag flag)
{ {
exception = flag; exception = flag;
SetFPException(fpscr, flag); SetFPException(ppc_state, flag);
} }
double value = 0.0; double value = 0.0;
FPSCRExceptionFlag exception{}; FPSCRExceptionFlag exception{};
}; };
inline FPResult NI_mul(UReg_FPSCR* fpscr, double a, double b) inline FPResult NI_mul(PowerPC::PowerPCState& ppc_state, double a, double b)
{ {
FPResult result{a * b}; FPResult result{a * b};
@ -129,10 +129,10 @@ inline FPResult NI_mul(UReg_FPSCR* fpscr, double a, double b)
{ {
if (Common::IsSNAN(a) || Common::IsSNAN(b)) if (Common::IsSNAN(a) || Common::IsSNAN(b))
{ {
result.SetException(fpscr, FPSCR_VXSNAN); result.SetException(ppc_state, FPSCR_VXSNAN);
} }
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (std::isnan(a)) if (std::isnan(a))
{ {
@ -146,14 +146,14 @@ inline FPResult NI_mul(UReg_FPSCR* fpscr, double a, double b)
} }
result.value = PPC_NAN; result.value = PPC_NAN;
result.SetException(fpscr, FPSCR_VXIMZ); result.SetException(ppc_state, FPSCR_VXIMZ);
return result; return result;
} }
return result; return result;
} }
inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b) inline FPResult NI_div(PowerPC::PowerPCState& ppc_state, double a, double b)
{ {
FPResult result{a / b}; FPResult result{a / b};
@ -161,16 +161,16 @@ inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b)
{ {
if (b == 0.0) if (b == 0.0)
{ {
result.SetException(fpscr, FPSCR_ZX); result.SetException(ppc_state, FPSCR_ZX);
return result; return result;
} }
} }
else if (std::isnan(result.value)) else if (std::isnan(result.value))
{ {
if (Common::IsSNAN(a) || Common::IsSNAN(b)) if (Common::IsSNAN(a) || Common::IsSNAN(b))
result.SetException(fpscr, FPSCR_VXSNAN); result.SetException(ppc_state, FPSCR_VXSNAN);
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (std::isnan(a)) if (std::isnan(a))
{ {
@ -184,9 +184,9 @@ inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b)
} }
if (b == 0.0) if (b == 0.0)
result.SetException(fpscr, FPSCR_VXZDZ); result.SetException(ppc_state, FPSCR_VXZDZ);
else if (std::isinf(a) && std::isinf(b)) else if (std::isinf(a) && std::isinf(b))
result.SetException(fpscr, FPSCR_VXIDI); result.SetException(ppc_state, FPSCR_VXIDI);
result.value = PPC_NAN; result.value = PPC_NAN;
return result; return result;
@ -195,16 +195,16 @@ inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b)
return result; return result;
} }
inline FPResult NI_add(UReg_FPSCR* fpscr, double a, double b) inline FPResult NI_add(PowerPC::PowerPCState& ppc_state, double a, double b)
{ {
FPResult result{a + b}; FPResult result{a + b};
if (std::isnan(result.value)) if (std::isnan(result.value))
{ {
if (Common::IsSNAN(a) || Common::IsSNAN(b)) if (Common::IsSNAN(a) || Common::IsSNAN(b))
result.SetException(fpscr, FPSCR_VXSNAN); result.SetException(ppc_state, FPSCR_VXSNAN);
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (std::isnan(a)) if (std::isnan(a))
{ {
@ -217,27 +217,27 @@ inline FPResult NI_add(UReg_FPSCR* fpscr, double a, double b)
return result; return result;
} }
result.SetException(fpscr, FPSCR_VXISI); result.SetException(ppc_state, FPSCR_VXISI);
result.value = PPC_NAN; result.value = PPC_NAN;
return result; return result;
} }
if (std::isinf(a) || std::isinf(b)) if (std::isinf(a) || std::isinf(b))
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
return result; return result;
} }
inline FPResult NI_sub(UReg_FPSCR* fpscr, double a, double b) inline FPResult NI_sub(PowerPC::PowerPCState& ppc_state, double a, double b)
{ {
FPResult result{a - b}; FPResult result{a - b};
if (std::isnan(result.value)) if (std::isnan(result.value))
{ {
if (Common::IsSNAN(a) || Common::IsSNAN(b)) if (Common::IsSNAN(a) || Common::IsSNAN(b))
result.SetException(fpscr, FPSCR_VXSNAN); result.SetException(ppc_state, FPSCR_VXSNAN);
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (std::isnan(a)) if (std::isnan(a))
{ {
@ -250,13 +250,13 @@ inline FPResult NI_sub(UReg_FPSCR* fpscr, double a, double b)
return result; return result;
} }
result.SetException(fpscr, FPSCR_VXISI); result.SetException(ppc_state, FPSCR_VXISI);
result.value = PPC_NAN; result.value = PPC_NAN;
return result; return result;
} }
if (std::isinf(a) || std::isinf(b)) if (std::isinf(a) || std::isinf(b))
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
return result; return result;
} }
@ -264,16 +264,16 @@ inline FPResult NI_sub(UReg_FPSCR* fpscr, double a, double b)
// FMA instructions on PowerPC are weird: // FMA instructions on PowerPC are weird:
// They calculate (a * c) + b, but the order in which // They calculate (a * c) + b, but the order in which
// inputs are checked for NaN is still a, b, c. // inputs are checked for NaN is still a, b, c.
inline FPResult NI_madd(UReg_FPSCR* fpscr, double a, double c, double b) inline FPResult NI_madd(PowerPC::PowerPCState& ppc_state, double a, double c, double b)
{ {
FPResult result{std::fma(a, c, b)}; FPResult result{std::fma(a, c, b)};
if (std::isnan(result.value)) if (std::isnan(result.value))
{ {
if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c)) if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c))
result.SetException(fpscr, FPSCR_VXSNAN); result.SetException(ppc_state, FPSCR_VXSNAN);
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (std::isnan(a)) if (std::isnan(a))
{ {
@ -291,27 +291,27 @@ inline FPResult NI_madd(UReg_FPSCR* fpscr, double a, double c, double b)
return result; return result;
} }
result.SetException(fpscr, std::isnan(a * c) ? FPSCR_VXIMZ : FPSCR_VXISI); result.SetException(ppc_state, std::isnan(a * c) ? FPSCR_VXIMZ : FPSCR_VXISI);
result.value = PPC_NAN; result.value = PPC_NAN;
return result; return result;
} }
if (std::isinf(a) || std::isinf(b) || std::isinf(c)) if (std::isinf(a) || std::isinf(b) || std::isinf(c))
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
return result; return result;
} }
inline FPResult NI_msub(UReg_FPSCR* fpscr, double a, double c, double b) inline FPResult NI_msub(PowerPC::PowerPCState& ppc_state, double a, double c, double b)
{ {
FPResult result{std::fma(a, c, -b)}; FPResult result{std::fma(a, c, -b)};
if (std::isnan(result.value)) if (std::isnan(result.value))
{ {
if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c)) if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c))
result.SetException(fpscr, FPSCR_VXSNAN); result.SetException(ppc_state, FPSCR_VXSNAN);
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (std::isnan(a)) if (std::isnan(a))
{ {
@ -329,13 +329,13 @@ inline FPResult NI_msub(UReg_FPSCR* fpscr, double a, double c, double b)
return result; return result;
} }
result.SetException(fpscr, std::isnan(a * c) ? FPSCR_VXIMZ : FPSCR_VXISI); result.SetException(ppc_state, std::isnan(a * c) ? FPSCR_VXIMZ : FPSCR_VXISI);
result.value = PPC_NAN; result.value = PPC_NAN;
return result; return result;
} }
if (std::isinf(a) || std::isinf(b) || std::isinf(c)) if (std::isinf(a) || std::isinf(b) || std::isinf(c))
fpscr->ClearFIFR(); ppc_state.fpscr.ClearFIFR();
return result; return result;
} }

View File

@ -23,13 +23,13 @@ enum class RoundingMode
TowardsNegativeInfinity = 0b11 TowardsNegativeInfinity = 0b11
}; };
void SetFI(UReg_FPSCR* fpscr, u32 FI) void SetFI(PowerPC::PowerPCState& ppc_state, u32 FI)
{ {
if (FI != 0) if (FI != 0)
{ {
SetFPException(fpscr, FPSCR_XX); SetFPException(ppc_state, FPSCR_XX);
} }
fpscr->FI = FI; ppc_state.fpscr.FI = FI;
} }
// Note that the convert to integer operation is defined // Note that the convert to integer operation is defined
@ -45,24 +45,24 @@ void ConvertToInteger(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst,
if (std::isnan(b)) if (std::isnan(b))
{ {
if (Common::IsSNAN(b)) if (Common::IsSNAN(b))
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); SetFPException(ppc_state, FPSCR_VXSNAN);
value = 0x80000000; value = 0x80000000;
SetFPException(&ppc_state.fpscr, FPSCR_VXCVI); SetFPException(ppc_state, FPSCR_VXCVI);
exception_occurred = true; exception_occurred = true;
} }
else if (b > static_cast<double>(0x7fffffff)) else if (b > static_cast<double>(0x7fffffff))
{ {
// Positive large operand or +inf // Positive large operand or +inf
value = 0x7fffffff; value = 0x7fffffff;
SetFPException(&ppc_state.fpscr, FPSCR_VXCVI); SetFPException(ppc_state, FPSCR_VXCVI);
exception_occurred = true; exception_occurred = true;
} }
else if (b < -static_cast<double>(0x80000000)) else if (b < -static_cast<double>(0x80000000))
{ {
// Negative large operand or -inf // Negative large operand or -inf
value = 0x80000000; value = 0x80000000;
SetFPException(&ppc_state.fpscr, FPSCR_VXCVI); SetFPException(ppc_state, FPSCR_VXCVI);
exception_occurred = true; exception_occurred = true;
} }
else else
@ -109,7 +109,7 @@ void ConvertToInteger(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst,
else else
{ {
// Also sets FPSCR[XX] // Also sets FPSCR[XX]
SetFI(&ppc_state.fpscr, 1); SetFI(ppc_state, 1);
ppc_state.fpscr.FR = fabs(di) > fabs(b); ppc_state.fpscr.FR = fabs(di) > fabs(b);
} }
} }
@ -145,15 +145,15 @@ void Interpreter::Helper_FloatCompareOrdered(PowerPC::PowerPCState& ppc_state,
compare_result = FPCC::FU; compare_result = FPCC::FU;
if (Common::IsSNAN(fa) || Common::IsSNAN(fb)) if (Common::IsSNAN(fa) || Common::IsSNAN(fb))
{ {
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); SetFPException(ppc_state, FPSCR_VXSNAN);
if (ppc_state.fpscr.VE == 0) if (ppc_state.fpscr.VE == 0)
{ {
SetFPException(&ppc_state.fpscr, FPSCR_VXVC); SetFPException(ppc_state, FPSCR_VXVC);
} }
} }
else // QNaN else // QNaN
{ {
SetFPException(&ppc_state.fpscr, FPSCR_VXVC); SetFPException(ppc_state, FPSCR_VXVC);
} }
} }
else if (fa < fb) else if (fa < fb)
@ -188,7 +188,7 @@ void Interpreter::Helper_FloatCompareUnordered(PowerPC::PowerPCState& ppc_state,
if (Common::IsSNAN(fa) || Common::IsSNAN(fb)) if (Common::IsSNAN(fa) || Common::IsSNAN(fb))
{ {
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); SetFPException(ppc_state, FPSCR_VXSNAN);
} }
} }
else if (fa < fb) else if (fa < fb)
@ -310,7 +310,7 @@ void Interpreter::frspx(Interpreter& interpreter, UGeckoInstruction inst) // ro
const bool is_snan = Common::IsSNAN(b); const bool is_snan = Common::IsSNAN(b);
if (is_snan) if (is_snan)
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); SetFPException(ppc_state, FPSCR_VXSNAN);
if (!is_snan || ppc_state.fpscr.VE == 0) if (!is_snan || ppc_state.fpscr.VE == 0)
{ {
@ -322,7 +322,7 @@ void Interpreter::frspx(Interpreter& interpreter, UGeckoInstruction inst) // ro
} }
else else
{ {
SetFI(&ppc_state.fpscr, b != rounded); SetFI(ppc_state, b != rounded);
ppc_state.fpscr.FR = fabs(rounded) > fabs(b); ppc_state.fpscr.FR = fabs(rounded) > fabs(b);
ppc_state.UpdateFPRFSingle(rounded); ppc_state.UpdateFPRFSingle(rounded);
ppc_state.ps[inst.FD].Fill(rounded); ppc_state.ps[inst.FD].Fill(rounded);
@ -338,7 +338,7 @@ void Interpreter::fmulx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const FPResult product = NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble()); const FPResult product = NI_mul(ppc_state, a.PS0AsDouble(), c.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
@ -360,7 +360,7 @@ void Interpreter::fmulsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult d_value = NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c_value); const FPResult d_value = NI_mul(ppc_state, a.PS0AsDouble(), c_value);
if (ppc_state.fpscr.VE == 0 || d_value.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || d_value.HasNoInvalidExceptions())
{ {
@ -382,8 +382,7 @@ void Interpreter::fmaddx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const FPResult product = const FPResult product = NI_madd(ppc_state, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
@ -404,7 +403,7 @@ void Interpreter::fmaddsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult d_value = NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); const FPResult d_value = NI_madd(ppc_state, a.PS0AsDouble(), c_value, b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || d_value.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || d_value.HasNoInvalidExceptions())
{ {
@ -426,7 +425,7 @@ void Interpreter::faddx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const FPResult sum = NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult sum = NI_add(ppc_state, a.PS0AsDouble(), b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || sum.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || sum.HasNoInvalidExceptions())
{ {
@ -444,7 +443,7 @@ void Interpreter::faddsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const FPResult sum = NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult sum = NI_add(ppc_state, a.PS0AsDouble(), b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || sum.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || sum.HasNoInvalidExceptions())
{ {
@ -463,7 +462,7 @@ void Interpreter::fdivx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const FPResult quotient = NI_div(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult quotient = NI_div(ppc_state, a.PS0AsDouble(), b.PS0AsDouble());
const bool not_divide_by_zero = ppc_state.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX; const bool not_divide_by_zero = ppc_state.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX;
const bool not_invalid = ppc_state.fpscr.VE == 0 || quotient.HasNoInvalidExceptions(); const bool not_invalid = ppc_state.fpscr.VE == 0 || quotient.HasNoInvalidExceptions();
@ -484,7 +483,7 @@ void Interpreter::fdivsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const FPResult quotient = NI_div(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult quotient = NI_div(ppc_state, a.PS0AsDouble(), b.PS0AsDouble());
const bool not_divide_by_zero = ppc_state.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX; const bool not_divide_by_zero = ppc_state.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX;
const bool not_invalid = ppc_state.fpscr.VE == 0 || quotient.HasNoInvalidExceptions(); const bool not_invalid = ppc_state.fpscr.VE == 0 || quotient.HasNoInvalidExceptions();
@ -513,7 +512,7 @@ void Interpreter::fresx(Interpreter& interpreter, UGeckoInstruction inst)
if (b == 0.0) if (b == 0.0)
{ {
SetFPException(&ppc_state.fpscr, FPSCR_ZX); SetFPException(ppc_state, FPSCR_ZX);
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.ZE == 0) if (ppc_state.fpscr.ZE == 0)
@ -521,7 +520,7 @@ void Interpreter::fresx(Interpreter& interpreter, UGeckoInstruction inst)
} }
else if (Common::IsSNAN(b)) else if (Common::IsSNAN(b))
{ {
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); SetFPException(ppc_state, FPSCR_VXSNAN);
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.VE == 0) if (ppc_state.fpscr.VE == 0)
@ -552,7 +551,7 @@ void Interpreter::frsqrtex(Interpreter& interpreter, UGeckoInstruction inst)
if (b < 0.0) if (b < 0.0)
{ {
SetFPException(&ppc_state.fpscr, FPSCR_VXSQRT); SetFPException(ppc_state, FPSCR_VXSQRT);
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.VE == 0) if (ppc_state.fpscr.VE == 0)
@ -560,7 +559,7 @@ void Interpreter::frsqrtex(Interpreter& interpreter, UGeckoInstruction inst)
} }
else if (b == 0.0) else if (b == 0.0)
{ {
SetFPException(&ppc_state.fpscr, FPSCR_ZX); SetFPException(ppc_state, FPSCR_ZX);
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.ZE == 0) if (ppc_state.fpscr.ZE == 0)
@ -568,7 +567,7 @@ void Interpreter::frsqrtex(Interpreter& interpreter, UGeckoInstruction inst)
} }
else if (Common::IsSNAN(b)) else if (Common::IsSNAN(b))
{ {
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); SetFPException(ppc_state, FPSCR_VXSNAN);
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.VE == 0) if (ppc_state.fpscr.VE == 0)
@ -593,8 +592,7 @@ void Interpreter::fmsubx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const FPResult product = const FPResult product = NI_msub(ppc_state, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
@ -615,7 +613,7 @@ void Interpreter::fmsubsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult product = NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); const FPResult product = NI_msub(ppc_state, a.PS0AsDouble(), c_value, b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
@ -635,8 +633,7 @@ void Interpreter::fnmaddx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const FPResult product = const FPResult product = NI_madd(ppc_state, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
@ -659,7 +656,7 @@ void Interpreter::fnmaddsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult product = NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); const FPResult product = NI_madd(ppc_state, a.PS0AsDouble(), c_value, b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
@ -681,8 +678,7 @@ void Interpreter::fnmsubx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const FPResult product = const FPResult product = NI_msub(ppc_state, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
@ -705,7 +701,7 @@ void Interpreter::fnmsubsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult product = NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); const FPResult product = NI_msub(ppc_state, a.PS0AsDouble(), c_value, b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
@ -726,7 +722,7 @@ void Interpreter::fsubx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const FPResult difference = NI_sub(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult difference = NI_sub(ppc_state, a.PS0AsDouble(), b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || difference.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || difference.HasNoInvalidExceptions())
{ {
@ -745,7 +741,7 @@ void Interpreter::fsubsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const FPResult difference = NI_sub(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult difference = NI_sub(ppc_state, a.PS0AsDouble(), b.PS0AsDouble());
if (ppc_state.fpscr.VE == 0 || difference.HasNoInvalidExceptions()) if (ppc_state.fpscr.VE == 0 || difference.HasNoInvalidExceptions())
{ {

View File

@ -149,7 +149,7 @@ void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst)
if ((a < b && (TO & 0x10) != 0) || (a > b && (TO & 0x08) != 0) || (a == b && (TO & 0x04) != 0) || if ((a < b && (TO & 0x10) != 0) || (a > b && (TO & 0x08) != 0) || (a == b && (TO & 0x04) != 0) ||
(u32(a) < u32(b) && (TO & 0x02) != 0) || (u32(a) > u32(b) && (TO & 0x01) != 0)) (u32(a) < u32(b) && (TO & 0x02) != 0) || (u32(a) > u32(b) && (TO & 0x01) != 0))
{ {
GenerateProgramException(ProgramExceptionCause::Trap); GenerateProgramException(ppc_state, ProgramExceptionCause::Trap);
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
interpreter.m_end_block = true; // Dunno about this interpreter.m_end_block = true; // Dunno about this
} }
@ -380,7 +380,7 @@ void Interpreter::tw(Interpreter& interpreter, UGeckoInstruction inst)
if ((a < b && (TO & 0x10) != 0) || (a > b && (TO & 0x08) != 0) || (a == b && (TO & 0x04) != 0) || if ((a < b && (TO & 0x10) != 0) || (a > b && (TO & 0x08) != 0) || (a == b && (TO & 0x04) != 0) ||
((u32(a) < u32(b)) && (TO & 0x02) != 0) || ((u32(a) > u32(b)) && (TO & 0x01) != 0)) ((u32(a) < u32(b)) && (TO & 0x02) != 0) || ((u32(a) > u32(b)) && (TO & 0x01) != 0))
{ {
GenerateProgramException(ProgramExceptionCause::Trap); GenerateProgramException(ppc_state, ProgramExceptionCause::Trap);
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
interpreter.m_end_block = true; // Dunno about this interpreter.m_end_block = true; // Dunno about this
} }

View File

@ -66,7 +66,7 @@ void Interpreter::lfd(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -83,7 +83,7 @@ void Interpreter::lfdu(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -103,7 +103,7 @@ void Interpreter::lfdux(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -123,7 +123,7 @@ void Interpreter::lfdx(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -140,7 +140,7 @@ void Interpreter::lfs(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -160,7 +160,7 @@ void Interpreter::lfsu(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -181,7 +181,7 @@ void Interpreter::lfsux(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -202,7 +202,7 @@ void Interpreter::lfsx(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -271,7 +271,7 @@ void Interpreter::lmw(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0 || ppc_state.msr.LE) if ((address & 0b11) != 0 || ppc_state.msr.LE)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -300,7 +300,7 @@ void Interpreter::stmw(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0 || ppc_state.msr.LE) if ((address & 0b11) != 0 || ppc_state.msr.LE)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -366,7 +366,7 @@ void Interpreter::stfd(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -380,7 +380,7 @@ void Interpreter::stfdu(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -398,7 +398,7 @@ void Interpreter::stfs(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -412,7 +412,7 @@ void Interpreter::stfsu(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -485,7 +485,7 @@ void Interpreter::dcbi(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -537,7 +537,7 @@ void Interpreter::dcbz(Interpreter& interpreter, UGeckoInstruction inst)
if (!HID0(ppc_state).DCE) if (!HID0(ppc_state).DCE)
{ {
GenerateAlignmentException(dcbz_addr); GenerateAlignmentException(ppc_state, dcbz_addr);
return; return;
} }
@ -560,7 +560,7 @@ void Interpreter::dcbz_l(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (!HID2(ppc_state).LCE) if (!HID2(ppc_state).LCE)
{ {
GenerateProgramException(ProgramExceptionCause::IllegalInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
return; return;
} }
@ -568,7 +568,7 @@ void Interpreter::dcbz_l(Interpreter& interpreter, UGeckoInstruction inst)
if (!HID0(ppc_state).DCE) if (!HID0(ppc_state).DCE)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -584,13 +584,13 @@ void Interpreter::eciwx(Interpreter& interpreter, UGeckoInstruction inst)
if ((ppc_state.spr[SPR_EAR] & 0x80000000) == 0) if ((ppc_state.spr[SPR_EAR] & 0x80000000) == 0)
{ {
GenerateDSIException(EA); GenerateDSIException(ppc_state, EA);
return; return;
} }
if ((EA & 0b11) != 0) if ((EA & 0b11) != 0)
{ {
GenerateAlignmentException(EA); GenerateAlignmentException(ppc_state, EA);
return; return;
} }
@ -604,13 +604,13 @@ void Interpreter::ecowx(Interpreter& interpreter, UGeckoInstruction inst)
if ((ppc_state.spr[SPR_EAR] & 0x80000000) == 0) if ((ppc_state.spr[SPR_EAR] & 0x80000000) == 0)
{ {
GenerateDSIException(EA); GenerateDSIException(ppc_state, EA);
return; return;
} }
if ((EA & 0b11) != 0) if ((EA & 0b11) != 0)
{ {
GenerateAlignmentException(EA); GenerateAlignmentException(ppc_state, EA);
return; return;
} }
@ -724,7 +724,7 @@ void Interpreter::lswx(Interpreter& interpreter, UGeckoInstruction inst)
if (ppc_state.msr.LE) if (ppc_state.msr.LE)
{ {
GenerateAlignmentException(EA); GenerateAlignmentException(ppc_state, EA);
return; return;
} }
@ -811,7 +811,7 @@ void Interpreter::stfdux(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -829,7 +829,7 @@ void Interpreter::stfdx(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -844,7 +844,7 @@ void Interpreter::stfiwx(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -858,7 +858,7 @@ void Interpreter::stfsux(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -876,7 +876,7 @@ void Interpreter::stfsx(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -918,7 +918,7 @@ void Interpreter::lswi(Interpreter& interpreter, UGeckoInstruction inst)
if (ppc_state.msr.LE) if (ppc_state.msr.LE)
{ {
GenerateAlignmentException(EA); GenerateAlignmentException(ppc_state, EA);
return; return;
} }
@ -966,7 +966,7 @@ void Interpreter::stswi(Interpreter& interpreter, UGeckoInstruction inst)
if (ppc_state.msr.LE) if (ppc_state.msr.LE)
{ {
GenerateAlignmentException(EA); GenerateAlignmentException(ppc_state, EA);
return; return;
} }
@ -1005,7 +1005,7 @@ void Interpreter::stswx(Interpreter& interpreter, UGeckoInstruction inst)
if (ppc_state.msr.LE) if (ppc_state.msr.LE)
{ {
GenerateAlignmentException(EA); GenerateAlignmentException(ppc_state, EA);
return; return;
} }
@ -1046,7 +1046,7 @@ void Interpreter::lwarx(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -1068,7 +1068,7 @@ void Interpreter::stwcxd(Interpreter& interpreter, UGeckoInstruction inst)
if ((address & 0b11) != 0) if ((address & 0b11) != 0)
{ {
GenerateAlignmentException(address); GenerateAlignmentException(ppc_state, address);
return; return;
} }
@ -1119,7 +1119,7 @@ void Interpreter::tlbie(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -1134,7 +1134,7 @@ void Interpreter::tlbsync(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
} }
// Ignored // Ignored

View File

@ -313,7 +313,7 @@ void Interpreter::psq_l(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0) if (HID2(ppc_state).LSQE == 0)
{ {
GenerateProgramException(ProgramExceptionCause::IllegalInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
return; return;
} }
@ -326,7 +326,7 @@ void Interpreter::psq_lu(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0) if (HID2(ppc_state).LSQE == 0)
{ {
GenerateProgramException(ProgramExceptionCause::IllegalInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
return; return;
} }
@ -346,7 +346,7 @@ void Interpreter::psq_st(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0) if (HID2(ppc_state).LSQE == 0)
{ {
GenerateProgramException(ProgramExceptionCause::IllegalInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
return; return;
} }
@ -359,7 +359,7 @@ void Interpreter::psq_stu(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0) if (HID2(ppc_state).LSQE == 0)
{ {
GenerateProgramException(ProgramExceptionCause::IllegalInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
return; return;
} }

View File

@ -126,10 +126,10 @@ void Interpreter::ps_div(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const float ps0 = ForceSingle(ppc_state.fpscr, const float ps0 =
NI_div(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_div(ppc_state, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 = ForceSingle(ppc_state.fpscr, const float ps1 =
NI_div(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_div(ppc_state, a.PS1AsDouble(), b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -147,7 +147,7 @@ void Interpreter::ps_res(Interpreter& interpreter, UGeckoInstruction inst)
if (a == 0.0 || b == 0.0) if (a == 0.0 || b == 0.0)
{ {
SetFPException(&ppc_state.fpscr, FPSCR_ZX); SetFPException(ppc_state, FPSCR_ZX);
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
} }
@ -155,7 +155,7 @@ void Interpreter::ps_res(Interpreter& interpreter, UGeckoInstruction inst)
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (Common::IsSNAN(a) || Common::IsSNAN(b)) if (Common::IsSNAN(a) || Common::IsSNAN(b))
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); SetFPException(ppc_state, FPSCR_VXSNAN);
const double ps0 = Common::ApproximateReciprocal(a); const double ps0 = Common::ApproximateReciprocal(a);
const double ps1 = Common::ApproximateReciprocal(b); const double ps1 = Common::ApproximateReciprocal(b);
@ -175,13 +175,13 @@ void Interpreter::ps_rsqrte(Interpreter& interpreter, UGeckoInstruction inst)
if (ps0 == 0.0 || ps1 == 0.0) if (ps0 == 0.0 || ps1 == 0.0)
{ {
SetFPException(&ppc_state.fpscr, FPSCR_ZX); SetFPException(ppc_state, FPSCR_ZX);
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
} }
if (ps0 < 0.0 || ps1 < 0.0) if (ps0 < 0.0 || ps1 < 0.0)
{ {
SetFPException(&ppc_state.fpscr, FPSCR_VXSQRT); SetFPException(ppc_state, FPSCR_VXSQRT);
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
} }
@ -189,7 +189,7 @@ void Interpreter::ps_rsqrte(Interpreter& interpreter, UGeckoInstruction inst)
ppc_state.fpscr.ClearFIFR(); ppc_state.fpscr.ClearFIFR();
if (Common::IsSNAN(ps0) || Common::IsSNAN(ps1)) if (Common::IsSNAN(ps0) || Common::IsSNAN(ps1))
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); SetFPException(ppc_state, FPSCR_VXSNAN);
const float dst_ps0 = ForceSingle(ppc_state.fpscr, Common::ApproximateReciprocalSquareRoot(ps0)); const float dst_ps0 = ForceSingle(ppc_state.fpscr, Common::ApproximateReciprocalSquareRoot(ps0));
const float dst_ps1 = ForceSingle(ppc_state.fpscr, Common::ApproximateReciprocalSquareRoot(ps1)); const float dst_ps1 = ForceSingle(ppc_state.fpscr, Common::ApproximateReciprocalSquareRoot(ps1));
@ -207,10 +207,10 @@ void Interpreter::ps_sub(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const float ps0 = ForceSingle(ppc_state.fpscr, const float ps0 =
NI_sub(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_sub(ppc_state, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 = ForceSingle(ppc_state.fpscr, const float ps1 =
NI_sub(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_sub(ppc_state, a.PS1AsDouble(), b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -225,10 +225,10 @@ void Interpreter::ps_add(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA]; const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const float ps0 = ForceSingle(ppc_state.fpscr, const float ps0 =
NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_add(ppc_state, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 = ForceSingle(ppc_state.fpscr, const float ps1 =
NI_add(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_add(ppc_state, a.PS1AsDouble(), b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -246,10 +246,8 @@ void Interpreter::ps_mul(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = const float ps0 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS0AsDouble(), c0).value);
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c0).value); const float ps1 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS1AsDouble(), c1).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c1).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -268,10 +266,10 @@ void Interpreter::ps_msub(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = ForceSingle( const float ps0 =
ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_msub(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 = ForceSingle( const float ps1 =
ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_msub(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -290,10 +288,10 @@ void Interpreter::ps_madd(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = ForceSingle( const float ps0 =
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 = ForceSingle( const float ps1 =
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -312,10 +310,10 @@ void Interpreter::ps_nmsub(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float tmp0 = ForceSingle( const float tmp0 =
ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_msub(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float tmp1 = ForceSingle( const float tmp1 =
ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_msub(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float ps0 = std::isnan(tmp0) ? tmp0 : -tmp0; const float ps0 = std::isnan(tmp0) ? tmp0 : -tmp0;
const float ps1 = std::isnan(tmp1) ? tmp1 : -tmp1; const float ps1 = std::isnan(tmp1) ? tmp1 : -tmp1;
@ -337,10 +335,10 @@ void Interpreter::ps_nmadd(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float tmp0 = ForceSingle( const float tmp0 =
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float tmp1 = ForceSingle( const float tmp1 =
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float ps0 = std::isnan(tmp0) ? tmp0 : -tmp0; const float ps0 = std::isnan(tmp0) ? tmp0 : -tmp0;
const float ps1 = std::isnan(tmp1) ? tmp1 : -tmp1; const float ps1 = std::isnan(tmp1) ? tmp1 : -tmp1;
@ -359,8 +357,8 @@ void Interpreter::ps_sum0(Interpreter& interpreter, UGeckoInstruction inst)
const auto& b = ppc_state.ps[inst.FB]; const auto& b = ppc_state.ps[inst.FB];
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const float ps0 = ForceSingle(ppc_state.fpscr, const float ps0 =
NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_add(ppc_state, a.PS0AsDouble(), b.PS1AsDouble()).value);
const float ps1 = ForceSingle(ppc_state.fpscr, c.PS1AsDouble()); const float ps1 = ForceSingle(ppc_state.fpscr, c.PS1AsDouble());
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
@ -378,8 +376,8 @@ void Interpreter::ps_sum1(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const float ps0 = ForceSingle(ppc_state.fpscr, c.PS0AsDouble()); const float ps0 = ForceSingle(ppc_state.fpscr, c.PS0AsDouble());
const float ps1 = ForceSingle(ppc_state.fpscr, const float ps1 =
NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_add(ppc_state, a.PS0AsDouble(), b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps1); ppc_state.UpdateFPRFSingle(ps1);
@ -395,10 +393,8 @@ void Interpreter::ps_muls0(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const float ps0 = const float ps0 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS0AsDouble(), c0).value);
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c0).value); const float ps1 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS1AsDouble(), c0).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c0).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -414,10 +410,8 @@ void Interpreter::ps_muls1(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = const float ps0 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS0AsDouble(), c1).value);
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c1).value); const float ps1 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS1AsDouble(), c1).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c1).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -434,10 +428,10 @@ void Interpreter::ps_madds0(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const float ps0 = ForceSingle( const float ps0 =
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 = ForceSingle( const float ps1 =
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c0, b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS1AsDouble(), c0, b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);
@ -454,10 +448,10 @@ void Interpreter::ps_madds1(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC]; const auto& c = ppc_state.ps[inst.FC];
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = ForceSingle( const float ps0 =
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c1, b.PS0AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS0AsDouble(), c1, b.PS0AsDouble()).value);
const float ps1 = ForceSingle( const float ps1 =
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1); ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0); ppc_state.UpdateFPRFSingle(ps0);

View File

@ -26,9 +26,9 @@ mffsx: 80036650 (huh?)
*/ */
static void FPSCRUpdated(UReg_FPSCR* fpscr) static void FPSCRUpdated(PowerPC::PowerPCState& ppc_state)
{ {
UpdateFPExceptionSummary(fpscr); UpdateFPExceptionSummary(ppc_state);
PowerPC::RoundingModeUpdated(); PowerPC::RoundingModeUpdated();
} }
@ -38,7 +38,7 @@ void Interpreter::mtfsb0x(Interpreter& interpreter, UGeckoInstruction inst)
u32 b = 0x80000000 >> inst.CRBD; u32 b = 0x80000000 >> inst.CRBD;
ppc_state.fpscr.Hex &= ~b; ppc_state.fpscr.Hex &= ~b;
FPSCRUpdated(&ppc_state.fpscr); FPSCRUpdated(ppc_state);
if (inst.Rc) if (inst.Rc)
ppc_state.UpdateCR1(); ppc_state.UpdateCR1();
@ -52,11 +52,11 @@ void Interpreter::mtfsb1x(Interpreter& interpreter, UGeckoInstruction inst)
const u32 b = 0x80000000 >> bit; const u32 b = 0x80000000 >> bit;
if ((b & FPSCR_ANY_X) != 0) if ((b & FPSCR_ANY_X) != 0)
SetFPException(&ppc_state.fpscr, b); SetFPException(ppc_state, b);
else else
ppc_state.fpscr |= b; ppc_state.fpscr |= b;
FPSCRUpdated(&ppc_state.fpscr); FPSCRUpdated(ppc_state);
if (inst.Rc) if (inst.Rc)
ppc_state.UpdateCR1(); ppc_state.UpdateCR1();
@ -72,7 +72,7 @@ void Interpreter::mtfsfix(Interpreter& interpreter, UGeckoInstruction inst)
ppc_state.fpscr = (ppc_state.fpscr.Hex & ~mask) | (imm >> (4 * field)); ppc_state.fpscr = (ppc_state.fpscr.Hex & ~mask) | (imm >> (4 * field));
FPSCRUpdated(&ppc_state.fpscr); FPSCRUpdated(ppc_state);
if (inst.Rc) if (inst.Rc)
ppc_state.UpdateCR1(); ppc_state.UpdateCR1();
@ -91,7 +91,7 @@ void Interpreter::mtfsfx(Interpreter& interpreter, UGeckoInstruction inst)
ppc_state.fpscr = ppc_state.fpscr =
(ppc_state.fpscr.Hex & ~m) | (static_cast<u32>(ppc_state.ps[inst.FB].PS0AsU64()) & m); (ppc_state.fpscr.Hex & ~m) | (static_cast<u32>(ppc_state.ps[inst.FB].PS0AsU64()) & m);
FPSCRUpdated(&ppc_state.fpscr); FPSCRUpdated(ppc_state);
if (inst.Rc) if (inst.Rc)
ppc_state.UpdateCR1(); ppc_state.UpdateCR1();
@ -138,7 +138,7 @@ void Interpreter::mfmsr(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -150,7 +150,7 @@ void Interpreter::mfsr(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -162,7 +162,7 @@ void Interpreter::mfsrin(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -175,14 +175,14 @@ void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
ppc_state.msr.Hex = ppc_state.gpr[inst.RS]; ppc_state.msr.Hex = ppc_state.gpr[inst.RS];
// FE0/FE1 may have been set // FE0/FE1 may have been set
CheckFPExceptions(ppc_state.fpscr); CheckFPExceptions(ppc_state);
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
interpreter.m_end_block = true; interpreter.m_end_block = true;
@ -195,7 +195,7 @@ void Interpreter::mtsr(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -209,7 +209,7 @@ void Interpreter::mtsrin(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR) if (ppc_state.msr.PR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -234,7 +234,7 @@ void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst)
if (ppc_state.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR && if (ppc_state.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR &&
index != SPR_TL && index != SPR_TU) index != SPR_TL && index != SPR_TU)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -260,7 +260,7 @@ void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst)
// GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS)). // GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS)).
// Currently, we always treat the buffer as not empty, as the exact behavior is unclear // Currently, we always treat the buffer as not empty, as the exact behavior is unclear
// (and games that use display lists will hang if the bit doesn't eventually become zero). // (and games that use display lists will hang if the bit doesn't eventually become zero).
if (Core::System::GetInstance().GetGPFifo().IsBNE()) if (interpreter.m_system.GetGPFifo().IsBNE())
ppc_state.spr[index] |= 1; ppc_state.spr[index] |= 1;
else else
ppc_state.spr[index] &= ~1; ppc_state.spr[index] &= ~1;
@ -305,7 +305,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
// XER, LR, and CTR are the only ones available to be written to in user mode // XER, LR, and CTR are the only ones available to be written to in user mode
if (ppc_state.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR) if (ppc_state.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR)
{ {
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return; return;
} }
@ -388,7 +388,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
ASSERT_MSG(POWERPC, ppc_state.spr[SPR_WPAR] == GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS, ASSERT_MSG(POWERPC, ppc_state.spr[SPR_WPAR] == GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS,
"Gather pipe changed to unexpected address {:08x} @ PC {:08x}", "Gather pipe changed to unexpected address {:08x} @ PC {:08x}",
ppc_state.spr[SPR_WPAR], ppc_state.pc); ppc_state.spr[SPR_WPAR], ppc_state.pc);
Core::System::GetInstance().GetGPFifo().ResetGatherPipe(); interpreter.m_system.GetGPFifo().ResetGatherPipe();
break; break;
// Graphics Quantization Registers // Graphics Quantization Registers
@ -616,7 +616,7 @@ void Interpreter::mcrfs(Interpreter& interpreter, UGeckoInstruction inst)
// If any exception bits were read, clear them // If any exception bits were read, clear them
ppc_state.fpscr.Hex &= ~((0xF << shift) & (FPSCR_FX | FPSCR_ANY_X)); ppc_state.fpscr.Hex &= ~((0xF << shift) & (FPSCR_FX | FPSCR_ANY_X));
FPSCRUpdated(&ppc_state.fpscr); FPSCRUpdated(ppc_state);
ppc_state.cr.SetField(inst.CRFD, fpflags); ppc_state.cr.SetField(inst.CRFD, fpflags);
} }