From 752c4898b19a11368ebf7314c4d659bc946ee76b Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 17 Jun 2021 16:34:24 +0200 Subject: [PATCH] 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. --- Source/Core/Core/PowerPC/JitArm64/Jit.h | 1 + .../PowerPC/JitArm64/JitArm64_Integer.cpp | 126 ++++++------------ 2 files changed, 43 insertions(+), 84 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: - { - // 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]]; - } - case CarryFlag::InHostCarry: - { - CARRY_IF_NEEDED(SBC, SBCS, gpr.R(d), gpr.R(b), gpr.R(a)); - ComputeCarry(); - break; - } - case CarryFlag::ConstantTrue: + if (js.carryFlag == CarryFlag::ConstantTrue) { CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a)); - ComputeCarry(); - break; } - case CarryFlag::ConstantFalse: + else { - 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; - } + LoadCarry(); + CARRY_IF_NEEDED(SBC, SBCS, gpr.R(d), gpr.R(b), gpr.R(a)); } + + 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)) - { - 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]]; - } - case CarryFlag::InHostCarry: - { - 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: + if (js.carryFlag == CarryFlag::ConstantFalse) { CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b)); - ComputeCarry(); - break; } + else + { + LoadCarry(); + CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), gpr.R(b)); } + + ComputeCarry(); } if (inst.Rc)