o fix several issues with floating point exceptions

+ mask underflow and precision on startup
  + check for floating point exceptions after inlined float routine helpers
  - do not check for floating point exceptions after floating point moves 

git-svn-id: branches/laksen/riscv_new@39645 -
This commit is contained in:
florian 2018-08-19 15:26:00 +00:00
parent 6b9f52b4f2
commit 4f052e4f90
5 changed files with 34 additions and 15 deletions

View File

@ -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;

View File

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

View File

@ -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;

View File

@ -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;

View File

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