Interpreter: Remove remaining System::GetInstance() and global ppcState.
This commit is contained in:
parent
7de01597c6
commit
b568cf5268
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue