mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-08 15:20:45 +01:00
JitArm64_Integer: addzex - Optimize ConstantFalse and ConstantTrue
When the input register and carry flags are known, we can always precompute the result. We still materialize the immediate when the condition register needs to be updated, but this seems to be a general problem. I might look into that one day, but for now this'll do. - ConstantFalse Before: 0x52800119 mov w25, #0x8 ; =8 0x2a1903fa mov w26, w25 After: N/A - ConstantTrue Before: 0x52800119 mov w25, #0x8 ; =8 0x1100073a add w26, w25, #0x1 After: N/A
This commit is contained in:
parent
a4ba13b4c9
commit
14641b06fc
@ -10,6 +10,7 @@
|
||||
#include "Common/BitUtils.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Common/Unreachable.h"
|
||||
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
@ -1128,47 +1129,73 @@ void JitArm64::addzex(UGeckoInstruction inst)
|
||||
|
||||
int a = inst.RA, d = inst.RD;
|
||||
|
||||
switch (js.carryFlag)
|
||||
if (gpr.IsImm(a) && HasConstantCarry())
|
||||
{
|
||||
case CarryFlag::InPPCState:
|
||||
{
|
||||
const bool allocate_reg = d == a;
|
||||
gpr.BindToRegister(d, allocate_reg);
|
||||
const u32 imm = gpr.GetImm(a);
|
||||
const bool is_all_ones = imm == 0xFFFFFFFF;
|
||||
|
||||
switch (js.carryFlag)
|
||||
{
|
||||
auto WA = allocate_reg ? gpr.GetScopedReg() : Arm64GPRCache::ScopedARM64Reg(gpr.R(d));
|
||||
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), WA);
|
||||
}
|
||||
|
||||
ComputeCarry();
|
||||
break;
|
||||
}
|
||||
case CarryFlag::InHostCarry:
|
||||
{
|
||||
gpr.BindToRegister(d, d == a);
|
||||
CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), ARM64Reg::WZR);
|
||||
ComputeCarry();
|
||||
break;
|
||||
}
|
||||
case CarryFlag::ConstantTrue:
|
||||
{
|
||||
gpr.BindToRegister(d, d == a);
|
||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), 1);
|
||||
ComputeCarry();
|
||||
break;
|
||||
}
|
||||
case CarryFlag::ConstantFalse:
|
||||
{
|
||||
if (d != a)
|
||||
case CarryFlag::ConstantTrue:
|
||||
{
|
||||
gpr.BindToRegister(d, false);
|
||||
MOV(gpr.R(d), gpr.R(a));
|
||||
gpr.SetImmediate(d, imm + 1);
|
||||
ComputeCarry(is_all_ones);
|
||||
break;
|
||||
}
|
||||
case CarryFlag::ConstantFalse:
|
||||
{
|
||||
gpr.SetImmediate(d, imm);
|
||||
ComputeCarry(false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Common::Unreachable();
|
||||
}
|
||||
|
||||
ComputeCarry(false);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (js.carryFlag)
|
||||
{
|
||||
case CarryFlag::InPPCState:
|
||||
{
|
||||
const bool allocate_reg = d == a;
|
||||
gpr.BindToRegister(d, allocate_reg);
|
||||
|
||||
{
|
||||
auto WA = allocate_reg ? gpr.GetScopedReg() : Arm64GPRCache::ScopedARM64Reg(gpr.R(d));
|
||||
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
|
||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), WA);
|
||||
}
|
||||
|
||||
ComputeCarry();
|
||||
break;
|
||||
}
|
||||
case CarryFlag::InHostCarry:
|
||||
{
|
||||
gpr.BindToRegister(d, d == a);
|
||||
CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), ARM64Reg::WZR);
|
||||
ComputeCarry();
|
||||
break;
|
||||
}
|
||||
case CarryFlag::ConstantTrue:
|
||||
{
|
||||
gpr.BindToRegister(d, d == a);
|
||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), 1);
|
||||
ComputeCarry();
|
||||
break;
|
||||
}
|
||||
case CarryFlag::ConstantFalse:
|
||||
{
|
||||
if (d != a)
|
||||
{
|
||||
gpr.BindToRegister(d, false);
|
||||
MOV(gpr.R(d), gpr.R(a));
|
||||
}
|
||||
|
||||
ComputeCarry(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inst.Rc)
|
||||
|
Loading…
Reference in New Issue
Block a user