JIT64: Optimize cmpXX
Use TEST instead of CMP if we're comparing against 0 (rather common), and optimize the case of immediate compares further.
This commit is contained in:
parent
de662a79b7
commit
faf6bdfd96
|
@ -460,12 +460,13 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
X64Reg input = RSCRATCH;
|
||||||
if (signedCompare)
|
if (signedCompare)
|
||||||
{
|
{
|
||||||
if (gpr.R(a).IsImm())
|
if (gpr.R(a).IsImm())
|
||||||
MOV(64, R(RSCRATCH), Imm32((s32)gpr.R(a).offset));
|
MOV(64, R(input), Imm32((s32)gpr.R(a).offset));
|
||||||
else
|
else
|
||||||
MOVSX(64, 32, RSCRATCH, gpr.R(a));
|
MOVSX(64, 32, input, gpr.R(a));
|
||||||
|
|
||||||
if (!comparand.IsImm())
|
if (!comparand.IsImm())
|
||||||
{
|
{
|
||||||
|
@ -476,19 +477,46 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gpr.R(a).IsImm())
|
if (gpr.R(a).IsImm())
|
||||||
MOV(32, R(RSCRATCH), Imm32((u32)gpr.R(a).offset));
|
{
|
||||||
|
MOV(32, R(input), Imm32((u32)gpr.R(a).offset));
|
||||||
|
}
|
||||||
|
else if (comparand.IsImm() && !comparand.offset)
|
||||||
|
{
|
||||||
|
gpr.BindToRegister(a, true, false);
|
||||||
|
input = gpr.RX(a);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
MOVZX(64, 32, RSCRATCH, gpr.R(a));
|
{
|
||||||
|
MOVZX(64, 32, input, gpr.R(a));
|
||||||
|
}
|
||||||
|
|
||||||
if (comparand.IsImm())
|
if (comparand.IsImm())
|
||||||
MOV(32, R(RSCRATCH2), comparand);
|
{
|
||||||
|
// sign extension will ruin this, so store it in a register
|
||||||
|
if (comparand.offset & 0x80000000U)
|
||||||
|
{
|
||||||
|
MOV(32, R(RSCRATCH2), comparand);
|
||||||
|
comparand = R(RSCRATCH2);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
MOVZX(64, 32, RSCRATCH2, comparand);
|
{
|
||||||
|
gpr.BindToRegister(b, true, false);
|
||||||
comparand = R(RSCRATCH2);
|
comparand = gpr.R(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (comparand.IsImm() && !comparand.offset)
|
||||||
|
{
|
||||||
|
MOV(64, PPCSTATE(cr_val[crf]), R(input));
|
||||||
|
// Place the comparison next to the branch for macro-op fusion
|
||||||
|
if (merge_branch)
|
||||||
|
TEST(64, R(input), R(input));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SUB(64, R(input), comparand);
|
||||||
|
MOV(64, PPCSTATE(cr_val[crf]), R(input));
|
||||||
}
|
}
|
||||||
SUB(64, R(RSCRATCH), comparand);
|
|
||||||
MOV(64, PPCSTATE(cr_val[crf]), R(RSCRATCH));
|
|
||||||
|
|
||||||
if (merge_branch)
|
if (merge_branch)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue