JIT: unify subfe/submex/subfex/adde/addmex/addzex code
Shorter, plus should make future optimizations easier.
This commit is contained in:
parent
64b21a4812
commit
5d80145dc0
|
@ -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);
|
||||
|
||||
|
|
|
@ -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[] =
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue