diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index beb287620c..78363d7493 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -143,8 +143,7 @@ namespace Jit64 void fcmpx(UGeckoInstruction inst); void fmrx(UGeckoInstruction inst); - void cmpXi(UGeckoInstruction inst); - void cmpX(UGeckoInstruction inst); + void cmpXX(UGeckoInstruction inst); void cntlzwx(UGeckoInstruction inst); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp index 8fedb90f7b..14729d8056 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp @@ -147,7 +147,7 @@ namespace Jit64 */ // unsigned - void cmpXi(UGeckoInstruction inst) + void cmpXX(UGeckoInstruction inst) { // USES_CR #ifdef JIT_OFF_OPTIONS @@ -159,21 +159,40 @@ namespace Jit64 // towards branches. INSTRUCTION_START; int a = inst.RA; + int b = inst.RB; int crf = inst.CRFD; int shift = crf * 4; Gen::CCFlags less_than, greater_than; OpArg comparand; - if (inst.OPCD == 10) { - less_than = CC_B; - greater_than = CC_A; - comparand = Imm32(inst.UIMM); - } else { - less_than = CC_L; - greater_than = CC_G; - comparand = Imm32((s32)(s16)inst.UIMM); + if (inst.OPCD == 31) { + gpr.Lock(a, b); + gpr.LoadToX64(a, true, false); + comparand = gpr.R(b); + if (inst.SUBOP10 == 32) { + //cmpl + less_than = CC_B; + greater_than = CC_A; + } else { + //cmp + less_than = CC_L; + greater_than = CC_G; + } + } + else { + gpr.KillImmediate(a); // todo, optimize instead, but unlikely to make a difference + if (inst.OPCD == 10) { + //cmpli + less_than = CC_B; + greater_than = CC_A; + comparand = Imm32(inst.UIMM); + } else if (inst.OPCD == 11) { + //cmpi + less_than = CC_L; + greater_than = CC_G; + comparand = Imm32((s32)(s16)inst.UIMM); + } } - gpr.KillImmediate(a); // todo, optimize instead, but unlikely to make a difference CMP(32, gpr.R(a), comparand); FixupBranch pLesser = J_CC(less_than); FixupBranch pGreater = J_CC(greater_than); @@ -190,53 +209,13 @@ namespace Jit64 SetJumpTarget(continue1); SetJumpTarget(continue2); + gpr.UnlockAll(); + // TODO: Add extra code at the end for the "taken" case. Jump to it from the matching branches. // Since it's the last block, some liberties can be taken. // don't forget to flush registers AFTER the cmp BEFORE the jmp. Flushing doesn't affect flags. } - // signed - void cmpX(UGeckoInstruction inst) - { - // USES_CR -#ifdef JIT_OFF_OPTIONS - if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITIntegerOff) - {Default(inst); return;} // turn off from debugger -#endif - INSTRUCTION_START; - int a = inst.RA; - int b = inst.RB; - int crf = inst.CRFD; - int shift = crf * 4; - Gen::CCFlags less_than, greater_than; - Gen::OpArg comparand = gpr.R(b); - if (inst.SUBOP10 == 32) { - less_than = CC_B; - greater_than = CC_A; - } else { - less_than = CC_L; - greater_than = CC_G; - } - gpr.Lock(a, b); - gpr.LoadToX64(a, true, false); - CMP(32, gpr.R(a), comparand); - FixupBranch pLesser = J_CC(less_than); - FixupBranch pGreater = J_CC(greater_than); - // _x86Reg == 0 - MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x2)); // _x86Reg == 0 - FixupBranch continue1 = J(); - - SetJumpTarget(pGreater); - MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x4)); // _x86Reg > 0 - FixupBranch continue2 = J(); - - SetJumpTarget(pLesser); - MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x8)); // _x86Reg < 0 - SetJumpTarget(continue1); - SetJumpTarget(continue2); - gpr.UnlockAll(); - } - void orx(UGeckoInstruction inst) { #ifdef JIT_OFF_OPTIONS diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index 6681e5fa7c..7b779d7f87 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -141,8 +141,8 @@ GekkoOPTemplate primarytable[] = {7, Interpreter::mulli, Jit64::mulli, {"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}}, {8, Interpreter::subfic, Jit64::subfic, {"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, - {10, Interpreter::cmpli, Jit64::cmpXi, {"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, - {11, Interpreter::cmpi, Jit64::cmpXi, {"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, + {10, Interpreter::cmpli, Jit64::cmpXX, {"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, + {11, Interpreter::cmpi, Jit64::cmpXX, {"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, {12, Interpreter::addic, Jit64::reg_imm, {"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, {13, Interpreter::addic_rc, Jit64::reg_imm, {"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}}, {14, Interpreter::addi, Jit64::reg_imm, {"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}}, @@ -283,8 +283,8 @@ GekkoOPTemplate table31[] = {412, Interpreter::orcx, Jit64::Default, {"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {476, Interpreter::nandx, Jit64::Default, {"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {284, Interpreter::eqvx, Jit64::Default, {"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, - {0, Interpreter::cmp, Jit64::cmpX, {"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, - {32, Interpreter::cmpl, Jit64::cmpX, {"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, + {0, Interpreter::cmp, Jit64::cmpXX, {"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, + {32, Interpreter::cmpl, Jit64::cmpXX, {"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, {26, Interpreter::cntlzwx, Jit64::cntlzwx, {"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, {922, Interpreter::extshx, Jit64::extshx, {"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, {954, Interpreter::extsbx, Jit64::extsbx, {"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.h b/Source/Core/Core/Src/PowerPC/PowerPC.h index 838898669e..8b709ed232 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.h +++ b/Source/Core/Core/Src/PowerPC/PowerPC.h @@ -143,7 +143,7 @@ inline u32 GetCRBit(int bit) { return (PowerPC::ppcState.cr_fast[bit >> 2] >> (3 - (bit & 3))) & 1; } -// SetCR and GetCR may become fairly slow soon. Should be avoided if possible. +// SetCR and GetCR are fairly slow. Should be avoided if possible. inline void SetCR(u32 new_cr) { PowerPC::ppcState.cr = new_cr; PowerPC::ExpandCR();