Interpreter_FloatingPoint: Don't store to destination in fres if VE or ZE is set and a relevant exception occurs
In the PowerPC Microprocessor Family: The Programming Environments Manual for 32 and 64-bit Microprocessors, in section 3.3.6.1, Table 3-12 lists what should occur if an invalid operation exception occurs in situations where VE is set and when VE is not set. In the case where VE is set, it lists the frD as "Unchanged". It also lists the FPRF flags as "Unchanged". Further down in Table 3-13, the listings for what should occur when zero divide exceptions occur is listed, both for when ZE is set, and when it isn't. When ZE is set, it lists frD as "Unchanged". It also lists the FPRF flags as "Unchanged" as well. This also alters the code so that we don't even calculate the result if we don't need to compute it, making it a little bit less wasteful.
This commit is contained in:
parent
fcae27981a
commit
a08ad82ace
|
@ -387,27 +387,30 @@ void Interpreter::fdivsx(UGeckoInstruction inst)
|
||||||
void Interpreter::fresx(UGeckoInstruction inst)
|
void Interpreter::fresx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
const double b = rPS0(inst.FB);
|
const double b = rPS0(inst.FB);
|
||||||
const double result = Common::ApproximateReciprocal(b);
|
|
||||||
|
|
||||||
|
const auto compute_result = [inst](double value) {
|
||||||
|
const double result = Common::ApproximateReciprocal(value);
|
||||||
rPS0(inst.FD) = rPS1(inst.FD) = result;
|
rPS0(inst.FD) = rPS1(inst.FD) = result;
|
||||||
|
PowerPC::UpdateFPRF(result);
|
||||||
|
};
|
||||||
|
|
||||||
if (b == 0.0)
|
if (b == 0.0)
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_ZX);
|
SetFPException(FPSCR_ZX);
|
||||||
|
|
||||||
if (FPSCR.ZE == 0)
|
if (FPSCR.ZE == 0)
|
||||||
PowerPC::UpdateFPRF(result);
|
compute_result(b);
|
||||||
}
|
}
|
||||||
else if (Common::IsSNAN(b))
|
else if (Common::IsSNAN(b))
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
|
||||||
if (FPSCR.VE == 0)
|
if (FPSCR.VE == 0)
|
||||||
PowerPC::UpdateFPRF(result);
|
compute_result(b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PowerPC::UpdateFPRF(result);
|
compute_result(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
|
|
Loading…
Reference in New Issue