diff mbox series

[2/4] Use libc_fe* macros in ldbl-128/s_fmal.c.

Message ID 20200325100628.883397-2-stli@linux.ibm.com
State New
Headers show
Series [1/4] Use libc_fe* macros in ldbl-128/s_nearbyintl.c. | expand

Commit Message

Michael Kerrisk \(man-pages\) via Libc-alpha March 25, 2020, 10:06 a.m. UTC
The calls to feholdexcept, fesetround, feupdateenv, fetestexcept
are replaced by the libc_fe* macros as it is also done in dbl-64/s_fma.c.
---
 sysdeps/ieee754/float128/float128_private.h | 10 +++++++
 sysdeps/ieee754/ldbl-128/s_fmal.c           | 33 +++++++++++----------
 sysdeps/x86/fpu/fenv_private.h              |  4 +++
 3 files changed, 32 insertions(+), 15 deletions(-)
diff mbox series

Patch

diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
index af1ed8f3c0..671323035d 100644
--- a/sysdeps/ieee754/float128/float128_private.h
+++ b/sysdeps/ieee754/float128/float128_private.h
@@ -76,6 +76,16 @@ 
 # define libc_fesetenvl(ENV) libc_fesetenvf128 (ENV)
 #endif
 
+#ifdef libc_feupdateenvf128
+# undef libc_feupdateenvl
+# define libc_feupdateenvl(ENV) libc_feupdateenvf128 (ENV)
+#endif
+
+#ifdef libc_fesetroundf128
+# undef libc_fesetroundl
+# define libc_fesetroundl(RM) libc_fesetroundf128 (RM)
+#endif
+
 /* misc macros from the header below.  */
 #include <fix-fp-int-convert-overflow.h>
 #undef FIX_LDBL_LONG_CONVERT_OVERFLOW
diff --git a/sysdeps/ieee754/ldbl-128/s_fmal.c b/sysdeps/ieee754/ldbl-128/s_fmal.c
index 7475015bce..f5791b6a8a 100644
--- a/sysdeps/ieee754/ldbl-128/s_fmal.c
+++ b/sysdeps/ieee754/ldbl-128/s_fmal.c
@@ -23,6 +23,7 @@ 
 #include <ieee754.h>
 #include <math-barriers.h>
 #include <math_private.h>
+#include <fenv_private.h>
 #include <libm-alias-ldouble.h>
 #include <tininess.h>
 
@@ -187,8 +188,7 @@  __fmal (_Float128 x, _Float128 y, _Float128 z)
     }
 
   fenv_t env;
-  feholdexcept (&env);
-  fesetround (FE_TONEAREST);
+  libc_feholdexcept_setroundl (&env, FE_TONEAREST);
 
   /* Multiplication m1 + m2 = x * y using Dekker's algorithm.  */
 #define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
@@ -216,41 +216,44 @@  __fmal (_Float128 x, _Float128 y, _Float128 z)
   /* If the result is an exact zero, ensure it has the correct sign.  */
   if (a1 == 0 && m2 == 0)
     {
-      feupdateenv (&env);
+      libc_feupdateenvl (&env);
       /* Ensure that round-to-nearest value of z + m1 is not reused.  */
       z = math_opt_barrier (z);
       return z + m1;
     }
 
-  fesetround (FE_TOWARDZERO);
+  libc_fesetroundl (FE_TOWARDZERO);
   /* Perform m2 + a2 addition with round to odd.  */
   u.d = a2 + m2;
 
+  if (__glibc_unlikely (adjust < 0))
+    {
+      if ((u.ieee.mantissa3 & 1) == 0)
+	u.ieee.mantissa3 |= libc_fetestexceptl (FE_INEXACT) != 0;
+      v.d = a1 + u.d;
+      /* Ensure the addition is not scheduled after fetestexcept call.  */
+      math_force_eval (v.d);
+    }
+
+  /* Reset rounding mode and test for inexact simultaneously.  */
+  int j = libc_feupdateenv_testl (&env, FE_INEXACT) != 0;
+
   if (__glibc_likely (adjust == 0))
     {
       if ((u.ieee.mantissa3 & 1) == 0 && u.ieee.exponent != 0x7fff)
-	u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0;
-      feupdateenv (&env);
+	u.ieee.mantissa3 |= j;
       /* Result is a1 + u.d.  */
       return a1 + u.d;
     }
   else if (__glibc_likely (adjust > 0))
     {
       if ((u.ieee.mantissa3 & 1) == 0 && u.ieee.exponent != 0x7fff)
-	u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0;
-      feupdateenv (&env);
+	u.ieee.mantissa3 |= j;
       /* Result is a1 + u.d, scaled up.  */
       return (a1 + u.d) * L(0x1p113);
     }
   else
     {
-      if ((u.ieee.mantissa3 & 1) == 0)
-	u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0;
-      v.d = a1 + u.d;
-      /* Ensure the addition is not scheduled after fetestexcept call.  */
-      math_force_eval (v.d);
-      int j = fetestexcept (FE_INEXACT) != 0;
-      feupdateenv (&env);
       /* Ensure the following computations are performed in default rounding
 	 mode instead of just reusing the round to zero computation.  */
       asm volatile ("" : "=m" (u) : "m" (u));
diff --git a/sysdeps/x86/fpu/fenv_private.h b/sysdeps/x86/fpu/fenv_private.h
index 23a430362a..8453aaa270 100644
--- a/sysdeps/x86/fpu/fenv_private.h
+++ b/sysdeps/x86/fpu/fenv_private.h
@@ -302,6 +302,8 @@  libc_feresetround_387 (fenv_t *e)
 # define libc_feupdateenv_testf128	libc_feupdateenv_test_sse
 # define libc_feholdexceptf128	libc_feholdexcept_sse
 # define libc_fesetenvf128	libc_fesetenv_sse
+# define libc_feupdateenvf128	libc_feupdateenv_sse
+# define libc_fesetroundf128	libc_fesetround_sse
 #else
 /* The 387 rounding mode is used by soft-fp for 32-bit, but whether
    387 or SSE exceptions are used depends on whether libgcc was built
@@ -310,6 +312,8 @@  libc_feresetround_387 (fenv_t *e)
 # define libc_feupdateenv_testf128	default_libc_feupdateenv_test
 # define libc_feholdexceptf128	default_libc_feholdexcept
 # define libc_fesetenvf128	default_libc_fesetenv
+# define libc_feupdateenvf128	default_libc_feupdateenv
+# define libc_fesetroundf128	default_libc_fesetround
 #endif
 
 /* We have support for rounding mode context.  */