Browse Source

* arm/a64: Added new TST post-peephole optimisation to replace previous AND/CMP/B(c) optimisation

J. Gareth "Curious Kit" Moreton 1 year ago
parent
commit
bf29f2051c
1 changed files with 43 additions and 0 deletions
  1. 43 0
      compiler/aarch64/aoptcpu.pas

+ 43 - 0
compiler/aarch64/aoptcpu.pas

@@ -67,6 +67,7 @@ Interface
 
         function PostPeepholeOptAND(var p: tai): Boolean;
         function PostPeepholeOptCMP(var p: tai): boolean;
+        function PostPeepholeOptTST(var p: tai): Boolean;
       End;
 
 Implementation
@@ -1169,6 +1170,46 @@ Implementation
     end;
 
 
+  function TCpuAsmOptimizer.PostPeepholeOptTST(var p : tai): boolean;
+    var
+      hp1: tai;
+      hp3: taicpu;
+      bitval : cardinal;
+    begin
+      Result:=false;
+      {
+        tst reg1,<const=power of 2>
+        b.e/b.ne label
+
+        into
+
+        tb(n)z reg0,<power of 2>,label
+      }
+      if MatchOpType(taicpu(p),top_reg,top_const) and
+        (PopCnt(QWord(taicpu(p).oper[1]^.val))=1) and
+        GetNextInstruction(p,hp1) and
+        MatchInstruction(hp1,A_B,[C_EQ,C_NE],[PF_None]) then
+        begin
+           bitval:=BsfQWord(qword(taicpu(p).oper[1]^.val));
+           case taicpu(hp1).condition of
+            C_NE:
+              hp3:=taicpu.op_reg_const_ref(A_TBNZ,taicpu(p).oper[0]^.reg,bitval,taicpu(hp1).oper[0]^.ref^);
+            C_EQ:
+              hp3:=taicpu.op_reg_const_ref(A_TBZ,taicpu(p).oper[0]^.reg,bitval,taicpu(hp1).oper[0]^.ref^);
+            else
+              Internalerror(2021100210);
+          end;
+          taicpu(hp3).fileinfo:=taicpu(p).fileinfo;
+          asml.insertafter(hp3, p);
+
+          RemoveInstruction(hp1);
+          RemoveCurrentP(p, hp3);
+          DebugMsg(SPeepholeOptimization + 'TST; B(E/NE) -> TB(Z/NZ) done', p);
+          Result:=true;
+        end;
+    end;
+
+
   function TCpuAsmOptimizer.PrePeepHoleOptsCpu(var p: tai): boolean;
     begin
       result := false;
@@ -1285,6 +1326,8 @@ Implementation
               Result:=PostPeepholeOptCMP(p);
             A_AND:
               Result:=PostPeepholeOptAND(p);
+            A_TST:
+              Result:=PostPeepholeOptTST(p);
             else
               ;
           end;