+ Add/SubLdr2Ldr optimization

git-svn-id: trunk@22217 -
This commit is contained in:
florian 2012-08-23 21:03:24 +00:00
parent ca5078f9cf
commit 8a20ccc5f9

View File

@ -950,6 +950,71 @@ Implementation
asml.remove(hp1);
hp1.free;
end;
{
change
add/sub reg2,reg1,const1
str/ldr reg3,[reg2,const2]
dealloc reg2
to
str/ldr reg3,[reg1,const2+/-const1]
}
if (taicpu(p).opcode in [A_ADD,A_SUB]) and
(taicpu(p).oper[1]^.typ = top_reg) and
(taicpu(p).oper[2]^.typ = top_const) then
begin
hp1:=p;
while GetNextInstructionUsingReg(hp1, hp1, taicpu(p).oper[0]^.reg) and
(MatchInstruction(hp1, A_LDR, [taicpu(p).condition], [PF_None]) or
MatchInstruction(hp1, A_STR, [taicpu(p).condition], [PF_None])) and
(taicpu(hp1).oper[1]^.ref^.base=taicpu(p).oper[0]^.reg) and
(taicpu(hp1).oper[1]^.ref^.index=NR_NO) and
(taicpu(hp1).oper[1]^.ref^.addressmode=AM_OFFSET) and
{ new offset must be valid: either in the range of 8 or 12 bit, depend on the
ldr postfix }
(((taicpu(p).opcode=A_ADD) and
(((taicpu(hp1).oppostfix=PF_None) and
(abs(taicpu(hp1).oper[1]^.ref^.offset+taicpu(p).oper[2]^.val)<4096)) or
(abs(taicpu(hp1).oper[1]^.ref^.offset+taicpu(p).oper[2]^.val)<256)
)
) or
((taicpu(p).opcode=A_SUB) and
(((taicpu(hp1).oppostfix=PF_None) and
(abs(taicpu(hp1).oper[1]^.ref^.offset-taicpu(p).oper[2]^.val)<4096)) or
(abs(taicpu(hp1).oper[1]^.ref^.offset-taicpu(p).oper[2]^.val)<256)
)
)
) do
begin
{ reg2 might not be changed inbetween }
if RegModifiedBetween(taicpu(p).oper[0]^.reg,p,hp1) then
break;
{ reg2 must be either overwritten by the ldr or it is deallocated afterwards }
if ((taicpu(hp1).opcode=A_LDR) and (taicpu(p).oper[0]^.reg=taicpu(hp1).oper[0]^.reg)) or
assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) then
begin
{ remember last instruction }
hp2:=hp1;
asml.insertbefore(tai_comment.Create(strpnew('Peephole Add/SubLdr2Ldr done')), p);
hp1:=p;
{ fix all ldr/str }
while GetNextInstructionUsingReg(hp1, hp1, taicpu(p).oper[0]^.reg) do
begin
taicpu(hp1).oper[1]^.ref^.base:=taicpu(p).oper[1]^.reg;
if taicpu(p).opcode=A_ADD then
inc(taicpu(hp1).oper[1]^.ref^.offset,taicpu(p).oper[2]^.val)
else
dec(taicpu(hp1).oper[1]^.ref^.offset,taicpu(p).oper[2]^.val);
if hp1=hp2 then
break;
end;
GetNextInstruction(p,hp1);
asml.remove(p);
p.free;
p:=hp1;
break;
end;
end;
end;
{
change
add reg1, ...