Browse Source

+ AndShlToShl optimization
* moved topsize2memsize to cpubase

git-svn-id: trunk@38343 -

florian 7 years ago
parent
commit
fc6c0e8ef4
3 changed files with 52 additions and 28 deletions
  1. 25 0
      compiler/x86/aoptx86.pas
  2. 27 0
      compiler/x86/cpubase.pas
  3. 0 28
      compiler/x86/rax86.pas

+ 25 - 0
compiler/x86/aoptx86.pas

@@ -2812,6 +2812,7 @@ unit aoptx86;
       var
       var
         hp1 : tai;
         hp1 : tai;
         RegName1, RegName2: string;
         RegName1, RegName2: string;
+        MaskLength : Cardinal;
       begin
       begin
         Result:=false;
         Result:=false;
 
 
@@ -2876,6 +2877,30 @@ unit aoptx86;
                     hp1.free;
                     hp1.free;
                   end;
                   end;
               end
               end
+        else if MatchOpType(taicpu(p),top_const,top_reg) and
+          MatchInstruction(hp1,A_SHL,[]) and
+          MatchOpType(taicpu(hp1),top_const,top_reg) and
+          (getsupreg(taicpu(p).oper[1]^.reg)=getsupreg(taicpu(hp1).oper[1]^.reg)) then
+          begin
+            { get length of potential and mask }
+            MaskLength:=SizeOf(taicpu(p).oper[0]^.val)*8-BsrQWord(taicpu(p).oper[0]^.val)-1;
+
+            { really a mask? }
+            if (((QWord(1) shl MaskLength)-1)=taicpu(p).oper[0]^.val) and
+              { unmasked part shifted out? }
+              ((MaskLength+taicpu(hp1).oper[0]^.val)>=topsize2memsize[taicpu(hp1).opsize]) then
+              begin
+                DebugMsg(SPeepholeOptimization + 'AndShlToShl done',p);
+
+                { take care of the register (de)allocs following p }
+                UpdateUsedRegs(tai(p.next));
+                asml.remove(p);
+                p.free;
+                p:=hp1;
+                Result:=true;
+                exit;
+              end;
+          end
         else if MatchOpType(taicpu(p),top_const,top_reg) and
         else if MatchOpType(taicpu(p),top_const,top_reg) and
           MatchInstruction(hp1,A_MOVSX{$ifdef x86_64},A_MOVSXD{$endif x86_64},[]) and
           MatchInstruction(hp1,A_MOVSX{$ifdef x86_64},A_MOVSXD{$endif x86_64},[]) and
           (taicpu(hp1).oper[0]^.typ = top_reg) and
           (taicpu(hp1).oper[0]^.typ = top_reg) and

+ 27 - 0
compiler/x86/cpubase.pas

@@ -293,6 +293,33 @@ uses
 
 
     {$i cpubase.inc}
     {$i cpubase.inc}
 
 
+const
+{$ifdef x86_64}
+  topsize2memsize: array[topsize] of integer =
+    (0, 8,16,32,64,8,8,16,8,16,32,
+     16,32,64,
+     16,32,64,0,0,
+     64,
+     0,0,0,
+     80,
+     128,
+     256,
+     512
+    );
+{$else}
+topsize2memsize: array[topsize] of integer =
+  (0, 8,16,32,64,8,8,16,
+   16,32,64,
+   16,32,64,0,0,
+   64,
+   0,0,0,
+   80,
+   128,
+   256,
+   512
+  );
+{$endif}
+
 {*****************************************************************************
 {*****************************************************************************
                                   Helpers
                                   Helpers
 *****************************************************************************}
 *****************************************************************************}

+ 0 - 28
compiler/x86/rax86.pas

@@ -332,34 +332,6 @@ begin
   Opsize:=S_NO;
   Opsize:=S_NO;
 end;
 end;
 
 
-
-const
-{$ifdef x86_64}
-  topsize2memsize: array[topsize] of integer =
-    (0, 8,16,32,64,8,8,16,8,16,32,
-     16,32,64,
-     16,32,64,0,0,
-     64,
-     0,0,0,
-     80,
-     128,
-     256,
-     512
-    );
-{$else}
-topsize2memsize: array[topsize] of integer =
-  (0, 8,16,32,64,8,8,16,
-   16,32,64,
-   16,32,64,0,0,
-   64,
-   0,0,0,
-   80,
-   128,
-   256,
-   512
-  );
-{$endif}
-
 procedure Tx86Instruction.AddReferenceSizes;
 procedure Tx86Instruction.AddReferenceSizes;
 { this will add the sizes for references like [esi] which do not
 { this will add the sizes for references like [esi] which do not
   have the size set yet, it will take only the size if the other
   have the size set yet, it will take only the size if the other