PowerPC: Move a few functions to PowerPCState.

This commit is contained in:
Admiral H. Curtiss 2023-01-10 02:05:48 +01:00
parent 0dcf228aaf
commit 61ba516570
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
9 changed files with 124 additions and 139 deletions

View File

@ -305,7 +305,7 @@ void Interpreter::frspx(UGeckoInstruction inst) // round to single
if (!is_snan || PowerPC::ppcState.fpscr.VE == 0)
{
PowerPC::ppcState.ps[inst.FD].Fill(rounded);
PowerPC::UpdateFPRFSingle(rounded);
PowerPC::ppcState.UpdateFPRFSingle(rounded);
}
PowerPC::ppcState.fpscr.ClearFIFR();
@ -314,7 +314,7 @@ void Interpreter::frspx(UGeckoInstruction inst) // round to single
{
SetFI(&PowerPC::ppcState.fpscr, b != rounded);
PowerPC::ppcState.fpscr.FR = fabs(rounded) > fabs(b);
PowerPC::UpdateFPRFSingle(rounded);
PowerPC::ppcState.UpdateFPRFSingle(rounded);
PowerPC::ppcState.ps[inst.FD].Fill(rounded);
}
@ -336,7 +336,7 @@ void Interpreter::fmulx(UGeckoInstruction inst)
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::ppcState.fpscr.FI = 0; // are these flags important?
PowerPC::ppcState.fpscr.FR = 0;
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
}
if (inst.Rc)
@ -357,7 +357,7 @@ void Interpreter::fmulsx(UGeckoInstruction inst)
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::ppcState.fpscr.FI = 0;
PowerPC::ppcState.fpscr.FR = 0;
PowerPC::UpdateFPRFSingle(result);
PowerPC::ppcState.UpdateFPRFSingle(result);
}
if (inst.Rc)
@ -376,7 +376,7 @@ void Interpreter::fmaddx(UGeckoInstruction inst)
{
const double result = ForceDouble(PowerPC::ppcState.fpscr, product.value);
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
}
if (inst.Rc)
@ -400,7 +400,7 @@ void Interpreter::fmaddsx(UGeckoInstruction inst)
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::ppcState.fpscr.FI = d_value.value != result;
PowerPC::ppcState.fpscr.FR = 0;
PowerPC::UpdateFPRFSingle(result);
PowerPC::ppcState.UpdateFPRFSingle(result);
}
if (inst.Rc)
@ -418,7 +418,7 @@ void Interpreter::faddx(UGeckoInstruction inst)
{
const double result = ForceDouble(PowerPC::ppcState.fpscr, sum.value);
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
}
if (inst.Rc)
@ -435,7 +435,7 @@ void Interpreter::faddsx(UGeckoInstruction inst)
{
const float result = ForceSingle(PowerPC::ppcState.fpscr, sum.value);
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::UpdateFPRFSingle(result);
PowerPC::ppcState.UpdateFPRFSingle(result);
}
if (inst.Rc)
@ -455,7 +455,7 @@ void Interpreter::fdivx(UGeckoInstruction inst)
{
const double result = ForceDouble(PowerPC::ppcState.fpscr, quotient.value);
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
}
// FR,FI,OX,UX???
@ -475,7 +475,7 @@ void Interpreter::fdivsx(UGeckoInstruction inst)
{
const float result = ForceSingle(PowerPC::ppcState.fpscr, quotient.value);
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::UpdateFPRFSingle(result);
PowerPC::ppcState.UpdateFPRFSingle(result);
}
if (inst.Rc)
@ -490,7 +490,7 @@ void Interpreter::fresx(UGeckoInstruction inst)
const auto compute_result = [inst](double value) {
const double result = Common::ApproximateReciprocal(value);
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::UpdateFPRFSingle(float(result));
PowerPC::ppcState.UpdateFPRFSingle(float(result));
};
if (b == 0.0)
@ -528,7 +528,7 @@ void Interpreter::frsqrtex(UGeckoInstruction inst)
const auto compute_result = [inst](double value) {
const double result = Common::ApproximateReciprocalSquareRoot(value);
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
};
if (b < 0.0)
@ -580,7 +580,7 @@ void Interpreter::fmsubx(UGeckoInstruction inst)
{
const double result = ForceDouble(PowerPC::ppcState.fpscr, product.value);
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
}
if (inst.Rc)
@ -601,7 +601,7 @@ void Interpreter::fmsubsx(UGeckoInstruction inst)
{
const float result = ForceSingle(PowerPC::ppcState.fpscr, product.value);
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::UpdateFPRFSingle(result);
PowerPC::ppcState.UpdateFPRFSingle(result);
}
if (inst.Rc)
@ -623,7 +623,7 @@ void Interpreter::fnmaddx(UGeckoInstruction inst)
const double result = std::isnan(tmp) ? tmp : -tmp;
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
}
if (inst.Rc)
@ -646,7 +646,7 @@ void Interpreter::fnmaddsx(UGeckoInstruction inst)
const float result = std::isnan(tmp) ? tmp : -tmp;
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::UpdateFPRFSingle(result);
PowerPC::ppcState.UpdateFPRFSingle(result);
}
if (inst.Rc)
@ -668,7 +668,7 @@ void Interpreter::fnmsubx(UGeckoInstruction inst)
const double result = std::isnan(tmp) ? tmp : -tmp;
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
}
if (inst.Rc)
@ -691,7 +691,7 @@ void Interpreter::fnmsubsx(UGeckoInstruction inst)
const float result = std::isnan(tmp) ? tmp : -tmp;
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::UpdateFPRFSingle(result);
PowerPC::ppcState.UpdateFPRFSingle(result);
}
if (inst.Rc)
@ -709,7 +709,7 @@ void Interpreter::fsubx(UGeckoInstruction inst)
{
const double result = ForceDouble(PowerPC::ppcState.fpscr, difference.value);
PowerPC::ppcState.ps[inst.FD].SetPS0(result);
PowerPC::UpdateFPRFDouble(result);
PowerPC::ppcState.UpdateFPRFDouble(result);
}
if (inst.Rc)
@ -727,7 +727,7 @@ void Interpreter::fsubsx(UGeckoInstruction inst)
{
const float result = ForceSingle(PowerPC::ppcState.fpscr, difference.value);
PowerPC::ppcState.ps[inst.FD].Fill(result);
PowerPC::UpdateFPRFSingle(result);
PowerPC::ppcState.UpdateFPRFSingle(result);
}
if (inst.Rc)

View File

@ -16,7 +16,7 @@ void Interpreter::Helper_UpdateCR0(u32 value)
const s64 sign_extended = s64{s32(value)};
u64 cr_val = u64(sign_extended);
cr_val = (cr_val & ~(1ULL << PowerPC::CR_EMU_SO_BIT)) |
(u64{PowerPC::GetXER_SO()} << PowerPC::CR_EMU_SO_BIT);
(u64{PowerPC::ppcState.GetXER_SO()} << PowerPC::CR_EMU_SO_BIT);
PowerPC::ppcState.cr.fields[0] = cr_val;
}
@ -40,7 +40,7 @@ void Interpreter::addic(UGeckoInstruction inst)
const u32 imm = u32(s32{inst.SIMM_16});
PowerPC::ppcState.gpr[inst.RD] = a + imm;
PowerPC::SetCarry(Helper_Carry(a, imm));
PowerPC::ppcState.SetCarry(Helper_Carry(a, imm));
}
void Interpreter::addic_rc(UGeckoInstruction inst)
@ -81,7 +81,7 @@ void Interpreter::Helper_IntCompare(UGeckoInstruction inst, T a, T b)
else
cr_field = PowerPC::CR_EQ;
if (PowerPC::GetXER_SO())
if (PowerPC::ppcState.GetXER_SO())
cr_field |= PowerPC::CR_SO;
PowerPC::ppcState.cr.SetField(inst.CRFD, cr_field);
@ -120,8 +120,8 @@ void Interpreter::subfic(UGeckoInstruction inst)
{
const s32 immediate = inst.SIMM_16;
PowerPC::ppcState.gpr[inst.RD] = u32(immediate - s32(PowerPC::ppcState.gpr[inst.RA]));
PowerPC::SetCarry((PowerPC::ppcState.gpr[inst.RA] == 0) ||
(Helper_Carry(0 - PowerPC::ppcState.gpr[inst.RA], u32(immediate))));
PowerPC::ppcState.SetCarry((PowerPC::ppcState.gpr[inst.RA] == 0) ||
(Helper_Carry(0 - PowerPC::ppcState.gpr[inst.RA], u32(immediate))));
}
void Interpreter::twi(UGeckoInstruction inst)
@ -297,12 +297,12 @@ void Interpreter::srawx(UGeckoInstruction inst)
if ((PowerPC::ppcState.gpr[inst.RS] & 0x80000000) != 0)
{
PowerPC::ppcState.gpr[inst.RA] = 0xFFFFFFFF;
PowerPC::SetCarry(1);
PowerPC::ppcState.SetCarry(1);
}
else
{
PowerPC::ppcState.gpr[inst.RA] = 0x00000000;
PowerPC::SetCarry(0);
PowerPC::ppcState.SetCarry(0);
}
}
else
@ -311,7 +311,7 @@ void Interpreter::srawx(UGeckoInstruction inst)
const s32 rrs = s32(PowerPC::ppcState.gpr[inst.RS]);
PowerPC::ppcState.gpr[inst.RA] = u32(rrs >> amount);
PowerPC::SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0);
PowerPC::ppcState.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0);
}
if (inst.Rc)
@ -324,7 +324,7 @@ void Interpreter::srawix(UGeckoInstruction inst)
const s32 rrs = s32(PowerPC::ppcState.gpr[inst.RS]);
PowerPC::ppcState.gpr[inst.RA] = u32(rrs >> amount);
PowerPC::SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0);
PowerPC::ppcState.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0);
if (inst.Rc)
Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]);
@ -381,7 +381,7 @@ void Interpreter::addx(UGeckoInstruction inst)
PowerPC::ppcState.gpr[inst.RD] = result;
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, b, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -394,10 +394,10 @@ void Interpreter::addcx(UGeckoInstruction inst)
const u32 result = a + b;
PowerPC::ppcState.gpr[inst.RD] = result;
PowerPC::SetCarry(Helper_Carry(a, b));
PowerPC::ppcState.SetCarry(Helper_Carry(a, b));
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, b, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -405,16 +405,16 @@ void Interpreter::addcx(UGeckoInstruction inst)
void Interpreter::addex(UGeckoInstruction inst)
{
const u32 carry = PowerPC::GetCarry();
const u32 carry = PowerPC::ppcState.GetCarry();
const u32 a = PowerPC::ppcState.gpr[inst.RA];
const u32 b = PowerPC::ppcState.gpr[inst.RB];
const u32 result = a + b + carry;
PowerPC::ppcState.gpr[inst.RD] = result;
PowerPC::SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry)));
PowerPC::ppcState.SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry)));
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, b, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -422,16 +422,16 @@ void Interpreter::addex(UGeckoInstruction inst)
void Interpreter::addmex(UGeckoInstruction inst)
{
const u32 carry = PowerPC::GetCarry();
const u32 carry = PowerPC::ppcState.GetCarry();
const u32 a = PowerPC::ppcState.gpr[inst.RA];
const u32 b = 0xFFFFFFFF;
const u32 result = a + b + carry;
PowerPC::ppcState.gpr[inst.RD] = result;
PowerPC::SetCarry(Helper_Carry(a, carry - 1));
PowerPC::ppcState.SetCarry(Helper_Carry(a, carry - 1));
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, b, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -439,15 +439,15 @@ void Interpreter::addmex(UGeckoInstruction inst)
void Interpreter::addzex(UGeckoInstruction inst)
{
const u32 carry = PowerPC::GetCarry();
const u32 carry = PowerPC::ppcState.GetCarry();
const u32 a = PowerPC::ppcState.gpr[inst.RA];
const u32 result = a + carry;
PowerPC::ppcState.gpr[inst.RD] = result;
PowerPC::SetCarry(Helper_Carry(a, carry));
PowerPC::ppcState.SetCarry(Helper_Carry(a, carry));
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, 0, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, 0, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -472,7 +472,7 @@ void Interpreter::divwx(UGeckoInstruction inst)
}
if (inst.OE)
PowerPC::SetXER_OV(overflow);
PowerPC::ppcState.SetXER_OV(overflow);
if (inst.Rc)
Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]);
@ -494,7 +494,7 @@ void Interpreter::divwux(UGeckoInstruction inst)
}
if (inst.OE)
PowerPC::SetXER_OV(overflow);
PowerPC::ppcState.SetXER_OV(overflow);
if (inst.Rc)
Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]);
@ -533,7 +533,7 @@ void Interpreter::mullwx(UGeckoInstruction inst)
PowerPC::ppcState.gpr[inst.RD] = static_cast<u32>(result);
if (inst.OE)
PowerPC::SetXER_OV(result < -0x80000000LL || result > 0x7FFFFFFFLL);
PowerPC::ppcState.SetXER_OV(result < -0x80000000LL || result > 0x7FFFFFFFLL);
if (inst.Rc)
Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]);
@ -546,7 +546,7 @@ void Interpreter::negx(UGeckoInstruction inst)
PowerPC::ppcState.gpr[inst.RD] = (~a) + 1;
if (inst.OE)
PowerPC::SetXER_OV(a == 0x80000000);
PowerPC::ppcState.SetXER_OV(a == 0x80000000);
if (inst.Rc)
Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]);
@ -561,7 +561,7 @@ void Interpreter::subfx(UGeckoInstruction inst)
PowerPC::ppcState.gpr[inst.RD] = result;
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, b, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -574,10 +574,10 @@ void Interpreter::subfcx(UGeckoInstruction inst)
const u32 result = a + b + 1;
PowerPC::ppcState.gpr[inst.RD] = result;
PowerPC::SetCarry(a == 0xFFFFFFFF || Helper_Carry(b, a + 1));
PowerPC::ppcState.SetCarry(a == 0xFFFFFFFF || Helper_Carry(b, a + 1));
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, b, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -587,14 +587,14 @@ void Interpreter::subfex(UGeckoInstruction inst)
{
const u32 a = ~PowerPC::ppcState.gpr[inst.RA];
const u32 b = PowerPC::ppcState.gpr[inst.RB];
const u32 carry = PowerPC::GetCarry();
const u32 carry = PowerPC::ppcState.GetCarry();
const u32 result = a + b + carry;
PowerPC::ppcState.gpr[inst.RD] = result;
PowerPC::SetCarry(Helper_Carry(a, b) || Helper_Carry(a + b, carry));
PowerPC::ppcState.SetCarry(Helper_Carry(a, b) || Helper_Carry(a + b, carry));
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, b, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -605,14 +605,14 @@ void Interpreter::subfmex(UGeckoInstruction inst)
{
const u32 a = ~PowerPC::ppcState.gpr[inst.RA];
const u32 b = 0xFFFFFFFF;
const u32 carry = PowerPC::GetCarry();
const u32 carry = PowerPC::ppcState.GetCarry();
const u32 result = a + b + carry;
PowerPC::ppcState.gpr[inst.RD] = result;
PowerPC::SetCarry(Helper_Carry(a, carry - 1));
PowerPC::ppcState.SetCarry(Helper_Carry(a, carry - 1));
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, b, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result));
if (inst.Rc)
Helper_UpdateCR0(result);
@ -622,14 +622,14 @@ void Interpreter::subfmex(UGeckoInstruction inst)
void Interpreter::subfzex(UGeckoInstruction inst)
{
const u32 a = ~PowerPC::ppcState.gpr[inst.RA];
const u32 carry = PowerPC::GetCarry();
const u32 carry = PowerPC::ppcState.GetCarry();
const u32 result = a + carry;
PowerPC::ppcState.gpr[inst.RD] = result;
PowerPC::SetCarry(Helper_Carry(a, carry));
PowerPC::ppcState.SetCarry(Helper_Carry(a, carry));
if (inst.OE)
PowerPC::SetXER_OV(HasAddOverflowed(a, 0, result));
PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, 0, result));
if (inst.Rc)
Helper_UpdateCR0(result);

View File

@ -1017,13 +1017,13 @@ void Interpreter::stwcxd(UGeckoInstruction inst)
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{
PowerPC::ppcState.reserve = false;
PowerPC::ppcState.cr.SetField(0, 2 | PowerPC::GetXER_SO());
PowerPC::ppcState.cr.SetField(0, 2 | PowerPC::ppcState.GetXER_SO());
return;
}
}
}
PowerPC::ppcState.cr.SetField(0, PowerPC::GetXER_SO());
PowerPC::ppcState.cr.SetField(0, PowerPC::ppcState.GetXER_SO());
}
void Interpreter::stwux(UGeckoInstruction inst)

View File

@ -125,7 +125,7 @@ void Interpreter::ps_div(UGeckoInstruction inst)
NI_div(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -153,7 +153,7 @@ void Interpreter::ps_res(UGeckoInstruction inst)
const double ps1 = Common::ApproximateReciprocal(b);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(float(ps0));
PowerPC::ppcState.UpdateFPRFSingle(float(ps0));
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -188,7 +188,7 @@ void Interpreter::ps_rsqrte(UGeckoInstruction inst)
ForceSingle(PowerPC::ppcState.fpscr, Common::ApproximateReciprocalSquareRoot(ps1));
PowerPC::ppcState.ps[inst.FD].SetBoth(dst_ps0, dst_ps1);
PowerPC::UpdateFPRFSingle(dst_ps0);
PowerPC::ppcState.UpdateFPRFSingle(dst_ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -207,7 +207,7 @@ void Interpreter::ps_sub(UGeckoInstruction inst)
NI_sub(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -226,7 +226,7 @@ void Interpreter::ps_add(UGeckoInstruction inst)
NI_add(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -246,7 +246,7 @@ void Interpreter::ps_mul(UGeckoInstruction inst)
NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -269,7 +269,7 @@ void Interpreter::ps_msub(UGeckoInstruction inst)
NI_msub(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -292,7 +292,7 @@ void Interpreter::ps_madd(UGeckoInstruction inst)
NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -318,7 +318,7 @@ void Interpreter::ps_nmsub(UGeckoInstruction inst)
const float ps1 = std::isnan(tmp1) ? tmp1 : -tmp1;
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -344,7 +344,7 @@ void Interpreter::ps_nmadd(UGeckoInstruction inst)
const float ps1 = std::isnan(tmp1) ? tmp1 : -tmp1;
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -362,7 +362,7 @@ void Interpreter::ps_sum0(UGeckoInstruction inst)
const float ps1 = ForceSingle(PowerPC::ppcState.fpscr, c.PS1AsDouble());
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -380,7 +380,7 @@ void Interpreter::ps_sum1(UGeckoInstruction inst)
NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps1);
PowerPC::ppcState.UpdateFPRFSingle(ps1);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -398,7 +398,7 @@ void Interpreter::ps_muls0(UGeckoInstruction inst)
NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c0).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -416,7 +416,7 @@ void Interpreter::ps_muls1(UGeckoInstruction inst)
NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -437,7 +437,7 @@ void Interpreter::ps_madds0(UGeckoInstruction inst)
NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c0, b.PS1AsDouble()).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();
@ -458,7 +458,7 @@ void Interpreter::ps_madds1(UGeckoInstruction inst)
NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value);
PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1);
PowerPC::UpdateFPRFSingle(ps0);
PowerPC::ppcState.UpdateFPRFSingle(ps0);
if (inst.Rc)
PowerPC::ppcState.UpdateCR1();

View File

@ -95,7 +95,7 @@ void Interpreter::mtfsfx(UGeckoInstruction inst)
void Interpreter::mcrxr(UGeckoInstruction inst)
{
PowerPC::ppcState.cr.SetField(inst.CRFD, PowerPC::GetXER().Hex >> 28);
PowerPC::ppcState.cr.SetField(inst.CRFD, PowerPC::ppcState.GetXER().Hex >> 28);
PowerPC::ppcState.xer_ca = 0;
PowerPC::ppcState.xer_so_ov = 0;
}
@ -255,7 +255,7 @@ void Interpreter::mfspr(UGeckoInstruction inst)
break;
case SPR_XER:
PowerPC::ppcState.spr[index] = PowerPC::GetXER().Hex;
PowerPC::ppcState.spr[index] = PowerPC::ppcState.GetXER().Hex;
break;
case SPR_UPMC1:
@ -429,7 +429,7 @@ void Interpreter::mtspr(UGeckoInstruction inst)
break;
case SPR_XER:
PowerPC::SetXER(UReg_XER{PowerPC::ppcState.spr[index]});
PowerPC::ppcState.SetXER(UReg_XER{PowerPC::ppcState.spr[index]});
break;
case SPR_DBAT0L:

View File

@ -200,7 +200,7 @@ static void ResetRegisters()
{
v = 0x8000000000000001;
}
SetXER({});
ppcState.SetXER({});
RoundingModeUpdated();
DBATUpdated();
@ -661,14 +661,14 @@ void PowerPCState::SetSR(u32 index, u32 value)
// FPSCR update functions
void UpdateFPRFDouble(double dvalue)
void PowerPCState::UpdateFPRFDouble(double dvalue)
{
PowerPC::ppcState.fpscr.FPRF = Common::ClassifyDouble(dvalue);
fpscr.FPRF = Common::ClassifyDouble(dvalue);
}
void UpdateFPRFSingle(float fvalue)
void PowerPCState::UpdateFPRFSingle(float fvalue)
{
PowerPC::ppcState.fpscr.FPRF = Common::ClassifyFloat(fvalue);
fpscr.FPRF = Common::ClassifyFloat(fvalue);
}
void RoundingModeUpdated()

View File

@ -185,6 +185,41 @@ struct PowerPCState
}
void SetSR(u32 index, u32 value);
void SetCarry(u32 ca) { xer_ca = ca; }
u32 GetCarry() const { return xer_ca; }
UReg_XER GetXER() const
{
u32 xer = 0;
xer |= xer_stringctrl;
xer |= xer_ca << XER_CA_SHIFT;
xer |= xer_so_ov << XER_OV_SHIFT;
return UReg_XER{xer};
}
void SetXER(UReg_XER new_xer)
{
xer_stringctrl = new_xer.BYTE_COUNT + (new_xer.BYTE_CMP << 8);
xer_ca = new_xer.CA;
xer_so_ov = (new_xer.SO << 1) + new_xer.OV;
}
u32 GetXER_SO() const { return xer_so_ov >> 1; }
void SetXER_SO(bool value) { xer_so_ov |= static_cast<u32>(value) << 1; }
u32 GetXER_OV() const { return xer_so_ov & 1; }
void SetXER_OV(bool value)
{
xer_so_ov = (xer_so_ov & 0xFE) | static_cast<u32>(value);
SetXER_SO(value);
}
void UpdateFPRFDouble(double dvalue);
void UpdateFPRFSingle(float fvalue);
};
#if _M_X86_64
@ -254,56 +289,6 @@ void UpdatePerformanceMonitor(u32 cycles, u32 num_load_stores, u32 num_fp_inst);
#define TL(ppc_state) (ppc_state).spr[SPR_TL]
#define TU(ppc_state) (ppc_state).spr[SPR_TU]
inline void SetCarry(u32 ca)
{
PowerPC::ppcState.xer_ca = ca;
}
inline u32 GetCarry()
{
return PowerPC::ppcState.xer_ca;
}
inline UReg_XER GetXER()
{
u32 xer = 0;
xer |= PowerPC::ppcState.xer_stringctrl;
xer |= PowerPC::ppcState.xer_ca << XER_CA_SHIFT;
xer |= PowerPC::ppcState.xer_so_ov << XER_OV_SHIFT;
return UReg_XER{xer};
}
inline void SetXER(UReg_XER new_xer)
{
PowerPC::ppcState.xer_stringctrl = new_xer.BYTE_COUNT + (new_xer.BYTE_CMP << 8);
PowerPC::ppcState.xer_ca = new_xer.CA;
PowerPC::ppcState.xer_so_ov = (new_xer.SO << 1) + new_xer.OV;
}
inline u32 GetXER_SO()
{
return PowerPC::ppcState.xer_so_ov >> 1;
}
inline void SetXER_SO(bool value)
{
PowerPC::ppcState.xer_so_ov |= static_cast<u32>(value) << 1;
}
inline u32 GetXER_OV()
{
return PowerPC::ppcState.xer_so_ov & 1;
}
inline void SetXER_OV(bool value)
{
PowerPC::ppcState.xer_so_ov = (PowerPC::ppcState.xer_so_ov & 0xFE) | static_cast<u32>(value);
SetXER_SO(value);
}
void UpdateFPRFDouble(double dvalue);
void UpdateFPRFSingle(float fvalue);
void RoundingModeUpdated();
} // namespace PowerPC

View File

@ -422,8 +422,8 @@ void RegisterWidget::PopulateTable()
// XER
AddRegister(
21, 5, RegisterType::xer, "XER", [] { return PowerPC::GetXER().Hex; },
[](u64 value) { PowerPC::SetXER(UReg_XER(value)); });
21, 5, RegisterType::xer, "XER", [] { return PowerPC::ppcState.GetXER().Hex; },
[](u64 value) { PowerPC::ppcState.SetXER(UReg_XER(value)); });
// FPSCR
AddRegister(

View File

@ -71,15 +71,15 @@ TEST(JitArm64, FPRF)
for (const u64 double_input : double_test_values)
{
const u32 expected_double =
RunUpdateFPRF([&] { PowerPC::UpdateFPRFDouble(Common::BitCast<double>(double_input)); });
const u32 expected_double = RunUpdateFPRF(
[&] { PowerPC::ppcState.UpdateFPRFDouble(Common::BitCast<double>(double_input)); });
const u32 actual_double = RunUpdateFPRF([&] { test.fprf_double(double_input); });
EXPECT_EQ(expected_double, actual_double);
const u32 single_input = ConvertToSingle(double_input);
const u32 expected_single =
RunUpdateFPRF([&] { PowerPC::UpdateFPRFSingle(Common::BitCast<float>(single_input)); });
const u32 expected_single = RunUpdateFPRF(
[&] { PowerPC::ppcState.UpdateFPRFSingle(Common::BitCast<float>(single_input)); });
const u32 actual_single = RunUpdateFPRF([&] { test.fprf_single(single_input); });
EXPECT_EQ(expected_single, actual_single);
}