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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -659,12 +659,12 @@ void PowerPCState::SetSR(u32 index, u32 value)
void UpdateFPRFDouble(double dvalue)
{
FPSCR.FPRF = Common::ClassifyDouble(dvalue);
PowerPC::ppcState.fpscr.FPRF = Common::ClassifyDouble(dvalue);
}
void UpdateFPRFSingle(float fvalue)
{
FPSCR.FPRF = Common::ClassifyFloat(fvalue);
PowerPC::ppcState.fpscr.FPRF = Common::ClassifyFloat(fvalue);
}
void RoundingModeUpdated()
@ -672,7 +672,7 @@ void RoundingModeUpdated()
// The rounding mode is separate for each thread, so this must run on the CPU thread
ASSERT(Core::IsCPUThread());
FPURoundMode::SetSIMDMode(FPSCR.RN, FPSCR.NI);
FPURoundMode::SetSIMDMode(PowerPC::ppcState.fpscr.RN, PowerPC::ppcState.fpscr.NI);
}
} // 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 THRM2(ppc_state) ((UReg_THRM12&)(ppc_state).spr[SPR_THRM2])
#define THRM3(ppc_state) ((UReg_THRM3&)(ppc_state).spr[SPR_THRM3])
#define FPSCR PowerPC::ppcState.fpscr
#define MSR PowerPC::ppcState.msr
#define GPR(n) PowerPC::ppcState.gpr[n]