mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-27 15:54:55 +00:00
Merge pull request #13324 from Sintendo/jitarm64-cmp-imm
JitArm64_Integer: cmp/cmpl optimizations
This commit is contained in:
commit
f9accfd4d6
2 changed files with 55 additions and 6 deletions
|
@ -652,17 +652,58 @@ void JitArm64::cmp(UGeckoInstruction inst)
|
||||||
SXTW(CR, gpr.R(b));
|
SXTW(CR, gpr.R(b));
|
||||||
MVN(CR, CR);
|
MVN(CR, CR);
|
||||||
}
|
}
|
||||||
else if (gpr.IsImm(b) && !gpr.GetImm(b))
|
else if (gpr.IsImm(b) && (gpr.GetImm(b) & 0xFFF) == gpr.GetImm(b))
|
||||||
{
|
{
|
||||||
SXTW(CR, gpr.R(a));
|
SXTW(CR, gpr.R(a));
|
||||||
|
if (const u32 imm = gpr.GetImm(b); imm != 0)
|
||||||
|
SUB(CR, CR, imm);
|
||||||
|
}
|
||||||
|
else if (gpr.IsImm(b) && (gpr.GetImm(b) & 0xFFF000) == gpr.GetImm(b))
|
||||||
|
{
|
||||||
|
SXTW(CR, gpr.R(a));
|
||||||
|
SUB(CR, CR, gpr.GetImm(b) >> 12, true);
|
||||||
|
}
|
||||||
|
else if (gpr.IsImm(b) && (((~gpr.GetImm(b) + 1) & 0xFFF) == (~gpr.GetImm(b) + 1)))
|
||||||
|
{
|
||||||
|
SXTW(CR, gpr.R(a));
|
||||||
|
ADD(CR, CR, ~gpr.GetImm(b) + 1);
|
||||||
|
}
|
||||||
|
else if (gpr.IsImm(b) && (((~gpr.GetImm(b) + 1) & 0xFFF000) == (~gpr.GetImm(b) + 1)))
|
||||||
|
{
|
||||||
|
SXTW(CR, gpr.R(a));
|
||||||
|
ADD(CR, CR, (~gpr.GetImm(b) + 1) >> 12, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// If we're dealing with immediates, check their most significant bit to
|
||||||
|
// see if we can skip sign extension.
|
||||||
|
const auto should_sign_extend = [&](u32 reg) -> bool {
|
||||||
|
return !gpr.IsImm(reg) || (gpr.GetImm(reg) & (1U << 31));
|
||||||
|
};
|
||||||
|
bool sign_extend_a = should_sign_extend(a);
|
||||||
|
bool sign_extend_b = should_sign_extend(b);
|
||||||
|
|
||||||
ARM64Reg RA = gpr.R(a);
|
ARM64Reg RA = gpr.R(a);
|
||||||
ARM64Reg RB = gpr.R(b);
|
ARM64Reg RB = gpr.R(b);
|
||||||
|
|
||||||
SXTW(CR, RA);
|
if (sign_extend_a)
|
||||||
SUB(CR, CR, RB, ArithOption(RB, ExtendSpecifier::SXTW));
|
{
|
||||||
|
SXTW(CR, RA);
|
||||||
|
RA = CR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RA = EncodeRegTo64(RA);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto opt = ArithOption(RB, ExtendSpecifier::SXTW);
|
||||||
|
if (!sign_extend_b)
|
||||||
|
{
|
||||||
|
opt = ArithOption(CR, ShiftType::LSL, 0);
|
||||||
|
RB = EncodeRegTo64(RB);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUB(CR, RA, RB, opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,9 +728,17 @@ void JitArm64::cmpl(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
NEG(CR, EncodeRegTo64(gpr.R(b)));
|
NEG(CR, EncodeRegTo64(gpr.R(b)));
|
||||||
}
|
}
|
||||||
else if (gpr.IsImm(b) && !gpr.GetImm(b))
|
else if (gpr.IsImm(b) && (gpr.GetImm(b) & 0xFFF) == gpr.GetImm(b))
|
||||||
{
|
{
|
||||||
MOV(EncodeRegTo32(CR), gpr.R(a));
|
const u32 imm = gpr.GetImm(b);
|
||||||
|
if (imm == 0)
|
||||||
|
MOV(EncodeRegTo32(CR), gpr.R(a));
|
||||||
|
else
|
||||||
|
SUB(CR, EncodeRegTo64(gpr.R(a)), imm);
|
||||||
|
}
|
||||||
|
else if (gpr.IsImm(b) && (gpr.GetImm(b) & 0xFFF000) == gpr.GetImm(b))
|
||||||
|
{
|
||||||
|
SUB(CR, EncodeRegTo64(gpr.R(a)), gpr.GetImm(b) >> 12, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -345,7 +345,7 @@ public:
|
||||||
// Gets the immediate that a register is set to. Only valid for guest GPRs.
|
// Gets the immediate that a register is set to. Only valid for guest GPRs.
|
||||||
u32 GetImm(size_t preg) const { return GetGuestGPROpArg(preg).GetImm(); }
|
u32 GetImm(size_t preg) const { return GetGuestGPROpArg(preg).GetImm(); }
|
||||||
|
|
||||||
bool IsImm(size_t preg, u32 imm) { return IsImm(preg) && GetImm(preg) == imm; }
|
bool IsImm(size_t preg, u32 imm) const { return IsImm(preg) && GetImm(preg) == imm; }
|
||||||
|
|
||||||
// Binds a guest GPR to a host register, optionally loading its value.
|
// Binds a guest GPR to a host register, optionally loading its value.
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Reference in a new issue