summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2014-12-21 20:56:49 -0600
committerRyan Houdek <Sonicadvance1@gmail.com>2014-12-21 20:56:49 -0600
commit0d744cddf68debc27134d4c8604f373db3ca19ff (patch)
treee53a917b8d91268c91f29fa00381ec8eb9edac9e /Source
parentd35f7231dc803b5b71a7bde7e54d3012daf66253 (diff)
parentc22e750f74c3836024c76e4b3ee9b7ffe3cf271d (diff)
Merge pull request #1729 from Sonicadvance1/AArch64_compare_me
[AArch64] Add partial support for cmp* instructions.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h4
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp99
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp8
3 files changed, 107 insertions, 4 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h
index fdefed6556..b0c4689bff 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h
@@ -83,6 +83,10 @@ public:
void extsXx(UGeckoInstruction inst);
void cntlzwx(UGeckoInstruction inst);
void negx(UGeckoInstruction inst);
+ void cmp(UGeckoInstruction inst);
+ void cmpl(UGeckoInstruction inst);
+ void cmpi(UGeckoInstruction inst);
+ void cmpli(UGeckoInstruction inst);
// System Registers
void mtmsr(UGeckoInstruction inst);
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index db03b99872..a1a7ffa005 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -316,3 +316,102 @@ void JitArm64::negx(UGeckoInstruction inst)
ComputeRC(gpr.R(d), 0);
}
}
+
+void JitArm64::cmp(UGeckoInstruction inst)
+{
+ INSTRUCTION_START
+ JITDISABLE(bJITIntegerOff);
+
+ int crf = inst.CRFD;
+ u32 a = inst.RA, b = inst.RB;
+
+ if (gpr.IsImm(a) && gpr.IsImm(b))
+ {
+ ComputeRC((s32)gpr.GetImm(a) - (s32)gpr.GetImm(b), crf);
+ return;
+ }
+
+ ARM64Reg WA = gpr.GetReg();
+ ARM64Reg RA = gpr.R(a);
+ ARM64Reg RB = gpr.R(b);
+
+ SUB(WA, RA, RB);
+ ComputeRC(WA, crf);
+
+ gpr.Unlock(WA);
+}
+
+void JitArm64::cmpl(UGeckoInstruction inst)
+{
+ INSTRUCTION_START
+ JITDISABLE(bJITIntegerOff);
+
+ int crf = inst.CRFD;
+ u32 a = inst.RA, b = inst.RB;
+
+ if (gpr.IsImm(a) && gpr.IsImm(b))
+ {
+ ComputeRC(gpr.GetImm(a) - gpr.GetImm(b), crf);
+ return;
+ }
+ else if (gpr.IsImm(b) && !gpr.GetImm(b))
+ {
+ ComputeRC(gpr.R(a), crf);
+ return;
+ }
+
+ FALLBACK_IF(true);
+}
+
+void JitArm64::cmpi(UGeckoInstruction inst)
+{
+ INSTRUCTION_START
+ JITDISABLE(bJITIntegerOff);
+
+ u32 a = inst.RA;
+ int crf = inst.CRFD;
+ if (gpr.IsImm(a))
+ {
+ ComputeRC((s32)gpr.GetImm(a) - inst.SIMM_16, crf);
+ return;
+ }
+
+ ARM64Reg WA = gpr.GetReg();
+
+ if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 4096)
+ {
+ SUB(WA, gpr.R(a), inst.SIMM_16);
+ }
+ else
+ {
+ MOVI2R(WA, inst.SIMM_16);
+ SUB(WA, gpr.R(a), WA);
+ }
+
+ ComputeRC(WA, crf);
+
+ gpr.Unlock(WA);
+}
+
+void JitArm64::cmpli(UGeckoInstruction inst)
+{
+ INSTRUCTION_START
+ JITDISABLE(bJITIntegerOff);
+ u32 a = inst.RA;
+ int crf = inst.CRFD;
+
+ if (gpr.IsImm(a))
+ {
+ ComputeRC(gpr.GetImm(a) - inst.UIMM, crf);
+ return;
+ }
+
+ if (!inst.UIMM)
+ {
+ ComputeRC(gpr.R(a), crf);
+ return;
+ }
+
+ FALLBACK_IF(true);
+}
+
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
index 6e27274511..04ed7e7be6 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
@@ -47,8 +47,8 @@ static GekkoOPTemplate primarytable[] =
{7, &JitArm64::FallBackToInterpreter}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
{8, &JitArm64::FallBackToInterpreter}, //"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
- {10, &JitArm64::FallBackToInterpreter}, //"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
- {11, &JitArm64::FallBackToInterpreter}, //"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
+ {10, &JitArm64::cmpli}, //"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
+ {11, &JitArm64::cmpi}, //"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
{12, &JitArm64::FallBackToInterpreter}, //"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
{13, &JitArm64::FallBackToInterpreter}, //"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}},
{14, &JitArm64::arith_imm}, //"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}},
@@ -189,8 +189,8 @@ static GekkoOPTemplate table31[] =
{412, &JitArm64::boolX}, //"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
{476, &JitArm64::boolX}, //"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
{284, &JitArm64::boolX}, //"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
- {0, &JitArm64::FallBackToInterpreter}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
- {32, &JitArm64::FallBackToInterpreter}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
+ {0, &JitArm64::cmp}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
+ {32, &JitArm64::cmpl}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
{26, &JitArm64::cntlzwx}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
{922, &JitArm64::extsXx}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
{954, &JitArm64::extsXx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},