From c22e750f74c3836024c76e4b3ee9b7ffe3cf271d Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Fri, 19 Dec 2014 22:00:43 -0600 Subject: [PATCH] [AArch64] Add partial support for cmp* instructions. This support is as far as ARMv7's support for these instructions. Requires PR #1728 prior to merging. --- Source/Core/Core/PowerPC/JitArm64/Jit.h | 4 + .../PowerPC/JitArm64/JitArm64_Integer.cpp | 99 +++++++++++++++++++ .../Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 8 +- 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 d52e7c5ba4..f309a7cde2 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 84c00449be..d7ab813fe3 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -277,3 +277,102 @@ void JitArm64::negx(UGeckoInstruction inst) if (inst.Rc) ComputeRC(d); } + +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 336bf47640..e285b09535 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}},