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;
|
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)
|
inline double NI_add(double a, double b)
|
||||||
{
|
{
|
||||||
double t = a + b;
|
double t = a + b;
|
||||||
|
|
|
@ -351,38 +351,7 @@ void Interpreter::faddsx(UGeckoInstruction _inst)
|
||||||
|
|
||||||
void Interpreter::fdivx(UGeckoInstruction _inst)
|
void Interpreter::fdivx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double a = rPS0(_inst.FA);
|
rPS0(_inst.FD) = ForceDouble(NI_div(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
|
|
||||||
// FR,FI,OX,UX???
|
// FR,FI,OX,UX???
|
||||||
|
@ -391,41 +360,7 @@ void Interpreter::fdivx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
void Interpreter::fdivsx(UGeckoInstruction _inst)
|
void Interpreter::fdivsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double a = rPS0(_inst.FA);
|
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
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;
|
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
|
|
||||||
if (_inst.Rc)
|
if (_inst.Rc)
|
||||||
|
|
|
@ -104,97 +104,8 @@ void Interpreter::ps_merge11(UGeckoInstruction _inst)
|
||||||
// From here on, the real deal.
|
// From here on, the real deal.
|
||||||
void Interpreter::ps_div(UGeckoInstruction _inst)
|
void Interpreter::ps_div(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 ex_mask = 0;
|
rPS0(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
|
rPS1(_inst.FD) = ForceSingle(NI_div(rPS1(_inst.FA), rPS1(_inst.FB)));
|
||||||
// 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);
|
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
|
|
||||||
if (_inst.Rc)
|
if (_inst.Rc)
|
||||||
|
|
Loading…
Reference in New Issue