about summary refs log tree commit diff
path: root/sysdeps/ieee754
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c109
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_rintl.c14
2 files changed, 16 insertions, 107 deletions
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
index 08134edd10..dfdefe3f02 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
@@ -17,110 +17,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-/* This has been coded in assembler because GCC makes such a mess of it
-   when it's coded in C.  */
-
-#include <math.h>
-#include <math_private.h>
-#include <fenv.h>
-#include <math_ldbl_opt.h>
-#include <float.h>
-#include <ieee754.h>
-
-
-long double
-__nearbyintl (long double x)
-{
-  fenv_t env;
-  static const long double TWO52 = 4503599627370496.0L;
-  union ibm_extended_long_double u;
-  u.ld = x;
-
-  if (!isfinite (u.d[0].d))
-    return x;
-  else if (fabs (u.d[0].d) < TWO52)
-    {
-      double xh = u.d[0].d;
-      double high = u.d[0].d;
-      feholdexcept (&env);
-      if (high > 0.0)
-	{
-	  high += TWO52;
-	  high -= TWO52;
-          if (high == -0.0) high = 0.0;
-	}
-      else if (high < 0.0)
-	{
-	  high -= TWO52;
-	  high += TWO52;
-          if (high == 0.0) high = -0.0;
-	}
-      if (u.d[1].d > 0.0 && (xh - high == 0.5))
-        high += 1.0;
-      else if (u.d[1].d < 0.0 && (-(xh - high) == 0.5))
-        high -= 1.0;
-      u.d[0].d = high;
-      u.d[1].d = 0.0;
-      math_force_eval (u.d[0]);
-      math_force_eval (u.d[1]);
-      fesetenv (&env);
-    }
-  else if (fabs (u.d[1].d) < TWO52 && u.d[1].d != 0.0)
-    {
-      double high = u.d[0].d, low = u.d[1].d, tau;
-      /* In this case we have to round the low double and handle any
-         adjustment to the high double that may be caused by rounding
-         (up).  This is complicated by the fact that the high double
-         may already be rounded and the low double may have the
-         opposite sign to compensate.  */
-      feholdexcept (&env);
-      if (u.d[0].d > 0.0)
-	{
-	  if (u.d[1].d > 0.0)
-	    {
-	      /* If the high/low doubles are the same sign then simply
-	         round the low double.  */
-	    }
-	  else if (u.d[1].d < 0.0)
-	    {
-	      /* Else the high double is pre rounded and we need to
-	         adjust for that.  */
-
-	      tau = __nextafter (u.d[0].d, 0.0);
-	      tau = (u.d[0].d - tau) * 2.0;
-	      high -= tau;
-	      low += tau;
-	    }
-	  low += TWO52;
-	  low -= TWO52;
-	}
-      else if (u.d[0].d < 0.0)
-	{
-	  if (u.d[1].d < 0.0)
-	    {
-	      /* If the high/low doubles are the same sign then simply
-	         round the low double.  */
-	    }
-	  else if (u.d[1].d > 0.0)
-	    {
-	      /* Else the high double is pre rounded and we need to
-	         adjust for that.  */
-	      tau = __nextafter (u.d[0].d, 0.0);
-	      tau = (u.d[0].d - tau) * 2.0;
-	      high -= tau;
-	      low += tau;
-	    }
-	  low = TWO52 - low;
-	  low = -(low - TWO52);
-	}
-      u.d[0].d = high + low;
-      u.d[1].d = high - u.d[0].d + low;
-      math_force_eval (u.d[0]);
-      math_force_eval (u.d[1]);
-      fesetenv (&env);
-    }
-
-  return u.ld;
-}
-
-long_double_symbol (libm, __nearbyintl, nearbyintl);
+#define USE_AS_NEARBYINTL
+#include "s_rintl.c"
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_rintl.c b/sysdeps/ieee754/ldbl-128ibm/s_rintl.c
index 8c51ded1d6..e4af01c9a0 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_rintl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_rintl.c
@@ -26,6 +26,11 @@
 #include <float.h>
 #include <ieee754.h>
 
+#ifdef USE_AS_NEARBYINTL
+# define rintl nearbyintl
+# define __rintl __nearbyintl
+#endif
+
 
 long double
 __rintl (long double x)
@@ -44,7 +49,11 @@ __rintl (long double x)
 
       /* Long double arithmetic, including the canonicalisation below,
 	 only works in round-to-nearest mode.  */
+#ifdef USE_AS_NEARBYINTL
+      SET_RESTORE_ROUND_NOEX (FE_TONEAREST);
+#else
       fesetround (FE_TONEAREST);
+#endif
 
       /* Convert the high double to integer.  */
       orig_xh = xh;
@@ -103,7 +112,12 @@ __rintl (long double x)
       if (orig_xh < 0.0)
 	xh = -__builtin_fabs (xh);
 
+#ifdef USE_AS_NEARBYINTL
+      math_force_eval (xh);
+      math_force_eval (xl);
+#else
       fesetround (save_round);
+#endif
     }
 
   return ldbl_pack (xh, xl);