浏览代码

+ Added method taddnode.use_generic_mul64bit, allowing it to inline full 64-bit multiplications, and fixed ARM to comply (it was not checking for possible 32x32 to 64 optimization after detecting a 64-bit operand, so recently added code for 32x32 to 64 bit optimization was inactive).

git-svn-id: trunk@26500 -
sergei 11 年之前
父节点
当前提交
a3efd9e1df
共有 2 个文件被更改,包括 33 次插入23 次删除
  1. 10 14
      compiler/arm/narmadd.pas
  2. 23 9
      compiler/nadd.pas

+ 10 - 14
compiler/arm/narmadd.pas

@@ -35,6 +35,7 @@ interface
        public
        public
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function use_generic_mul32to64: boolean; override;
           function use_generic_mul32to64: boolean; override;
+          function use_generic_mul64bit: boolean; override;
        protected
        protected
           function first_addfloat: tnode; override;
           function first_addfloat: tnode; override;
           procedure second_addordinal;override;
           procedure second_addordinal;override;
@@ -505,20 +506,7 @@ interface
       var
       var
         unsigned : boolean;
         unsigned : boolean;
       begin
       begin
-        { prepare for MUL64 inlining }
-        if (not(cs_check_overflow in current_settings.localswitches)) and
-           (nodetype in [muln]) and
-           (is_64bitint(left.resultdef)) and
-           not(GenerateThumbCode) and
-           (CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) then
-          begin
-            result := nil;
-            firstpass(left);
-            firstpass(right);
-            expectloc := LOC_REGISTER;
-          end
-        else
-          result:=inherited pass_1;
+        result:=inherited pass_1;
 
 
         if not(assigned(result)) then
         if not(assigned(result)) then
           begin
           begin
@@ -672,6 +660,14 @@ interface
       begin
       begin
         result:=GenerateThumbCode or not(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]);
         result:=GenerateThumbCode or not(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]);
       end;
       end;
+
+    function tarmaddnode.use_generic_mul64bit: boolean;
+      begin
+        result:=GenerateThumbCode or
+          not(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) or
+          (cs_check_overflow in current_settings.localswitches);
+      end;
+
 begin
 begin
   caddnode:=tarmaddnode;
   caddnode:=tarmaddnode;
 end.
 end.

+ 23 - 9
compiler/nadd.pas

@@ -67,6 +67,10 @@ interface
           { and resultdef of the muln s64bit or u64bit           }
           { and resultdef of the muln s64bit or u64bit           }
           function use_generic_mul32to64: boolean; virtual;
           function use_generic_mul32to64: boolean; virtual;
 
 
+          { override and return false if code generator can handle }
+          { full 64 bit multiplies.                                }
+          function use_generic_mul64bit: boolean; virtual;
+
           { This routine calls internal runtime library helpers
           { This routine calls internal runtime library helpers
             for all floating point arithmetic in the case
             for all floating point arithmetic in the case
             where the emulation switches is on. Otherwise
             where the emulation switches is on. Otherwise
@@ -2518,6 +2522,12 @@ implementation
       end;
       end;
 
 
 
 
+    function taddnode.use_generic_mul64bit: boolean;
+      begin
+        result := true;
+      end;
+
+
     function taddnode.try_make_mul32to64: boolean;
     function taddnode.try_make_mul32to64: boolean;
 
 
       function canbe32bitint(v: tconstexprint): boolean;
       function canbe32bitint(v: tconstexprint): boolean;
@@ -2584,7 +2594,6 @@ implementation
         procname: string[31];
         procname: string[31];
         temp: tnode;
         temp: tnode;
         power: longint;
         power: longint;
-        is_mul32to64: Boolean;
       begin
       begin
         result := nil;
         result := nil;
         { create helper calls mul }
         { create helper calls mul }
@@ -2613,15 +2622,12 @@ implementation
             exit;
             exit;
           end;
           end;
 
 
-        { is it a 32 to 64-bit mul? }
-        is_mul32to64:=try_make_mul32to64;
-
-        { if the code generator can handle 32 to 64-bit muls, we're done here }
-        if not(use_generic_mul32to64) and is_mul32to64 then
-          exit;
-
-        if is_mul32to64 then
+        if try_make_mul32to64 then
           begin
           begin
+            { if the code generator can handle 32 to 64-bit muls, we're done here }
+            if not use_generic_mul32to64 then
+              exit;
+
             { this uses the same criteria for signedness as the 32 to 64-bit mul
             { this uses the same criteria for signedness as the 32 to 64-bit mul
               handling in the i386 code generator }
               handling in the i386 code generator }
             if is_signed(left.resultdef) and is_signed(right.resultdef) then
             if is_signed(left.resultdef) and is_signed(right.resultdef) then
@@ -2644,6 +2650,14 @@ implementation
                 right.resultdef:=s64inttype;
                 right.resultdef:=s64inttype;
               end;
               end;
 
 
+            { can full 64-bit multiplication be handled inline? }
+            if not use_generic_mul64bit then
+              begin
+                firstpass(left);
+                firstpass(right);
+                exit;
+              end;
+
             { otherwise, create the parameters for the helper }
             { otherwise, create the parameters for the helper }
             right := ccallparanode.create(
             right := ccallparanode.create(
               cordconstnode.create(ord(cs_check_overflow in current_settings.localswitches),pasbool8type,true),
               cordconstnode.create(ord(cs_check_overflow in current_settings.localswitches),pasbool8type,true),