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),
};
inline void GenerateAlignmentException(u32 address)
inline void GenerateAlignmentException(PowerPC::PowerPCState& ppc_state, u32 address)
{
PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT;
PowerPC::ppcState.spr[SPR_DAR] = address;
ppc_state.Exceptions |= EXCEPTION_ALIGNMENT;
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;
PowerPC::ppcState.spr[SPR_DAR] = address;
ppc_state.Exceptions |= EXCEPTION_DSI;
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;
PowerPC::ppcState.spr[SPR_SRR1] = static_cast<u32>(cause);
ppc_state.Exceptions |= EXCEPTION_PROGRAM;
ppc_state.spr[SPR_SRR1] = static_cast<u32>(cause);
}

View File

@ -148,7 +148,7 @@ int Interpreter::SingleStepInner()
{
if (IsInvalidPairedSingleExecution(m_prev_inst))
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
GenerateProgramException(m_ppc_state, ProgramExceptionCause::IllegalInstruction);
CheckExceptions();
}
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)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return;
}

View File

@ -25,29 +25,29 @@ enum class FPCC
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))
GenerateProgramException(ProgramExceptionCause::FloatingPoint);
if (ppc_state.fpscr.FEX && (ppc_state.msr.FE0 || ppc_state.msr.FE1))
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;
fpscr->FEX = ((fpscr->Hex >> 22) & (fpscr->Hex & FPSCR_ANY_E)) != 0;
ppc_state.fpscr.VX = (ppc_state.fpscr.Hex & FPSCR_VX_ANY) != 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;
UpdateFPExceptionSummary(fpscr);
ppc_state.fpscr.Hex |= mask;
UpdateFPExceptionSummary(ppc_state);
}
inline float ForceSingle(const UReg_FPSCR& fpscr, double value)
@ -111,17 +111,17 @@ struct FPResult
{
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;
SetFPException(fpscr, flag);
SetFPException(ppc_state, flag);
}
double value = 0.0;
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};
@ -129,10 +129,10 @@ inline FPResult NI_mul(UReg_FPSCR* fpscr, double a, double 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))
{
@ -146,14 +146,14 @@ inline FPResult NI_mul(UReg_FPSCR* fpscr, double a, double b)
}
result.value = PPC_NAN;
result.SetException(fpscr, FPSCR_VXIMZ);
result.SetException(ppc_state, FPSCR_VXIMZ);
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};
@ -161,16 +161,16 @@ inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b)
{
if (b == 0.0)
{
result.SetException(fpscr, FPSCR_ZX);
result.SetException(ppc_state, FPSCR_ZX);
return result;
}
}
else if (std::isnan(result.value))
{
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))
{
@ -184,9 +184,9 @@ inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b)
}
if (b == 0.0)
result.SetException(fpscr, FPSCR_VXZDZ);
result.SetException(ppc_state, FPSCR_VXZDZ);
else if (std::isinf(a) && std::isinf(b))
result.SetException(fpscr, FPSCR_VXIDI);
result.SetException(ppc_state, FPSCR_VXIDI);
result.value = PPC_NAN;
return result;
@ -195,16 +195,16 @@ inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b)
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};
if (std::isnan(result.value))
{
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))
{
@ -217,27 +217,27 @@ inline FPResult NI_add(UReg_FPSCR* fpscr, double a, double b)
return result;
}
result.SetException(fpscr, FPSCR_VXISI);
result.SetException(ppc_state, FPSCR_VXISI);
result.value = PPC_NAN;
return result;
}
if (std::isinf(a) || std::isinf(b))
fpscr->ClearFIFR();
ppc_state.fpscr.ClearFIFR();
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};
if (std::isnan(result.value))
{
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))
{
@ -250,13 +250,13 @@ inline FPResult NI_sub(UReg_FPSCR* fpscr, double a, double b)
return result;
}
result.SetException(fpscr, FPSCR_VXISI);
result.SetException(ppc_state, FPSCR_VXISI);
result.value = PPC_NAN;
return result;
}
if (std::isinf(a) || std::isinf(b))
fpscr->ClearFIFR();
ppc_state.fpscr.ClearFIFR();
return result;
}
@ -264,16 +264,16 @@ inline FPResult NI_sub(UReg_FPSCR* fpscr, double a, double b)
// FMA instructions on PowerPC are weird:
// They calculate (a * c) + b, but the order in which
// 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)};
if (std::isnan(result.value))
{
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))
{
@ -291,27 +291,27 @@ inline FPResult NI_madd(UReg_FPSCR* fpscr, double a, double c, double b)
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;
return result;
}
if (std::isinf(a) || std::isinf(b) || std::isinf(c))
fpscr->ClearFIFR();
ppc_state.fpscr.ClearFIFR();
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)};
if (std::isnan(result.value))
{
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))
{
@ -329,13 +329,13 @@ inline FPResult NI_msub(UReg_FPSCR* fpscr, double a, double c, double b)
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;
return result;
}
if (std::isinf(a) || std::isinf(b) || std::isinf(c))
fpscr->ClearFIFR();
ppc_state.fpscr.ClearFIFR();
return result;
}

View File

@ -23,13 +23,13 @@ enum class RoundingMode
TowardsNegativeInfinity = 0b11
};
void SetFI(UReg_FPSCR* fpscr, u32 FI)
void SetFI(PowerPC::PowerPCState& ppc_state, u32 FI)
{
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
@ -45,24 +45,24 @@ void ConvertToInteger(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst,
if (std::isnan(b))
{
if (Common::IsSNAN(b))
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN);
SetFPException(ppc_state, FPSCR_VXSNAN);
value = 0x80000000;
SetFPException(&ppc_state.fpscr, FPSCR_VXCVI);
SetFPException(ppc_state, FPSCR_VXCVI);
exception_occurred = true;
}
else if (b > static_cast<double>(0x7fffffff))
{
// Positive large operand or +inf
value = 0x7fffffff;
SetFPException(&ppc_state.fpscr, FPSCR_VXCVI);
SetFPException(ppc_state, FPSCR_VXCVI);
exception_occurred = true;
}
else if (b < -static_cast<double>(0x80000000))
{
// Negative large operand or -inf
value = 0x80000000;
SetFPException(&ppc_state.fpscr, FPSCR_VXCVI);
SetFPException(ppc_state, FPSCR_VXCVI);
exception_occurred = true;
}
else
@ -109,7 +109,7 @@ void ConvertToInteger(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst,
else
{
// Also sets FPSCR[XX]
SetFI(&ppc_state.fpscr, 1);
SetFI(ppc_state, 1);
ppc_state.fpscr.FR = fabs(di) > fabs(b);
}
}
@ -145,15 +145,15 @@ void Interpreter::Helper_FloatCompareOrdered(PowerPC::PowerPCState& ppc_state,
compare_result = FPCC::FU;
if (Common::IsSNAN(fa) || Common::IsSNAN(fb))
{
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN);
SetFPException(ppc_state, FPSCR_VXSNAN);
if (ppc_state.fpscr.VE == 0)
{
SetFPException(&ppc_state.fpscr, FPSCR_VXVC);
SetFPException(ppc_state, FPSCR_VXVC);
}
}
else // QNaN
{
SetFPException(&ppc_state.fpscr, FPSCR_VXVC);
SetFPException(ppc_state, FPSCR_VXVC);
}
}
else if (fa < fb)
@ -188,7 +188,7 @@ void Interpreter::Helper_FloatCompareUnordered(PowerPC::PowerPCState& ppc_state,
if (Common::IsSNAN(fa) || Common::IsSNAN(fb))
{
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN);
SetFPException(ppc_state, FPSCR_VXSNAN);
}
}
else if (fa < fb)
@ -310,7 +310,7 @@ void Interpreter::frspx(Interpreter& interpreter, UGeckoInstruction inst) // ro
const bool is_snan = Common::IsSNAN(b);
if (is_snan)
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN);
SetFPException(ppc_state, FPSCR_VXSNAN);
if (!is_snan || ppc_state.fpscr.VE == 0)
{
@ -322,7 +322,7 @@ void Interpreter::frspx(Interpreter& interpreter, UGeckoInstruction inst) // ro
}
else
{
SetFI(&ppc_state.fpscr, b != rounded);
SetFI(ppc_state, b != rounded);
ppc_state.fpscr.FR = fabs(rounded) > fabs(b);
ppc_state.UpdateFPRFSingle(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& 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())
{
@ -360,7 +360,7 @@ void Interpreter::fmulsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& c = ppc_state.ps[inst.FC];
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())
{
@ -382,8 +382,7 @@ void Interpreter::fmaddx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA];
const auto& b = ppc_state.ps[inst.FB];
const auto& c = ppc_state.ps[inst.FC];
const FPResult product =
NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
const FPResult product = NI_madd(ppc_state, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
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 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())
{
@ -426,7 +425,7 @@ void Interpreter::faddx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA];
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())
{
@ -444,7 +443,7 @@ void Interpreter::faddsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA];
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())
{
@ -463,7 +462,7 @@ void Interpreter::fdivx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA];
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_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& 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_invalid = ppc_state.fpscr.VE == 0 || quotient.HasNoInvalidExceptions();
@ -513,7 +512,7 @@ void Interpreter::fresx(Interpreter& interpreter, UGeckoInstruction inst)
if (b == 0.0)
{
SetFPException(&ppc_state.fpscr, FPSCR_ZX);
SetFPException(ppc_state, FPSCR_ZX);
ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.ZE == 0)
@ -521,7 +520,7 @@ void Interpreter::fresx(Interpreter& interpreter, UGeckoInstruction inst)
}
else if (Common::IsSNAN(b))
{
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN);
SetFPException(ppc_state, FPSCR_VXSNAN);
ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.VE == 0)
@ -552,7 +551,7 @@ void Interpreter::frsqrtex(Interpreter& interpreter, UGeckoInstruction inst)
if (b < 0.0)
{
SetFPException(&ppc_state.fpscr, FPSCR_VXSQRT);
SetFPException(ppc_state, FPSCR_VXSQRT);
ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.VE == 0)
@ -560,7 +559,7 @@ void Interpreter::frsqrtex(Interpreter& interpreter, UGeckoInstruction inst)
}
else if (b == 0.0)
{
SetFPException(&ppc_state.fpscr, FPSCR_ZX);
SetFPException(ppc_state, FPSCR_ZX);
ppc_state.fpscr.ClearFIFR();
if (ppc_state.fpscr.ZE == 0)
@ -568,7 +567,7 @@ void Interpreter::frsqrtex(Interpreter& interpreter, UGeckoInstruction inst)
}
else if (Common::IsSNAN(b))
{
SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN);
SetFPException(ppc_state, FPSCR_VXSNAN);
ppc_state.fpscr.ClearFIFR();
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& c = ppc_state.ps[inst.FC];
const FPResult product =
NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
const FPResult product = NI_msub(ppc_state, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
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 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())
{
@ -635,8 +633,7 @@ void Interpreter::fnmaddx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& b = ppc_state.ps[inst.FB];
const auto& c = ppc_state.ps[inst.FC];
const FPResult product =
NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
const FPResult product = NI_madd(ppc_state, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
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 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())
{
@ -681,8 +678,7 @@ void Interpreter::fnmsubx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& b = ppc_state.ps[inst.FB];
const auto& c = ppc_state.ps[inst.FC];
const FPResult product =
NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
const FPResult product = NI_msub(ppc_state, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
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 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())
{
@ -726,7 +722,7 @@ void Interpreter::fsubx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA];
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())
{
@ -745,7 +741,7 @@ void Interpreter::fsubsx(Interpreter& interpreter, UGeckoInstruction inst)
const auto& a = ppc_state.ps[inst.FA];
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())
{

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

View File

@ -313,7 +313,7 @@ void Interpreter::psq_l(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0)
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
return;
}
@ -326,7 +326,7 @@ void Interpreter::psq_lu(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0)
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
return;
}
@ -346,7 +346,7 @@ void Interpreter::psq_st(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0)
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
return;
}
@ -359,7 +359,7 @@ void Interpreter::psq_stu(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (HID2(ppc_state).LSQE == 0)
{
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::IllegalInstruction);
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& b = ppc_state.ps[inst.FB];
const float ps0 = ForceSingle(ppc_state.fpscr,
NI_div(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 = ForceSingle(ppc_state.fpscr,
NI_div(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_div(ppc_state, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_div(ppc_state, a.PS1AsDouble(), b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0);
@ -147,7 +147,7 @@ void Interpreter::ps_res(Interpreter& interpreter, UGeckoInstruction inst)
if (a == 0.0 || b == 0.0)
{
SetFPException(&ppc_state.fpscr, FPSCR_ZX);
SetFPException(ppc_state, FPSCR_ZX);
ppc_state.fpscr.ClearFIFR();
}
@ -155,7 +155,7 @@ void Interpreter::ps_res(Interpreter& interpreter, UGeckoInstruction inst)
ppc_state.fpscr.ClearFIFR();
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 ps1 = Common::ApproximateReciprocal(b);
@ -175,13 +175,13 @@ void Interpreter::ps_rsqrte(Interpreter& interpreter, UGeckoInstruction inst)
if (ps0 == 0.0 || ps1 == 0.0)
{
SetFPException(&ppc_state.fpscr, FPSCR_ZX);
SetFPException(ppc_state, FPSCR_ZX);
ppc_state.fpscr.ClearFIFR();
}
if (ps0 < 0.0 || ps1 < 0.0)
{
SetFPException(&ppc_state.fpscr, FPSCR_VXSQRT);
SetFPException(ppc_state, FPSCR_VXSQRT);
ppc_state.fpscr.ClearFIFR();
}
@ -189,7 +189,7 @@ void Interpreter::ps_rsqrte(Interpreter& interpreter, UGeckoInstruction inst)
ppc_state.fpscr.ClearFIFR();
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_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& b = ppc_state.ps[inst.FB];
const float ps0 = ForceSingle(ppc_state.fpscr,
NI_sub(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 = ForceSingle(ppc_state.fpscr,
NI_sub(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_sub(ppc_state, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_sub(ppc_state, a.PS1AsDouble(), b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
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& b = ppc_state.ps[inst.FB];
const float ps0 = ForceSingle(ppc_state.fpscr,
NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 = ForceSingle(ppc_state.fpscr,
NI_add(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_add(ppc_state, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_add(ppc_state, a.PS1AsDouble(), b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0);
@ -246,10 +246,8 @@ void Interpreter::ps_mul(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c0).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c1).value);
const float ps0 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS0AsDouble(), c0).value);
const float ps1 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS1AsDouble(), c1).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0);
@ -268,10 +266,10 @@ void Interpreter::ps_msub(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = ForceSingle(
ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 = ForceSingle(
ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_msub(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_msub(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0);
@ -290,10 +288,10 @@ void Interpreter::ps_madd(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = ForceSingle(
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 = ForceSingle(
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
ppc_state.UpdateFPRFSingle(ps0);
@ -312,10 +310,10 @@ void Interpreter::ps_nmsub(Interpreter& interpreter, UGeckoInstruction inst)
const double c0 = Force25Bit(c.PS0AsDouble());
const double c1 = Force25Bit(c.PS1AsDouble());
const float tmp0 = ForceSingle(
ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float tmp1 = ForceSingle(
ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float tmp0 =
ForceSingle(ppc_state.fpscr, NI_msub(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float tmp1 =
ForceSingle(ppc_state.fpscr, NI_msub(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float ps0 = std::isnan(tmp0) ? tmp0 : -tmp0;
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 c1 = Force25Bit(c.PS1AsDouble());
const float tmp0 = ForceSingle(
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float tmp1 = ForceSingle(
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float tmp0 =
ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float tmp1 =
ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float ps0 = std::isnan(tmp0) ? tmp0 : -tmp0;
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& c = ppc_state.ps[inst.FC];
const float ps0 = ForceSingle(ppc_state.fpscr,
NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value);
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_add(ppc_state, a.PS0AsDouble(), b.PS1AsDouble()).value);
const float ps1 = ForceSingle(ppc_state.fpscr, c.PS1AsDouble());
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 float ps0 = ForceSingle(ppc_state.fpscr, c.PS0AsDouble());
const float ps1 = ForceSingle(ppc_state.fpscr,
NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_add(ppc_state, a.PS0AsDouble(), b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, 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 double c0 = Force25Bit(c.PS0AsDouble());
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c0).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c0).value);
const float ps0 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS0AsDouble(), c0).value);
const float ps1 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS1AsDouble(), c0).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
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 double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c1).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c1).value);
const float ps0 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS0AsDouble(), c1).value);
const float ps1 = ForceSingle(ppc_state.fpscr, NI_mul(ppc_state, a.PS1AsDouble(), c1).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
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 double c0 = Force25Bit(c.PS0AsDouble());
const float ps0 = ForceSingle(
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 = ForceSingle(
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c0, b.PS1AsDouble()).value);
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS1AsDouble(), c0, b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
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 double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = ForceSingle(
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c1, b.PS0AsDouble()).value);
const float ps1 = ForceSingle(
ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
const float ps0 =
ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS0AsDouble(), c1, b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(ppc_state.fpscr, NI_madd(ppc_state, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
ppc_state.ps[inst.FD].SetBoth(ps0, ps1);
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();
}
@ -38,7 +38,7 @@ void Interpreter::mtfsb0x(Interpreter& interpreter, UGeckoInstruction inst)
u32 b = 0x80000000 >> inst.CRBD;
ppc_state.fpscr.Hex &= ~b;
FPSCRUpdated(&ppc_state.fpscr);
FPSCRUpdated(ppc_state);
if (inst.Rc)
ppc_state.UpdateCR1();
@ -52,11 +52,11 @@ void Interpreter::mtfsb1x(Interpreter& interpreter, UGeckoInstruction inst)
const u32 b = 0x80000000 >> bit;
if ((b & FPSCR_ANY_X) != 0)
SetFPException(&ppc_state.fpscr, b);
SetFPException(ppc_state, b);
else
ppc_state.fpscr |= b;
FPSCRUpdated(&ppc_state.fpscr);
FPSCRUpdated(ppc_state);
if (inst.Rc)
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));
FPSCRUpdated(&ppc_state.fpscr);
FPSCRUpdated(ppc_state);
if (inst.Rc)
ppc_state.UpdateCR1();
@ -91,7 +91,7 @@ void Interpreter::mtfsfx(Interpreter& interpreter, UGeckoInstruction inst)
ppc_state.fpscr =
(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)
ppc_state.UpdateCR1();
@ -138,7 +138,7 @@ void Interpreter::mfmsr(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return;
}
@ -150,7 +150,7 @@ void Interpreter::mfsr(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return;
}
@ -162,7 +162,7 @@ void Interpreter::mfsrin(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return;
}
@ -175,14 +175,14 @@ void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return;
}
ppc_state.msr.Hex = ppc_state.gpr[inst.RS];
// FE0/FE1 may have been set
CheckFPExceptions(ppc_state.fpscr);
CheckFPExceptions(ppc_state);
PowerPC::CheckExceptions();
interpreter.m_end_block = true;
@ -195,7 +195,7 @@ void Interpreter::mtsr(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return;
}
@ -209,7 +209,7 @@ void Interpreter::mtsrin(Interpreter& interpreter, UGeckoInstruction inst)
auto& ppc_state = interpreter.m_ppc_state;
if (ppc_state.msr.PR)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
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 &&
index != SPR_TL && index != SPR_TU)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
return;
}
@ -260,7 +260,7 @@ void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst)
// GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS)).
// 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).
if (Core::System::GetInstance().GetGPFifo().IsBNE())
if (interpreter.m_system.GetGPFifo().IsBNE())
ppc_state.spr[index] |= 1;
else
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
if (ppc_state.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR)
{
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
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,
"Gather pipe changed to unexpected address {:08x} @ PC {:08x}",
ppc_state.spr[SPR_WPAR], ppc_state.pc);
Core::System::GetInstance().GetGPFifo().ResetGatherPipe();
interpreter.m_system.GetGPFifo().ResetGatherPipe();
break;
// Graphics Quantization Registers
@ -616,7 +616,7 @@ void Interpreter::mcrfs(Interpreter& interpreter, UGeckoInstruction inst)
// If any exception bits were read, clear them
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);
}