From afb9b7108104a73e8ac7a9b8e6875870e5ca4bbb Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Fri, 1 May 2020 19:20:57 +0200 Subject: [PATCH] i386: Use generic division to generate INVALID and DIVZERO exceptions Introduce math_force_eval to evaluate generic division to generate INVALID and DIVZERO exceptions. libgcc/ChangeLog: * config/i386/sfp-exceptions.c (__math_force_eval): New define. (__sfp_handle_exceptions): Use __math_force_eval to evaluete generic division to generate INVALID and DIVZERO exceptions. libatomic/ChangeLog: * config/x86/fenv.c (__math_force_eval): New define. (__atomic_feraiseexcept): Use __math_force_eval to evaluete generic division to generate INVALID and DIVZERO exceptions. libgfortran/ChangeLog: * config/fpu-387.h (__math_force_eval): New define. (local_feraiseexcept): Use __math_force_eval to evaluete generic division to generate INVALID and DIVZERO exceptions. --- libatomic/ChangeLog | 6 ++++++ libatomic/config/x86/fenv.c | 20 ++++++++------------ libgcc/ChangeLog | 6 ++++++ libgcc/config/i386/sfp-exceptions.c | 20 ++++++++------------ libgfortran/ChangeLog | 6 ++++++ libgfortran/config/fpu-387.h | 19 +++++++------------ 6 files changed, 41 insertions(+), 36 deletions(-) diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog index 33527a7b456..48c115de49f 100644 --- a/libatomic/ChangeLog +++ b/libatomic/ChangeLog @@ -1,3 +1,9 @@ +2020-05-01 Uroš Bizjak + + * config/x86/fenv.c (__math_force_eval): New define. + (__atomic_feraiseexcept): Use __math_force_eval to evaluete + generic division to generate INVALID and DIVZERO exceptions. + 2020-04-19 Uroš Bizjak * config/x86/fenv.c (__atomic_feraiseexcept) [__SSE_MATH__]: diff --git a/libatomic/config/x86/fenv.c b/libatomic/config/x86/fenv.c index d7b1bbe5ea1..d972a99f594 100644 --- a/libatomic/config/x86/fenv.c +++ b/libatomic/config/x86/fenv.c @@ -47,6 +47,12 @@ struct fenv unsigned short int __unused5; }; +#ifdef __SSE_MATH__ +# define __math_force_eval(x) asm volatile ("" : : "x" (x)); +#else +# define __math_force_eval(x) asm volatile ("" : : "f" (x)); +#endif + /* Raise the supported floating-point exceptions from EXCEPTS. Other bits in EXCEPTS are ignored. */ @@ -56,12 +62,7 @@ __atomic_feraiseexcept (int excepts) if (excepts & FE_INVALID) { float f = 0.0f; -#ifdef __SSE_MATH__ - asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f)); -#else - asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + __math_force_eval (f / f); } if (excepts & FE_DENORM) { @@ -74,12 +75,7 @@ __atomic_feraiseexcept (int excepts) if (excepts & FE_DIVBYZERO) { float f = 1.0f, g = 0.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 (f / g); } if (excepts & FE_OVERFLOW) { diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 7dbab3ef499..02b36d3a380 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2020-05-01 Uroš Bizjak + + * config/i386/sfp-exceptions.c (__math_force_eval): New define. + (__sfp_handle_exceptions): Use __math_force_eval to evaluete + generic division to generate INVALID and DIVZERO exceptions. + 2020-04-27 Sebastian Huber * config/rs6000/crtresfpr.S: Use .machine ppc. diff --git a/libgcc/config/i386/sfp-exceptions.c b/libgcc/config/i386/sfp-exceptions.c index 31a24ced704..4b3a7a08da1 100644 --- a/libgcc/config/i386/sfp-exceptions.c +++ b/libgcc/config/i386/sfp-exceptions.c @@ -41,18 +41,19 @@ struct fenv unsigned short int __unused5; }; +#ifdef __SSE_MATH__ +# define __math_force_eval(x) asm volatile ("" : : "x" (x)); +#else +# define __math_force_eval(x) asm volatile ("" : : "f" (x)); +#endif + void __sfp_handle_exceptions (int _fex) { if (_fex & FP_EX_INVALID) { float f = 0.0f; -#ifdef __SSE_MATH__ - asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f)); -#else - asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + __math_force_eval (f / f); } if (_fex & FP_EX_DENORM) { @@ -65,12 +66,7 @@ __sfp_handle_exceptions (int _fex) if (_fex & FP_EX_DIVZERO) { float f = 1.0f, g = 0.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 (f / g); } if (_fex & FP_EX_OVERFLOW) { diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 8e3e087818d..eecfb904f55 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,9 @@ +2020-05-01 Uroš Bizjak + + * config/fpu-387.h (__math_force_eval): New define. + (local_feraiseexcept): Use __math_force_eval to evaluete + generic division to generate INVALID and DIVZERO exceptions. + 2020-04-22 Fritz Reese * intrinsics/trigd.c, intrinsics/trigd_lib.inc, intrinsics/trigd.inc: diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h index 13be2045b72..41b82bc8098 100644 --- a/libgfortran/config/fpu-387.h +++ b/libgfortran/config/fpu-387.h @@ -91,6 +91,11 @@ my_fenv_t; _Static_assert (sizeof(my_fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE, "GFC_FPE_STATE_BUFFER_SIZE is too small"); +#ifdef __SSE_MATH__ +# define __math_force_eval(x) __asm__ __volatile__ ("" : : "x" (x)); +#else +# define __math_force_eval(x) __asm__ __volatile__ ("" : : "f" (x)); +#endif /* Raise the supported floating-point exceptions from EXCEPTS. Other bits in EXCEPTS are ignored. Code originally borrowed from @@ -102,12 +107,7 @@ local_feraiseexcept (int excepts) if (excepts & _FPU_MASK_IM) { float f = 0.0f; -#ifdef __SSE_MATH__ - __asm__ __volatile__ ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f)); -#else - __asm__ __volatile__ ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + __math_force_eval (f / f); } if (excepts & _FPU_MASK_DM) { @@ -120,12 +120,7 @@ local_feraiseexcept (int excepts) if (excepts & _FPU_MASK_ZM) { float f = 1.0f, g = 0.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 (f / g); } if (excepts & _FPU_MASK_OM) { -- 2.30.2