+ 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 -
This commit is contained in:
nickysn 2014-01-05 03:01:18 +00:00
parent 5aacd4a118
commit c2ba9ebfe5
3 changed files with 63 additions and 20 deletions

View File

@ -2575,6 +2575,7 @@ implementation
procname: string[31];
temp: tnode;
power: longint;
is_mul32to64: Boolean;
begin
result := nil;
{ create helper calls mul }
@ -2603,31 +2604,51 @@ implementation
exit;
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;
{ 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
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
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;

View File

@ -535,6 +535,8 @@ function fpc_div_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_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}
function fpc_shl_qword(value : qword; shift : sizeint) : qword; compilerproc;

View File

@ -292,6 +292,16 @@
{$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}
function fpc_mul_int64(f1,f2 : int64;checkoverflow : longbool) : int64;[public,alias: 'FPC_MUL_INT64']; compilerproc;
@ -336,3 +346,13 @@
end;
{$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}