diff options
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c | 109 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128ibm/s_rintl.c | 14 |
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); |