浏览代码

* the llvm.experimental.constrained.fpext intrinsic doesn't have a rounding
mode parameter

git-svn-id: trunk@43828 -

Jonas Maebe 5 年之前
父节点
当前提交
9b53ed53e3
共有 2 个文件被更改,包括 26 次插入15 次删除
  1. 20 9
      compiler/llvm/hlcgllvm.pas
  2. 6 6
      rtl/inc/llvmintr.inc

+ 20 - 9
compiler/llvm/hlcgllvm.pas

@@ -97,7 +97,7 @@ uses
       procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const ref: treference); override;
       procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tdef; reg1, reg2: tregister); override;
      protected
-      procedure gen_fpconstrained_intrinsic(list: TAsmList; const intrinsic: TIDString; fromsize, tosize: tdef; fromreg, toreg: tregister);
+      procedure gen_fpconstrained_intrinsic(list: TAsmList; const intrinsic: TIDString; fromsize, tosize: tdef; fromreg, toreg: tregister; roundingmode: boolean);
      public
 
       procedure gen_proc_symbol(list: TAsmList); override;
@@ -1339,38 +1339,49 @@ implementation
             intrinsic:='llvm_experimental_constrained_fpext';
           gen_fpconstrained_intrinsic(list,
             intrinsic+llvmfloatintrinsicsuffix(tfloatdef(tosize))+llvmfloatintrinsicsuffix(tfloatdef(fromsize)),
-            fromsize,tosize,reg1,reg2);
+            fromsize,tosize,reg1,reg2,op=la_fptrunc);
         end;
     end;
 
 
-  procedure thlcgllvm.gen_fpconstrained_intrinsic(list: TAsmList; const intrinsic: TIDString; fromsize, tosize: tdef; fromreg, toreg: tregister);
+  procedure thlcgllvm.gen_fpconstrained_intrinsic(list: TAsmList; const intrinsic: TIDString; fromsize, tosize: tdef; fromreg, toreg: tregister; roundingmode: boolean);
     var
       frompara, roundpara, exceptpara, respara: tcgpara;
       tmploc: tlocation;
       pd: tprocdef;
     begin
       frompara.init;
-      roundpara.init;
+      if roundingmode then
+        roundpara.init;
       exceptpara.init;
       pd:=search_system_proc(intrinsic);
 
       paramanager.getcgtempparaloc(list,pd,1,frompara);
-      paramanager.getcgtempparaloc(list,pd,2,roundpara);
-      paramanager.getcgtempparaloc(list,pd,3,exceptpara);
+      if roundingmode then
+        begin
+          paramanager.getcgtempparaloc(list,pd,2,roundpara);
+          paramanager.getcgtempparaloc(list,pd,3,exceptpara);
+        end
+      else
+        paramanager.getcgtempparaloc(list,pd,2,exceptpara);
 
       location_reset(tmploc,frompara.location^.loc,def_cgsize(fromsize));
       tmploc.register:=fromreg;
       gen_load_loc_cgpara(list,fromsize,tmploc,frompara);
-      a_load_reg_cgpara(list,llvm_metadatatype,tllvmmetadata.getstringreg('round.dynamic'),roundpara);
+      if roundingmode then
+        a_load_reg_cgpara(list,llvm_metadatatype,tllvmmetadata.getstringreg('round.dynamic'),roundpara);
       a_load_reg_cgpara(list,llvm_metadatatype,tllvmmetadata.getstringreg('fpexcept.strict'),exceptpara);
-      respara:=g_call_system_proc(list,pd,[@frompara,@roundpara,@exceptpara],nil);
+      if roundingmode then
+        respara:=g_call_system_proc(list,pd,[@frompara,@roundpara,@exceptpara],nil)
+      else
+        respara:=g_call_system_proc(list,pd,[@frompara,@exceptpara],nil);
 
       location_reset(tmploc,respara.location^.loc,def_cgsize(tosize));
       tmploc.register:=toreg;
       gen_load_cgpara_loc(list,tosize,respara,tmploc,false);
       frompara.done;
-      roundpara.done;
+      if roundingmode then
+        roundpara.done;
       exceptpara.done;
       respara.resetiftemp;
     end;

+ 6 - 6
rtl/inc/llvmintr.inc

@@ -88,20 +88,20 @@ function llvm_experimental_constrained_fdiv(a, b: float128; rounding, exceptions
 {$endif}
 
 function llvm_experimental_constrained_fptrunc_f32_f64(a: double; rounding, exceptions: LLVMMetadata): single; compilerproc; external name 'llvm.experimental.constrained.fptrunc.f32.f64';
-function llvm_experimental_constrained_fpext_f64_f32(a: single; rounding, exceptions: LLVMMetadata): double; compilerproc; external name 'llvm.experimental.constrained.fpext.f64.f32';
+function llvm_experimental_constrained_fpext_f64_f32(a: single; exceptions: LLVMMetadata): double; compilerproc; external name 'llvm.experimental.constrained.fpext.f64.f32';
 {$ifdef SUPPORT_EXTENDED}
 function llvm_experimental_constrained_fptrunc_f32_f80(a: extended; rounding, exceptions: LLVMMetadata): single; compilerproc; external name 'llvm.experimental.constrained.fptrunc.f32.x86_fp80';
 function llvm_experimental_constrained_fptrunc_f64_f80(a: extended; rounding, exceptions: LLVMMetadata): double; compilerproc; external name 'llvm.experimental.constrained.fptrunc.f64.x86_fp80';
-function llvm_experimental_constrained_fpext_f80_f32(a: single; rounding, exceptions: LLVMMetadata): extended; compilerproc; external name 'llvm.experimental.constrained.fpext.x86_fp80.f32';
-function llvm_experimental_constrained_fpext_f80_f64(a: double; rounding, exceptions: LLVMMetadata): extended; compilerproc; external name 'llvm.experimental.constrained.fpext.x86_fp80.f64';
+function llvm_experimental_constrained_fpext_f80_f32(a: single; exceptions: LLVMMetadata): extended; compilerproc; external name 'llvm.experimental.constrained.fpext.x86_fp80.f32';
+function llvm_experimental_constrained_fpext_f80_f64(a: double; exceptions: LLVMMetadata): extended; compilerproc; external name 'llvm.experimental.constrained.fpext.x86_fp80.f64';
 {$ifdef SUPPORT_FLOAT128}
 function llvm_experimental_constrained_fptrunc_f128_f80(a: extended; rounding, exceptions: LLVMMetadata): float128; compilerproc; external name 'llvm.experimental.constrained.fptrunc.f128.x86_fp80';
-function llvm_experimental_constrained_fpext_f80_f32(a: float128; rounding, exceptions: LLVMMetadata): extended; compilerproc; external name 'llvm.experimental.constrained.fpext.x86_fp80.f128';
+function llvm_experimental_constrained_fpext_f80_f32(a: float128; exceptions: LLVMMetadata): extended; compilerproc; external name 'llvm.experimental.constrained.fpext.x86_fp80.f128';
 {$endif}
 {$endif}
 {$ifdef SUPPORT_FLOAT128}
 function llvm_experimental_constrained_fptrunc_f32_f128(a: float128; rounding, exceptions: LLVMMetadata): single; compilerproc; external name 'llvm.experimental.constrained.fptrunc.f32.f128';
 function llvm_experimental_constrained_fptrunc_f64_f128(a: float128; rounding, exceptions: LLVMMetadata): double; compilerproc; external name 'llvm.experimental.constrained.fptrunc.f64.f128';
-function llvm_experimental_constrained_fpext_f128_f32(a: single; rounding, exceptions: LLVMMetadata): float128; compilerproc; external name 'llvm.experimental.constrained.fpext.f128.f32';
-function llvm_experimental_constrained_fpext_f128_f64(a: double; rounding, exceptions: LLVMMetadata): float128; compilerproc; external name 'llvm.experimental.constrained.fpext.f128.f64';
+function llvm_experimental_constrained_fpext_f128_f32(a: single; exceptions: LLVMMetadata): float128; compilerproc; external name 'llvm.experimental.constrained.fpext.f128.f32';
+function llvm_experimental_constrained_fpext_f128_f64(a: double; exceptions: LLVMMetadata): float128; compilerproc; external name 'llvm.experimental.constrained.fpext.f128.f64';
 {$endif}