i386: Use generic division to generate INVALID and DIVZERO exceptions
authorUros Bizjak <ubizjak@gmail.com>
Fri, 1 May 2020 17:20:57 +0000 (19:20 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Fri, 1 May 2020 17:20:57 +0000 (19:20 +0200)
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
libatomic/config/x86/fenv.c
libgcc/ChangeLog
libgcc/config/i386/sfp-exceptions.c
libgfortran/ChangeLog
libgfortran/config/fpu-387.h

index 33527a7b4564d6239103e6458fbf9821930eef00..48c115de49f2b35149ef1dc630c33f1d9c873bf7 100644 (file)
@@ -1,3 +1,9 @@
+2020-05-01  Uroš Bizjak  <ubizjak@gmail.com>
+
+       * 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  <ubizjak@gmail.com>
 
        * config/x86/fenv.c (__atomic_feraiseexcept) [__SSE_MATH__]:
index d7b1bbe5ea125a5d300a2c84dda14124aba1e9cd..d972a99f5943bfa0b6016823bb3a41185dae9b46 100644 (file)
@@ -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)
     {
index 7dbab3ef4997ac0139709807ea42947b29f953d6..02b36d3a380912a89da653519a14e5c1ea06e51f 100644 (file)
@@ -1,3 +1,9 @@
+2020-05-01  Uroš Bizjak  <ubizjak@gmail.com>
+
+       * 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  <sebastian.huber@embedded-brains.de>
 
        * config/rs6000/crtresfpr.S: Use .machine ppc.
index 31a24ced704a7b0a17f9e3a876cd6cb070416c85..4b3a7a08da124dcee465384d56138ac8822ab1f2 100644 (file)
@@ -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)
     {
index 8e3e087818d67a4eec90bfa453fa175e8ee3d00e..eecfb904f551767c9f4a266cb70fe5f2c029c788 100644 (file)
@@ -1,3 +1,9 @@
+2020-05-01  Uroš Bizjak  <ubizjak@gmail.com>
+
+       * 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  <foreese@gcc.gnu.org>
 
        * intrinsics/trigd.c, intrinsics/trigd_lib.inc, intrinsics/trigd.inc:
index 13be2045b72f8bc8310b29dccaf2cdfac28b5f52..41b82bc809858ef170ca3760e3e3af4b2912cfc2 100644 (file)
@@ -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)
     {