JitArm64: ADDI2R optimizations 2.
This commit is contained in:
parent
1df694626d
commit
694e9b4132
|
@ -2055,6 +2055,28 @@ void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ARM64XEmitter::MOVI2R2(ARM64Reg Rd, u64 imm1, u64 imm2)
|
||||||
|
{
|
||||||
|
// TODO: Also optimize for performance, not just for code size.
|
||||||
|
u8* start_pointer = GetWritableCodePtr();
|
||||||
|
|
||||||
|
MOVI2R(Rd, imm1);
|
||||||
|
int size1 = GetCodePtr() - start_pointer;
|
||||||
|
|
||||||
|
SetCodePtrUnsafe(start_pointer);
|
||||||
|
|
||||||
|
MOVI2R(Rd, imm2);
|
||||||
|
int size2 = GetCodePtr() - start_pointer;
|
||||||
|
|
||||||
|
SetCodePtrUnsafe(start_pointer);
|
||||||
|
|
||||||
|
bool element = size1 > size2;
|
||||||
|
|
||||||
|
MOVI2R(Rd, element ? imm2 : imm1);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
void ARM64XEmitter::ABI_PushRegisters(BitSet32 registers)
|
void ARM64XEmitter::ABI_PushRegisters(BitSet32 registers)
|
||||||
{
|
{
|
||||||
int num_regs = registers.Count();
|
int num_regs = registers.Count();
|
||||||
|
@ -4140,13 +4162,25 @@ void ARM64XEmitter::ADDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
||||||
{
|
{
|
||||||
SUB(Rd, Rn, val, shift);
|
SUB(Rd, Rn, val, shift);
|
||||||
}
|
}
|
||||||
|
else if ((imm >= 0x10000u || scratch == INVALID_REG) && imm < 0x1000000u)
|
||||||
|
{
|
||||||
|
ADD(Rd, Rn, imm & 0xFFF, false);
|
||||||
|
ADD(Rd, Rd, imm >> 12, true);
|
||||||
|
}
|
||||||
|
else if ((imm_neg >= 0x10000u || scratch == INVALID_REG) && imm_neg < 0x1000000u)
|
||||||
|
{
|
||||||
|
SUB(Rd, Rn, imm_neg & 0xFFF, false);
|
||||||
|
SUB(Rd, Rd, imm_neg >> 12, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_assert_msg_(DYNA_REC, scratch != INVALID_REG,
|
_assert_msg_(DYNA_REC, scratch != INVALID_REG,
|
||||||
"ADDI2R - failed to construct arithmetic immediate value from %08x, need scratch",
|
"ADDI2R - failed to construct arithmetic immediate value from %08x, need scratch",
|
||||||
(u32)imm);
|
(u32)imm);
|
||||||
MOVI2R(scratch, imm);
|
if (MOVI2R2(scratch, imm, imm_neg))
|
||||||
ADD(Rd, Rn, scratch);
|
SUB(Rd, Rn, scratch);
|
||||||
|
else
|
||||||
|
ADD(Rd, Rn, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4168,8 +4202,10 @@ void ARM64XEmitter::ADDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
||||||
_assert_msg_(DYNA_REC, scratch != INVALID_REG,
|
_assert_msg_(DYNA_REC, scratch != INVALID_REG,
|
||||||
"ADDSI2R - failed to construct arithmetic immediate value from %08x, need scratch",
|
"ADDSI2R - failed to construct arithmetic immediate value from %08x, need scratch",
|
||||||
(u32)imm);
|
(u32)imm);
|
||||||
MOVI2R(scratch, imm);
|
if (MOVI2R2(scratch, imm, imm_neg))
|
||||||
ADDS(Rd, Rn, scratch);
|
SUBS(Rd, Rn, scratch);
|
||||||
|
else
|
||||||
|
ADDS(Rd, Rn, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4186,13 +4222,25 @@ void ARM64XEmitter::SUBI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
||||||
{
|
{
|
||||||
ADD(Rd, Rn, val, shift);
|
ADD(Rd, Rn, val, shift);
|
||||||
}
|
}
|
||||||
|
else if ((imm >= 0x10000u || scratch == INVALID_REG) && imm < 0x1000000u)
|
||||||
|
{
|
||||||
|
SUB(Rd, Rn, imm & 0xFFF, false);
|
||||||
|
SUB(Rd, Rd, imm >> 12, true);
|
||||||
|
}
|
||||||
|
else if ((imm_neg >= 0x10000u || scratch == INVALID_REG) && imm_neg < 0x1000000u)
|
||||||
|
{
|
||||||
|
ADD(Rd, Rn, imm_neg & 0xFFF, false);
|
||||||
|
ADD(Rd, Rd, imm_neg >> 12, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_assert_msg_(DYNA_REC, scratch != INVALID_REG,
|
_assert_msg_(DYNA_REC, scratch != INVALID_REG,
|
||||||
"SUBI2R - failed to construct arithmetic immediate value from %08x, need scratch",
|
"SUBI2R - failed to construct arithmetic immediate value from %08x, need scratch",
|
||||||
(u32)imm);
|
(u32)imm);
|
||||||
MOVI2R(scratch, imm);
|
if (MOVI2R2(scratch, imm, imm_neg))
|
||||||
SUB(Rd, Rn, scratch);
|
ADD(Rd, Rn, scratch);
|
||||||
|
else
|
||||||
|
SUB(Rd, Rn, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4213,8 +4261,10 @@ void ARM64XEmitter::SUBSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
||||||
{
|
{
|
||||||
_assert_msg_(DYNA_REC, scratch != INVALID_REG,
|
_assert_msg_(DYNA_REC, scratch != INVALID_REG,
|
||||||
"ANDSI2R - failed to construct immediate value from %08x, need scratch", (u32)imm);
|
"ANDSI2R - failed to construct immediate value from %08x, need scratch", (u32)imm);
|
||||||
MOVI2R(scratch, imm);
|
if (MOVI2R2(scratch, imm, imm_neg))
|
||||||
SUBS(Rd, Rn, scratch);
|
ADDS(Rd, Rn, scratch);
|
||||||
|
else
|
||||||
|
SUBS(Rd, Rn, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -835,6 +835,7 @@ public:
|
||||||
|
|
||||||
// Wrapper around MOVZ+MOVK
|
// Wrapper around MOVZ+MOVK
|
||||||
void MOVI2R(ARM64Reg Rd, u64 imm, bool optimize = true);
|
void MOVI2R(ARM64Reg Rd, u64 imm, bool optimize = true);
|
||||||
|
bool MOVI2R2(ARM64Reg Rd, u64 imm1, u64 imm2);
|
||||||
template <class P>
|
template <class P>
|
||||||
void MOVP2R(ARM64Reg Rd, P* ptr)
|
void MOVP2R(ARM64Reg Rd, P* ptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -492,29 +492,7 @@ void JitArm64::lmw(UGeckoInstruction inst)
|
||||||
ARM64Reg XA = EncodeRegTo64(WA);
|
ARM64Reg XA = EncodeRegTo64(WA);
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
bool add = inst.SIMM_16 >= 0;
|
ADDI2R(WA, gpr.R(a), inst.SIMM_16, WA);
|
||||||
u16 off = std::abs(inst.SIMM_16);
|
|
||||||
if (off < 4096)
|
|
||||||
{
|
|
||||||
if (add)
|
|
||||||
ADD(WA, gpr.R(a), off);
|
|
||||||
else
|
|
||||||
SUB(WA, gpr.R(a), off);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u16 remaining = off >> 12;
|
|
||||||
if (add)
|
|
||||||
{
|
|
||||||
ADD(WA, gpr.R(a), off & 0xFFF);
|
|
||||||
ADD(WA, WA, remaining, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SUB(WA, gpr.R(a), off & 0xFFF);
|
|
||||||
SUB(WA, WA, remaining, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ADD(XA, XA, MEM_REG);
|
ADD(XA, XA, MEM_REG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -579,29 +557,7 @@ void JitArm64::stmw(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
bool add = inst.SIMM_16 >= 0;
|
ADDI2R(WA, gpr.R(a), inst.SIMM_16, WA);
|
||||||
u16 off = std::abs(inst.SIMM_16);
|
|
||||||
if (off < 4096)
|
|
||||||
{
|
|
||||||
if (add)
|
|
||||||
ADD(WA, gpr.R(a), off);
|
|
||||||
else
|
|
||||||
SUB(WA, gpr.R(a), off);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u16 remaining = off >> 12;
|
|
||||||
if (add)
|
|
||||||
{
|
|
||||||
ADD(WA, gpr.R(a), off & 0xFFF);
|
|
||||||
ADD(WA, WA, remaining, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SUB(WA, gpr.R(a), off & 0xFFF);
|
|
||||||
SUB(WA, WA, remaining, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ADD(XA, XA, MEM_REG);
|
ADD(XA, XA, MEM_REG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue