[AArch64] Optimize loadstores address calculation.
For offsets that fit in the instruction encoding then we should just put it in the instruction encoding. Saves an instruction in a large amount of loadstores.
This commit is contained in:
parent
cfd4348b7a
commit
98d99a9eef
|
@ -61,11 +61,22 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o
|
||||||
imm_addr = gpr.GetImm(addr) + offset;
|
imm_addr = gpr.GetImm(addr) + offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (offset >= 0 && offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, up_reg, offset);
|
||||||
|
}
|
||||||
|
else if (offset < 0 && offset > -4096)
|
||||||
|
{
|
||||||
|
SUB(addr_reg, up_reg, std::abs(offset));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, offset);
|
MOVI2R(addr_reg, offset);
|
||||||
ADD(addr_reg, addr_reg, up_reg);
|
ADD(addr_reg, addr_reg, up_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
is_immediate = true;
|
is_immediate = true;
|
||||||
|
@ -82,15 +93,31 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o
|
||||||
imm_addr = gpr.GetImm(addr) + gpr.GetImm(offsetReg);
|
imm_addr = gpr.GetImm(addr) + gpr.GetImm(offsetReg);
|
||||||
}
|
}
|
||||||
else if (gpr.IsImm(addr) && !gpr.IsImm(offsetReg))
|
else if (gpr.IsImm(addr) && !gpr.IsImm(offsetReg))
|
||||||
|
{
|
||||||
|
u32 reg_offset = gpr.GetImm(addr);
|
||||||
|
if (reg_offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, off_reg, reg_offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, gpr.GetImm(addr));
|
MOVI2R(addr_reg, gpr.GetImm(addr));
|
||||||
ADD(addr_reg, addr_reg, off_reg);
|
ADD(addr_reg, addr_reg, off_reg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (!gpr.IsImm(addr) && gpr.IsImm(offsetReg))
|
else if (!gpr.IsImm(addr) && gpr.IsImm(offsetReg))
|
||||||
|
{
|
||||||
|
u32 reg_offset = gpr.GetImm(offsetReg);
|
||||||
|
if (reg_offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, up_reg, reg_offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, gpr.GetImm(offsetReg));
|
MOVI2R(addr_reg, gpr.GetImm(offsetReg));
|
||||||
ADD(addr_reg, addr_reg, up_reg);
|
ADD(addr_reg, addr_reg, up_reg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ADD(addr_reg, up_reg, off_reg);
|
ADD(addr_reg, up_reg, off_reg);
|
||||||
|
@ -175,11 +202,22 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
|
||||||
imm_addr = gpr.GetImm(dest) + offset;
|
imm_addr = gpr.GetImm(dest) + offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (offset >= 0 && offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, reg_dest, offset);
|
||||||
|
}
|
||||||
|
else if (offset < 0 && offset > -4096)
|
||||||
|
{
|
||||||
|
SUB(addr_reg, reg_dest, std::abs(offset));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, offset);
|
MOVI2R(addr_reg, offset);
|
||||||
ADD(addr_reg, addr_reg, reg_dest);
|
ADD(addr_reg, addr_reg, reg_dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
is_immediate = true;
|
is_immediate = true;
|
||||||
|
@ -197,14 +235,30 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
|
||||||
}
|
}
|
||||||
else if (gpr.IsImm(dest) && !gpr.IsImm(regOffset))
|
else if (gpr.IsImm(dest) && !gpr.IsImm(regOffset))
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, gpr.GetImm(dest));
|
u32 reg_offset = gpr.GetImm(dest);
|
||||||
|
if (reg_offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, reg_off, reg_offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MOVI2R(addr_reg, reg_offset);
|
||||||
ADD(addr_reg, addr_reg, reg_off);
|
ADD(addr_reg, addr_reg, reg_off);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (!gpr.IsImm(dest) && gpr.IsImm(regOffset))
|
else if (!gpr.IsImm(dest) && gpr.IsImm(regOffset))
|
||||||
|
{
|
||||||
|
u32 reg_offset = gpr.GetImm(regOffset);
|
||||||
|
if (reg_offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, reg_dest, reg_offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, gpr.GetImm(regOffset));
|
MOVI2R(addr_reg, gpr.GetImm(regOffset));
|
||||||
ADD(addr_reg, addr_reg, reg_dest);
|
ADD(addr_reg, addr_reg, reg_dest);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ADD(addr_reg, reg_dest, reg_off);
|
ADD(addr_reg, reg_dest, reg_off);
|
||||||
|
|
|
@ -93,10 +93,20 @@ void JitArm64::lfXX(UGeckoInstruction inst)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (offset_reg == -1)
|
if (offset_reg == -1)
|
||||||
|
{
|
||||||
|
if (offset >= 0 && offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, gpr.R(a), offset);
|
||||||
|
}
|
||||||
|
else if (offset < 0 && offset > -4096)
|
||||||
|
{
|
||||||
|
SUB(addr_reg, gpr.R(a), std::abs(offset));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, offset);
|
MOVI2R(addr_reg, offset);
|
||||||
ADD(addr_reg, addr_reg, gpr.R(a));
|
ADD(addr_reg, addr_reg, gpr.R(a));
|
||||||
}
|
} }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ADD(addr_reg, gpr.R(offset_reg), gpr.R(a));
|
ADD(addr_reg, gpr.R(offset_reg), gpr.R(a));
|
||||||
|
@ -113,10 +123,20 @@ void JitArm64::lfXX(UGeckoInstruction inst)
|
||||||
imm_addr = gpr.GetImm(a) + offset;
|
imm_addr = gpr.GetImm(a) + offset;
|
||||||
}
|
}
|
||||||
else if (a)
|
else if (a)
|
||||||
|
{
|
||||||
|
if (offset >= 0 && offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, gpr.R(a), offset);
|
||||||
|
}
|
||||||
|
else if (offset < 0 && offset > -4096)
|
||||||
|
{
|
||||||
|
SUB(addr_reg, gpr.R(a), std::abs(offset));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, offset);
|
MOVI2R(addr_reg, offset);
|
||||||
ADD(addr_reg, addr_reg, gpr.R(a));
|
ADD(addr_reg, addr_reg, gpr.R(a));
|
||||||
}
|
} }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
is_immediate = true;
|
is_immediate = true;
|
||||||
|
@ -265,10 +285,21 @@ void JitArm64::stfXX(UGeckoInstruction inst)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (offset_reg == -1)
|
if (offset_reg == -1)
|
||||||
|
{
|
||||||
|
if (offset >= 0 && offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, gpr.R(a), offset);
|
||||||
|
}
|
||||||
|
else if (offset < 0 && offset > -4096)
|
||||||
|
{
|
||||||
|
SUB(addr_reg, gpr.R(a), std::abs(offset));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, offset);
|
MOVI2R(addr_reg, offset);
|
||||||
ADD(addr_reg, addr_reg, gpr.R(a));
|
ADD(addr_reg, addr_reg, gpr.R(a));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ADD(addr_reg, gpr.R(offset_reg), gpr.R(a));
|
ADD(addr_reg, gpr.R(offset_reg), gpr.R(a));
|
||||||
|
@ -285,10 +316,20 @@ void JitArm64::stfXX(UGeckoInstruction inst)
|
||||||
imm_addr = gpr.GetImm(a) + offset;
|
imm_addr = gpr.GetImm(a) + offset;
|
||||||
}
|
}
|
||||||
else if (a)
|
else if (a)
|
||||||
|
{
|
||||||
|
if (offset >= 0 && offset < 4096)
|
||||||
|
{
|
||||||
|
ADD(addr_reg, gpr.R(a), offset);
|
||||||
|
}
|
||||||
|
else if (offset < 0 && offset > -4096)
|
||||||
|
{
|
||||||
|
SUB(addr_reg, gpr.R(a), std::abs(offset));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MOVI2R(addr_reg, offset);
|
MOVI2R(addr_reg, offset);
|
||||||
ADD(addr_reg, addr_reg, gpr.R(a));
|
ADD(addr_reg, addr_reg, gpr.R(a));
|
||||||
}
|
} }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
is_immediate = true;
|
is_immediate = true;
|
||||||
|
|
Loading…
Reference in New Issue