summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-08-19 15:26:00 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-08-19 15:26:00 +0000
commit7700a23409089e824dfa17f35313e21bc4a706ef (patch)
tree5b3daab74866a8a5130acc11df21f93d4d4ea1f8
parent790674f80c91c18ebbcd6946fdd1c8c58ce34cec (diff)
downloadfpc-7700a23409089e824dfa17f35313e21bc4a706ef.tar.gz
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: https://svn.freepascal.org/svn/fpc/branches/laksen@39645 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--riscv_new/compiler/ncal.pas3
-rw-r--r--riscv_new/compiler/ncgcal.pas4
-rw-r--r--riscv_new/compiler/ninl.pas27
-rw-r--r--riscv_new/compiler/riscv/cgrv.pas6
-rw-r--r--riscv_new/rtl/riscv64/riscv64.inc9
5 files changed, 34 insertions, 15 deletions
diff --git a/riscv_new/compiler/ncal.pas b/riscv_new/compiler/ncal.pas
index 0984293d8b..81e505866f 100644
--- a/riscv_new/compiler/ncal.pas
+++ b/riscv_new/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/riscv_new/compiler/ncgcal.pas b/riscv_new/compiler/ncgcal.pas
index 490f2934ab..be9705da5f 100644
--- a/riscv_new/compiler/ncgcal.pas
+++ b/riscv_new/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/riscv_new/compiler/ninl.pas b/riscv_new/compiler/ninl.pas
index 7f4b1323a1..d771ea0adc 100644
--- a/riscv_new/compiler/ninl.pas
+++ b/riscv_new/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/riscv_new/compiler/riscv/cgrv.pas b/riscv_new/compiler/riscv/cgrv.pas
index 0d5075f987..0cbfd753c0 100644
--- a/riscv_new/compiler/riscv/cgrv.pas
+++ b/riscv_new/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/riscv_new/rtl/riscv64/riscv64.inc b/riscv_new/rtl/riscv64/riscv64.inc
index cac65a5b85..964c6babf6 100644
--- a/riscv_new/rtl/riscv64/riscv64.inc
+++ b/riscv_new/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
****************************************************************************}