JIT: unify subfe/submex/subfex/adde/addmex/addzex code

Shorter, plus should make future optimizations easier.
This commit is contained in:
Fiora 2014-09-06 19:33:34 -07:00
parent 64b21a4812
commit 5d80145dc0
3 changed files with 30 additions and 138 deletions

View File

@ -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);

View File

@ -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[] =

View File

@ -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