* use system.round() instead of LLVM's fptosui operation for converting a

floating point type to currency, as fptosui is defined as always rounding
    to zero while on other platforms we use the FPU's current rounding mode
    (fixes webtbs/tw21449 for LLVM, and also webtbs/tw24197 because LLVM's
     code generated for fptosui temporarily changes the FPU control word so
     it rounds to zero and also to disable FPU exceptions)

git-svn-id: trunk@35061 -
This commit is contained in:
Jonas Maebe 2016-12-04 11:15:22 +00:00
parent 8b1c90124e
commit f55d962e40

View File

@ -37,6 +37,7 @@ interface
function first_int_to_real: tnode; override;
function first_int_to_bool: tnode; override;
function first_nil_to_methodprocvar: tnode; override;
function first_real_to_real: tnode; override;
{ procedure second_int_to_int;override; }
{ procedure second_string_to_string;override; }
{ procedure second_cstring_to_pchar;override; }
@ -67,6 +68,7 @@ uses
aasmbase,aasmdata,
llvmbase,aasmllvm,
procinfo,
ncal,
symconst,symdef,defutil,
cgbase,cgutils,tgobj,hlcgobj,pass_2;
@ -114,6 +116,28 @@ function tllvmtypeconvnode.first_nil_to_methodprocvar: tnode;
end;
function tllvmtypeconvnode.first_real_to_real: tnode;
begin
result:=inherited;
if assigned(result) then
exit;
{ fptosui always uses round to zero, while we have to use the current
rounding mode when converting from another floating point type to
currency/comp to be compatible with the regular code generators ->
call round() instead }
if (tfloatdef(resultdef).floattype in [s64currency,s64comp]) and
not(tfloatdef(left.resultdef).floattype in [s64currency,s64comp]) then
begin
result:=ccallnode.createinternfromunit('SYSTEM','ROUND',
ccallparanode.create(left,nil));
left:=nil;
{ left was already been multiplied by 10000 by typecheck_real_to_real
-> ensure we don't do that again with the result of round }
result:=ctypeconvnode.create_internal(result,resultdef);
end;
end;
procedure tllvmtypeconvnode.second_pointer_to_array;
var
hreg: tregister;