Ver código fonte

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 -

florian 7 anos atrás
pai
commit
4f052e4f90
5 arquivos alterados com 34 adições e 15 exclusões
  1. 2 1
      compiler/ncal.pas
  2. 4 0
      compiler/ncgcal.pas
  3. 19 8
      compiler/ninl.pas
  4. 4 2
      compiler/riscv/cgrv.pas
  5. 5 4
      rtl/riscv64/riscv64.inc

+ 2 - 1
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;
 

+ 4 - 0
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

+ 19 - 8
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;
 

+ 4 - 2
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;
 
 

+ 5 - 4
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
 ****************************************************************************}