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 divwx(UGeckoInstruction inst);
|
||||||
void srawix(UGeckoInstruction inst);
|
void srawix(UGeckoInstruction inst);
|
||||||
void srawx(UGeckoInstruction inst);
|
void srawx(UGeckoInstruction inst);
|
||||||
void addex(UGeckoInstruction inst);
|
void arithXex(UGeckoInstruction inst);
|
||||||
void addmex(UGeckoInstruction inst);
|
|
||||||
void addzex(UGeckoInstruction inst);
|
|
||||||
|
|
||||||
void extsXx(UGeckoInstruction inst);
|
void extsXx(UGeckoInstruction inst);
|
||||||
|
|
||||||
|
@ -219,9 +217,6 @@ public:
|
||||||
void subfic(UGeckoInstruction inst);
|
void subfic(UGeckoInstruction inst);
|
||||||
void subfcx(UGeckoInstruction inst);
|
void subfcx(UGeckoInstruction inst);
|
||||||
void subfx(UGeckoInstruction inst);
|
void subfx(UGeckoInstruction inst);
|
||||||
void subfex(UGeckoInstruction inst);
|
|
||||||
void subfmex(UGeckoInstruction inst);
|
|
||||||
void subfzex(UGeckoInstruction inst);
|
|
||||||
|
|
||||||
void twx(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}},
|
{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}},
|
{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}},
|
{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}},
|
{138, &Jit64::arithXex}, //"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}},
|
{650, &Jit64::arithXex}, //"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}},
|
{234, &Jit64::arithXex}, //"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}},
|
{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}},
|
{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}},
|
{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}},
|
{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}},
|
{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}},
|
{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}},
|
{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}},
|
{136, &Jit64::arithXex}, //"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}},
|
{232, &Jit64::arithXex}, //"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}},
|
{200, &Jit64::arithXex}, //"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
|
||||||
};
|
};
|
||||||
|
|
||||||
static GekkoOPTemplate table59[] =
|
static GekkoOPTemplate table59[] =
|
||||||
|
|
|
@ -781,84 +781,6 @@ void Jit64::subfcx(UGeckoInstruction inst)
|
||||||
gpr.UnlockAll();
|
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)
|
void Jit64::subfx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
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
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITIntegerOff);
|
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.Lock(a, b, d);
|
||||||
gpr.BindToRegister(d, (d == a) || (d == b));
|
gpr.BindToRegister(d, d == a || d == b);
|
||||||
JitGetAndClearCAOV(inst.OE);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
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));
|
MOV(32, gpr.R(d), gpr.R(a));
|
||||||
ADC(32, gpr.R(d), gpr.R(b));
|
if (!add)
|
||||||
|
NOT(32, gpr.R(d));
|
||||||
|
ADC(32, gpr.R(d), source);
|
||||||
}
|
}
|
||||||
FinalizeCarryOverflow(inst.OE);
|
FinalizeCarryOverflow(inst.OE, invertedCarry);
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC(gpr.R(d));
|
ComputeRC(gpr.R(d));
|
||||||
gpr.UnlockAll();
|
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)
|
void Jit64::rlwinmx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
|
Loading…
Reference in New Issue