From 71e71ad2678a2ec12c4c98a693b7e6d34f2a48cc Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 17 Mar 2018 22:44:44 +0000 Subject: [PATCH] * fix currency division on non x86 32 bit targets * disable fix for #33439 during bootstrapping with 3.0.x, as 3.0.x cannot compile the currency division without the fix above git-svn-id: trunk@38558 - --- compiler/arm/narmmat.pas | 6 +++--- compiler/nadd.pas | 4 ++++ compiler/nmat.pas | 7 +++++-- rtl/inc/compproc.inc | 3 +++ rtl/inc/int64.inc | 14 ++++++++++++++ 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/compiler/arm/narmmat.pas b/compiler/arm/narmmat.pas index 2939e403d7..a3e7bcc0f2 100644 --- a/compiler/arm/narmmat.pas +++ b/compiler/arm/narmmat.pas @@ -75,7 +75,7 @@ implementation if not(cs_check_overflow in current_settings.localswitches) and (right.nodetype=ordconstn) and (nodetype=divn) and - not(is_64bitint(resultdef)) and + not(is_64bit(resultdef)) and {Only the ARM and thumb2-isa support umull and smull, which are required for arbitary division by const optimization} (GenerateArmCode or GenerateThumb2Code or @@ -87,11 +87,11 @@ implementation result:=nil else if ((GenerateThumbCode or GenerateThumb2Code) and (CPUARM_HAS_THUMB_IDIV in cpu_capabilities[current_settings.cputype])) and (nodetype=divn) and - not(is_64bitint(resultdef)) then + not(is_64bit(resultdef)) then result:=nil else if ((GenerateThumbCode or GenerateThumb2Code) and (CPUARM_HAS_THUMB_IDIV in cpu_capabilities[current_settings.cputype])) and (nodetype=modn) and - not(is_64bitint(resultdef)) then + not(is_64bit(resultdef)) then begin if (right.nodetype=ordconstn) and ispowerof2(tordconstnode(right).value,power) and diff --git a/compiler/nadd.pas b/compiler/nadd.pas index 02dfa24415..948ff4ae45 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -2358,6 +2358,7 @@ implementation hp:=nil; if s64currencytype.typ=floatdef then begin +{$ifndef VER3_0} { if left is a currency integer constant, we can get rid of the factor 10000 } { int64(...) causes a cast on currency, so it is the currency value multiplied by 10000 } if (left.nodetype=realconstn) and (is_currency(left.resultdef)) and ((int64(trealconstnode(left).value_currency) mod 10000)=0) then @@ -2374,6 +2375,7 @@ implementation trealconstnode(right).value_real:=trealconstnode(right).value_real/10000; end else +{$endif VER3_0} begin hp:=caddnode.create(slashn,getcopy,crealconstnode.create(10000.0,s64currencytype)); include(hp.flags,nf_is_currency); @@ -2381,6 +2383,7 @@ implementation end else begin +{$ifndef VER3_0} { if left is a currency integer constant, we can get rid of the factor 10000 } if (left.nodetype=ordconstn) and (is_currency(left.resultdef)) and ((tordconstnode(left).value mod 10000)=0) then tordconstnode(left).value:=tordconstnode(left).value div 10000 @@ -2388,6 +2391,7 @@ implementation else if (right.nodetype=ordconstn) and (is_currency(right.resultdef)) and ((tordconstnode(right).value mod 10000)=0) then tordconstnode(right).value:=tordconstnode(right).value div 10000 else +{$endif VER3_0} begin hp:=cmoddivnode.create(divn,getcopy,cordconstnode.create(10000,s64currencytype,false)); include(hp.flags,nf_is_currency); diff --git a/compiler/nmat.pas b/compiler/nmat.pas index ab6939fb90..5b49adeb28 100644 --- a/compiler/nmat.pas +++ b/compiler/nmat.pas @@ -189,7 +189,8 @@ implementation result:= (left.resultdef.typ=orddef) and (right.resultdef.typ=orddef) and - (is_64bitint(left.resultdef) or is_64bitint(right.resultdef)); + { include currency as well } + (is_64bit(left.resultdef) or is_64bit(right.resultdef)); {$endif cpu64bitaly} end; @@ -429,7 +430,9 @@ implementation u32bit: procname := procname + 'dword'; s32bit: - procname := procname + 'longint' + procname := procname + 'longint'; + scurrency: + procname := procname + 'currency'; else internalerror(2015070501); end; diff --git a/rtl/inc/compproc.inc b/rtl/inc/compproc.inc index b8cbe3bfba..3d7a5a5f49 100644 --- a/rtl/inc/compproc.inc +++ b/rtl/inc/compproc.inc @@ -633,6 +633,9 @@ function fpc_mul_int64_checkoverflow(f1,f2 : int64) : int64; compilerproc; function fpc_mul_dword_to_qword(f1,f2 : dword) : qword; compilerproc; function fpc_mul_longint_to_int64(f1,f2 : longint) : int64; compilerproc; +function fpc_div_currency(n,z : currency) : currency; compilerproc; +function fpc_mod_currency(n,z : currency) : currency; compilerproc; + {$ifdef FPC_INCLUDE_SOFTWARE_SHIFT_INT64} function fpc_shl_qword(value : qword; shift : sizeint) : qword; compilerproc; function fpc_shr_qword(value : qword; shift : sizeint) : qword; compilerproc; diff --git a/rtl/inc/int64.inc b/rtl/inc/int64.inc index d40b4e32b6..87fd335a0c 100644 --- a/rtl/inc/int64.inc +++ b/rtl/inc/int64.inc @@ -585,3 +585,17 @@ {$endif FPC_SYSTEM_HAS_MUL_LONGINT_TO_INT64} +{$ifndef FPC_SYSTEM_HAS_DIV_CURRENCY} +function fpc_div_currency(n,z : currency) : currency; [public,alias: 'FPC_DIV_CURRENCY']; compilerproc; + begin + Result:=(int64(z)*10000) div int64(n); + end; +{$endif FPC_SYSTEM_HAS_DIV_CURRENCY} + +{$ifndef FPC_SYSTEM_HAS_MOD_CURRENCY} +function fpc_mod_currency(n,z : currency) : currency; [public,alias: 'FPC_MOD_CURRENCY']; compilerproc; + begin + Result:=int64(z) mod int64(n); + end; +{$endif FPC_SYSTEM_HAS_MOD_CURRENCY} +