CPU/Recompiler/AArch64: Use cmn for negative constant comparisons

This commit is contained in:
Connor McLaughlin 2020-08-08 22:56:15 +10:00
parent 901ca71fdc
commit 70767dc6bf
3 changed files with 24 additions and 8 deletions

View file

@ -1522,8 +1522,8 @@ bool CodeGenerator::Compile_SignedDivide(const CodeBlockInstruction& cbi)
// else if (static_cast<u32>(num) == UINT32_C(0x80000000) && denom == -1) // else if (static_cast<u32>(num) == UINT32_C(0x80000000) && denom == -1)
{ {
EmitBindLabel(&not_zero); EmitBindLabel(&not_zero);
EmitConditionalBranch(Condition::NotEqual, false, denom_reg.GetHostRegister(), EmitConditionalBranch(Condition::NotEqual, false, denom_reg.GetHostRegister(), Value::FromConstantS32(-1),
Value::FromConstantU32(0xFFFFFFFFu), &do_divide); &do_divide);
EmitConditionalBranch(Condition::NotEqual, false, num_reg.GetHostRegister(), lo, &do_divide); EmitConditionalBranch(Condition::NotEqual, false, num_reg.GetHostRegister(), lo, &do_divide);
// unrepresentable // unrepresentable

View file

@ -465,6 +465,8 @@ void CodeGenerator::EmitCmp(HostReg to_reg, const Value& value)
// do we need temporary storage for the constant, if it won't fit in an immediate? // do we need temporary storage for the constant, if it won't fit in an immediate?
const s64 constant_value = value.GetS64ConstantValue(); const s64 constant_value = value.GetS64ConstantValue();
if (constant_value >= 0)
{
if (a64::Assembler::IsImmAddSub(constant_value)) if (a64::Assembler::IsImmAddSub(constant_value))
{ {
if (value.size < RegSize_64) if (value.size < RegSize_64)
@ -474,6 +476,19 @@ void CodeGenerator::EmitCmp(HostReg to_reg, const Value& value)
return; return;
} }
}
else
{
if (a64::Assembler::IsImmAddSub(-constant_value))
{
if (value.size < RegSize_64)
m_emit->cmn(GetHostReg32(to_reg), -constant_value);
else
m_emit->cmn(GetHostReg64(to_reg), -constant_value);
return;
}
}
// need a temporary // need a temporary
Value temp_value = m_register_cache.AllocateScratch(value.size); Value temp_value = m_register_cache.AllocateScratch(value.size);

View file

@ -191,6 +191,7 @@ struct Value
static Value FromConstantU8(u8 value) { return FromConstant(ZeroExtend64(value), RegSize_8); } static Value FromConstantU8(u8 value) { return FromConstant(ZeroExtend64(value), RegSize_8); }
static Value FromConstantU16(u16 value) { return FromConstant(ZeroExtend64(value), RegSize_16); } static Value FromConstantU16(u16 value) { return FromConstant(ZeroExtend64(value), RegSize_16); }
static Value FromConstantU32(u32 value) { return FromConstant(ZeroExtend64(value), RegSize_32); } static Value FromConstantU32(u32 value) { return FromConstant(ZeroExtend64(value), RegSize_32); }
static Value FromConstantS32(s32 value) { return FromConstant(ZeroExtend64(static_cast<u32>(value)), RegSize_32); }
static Value FromConstantU64(u64 value) { return FromConstant(value, RegSize_64); } static Value FromConstantU64(u64 value) { return FromConstant(value, RegSize_64); }
private: private: