Jit64: Split arithcx into addcx and subfcx

JitArm64 also opts to separate the two. The shared logic makes less
sense once we start adding more optimizations.
This commit is contained in:
Sintendo 2021-09-17 22:59:00 +02:00
parent cc84799c7f
commit a9e0f21373
3 changed files with 42 additions and 23 deletions

View File

@ -150,7 +150,7 @@ public:
void DynaRunTable63(UGeckoInstruction inst);
void addx(UGeckoInstruction inst);
void arithcx(UGeckoInstruction inst);
void addcx(UGeckoInstruction inst);
void mulli(UGeckoInstruction inst);
void mulhwXx(UGeckoInstruction inst);
void mullwx(UGeckoInstruction inst);
@ -233,6 +233,7 @@ public:
void subfic(UGeckoInstruction inst);
void subfx(UGeckoInstruction inst);
void subfcx(UGeckoInstruction inst);
void twX(UGeckoInstruction inst);

View File

@ -150,8 +150,8 @@ constexpr std::array<GekkoOPTemplate, 13> s_table19{{
constexpr std::array<GekkoOPTemplate, 107> s_table31{{
{266, &Jit64::addx}, // addx
{778, &Jit64::addx}, // addox
{10, &Jit64::arithcx}, // addcx
{522, &Jit64::arithcx}, // addcox
{10, &Jit64::addcx}, // addcx
{522, &Jit64::addcx}, // addcox
{138, &Jit64::arithXex}, // addex
{650, &Jit64::arithXex}, // addeox
{234, &Jit64::arithXex}, // addmex
@ -170,8 +170,8 @@ constexpr std::array<GekkoOPTemplate, 107> s_table31{{
{616, &Jit64::negx}, // negox
{40, &Jit64::subfx}, // subfx
{552, &Jit64::subfx}, // subfox
{8, &Jit64::arithcx}, // subfcx
{520, &Jit64::arithcx}, // subfcox
{8, &Jit64::subfcx}, // subfcx
{520, &Jit64::subfcx}, // subfcox
{136, &Jit64::arithXex}, // subfex
{648, &Jit64::arithXex}, // subfeox
{232, &Jit64::arithXex}, // subfmex

View File

@ -1806,11 +1806,39 @@ void Jit64::arithXex(UGeckoInstruction inst)
ComputeRC(d);
}
void Jit64::arithcx(UGeckoInstruction inst)
void Jit64::addcx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
int a = inst.RA, b = inst.RB, d = inst.RD;
{
RCOpArg Ra = gpr.Use(a, RCMode::Read);
RCOpArg Rb = gpr.Use(b, RCMode::Read);
RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
RegCache::Realize(Ra, Rb, Rd);
if (d == a)
{
ADD(32, Rd, Rb);
}
else
{
if (d != b)
MOV(32, Rd, Rb);
ADD(32, Rd, Ra);
}
}
FinalizeCarryOverflow(inst.OE);
if (inst.Rc)
ComputeRC(d);
}
void Jit64::subfcx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
bool add = !!(inst.SUBOP10 & 2); // add or sub
int a = inst.RA, b = inst.RB, d = inst.RD;
{
@ -1820,31 +1848,21 @@ void Jit64::arithcx(UGeckoInstruction inst)
RegCache::Realize(Ra, Rb, Rd);
if (d == a && d != b)
{
if (add)
{
ADD(32, Rd, Rb);
}
else
{
// special case, because sub isn't reversible
MOV(32, R(RSCRATCH), Ra);
MOV(32, Rd, Rb);
SUB(32, Rd, R(RSCRATCH));
}
}
else
{
if (d != b)
MOV(32, Rd, Rb);
if (add)
ADD(32, Rd, Ra);
else
SUB(32, Rd, Ra);
}
}
FinalizeCarryOverflow(inst.OE, !add);
FinalizeCarryOverflow(inst.OE, true);
if (inst.Rc)
ComputeRC(d);
}