Prechádzať zdrojové kódy

* factored out PrePeepholeOptSxx
+ x86-64 uses PrePeepholeOptSxx now as well

git-svn-id: trunk@36158 -

florian 8 rokov pred
rodič
commit
06c4c651fd

+ 3 - 61
compiler/i386/aoptcpu.pas

@@ -607,67 +607,9 @@ begin
                         end;
                         end;
                       end;
                       end;
                 end;
                 end;
-              A_SAR, A_SHR:
-                  {changes the code sequence
-                   shr/sar const1, x
-                   shl     const2, x
-                   to either "sar/and", "shl/and" or just "and" depending on const1 and const2}
-                begin
-                  if GetNextInstruction(p, hp1) and
-                     (tai(hp1).typ = ait_instruction) and
-                     (taicpu(hp1).opcode = A_SHL) and
-                     (taicpu(p).oper[0]^.typ = top_const) and
-                     (taicpu(hp1).oper[0]^.typ = top_const) and
-                     (taicpu(hp1).opsize = taicpu(p).opsize) and
-                     (taicpu(hp1).oper[1]^.typ = taicpu(p).oper[1]^.typ) and
-                     OpsEqual(taicpu(hp1).oper[1]^, taicpu(p).oper[1]^) then
-                    if (taicpu(p).oper[0]^.val > taicpu(hp1).oper[0]^.val) and
-                       not(cs_opt_size in current_settings.optimizerswitches) then
-                  { shr/sar const1, %reg
-                    shl     const2, %reg
-                    with const1 > const2 }
-                      begin
-                        taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
-                        taicpu(hp1).opcode := A_AND;
-                        l := (1 shl (taicpu(hp1).oper[0]^.val)) - 1;
-                        case taicpu(p).opsize Of
-                          S_L: taicpu(hp1).loadConst(0,l Xor aint($ffffffff));
-                          S_B: taicpu(hp1).loadConst(0,l Xor $ff);
-                          S_W: taicpu(hp1).loadConst(0,l Xor $ffff);
-                        end;
-                      end
-                    else if (taicpu(p).oper[0]^.val<taicpu(hp1).oper[0]^.val) and
-                            not(cs_opt_size in current_settings.optimizerswitches) then
-                  { shr/sar const1, %reg
-                    shl     const2, %reg
-                    with const1 < const2 }
-                      begin
-                        taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val-taicpu(p).oper[0]^.val);
-                        taicpu(p).opcode := A_AND;
-                        l := (1 shl (taicpu(p).oper[0]^.val))-1;
-                        case taicpu(p).opsize Of
-                          S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
-                          S_B: taicpu(p).loadConst(0,l Xor $ff);
-                          S_W: taicpu(p).loadConst(0,l Xor $ffff);
-                        end;
-                      end
-                    else
-                  { shr/sar const1, %reg
-                    shl     const2, %reg
-                    with const1 = const2 }
-                      if (taicpu(p).oper[0]^.val = taicpu(hp1).oper[0]^.val) then
-                        begin
-                          taicpu(p).opcode := A_AND;
-                          l := (1 shl (taicpu(p).oper[0]^.val))-1;
-                          case taicpu(p).opsize Of
-                            S_B: taicpu(p).loadConst(0,l Xor $ff);
-                            S_W: taicpu(p).loadConst(0,l Xor $ffff);
-                            S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
-                          end;
-                          asml.remove(hp1);
-                          hp1.free;
-                        end;
-                end;
+              A_SAR,A_SHR:
+                if PrePeepholeOptSxx(p) then
+                  continue;
               A_XOR:
               A_XOR:
                 if (taicpu(p).oper[0]^.typ = top_reg) and
                 if (taicpu(p).oper[0]^.typ = top_reg) and
                    (taicpu(p).oper[1]^.typ = top_reg) and
                    (taicpu(p).oper[1]^.typ = top_reg) and

+ 88 - 7
compiler/x86/aoptx86.pas

@@ -46,7 +46,14 @@ unit aoptx86;
           depend on the value in AH). }
           depend on the value in AH). }
         function Reg1ReadDependsOnReg2(reg1, reg2: tregister): boolean;
         function Reg1ReadDependsOnReg2(reg1, reg2: tregister): boolean;
 
 
-        procedure PostPeepholeOptMov(const p : tai);
+        procedure DebugMsg(const s : string; p : tai);inline;
+
+        procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
+        class function IsExitCode(p : tai) : boolean;
+        class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
+        procedure RemoveLastDeallocForFuncRes(p : tai);
+
+        function PrePeepholeOptSxx(var p : tai) : boolean;
 
 
         function OptPass1AND(var p : tai) : boolean;
         function OptPass1AND(var p : tai) : boolean;
         function OptPass1VMOVAP(var p : tai) : boolean;
         function OptPass1VMOVAP(var p : tai) : boolean;
@@ -58,12 +65,7 @@ unit aoptx86;
         function OptPass2Jmp(var p : tai) : boolean;
         function OptPass2Jmp(var p : tai) : boolean;
         function OptPass2Jcc(var p : tai) : boolean;
         function OptPass2Jcc(var p : tai) : boolean;
 
 
-        procedure DebugMsg(const s : string; p : tai);inline;
-
-        procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
-        class function IsExitCode(p : tai) : boolean;
-        class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
-        procedure RemoveLastDeallocForFuncRes(p : tai);
+        procedure PostPeepholeOptMov(const p : tai);
       end;
       end;
 
 
     function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
     function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
@@ -284,6 +286,85 @@ unit aoptx86;
       end;
       end;
 
 
 
 
+    function TX86AsmOptimizer.PrePeepholeOptSxx(var p : tai) : boolean;
+      var
+        hp1 : tai;
+        l : TCGInt;
+      begin
+        result:=false;
+        { changes the code sequence
+          shr/sar const1, x
+          shl     const2, x
+
+          to
+
+          either "sar/and", "shl/and" or just "and" depending on const1 and const2 }
+        if GetNextInstruction(p, hp1) and
+          MatchInstruction(hp1,A_SHL,[]) and
+          (taicpu(p).oper[0]^.typ = top_const) and
+          (taicpu(hp1).oper[0]^.typ = top_const) and
+          (taicpu(hp1).opsize = taicpu(p).opsize) and
+          (taicpu(hp1).oper[1]^.typ = taicpu(p).oper[1]^.typ) and
+          OpsEqual(taicpu(hp1).oper[1]^, taicpu(p).oper[1]^) then
+          begin
+            if (taicpu(p).oper[0]^.val > taicpu(hp1).oper[0]^.val) and
+              not(cs_opt_size in current_settings.optimizerswitches) then
+              begin
+                { shr/sar const1, %reg
+                  shl     const2, %reg
+                  with const1 > const2 }
+                taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
+                taicpu(hp1).opcode := A_AND;
+                l := (1 shl (taicpu(hp1).oper[0]^.val)) - 1;
+                case taicpu(p).opsize Of
+                  S_B: taicpu(hp1).loadConst(0,l Xor $ff);
+                  S_W: taicpu(hp1).loadConst(0,l Xor $ffff);
+                  S_L: taicpu(hp1).loadConst(0,l Xor aint($ffffffff));
+                  S_Q: taicpu(hp1).loadConst(0,l Xor aint($ffffffffffffffff));
+                  else
+                    Internalerror(2017050703)
+                end;
+              end
+            else if (taicpu(p).oper[0]^.val<taicpu(hp1).oper[0]^.val) and
+              not(cs_opt_size in current_settings.optimizerswitches) then
+              begin
+                { shr/sar const1, %reg
+                  shl     const2, %reg
+                  with const1 < const2 }
+                taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val-taicpu(p).oper[0]^.val);
+                taicpu(p).opcode := A_AND;
+                l := (1 shl (taicpu(p).oper[0]^.val))-1;
+                case taicpu(p).opsize Of
+                  S_B: taicpu(p).loadConst(0,l Xor $ff);
+                  S_W: taicpu(p).loadConst(0,l Xor $ffff);
+                  S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
+                  S_Q: taicpu(p).loadConst(0,l Xor aint($ffffffffffffffff));
+                  else
+                    Internalerror(2017050702)
+                end;
+              end
+            else if (taicpu(p).oper[0]^.val = taicpu(hp1).oper[0]^.val) then
+              begin
+                { shr/sar const1, %reg
+                  shl     const2, %reg
+                  with const1 = const2 }
+                taicpu(p).opcode := A_AND;
+                l := (1 shl (taicpu(p).oper[0]^.val))-1;
+                case taicpu(p).opsize Of
+                  S_B: taicpu(p).loadConst(0,l Xor $ff);
+                  S_W: taicpu(p).loadConst(0,l Xor $ffff);
+                  S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
+                  S_Q: taicpu(p).loadConst(0,l Xor aint($ffffffffffffffff));
+                  else
+                    Internalerror(2017050701)
+                end;
+                asml.remove(hp1);
+                hp1.free;
+              end;
+          end;
+      end;
+
+
     { allocates register reg between (and including) instructions p1 and p2
     { allocates register reg between (and including) instructions p1 and p2
       the type of p1 and p2 must not be in SkipInstr
       the type of p1 and p2 must not be in SkipInstr
       note that this routine is both called from the peephole optimizer
       note that this routine is both called from the peephole optimizer

+ 15 - 0
compiler/x86_64/aoptcpu.pas

@@ -31,6 +31,7 @@ uses cgbase, cpubase, aasmtai, aopt, aoptx86, aoptcpub;
 
 
 type
 type
   TCpuAsmOptimizer = class(TX86AsmOptimizer)
   TCpuAsmOptimizer = class(TX86AsmOptimizer)
+    function PrePeepHoleOptsCpu(var p: tai): boolean; override;
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
     function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
     function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
     function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
     function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
@@ -47,6 +48,20 @@ uses
   aasmbase, aasmdata, aasmcpu,
   aasmbase, aasmdata, aasmcpu,
   itcpugas;
   itcpugas;
 
 
+    function TCpuAsmOptimizer.PrePeepHoleOptsCpu(var p : tai) : boolean;
+      begin
+        result := false;
+        case p.typ of
+          ait_instruction:
+            begin
+              case taicpu(p).opcode of
+                A_SAR,A_SHR:
+                  result:=PrePeepholeOptSxx(p);
+              end;
+            end;
+        end;
+      end;
+
 function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
 function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
 var
 var
   hp1, hp2: tai;
   hp1, hp2: tai;