Browse Source

* factored out TX86AsmOptimizer.OptPass2Imul

git-svn-id: trunk@35252 -
florian 8 years ago
parent
commit
f68558b88c
3 changed files with 49 additions and 24 deletions
  1. 2 23
      compiler/i386/aoptcpu.pas
  2. 45 1
      compiler/x86/aoptx86.pas
  3. 2 0
      compiler/x86_64/aoptcpu.pas

+ 2 - 23
compiler/i386/aoptcpu.pas

@@ -1853,29 +1853,8 @@ begin
                 if DoFpuLoadStoreOpt(p) then
                 if DoFpuLoadStoreOpt(p) then
                   continue;
                   continue;
               A_IMUL:
               A_IMUL:
-                begin
-                  if (taicpu(p).ops >= 2) and
-                     ((taicpu(p).oper[0]^.typ = top_const) or
-                      ((taicpu(p).oper[0]^.typ = top_ref) and (taicpu(p).oper[0]^.ref^.refaddr=addr_full))) and
-                     (taicpu(p).oper[1]^.typ = top_reg) and
-                     ((taicpu(p).ops = 2) or
-                      ((taicpu(p).oper[2]^.typ = top_reg) and
-                       (taicpu(p).oper[2]^.reg = taicpu(p).oper[1]^.reg))) and
-                     getLastInstruction(p,hp1) and
-                     (hp1.typ = ait_instruction) and
-                     (taicpu(hp1).opcode = A_MOV) and
-                     (taicpu(hp1).oper[0]^.typ = top_reg) and
-                     (taicpu(hp1).oper[1]^.typ = top_reg) and
-                     (taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) then
-              { change "mov reg1,reg2; imul y,reg2" to "imul y,reg1,reg2" }
-                    begin
-                      taicpu(p).ops := 3;
-                      taicpu(p).loadreg(1,taicpu(hp1).oper[0]^.reg);
-                      taicpu(p).loadreg(2,taicpu(hp1).oper[1]^.reg);
-                      asml.remove(hp1);
-                      hp1.free;
-                    end;
-                end;
+                if OptPass2Imul(p) then
+                  continue;
               A_JMP:
               A_JMP:
                 {
                 {
                   change
                   change

+ 45 - 1
compiler/x86/aoptx86.pas

@@ -46,6 +46,7 @@ unit aoptx86;
         function OptPass1MOV(var p : tai) : boolean;
         function OptPass1MOV(var p : tai) : boolean;
 
 
         function OptPass2MOV(var p : tai) : boolean;
         function OptPass2MOV(var p : tai) : boolean;
+        function OptPass2Imul(var p : tai) : boolean;
 
 
         procedure DebugMsg(const s : string; p : tai);inline;
         procedure DebugMsg(const s : string; p : tai);inline;
 
 
@@ -366,7 +367,11 @@ unit aoptx86;
             ((p.oper[0]^.typ = top_ref) and
             ((p.oper[0]^.typ = top_ref) and
              not RegInRef(reg,p.oper[0]^.ref^)))) or
              not RegInRef(reg,p.oper[0]^.ref^)))) or
           ((p.opcode = A_POP) and
           ((p.opcode = A_POP) and
-           (SuperRegistersEqual(p.oper[0]^.reg,reg)));
+           (SuperRegistersEqual(p.oper[0]^.reg,reg))) or
+          ((p.opcode = A_IMUL) and
+           (p.ops=3) and
+           (SuperRegistersEqual(p.oper[2]^.reg,reg)) and
+           not((SuperRegistersEqual(p.oper[1]^.reg,reg))));
       end;
       end;
 
 
 
 
@@ -1173,6 +1178,45 @@ unit aoptx86;
       end;
       end;
 
 
 
 
+    function TX86AsmOptimizer.OptPass2Imul(var p : tai) : boolean;
+      var
+        TmpUsedRegs : TAllUsedRegs;
+        hp1 : tai;
+        i : longint;
+      begin
+        Result:=false;
+        if (taicpu(p).ops >= 2) and
+           ((taicpu(p).oper[0]^.typ = top_const) or
+            ((taicpu(p).oper[0]^.typ = top_ref) and (taicpu(p).oper[0]^.ref^.refaddr=addr_full))) and
+           (taicpu(p).oper[1]^.typ = top_reg) and
+           ((taicpu(p).ops = 2) or
+            ((taicpu(p).oper[2]^.typ = top_reg) and
+             (taicpu(p).oper[2]^.reg = taicpu(p).oper[1]^.reg))) and
+           GetLastInstruction(p,hp1) and
+           MatchInstruction(hp1,A_MOV,[]) and
+           MatchOpType(hp1,top_reg,top_reg) and
+           ((taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) or
+            ((taicpu(hp1).opsize=S_L) and (taicpu(p).opsize=S_Q) and SuperRegistersEqual(taicpu(hp1).oper[1]^.reg,taicpu(p).oper[1]^.reg))) then
+          begin
+            CopyUsedRegs(TmpUsedRegs);
+            if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,p,TmpUsedRegs)) then
+              { change
+                  mov reg1,reg2
+                  imul y,reg2 to imul y,reg1,reg2 }
+              begin
+                taicpu(p).ops := 3;
+                taicpu(p).loadreg(1,taicpu(hp1).oper[0]^.reg);
+                taicpu(p).loadreg(2,taicpu(hp1).oper[1]^.reg);
+                DebugMsg('Peephole MovImul2Imul done',p);
+                asml.remove(hp1);
+                hp1.free;
+                result:=true;
+              end;
+            ReleaseUsedRegs(TmpUsedRegs);
+          end;
+      end;
+
+
     function TX86AsmOptimizer.OptPass1AND(var p : tai) : boolean;
     function TX86AsmOptimizer.OptPass1AND(var p : tai) : boolean;
       var
       var
         hp1 : tai;
         hp1 : tai;

+ 2 - 0
compiler/x86_64/aoptcpu.pas

@@ -355,6 +355,8 @@ end;
               case taicpu(p).opcode of
               case taicpu(p).opcode of
                 A_MOV:
                 A_MOV:
                   Result:=OptPass2MOV(p);
                   Result:=OptPass2MOV(p);
+                A_IMUL:
+                  Result:=OptPass2Imul(p);
               end;
               end;
             end;
             end;
         end;
         end;