[PATCH, fortran ieee]: Clear stalled interrupt flags in glibc set_fpu_trap_exceptions
Uros Bizjak
ubizjak@gmail.com
Tue Jan 29 19:46:00 GMT 2019
Hello!
When changing trap masks, it is necessary to clear pending traps to
prevent firing spurious interrupts. Attached patch also optimizes
set_fpu_trap_exceptions function considerably to only call
feenableexcept and fedisableexcept functions each once.
2019-01-29 Uroš Bizjak <ubizjak@gmail.com>
* config/fpu-glibc.h (set_fpu_trap_exceptions): Clear stalled
exception flags before changing trap mode. Optimize to call
feenableexcept and fedisableexcept only once.
Patch was bootstrapped and regression tested on alphaev68-linux-gnu,
where it fixes gfortran.dg/ieee/ieee_10.f90 failures.
OK for mainline?
Uros.
-------------- next part --------------
Index: config/fpu-glibc.h
===================================================================
--- config/fpu-glibc.h (revision 268248)
+++ config/fpu-glibc.h (working copy)
@@ -39,48 +39,56 @@
void set_fpu_trap_exceptions (int trap, int notrap)
{
+ int mode_set = 0, mode_clr = 0;
+
#ifdef FE_INVALID
if (trap & GFC_FPE_INVALID)
- feenableexcept (FE_INVALID);
+ mode_set |= FE_INVALID;
if (notrap & GFC_FPE_INVALID)
- fedisableexcept (FE_INVALID);
+ mode_clr |= FE_INVALID;
#endif
/* Some glibc targets (like alpha) have FE_DENORMAL, but not many. */
#ifdef FE_DENORMAL
if (trap & GFC_FPE_DENORMAL)
- feenableexcept (FE_DENORMAL);
+ mode_set |= FE_DENORMAL;
if (notrap & GFC_FPE_DENORMAL)
- fedisableexcept (FE_DENORMAL);
+ mode_clr |= FE_DENORMAL;
#endif
#ifdef FE_DIVBYZERO
if (trap & GFC_FPE_ZERO)
- feenableexcept (FE_DIVBYZERO);
+ mode_set |= FE_DIVBYZERO;
if (notrap & GFC_FPE_ZERO)
- fedisableexcept (FE_DIVBYZERO);
+ mode_clr |= FE_DIVBYZERO;
#endif
#ifdef FE_OVERFLOW
if (trap & GFC_FPE_OVERFLOW)
- feenableexcept (FE_OVERFLOW);
+ mode_set |= FE_OVERFLOW;
if (notrap & GFC_FPE_OVERFLOW)
- fedisableexcept (FE_OVERFLOW);
+ mode_clr |= FE_OVERFLOW;
#endif
#ifdef FE_UNDERFLOW
if (trap & GFC_FPE_UNDERFLOW)
- feenableexcept (FE_UNDERFLOW);
+ mode_set |= FE_UNDERFLOW;
if (notrap & GFC_FPE_UNDERFLOW)
- fedisableexcept (FE_UNDERFLOW);
+ mode_clr |= FE_UNDERFLOW;
#endif
#ifdef FE_INEXACT
if (trap & GFC_FPE_INEXACT)
- feenableexcept (FE_INEXACT);
+ mode_set |= FE_INEXACT;
if (notrap & GFC_FPE_INEXACT)
- fedisableexcept (FE_INEXACT);
+ mode_clr |= FE_INEXACT;
#endif
+
+ /* Clear stalled exception flags. */
+ feclearexcept (FE_ALL_EXCEPT);
+
+ feenableexcept (mode_set);
+ fedisableexcept (mode_clr);
}
More information about the Fortran
mailing list