From d3a1459cd4f2d4997fb53e34ddef72e91a7855c1 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 6 May 2020 23:01:32 +0200 Subject: 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. --- libgcc/ChangeLog | 10 +++++++++- libgcc/config/i386/sfp-exceptions.c | 22 +++++++++------------- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 8e63e43..33e8929 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,11 @@ +2020-05-06 Uroš Bizjak + + * 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. + 2020-05-06 Kyrylo Tkachov * config/aarch64/lse-init.c (init_have_lse_atomics): Use __getauxval @@ -54,7 +62,7 @@ 2020-05-01 Uroš Bizjak * config/i386/sfp-exceptions.c (__math_force_eval): New define. - (__sfp_handle_exceptions): Use __math_force_eval to evaluete + (__sfp_handle_exceptions): Use __math_force_eval to evaluate generic division to generate INVALID and DIVZERO exceptions. 2020-04-27 Sebastian Huber diff --git a/libgcc/config/i386/sfp-exceptions.c b/libgcc/config/i386/sfp-exceptions.c index 4b3a7a0..72cb0f4 100644 --- a/libgcc/config/i386/sfp-exceptions.c +++ b/libgcc/config/i386/sfp-exceptions.c @@ -42,22 +42,25 @@ 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 void __sfp_handle_exceptions (int _fex) { + struct fenv temp; + if (_fex & FP_EX_INVALID) { float f = 0.0f; - __math_force_eval (f / f); + __math_force_eval_div (f, f); } if (_fex & FP_EX_DENORM) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FP_EX_DENORM; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -66,11 +69,10 @@ __sfp_handle_exceptions (int _fex) if (_fex & FP_EX_DIVZERO) { float f = 1.0f, g = 0.0f; - __math_force_eval (f / g); + __math_force_eval_div (f, g); } if (_fex & FP_EX_OVERFLOW) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FP_EX_OVERFLOW; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -78,7 +80,6 @@ __sfp_handle_exceptions (int _fex) } if (_fex & FP_EX_UNDERFLOW) { - struct fenv temp; asm volatile ("fnstenv\t%0" : "=m" (temp)); temp.__status_word |= FP_EX_UNDERFLOW; asm volatile ("fldenv\t%0" : : "m" (temp)); @@ -87,12 +88,7 @@ __sfp_handle_exceptions (int _fex) if (_fex & FP_EX_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); } } #endif -- cgit v1.1