summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorFiora <fioraaeterna@gmail.com>2014-08-24 11:24:27 -0700
committerFiora <fioraaeterna@gmail.com>2014-09-08 20:15:47 -0700
commitfaf6bdfd96b1953fd6eb40935d9162ccd986902c (patch)
tree29d9e64e8e084a73c02711fa2574b52c7dc66112 /Source/Core
parentde662a79b7fce6b309e03b85f5416ac89549db46 (diff)
JIT64: Optimize cmpXX
Use TEST instead of CMP if we're comparing against 0 (rather common), and optimize the case of immediate compares further.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp48
1 files changed, 38 insertions, 10 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index 90659d9729..ec5f68cd18 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -460,12 +460,13 @@ void Jit64::cmpXX(UGeckoInstruction inst)
}
else
{
+ X64Reg input = RSCRATCH;
if (signedCompare)
{
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
- MOVSX(64, 32, RSCRATCH, gpr.R(a));
+ MOVSX(64, 32, input, gpr.R(a));
if (!comparand.IsImm())
{
@@ -476,19 +477,46 @@ void Jit64::cmpXX(UGeckoInstruction inst)
else
{
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
- MOVZX(64, 32, RSCRATCH, gpr.R(a));
+ {
+ MOVZX(64, 32, input, gpr.R(a));
+ }
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
- MOVZX(64, 32, RSCRATCH2, comparand);
-
- comparand = R(RSCRATCH2);
+ {
+ gpr.BindToRegister(b, true, false);
+ 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)
{