Bladeren bron

m68k: add more cases, where TST instructions can beoptimized away, because the previous instruction already sets all the required flags

Karoly Balogh 1 jaar geleden
bovenliggende
commit
020ca55e25
1 gewijzigde bestanden met toevoegingen van 35 en 8 verwijderingen
  1. 35 8
      compiler/m68k/aoptcpu.pas

+ 35 - 8
compiler/m68k/aoptcpu.pas

@@ -38,10 +38,12 @@ unit aoptcpu;
         function RegLoadedWithNewValue(reg: tregister; hp: tai): boolean; override;
         function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
 
+        function TryToRemoveTST(var p: tai): boolean;
         function TryToOptimizeMove(var p: tai): boolean;
         function MaybeRealConstOperSimplify(var p: tai): boolean;
         function OptPass1LEA(var p: tai): Boolean;
         function OptPass1MOVEM(var p: tai): Boolean;
+        function OptPass1Bitwise(var p: tai): Boolean;
 
         { outputs a debug message into the assembler file }
         procedure DebugMsg(const s: string; p: tai);
@@ -217,28 +219,41 @@ unit aoptcpu;
     end;
 {$endif DEBUG_AOPTCPU}
 
-  function TCpuAsmOptimizer.TryToOptimizeMove(var p: tai): boolean;
+  function TCpuAsmOptimizer.TryToRemoveTST(var p: tai): boolean;
     var
       next, next2: tai;
       opstr: string[15];
     begin
       result:=false;
 
-      if (taicpu(p).opcode=A_MOVE) and
+      if not((taicpu(p).oper[1]^.typ=top_reg) and isaddressregister(taicpu(p).oper[1]^.reg)) and
         GetNextInstruction(p,next) and
         MatchInstruction(next,A_TST,[taicpu(p).opsize]) and
         MatchOperand(taicpu(p).oper[1]^,taicpu(next).oper[0]^) and
-        { for movea, it won't work }
-        not((taicpu(p).oper[1]^.typ=top_reg) and isaddressregister(taicpu(p).oper[1]^.reg)) and
         GetNextInstruction(next,next2) and
         MatchInstruction(next2,[A_BXX,A_SXX],[S_NO]) and
         (taicpu(next2).condition in [C_NE,C_EQ,C_PL,C_MI]) then
         begin
-          DebugMsg('Optimizer: MOVE, TST, Jxx/Sxx to MOVE, Jxx',p);
+          opstr:=opname(p);
+          DebugMsg('Optimizer: '+opstr+', TST, Jxx/Sxx to '+opstr+', Jxx/Sxx',p);
           asml.remove(next);
           next.free;
           result:=true;
-          exit;
+        end;
+    end;
+
+  function TCpuAsmOptimizer.TryToOptimizeMove(var p: tai): boolean;
+    var
+      next, next2: tai;
+      opstr: string[15];
+    begin
+      result:=false;
+
+      if (taicpu(p).opcode=A_MOVE) then
+        begin
+          result:=TryToRemoveTST(p);
+          if result then
+            exit;
         end;
       if GetNextInstruction(p,next) and
          (next.typ = ait_instruction) and
@@ -426,6 +441,11 @@ unit aoptcpu;
         end;
     end;
 
+  function TCpuAsmOptimizer.OptPass1Bitwise(var p: tai): Boolean;
+    begin
+      Result:=TryToRemoveTST(p);
+    end;
+
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
     var
       next: tai;
@@ -443,7 +463,10 @@ unit aoptcpu;
               A_MOVEM:
                 result:=OptPass1MOVEM(p);
               A_LEA:
-                Result:=OptPass1LEA(p);
+                result:=OptPass1LEA(p);
+              { Bitwise operations }
+              A_AND,A_OR,A_EOR:
+                result:=OptPass1Bitwise(p);
               { Address register sub/add can be replaced with ADDQ/SUBQ or LEA if the value is in the
                 SmallInt range, which is shorter to encode and faster to execute on most 68k }
               A_SUB,A_SUBA,A_ADD,A_ADDA:
@@ -473,7 +496,11 @@ unit aoptcpu;
                           taicpu(p).loadref(0,tmpref);
                           result:=true;
                         end;
-                  end;
+                  end
+                else
+                  result:=TryToRemoveTST(p);
+              A_SUBQ,A_ADDQ:
+                result:=TryToRemoveTST(p);
               { MOVEA #0,Ax to SUBA Ax,Ax, because it's shorter }
               A_MOVEA:
                 if (taicpu(p).oper[0]^.typ = top_const) and