summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorFiora <fioraaeterna@gmail.com>2014-08-24 11:25:56 -0700
committerFiora <fioraaeterna@gmail.com>2014-09-08 20:15:47 -0700
commit298f85e15243c562edd984f01a5eb3d8979bd8a2 (patch)
tree7163327b8d3b984aa614628e46a9d149458609ca /Source/Core
parentfaf6bdfd96b1953fd6eb40935d9162ccd986902c (diff)
JIT64: optimize sign-extend
Remove some code duplication. Also remove some comments that no longer apply since x86_32 was dropped.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.h3
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp4
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp53
3 files changed, 20 insertions, 40 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h
index 0b726521a6..a2b261d7b3 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.h
@@ -153,8 +153,7 @@ public:
void addmex(UGeckoInstruction inst);
void addzex(UGeckoInstruction inst);
- void extsbx(UGeckoInstruction inst);
- void extshx(UGeckoInstruction inst);
+ void extsXx(UGeckoInstruction inst);
void sc(UGeckoInstruction _inst);
void rfi(UGeckoInstruction _inst);
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
index fa7c19aec8..927e83353f 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
@@ -190,8 +190,8 @@ static GekkoOPTemplate table31[] =
{0, &Jit64::cmpXX}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
{32, &Jit64::cmpXX}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
{26, &Jit64::cntlzwx}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
- {922, &Jit64::extshx}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
- {954, &Jit64::extsbx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
+ {922, &Jit64::extsXx}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
+ {954, &Jit64::extsXx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
{536, &Jit64::srwx}, //"srwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
{792, &Jit64::srawx}, //"srawx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
{824, &Jit64::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index ec5f68cd18..01212e3065 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -796,56 +796,37 @@ void Jit64::boolX(UGeckoInstruction inst)
}
}
-void Jit64::extsbx(UGeckoInstruction inst)
+void Jit64::extsXx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
int a = inst.RA, s = inst.RS;
+ int size = inst.SUBOP10 == 922 ? 16 : 8;
if (gpr.R(s).IsImm())
{
- gpr.SetImmediate32(a, (u32)(s32)(s8)gpr.R(s).offset);
- }
- else
- {
- gpr.Lock(a, s);
- gpr.BindToRegister(a, a == s, true);
- MOVSX(32, 8, gpr.RX(a), gpr.R(s));
- gpr.UnlockAll();
- }
-
- if (inst.Rc)
- {
- ComputeRC(gpr.R(a));
- }
-}
-
-void Jit64::extshx(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITIntegerOff);
- int a = inst.RA, s = inst.RS;
-
- if (gpr.R(s).IsImm())
- {
- gpr.SetImmediate32(a, (u32)(s32)(s16)gpr.R(s).offset);
+ gpr.SetImmediate32(a, (u32)(s32)(size == 16 ? (s16)gpr.R(s).offset : (s8)gpr.R(s).offset));
+ if (inst.Rc)
+ ComputeRC(gpr.R(a));
}
else
{
gpr.Lock(a, s);
- gpr.KillImmediate(s, true, false);
gpr.BindToRegister(a, a == s, true);
- // This looks a little dangerous, but it's safe because
- // every 32-bit register has a 16-bit half at the same index
- // as the 32-bit register.
- MOVSX(32, 16, gpr.RX(a), gpr.R(s));
+ // exts is moderately commonly used with inst.Rc, so try to optimize it.
+ if (inst.Rc)
+ {
+ // Only do one movsx; the movzx is free on most modern CPUs.
+ MOVSX(64, size, gpr.RX(a), gpr.R(s));
+ MOV(64, PPCSTATE(cr_val[0]), gpr.R(a));
+ MOVZX(64, 32, gpr.RX(a), gpr.R(a));
+ }
+ else
+ {
+ MOVSX(32, size, gpr.RX(a), gpr.R(s));
+ }
gpr.UnlockAll();
}
-
- if (inst.Rc)
- {
- ComputeRC(gpr.R(a));
- }
}
void Jit64::subfic(UGeckoInstruction inst)