|
@@ -64,11 +64,11 @@ interface
|
|
|
implementation
|
|
|
|
|
|
uses
|
|
|
- globtype,globals,verbose,
|
|
|
+ globtype,globals,cutils,verbose,
|
|
|
aasmbase,aasmdata,
|
|
|
- llvmbase,aasmllvm,
|
|
|
+ llvmbase,llvminfo,aasmllvm,aasmllvmmetadata,llvmdef,
|
|
|
procinfo,
|
|
|
- ncal,
|
|
|
+ ncal,ncon,
|
|
|
symconst,symdef,defutil,
|
|
|
cgbase,cgutils,tgobj,hlcgobj,pass_2;
|
|
|
|
|
@@ -104,9 +104,37 @@ class function tllvmtypeconvnode.target_specific_need_equal_typeconv(fromdef, to
|
|
|
|
|
|
|
|
|
function tllvmtypeconvnode.first_int_to_real: tnode;
|
|
|
+{$push}{$j+}
|
|
|
+ const
|
|
|
+ intrinfix: array[boolean] of string[7] =
|
|
|
+ ('uitofp','sitofp');
|
|
|
+{$pop}
|
|
|
+ var
|
|
|
+ exceptmode: ansistring;
|
|
|
begin
|
|
|
- expectloc:=LOC_FPUREGISTER;
|
|
|
- result:=nil;
|
|
|
+ if (llvmflag_constrained_fptoi_itofp in llvmversion_properties[current_settings.llvmversion]) and
|
|
|
+ { these are converted to 80 bits first in any case }
|
|
|
+ not(tfloatdef(resultdef).floattype in [s64currency,s64comp]) and
|
|
|
+ ((left.resultdef.size>=resultdef.size) or
|
|
|
+ ((torddef(left.resultdef).ordtype=u64bit) and
|
|
|
+ (tfloatdef(resultdef).floattype=s80real))) then
|
|
|
+ begin
|
|
|
+ { in case rounding may have to be applied, use the intrinsic }
|
|
|
+ exceptmode:=llvm_constrainedexceptmodestring;
|
|
|
+ result:=ccallnode.createintern('llvm_experimental_constrained_'+intrinfix[is_signed(left.resultdef)]+llvmfloatintrinsicsuffix(tfloatdef(resultdef))+'_i'+tostr(left.resultdef.size*8),
|
|
|
+ ccallparanode.create(cstringconstnode.createpchar(ansistring2pchar(exceptmode),length(exceptmode),llvm_metadatatype),
|
|
|
+ ccallparanode.create(cstringconstnode.createpchar(ansistring2pchar('round.dynamic'),length('round.dynamic'),llvm_metadatatype),
|
|
|
+ ccallparanode.create(left,nil)
|
|
|
+ )
|
|
|
+ )
|
|
|
+ );
|
|
|
+ left:=nil;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ expectloc:=LOC_FPUREGISTER;
|
|
|
+ result:=nil;
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
|