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}},