summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorSintendo <bram.speeckaert@gmail.com>2021-09-20 23:56:38 +0200
committerSintendo <bram.speeckaert@gmail.com>2021-09-22 22:28:54 +0200
commita725eb80ffe5d6ecc66d1247ea7f003dd09bdfb0 (patch)
tree1d9d4a8d4db284e88349509da5a8f6936d578f29 /Source/Core
parenta9e0f21373d354cf6d9ab2882ca42a53a7002063 (diff)
Jit64: Merge addx and addcx
They are extremely similar and can share nearly all optimizations.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.h1
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp8
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp53
3 files changed, 22 insertions, 40 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h
index 7da679b86c..5916093295 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.h
@@ -150,7 +150,6 @@ public:
void DynaRunTable63(UGeckoInstruction inst);
void addx(UGeckoInstruction inst);
- void addcx(UGeckoInstruction inst);
void mulli(UGeckoInstruction inst);
void mulhwXx(UGeckoInstruction inst);
void mullwx(UGeckoInstruction inst);
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
index 35b17bcdb7..2d77df1d38 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp
@@ -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::addcx}, // addcx
- {522, &Jit64::addcx}, // addcox
+ {10, &Jit64::addx}, // addcx
+ {522, &Jit64::addx}, // 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::subfcx}, // subfcx
- {520, &Jit64::subfcx}, // subfcox
+ {8, &Jit64::subfcx}, // subfcx
+ {520, &Jit64::subfcx}, // subfcox
{136, &Jit64::arithXex}, // subfex
{648, &Jit64::arithXex}, // subfeox
{232, &Jit64::arithXex}, // subfmex
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index d85fd1a3a9..c1a6846d16 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -1656,19 +1656,21 @@ void Jit64::addx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
int a = inst.RA, b = inst.RB, d = inst.RD;
+ bool carry = !(inst.SUBOP10 & (1 << 8));
if (gpr.IsImm(a, b))
{
- s32 i = gpr.SImm32(a), j = gpr.SImm32(b);
+ const s32 i = gpr.SImm32(a), j = gpr.SImm32(b);
gpr.SetImmediate32(d, i + j);
+ if (carry)
+ FinalizeCarry(Interpreter::Helper_Carry(i, j));
if (inst.OE)
GenerateConstantOverflow((s64)i + (s64)j);
}
else if (gpr.IsImm(a) || gpr.IsImm(b))
{
- auto [i, j] = gpr.IsImm(a) ? std::pair(a, b) : std::pair(b, a);
-
- s32 imm = gpr.SImm32(i);
+ const auto [i, j] = gpr.IsImm(a) ? std::pair(a, b) : std::pair(b, a);
+ const s32 imm = gpr.SImm32(i);
RCOpArg Rj = gpr.Use(j, RCMode::Read);
RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
RegCache::Realize(Rj, Rd);
@@ -1677,16 +1679,20 @@ void Jit64::addx(UGeckoInstruction inst)
{
if (d != j)
MOV(32, Rd, Rj);
+ if (carry)
+ FinalizeCarry(false);
if (inst.OE)
GenerateConstantOverflow(false);
}
else if (d == j)
{
ADD(32, Rd, Imm32(imm));
+ if (carry)
+ FinalizeCarry(CC_C);
if (inst.OE)
GenerateOverflow();
}
- else if (Rj.IsSimpleReg() && !inst.OE)
+ else if (Rj.IsSimpleReg() && !carry && !inst.OE)
{
LEA(32, Rd, MDisp(Rj.GetSimpleReg(), imm));
}
@@ -1694,6 +1700,8 @@ void Jit64::addx(UGeckoInstruction inst)
{
MOV(32, Rd, Rj);
ADD(32, Rd, Imm32(imm));
+ if (carry)
+ FinalizeCarry(CC_C);
if (inst.OE)
GenerateOverflow();
}
@@ -1701,6 +1709,8 @@ void Jit64::addx(UGeckoInstruction inst)
{
MOV(32, Rd, Imm32(imm));
ADD(32, Rd, Rj);
+ if (carry)
+ FinalizeCarry(CC_C);
if (inst.OE)
GenerateOverflow();
}
@@ -1717,7 +1727,7 @@ void Jit64::addx(UGeckoInstruction inst)
RCOpArg& Rnotd = (d == a) ? Rb : Ra;
ADD(32, Rd, Rnotd);
}
- else if (Ra.IsSimpleReg() && Rb.IsSimpleReg() && !inst.OE)
+ else if (Ra.IsSimpleReg() && Rb.IsSimpleReg() && !carry && !inst.OE)
{
LEA(32, Rd, MRegSum(Ra.GetSimpleReg(), Rb.GetSimpleReg()));
}
@@ -1726,6 +1736,8 @@ void Jit64::addx(UGeckoInstruction inst)
MOV(32, Rd, Ra);
ADD(32, Rd, Rb);
}
+ if (carry)
+ FinalizeCarry(CC_C);
if (inst.OE)
GenerateOverflow();
}
@@ -1806,35 +1818,6 @@ void Jit64::arithXex(UGeckoInstruction inst)
ComputeRC(d);
}
-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