PowerPC: Remove FPSCR macro.

This commit is contained in:
Admiral H. Curtiss 2023-01-09 22:26:12 +01:00
parent 2f3187eba9
commit 4b6b8fa1ae
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
9 changed files with 215 additions and 162 deletions

View File

@ -447,7 +447,7 @@ static void ReadRegister()
wbe32hex(reply, PowerPC::ppcState.spr[SPR_XER]); wbe32hex(reply, PowerPC::ppcState.spr[SPR_XER]);
break; break;
case 70: case 70:
wbe32hex(reply, FPSCR.Hex); wbe32hex(reply, PowerPC::ppcState.fpscr.Hex);
break; break;
case 87: case 87:
wbe32hex(reply, PowerPC::ppcState.spr[SPR_PVR]); wbe32hex(reply, PowerPC::ppcState.spr[SPR_PVR]);
@ -659,7 +659,7 @@ static void WriteRegister()
PowerPC::ppcState.spr[SPR_XER] = re32hex(bufptr); PowerPC::ppcState.spr[SPR_XER] = re32hex(bufptr);
break; break;
case 70: case 70:
FPSCR.Hex = re32hex(bufptr); PowerPC::ppcState.fpscr.Hex = re32hex(bufptr);
break; break;
case 87: case 87:
PowerPC::ppcState.spr[SPR_PVR] = re32hex(bufptr); PowerPC::ppcState.spr[SPR_PVR] = re32hex(bufptr);

View File

@ -131,8 +131,9 @@ static void Trace(const UGeckoInstruction& inst)
DEBUG_LOG_FMT(POWERPC, DEBUG_LOG_FMT(POWERPC,
"INTER PC: {:08x} SRR0: {:08x} SRR1: {:08x} CRval: {:016x} " "INTER PC: {:08x} SRR0: {:08x} SRR1: {:08x} CRval: {:016x} "
"FPSCR: {:08x} MSR: {:08x} LR: {:08x} {} {:08x} {}", "FPSCR: {:08x} MSR: {:08x} LR: {:08x} {} {:08x} {}",
PowerPC::ppcState.pc, SRR0, SRR1, PowerPC::ppcState.cr.fields[0], FPSCR.Hex, PowerPC::ppcState.pc, SRR0, SRR1, PowerPC::ppcState.cr.fields[0],
MSR.Hex, PowerPC::ppcState.spr[8], regs, inst.hex, ppc_inst); PowerPC::ppcState.fpscr.Hex, MSR.Hex, PowerPC::ppcState.spr[8], regs, inst.hex,
ppc_inst);
} }
bool Interpreter::HandleFunctionHooking(u32 address) bool Interpreter::HandleFunctionHooking(u32 address)

View File

@ -44,24 +44,24 @@ void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode)
if (std::isnan(b)) if (std::isnan(b))
{ {
if (Common::IsSNAN(b)) if (Common::IsSNAN(b))
SetFPException(&FPSCR, FPSCR_VXSNAN); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN);
value = 0x80000000; value = 0x80000000;
SetFPException(&FPSCR, FPSCR_VXCVI); SetFPException(&PowerPC::ppcState.fpscr, 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(&FPSCR, FPSCR_VXCVI); SetFPException(&PowerPC::ppcState.fpscr, 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(&FPSCR, FPSCR_VXCVI); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXCVI);
exception_occurred = true; exception_occurred = true;
} }
else else
@ -103,22 +103,22 @@ void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode)
const double di = i; const double di = i;
if (di == b) if (di == b)
{ {
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
} }
else else
{ {
// Also sets FPSCR[XX] // Also sets FPSCR[XX]
SetFI(&FPSCR, 1); SetFI(&PowerPC::ppcState.fpscr, 1);
FPSCR.FR = fabs(di) > fabs(b); PowerPC::ppcState.fpscr.FR = fabs(di) > fabs(b);
} }
} }
if (exception_occurred) if (exception_occurred)
{ {
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
} }
if (!exception_occurred || FPSCR.VE == 0) if (!exception_occurred || PowerPC::ppcState.fpscr.VE == 0)
{ {
// Based on HW tests // Based on HW tests
// FPRF is not affected // FPRF is not affected
@ -143,15 +143,15 @@ void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction inst, double fa,
compare_result = FPCC::FU; compare_result = FPCC::FU;
if (Common::IsSNAN(fa) || Common::IsSNAN(fb)) if (Common::IsSNAN(fa) || Common::IsSNAN(fb))
{ {
SetFPException(&FPSCR, FPSCR_VXSNAN); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN);
if (FPSCR.VE == 0) if (PowerPC::ppcState.fpscr.VE == 0)
{ {
SetFPException(&FPSCR, FPSCR_VXVC); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXVC);
} }
} }
else // QNaN else // QNaN
{ {
SetFPException(&FPSCR, FPSCR_VXVC); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXVC);
} }
} }
else if (fa < fb) else if (fa < fb)
@ -170,7 +170,7 @@ void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction inst, double fa,
const u32 compare_value = static_cast<u32>(compare_result); const u32 compare_value = static_cast<u32>(compare_result);
// Clear and set the FPCC bits accordingly. // Clear and set the FPCC bits accordingly.
FPSCR.FPRF = (FPSCR.FPRF & ~FPCC_MASK) | compare_value; PowerPC::ppcState.fpscr.FPRF = (PowerPC::ppcState.fpscr.FPRF & ~FPCC_MASK) | compare_value;
PowerPC::ppcState.cr.SetField(inst.CRFD, compare_value); PowerPC::ppcState.cr.SetField(inst.CRFD, compare_value);
} }
@ -185,7 +185,7 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa
if (Common::IsSNAN(fa) || Common::IsSNAN(fb)) if (Common::IsSNAN(fa) || Common::IsSNAN(fb))
{ {
SetFPException(&FPSCR, FPSCR_VXSNAN); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN);
} }
} }
else if (fa < fb) else if (fa < fb)
@ -204,7 +204,7 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa
const u32 compare_value = static_cast<u32>(compare_result); const u32 compare_value = static_cast<u32>(compare_result);
// Clear and set the FPCC bits accordingly. // Clear and set the FPCC bits accordingly.
FPSCR.FPRF = (FPSCR.FPRF & ~FPCC_MASK) | compare_value; PowerPC::ppcState.fpscr.FPRF = (PowerPC::ppcState.fpscr.FPRF & ~FPCC_MASK) | compare_value;
PowerPC::ppcState.cr.SetField(inst.CRFD, compare_value); PowerPC::ppcState.cr.SetField(inst.CRFD, compare_value);
} }
@ -227,7 +227,7 @@ void Interpreter::fcmpu(UGeckoInstruction inst)
void Interpreter::fctiwx(UGeckoInstruction inst) void Interpreter::fctiwx(UGeckoInstruction inst)
{ {
ConvertToInteger(inst, static_cast<RoundingMode>(FPSCR.RN.Value())); ConvertToInteger(inst, static_cast<RoundingMode>(PowerPC::ppcState.fpscr.RN.Value()));
} }
void Interpreter::fctiwzx(UGeckoInstruction inst) void Interpreter::fctiwzx(UGeckoInstruction inst)
@ -290,27 +290,27 @@ void Interpreter::fselx(UGeckoInstruction inst)
void Interpreter::frspx(UGeckoInstruction inst) // round to single void Interpreter::frspx(UGeckoInstruction inst) // round to single
{ {
const double b = rPS(inst.FB).PS0AsDouble(); const double b = rPS(inst.FB).PS0AsDouble();
const float rounded = ForceSingle(FPSCR, b); const float rounded = ForceSingle(PowerPC::ppcState.fpscr, b);
if (std::isnan(b)) if (std::isnan(b))
{ {
const bool is_snan = Common::IsSNAN(b); const bool is_snan = Common::IsSNAN(b);
if (is_snan) if (is_snan)
SetFPException(&FPSCR, FPSCR_VXSNAN); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN);
if (!is_snan || FPSCR.VE == 0) if (!is_snan || PowerPC::ppcState.fpscr.VE == 0)
{ {
rPS(inst.FD).Fill(rounded); rPS(inst.FD).Fill(rounded);
PowerPC::UpdateFPRFSingle(rounded); PowerPC::UpdateFPRFSingle(rounded);
} }
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
} }
else else
{ {
SetFI(&FPSCR, b != rounded); SetFI(&PowerPC::ppcState.fpscr, b != rounded);
FPSCR.FR = fabs(rounded) > fabs(b); PowerPC::ppcState.fpscr.FR = fabs(rounded) > fabs(b);
PowerPC::UpdateFPRFSingle(rounded); PowerPC::UpdateFPRFSingle(rounded);
rPS(inst.FD).Fill(rounded); rPS(inst.FD).Fill(rounded);
} }
@ -324,15 +324,15 @@ void Interpreter::fmulx(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const FPResult product = NI_mul(&FPSCR, a.PS0AsDouble(), c.PS0AsDouble()); const FPResult product = NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble());
if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
const double result = ForceDouble(FPSCR, product.value); const double result = ForceDouble(PowerPC::ppcState.fpscr, product.value);
rPS(inst.FD).SetPS0(result); rPS(inst.FD).SetPS0(result);
FPSCR.FI = 0; // are these flags important? PowerPC::ppcState.fpscr.FI = 0; // are these flags important?
FPSCR.FR = 0; PowerPC::ppcState.fpscr.FR = 0;
PowerPC::UpdateFPRFDouble(result); PowerPC::UpdateFPRFDouble(result);
} }
@ -345,15 +345,15 @@ void Interpreter::fmulsx(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult d_value = NI_mul(&FPSCR, a.PS0AsDouble(), c_value); const FPResult d_value = NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value);
if (FPSCR.VE == 0 || d_value.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || d_value.HasNoInvalidExceptions())
{ {
const float result = ForceSingle(FPSCR, d_value.value); const float result = ForceSingle(PowerPC::ppcState.fpscr, d_value.value);
rPS(inst.FD).Fill(result); rPS(inst.FD).Fill(result);
FPSCR.FI = 0; PowerPC::ppcState.fpscr.FI = 0;
FPSCR.FR = 0; PowerPC::ppcState.fpscr.FR = 0;
PowerPC::UpdateFPRFSingle(result); PowerPC::UpdateFPRFSingle(result);
} }
@ -366,11 +366,12 @@ void Interpreter::fmaddx(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const FPResult product = NI_madd(&FPSCR, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); const FPResult product =
NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
const double result = ForceDouble(FPSCR, product.value); const double result = ForceDouble(PowerPC::ppcState.fpscr, product.value);
rPS(inst.FD).SetPS0(result); rPS(inst.FD).SetPS0(result);
PowerPC::UpdateFPRFDouble(result); PowerPC::UpdateFPRFDouble(result);
} }
@ -386,15 +387,16 @@ void Interpreter::fmaddsx(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult d_value = NI_madd(&FPSCR, a.PS0AsDouble(), c_value, b.PS0AsDouble()); const FPResult d_value =
NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble());
if (FPSCR.VE == 0 || d_value.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || d_value.HasNoInvalidExceptions())
{ {
const float result = ForceSingle(FPSCR, d_value.value); const float result = ForceSingle(PowerPC::ppcState.fpscr, d_value.value);
rPS(inst.FD).Fill(result); rPS(inst.FD).Fill(result);
FPSCR.FI = d_value.value != result; PowerPC::ppcState.fpscr.FI = d_value.value != result;
FPSCR.FR = 0; PowerPC::ppcState.fpscr.FR = 0;
PowerPC::UpdateFPRFSingle(result); PowerPC::UpdateFPRFSingle(result);
} }
@ -407,11 +409,11 @@ void Interpreter::faddx(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const FPResult sum = NI_add(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult sum = NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble());
if (FPSCR.VE == 0 || sum.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || sum.HasNoInvalidExceptions())
{ {
const double result = ForceDouble(FPSCR, sum.value); const double result = ForceDouble(PowerPC::ppcState.fpscr, sum.value);
rPS(inst.FD).SetPS0(result); rPS(inst.FD).SetPS0(result);
PowerPC::UpdateFPRFDouble(result); PowerPC::UpdateFPRFDouble(result);
} }
@ -424,11 +426,11 @@ void Interpreter::faddsx(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const FPResult sum = NI_add(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult sum = NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble());
if (FPSCR.VE == 0 || sum.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || sum.HasNoInvalidExceptions())
{ {
const float result = ForceSingle(FPSCR, sum.value); const float result = ForceSingle(PowerPC::ppcState.fpscr, sum.value);
rPS(inst.FD).Fill(result); rPS(inst.FD).Fill(result);
PowerPC::UpdateFPRFSingle(result); PowerPC::UpdateFPRFSingle(result);
} }
@ -442,13 +444,13 @@ void Interpreter::fdivx(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const FPResult quotient = NI_div(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult quotient = NI_div(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble());
const bool not_divide_by_zero = FPSCR.ZE == 0 || quotient.exception != FPSCR_ZX; const bool not_divide_by_zero = PowerPC::ppcState.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX;
const bool not_invalid = FPSCR.VE == 0 || quotient.HasNoInvalidExceptions(); const bool not_invalid = PowerPC::ppcState.fpscr.VE == 0 || quotient.HasNoInvalidExceptions();
if (not_divide_by_zero && not_invalid) if (not_divide_by_zero && not_invalid)
{ {
const double result = ForceDouble(FPSCR, quotient.value); const double result = ForceDouble(PowerPC::ppcState.fpscr, quotient.value);
rPS(inst.FD).SetPS0(result); rPS(inst.FD).SetPS0(result);
PowerPC::UpdateFPRFDouble(result); PowerPC::UpdateFPRFDouble(result);
} }
@ -462,13 +464,13 @@ void Interpreter::fdivsx(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const FPResult quotient = NI_div(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult quotient = NI_div(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble());
const bool not_divide_by_zero = FPSCR.ZE == 0 || quotient.exception != FPSCR_ZX; const bool not_divide_by_zero = PowerPC::ppcState.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX;
const bool not_invalid = FPSCR.VE == 0 || quotient.HasNoInvalidExceptions(); const bool not_invalid = PowerPC::ppcState.fpscr.VE == 0 || quotient.HasNoInvalidExceptions();
if (not_divide_by_zero && not_invalid) if (not_divide_by_zero && not_invalid)
{ {
const float result = ForceSingle(FPSCR, quotient.value); const float result = ForceSingle(PowerPC::ppcState.fpscr, quotient.value);
rPS(inst.FD).Fill(result); rPS(inst.FD).Fill(result);
PowerPC::UpdateFPRFSingle(result); PowerPC::UpdateFPRFSingle(result);
} }
@ -490,24 +492,24 @@ void Interpreter::fresx(UGeckoInstruction inst)
if (b == 0.0) if (b == 0.0)
{ {
SetFPException(&FPSCR, FPSCR_ZX); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_ZX);
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
if (FPSCR.ZE == 0) if (PowerPC::ppcState.fpscr.ZE == 0)
compute_result(b); compute_result(b);
} }
else if (Common::IsSNAN(b)) else if (Common::IsSNAN(b))
{ {
SetFPException(&FPSCR, FPSCR_VXSNAN); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN);
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
if (FPSCR.VE == 0) if (PowerPC::ppcState.fpscr.VE == 0)
compute_result(b); compute_result(b);
} }
else else
{ {
if (std::isnan(b) || std::isinf(b)) if (std::isnan(b) || std::isinf(b))
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
compute_result(b); compute_result(b);
} }
@ -528,32 +530,32 @@ void Interpreter::frsqrtex(UGeckoInstruction inst)
if (b < 0.0) if (b < 0.0)
{ {
SetFPException(&FPSCR, FPSCR_VXSQRT); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSQRT);
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
if (FPSCR.VE == 0) if (PowerPC::ppcState.fpscr.VE == 0)
compute_result(b); compute_result(b);
} }
else if (b == 0.0) else if (b == 0.0)
{ {
SetFPException(&FPSCR, FPSCR_ZX); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_ZX);
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
if (FPSCR.ZE == 0) if (PowerPC::ppcState.fpscr.ZE == 0)
compute_result(b); compute_result(b);
} }
else if (Common::IsSNAN(b)) else if (Common::IsSNAN(b))
{ {
SetFPException(&FPSCR, FPSCR_VXSNAN); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN);
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
if (FPSCR.VE == 0) if (PowerPC::ppcState.fpscr.VE == 0)
compute_result(b); compute_result(b);
} }
else else
{ {
if (std::isnan(b) || std::isinf(b)) if (std::isnan(b) || std::isinf(b))
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
compute_result(b); compute_result(b);
} }
@ -568,11 +570,12 @@ void Interpreter::fmsubx(UGeckoInstruction inst)
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const FPResult product = NI_msub(&FPSCR, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); const FPResult product =
NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
const double result = ForceDouble(FPSCR, product.value); const double result = ForceDouble(PowerPC::ppcState.fpscr, product.value);
rPS(inst.FD).SetPS0(result); rPS(inst.FD).SetPS0(result);
PowerPC::UpdateFPRFDouble(result); PowerPC::UpdateFPRFDouble(result);
} }
@ -588,11 +591,12 @@ void Interpreter::fmsubsx(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult product = NI_msub(&FPSCR, a.PS0AsDouble(), c_value, b.PS0AsDouble()); const FPResult product =
NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble());
if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
const float result = ForceSingle(FPSCR, product.value); const float result = ForceSingle(PowerPC::ppcState.fpscr, product.value);
rPS(inst.FD).Fill(result); rPS(inst.FD).Fill(result);
PowerPC::UpdateFPRFSingle(result); PowerPC::UpdateFPRFSingle(result);
} }
@ -607,11 +611,12 @@ void Interpreter::fnmaddx(UGeckoInstruction inst)
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const FPResult product = NI_madd(&FPSCR, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); const FPResult product =
NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
const double tmp = ForceDouble(FPSCR, product.value); const double tmp = ForceDouble(PowerPC::ppcState.fpscr, product.value);
const double result = std::isnan(tmp) ? tmp : -tmp; const double result = std::isnan(tmp) ? tmp : -tmp;
rPS(inst.FD).SetPS0(result); rPS(inst.FD).SetPS0(result);
@ -629,11 +634,12 @@ void Interpreter::fnmaddsx(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult product = NI_madd(&FPSCR, a.PS0AsDouble(), c_value, b.PS0AsDouble()); const FPResult product =
NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble());
if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
const float tmp = ForceSingle(FPSCR, product.value); const float tmp = ForceSingle(PowerPC::ppcState.fpscr, product.value);
const float result = std::isnan(tmp) ? tmp : -tmp; const float result = std::isnan(tmp) ? tmp : -tmp;
rPS(inst.FD).Fill(result); rPS(inst.FD).Fill(result);
@ -650,11 +656,12 @@ void Interpreter::fnmsubx(UGeckoInstruction inst)
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const FPResult product = NI_msub(&FPSCR, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); const FPResult product =
NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble());
if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
const double tmp = ForceDouble(FPSCR, product.value); const double tmp = ForceDouble(PowerPC::ppcState.fpscr, product.value);
const double result = std::isnan(tmp) ? tmp : -tmp; const double result = std::isnan(tmp) ? tmp : -tmp;
rPS(inst.FD).SetPS0(result); rPS(inst.FD).SetPS0(result);
@ -672,11 +679,12 @@ void Interpreter::fnmsubsx(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c_value = Force25Bit(c.PS0AsDouble()); const double c_value = Force25Bit(c.PS0AsDouble());
const FPResult product = NI_msub(&FPSCR, a.PS0AsDouble(), c_value, b.PS0AsDouble()); const FPResult product =
NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble());
if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions())
{ {
const float tmp = ForceSingle(FPSCR, product.value); const float tmp = ForceSingle(PowerPC::ppcState.fpscr, product.value);
const float result = std::isnan(tmp) ? tmp : -tmp; const float result = std::isnan(tmp) ? tmp : -tmp;
rPS(inst.FD).Fill(result); rPS(inst.FD).Fill(result);
@ -692,11 +700,11 @@ void Interpreter::fsubx(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const FPResult difference = NI_sub(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult difference = NI_sub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble());
if (FPSCR.VE == 0 || difference.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || difference.HasNoInvalidExceptions())
{ {
const double result = ForceDouble(FPSCR, difference.value); const double result = ForceDouble(PowerPC::ppcState.fpscr, difference.value);
rPS(inst.FD).SetPS0(result); rPS(inst.FD).SetPS0(result);
PowerPC::UpdateFPRFDouble(result); PowerPC::UpdateFPRFDouble(result);
} }
@ -710,11 +718,11 @@ void Interpreter::fsubsx(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const FPResult difference = NI_sub(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()); const FPResult difference = NI_sub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble());
if (FPSCR.VE == 0 || difference.HasNoInvalidExceptions()) if (PowerPC::ppcState.fpscr.VE == 0 || difference.HasNoInvalidExceptions())
{ {
const float result = ForceSingle(FPSCR, difference.value); const float result = ForceSingle(PowerPC::ppcState.fpscr, difference.value);
rPS(inst.FD).Fill(result); rPS(inst.FD).Fill(result);
PowerPC::UpdateFPRFSingle(result); PowerPC::UpdateFPRFSingle(result);
} }

View File

@ -113,8 +113,12 @@ void Interpreter::ps_div(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const float ps0 = ForceSingle(FPSCR, NI_div(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()).value); const float ps0 =
const float ps1 = ForceSingle(FPSCR, NI_div(&FPSCR, a.PS1AsDouble(), b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_div(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(PowerPC::ppcState.fpscr,
NI_div(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -131,15 +135,15 @@ void Interpreter::ps_res(UGeckoInstruction inst)
if (a == 0.0 || b == 0.0) if (a == 0.0 || b == 0.0)
{ {
SetFPException(&FPSCR, FPSCR_ZX); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_ZX);
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
} }
if (std::isnan(a) || std::isinf(a) || std::isnan(b) || std::isinf(b)) if (std::isnan(a) || std::isinf(a) || std::isnan(b) || std::isinf(b))
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
if (Common::IsSNAN(a) || Common::IsSNAN(b)) if (Common::IsSNAN(a) || Common::IsSNAN(b))
SetFPException(&FPSCR, FPSCR_VXSNAN); SetFPException(&PowerPC::ppcState.fpscr, 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);
@ -158,24 +162,26 @@ void Interpreter::ps_rsqrte(UGeckoInstruction inst)
if (ps0 == 0.0 || ps1 == 0.0) if (ps0 == 0.0 || ps1 == 0.0)
{ {
SetFPException(&FPSCR, FPSCR_ZX); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_ZX);
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
} }
if (ps0 < 0.0 || ps1 < 0.0) if (ps0 < 0.0 || ps1 < 0.0)
{ {
SetFPException(&FPSCR, FPSCR_VXSQRT); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSQRT);
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
} }
if (std::isnan(ps0) || std::isinf(ps0) || std::isnan(ps1) || std::isinf(ps1)) if (std::isnan(ps0) || std::isinf(ps0) || std::isnan(ps1) || std::isinf(ps1))
FPSCR.ClearFIFR(); PowerPC::ppcState.fpscr.ClearFIFR();
if (Common::IsSNAN(ps0) || Common::IsSNAN(ps1)) if (Common::IsSNAN(ps0) || Common::IsSNAN(ps1))
SetFPException(&FPSCR, FPSCR_VXSNAN); SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN);
const float dst_ps0 = ForceSingle(FPSCR, Common::ApproximateReciprocalSquareRoot(ps0)); const float dst_ps0 =
const float dst_ps1 = ForceSingle(FPSCR, Common::ApproximateReciprocalSquareRoot(ps1)); ForceSingle(PowerPC::ppcState.fpscr, Common::ApproximateReciprocalSquareRoot(ps0));
const float dst_ps1 =
ForceSingle(PowerPC::ppcState.fpscr, Common::ApproximateReciprocalSquareRoot(ps1));
rPS(inst.FD).SetBoth(dst_ps0, dst_ps1); rPS(inst.FD).SetBoth(dst_ps0, dst_ps1);
PowerPC::UpdateFPRFSingle(dst_ps0); PowerPC::UpdateFPRFSingle(dst_ps0);
@ -189,8 +195,12 @@ void Interpreter::ps_sub(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const float ps0 = ForceSingle(FPSCR, NI_sub(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()).value); const float ps0 =
const float ps1 = ForceSingle(FPSCR, NI_sub(&FPSCR, a.PS1AsDouble(), b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_sub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(PowerPC::ppcState.fpscr,
NI_sub(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -204,8 +214,12 @@ void Interpreter::ps_add(UGeckoInstruction inst)
const auto& a = rPS(inst.FA); const auto& a = rPS(inst.FA);
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const float ps0 = ForceSingle(FPSCR, NI_add(&FPSCR, a.PS0AsDouble(), b.PS0AsDouble()).value); const float ps0 =
const float ps1 = ForceSingle(FPSCR, NI_add(&FPSCR, a.PS1AsDouble(), b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(PowerPC::ppcState.fpscr,
NI_add(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -222,8 +236,10 @@ void Interpreter::ps_mul(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(FPSCR, NI_mul(&FPSCR, a.PS0AsDouble(), c0).value); const float ps0 = ForceSingle(PowerPC::ppcState.fpscr,
const float ps1 = ForceSingle(FPSCR, NI_mul(&FPSCR, a.PS1AsDouble(), c1).value); NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0).value);
const float ps1 = ForceSingle(PowerPC::ppcState.fpscr,
NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -241,8 +257,12 @@ void Interpreter::ps_msub(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(FPSCR, NI_msub(&FPSCR, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); const float ps0 =
const float ps1 = ForceSingle(FPSCR, NI_msub(&FPSCR, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(PowerPC::ppcState.fpscr,
NI_msub(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -260,8 +280,12 @@ void Interpreter::ps_madd(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(FPSCR, NI_madd(&FPSCR, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); const float ps0 =
const float ps1 = ForceSingle(FPSCR, NI_madd(&FPSCR, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(PowerPC::ppcState.fpscr,
NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -280,9 +304,11 @@ void Interpreter::ps_nmsub(UGeckoInstruction inst)
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float tmp0 = const float tmp0 =
ForceSingle(FPSCR, NI_msub(&FPSCR, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float tmp1 = const float tmp1 =
ForceSingle(FPSCR, NI_msub(&FPSCR, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_msub(&PowerPC::ppcState.fpscr, 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;
@ -304,9 +330,11 @@ void Interpreter::ps_nmadd(UGeckoInstruction inst)
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float tmp0 = const float tmp0 =
ForceSingle(FPSCR, NI_madd(&FPSCR, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float tmp1 = const float tmp1 =
ForceSingle(FPSCR, NI_madd(&FPSCR, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_madd(&PowerPC::ppcState.fpscr, 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;
@ -324,8 +352,10 @@ void Interpreter::ps_sum0(UGeckoInstruction inst)
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const float ps0 = ForceSingle(FPSCR, NI_add(&FPSCR, a.PS0AsDouble(), b.PS1AsDouble()).value); const float ps0 =
const float ps1 = ForceSingle(FPSCR, c.PS1AsDouble()); ForceSingle(PowerPC::ppcState.fpscr,
NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value);
const float ps1 = ForceSingle(PowerPC::ppcState.fpscr, c.PS1AsDouble());
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -340,8 +370,10 @@ void Interpreter::ps_sum1(UGeckoInstruction inst)
const auto& b = rPS(inst.FB); const auto& b = rPS(inst.FB);
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const float ps0 = ForceSingle(FPSCR, c.PS0AsDouble()); const float ps0 = ForceSingle(PowerPC::ppcState.fpscr, c.PS0AsDouble());
const float ps1 = ForceSingle(FPSCR, NI_add(&FPSCR, a.PS0AsDouble(), b.PS1AsDouble()).value); const float ps1 =
ForceSingle(PowerPC::ppcState.fpscr,
NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps1); PowerPC::UpdateFPRFSingle(ps1);
@ -356,8 +388,10 @@ void Interpreter::ps_muls0(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const float ps0 = ForceSingle(FPSCR, NI_mul(&FPSCR, a.PS0AsDouble(), c0).value); const float ps0 = ForceSingle(PowerPC::ppcState.fpscr,
const float ps1 = ForceSingle(FPSCR, NI_mul(&FPSCR, a.PS1AsDouble(), c0).value); NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0).value);
const float ps1 = ForceSingle(PowerPC::ppcState.fpscr,
NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c0).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -372,8 +406,10 @@ void Interpreter::ps_muls1(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = ForceSingle(FPSCR, NI_mul(&FPSCR, a.PS0AsDouble(), c1).value); const float ps0 = ForceSingle(PowerPC::ppcState.fpscr,
const float ps1 = ForceSingle(FPSCR, NI_mul(&FPSCR, a.PS1AsDouble(), c1).value); NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c1).value);
const float ps1 = ForceSingle(PowerPC::ppcState.fpscr,
NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -389,8 +425,12 @@ void Interpreter::ps_madds0(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c0 = Force25Bit(c.PS0AsDouble()); const double c0 = Force25Bit(c.PS0AsDouble());
const float ps0 = ForceSingle(FPSCR, NI_madd(&FPSCR, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); const float ps0 =
const float ps1 = ForceSingle(FPSCR, NI_madd(&FPSCR, a.PS1AsDouble(), c0, b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(PowerPC::ppcState.fpscr,
NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c0, b.PS1AsDouble()).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);
@ -406,8 +446,12 @@ void Interpreter::ps_madds1(UGeckoInstruction inst)
const auto& c = rPS(inst.FC); const auto& c = rPS(inst.FC);
const double c1 = Force25Bit(c.PS1AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble());
const float ps0 = ForceSingle(FPSCR, NI_madd(&FPSCR, a.PS0AsDouble(), c1, b.PS0AsDouble()).value); const float ps0 =
const float ps1 = ForceSingle(FPSCR, NI_madd(&FPSCR, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); ForceSingle(PowerPC::ppcState.fpscr,
NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c1, b.PS0AsDouble()).value);
const float ps1 =
ForceSingle(PowerPC::ppcState.fpscr,
NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
rPS(inst.FD).SetBoth(ps0, ps1); rPS(inst.FD).SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0); PowerPC::UpdateFPRFSingle(ps0);

View File

@ -36,8 +36,8 @@ void Interpreter::mtfsb0x(UGeckoInstruction inst)
{ {
u32 b = 0x80000000 >> inst.CRBD; u32 b = 0x80000000 >> inst.CRBD;
FPSCR.Hex &= ~b; PowerPC::ppcState.fpscr.Hex &= ~b;
FPSCRUpdated(&FPSCR); FPSCRUpdated(&PowerPC::ppcState.fpscr);
if (inst.Rc) if (inst.Rc)
PowerPC::ppcState.UpdateCR1(); PowerPC::ppcState.UpdateCR1();
@ -50,11 +50,11 @@ void Interpreter::mtfsb1x(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(&FPSCR, b); SetFPException(&PowerPC::ppcState.fpscr, b);
else else
FPSCR |= b; PowerPC::ppcState.fpscr |= b;
FPSCRUpdated(&FPSCR); FPSCRUpdated(&PowerPC::ppcState.fpscr);
if (inst.Rc) if (inst.Rc)
PowerPC::ppcState.UpdateCR1(); PowerPC::ppcState.UpdateCR1();
@ -67,9 +67,9 @@ void Interpreter::mtfsfix(UGeckoInstruction inst)
const u32 mask = (pre_shifted_mask >> (4 * field)); const u32 mask = (pre_shifted_mask >> (4 * field));
const u32 imm = (inst.hex << 16) & pre_shifted_mask; const u32 imm = (inst.hex << 16) & pre_shifted_mask;
FPSCR = (FPSCR.Hex & ~mask) | (imm >> (4 * field)); PowerPC::ppcState.fpscr = (PowerPC::ppcState.fpscr.Hex & ~mask) | (imm >> (4 * field));
FPSCRUpdated(&FPSCR); FPSCRUpdated(&PowerPC::ppcState.fpscr);
if (inst.Rc) if (inst.Rc)
PowerPC::ppcState.UpdateCR1(); PowerPC::ppcState.UpdateCR1();
@ -85,8 +85,9 @@ void Interpreter::mtfsfx(UGeckoInstruction inst)
m |= (0xFU << (i * 4)); m |= (0xFU << (i * 4));
} }
FPSCR = (FPSCR.Hex & ~m) | (static_cast<u32>(rPS(inst.FB).PS0AsU64()) & m); PowerPC::ppcState.fpscr =
FPSCRUpdated(&FPSCR); (PowerPC::ppcState.fpscr.Hex & ~m) | (static_cast<u32>(rPS(inst.FB).PS0AsU64()) & m);
FPSCRUpdated(&PowerPC::ppcState.fpscr);
if (inst.Rc) if (inst.Rc)
PowerPC::ppcState.UpdateCR1(); PowerPC::ppcState.UpdateCR1();
@ -170,7 +171,7 @@ void Interpreter::mtmsr(UGeckoInstruction inst)
MSR.Hex = rGPR[inst.RS]; MSR.Hex = rGPR[inst.RS];
// FE0/FE1 may have been set // FE0/FE1 may have been set
CheckFPExceptions(FPSCR); CheckFPExceptions(PowerPC::ppcState.fpscr);
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
m_end_block = true; m_end_block = true;
@ -588,18 +589,18 @@ void Interpreter::isync(UGeckoInstruction inst)
void Interpreter::mcrfs(UGeckoInstruction inst) void Interpreter::mcrfs(UGeckoInstruction inst)
{ {
const u32 shift = 4 * (7 - inst.CRFS); const u32 shift = 4 * (7 - inst.CRFS);
const u32 fpflags = (FPSCR.Hex >> shift) & 0xF; const u32 fpflags = (PowerPC::ppcState.fpscr.Hex >> shift) & 0xF;
// If any exception bits were read, clear them // If any exception bits were read, clear them
FPSCR.Hex &= ~((0xF << shift) & (FPSCR_FX | FPSCR_ANY_X)); PowerPC::ppcState.fpscr.Hex &= ~((0xF << shift) & (FPSCR_FX | FPSCR_ANY_X));
FPSCRUpdated(&FPSCR); FPSCRUpdated(&PowerPC::ppcState.fpscr);
PowerPC::ppcState.cr.SetField(inst.CRFD, fpflags); PowerPC::ppcState.cr.SetField(inst.CRFD, fpflags);
} }
void Interpreter::mffsx(UGeckoInstruction inst) void Interpreter::mffsx(UGeckoInstruction inst)
{ {
rPS(inst.FD).SetPS0(UINT64_C(0xFFF8000000000000) | FPSCR.Hex); rPS(inst.FD).SetPS0(UINT64_C(0xFFF8000000000000) | PowerPC::ppcState.fpscr.Hex);
if (inst.Rc) if (inst.Rc)
PowerPC::ppcState.UpdateCR1(); PowerPC::ppcState.UpdateCR1();

View File

@ -758,8 +758,8 @@ void Jit64::Trace()
DEBUG_LOG_FMT(DYNA_REC, DEBUG_LOG_FMT(DYNA_REC,
"JIT64 PC: {:08x} SRR0: {:08x} SRR1: {:08x} FPSCR: {:08x} " "JIT64 PC: {:08x} SRR0: {:08x} SRR1: {:08x} FPSCR: {:08x} "
"MSR: {:08x} LR: {:08x} {} {}", "MSR: {:08x} LR: {:08x} {} {}",
PowerPC::ppcState.pc, SRR0, SRR1, FPSCR.Hex, MSR.Hex, PowerPC::ppcState.spr[8], PowerPC::ppcState.pc, SRR0, SRR1, PowerPC::ppcState.fpscr.Hex, MSR.Hex,
regs, fregs); PowerPC::ppcState.spr[8], regs, fregs);
} }
void Jit64::Jit(u32 em_address) void Jit64::Jit(u32 em_address)

View File

@ -705,8 +705,8 @@ void JitArm64::Trace()
DEBUG_LOG_FMT(DYNA_REC, DEBUG_LOG_FMT(DYNA_REC,
"JitArm64 PC: {:08x} SRR0: {:08x} SRR1: {:08x} FPSCR: {:08x} " "JitArm64 PC: {:08x} SRR0: {:08x} SRR1: {:08x} FPSCR: {:08x} "
"MSR: {:08x} LR: {:08x} {} {}", "MSR: {:08x} LR: {:08x} {} {}",
PowerPC::ppcState.pc, SRR0, SRR1, FPSCR.Hex, MSR.Hex, PowerPC::ppcState.spr[8], PowerPC::ppcState.pc, SRR0, SRR1, PowerPC::ppcState.fpscr.Hex, MSR.Hex,
regs, fregs); PowerPC::ppcState.spr[8], regs, fregs);
} }
void JitArm64::Jit(u32 em_address) void JitArm64::Jit(u32 em_address)

View File

@ -659,12 +659,12 @@ void PowerPCState::SetSR(u32 index, u32 value)
void UpdateFPRFDouble(double dvalue) void UpdateFPRFDouble(double dvalue)
{ {
FPSCR.FPRF = Common::ClassifyDouble(dvalue); PowerPC::ppcState.fpscr.FPRF = Common::ClassifyDouble(dvalue);
} }
void UpdateFPRFSingle(float fvalue) void UpdateFPRFSingle(float fvalue)
{ {
FPSCR.FPRF = Common::ClassifyFloat(fvalue); PowerPC::ppcState.fpscr.FPRF = Common::ClassifyFloat(fvalue);
} }
void RoundingModeUpdated() void RoundingModeUpdated()
@ -672,7 +672,7 @@ void RoundingModeUpdated()
// The rounding mode is separate for each thread, so this must run on the CPU thread // The rounding mode is separate for each thread, so this must run on the CPU thread
ASSERT(Core::IsCPUThread()); ASSERT(Core::IsCPUThread());
FPURoundMode::SetSIMDMode(FPSCR.RN, FPSCR.NI); FPURoundMode::SetSIMDMode(PowerPC::ppcState.fpscr.RN, PowerPC::ppcState.fpscr.NI);
} }
} // namespace PowerPC } // namespace PowerPC

View File

@ -245,7 +245,6 @@ void UpdatePerformanceMonitor(u32 cycles, u32 num_load_stores, u32 num_fp_inst);
#define THRM1(ppc_state) ((UReg_THRM12&)(ppc_state).spr[SPR_THRM1]) #define THRM1(ppc_state) ((UReg_THRM12&)(ppc_state).spr[SPR_THRM1])
#define THRM2(ppc_state) ((UReg_THRM12&)(ppc_state).spr[SPR_THRM2]) #define THRM2(ppc_state) ((UReg_THRM12&)(ppc_state).spr[SPR_THRM2])
#define THRM3(ppc_state) ((UReg_THRM3&)(ppc_state).spr[SPR_THRM3]) #define THRM3(ppc_state) ((UReg_THRM3&)(ppc_state).spr[SPR_THRM3])
#define FPSCR PowerPC::ppcState.fpscr
#define MSR PowerPC::ppcState.msr #define MSR PowerPC::ppcState.msr
#define GPR(n) PowerPC::ppcState.gpr[n] #define GPR(n) PowerPC::ppcState.gpr[n]