Merge pull request #1121 from FioraAeterna/fixfsel
JIT: fix fsel/ps_sel implementations for NaN input
This commit is contained in:
commit
a829e596c7
|
@ -212,10 +212,12 @@ void Jit64::fselx(UGeckoInstruction inst)
|
||||||
int c = inst.FC;
|
int c = inst.FC;
|
||||||
|
|
||||||
fpr.Lock(a, b, c, d);
|
fpr.Lock(a, b, c, d);
|
||||||
MOVSD(XMM0, fpr.R(a));
|
MOVSD(XMM1, fpr.R(a));
|
||||||
PXOR(XMM1, R(XMM1));
|
PXOR(XMM0, R(XMM0));
|
||||||
// XMM0 = XMM0 < 0 ? all 1s : all 0s
|
// This condition is very tricky; there's only one right way to handle both the case of
|
||||||
CMPSD(XMM0, R(XMM1), LT);
|
// negative/positive zero and NaN properly.
|
||||||
|
// (a >= -0.0 ? c : b) transforms into (0 > a ? b : c), hence the NLE.
|
||||||
|
CMPSD(XMM0, R(XMM1), NLE);
|
||||||
if (cpu_info.bSSE4_1)
|
if (cpu_info.bSSE4_1)
|
||||||
{
|
{
|
||||||
MOVSD(XMM1, fpr.R(c));
|
MOVSD(XMM1, fpr.R(c));
|
||||||
|
@ -228,7 +230,7 @@ void Jit64::fselx(UGeckoInstruction inst)
|
||||||
PANDN(XMM1, fpr.R(c));
|
PANDN(XMM1, fpr.R(c));
|
||||||
POR(XMM1, R(XMM0));
|
POR(XMM1, R(XMM0));
|
||||||
}
|
}
|
||||||
fpr.BindToRegister(d, false);
|
fpr.BindToRegister(d, true);
|
||||||
MOVSD(fpr.RX(d), R(XMM1));
|
MOVSD(fpr.RX(d), R(XMM1));
|
||||||
fpr.UnlockAll();
|
fpr.UnlockAll();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,17 +43,17 @@ void Jit64::ps_sel(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (cpu_info.bSSE4_1)
|
if (cpu_info.bSSE4_1)
|
||||||
{
|
{
|
||||||
MOVAPD(XMM0, fpr.R(a));
|
MOVAPD(XMM1, fpr.R(a));
|
||||||
PXOR(XMM1, R(XMM1));
|
PXOR(XMM0, R(XMM0));
|
||||||
CMPPD(XMM0, R(XMM1), LT); // XMM0 = XMM0 < 0 ? all 1s : all 0s
|
CMPPD(XMM0, R(XMM1), NLE);
|
||||||
MOVAPD(XMM1, fpr.R(c));
|
MOVAPD(XMM1, fpr.R(c));
|
||||||
BLENDVPD(XMM1, fpr.R(b));
|
BLENDVPD(XMM1, fpr.R(b));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MOVAPD(XMM1, fpr.R(a));
|
MOVAPD(XMM0, fpr.R(a));
|
||||||
PXOR(XMM0, R(XMM0));
|
PXOR(XMM1, R(XMM1));
|
||||||
CMPPD(XMM1, R(XMM0), LT); // XMM0 = XMM0 < 0 ? all 1s : all 0s
|
CMPPD(XMM1, R(XMM0), NLE);
|
||||||
MOVAPD(XMM0, R(XMM1));
|
MOVAPD(XMM0, R(XMM1));
|
||||||
PAND(XMM1, fpr.R(b));
|
PAND(XMM1, fpr.R(b));
|
||||||
PANDN(XMM0, fpr.R(c));
|
PANDN(XMM0, fpr.R(c));
|
||||||
|
|
Loading…
Reference in New Issue