소스 검색

+ 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
           function pass_1 : tnode;override;
           function use_generic_mul32to64: boolean; override;
+          function use_generic_mul64bit: boolean; override;
        protected
           function first_addfloat: tnode; override;
           procedure second_addordinal;override;
@@ -505,20 +506,7 @@ interface
       var
         unsigned : boolean;
       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
           begin
@@ -672,6 +660,14 @@ interface
       begin
         result:=GenerateThumbCode or not(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]);
       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
   caddnode:=tarmaddnode;
 end.

+ 23 - 9
compiler/nadd.pas

@@ -67,6 +67,10 @@ interface
           { and resultdef of the muln s64bit or u64bit           }
           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
             for all floating point arithmetic in the case
             where the emulation switches is on. Otherwise
@@ -2518,6 +2522,12 @@ implementation
       end;
 
 
+    function taddnode.use_generic_mul64bit: boolean;
+      begin
+        result := true;
+      end;
+
+
     function taddnode.try_make_mul32to64: boolean;
 
       function canbe32bitint(v: tconstexprint): boolean;
@@ -2584,7 +2594,6 @@ implementation
         procname: string[31];
         temp: tnode;
         power: longint;
-        is_mul32to64: Boolean;
       begin
         result := nil;
         { create helper calls mul }
@@ -2613,15 +2622,12 @@ implementation
             exit;
           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
+            { 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
               handling in the i386 code generator }
             if is_signed(left.resultdef) and is_signed(right.resultdef) then
@@ -2644,6 +2650,14 @@ implementation
                 right.resultdef:=s64inttype;
               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 }
             right := ccallparanode.create(
               cordconstnode.create(ord(cs_check_overflow in current_settings.localswitches),pasbool8type,true),