Interpreter: consolidate fdiv/fdivs/ps_div
This commit is contained in:
parent
da7ec75350
commit
ca36ff0551
|
@ -95,6 +95,28 @@ inline double NI_mul(double a, double b)
|
|||
return t;
|
||||
}
|
||||
|
||||
inline double NI_div(double a, double b)
|
||||
{
|
||||
double t = a / b;
|
||||
if (std::isnan(t))
|
||||
{
|
||||
if (std::isnan(a)) return a;
|
||||
if (std::isnan(b)) return b;
|
||||
if (b == 0.0)
|
||||
{
|
||||
SetFPException(FPSCR_ZX);
|
||||
if (a == 0.0)
|
||||
SetFPException(FPSCR_VXZDZ);
|
||||
}
|
||||
else if (std::isinf(a) && std::isinf(b))
|
||||
{
|
||||
SetFPException(FPSCR_VXIDI);
|
||||
}
|
||||
return PPC_NAN;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
inline double NI_add(double a, double b)
|
||||
{
|
||||
double t = a + b;
|
||||
|
|
|
@ -351,38 +351,7 @@ void Interpreter::faddsx(UGeckoInstruction _inst)
|
|||
|
||||
void Interpreter::fdivx(UGeckoInstruction _inst)
|
||||
{
|
||||
double a = rPS0(_inst.FA);
|
||||
double b = rPS0(_inst.FB);
|
||||
|
||||
if (a != a)
|
||||
{
|
||||
rPS0(_inst.FD) = a;
|
||||
}
|
||||
else if (b != b)
|
||||
{
|
||||
rPS0(_inst.FD) = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
rPS0(_inst.FD) = ForceDouble(a / b);
|
||||
if (b == 0.0)
|
||||
{
|
||||
if (a == 0.0)
|
||||
{
|
||||
SetFPException(FPSCR_VXZDZ);
|
||||
rPS0(_inst.FD) = PPC_NAN;
|
||||
}
|
||||
SetFPException(FPSCR_ZX);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsINF(a) && IsINF(b))
|
||||
{
|
||||
SetFPException(FPSCR_VXIDI);
|
||||
rPS0(_inst.FD) = PPC_NAN;
|
||||
}
|
||||
}
|
||||
}
|
||||
rPS0(_inst.FD) = ForceDouble(NI_div(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||
UpdateFPRF(rPS0(_inst.FD));
|
||||
|
||||
// FR,FI,OX,UX???
|
||||
|
@ -391,41 +360,7 @@ void Interpreter::fdivx(UGeckoInstruction _inst)
|
|||
}
|
||||
void Interpreter::fdivsx(UGeckoInstruction _inst)
|
||||
{
|
||||
double a = rPS0(_inst.FA);
|
||||
double b = rPS0(_inst.FB);
|
||||
double res;
|
||||
|
||||
if (a != a)
|
||||
{
|
||||
res = a;
|
||||
}
|
||||
else if (b != b)
|
||||
{
|
||||
res = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ForceSingle(a / b);
|
||||
if (b == 0.0)
|
||||
{
|
||||
if (a == 0.0)
|
||||
{
|
||||
SetFPException(FPSCR_VXZDZ);
|
||||
res = PPC_NAN;
|
||||
}
|
||||
SetFPException(FPSCR_ZX);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsINF(a) && IsINF(b))
|
||||
{
|
||||
SetFPException(FPSCR_VXIDI);
|
||||
res = PPC_NAN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rPS0(_inst.FD) = rPS1(_inst.FD) = res;
|
||||
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||
UpdateFPRF(rPS0(_inst.FD));
|
||||
|
||||
if (_inst.Rc)
|
||||
|
|
|
@ -104,97 +104,8 @@ void Interpreter::ps_merge11(UGeckoInstruction _inst)
|
|||
// From here on, the real deal.
|
||||
void Interpreter::ps_div(UGeckoInstruction _inst)
|
||||
{
|
||||
u32 ex_mask = 0;
|
||||
|
||||
// PS0
|
||||
{
|
||||
double a = rPS0(_inst.FA);
|
||||
double b = rPS0(_inst.FB);
|
||||
double &res = rPS0(_inst.FD);
|
||||
|
||||
if (a != a)
|
||||
{
|
||||
res = a;
|
||||
}
|
||||
else if (b != b)
|
||||
{
|
||||
res = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b == 0.0)
|
||||
{
|
||||
ex_mask |= FPSCR_ZX;
|
||||
if (rPS0(_inst.FA) == 0.0)
|
||||
{
|
||||
ex_mask |= FPSCR_VXZDZ;
|
||||
res = PPC_NAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ForceSingle(a / b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsINF(a) && IsINF(b))
|
||||
{
|
||||
ex_mask |= FPSCR_VXIDI;
|
||||
res = PPC_NAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ForceSingle(a / b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PS1
|
||||
{
|
||||
double a = rPS1(_inst.FA);
|
||||
double b = rPS1(_inst.FB);
|
||||
double &res = rPS1(_inst.FD);
|
||||
|
||||
if (a != a)
|
||||
{
|
||||
res = a;
|
||||
}
|
||||
else if (b != b)
|
||||
{
|
||||
res = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b == 0.0)
|
||||
{
|
||||
ex_mask |= FPSCR_ZX;
|
||||
if (rPS0(_inst.FA) == 0.0)
|
||||
{
|
||||
ex_mask |= FPSCR_VXZDZ;
|
||||
res = PPC_NAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ForceSingle(a / b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsINF(a) && IsINF(b))
|
||||
{
|
||||
ex_mask |= FPSCR_VXIDI;
|
||||
res = PPC_NAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = ForceSingle(a / b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetFPException(ex_mask);
|
||||
rPS0(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||
rPS1(_inst.FD) = ForceSingle(NI_div(rPS1(_inst.FA), rPS1(_inst.FB)));
|
||||
UpdateFPRF(rPS0(_inst.FD));
|
||||
|
||||
if (_inst.Rc)
|
||||
|
|
Loading…
Reference in New Issue