[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:
Ryan Houdek 2015-01-18 16:45:42 -06:00
parent cfd4348b7a
commit 98d99a9eef
2 changed files with 118 additions and 23 deletions

View file

@ -62,8 +62,19 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o
}
else
{
MOVI2R(addr_reg, offset);
ADD(addr_reg, addr_reg, up_reg);
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);
ADD(addr_reg, addr_reg, up_reg);
}
}
}
else
@ -83,13 +94,29 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o
}
else if (gpr.IsImm(addr) && !gpr.IsImm(offsetReg))
{
MOVI2R(addr_reg, gpr.GetImm(addr));
ADD(addr_reg, addr_reg, off_reg);
u32 reg_offset = gpr.GetImm(addr);
if (reg_offset < 4096)
{
ADD(addr_reg, off_reg, reg_offset);
}
else
{
MOVI2R(addr_reg, gpr.GetImm(addr));
ADD(addr_reg, addr_reg, off_reg);
}
}
else if (!gpr.IsImm(addr) && gpr.IsImm(offsetReg))
{
MOVI2R(addr_reg, gpr.GetImm(offsetReg));
ADD(addr_reg, addr_reg, up_reg);
u32 reg_offset = gpr.GetImm(offsetReg);
if (reg_offset < 4096)
{
ADD(addr_reg, up_reg, reg_offset);
}
else
{
MOVI2R(addr_reg, gpr.GetImm(offsetReg));
ADD(addr_reg, addr_reg, up_reg);
}
}
else
{
@ -176,8 +203,19 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
}
else
{
MOVI2R(addr_reg, offset);
ADD(addr_reg, addr_reg, reg_dest);
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);
ADD(addr_reg, addr_reg, reg_dest);
}
}
}
else
@ -197,13 +235,29 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
}
else if (gpr.IsImm(dest) && !gpr.IsImm(regOffset))
{
MOVI2R(addr_reg, gpr.GetImm(dest));
ADD(addr_reg, addr_reg, reg_off);
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);
}
}
else if (!gpr.IsImm(dest) && gpr.IsImm(regOffset))
{
MOVI2R(addr_reg, gpr.GetImm(regOffset));
ADD(addr_reg, addr_reg, reg_dest);
u32 reg_offset = gpr.GetImm(regOffset);
if (reg_offset < 4096)
{
ADD(addr_reg, reg_dest, reg_offset);
}
else
{
MOVI2R(addr_reg, gpr.GetImm(regOffset));
ADD(addr_reg, addr_reg, reg_dest);
}
}
else
{

View file

@ -94,9 +94,19 @@ void JitArm64::lfXX(UGeckoInstruction inst)
{
if (offset_reg == -1)
{
MOVI2R(addr_reg, offset);
ADD(addr_reg, addr_reg, gpr.R(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);
ADD(addr_reg, addr_reg, gpr.R(a));
} }
else
{
ADD(addr_reg, gpr.R(offset_reg), gpr.R(a));
@ -114,9 +124,19 @@ void JitArm64::lfXX(UGeckoInstruction inst)
}
else if (a)
{
MOVI2R(addr_reg, offset);
ADD(addr_reg, addr_reg, gpr.R(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);
ADD(addr_reg, addr_reg, gpr.R(a));
} }
else
{
is_immediate = true;
@ -266,8 +286,19 @@ void JitArm64::stfXX(UGeckoInstruction inst)
{
if (offset_reg == -1)
{
MOVI2R(addr_reg, offset);
ADD(addr_reg, addr_reg, gpr.R(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);
ADD(addr_reg, addr_reg, gpr.R(a));
}
}
else
{
@ -286,9 +317,19 @@ void JitArm64::stfXX(UGeckoInstruction inst)
}
else if (a)
{
MOVI2R(addr_reg, offset);
ADD(addr_reg, addr_reg, gpr.R(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);
ADD(addr_reg, addr_reg, gpr.R(a));
} }
else
{
is_immediate = true;