PowerPC: Move a few functions to PowerPCState.
This commit is contained in:
parent
0dcf228aaf
commit
61ba516570
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue