diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2020-05-06 23:01:32 +0200 |
---|---|---|
committer | Uros Bizjak <ubizjak@gmail.com> | 2020-05-06 23:01:32 +0200 |
commit | d3a1459cd4f2d4997fb53e34ddef72e91a7855c1 (patch) | |
tree | 7a23bc1474d3f382a9b8e6044e53e5ee7b335347 /libatomic/config | |
parent | bc95e478febd35e0d1fb13c1833d2383ad0e7d18 (diff) | |
download | gcc-d3a1459cd4f2d4997fb53e34ddef72e91a7855c1.zip gcc-d3a1459cd4f2d4997fb53e34ddef72e91a7855c1.tar.gz gcc-d3a1459cd4f2d4997fb53e34ddef72e91a7855c1.tar.bz2 |
i386: Use generic division to generate INEXACT exception
Introduce math_force_eval_div to use generic division to generate
INEXACT as well as INVALID and DIVZERO exceptions.
libgcc/ChangeLog:
* config/i386/sfp-exceptions.c (__math_force_eval): Remove.
(__math_force_eval_div): New define.
(__sfp_handle_exceptions): Use __math_force_eval_div to use
generic division to generate INVALID, DIVZERO and INEXACT
exceptions.
libatomic/ChangeLog:
* config/x86/fenv.c (__math_force_eval): Remove.
(__math_force_eval_div): New define.
(__atomic_deraiseexcept): Use __math_force_eval_div to use
generic division to generate INVALID, DIVZERO and INEXACT
exceptions.
libgfortran/ChangeLog:
* config/fpu-387.h (__math_force_eval): Remove.
(__math_force_eval_div): New define.
(local_feraiseexcept): Use __math_force_eval_div to use
generic division to generate INVALID, DIVZERO and INEXACT
exceptions.
(struct fenv): Define named struct instead of typedef.
Diffstat (limited to 'libatomic/config')
-rw-r--r-- | libatomic/config/x86/fenv.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/libatomic/config/x86/fenv.c b/libatomic/config/x86/fenv.c index d972a99..88622c6 100644 --- a/libatomic/config/x86/fenv.c +++ b/libatomic/config/x86/fenv.c @@ -48,9 +48,11 @@ struct fenv }; #ifdef __SSE_MATH__ -# define __math_force_eval(x) asm volatile ("" : : "x" (x)); +# define __math_force_eval_div(x, y) \ + do { asm ("" : "+x" (x)); asm volatile ("" : : "x" (x / y)); } while (0) #else -# define __math_force_eval(x) asm volatile ("" : : "f" (x)); +# define __math_force_eval_div(x, y) \ + do { asm ("" : "+t" (x)); asm volatile ("" : : "f" (x / y)); } while (0) #endif /* Raise the supported floating-point exceptions from EXCEPTS. Other @@ -59,14 +61,15 @@ struct fenv void __atomic_feraiseexcept (int excepts) { + struct fenv temp; + if (excepts & FE_INVALID) { float f = 0.0f; - __math_force_eval (f / f); + __math_force_eval_div (f, f); } if (excepts & FE_DENORM) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FE_DENORM; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -75,11 +78,10 @@ __atomic_feraiseexcept (int excepts) if (excepts & FE_DIVBYZERO) { float f = 1.0f, g = 0.0f; - __math_force_eval (f / g); + __math_force_eval_div (f, g); } if (excepts & FE_OVERFLOW) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FE_OVERFLOW; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -87,7 +89,6 @@ __atomic_feraiseexcept (int excepts) } if (excepts & FE_UNDERFLOW) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FE_UNDERFLOW; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -96,11 +97,6 @@ __atomic_feraiseexcept (int excepts) if (excepts & FE_INEXACT) { float f = 1.0f, g = 3.0f; -#ifdef __SSE_MATH__ - asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g)); -#else - asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + __math_force_eval_div (f, g); } } |