Jit64: merge ps_sel into fselx

This commit is contained in:
Tillmann Karras 2015-05-21 12:33:36 +02:00
parent 05a55de08f
commit dc220fa13d
4 changed files with 14 additions and 40 deletions

View File

@ -193,7 +193,6 @@ public:
void reg_imm(UGeckoInstruction inst);
void ps_sel(UGeckoInstruction inst);
void ps_mr(UGeckoInstruction inst);
void ps_sign(UGeckoInstruction inst); //aggregate
void ps_arith(UGeckoInstruction inst); //aggregate

View File

@ -127,7 +127,7 @@ static GekkoOPTemplate table4_2[] =
{18, &Jit64::ps_arith}, // ps_div
{20, &Jit64::ps_arith}, // ps_sub
{21, &Jit64::ps_arith}, // ps_add
{23, &Jit64::ps_sel}, // ps_sel
{23, &Jit64::fselx}, // ps_sel
{24, &Jit64::ps_res}, // ps_res
{25, &Jit64::ps_arith}, // ps_mul
{26, &Jit64::ps_rsqrte}, // ps_rsqrte

View File

@ -256,13 +256,18 @@ void Jit64::fselx(UGeckoInstruction inst)
int b = inst.FB;
int c = inst.FC;
bool packed = inst.OPCD == 4; // ps_sel
fpr.Lock(a, b, c, d);
MOVAPD(XMM1, fpr.R(a));
PXOR(XMM0, R(XMM0));
// This condition is very tricky; there's only one right way to handle both the case of
// 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 (packed)
CMPPD(XMM0, fpr.R(a), NLE);
else
CMPSD(XMM0, fpr.R(a), NLE);
if (cpu_info.bSSE4_1)
{
MOVAPD(XMM1, fpr.R(c));
@ -275,8 +280,12 @@ void Jit64::fselx(UGeckoInstruction inst)
PANDN(XMM1, fpr.R(c));
POR(XMM1, R(XMM0));
}
fpr.BindToRegister(d);
MOVSD(fpr.RX(d), R(XMM1));
fpr.BindToRegister(d, !packed);
if (packed)
MOVAPD(fpr.RX(d), R(XMM1));
else
MOVSD(fpr.RX(d), R(XMM1));
fpr.UnlockAll();
}

View File

@ -28,40 +28,6 @@ void Jit64::ps_mr(UGeckoInstruction inst)
MOVAPD(fpr.RX(d), fpr.R(b));
}
void Jit64::ps_sel(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
int d = inst.FD;
int a = inst.FA;
int b = inst.FB;
int c = inst.FC;
fpr.Lock(a, b, c, d);
if (cpu_info.bSSE4_1)
{
PXOR(XMM0, R(XMM0));
CMPPD(XMM0, fpr.R(a), NLE);
MOVAPD(XMM1, fpr.R(c));
BLENDVPD(XMM1, fpr.R(b));
}
else
{
PXOR(XMM1, R(XMM1));
CMPPD(XMM1, fpr.R(a), NLE);
MOVAPD(XMM0, R(XMM1));
PAND(XMM1, fpr.R(b));
PANDN(XMM0, fpr.R(c));
POR(XMM1, R(XMM0));
}
fpr.BindToRegister(d, false);
MOVAPD(fpr.RX(d), R(XMM1));
fpr.UnlockAll();
}
void Jit64::ps_sign(UGeckoInstruction inst)
{
INSTRUCTION_START