diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h index dc3eae8a4c..dd5af56673 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/PowerPC/Jit64/Jit.h @@ -139,7 +139,7 @@ public: void DynaRunTable63(UGeckoInstruction _inst); void addx(UGeckoInstruction inst); - void addcx(UGeckoInstruction inst); + void arithcx(UGeckoInstruction inst); void mulli(UGeckoInstruction inst); void mulhwXx(UGeckoInstruction inst); void mullwx(UGeckoInstruction inst); @@ -215,7 +215,6 @@ public: void dcbz(UGeckoInstruction inst); void subfic(UGeckoInstruction inst); - void subfcx(UGeckoInstruction inst); void subfx(UGeckoInstruction inst); void twx(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp index a285c815c2..98c986a2f0 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp @@ -294,8 +294,8 @@ static GekkoOPTemplate table31_2[] = { {266, &Jit64::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, {778, &Jit64::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, - {10, &Jit64::addcx}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, - {522, &Jit64::addcx}, //"addcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {10, &Jit64::arithcx}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {522, &Jit64::arithcx}, //"addcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, {138, &Jit64::arithXex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {650, &Jit64::arithXex}, //"addeox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {234, &Jit64::arithXex}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, @@ -311,8 +311,8 @@ static GekkoOPTemplate table31_2[] = {104, &Jit64::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, {40, &Jit64::subfx}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, {552, &Jit64::subfx}, //"subox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, - {8, &Jit64::subfcx}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, - {520, &Jit64::subfcx}, //"subfcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {8, &Jit64::arithcx}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {520, &Jit64::arithcx}, //"subfcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, {136, &Jit64::arithXex}, //"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {232, &Jit64::arithXex}, //"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {200, &Jit64::arithXex}, //"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index cf1e226c7c..0b6f0dac4f 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -750,36 +750,7 @@ void Jit64::subfic(UGeckoInstruction inst) // This instruction has no RC flag } -void Jit64::subfcx(UGeckoInstruction inst) -{ - INSTRUCTION_START; - JITDISABLE(bJITIntegerOff); - int a = inst.RA, b = inst.RB, d = inst.RD; - gpr.Lock(a, b, d); - gpr.BindToRegister(d, (d == a || d == b), true); - JitClearCAOV(inst.OE); - if (d == b) - { - SUB(32, gpr.R(d), gpr.R(a)); - } - else if (d == a) - { - MOV(32, R(RSCRATCH), gpr.R(a)); - MOV(32, gpr.R(d), gpr.R(b)); - SUB(32, gpr.R(d), R(RSCRATCH)); - } - else - { - MOV(32, gpr.R(d), gpr.R(b)); - SUB(32, gpr.R(d), gpr.R(a)); - } - if (inst.Rc) - ComputeRC(gpr.R(d)); - FinalizeCarryOverflow(inst.OE, true); - - gpr.UnlockAll(); -} void Jit64::subfx(UGeckoInstruction inst) { @@ -1285,36 +1256,44 @@ void Jit64::arithXex(UGeckoInstruction inst) gpr.UnlockAll(); } -void Jit64::addcx(UGeckoInstruction inst) +void Jit64::arithcx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(bJITIntegerOff); + bool add = !!(inst.SUBOP10 & 2); // add or sub int a = inst.RA, b = inst.RB, d = inst.RD; + gpr.Lock(a, b, d); + gpr.BindToRegister(d, d == a || d == b, true); + JitClearCAOV(inst.OE); - if ((d == a) || (d == b)) + if (d == a && d != b) { - int operand = ((d == a) ? b : a); - gpr.Lock(a, b, d); - gpr.BindToRegister(d, true); - JitClearCAOV(inst.OE); - ADD(32, gpr.R(d), gpr.R(operand)); - FinalizeCarryOverflow(inst.OE); - if (inst.Rc) - ComputeRC(gpr.R(d)); - gpr.UnlockAll(); + if (add) + { + ADD(32, gpr.R(d), gpr.R(b)); + } + else + { + // special case, because sub isn't reversible + MOV(32, R(RSCRATCH), gpr.R(a)); + MOV(32, gpr.R(d), gpr.R(b)); + SUB(32, gpr.R(d), R(RSCRATCH)); + } } else { - gpr.Lock(a, b, d); - gpr.BindToRegister(d, false); - JitClearCAOV(inst.OE); - MOV(32, gpr.R(d), gpr.R(a)); - ADD(32, gpr.R(d), gpr.R(b)); - FinalizeCarryOverflow(inst.OE); - if (inst.Rc) - ComputeRC(gpr.R(d)); - gpr.UnlockAll(); + if (d != b) + MOV(32, gpr.R(d), gpr.R(b)); + if (add) + ADD(32, gpr.R(d), gpr.R(a)); + else + SUB(32, gpr.R(d), gpr.R(a)); } + + FinalizeCarryOverflow(inst.OE, !add); + if (inst.Rc) + ComputeRC(gpr.R(d)); + gpr.UnlockAll(); } void Jit64::rlwinmx(UGeckoInstruction inst)