From 5d80145dc0de8d742f19995310bd04e442f521e1 Mon Sep 17 00:00:00 2001 From: Fiora Date: Sat, 6 Sep 2014 19:33:34 -0700 Subject: [PATCH] JIT: unify subfe/submex/subfex/adde/addmex/addzex code Shorter, plus should make future optimizations easier. --- Source/Core/Core/PowerPC/Jit64/Jit.h | 7 +- .../Core/Core/PowerPC/Jit64/Jit64_Tables.cpp | 14 +- .../Core/Core/PowerPC/Jit64/Jit_Integer.cpp | 147 +++--------------- 3 files changed, 30 insertions(+), 138 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h index 821df102d1..dc3eae8a4c 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/PowerPC/Jit64/Jit.h @@ -147,9 +147,7 @@ public: void divwx(UGeckoInstruction inst); void srawix(UGeckoInstruction inst); void srawx(UGeckoInstruction inst); - void addex(UGeckoInstruction inst); - void addmex(UGeckoInstruction inst); - void addzex(UGeckoInstruction inst); + void arithXex(UGeckoInstruction inst); void extsXx(UGeckoInstruction inst); @@ -219,9 +217,6 @@ public: void subfic(UGeckoInstruction inst); void subfcx(UGeckoInstruction inst); void subfx(UGeckoInstruction inst); - void subfex(UGeckoInstruction inst); - void subfmex(UGeckoInstruction inst); - void subfzex(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 927e83353f..a285c815c2 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp @@ -296,10 +296,10 @@ static GekkoOPTemplate table31_2[] = {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}}, - {138, &Jit64::addex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, - {650, &Jit64::addex}, //"addeox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, - {234, &Jit64::addmex}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, - {202, &Jit64::addzex}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | 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}}, + {202, &Jit64::arithXex}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {491, &Jit64::divwx}, //"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, {1003, &Jit64::divwx}, //"divwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, {459, &Jit64::divwux}, //"divwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, @@ -313,9 +313,9 @@ static GekkoOPTemplate table31_2[] = {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}}, - {136, &Jit64::subfex}, //"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, - {232, &Jit64::subfmex}, //"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, - {200, &Jit64::subfzex}, //"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | 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}}, }; static GekkoOPTemplate table59[] = diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index 10ea9f8448..cf1e226c7c 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -781,84 +781,6 @@ void Jit64::subfcx(UGeckoInstruction inst) gpr.UnlockAll(); } -void Jit64::subfex(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); - - JitGetAndClearCAOV(inst.OE); - - bool invertedCarry = false; - if (d == b) - { - // Convert carry to borrow - CMC(); - SBB(32, gpr.R(d), gpr.R(a)); - invertedCarry = true; - } - else if (d == a) - { - NOT(32, gpr.R(d)); - ADC(32, gpr.R(d), gpr.R(b)); - } - else - { - MOV(32, gpr.R(d), gpr.R(a)); - NOT(32, gpr.R(d)); - ADC(32, gpr.R(d), gpr.R(b)); - } - FinalizeCarryOverflow(inst.OE, invertedCarry); - if (inst.Rc) - ComputeRC(gpr.R(d)); - - gpr.UnlockAll(); -} - -void Jit64::subfmex(UGeckoInstruction inst) -{ - // USES_XER - INSTRUCTION_START - JITDISABLE(bJITIntegerOff); - int a = inst.RA, d = inst.RD; - gpr.Lock(a, d); - gpr.BindToRegister(d, d == a); - - JitGetAndClearCAOV(inst.OE); - if (d != a) - MOV(32, gpr.R(d), gpr.R(a)); - NOT(32, gpr.R(d)); - ADC(32, gpr.R(d), Imm32(0xFFFFFFFF)); - FinalizeCarryOverflow(inst.OE); - if (inst.Rc) - ComputeRC(gpr.R(d)); - gpr.UnlockAll(); -} - -void Jit64::subfzex(UGeckoInstruction inst) -{ - // USES_XER - INSTRUCTION_START - JITDISABLE(bJITIntegerOff); - int a = inst.RA, d = inst.RD; - - gpr.Lock(a, d); - gpr.BindToRegister(d, d == a); - - JitGetAndClearCAOV(inst.OE); - if (d != a) - MOV(32, gpr.R(d), gpr.R(a)); - NOT(32, gpr.R(d)); - ADC(32, gpr.R(d), Imm8(0)); - FinalizeCarryOverflow(inst.OE); - if (inst.Rc) - ComputeRC(gpr.R(d)); - - gpr.UnlockAll(); -} - void Jit64::subfx(UGeckoInstruction inst) { INSTRUCTION_START @@ -1325,26 +1247,39 @@ void Jit64::addx(UGeckoInstruction inst) } } -void Jit64::addex(UGeckoInstruction inst) +void Jit64::arithXex(UGeckoInstruction inst) { - // USES_XER INSTRUCTION_START JITDISABLE(bJITIntegerOff); - int a = inst.RA, b = inst.RB, d = inst.RD; + bool regsource = !(inst.SUBOP10 & 64); // addex or subfex + bool mex = !!(inst.SUBOP10 & 32); // addmex/subfmex or addzex/subfzex + bool add = !!(inst.SUBOP10 & 2); // add or sub + int a = inst.RA; + int b = regsource ? inst.RB : a; + int d = inst.RD; gpr.Lock(a, b, d); - gpr.BindToRegister(d, (d == a) || (d == b)); + gpr.BindToRegister(d, d == a || d == b); JitGetAndClearCAOV(inst.OE); - if ((d == a) || (d == b)) + + bool invertedCarry = false; + if (!add && regsource && d == b) { - ADC(32, gpr.R(d), gpr.R((d == a) ? b : a)); + // Convert carry to borrow + CMC(); + SBB(32, gpr.R(d), gpr.R(a)); + invertedCarry = true; } else { - MOV(32, gpr.R(d), gpr.R(a)); - ADC(32, gpr.R(d), gpr.R(b)); + OpArg source = regsource ? gpr.R(d == b ? a : b) : Imm32(mex ? 0xFFFFFFFF : 0); + if (d != a && d != b) + MOV(32, gpr.R(d), gpr.R(a)); + if (!add) + NOT(32, gpr.R(d)); + ADC(32, gpr.R(d), source); } - FinalizeCarryOverflow(inst.OE); + FinalizeCarryOverflow(inst.OE, invertedCarry); if (inst.Rc) ComputeRC(gpr.R(d)); gpr.UnlockAll(); @@ -1382,44 +1317,6 @@ void Jit64::addcx(UGeckoInstruction inst) } } -void Jit64::addmex(UGeckoInstruction inst) -{ - // USES_XER - INSTRUCTION_START - JITDISABLE(bJITIntegerOff); - int a = inst.RA, d = inst.RD; - - gpr.Lock(d); - gpr.BindToRegister(d, d == a); - JitGetAndClearCAOV(inst.OE); - if (d != a) - MOV(32, gpr.R(d), gpr.R(a)); - ADC(32, gpr.R(d), Imm32(0xFFFFFFFF)); - FinalizeCarryOverflow(inst.OE); - if (inst.Rc) - ComputeRC(gpr.R(d)); - gpr.UnlockAll(); -} - -void Jit64::addzex(UGeckoInstruction inst) -{ - // USES_XER - INSTRUCTION_START - JITDISABLE(bJITIntegerOff); - int a = inst.RA, d = inst.RD; - - gpr.Lock(d); - gpr.BindToRegister(d, d == a); - JitGetAndClearCAOV(inst.OE); - if (d != a) - MOV(32, gpr.R(d), gpr.R(a)); - ADC(32, gpr.R(d), Imm8(0)); - FinalizeCarryOverflow(inst.OE); - if (inst.Rc) - ComputeRC(gpr.R(d)); - gpr.UnlockAll(); -} - void Jit64::rlwinmx(UGeckoInstruction inst) { INSTRUCTION_START