Browse Source

+ LookForPostindexedPattern

git-svn-id: trunk@22228 -
florian 13 years ago
parent
commit
245d8286d5
1 changed files with 60 additions and 0 deletions
  1. 60 0
      compiler/arm/aoptcpu.pas

+ 60 - 0
compiler/arm/aoptcpu.pas

@@ -50,6 +50,9 @@ Type
 
 
     { outputs a debug message into the assembler file }
     { outputs a debug message into the assembler file }
     procedure DebugMsg(const s: string; p: tai);
     procedure DebugMsg(const s: string; p: tai);
+
+  protected
+    function LookForPostindexedPattern(p: taicpu): boolean;
   End;
   End;
 
 
   TCpuPreRegallocScheduler = class(TAsmScheduler)
   TCpuPreRegallocScheduler = class(TAsmScheduler)
@@ -349,6 +352,60 @@ Implementation
         end;
         end;
     end;
     end;
 
 
+
+  {
+    optimize
+      ldr/str regX,[reg1]
+      ...
+      add/sub reg1,reg1,regY/const
+
+      into
+
+      ldr/str regX,[reg1], regY/const
+  }
+  function TCpuAsmOptimizer.LookForPostindexedPattern(p: taicpu) : boolean;
+    var
+      hp1 : tai;
+    begin
+      Result:=false;
+      if (p.oper[1]^.ref^.addressmode=AM_OFFSET) and
+        (p.oper[1]^.ref^.index=NR_NO) and
+        (p.oper[1]^.ref^.offset=0) and
+        GetNextInstructionUsingReg(p, hp1, p.oper[1]^.ref^.base) and
+        (hp1.typ=ait_instruction) and
+        { we cannot check NR_DEFAULTFLAGS for modification yet so don't allow a condition }
+        (MatchInstruction(hp1, A_ADD, [C_None], [PF_None]) or
+         MatchInstruction(hp1, A_SUB, [C_None], [PF_None])) and
+        (taicpu(hp1).oper[0]^.reg=p.oper[1]^.ref^.base) and
+        (taicpu(hp1).oper[1]^.reg=p.oper[1]^.ref^.base) and
+        { don't apply the optimization if the base register is loaded }
+        (p.oper[0]^.reg<>p.oper[1]^.ref^.base) and
+        not(RegModifiedBetween(taicpu(hp1).oper[0]^.reg,p,hp1)) then
+        begin
+          DebugMsg('Peephole Str/LdrAdd/Sub2Str/Ldr Postindex done', p);
+          p.oper[1]^.ref^.addressmode:=AM_POSTINDEXED;
+          if taicpu(hp1).oper[2]^.typ=top_const then
+            begin
+              if taicpu(hp1).opcode=A_ADD then
+                p.oper[1]^.ref^.offset:=taicpu(hp1).oper[2]^.val
+              else
+                p.oper[1]^.ref^.offset:=-taicpu(hp1).oper[2]^.val;
+            end
+          else
+            begin
+              p.oper[1]^.ref^.index:=taicpu(hp1).oper[1]^.reg;
+              if taicpu(hp1).opcode=A_ADD then
+                p.oper[1]^.ref^.signindex:=1
+              else
+                p.oper[1]^.ref^.signindex:=-1;
+            end;
+          asml.Remove(hp1);
+          hp1.Free;
+          Result:=true;
+        end;
+    end;
+
+
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
     var
     var
       hp1,hp2: tai;
       hp1,hp2: tai;
@@ -472,6 +529,7 @@ Implementation
                         asml.remove(hp1);
                         asml.remove(hp1);
                         hp1.free;
                         hp1.free;
                       end;
                       end;
+                    LookForPostindexedPattern(taicpu(p));
                   end;
                   end;
                 A_LDR:
                 A_LDR:
                   begin
                   begin
@@ -534,6 +592,8 @@ Implementation
                             hp1.free;
                             hp1.free;
                           end;
                           end;
                       end;
                       end;
+
+                    LookForPostindexedPattern(taicpu(p));
                     { Remove superfluous mov after ldr
                     { Remove superfluous mov after ldr
                       changes
                       changes
                       ldr reg1, ref
                       ldr reg1, ref