浏览代码

* 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 -

florian 7 年之前
父节点
当前提交
71e71ad267
共有 5 个文件被更改,包括 29 次插入5 次删除
  1. 3 3
      compiler/arm/narmmat.pas
  2. 4 0
      compiler/nadd.pas
  3. 5 2
      compiler/nmat.pas
  4. 3 0
      rtl/inc/compproc.inc
  5. 14 0
      rtl/inc/int64.inc

+ 3 - 3
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

+ 4 - 0
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);

+ 5 - 2
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;

+ 3 - 0
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;

+ 14 - 0
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}
+