From 8a20ccc5f9f1da5013dfa89a579741ffea4cb9a8 Mon Sep 17 00:00:00 2001 From: florian Date: Thu, 23 Aug 2012 21:03:24 +0000 Subject: [PATCH] + Add/SubLdr2Ldr optimization git-svn-id: trunk@22217 - --- compiler/arm/aoptcpu.pas | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index 03ef9e8a58..15a8a59699 100644 --- a/compiler/arm/aoptcpu.pas +++ b/compiler/arm/aoptcpu.pas @@ -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, ...