瀏覽代碼

+ use cpurox define in the compiler for CPUs having internal ror/rol support
+ optimize (i shl x) or (i shr (bitsizeof(i)-x)) and friends into rol/ror(x,i)

git-svn-id: trunk@19635 -

florian 13 年之前
父節點
當前提交
c12a4989d0
共有 3 個文件被更改,包括 77 次插入3 次删除
  1. 5 0
      compiler/fpcdefs.inc
  2. 71 2
      compiler/nadd.pas
  3. 1 1
      compiler/options.pas

+ 5 - 0
compiler/fpcdefs.inc

@@ -59,6 +59,7 @@
   {$define SUPPORT_MMX}
   {$define SUPPORT_MMX}
   {$define cpumm}
   {$define cpumm}
   {$define fewintregisters}
   {$define fewintregisters}
+  {$define cpurox}
 {$endif i386}
 {$endif i386}
 
 
 {$ifdef x86_64}
 {$ifdef x86_64}
@@ -70,6 +71,7 @@
   {$define cpufloat128}
   {$define cpufloat128}
   {$define cputargethasfixedstack}
   {$define cputargethasfixedstack}
   {$define cpumm}
   {$define cpumm}
+  {$define cpurox}
 {$endif x86_64}
 {$endif x86_64}
 
 
 {$ifdef alpha}
 {$ifdef alpha}
@@ -92,6 +94,7 @@
   {$define cpuflags}
   {$define cpuflags}
   {$define cputargethasfixedstack}
   {$define cputargethasfixedstack}
   {$define cpumm}
   {$define cpumm}
+  {$define cpurox}
 {$endif powerpc}
 {$endif powerpc}
 
 
 {$ifdef powerpc64}
 {$ifdef powerpc64}
@@ -100,6 +103,7 @@
   {$define cpuflags}
   {$define cpuflags}
   {$define cputargethasfixedstack}
   {$define cputargethasfixedstack}
   {$define cpumm}
   {$define cpumm}
+  {$define cpurox}
 {$endif powerpc64}
 {$endif powerpc64}
 
 
 {$ifdef arm}
 {$ifdef arm}
@@ -109,6 +113,7 @@
   {$define cpuflags}
   {$define cpuflags}
   {$define cpufpemu}
   {$define cpufpemu}
   {$define cpuneedsdiv32helper}
   {$define cpuneedsdiv32helper}
+  {$define cpurox}
   {$define cputargethasfixedstack}
   {$define cputargethasfixedstack}
   { default to armel }
   { default to armel }
   {$if not(defined(CPUARM)) and not(defined(CPUARMEB)) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEB))}
   {$if not(defined(CPUARM)) and not(defined(CPUARMEB)) and not(defined(FPC_OARM)) and not(defined(FPC_ARMEB))}

+ 71 - 2
compiler/nadd.pas

@@ -861,7 +861,7 @@ implementation
               memory accesses while sqr(<real>) has no drawback }
               memory accesses while sqr(<real>) has no drawback }
             if
             if
 {$ifdef cpufpemu}
 {$ifdef cpufpemu}
-               (current_settings.fputype<>fpu_soft) and 
+               (current_settings.fputype<>fpu_soft) and
                not(cs_fp_emulation in current_settings.moduleswitches) and
                not(cs_fp_emulation in current_settings.moduleswitches) and
 {$endif cpufpemu}
 {$endif cpufpemu}
                (nodetype=muln) and
                (nodetype=muln) and
@@ -873,6 +873,75 @@ implementation
                 left:=nil;
                 left:=nil;
                 exit;
                 exit;
               end;
               end;
+{$ifdef cpurox}
+            { optimize (i shl x) or (i shr (bitsizeof(i)-x)) into rol(x,i) (and different flavours with shl/shr swapped etc.) }
+            if (nodetype=orn)
+{$ifndef cpu64bitalu}
+               and (left.resultdef.typ=orddef) and
+               not(torddef(left.resultdef).ordtype in [s64bit,u64bit,scurrency])
+{$endif cpu64bitalu}
+              then
+              begin
+                if (left.nodetype=shrn) and (right.nodetype=shln) and
+                   is_constintnode(tshlshrnode(left).right) and
+                   is_constintnode(tshlshrnode(right).right) and
+                   (tordconstnode(tshlshrnode(right).right).value>0) and
+                   (tordconstnode(tshlshrnode(left).right).value>0) and
+                   tshlshrnode(left).left.isequal(tshlshrnode(right).left) and
+                   not(might_have_sideeffects(tshlshrnode(left).left)) then
+                   begin
+                     if tordconstnode(tshlshrnode(left).right).value=
+                       tshlshrnode(left).left.resultdef.size*8-tordconstnode(tshlshrnode(right).right).value then
+                       begin
+                         result:=cinlinenode.create(in_ror_x_y,false,
+                           ccallparanode.create(tshlshrnode(left).right,
+                           ccallparanode.create(tshlshrnode(left).left,nil)));
+                         tshlshrnode(left).left:=nil;
+                         tshlshrnode(left).right:=nil;
+                         exit;
+                       end
+                     else if tordconstnode(tshlshrnode(right).right).value=
+                       tshlshrnode(left).left.resultdef.size*8-tordconstnode(tshlshrnode(left).right).value then
+                       begin
+                         result:=cinlinenode.create(in_rol_x_y,false,
+                           ccallparanode.create(tshlshrnode(right).right,
+                           ccallparanode.create(tshlshrnode(left).left,nil)));
+                         tshlshrnode(left).left:=nil;
+                         tshlshrnode(right).right:=nil;
+                         exit;
+                       end;
+                   end;
+                if (left.nodetype=shln) and (right.nodetype=shrn) and
+                   is_constintnode(tshlshrnode(left).right) and
+                   is_constintnode(tshlshrnode(right).right) and
+                   (tordconstnode(tshlshrnode(right).right).value>0) and
+                   (tordconstnode(tshlshrnode(left).right).value>0) and
+                   tshlshrnode(left).left.isequal(tshlshrnode(right).left) and
+                   not(might_have_sideeffects(tshlshrnode(left).left)) then
+                   begin
+                     if tordconstnode(tshlshrnode(left).right).value=
+                       tshlshrnode(left).left.resultdef.size*8-tordconstnode(tshlshrnode(right).right).value then
+                       begin
+                         result:=cinlinenode.create(in_rol_x_y,false,
+                           ccallparanode.create(tshlshrnode(left).right,
+                           ccallparanode.create(tshlshrnode(left).left,nil)));
+                         tshlshrnode(left).left:=nil;
+                         tshlshrnode(left).right:=nil;
+                         exit;
+                       end
+                     else if tordconstnode(tshlshrnode(right).right).value=
+                       tshlshrnode(left).left.resultdef.size*8-tordconstnode(tshlshrnode(left).right).value then
+                       begin
+                         result:=cinlinenode.create(in_ror_x_y,false,
+                           ccallparanode.create(tshlshrnode(right).right,
+                           ccallparanode.create(tshlshrnode(left).left,nil)));
+                         tshlshrnode(left).left:=nil;
+                         tshlshrnode(right).right:=nil;
+                         exit;
+                       end;
+                   end;
+              end;
+{$endif cpurox}
           end;
           end;
       end;
       end;
 
 
@@ -1963,7 +2032,7 @@ implementation
                     if is_shortstring(left.resultdef) then
                     if is_shortstring(left.resultdef) then
                       resultdef:=cshortstringtype
                       resultdef:=cshortstringtype
                     else
                     else
-                    { for ansistrings set resultdef to assignment left node 
+                    { for ansistrings set resultdef to assignment left node
                       if it is an assignment and left node expects ansistring }
                       if it is an assignment and left node expects ansistring }
                     if is_ansistring(left.resultdef) and
                     if is_ansistring(left.resultdef) and
                        assigned(aktassignmentnode) and
                        assigned(aktassignmentnode) and

+ 1 - 1
compiler/options.pas

@@ -2509,7 +2509,7 @@ begin
   def_system_macro('FPC_HAS_RESSTRINITS');
   def_system_macro('FPC_HAS_RESSTRINITS');
 
 
 { these cpus have an inline rol/ror implementaion }
 { these cpus have an inline rol/ror implementaion }
-{$if defined(x86) or defined(arm) or defined(powerpc) or defined(powerpc64)}
+{$ifdef cpurox}
   def_system_macro('FPC_HAS_INTERNAL_ROX');
   def_system_macro('FPC_HAS_INTERNAL_ROX');
 {$endif}
 {$endif}