Forráskód Böngészése

* arm cond. instruction support

git-svn-id: trunk@5387 -
florian 18 éve
szülő
commit
4010d66c2c
3 módosított fájl, 162 hozzáadás és 2 törlés
  1. 1 1
      compiler/aopt.pas
  2. 1 1
      compiler/aoptobj.pas
  3. 160 0
      compiler/arm/aoptcpu.pas

+ 1 - 1
compiler/aopt.pas

@@ -229,7 +229,7 @@ Unit aopt;
       {          CSE;}
               End;
             { more peephole optimizations }
-      {      PeepHoleOptPass2;}
+            PeepHoleOptPass2;
             { if pass = last_pass then }
             PostPeepHoleOpts;
             { free memory }

+ 1 - 1
compiler/aoptobj.pas

@@ -288,7 +288,7 @@ Unit AoptObj;
         { peephole optimizer }
         procedure PrePeepHoleOpts;
         procedure PeepHoleOptPass1;
-        procedure PeepHoleOptPass2;
+        procedure PeepHoleOptPass2; virtual;
         procedure PostPeepHoleOpts;
 
         { processor dependent methods }

+ 160 - 0
compiler/arm/aoptcpu.pas

@@ -33,10 +33,170 @@ uses cpubase, aopt, aoptcpub;
 Type
   TCpuAsmOptimizer = class(TAsmOptimizer)
     { uses the same constructor as TAopObj }
+    procedure PeepHoleOptPass2;override;
   End;
 
 Implementation
 
+  uses
+    aasmbase,aasmtai,aasmcpu;
+
+  function CanBeCond(p : tai) : boolean;
+    begin
+      result:=true;
+    end;
+
+  procedure TCpuAsmOptimizer.PeepHoleOptPass2;
+    var
+      p,hp1,hp2: tai;
+      l : longint;
+      condition : tasmcond;
+      hp3: tai;
+      { UsedRegs, TmpUsedRegs: TRegSet; }
+
+    begin
+      exit; { deactived, not working yet FK }
+      p := BlockStart;
+      { UsedRegs := []; }
+      while (p <> BlockEnd) Do
+        begin
+          { UpdateUsedRegs(UsedRegs, tai(p.next)); }
+          case p.Typ Of
+            Ait_Instruction:
+              begin
+                case taicpu(p).opcode Of
+                  A_B:
+                    if taicpu(p).condition<>C_None then
+                      begin
+                         { check for
+                                Bxx   xxx
+                                <several instructions>
+                             xxx:
+                         }
+                         l:=0;
+                         GetNextInstruction(p, hp1);
+                         while assigned(hp1) and
+                           (l<=4) and
+                           CanBeCond(hp1) and
+                           { stop on labels }
+                           not(hp1.typ=ait_label) do
+                           begin
+                              inc(l);
+                              GetNextInstruction(hp1,hp1);
+                           end;
+                         if assigned(hp1) then
+                           begin
+                              if FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol),hp1) then
+                                begin
+                                  if (l<=4) and (l>0) then
+                                    begin
+                                      condition:=inverse_cond(taicpu(p).condition);
+                                      hp2:=p;
+                                      GetNextInstruction(p,hp1);
+                                      p:=hp1;
+                                      repeat
+                                        if hp1.typ=ait_instruction then
+                                          taicpu(hp1).condition:=condition;
+                                        GetNextInstruction(hp1,hp1);
+                                      until not(assigned(hp1)) or
+                                        not(CanBeCond(hp1)) or
+                                        (hp1.typ=ait_label);
+                                      { wait with removing else GetNextInstruction could
+                                        ignore the label if it was the only usage in the
+                                        jump moved away }
+                                      tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol).decrefs;
+                                      asml.remove(hp2);
+                                      hp2.free;
+                                      continue;
+                                    end;
+                                end
+                              else
+                                begin
+                                   { check further for
+                                          Bcc   xxx
+                                          <several movs 1>
+                                          B   yyy
+                                  xxx:
+                                          <several movs 2>
+                                  yyy:
+                                   }
+                                  { hp2 points to jmp yyy }
+                                  hp2:=hp1;
+                                  { skip hp1 to xxx }
+                                  GetNextInstruction(hp1, hp1);
+                                  if assigned(hp2) and
+                                    assigned(hp1) and
+                                    (l<=3) and
+                                    (hp2.typ=ait_instruction) and
+                                    (taicpu(hp2).is_jmp) and
+                                    (taicpu(hp2).condition=C_None) and
+                                    { real label and jump, no further references to the
+                                      label are allowed }
+                                    (tasmlabel(taicpu(p).oper[0]^.ref^.symbol).getrefs=2) and
+                                    FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol),hp1) then
+                                     begin
+                                       l:=0;
+                                       { skip hp1 to <several moves 2> }
+                                       GetNextInstruction(hp1, hp1);
+                                       while assigned(hp1) and
+                                         CanBeCond(hp1) do
+                                         begin
+                                           inc(l);
+                                           GetNextInstruction(hp1, hp1);
+                                         end;
+                                       { hp1 points to yyy: }
+                                       if assigned(hp1) and
+                                         FindLabel(tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol),hp1) then
+                                         begin
+                                            condition:=inverse_cond(taicpu(p).condition);
+                                            GetNextInstruction(p,hp1);
+                                            hp3:=p;
+                                            p:=hp1;
+                                            repeat
+                                              if hp1.typ=ait_instruction then
+                                                taicpu(hp1).condition:=condition;
+                                              GetNextInstruction(hp1,hp1);
+                                            until not(assigned(hp1)) or
+                                              not(CanBeCond(hp1));
+                                            { hp2 is still at jmp yyy }
+                                            GetNextInstruction(hp2,hp1);
+                                            { hp2 is now at xxx: }
+                                            condition:=inverse_cond(condition);
+                                            GetNextInstruction(hp1,hp1);
+                                            { hp1 is now at <several movs 2> }
+                                            repeat
+                                              taicpu(hp1).condition:=condition;
+                                              GetNextInstruction(hp1,hp1);
+                                            until not(assigned(hp1)) or
+                                              not(CanBeCond(hp1)) or
+                                              (hp1.typ=ait_label);
+                                            {
+                                            asml.remove(hp1.next)
+                                            hp1.next.free;
+                                            asml.remove(hp1);
+                                            hp1.free;
+                                            }
+                                            { remove Bcc }
+                                            tasmlabel(taicpu(hp3).oper[0]^.ref^.symbol).decrefs;
+                                            asml.remove(hp3);
+                                            hp3.free;
+                                            { remove jmp }
+                                            tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol).decrefs;
+                                            asml.remove(hp2);
+                                            hp2.free;
+                                            continue;
+                                         end;
+                                     end;
+                                end;
+                           end;
+                      end;
+                end;
+              end;
+          end;
+          p := tai(p.next)
+        end;
+    end;
+
 begin
   casmoptimizer:=TCpuAsmOptimizer;
 End.