Sfoglia il codice sorgente

+ added different mul helpers for the 32 to 64-bit muls, since they can usually
be implemented more efficiently than the 64 to 64-bit ones.

git-svn-id: trunk@26386 -

nickysn 11 anni fa
parent
commit
c2ba9ebfe5
3 ha cambiato i file con 63 aggiunte e 20 eliminazioni
  1. 41 20
      compiler/nadd.pas
  2. 2 0
      rtl/inc/compproc.inc
  3. 20 0
      rtl/inc/int64.inc

+ 41 - 20
compiler/nadd.pas

@@ -2575,6 +2575,7 @@ 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 }
@@ -2603,31 +2604,51 @@ implementation
             exit;
             exit;
           end;
           end;
 
 
-        if not(use_generic_mul32to64) and
-           try_make_mul32to64 then
+        { 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;
           exit;
 
 
-        { when currency is used set the result of the
-          parameters to s64bit, so they are not converted }
-        if is_currency(resultdef) then
+        if is_mul32to64 then
           begin
           begin
-            left.resultdef:=s64inttype;
-            right.resultdef:=s64inttype;
-          end;
+            { 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
+              procname := 'fpc_mul_longint_to_int64'
+            else
+              procname := 'fpc_mul_dword_to_qword';
 
 
-        { otherwise, create the parameters for the helper }
-        right := ccallparanode.create(
-          cordconstnode.create(ord(cs_check_overflow in current_settings.localswitches),pasbool8type,true),
-          ccallparanode.create(right,ccallparanode.create(left,nil)));
-        left := nil;
-        { only qword needs the unsigned code, the
-          signed code is also used for currency }
-        if is_signed(resultdef) then
-          procname := 'fpc_mul_int64'
+            right := ccallparanode.create(right,ccallparanode.create(left,nil));
+            result := ccallnode.createintern(procname,right);
+            left := nil;
+            right := nil;
+          end
         else
         else
-          procname := 'fpc_mul_qword';
-        result := ccallnode.createintern(procname,right);
-        right := nil;
+          begin
+            { when currency is used set the result of the
+              parameters to s64bit, so they are not converted }
+            if is_currency(resultdef) then
+              begin
+                left.resultdef:=s64inttype;
+                right.resultdef:=s64inttype;
+              end;
+
+            { otherwise, create the parameters for the helper }
+            right := ccallparanode.create(
+              cordconstnode.create(ord(cs_check_overflow in current_settings.localswitches),pasbool8type,true),
+              ccallparanode.create(right,ccallparanode.create(left,nil)));
+            left := nil;
+            { only qword needs the unsigned code, the
+              signed code is also used for currency }
+            if is_signed(resultdef) then
+              procname := 'fpc_mul_int64'
+            else
+              procname := 'fpc_mul_qword';
+            result := ccallnode.createintern(procname,right);
+            right := nil;
+          end;
       end;
       end;
 
 
 
 

+ 2 - 0
rtl/inc/compproc.inc

@@ -535,6 +535,8 @@ function fpc_div_int64(n,z : int64) : int64; compilerproc;
 function fpc_mod_int64(n,z : int64) : int64; compilerproc;
 function fpc_mod_int64(n,z : int64) : int64; compilerproc;
 function fpc_mul_qword(f1,f2 : qword;checkoverflow : longbool) : qword; compilerproc;
 function fpc_mul_qword(f1,f2 : qword;checkoverflow : longbool) : qword; compilerproc;
 function fpc_mul_int64(f1,f2 : int64;checkoverflow : longbool) : int64; compilerproc;
 function fpc_mul_int64(f1,f2 : int64;checkoverflow : longbool) : int64; compilerproc;
+function fpc_mul_dword_to_qword(f1,f2 : dword) : qword; compilerproc;
+function fpc_mul_longint_to_int64(f1,f2 : longint) : int64; compilerproc;
 
 
 {$ifdef FPC_INCLUDE_SOFTWARE_SHIFT_INT64}
 {$ifdef FPC_INCLUDE_SOFTWARE_SHIFT_INT64}
 function fpc_shl_qword(value : qword; shift : sizeint) : qword; compilerproc;
 function fpc_shl_qword(value : qword; shift : sizeint) : qword; compilerproc;

+ 20 - 0
rtl/inc/int64.inc

@@ -292,6 +292,16 @@
 {$endif FPC_SYSTEM_HAS_MUL_QWORD}
 {$endif FPC_SYSTEM_HAS_MUL_QWORD}
 
 
 
 
+{$ifndef FPC_SYSTEM_HAS_MUL_DWORD_TO_QWORD}
+    function fpc_mul_qword_compilerproc(f1,f2 : qword;checkoverflow : longbool) : qword; external name 'FPC_MUL_QWORD';
+
+    function fpc_mul_dword_to_qword(f1,f2 : dword) : qword;[public,alias: 'FPC_MUL_DWORD_TO_QWORD']; compilerproc;
+      begin
+        fpc_mul_dword_to_qword:=fpc_mul_qword_compilerproc(f1,f2,false);
+      end;
+{$endif FPC_SYSTEM_HAS_MUL_DWORD_TO_QWORD}
+
+
 {$ifndef FPC_SYSTEM_HAS_MUL_INT64}
 {$ifndef FPC_SYSTEM_HAS_MUL_INT64}
     function fpc_mul_int64(f1,f2 : int64;checkoverflow : longbool) : int64;[public,alias: 'FPC_MUL_INT64']; compilerproc;
     function fpc_mul_int64(f1,f2 : int64;checkoverflow : longbool) : int64;[public,alias: 'FPC_MUL_INT64']; compilerproc;
 
 
@@ -336,3 +346,13 @@
       end;
       end;
 {$endif FPC_SYSTEM_HAS_MUL_INT64}
 {$endif FPC_SYSTEM_HAS_MUL_INT64}
 
 
+
+{$ifndef FPC_SYSTEM_HAS_MUL_LONGINT_TO_INT64}
+    function fpc_mul_int64_compilerproc(f1,f2 : int64;checkoverflow : longbool) : int64; external name 'FPC_MUL_INT64';
+
+    function fpc_mul_longint_to_int64(f1,f2 : longint) : int64;[public,alias: 'FPC_MUL_LONGINT_TO_INT64']; compilerproc;
+      begin
+        fpc_mul_longint_to_int64:=fpc_mul_int64_compilerproc(f1,f2,false);
+      end;
+{$endif FPC_SYSTEM_HAS_MUL_LONGINT_TO_INT64}
+