summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2021-04-06 04:41:16 -0400
committerGitHub <noreply@github.com>2021-04-06 04:41:16 -0400
commit5222a4b7e5f07d6d80d5aa9daa390dccf65eb7c4 (patch)
tree2475724f16a36925ff6e1e0cddd691f345f8f302 /Source/Core
parent99d43362e611a3b2f2ef778e5d5c56d65a95e3a2 (diff)
parentbaecddd262ae3ce48b0f01e38db1213be889f16f (diff)
Merge pull request #9585 from JosJuice/jitarm64-skip-carry
JitArm64: Skip calculating carry flag when not needed
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp41
1 files changed, 25 insertions, 16 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index d3bb2c71ad..4e45b3d5c9 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -16,6 +16,15 @@
using namespace Arm64Gen;
+#define CARRY_IF_NEEDED(inst_without_carry, inst_with_carry, ...) \
+ do \
+ { \
+ if (js.op->wantsCA) \
+ inst_with_carry(__VA_ARGS__); \
+ else \
+ inst_without_carry(__VA_ARGS__); \
+ } while (0)
+
void JitArm64::ComputeRC0(ARM64Reg reg)
{
gpr.BindCRToRegister(0, false);
@@ -733,7 +742,7 @@ void JitArm64::addic(UGeckoInstruction inst)
{
gpr.BindToRegister(d, d == a);
ARM64Reg WA = gpr.GetReg();
- ADDSI2R(gpr.R(d), gpr.R(a), simm, WA);
+ CARRY_IF_NEEDED(ADDI2R, ADDSI2R, gpr.R(d), gpr.R(a), simm, WA);
gpr.Unlock(WA);
ComputeCarry();
@@ -854,7 +863,7 @@ void JitArm64::addzex(UGeckoInstruction inst)
ARM64Reg WA = d == a ? gpr.GetReg() : gpr.R(d);
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
- ADDS(gpr.R(d), gpr.R(a), WA);
+ CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), WA);
ComputeCarry();
if (d == a)
@@ -865,14 +874,14 @@ void JitArm64::addzex(UGeckoInstruction inst)
case CarryFlag::InHostCarry:
{
gpr.BindToRegister(d, d == a);
- ADCS(gpr.R(d), gpr.R(a), ARM64Reg::WZR);
+ CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), ARM64Reg::WZR);
ComputeCarry();
break;
}
case CarryFlag::ConstantTrue:
{
gpr.BindToRegister(d, d == a);
- ADDS(gpr.R(d), gpr.R(a), 1);
+ CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), 1);
ComputeCarry();
break;
}
@@ -1004,13 +1013,13 @@ void JitArm64::subfex(UGeckoInstruction inst)
else
MVN(WA, gpr.R(a));
- ADCS(gpr.R(d), WA, gpr.R(b));
+ CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), WA, gpr.R(b));
ComputeCarry();
break;
}
case CarryFlag::ConstantTrue:
{
- SUBS(gpr.R(d), gpr.R(b), gpr.R(a));
+ CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
ComputeCarry();
break;
}
@@ -1021,7 +1030,7 @@ void JitArm64::subfex(UGeckoInstruction inst)
else
MVN(WA, gpr.R(a));
- ADDS(gpr.R(d), WA, gpr.R(b));
+ CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), WA, gpr.R(b));
ComputeCarry();
break;
}
@@ -1058,7 +1067,7 @@ void JitArm64::subfcx(UGeckoInstruction inst)
gpr.BindToRegister(d, d == a || d == b);
// d = b - a
- SUBS(gpr.R(d), gpr.R(b), gpr.R(a));
+ CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
ComputeCarry();
@@ -1084,7 +1093,7 @@ void JitArm64::subfzex(UGeckoInstruction inst)
ARM64Reg WA = gpr.GetReg();
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
MVN(gpr.R(d), gpr.R(a));
- ADDS(gpr.R(d), gpr.R(d), WA);
+ CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(d), WA);
ComputeCarry();
gpr.Unlock(WA);
break;
@@ -1092,13 +1101,13 @@ void JitArm64::subfzex(UGeckoInstruction inst)
case CarryFlag::InHostCarry:
{
MVN(gpr.R(d), gpr.R(a));
- ADCS(gpr.R(d), gpr.R(d), ARM64Reg::WZR);
+ CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(d), ARM64Reg::WZR);
ComputeCarry();
break;
}
case CarryFlag::ConstantTrue:
{
- NEGS(gpr.R(d), gpr.R(a));
+ CARRY_IF_NEEDED(NEG, NEGS, gpr.R(d), gpr.R(a));
ComputeCarry();
break;
}
@@ -1136,7 +1145,7 @@ void JitArm64::subfic(UGeckoInstruction inst)
// d = imm - a
ARM64Reg WA = gpr.GetReg();
MOVI2R(WA, imm);
- SUBS(gpr.R(d), WA, gpr.R(a));
+ CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), WA, gpr.R(a));
gpr.Unlock(WA);
ComputeCarry();
@@ -1226,7 +1235,7 @@ void JitArm64::addex(UGeckoInstruction inst)
}
case CarryFlag::InHostCarry:
{
- ADCS(gpr.R(d), gpr.R(a), gpr.R(b));
+ CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), gpr.R(b));
ComputeCarry();
break;
}
@@ -1247,7 +1256,7 @@ void JitArm64::addex(UGeckoInstruction inst)
}
else
{
- ADDSI2R(gpr.R(d), gpr.R(a), imm, WA);
+ CARRY_IF_NEEDED(ADDI2R, ADDSI2R, gpr.R(d), gpr.R(a), imm, WA);
ComputeCarry();
}
gpr.Unlock(WA);
@@ -1256,7 +1265,7 @@ void JitArm64::addex(UGeckoInstruction inst)
}
case CarryFlag::ConstantFalse:
{
- ADDS(gpr.R(d), gpr.R(a), gpr.R(b));
+ CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
ComputeCarry();
break;
}
@@ -1288,7 +1297,7 @@ void JitArm64::addcx(UGeckoInstruction inst)
else
{
gpr.BindToRegister(d, d == a || d == b);
- ADDS(gpr.R(d), gpr.R(a), gpr.R(b));
+ CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
ComputeCarry();
if (inst.Rc)