diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 0984293d8b..81e505866f 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -56,7 +56,8 @@ interface cnf_call_never_returns, { information for the dfa that a subroutine never returns } cnf_call_self_node_done,{ the call_self_node has been generated if necessary (to prevent it from potentially happening again in a wrong context in case of constant propagation or so) } - cnf_ignore_visibility { internally generated call that should ignore visibility checks } + cnf_ignore_visibility, { internally generated call that should ignore visibility checks } + cnf_check_fpu_exceptions { after the call fpu exceptions shall be checked } ); tcallnodeflags = set of tcallnodeflag; diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index 490f2934ab..be9705da5f 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -1272,6 +1272,10 @@ implementation { release temps of paras } release_para_temps; + { check for fpu exceptions } + if cnf_check_fpu_exceptions in callnodeflags then + cg.g_check_for_fpu_exception(current_asmdata.CurrAsmList); + { perhaps i/o check ? } if (cs_check_io in current_settings.localswitches) and (po_iocheck in procdefinition.procoptions) and diff --git a/compiler/ninl.pas b/compiler/ninl.pas index 7f4b1323a1..d771ea0adc 100644 --- a/compiler/ninl.pas +++ b/compiler/ninl.pas @@ -4019,7 +4019,7 @@ implementation begin { create the call to the helper } { on entry left node contains the parameter } - first_arctan_real := ccallnode.createintern('fpc_arctan_real', + result := ccallnode.createintern('fpc_arctan_real', ccallparanode.create(left,nil)); left := nil; end; @@ -4028,8 +4028,9 @@ implementation begin { create the call to the helper } { on entry left node contains the parameter } - first_abs_real := ctypeconvnode.create(ccallnode.createintern('fpc_abs_real', + result := ctypeconvnode.create(ccallnode.createintern('fpc_abs_real', ccallparanode.create(left,nil)),resultdef); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4042,8 +4043,9 @@ implementation {$endif cpufpemu} { create the call to the helper } { on entry left node contains the parameter } - first_sqr_real := ctypeconvnode.create(ccallnode.createintern('fpc_sqr_real', + result := ctypeconvnode.create(ccallnode.createintern('fpc_sqr_real', ccallparanode.create(left,nil)),resultdef); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4075,15 +4077,16 @@ implementation else internalerror(2014052101); end; - first_sqrt_real:=ctypeconvnode.create_internal(ccallnode.createintern(procname,ccallparanode.create( + result:=ctypeconvnode.create_internal(ccallnode.createintern(procname,ccallparanode.create( ctypeconvnode.create_internal(left,fdef),nil)),resultdef); end else begin { create the call to the helper } { on entry left node contains the parameter } - first_sqrt_real := ctypeconvnode.create(ccallnode.createintern('fpc_sqrt_real', + result := ctypeconvnode.create(ccallnode.createintern('fpc_sqrt_real', ccallparanode.create(left,nil)),resultdef); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); end; left := nil; end; @@ -4092,8 +4095,9 @@ implementation begin { create the call to the helper } { on entry left node contains the parameter } - first_ln_real := ccallnode.createintern('fpc_ln_real', + result := ccallnode.createintern('fpc_ln_real', ccallparanode.create(left,nil)); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4101,8 +4105,9 @@ implementation begin { create the call to the helper } { on entry left node contains the parameter } - first_cos_real := ccallnode.createintern('fpc_cos_real', + result := ccallnode.createintern('fpc_cos_real', ccallparanode.create(left,nil)); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4110,8 +4115,9 @@ implementation begin { create the call to the helper } { on entry left node contains the parameter } - first_sin_real := ccallnode.createintern('fpc_sin_real', + result := ccallnode.createintern('fpc_sin_real', ccallparanode.create(left,nil)); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4120,6 +4126,7 @@ implementation { create the call to the helper } { on entry left node contains the parameter } result := ccallnode.createintern('fpc_exp_real',ccallparanode.create(left,nil)); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4128,6 +4135,7 @@ implementation { create the call to the helper } { on entry left node contains the parameter } result := ccallnode.createintern('fpc_int_real',ccallparanode.create(left,nil)); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4136,6 +4144,7 @@ implementation { create the call to the helper } { on entry left node contains the parameter } result := ccallnode.createintern('fpc_frac_real',ccallparanode.create(left,nil)); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4144,6 +4153,7 @@ implementation { create the call to the helper } { on entry left node contains the parameter } result := ccallnode.createintern('fpc_round_real',ccallparanode.create(left,nil)); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; @@ -4152,6 +4162,7 @@ implementation { create the call to the helper } { on entry left node contains the parameter } result := ccallnode.createintern('fpc_trunc_real',ccallparanode.create(left,nil)); + include(tcallnode(result).callnodeflags,cnf_check_fpu_exceptions); left := nil; end; diff --git a/compiler/riscv/cgrv.pas b/compiler/riscv/cgrv.pas index 0d5075f987..0cbfd753c0 100644 --- a/compiler/riscv/cgrv.pas +++ b/compiler/riscv/cgrv.pas @@ -545,7 +545,10 @@ unit cgrv; begin if fromsize<>tosize then - list.concat(taicpu.op_reg_reg(convOp[fromsize,tosize],reg2,reg1)) + begin + list.concat(taicpu.op_reg_reg(convOp[fromsize,tosize],reg2,reg1)); + g_check_for_fpu_exception(list); + end else begin if tosize=OS_F32 then @@ -557,7 +560,6 @@ unit cgrv; list.concat(ai); rg[R_FPUREGISTER].add_move_instruction(ai); end; - g_check_for_fpu_exception(list); end; diff --git a/rtl/riscv64/riscv64.inc b/rtl/riscv64/riscv64.inc index cac65a5b85..964c6babf6 100644 --- a/rtl/riscv64/riscv64.inc +++ b/rtl/riscv64/riscv64.inc @@ -15,10 +15,6 @@ **********************************************************************} -procedure fpc_cpuinit;{$ifdef SYSTEMINLINE}inline;{$endif} - begin - end; - {**************************************************************************** fpu exception related stuff ****************************************************************************} @@ -86,6 +82,11 @@ procedure fpc_throwfpuexception;[public,alias:'FPC_THROWFPUEXCEPTION']; end; +procedure fpc_cpuinit;{$ifdef SYSTEMINLINE}inline;{$endif} + begin + softfloat_exception_mask:=[exPrecision,exUnderflow]; + end; + {**************************************************************************** stack frame related stuff ****************************************************************************}