Browse Source

Use GetExceptionMask/SetExceptionMask to avoid floating point exception inside FPC_SOFT_FFPUX80 code

Pierre Muller 2 years ago
parent
commit
b53034705f
1 changed files with 9 additions and 1 deletions
  1. 9 1
      compiler/entfile.pas

+ 9 - 1
compiler/entfile.pas

@@ -344,7 +344,7 @@ implementation
   uses
 {$ifndef FPC_HAS_TYPE_EXTENDED}
 {$ifdef FPC_SOFT_FPUX80}
-    sfpux80,
+    sfpux80,math,
 {$endif FPC_SOFT_FPUX80}
 {$endif ndef FPC_HAS_TYPE_EXTENDED}
     cutils;
@@ -1244,6 +1244,7 @@ var
 {$ifdef FPC_SOFT_FPUX80}
   floatx80_ba : floatx80_byte_array;
   floatx80_e: floatx80;
+  ExMask : TFPUExceptionMask;
   high : word;
   qlow : qword;
   f64 : float64;
@@ -1279,8 +1280,11 @@ begin
       floatx80_e.high:=pword(@floatx80_ba[8])^;
       floatx80_e.low:=pqword(@floatx80_ba[0])^;
 {$endif}
+      ExMask:=GetExceptionMask;
+      SetExceptionMask([exInvalidOp,exDenormalized,exZeroDivide,exOverflow,exUnderflow,exPrecision]);
       f64:=floatx80_to_float64(floatx80_e);
       result:=pentryreal(@f64)^;
+      SetExceptionMask(ExMask);
       inc(entryidx,sizeof(floatx80_ba));
 {$ifdef DEBUG_PPU}
       ppu_log_val(realtostr(result));
@@ -1893,6 +1897,7 @@ var
   floatx80_ba : floatx80_byte_array;
   floatx80_e : floatx80;
   f64 : float64;
+  ExMask : TFPUExceptionMask;
   i:byte;
 {$endif FPC_SOFT_FFPUX80}
 {$endif ndef FPC_HAS_TYPE_EXTENDED}
@@ -1915,8 +1920,11 @@ begin
       ppu_log('putreal,size='+tostr(sizeof(floatx80_e)));
       inc_log_level;
 {$endif}
+      ExMask:=GetExceptionMask;
+      SetExceptionMask([exDenormalized,exZeroDivide,exOverflow,exUnderflow,exPrecision]);
       f64:=float64(d);
       floatx80_e:=float64_to_floatx80(f64);
+      SetExceptionMask(ExMask);
 {$ifdef FPC_BIG_ENDIAN}
       pword(@floatx80_ba[0])^:=floatx80_e.high;
       pqword(@floatx80_ba[8])^:=floatx80_e.low;