summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2021-06-17 16:34:24 +0200
committerJosJuice <josjuice@gmail.com>2021-06-17 16:47:55 +0200
commit752c4898b19a11368ebf7314c4d659bc946ee76b (patch)
treee42d5fda592f8f5ea387fdf195450d38a336f919 /Source/Core
parent503c62ec00f53fac6995b255ce189e3e0127f233 (diff)
JitArm64: Simplify addex/subfex
Some of the code used when the carry flag is known to be a constant value is really not much better than just setting the carry flag and then using the normal code, and with how rarely this code runs, it isn't well tested either. Might as well get rid of some of this code and simplify things.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h1
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp120
2 files changed, 40 insertions, 81 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h
index c16521b240..817563dd32 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h
@@ -263,6 +263,7 @@ protected:
void ComputeCarry(Arm64Gen::ARM64Reg reg); // reg must contain 0 or 1
void ComputeCarry(bool carry);
void ComputeCarry();
+ void LoadCarry();
void FlushCarry();
void reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index c92eeb9f84..a25e742466 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -76,6 +76,35 @@ void JitArm64::ComputeCarry()
FlushCarry();
}
+void JitArm64::LoadCarry()
+{
+ switch (js.carryFlag)
+ {
+ case CarryFlag::InPPCState:
+ {
+ ARM64Reg WA = gpr.GetReg();
+ LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
+ CMP(WA, 1);
+ gpr.Unlock(WA);
+ break;
+ }
+ case CarryFlag::InHostCarry:
+ {
+ break;
+ }
+ case CarryFlag::ConstantTrue:
+ {
+ CMP(ARM64Reg::WZR, ARM64Reg::WZR);
+ break;
+ }
+ case CarryFlag::ConstantFalse:
+ {
+ CMN(ARM64Reg::WZR, ARM64Reg::WZR);
+ break;
+ }
+ }
+}
+
void JitArm64::FlushCarry()
{
switch (js.carryFlag)
@@ -996,45 +1025,17 @@ void JitArm64::subfex(UGeckoInstruction inst)
{
gpr.BindToRegister(d, d == a || d == b);
- switch (js.carryFlag)
- {
- case CarryFlag::InPPCState:
+ if (js.carryFlag == CarryFlag::ConstantTrue)
{
- // upload the carry state
- ARM64Reg WA = gpr.GetReg();
- LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
- CMP(WA, 1);
- gpr.Unlock(WA);
- [[fallthrough]];
+ CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
}
- case CarryFlag::InHostCarry:
+ else
{
+ LoadCarry();
CARRY_IF_NEEDED(SBC, SBCS, gpr.R(d), gpr.R(b), gpr.R(a));
- ComputeCarry();
- break;
- }
- case CarryFlag::ConstantTrue:
- {
- CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
- ComputeCarry();
- break;
}
- case CarryFlag::ConstantFalse:
- {
- ARM64Reg WA = gpr.GetReg();
- if (gpr.IsImm(a))
- MOVI2R(WA, u32(~gpr.GetImm(a)));
- else
- MVN(WA, gpr.R(a));
-
- CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), WA, gpr.R(b));
-
- gpr.Unlock(WA);
- ComputeCarry();
- break;
- }
- }
+ ComputeCarry();
}
if (inst.Rc)
@@ -1213,60 +1214,17 @@ void JitArm64::addex(UGeckoInstruction inst)
{
gpr.BindToRegister(d, d == a || d == b);
- if (js.carryFlag == CarryFlag::ConstantTrue && !gpr.IsImm(a) && !gpr.IsImm(b))
+ if (js.carryFlag == CarryFlag::ConstantFalse)
{
- CMP(ARM64Reg::WZR, ARM64Reg::WZR);
- js.carryFlag = CarryFlag::InHostCarry;
- }
-
- switch (js.carryFlag)
- {
- case CarryFlag::InPPCState:
- {
- // upload the carry state
- ARM64Reg WA = gpr.GetReg();
- LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
- CMP(WA, 1);
- gpr.Unlock(WA);
- [[fallthrough]];
+ CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
}
- case CarryFlag::InHostCarry:
+ else
{
+ LoadCarry();
CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), gpr.R(b));
- ComputeCarry();
- break;
}
- case CarryFlag::ConstantTrue:
- {
- if (!gpr.IsImm(b))
- std::swap(a, b);
- ASSERT(gpr.IsImm(b));
-
- ARM64Reg WA = gpr.GetReg();
- const u32 imm = gpr.GetImm(b) + 1;
- if (imm == 0)
- {
- if (d != a)
- MOV(gpr.R(d), gpr.R(a));
- ComputeCarry(true);
- }
- else
- {
- CARRY_IF_NEEDED(ADDI2R, ADDSI2R, gpr.R(d), gpr.R(a), imm, WA);
- ComputeCarry();
- }
- gpr.Unlock(WA);
-
- break;
- }
- case CarryFlag::ConstantFalse:
- {
- CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
- ComputeCarry();
- break;
- }
- }
+ ComputeCarry();
}
if (inst.Rc)