diff --git a/glibc-fedora.patch b/glibc-fedora.patch index 245d867..b0c91ab 100644 --- a/glibc-fedora.patch +++ b/glibc-fedora.patch @@ -1,6 +1,44 @@ --- glibc-20060306T1239/ChangeLog 6 Mar 2006 10:59:43 -0000 1.10062 -+++ glibc-20060306T1239-fedora/ChangeLog 6 Mar 2006 13:15:14 -0000 1.8782.2.172 -@@ -18,6 +18,34 @@ ++++ glibc-20060306T1239-fedora/ChangeLog 7 Mar 2006 08:24:11 -0000 1.8782.2.173 +@@ -1,3 +1,37 @@ ++2006-03-03 Steven Munroe ++ Alan Modra ++ ++ [BZ #2423] ++ * math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test, ++ round_test, trunc_test): Add new tests. ++ ++ * sysdeps/powerpc/fpu/fenv_libc.h (__fegetround, __fesetround): ++ Define inline implementations. ++ * sysdeps/powerpc/fpu/fegetround.c: Use __fegetround. ++ * sysdeps/powerpc/fpu/fesetround.c: Use __fesetround. ++ ++ * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h ++ (EXTRACT_IBM_EXTENDED_MANTISSA, INSERT_IBM_EXTENDED_MANTISSA): ++ Removed, replaced with. ++ (ldbl_extract_mantissa, ldbl_insert_mantissa, ldbl_pack, ldbl_unpack, ++ ldbl_canonicalise, ldbl_nearbyint): Define inline utility ++ functions for IBM long double format. ++ * sysdeps/ieee754/ldbl-128ibm/e_fmodl.c (__ieee754_fmodl): Replace ++ EXTRACT_IBM_EXTENDED_MANTISSA and INSERT_IBM_EXTENDED_MANTISSA ++ with ldbl_extract_mantissa and ldbl_insert_mantissa. ++ * sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c (__ieee754_rem_pio2l): ++ Replace EXTRACT_IBM_EXTENDED_MANTISSA with ldbl_extract_mantissa. ++ (ldbl_extract_mantissa, ldbl_insert_mantissa): Defined. ++ ++ * sysdeps/ieee754/ldbl-128ibm/s_ceill.c (__ceill): Handle rounding ++ that spans doubles in IBM long double format. ++ * sysdeps/ieee754/ldbl-128ibm/s_floorl.c: Likewise. ++ * sysdeps/ieee754/ldbl-128ibm/s_rintl.c: Likewise. ++ * sysdeps/ieee754/ldbl-128ibm/s_roundl.c: Likewise. ++ * sysdeps/ieee754/ldbl-128ibm/s_truncl.c: Likewise. ++ * sysdeps/powerpc/fpu/math_ldbl.h: New file. ++ * sysdeps/powerpc/powerpc64/fpu/s_rintl.S: Removed. ++ + 2006-03-06 Roland McGrath + + * version.h (VERSION): 2.4 +@@ -18,6 +52,34 @@ _SC_CPUTIME and _SC_THREAD_CPUTIME here. * sysdeps/unix/sysv/linux/x86_64/sysconf.c (__sysconf): Likewise. @@ -35,7 +73,7 @@ 2006-03-05 Roland McGrath * malloc/malloc.c (MALLOC_ALIGNMENT): Revert to (2 * SIZE_SZ) value. -@@ -1030,6 +1058,11 @@ +@@ -1030,6 +1092,11 @@ (__MATHDECL_2): Use __REDIRECT_NTH instead of __REDIRECT followed by __THROW. @@ -47,7 +85,7 @@ 2006-02-02 Ulrich Drepper * sysdeps/unix/sysv/linux/futimesat.c [__NR_futimesat] -@@ -1089,6 +1122,11 @@ +@@ -1089,6 +1156,11 @@ * sysdeps/ieee754/ldbl-128/s_llrintl.c (__llrintl): Fix a typo. * sysdeps/s390/fpu/libm-test-ulps: Remove llrint ulps. @@ -59,7 +97,7 @@ 2006-01-19 Thomas Schwinge * libio/genops.c: Include . -@@ -3515,6 +3553,10 @@ +@@ -3515,6 +3587,10 @@ * elf/order2mod2.c (init): Cast ignored value to void. @@ -70,7 +108,7 @@ 2005-12-27 Ulrich Drepper * elf/tst-tls13.c (do_test): Avoid using the library path when -@@ -3798,6 +3840,26 @@ +@@ -3798,6 +3874,26 @@ * sysdeps/unix/sysv/linux/time.c: If __NR_time is not defined, use sysdeps/unix/time.c implementation. @@ -97,7 +135,7 @@ 2005-12-19 Ulrich Drepper [BZ #1955] -@@ -6916,6 +6978,11 @@ +@@ -6916,6 +7012,11 @@ R_ARM_TLS_TPOFF32, R_ARM_TLS_GD32, R_ARM_TLS_LDM32, R_ARM_TLS_LDO32, R_ARM_TLS_IE32, R_ARM_TLS_LE32): New macros. @@ -109,7 +147,7 @@ 2005-10-03 Roland McGrath * sysdeps/powerpc/nofpu: Directory removed, saved in ports repository. -@@ -7910,6 +7977,12 @@ +@@ -7910,6 +8011,12 @@ * argp/argp-help.c (__argp_error): __asprintf -> vasprintf. (__argp_failure): Likewise. @@ -122,7 +160,7 @@ 2005-08-08 Ulrich Drepper * nscd/cache.c (cache_add): Commit hash table and header to disk. -@@ -8034,6 +8107,17 @@ +@@ -8034,6 +8141,17 @@ __syslog_chk. * misc/Versions: Export __syslog_chk and __vsyslog_chk. @@ -140,7 +178,7 @@ 2005-07-28 Thomas Schwinge [BZ #1137] -@@ -11094,6 +11178,18 @@ +@@ -11094,6 +11212,18 @@ * scripts/soversions.awk: Fix default version set handling. @@ -1101,6 +1139,462 @@ __memalign_hook = tr_memalignhook; __malloc_hook = tr_mallochook; +--- glibc-20060306T1239/math/libm-test.inc 28 Jan 2006 00:35:55 -0000 1.69 ++++ glibc-20060306T1239-fedora/math/libm-test.inc 7 Mar 2006 08:24:12 -0000 1.61.2.7 +@@ -1628,8 +1628,12 @@ ceil_test (void) + + TEST_f_f (ceil, M_PIl, 4.0); + TEST_f_f (ceil, -M_PIl, -3.0); ++ TEST_f_f (ceil, 0.1, 1.0); + TEST_f_f (ceil, 0.25, 1.0); ++ TEST_f_f (ceil, 0.625, 1.0); ++ TEST_f_f (ceil, -0.1, minus_zero); + TEST_f_f (ceil, -0.25, minus_zero); ++ TEST_f_f (ceil, -0.625, minus_zero); + + #ifdef TEST_LDOUBLE + /* The result can only be represented in long double. */ +@@ -1644,6 +1648,13 @@ ceil_test (void) + TEST_f_f (ceil, -4503599627370496.5L, -4503599627370496.0L); + TEST_f_f (ceil, -4503599627370496.75L, -4503599627370496.0L); + TEST_f_f (ceil, -4503599627370497.5L, -4503599627370497.0L); ++ ++ TEST_f_f (ceil, 4503599627370494.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (ceil, 4503599627370495.5000000000001L, 4503599627370496.0L); ++ TEST_f_f (ceil, 4503599627370496.5000000000001L, 4503599627370497.0L); ++ TEST_f_f (ceil, -4503599627370494.5000000000001L, -4503599627370494.0L); ++ TEST_f_f (ceil, -4503599627370495.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (ceil, -4503599627370496.5000000000001L, -4503599627370496.0L); + + TEST_f_f (ceil, 9007199254740991.5L, 9007199254740992.0L); + TEST_f_f (ceil, 9007199254740992.25L, 9007199254740993.0L); +@@ -1657,6 +1668,20 @@ ceil_test (void) + TEST_f_f (ceil, -9007199254740992.75L, -9007199254740992.0L); + TEST_f_f (ceil, -9007199254740993.5L, -9007199254740993.0L); + ++ TEST_f_f (ceil, 9007199254740991.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (ceil, 9007199254740992.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (ceil, 9007199254740993.0000000000001L, 9007199254740994.0L); ++ TEST_f_f (ceil, 9007199254740991.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (ceil, 9007199254740992.5000000000001L, 9007199254740993.0L); ++ TEST_f_f (ceil, 9007199254740993.5000000000001L, 9007199254740994.0L); ++ ++ TEST_f_f (ceil, -9007199254740991.0000000000001L, -9007199254740991.0L); ++ TEST_f_f (ceil, -9007199254740992.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (ceil, -9007199254740993.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (ceil, -9007199254740991.5000000000001L, -9007199254740991.0L); ++ TEST_f_f (ceil, -9007199254740992.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (ceil, -9007199254740993.5000000000001L, -9007199254740993.0L); ++ + TEST_f_f (ceil, 72057594037927935.5L, 72057594037927936.0L); + TEST_f_f (ceil, 72057594037927936.25L, 72057594037927937.0L); + TEST_f_f (ceil, 72057594037927936.5L, 72057594037927937.0L); +@@ -2628,9 +2653,12 @@ floor_test (void) + TEST_f_f (floor, M_PIl, 3.0); + TEST_f_f (floor, -M_PIl, -4.0); + ++ TEST_f_f (floor, 0.1, 0.0); + TEST_f_f (floor, 0.25, 0.0); ++ TEST_f_f (floor, 0.625, 0.0); ++ TEST_f_f (floor, -0.1, -1.0); + TEST_f_f (floor, -0.25, -1.0); +- ++ TEST_f_f (floor, -0.625, -1.0); + + #ifdef TEST_LDOUBLE + /* The result can only be represented in long double. */ +@@ -2639,12 +2667,18 @@ floor_test (void) + TEST_f_f (floor, 4503599627370496.5L, 4503599627370496.0L); + TEST_f_f (floor, 4503599627370496.75L, 4503599627370496.0L); + TEST_f_f (floor, 4503599627370497.5L, 4503599627370497.0L); ++ TEST_f_f (floor, 4503599627370494.5000000000001L, 4503599627370494.0L); ++ TEST_f_f (floor, 4503599627370495.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (floor, 4503599627370496.5000000000001L, 4503599627370496.0L); + + TEST_f_f (floor, -4503599627370495.5L, -4503599627370496.0L); + TEST_f_f (floor, -4503599627370496.25L, -4503599627370497.0L); + TEST_f_f (floor, -4503599627370496.5L, -4503599627370497.0L); + TEST_f_f (floor, -4503599627370496.75L, -4503599627370497.0L); + TEST_f_f (floor, -4503599627370497.5L, -4503599627370498.0L); ++ TEST_f_f (floor, -4503599627370494.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (floor, -4503599627370495.5000000000001L, -4503599627370496.0L); ++ TEST_f_f (floor, -4503599627370496.5000000000001L, -4503599627370497.0L); + + TEST_f_f (floor, 9007199254740991.5L, 9007199254740991.0L); + TEST_f_f (floor, 9007199254740992.25L, 9007199254740992.0L); +@@ -2652,12 +2686,26 @@ floor_test (void) + TEST_f_f (floor, 9007199254740992.75L, 9007199254740992.0L); + TEST_f_f (floor, 9007199254740993.5L, 9007199254740993.0L); + ++ TEST_f_f (floor, 9007199254740991.0000000000001L, 9007199254740991.0L); ++ TEST_f_f (floor, 9007199254740992.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (floor, 9007199254740993.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (floor, 9007199254740991.5000000000001L, 9007199254740991.0L); ++ TEST_f_f (floor, 9007199254740992.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (floor, 9007199254740993.5000000000001L, 9007199254740993.0L); ++ + TEST_f_f (floor, -9007199254740991.5L, -9007199254740992.0L); + TEST_f_f (floor, -9007199254740992.25L, -9007199254740993.0L); + TEST_f_f (floor, -9007199254740992.5L, -9007199254740993.0L); + TEST_f_f (floor, -9007199254740992.75L, -9007199254740993.0L); + TEST_f_f (floor, -9007199254740993.5L, -9007199254740994.0L); + ++ TEST_f_f (floor, -9007199254740991.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (floor, -9007199254740992.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (floor, -9007199254740993.0000000000001L, -9007199254740994.0L); ++ TEST_f_f (floor, -9007199254740991.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (floor, -9007199254740992.5000000000001L, -9007199254740993.0L); ++ TEST_f_f (floor, -9007199254740993.5000000000001L, -9007199254740994.0L); ++ + TEST_f_f (floor, 72057594037927935.5L, 72057594037927935.0L); + TEST_f_f (floor, 72057594037927936.25L, 72057594037927936.0L); + TEST_f_f (floor, 72057594037927936.5L, 72057594037927936.0L); +@@ -3971,6 +4019,12 @@ rint_test (void) + TEST_f_f (rint, -2.5, -2.0); + TEST_f_f (rint, -3.5, -4.0); + TEST_f_f (rint, -4.5, -4.0); ++ TEST_f_f (rint, 0.1, 0.0); ++ TEST_f_f (rint, 0.25, 0.0); ++ TEST_f_f (rint, 0.625, 1.0); ++ TEST_f_f (rint, -0.1, -0.0); ++ TEST_f_f (rint, -0.25, -0.0); ++ TEST_f_f (rint, -0.625, -1.0); + #ifdef TEST_LDOUBLE + /* The result can only be represented in long double. */ + TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L); +@@ -3978,12 +4032,34 @@ rint_test (void) + TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); + TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L); + TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L); ++ ++ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); + + TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); + TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L); + TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L); ++ ++ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L); ++ ++ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); ++ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L); ++ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L); ++ ++ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); ++ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L); ++ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); + + TEST_f_f (rint, 9007199254740991.5L, 9007199254740992.0L); + TEST_f_f (rint, 9007199254740992.25L, 9007199254740992.0L); +@@ -4039,6 +4115,45 @@ rint_test_tonearest (void) + TEST_f_f (rint, -1.0, -1.0); + TEST_f_f (rint, -1.5, -2.0); + TEST_f_f (rint, -2.0, -2.0); ++ TEST_f_f (rint, 0.1, 0.0); ++ TEST_f_f (rint, 0.25, 0.0); ++ TEST_f_f (rint, 0.625, 1.0); ++ TEST_f_f (rint, -0.1, -0.0); ++ TEST_f_f (rint, -0.25, -0.0); ++ TEST_f_f (rint, -0.625, -1.0); ++#ifdef TEST_LDOUBLE ++ /* The result can only be represented in long double. */ ++ TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L); ++ TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L); ++ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); ++ TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L); ++ TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L); ++ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L); ++ ++ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); ++ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L); ++ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L); ++ ++ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); ++ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L); ++ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); ++#endif + } + + fesetround(save_round_mode); +@@ -4066,6 +4181,45 @@ rint_test_towardzero (void) + TEST_f_f (rint, -1.0, -1.0); + TEST_f_f (rint, -1.5, -1.0); + TEST_f_f (rint, -2.0, -2.0); ++ TEST_f_f (rint, 0.1, 0.0); ++ TEST_f_f (rint, 0.25, 0.0); ++ TEST_f_f (rint, 0.625, 0.0); ++ TEST_f_f (rint, -0.1, -0.0); ++ TEST_f_f (rint, -0.25, -0.0); ++ TEST_f_f (rint, -0.625, -0.0); ++#ifdef TEST_LDOUBLE ++ /* The result can only be represented in long double. */ ++ TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L); ++ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L); ++ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L); ++ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L); ++ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L); ++ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L); ++ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L); ++ ++ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); ++ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L); ++ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L); ++ ++ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); ++ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L); ++ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L); ++#endif + } + + fesetround(save_round_mode); +@@ -4093,6 +4247,45 @@ rint_test_downward (void) + TEST_f_f (rint, -1.0, -1.0); + TEST_f_f (rint, -1.5, -2.0); + TEST_f_f (rint, -2.0, -2.0); ++ TEST_f_f (rint, 0.1, 0.0); ++ TEST_f_f (rint, 0.25, 0.0); ++ TEST_f_f (rint, 0.625, 0.0); ++ TEST_f_f (rint, -0.1, -1.0); ++ TEST_f_f (rint, -0.25, -1.0); ++ TEST_f_f (rint, -0.625, -1.0); ++#ifdef TEST_LDOUBLE ++ /* The result can only be represented in long double. */ ++ TEST_f_f (rint, 4503599627370495.5L, 4503599627370495.0L); ++ TEST_f_f (rint, 4503599627370496.25L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.5L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L); ++ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L); ++ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.25L, -4503599627370497.0L); ++ TEST_f_f (rint, -4503599627370496.5L, -4503599627370497.0L); ++ TEST_f_f (rint, -4503599627370496.75L, -4503599627370497.0L); ++ TEST_f_f (rint, -4503599627370497.5L, -4503599627370498.0L); ++ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370497.0L); ++ ++ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740991.0L); ++ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740991.0L); ++ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740993.0L); ++ ++ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740994.0L); ++ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740993.0L); ++ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L); ++#endif + } + + fesetround(save_round_mode); +@@ -4120,6 +4313,45 @@ rint_test_upward (void) + TEST_f_f (rint, -1.0, -1.0); + TEST_f_f (rint, -1.5, -1.0); + TEST_f_f (rint, -2.0, -2.0); ++ TEST_f_f (rint, 0.1, 1.0); ++ TEST_f_f (rint, 0.25, 1.0); ++ TEST_f_f (rint, 0.625, 1.0); ++ TEST_f_f (rint, -0.1, -0.0); ++ TEST_f_f (rint, -0.25, -0.0); ++ TEST_f_f (rint, -0.625, -0.0); ++#ifdef TEST_LDOUBLE ++ /* The result can only be represented in long double. */ ++ TEST_f_f (rint, 4503599627370495.5L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.25L, 4503599627370497.0L); ++ TEST_f_f (rint, 4503599627370496.5L, 4503599627370497.0L); ++ TEST_f_f (rint, 4503599627370496.75L, 4503599627370497.0L); ++ TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L); ++ TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L); ++ TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L); ++ TEST_f_f (rint, -4503599627370495.5L, -4503599627370495.0L); ++ TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370496.75L, -4503599627370496.0L); ++ TEST_f_f (rint, -4503599627370497.5L, -4503599627370497.0L); ++ TEST_f_f (rint, -4503599627370494.5000000000001L, -4503599627370494.0L); ++ TEST_f_f (rint, -4503599627370495.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (rint, -4503599627370496.5000000000001L, -4503599627370496.0L); ++ ++ TEST_f_f (rint, 9007199254740991.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740992.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (rint, 9007199254740993.0000000000001L, 9007199254740994.0L); ++ TEST_f_f (rint, 9007199254740991.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (rint, 9007199254740992.5000000000001L, 9007199254740993.0L); ++ TEST_f_f (rint, 9007199254740993.5000000000001L, 9007199254740994.0L); ++ ++ TEST_f_f (rint, -9007199254740991.0000000000001L, -9007199254740991.0L); ++ TEST_f_f (rint, -9007199254740992.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740993.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (rint, -9007199254740991.5000000000001L, -9007199254740991.0L); ++ TEST_f_f (rint, -9007199254740992.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740993.0L); ++#endif + } + + fesetround(save_round_mode); +@@ -4142,6 +4374,12 @@ round_test (void) + TEST_f_f (round, -0.8L, -1.0); + TEST_f_f (round, 1.5, 2.0); + TEST_f_f (round, -1.5, -2.0); ++ TEST_f_f (round, 0.1, 0.0); ++ TEST_f_f (round, 0.25, 0.0); ++ TEST_f_f (round, 0.625, 1.0); ++ TEST_f_f (round, -0.1, -0.0); ++ TEST_f_f (round, -0.25, -0.0); ++ TEST_f_f (round, -0.625, -1.0); + TEST_f_f (round, 2097152.5, 2097153); + TEST_f_f (round, -2097152.5, -2097153); + +@@ -4151,13 +4389,19 @@ round_test (void) + TEST_f_f (round, 4503599627370496.25L, 4503599627370496.0L); + TEST_f_f (round, 4503599627370496.5L, 4503599627370497.0L); + TEST_f_f (round, 4503599627370496.75L, 4503599627370497.0L); +- TEST_f_f (round, 4503599627370497.5L, 4503599627370498.0L); ++ TEST_f_f (round, 4503599627370497.5L, 4503599627370498.0L); ++ TEST_f_f (round, 4503599627370494.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (round, 4503599627370495.5000000000001L, 4503599627370496.0L); ++ TEST_f_f (round, 4503599627370496.5000000000001L, 4503599627370497.0L); + + TEST_f_f (round, -4503599627370495.5L, -4503599627370496.0L); + TEST_f_f (round, -4503599627370496.25L, -4503599627370496.0L); + TEST_f_f (round, -4503599627370496.5L, -4503599627370497.0L); + TEST_f_f (round, -4503599627370496.75L, -4503599627370497.0L); + TEST_f_f (round, -4503599627370497.5L, -4503599627370498.0L); ++ TEST_f_f (round, -4503599627370494.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (round, -4503599627370495.5000000000001L, -4503599627370496.0L); ++ TEST_f_f (round, -4503599627370496.5000000000001L, -4503599627370497.0L); + + TEST_f_f (round, 9007199254740991.5L, 9007199254740992.0L); + TEST_f_f (round, 9007199254740992.25L, 9007199254740992.0L); +@@ -4171,6 +4415,20 @@ round_test (void) + TEST_f_f (round, -9007199254740992.75L, -9007199254740993.0L); + TEST_f_f (round, -9007199254740993.5L, -9007199254740994.0L); + ++ TEST_f_f (round, 9007199254740991.0000000000001L, 9007199254740991.0L); ++ TEST_f_f (round, 9007199254740992.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (round, 9007199254740993.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (round, 9007199254740991.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (round, 9007199254740992.5000000000001L, 9007199254740993.0L); ++ TEST_f_f (round, 9007199254740993.5000000000001L, 9007199254740994.0L); ++ ++ TEST_f_f (round, -9007199254740991.0000000000001L, -9007199254740991.0L); ++ TEST_f_f (round, -9007199254740992.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (round, -9007199254740993.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (round, -9007199254740991.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (round, -9007199254740992.5000000000001L, -9007199254740993.0L); ++ TEST_f_f (round, -9007199254740993.5000000000001L, -9007199254740994.0L); ++ + TEST_f_f (round, 72057594037927935.5L, 72057594037927936.0L); + TEST_f_f (round, 72057594037927936.25L, 72057594037927936.0L); + TEST_f_f (round, 72057594037927936.5L, 72057594037927937.0L); +@@ -4541,7 +4799,11 @@ trunc_test (void) + + TEST_f_f (trunc, 0, 0); + TEST_f_f (trunc, minus_zero, minus_zero); ++ TEST_f_f (trunc, 0.1, 0); ++ TEST_f_f (trunc, 0.25, 0); + TEST_f_f (trunc, 0.625, 0); ++ TEST_f_f (trunc, -0.1, minus_zero); ++ TEST_f_f (trunc, -0.25, minus_zero); + TEST_f_f (trunc, -0.625, minus_zero); + TEST_f_f (trunc, 1, 1); + TEST_f_f (trunc, -1, -1); +@@ -4565,11 +4827,19 @@ trunc_test (void) + TEST_f_f (trunc, 4503599627370496.75L, 4503599627370496.0L); + TEST_f_f (trunc, 4503599627370497.5L, 4503599627370497.0L); + ++ TEST_f_f (trunc, 4503599627370494.5000000000001L, 4503599627370494.0L); ++ TEST_f_f (trunc, 4503599627370495.5000000000001L, 4503599627370495.0L); ++ TEST_f_f (trunc, 4503599627370496.5000000000001L, 4503599627370496.0L); ++ + TEST_f_f (trunc, -4503599627370495.5L, -4503599627370495.0L); + TEST_f_f (trunc, -4503599627370496.25L, -4503599627370496.0L); + TEST_f_f (trunc, -4503599627370496.5L, -4503599627370496.0L); + TEST_f_f (trunc, -4503599627370496.75L, -4503599627370496.0L); + TEST_f_f (trunc, -4503599627370497.5L, -4503599627370497.0L); ++ ++ TEST_f_f (trunc, -4503599627370494.5000000000001L, -4503599627370494.0L); ++ TEST_f_f (trunc, -4503599627370495.5000000000001L, -4503599627370495.0L); ++ TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L); + + TEST_f_f (trunc, 9007199254740991.5L, 9007199254740991.0L); + TEST_f_f (trunc, 9007199254740992.25L, 9007199254740992.0L); +@@ -4577,12 +4847,26 @@ trunc_test (void) + TEST_f_f (trunc, 9007199254740992.75L, 9007199254740992.0L); + TEST_f_f (trunc, 9007199254740993.5L, 9007199254740993.0L); + ++ TEST_f_f (trunc, 9007199254740991.0000000000001L, 9007199254740991.0L); ++ TEST_f_f (trunc, 9007199254740992.0000000000001L, 9007199254740992.0L); ++ TEST_f_f (trunc, 9007199254740993.0000000000001L, 9007199254740993.0L); ++ TEST_f_f (trunc, 9007199254740991.5000000000001L, 9007199254740991.0L); ++ TEST_f_f (trunc, 9007199254740992.5000000000001L, 9007199254740992.0L); ++ TEST_f_f (trunc, 9007199254740993.5000000000001L, 9007199254740993.0L); ++ + TEST_f_f (trunc, -9007199254740991.5L, -9007199254740991.0L); + TEST_f_f (trunc, -9007199254740992.25L, -9007199254740992.0L); + TEST_f_f (trunc, -9007199254740992.5L, -9007199254740992.0L); + TEST_f_f (trunc, -9007199254740992.75L, -9007199254740992.0L); + TEST_f_f (trunc, -9007199254740993.5L, -9007199254740993.0L); + ++ TEST_f_f (trunc, -9007199254740991.0000000000001L, -9007199254740991.0L); ++ TEST_f_f (trunc, -9007199254740992.0000000000001L, -9007199254740992.0L); ++ TEST_f_f (trunc, -9007199254740993.0000000000001L, -9007199254740993.0L); ++ TEST_f_f (trunc, -9007199254740991.5000000000001L, -9007199254740991.0L); ++ TEST_f_f (trunc, -9007199254740992.5000000000001L, -9007199254740992.0L); ++ TEST_f_f (trunc, -9007199254740993.5000000000001L, -9007199254740993.0L); ++ + TEST_f_f (trunc, 72057594037927935.5L, 72057594037927935.0L); + TEST_f_f (trunc, 72057594037927936.25L, 72057594037927936.0L); + TEST_f_f (trunc, 72057594037927936.5L, 72057594037927936.0L); --- glibc-20060306T1239/nptl/ChangeLog 6 Mar 2006 01:41:08 -0000 1.879 +++ glibc-20060306T1239-fedora/nptl/ChangeLog 6 Mar 2006 07:29:58 -0000 1.706.2.83 @@ -731,6 +731,15 @@ @@ -3035,6 +3529,1393 @@ +symbol_version (INTUSE (__multi3), __multi3, GLIBC_2.2); + +#endif +--- glibc-20060306T1239/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20060306T1239-fedora/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c 7 Mar 2006 08:24:12 -0000 1.1.2.2 +@@ -76,8 +76,8 @@ static long double one = 1.0, Zero[] = { + /* Make the IBM extended format 105 bit mantissa look like the ieee854 112 + bit mantissa so the following operatations will give the correct + result. */ +- EXTRACT_IBM_EXTENDED_MANTISSA(hx, lx, temp, x); +- EXTRACT_IBM_EXTENDED_MANTISSA(hy, ly, temp, y); ++ ldbl_extract_mantissa(&hx, &lx, &temp, x); ++ ldbl_extract_mantissa(&hy, &ly, &temp, y); + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -1022) +@@ -127,7 +127,7 @@ static long double one = 1.0, Zero[] = { + iy -= 1; + } + if(iy>= -1022) { /* normalize output */ +- INSERT_IBM_EXTENDED_MANTISSA(x, (sx>>63), iy, hx, lx); ++ x = ldbl_insert_mantissa((sx>>63), iy, hx, lx); + } else { /* subnormal output */ + n = -1022 - iy; + if(n<=48) { +@@ -138,7 +138,7 @@ static long double one = 1.0, Zero[] = { + } else { + lx = hx>>(n-64); hx = sx; + } +- INSERT_IBM_EXTENDED_MANTISSA(x, (sx>>63), iy, hx, lx); ++ x = ldbl_insert_mantissa((sx>>63), iy, hx, lx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +--- glibc-20060306T1239/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20060306T1239-fedora/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c 7 Mar 2006 08:24:12 -0000 1.1.2.2 +@@ -199,7 +199,8 @@ int32_t __ieee754_rem_pio2l(long double + { + long double z, w, t; + double tx[8]; +- int64_t exp, n, ix, hx, ixd; ++ int exp; ++ int64_t n, ix, hx, ixd; + u_int64_t lx, lxd; + + GET_LDOUBLE_WORDS64 (hx, lx, x); +@@ -243,7 +244,7 @@ int32_t __ieee754_rem_pio2l(long double + stored in a double array. */ + /* Make the IBM extended format 105 bit mantissa look like the ieee854 112 + bit mantissa so the next operatation will give the correct result. */ +- EXTRACT_IBM_EXTENDED_MANTISSA (ixd, lxd, exp, x); ++ ldbl_extract_mantissa (&ixd, &lxd, &exp, x); + exp = exp - 23; + /* This is faster than doing this in floating point, because we + have to convert it to integers anyway and like this we can keep +--- glibc-20060306T1239/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20060306T1239-fedora/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 7 Mar 2006 08:24:12 -0000 1.1.2.2 +@@ -3,122 +3,179 @@ + #endif + + #include ++#include ++ ++static inline void ++ldbl_extract_mantissa (int64_t *hi64, u_int64_t *lo64, int *exp, long double x) ++{ ++ /* We have 105 bits of mantissa plus one implicit digit. Since ++ 106 bits are representable we use the first implicit digit for ++ the number before the decimal point and the second implicit bit ++ as bit 53 of the mantissa. */ ++ unsigned long long hi, lo; ++ int ediff; ++ union ibm_extended_long_double eldbl; ++ eldbl.d = x; ++ *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; + +-#define EXTRACT_IBM_EXTENDED_MANTISSA(hi64, lo64, expnt, ibm_ext_ldbl) \ +- do \ +- { \ +- /* We have 105 bits of mantissa plus one implicit digit. Since \ +- 106 bits are representable without the rest using hexadecimal \ +- digits we use only the implicit digits for the number before \ +- the decimal point. */ \ +- unsigned long long hi, lo; \ +- int ediff; \ +- union ibm_extended_long_double eldbl; \ +- eldbl.d = ibm_ext_ldbl; \ +- expnt = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; \ +- \ +- lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; \ +- hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; \ +- /* If the lower double is not a denomal or zero then set the hidden \ +- 53rd bit. */ \ +- if (eldbl.ieee.exponent2 > 0x001) \ +- { \ +- lo |= (1ULL << 52); \ +- lo = lo << 7; /* pre-shift lo to match ieee854. */ \ +- /* The lower double is normalized separately from the upper. We \ +- may need to adjust the lower manitissa to reflect this. */ \ +- ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ +- if (ediff > 53) \ +- lo = lo >> (ediff-53); \ +- } \ +- hi |= (1ULL << 52); \ +- \ +- if ((eldbl.ieee.negative != eldbl.ieee.negative2) \ +- && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL))) \ +- { \ +- hi--; \ +- lo = (1ULL << 60) - lo; \ +- if (hi < (1ULL << 52)) \ +- { \ +- /* we have a borrow from the hidden bit, so shift left 1. */ \ +- hi = (hi << 1) | (lo >> 59); \ +- lo = 0xfffffffffffffffLL & (lo << 1); \ +- expnt--; \ +- } \ +- } \ +- lo64 = (hi << 60) | lo; \ +- hi64 = hi >> 4; \ +- } \ +- while (0) +- +-#define INSERT_IBM_EXTENDED_MANTISSA(ibm_ext_ldbl, sign, expnt, hi64, lo64) \ +- do \ +- { \ +- union ibm_extended_long_double u; \ +- unsigned long hidden2, lzcount; \ +- unsigned long long hi, lo; \ +- \ +- u.ieee.negative = sign; \ +- u.ieee.negative2 = sign; \ +- u.ieee.exponent = expnt + IBM_EXTENDED_LONG_DOUBLE_BIAS; \ +- u.ieee.exponent2 = expnt-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; \ +- /* Expect 113 bits (112 bits + hidden) right justified in two longs. \ +- The low order 53 bits (52 + hidden) go into the lower double */ \ +- lo = (lo64 >> 7)& ((1ULL << 53) - 1); \ +- hidden2 = (lo64 >> 59) & 1ULL; \ +- /* The high order 53 bits (52 + hidden) go into the upper double */ \ +- hi = (lo64 >> 60) & ((1ULL << 11) - 1); \ +- hi |= (hi64 << 4); \ +- \ +- if (lo != 0LL) \ +- { \ +- /* hidden2 bit of low double controls rounding of the high double. \ +- If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) \ +- plus change the sign of the low double to compensate. */ \ +- if (hidden2) \ +- { \ +- hi++; \ +- u.ieee.negative2 = !sign; \ +- lo = (1ULL << 53) - lo; \ +- } \ +- /* The hidden bit of the lo mantissa is zero so we need to \ +- normalize the it for the low double. Shift it left until the \ +- hidden bit is '1' then adjust the 2nd exponent accordingly. */ \ +- \ +- if (sizeof (lo) == sizeof (long)) \ +- lzcount = __builtin_clzl (lo); \ +- else if ((lo >> 32) != 0) \ +- lzcount = __builtin_clzl ((long) (lo >> 32)); \ +- else \ +- lzcount = __builtin_clzl ((long) lo) + 32; \ +- lzcount = lzcount - 11; \ +- if (lzcount > 0) \ +- { \ +- int expnt2 = u.ieee.exponent2 - lzcount; \ +- if (expnt2 >= 1) \ +- { \ +- /* Not denormal. Normalize and set low exponent. */ \ +- lo = lo << lzcount; \ +- u.ieee.exponent2 = expnt2; \ +- } \ +- else \ +- { \ +- /* Is denormal. */ \ +- lo = lo << (lzcount + expnt2); \ +- u.ieee.exponent2 = 0; \ +- } \ +- } \ +- } \ +- else \ +- { \ +- u.ieee.negative2 = 0; \ +- u.ieee.exponent2 = 0; \ +- } \ +- \ +- u.ieee.mantissa3 = lo & ((1ULL << 32) - 1); \ +- u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1); \ +- u.ieee.mantissa1 = hi & ((1ULL << 32) - 1); \ +- u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); \ +- ibm_ext_ldbl = u.d; \ +- } \ +- while (0) ++ lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; ++ hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; ++ /* If the lower double is not a denomal or zero then set the hidden ++ 53rd bit. */ ++ if (eldbl.ieee.exponent2 > 0x001) ++ { ++ lo |= (1ULL << 52); ++ lo = lo << 7; /* pre-shift lo to match ieee854. */ ++ /* The lower double is normalized separately from the upper. We ++ may need to adjust the lower manitissa to reflect this. */ ++ ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; ++ if (ediff > 53) ++ lo = lo >> (ediff-53); ++ } ++ hi |= (1ULL << 52); ++ ++ if ((eldbl.ieee.negative != eldbl.ieee.negative2) ++ && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL))) ++ { ++ hi--; ++ lo = (1ULL << 60) - lo; ++ if (hi < (1ULL << 52)) ++ { ++ /* we have a borrow from the hidden bit, so shift left 1. */ ++ hi = (hi << 1) | (lo >> 59); ++ lo = 0xfffffffffffffffLL & (lo << 1); ++ *exp = *exp - 1; ++ } ++ } ++ *lo64 = (hi << 60) | lo; ++ *hi64 = hi >> 4; ++} ++ ++static inline long double ++ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) ++{ ++ union ibm_extended_long_double u; ++ unsigned long hidden2, lzcount; ++ unsigned long long hi, lo; ++ ++ u.ieee.negative = sign; ++ u.ieee.negative2 = sign; ++ u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ /* Expect 113 bits (112 bits + hidden) right justified in two longs. ++ The low order 53 bits (52 + hidden) go into the lower double */ ++ lo = (lo64 >> 7)& ((1ULL << 53) - 1); ++ hidden2 = (lo64 >> 59) & 1ULL; ++ /* The high order 53 bits (52 + hidden) go into the upper double */ ++ hi = (lo64 >> 60) & ((1ULL << 11) - 1); ++ hi |= (hi64 << 4); ++ ++ if (lo != 0LL) ++ { ++ /* hidden2 bit of low double controls rounding of the high double. ++ If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) ++ plus change the sign of the low double to compensate. */ ++ if (hidden2) ++ { ++ hi++; ++ u.ieee.negative2 = !sign; ++ lo = (1ULL << 53) - lo; ++ } ++ /* The hidden bit of the lo mantissa is zero so we need to ++ normalize the it for the low double. Shift it left until the ++ hidden bit is '1' then adjust the 2nd exponent accordingly. */ ++ ++ if (sizeof (lo) == sizeof (long)) ++ lzcount = __builtin_clzl (lo); ++ else if ((lo >> 32) != 0) ++ lzcount = __builtin_clzl ((long) (lo >> 32)); ++ else ++ lzcount = __builtin_clzl ((long) lo) + 32; ++ lzcount = lzcount - 11; ++ if (lzcount > 0) ++ { ++ int expnt2 = u.ieee.exponent2 - lzcount; ++ if (expnt2 >= 1) ++ { ++ /* Not denormal. Normalize and set low exponent. */ ++ lo = lo << lzcount; ++ u.ieee.exponent2 = expnt2; ++ } ++ else ++ { ++ /* Is denormal. */ ++ lo = lo << (lzcount + expnt2); ++ u.ieee.exponent2 = 0; ++ } ++ } ++ } ++ else ++ { ++ u.ieee.negative2 = 0; ++ u.ieee.exponent2 = 0; ++ } ++ ++ u.ieee.mantissa3 = lo & ((1ULL << 32) - 1); ++ u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1); ++ u.ieee.mantissa1 = hi & ((1ULL << 32) - 1); ++ u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); ++ return u.d; ++} ++ ++/* Handy utility functions to pack/unpack/cononicalize and find the nearbyint ++ of long double implemented as double double. */ ++static inline long double ++ldbl_pack (double a, double aa) ++{ ++ union ibm_extended_long_double u; ++ u.dd[0] = a; ++ u.dd[1] = aa; ++ return u.d; ++} ++ ++static inline void ++ldbl_unpack (long double l, double *a, double *aa) ++{ ++ union ibm_extended_long_double u; ++ u.d = l; ++ *a = u.dd[0]; ++ *aa = u.dd[1]; ++} ++ ++ ++/* Convert a finite long double to canonical form. ++ Does not handle +/-Inf properly. */ ++static inline void ++ldbl_canonicalize (double *a, double *aa) ++{ ++ double xh, xl; ++ ++ xh = *a + *aa; ++ xl = (*a - xh) + *aa; ++ *a = xh; ++ *aa = xl; ++} ++ ++/* Simple inline nearbyint (double) function . ++ Only works in the default rounding mode ++ but is useful in long double rounding functions. */ ++static inline double ++ldbl_nearbyint (double a) ++{ ++ double two52 = 0x10000000000000LL; ++ ++ if (__builtin_expect ((__builtin_fabs (a) < two52), 1)) ++ { ++ if (__builtin_expect ((a > 0.0), 1)) ++ { ++ a += two52; ++ a -= two52; ++ } ++ else if (__builtin_expect ((a < 0.0), 1)) ++ { ++ a = two52 - a; ++ a = -(a - two52); ++ } ++ } ++ return a; ++} +--- glibc-20060306T1239/sysdeps/ieee754/ldbl-128ibm/s_ceill.c 31 Jan 2006 18:56:23 -0000 1.2 ++++ glibc-20060306T1239-fedora/sysdeps/ieee754/ldbl-128ibm/s_ceill.c 7 Mar 2006 08:24:12 -0000 1.1.2.3 +@@ -19,7 +19,7 @@ + 02111-1307 USA. */ + + #include +-#include ++#include + #include + #include + #include +@@ -34,87 +34,58 @@ __ceill (x) + long double x; + #endif + { +- static const double TWO52 = 4503599627370496.0L; +- int mode = fegetround(); +- union ibm_extended_long_double u; ++ double xh, xl, hi, lo; + +- u.d = x; ++ ldbl_unpack (x, &xh, &xl); + +- if (fabs (u.dd[0]) < TWO52) ++ /* Return Inf, Nan, +/-0 unchanged. */ ++ if (__builtin_expect (xh != 0.0 ++ && __builtin_isless (__builtin_fabs (xh), ++ __builtin_inf ()), 1)) + { +- double high = u.dd[0]; +- fesetround(FE_UPWARD); +- 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; +- } +- u.dd[0] = high; +- u.dd[1] = 0.0; +- fesetround(mode); +- } +- else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) +- { +- double high, low; +- /* 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. */ +- if (u.dd[0] > 0.0) +- { +- if (u.dd[1] > 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] < 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- high = nextafter (u.dd[0], 0.0); +- low = u.dd[1] + (u.dd[0] - high); +- } +- fesetround(FE_UPWARD); +- low += TWO52; +- low -= TWO52; +- fesetround(mode); +- } +- else if (u.dd[0] < 0.0) +- { +- if (u.dd[1] < 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] > 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- high = nextafter (u.dd[0], 0.0); +- low = u.dd[1] + (u.dd[0] - high); +- } +- fesetround(FE_UPWARD); +- low -= TWO52; +- low += TWO52; +- fesetround(mode); +- } +- u.dd[0] = high + low; +- u.dd[1] = high - u.dd[0] + low; ++ double orig_xh; ++ int save_round = fegetround (); ++ ++ /* Long double arithmetic, including the canonicalisation below, ++ only works in round-to-nearest mode. */ ++ fesetround (FE_TONEAREST); ++ ++ /* Convert the high double to integer. */ ++ orig_xh = xh; ++ hi = ldbl_nearbyint (xh); ++ ++ /* Subtract integral high part from the value. */ ++ xh -= hi; ++ ldbl_canonicalize (&xh, &xl); ++ ++ /* Now convert the low double, adjusted for any remainder from the ++ high double. */ ++ lo = ldbl_nearbyint (xh); ++ ++ /* Adjust the result when the remainder is non-zero. nearbyint ++ rounds values to the nearest integer, and values halfway ++ between integers to the nearest even integer. ceill must ++ round towards +Inf. */ ++ xh -= lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ if (xh > 0.0 || (xh == 0.0 && xl > 0.0)) ++ lo += 1.0; ++ ++ /* Ensure the final value is canonical. In certain cases, ++ rounding causes hi,lo calculated so far to be non-canonical. */ ++ xh = hi; ++ xl = lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ /* Ensure we return -0 rather than +0 when appropriate. */ ++ if (orig_xh < 0.0) ++ xh = -__builtin_fabs (xh); ++ ++ fesetround (save_round); + } + +- return u.d; ++ return ldbl_pack (xh, xl); + } + + long_double_symbol (libm, __ceill, ceill); +--- glibc-20060306T1239/sysdeps/ieee754/ldbl-128ibm/s_floorl.c 31 Jan 2006 18:56:23 -0000 1.2 ++++ glibc-20060306T1239-fedora/sysdeps/ieee754/ldbl-128ibm/s_floorl.c 7 Mar 2006 08:24:12 -0000 1.1.2.3 +@@ -19,7 +19,7 @@ + 02111-1307 USA. */ + + #include +-#include ++#include + #include + #include + #include +@@ -34,86 +34,52 @@ __floorl (x) + long double x; + #endif + { +- static const double TWO52 = 4503599627370496.0L; +- int mode = fegetround(); +- union ibm_extended_long_double u; ++ double xh, xl, hi, lo; + +- u.d = x; ++ ldbl_unpack (x, &xh, &xl); + +- if (fabs (u.dd[0]) < TWO52) ++ /* Return Inf, Nan, +/-0 unchanged. */ ++ if (__builtin_expect (xh != 0.0 ++ && __builtin_isless (__builtin_fabs (xh), ++ __builtin_inf ()), 1)) + { +- double high = u.dd[0]; +- fesetround(FE_DOWNWARD); +- 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; +- } +- u.dd[0] = high; +- u.dd[1] = 0.0; +- fesetround(mode); +- } +- else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) +- { +- double high, low; +- /* 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. */ +- if (u.dd[0] > 0.0) +- { +- if (u.dd[1] > 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] < 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- high = nextafter (u.dd[0], 0.0); +- low = u.dd[1] + (u.dd[0] - high); +- } +- fesetround(FE_DOWNWARD); +- low += TWO52; +- low -= TWO52; +- } +- else if (u.dd[0] < 0.0) +- { +- if (u.dd[1] < 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] > 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- high = nextafter (u.dd[0], 0.0); +- low = u.dd[1] + (u.dd[0] - high); +- } +- fesetround(FE_DOWNWARD); +- low -= TWO52; +- low += TWO52; +- } +- fesetround(mode); +- u.dd[0] = high + low; +- u.dd[1] = high - u.dd[0] + low; ++ int save_round = fegetround (); ++ ++ /* Long double arithmetic, including the canonicalisation below, ++ only works in round-to-nearest mode. */ ++ fesetround (FE_TONEAREST); ++ ++ /* Convert the high double to integer. */ ++ hi = ldbl_nearbyint (xh); ++ ++ /* Subtract integral high part from the value. */ ++ xh -= hi; ++ ldbl_canonicalize (&xh, &xl); ++ ++ /* Now convert the low double, adjusted for any remainder from the ++ high double. */ ++ lo = ldbl_nearbyint (xh); ++ ++ /* Adjust the result when the remainder is non-zero. nearbyint ++ rounds values to the nearest integer, and values halfway ++ between integers to the nearest even integer. floorl must ++ round towards -Inf. */ ++ xh -= lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ if (xh < 0.0 || (xh == 0.0 && xl < 0.0)) ++ lo += -1.0; ++ ++ /* Ensure the final value is canonical. In certain cases, ++ rounding causes hi,lo calculated so far to be non-canonical. */ ++ xh = hi; ++ xl = lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ fesetround (save_round); + } + +- return u.d; ++ return ldbl_pack (xh, xl); + } + + long_double_symbol (libm, __floorl, floorl); +--- glibc-20060306T1239/sysdeps/ieee754/ldbl-128ibm/s_rintl.c 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20060306T1239-fedora/sysdeps/ieee754/ldbl-128ibm/s_rintl.c 7 Mar 2006 08:24:12 -0000 1.1.2.2 +@@ -22,6 +22,7 @@ + when it's coded in C. */ + + #include ++#include + #include + #include + #include +@@ -36,84 +37,83 @@ __rintl (x) + long double x; + #endif + { +- static const long double TWO52 = 4503599627370496.0L; +- union ibm_extended_long_double u; +- u.d = x; ++ double xh, xl, hi, lo; + +- if (fabs (u.dd[0]) < TWO52) +- { +- double high = u.dd[0]; +- 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; +- } +- u.dd[0] = high; +- u.dd[1] = 0.0; +- } +- else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) ++ ldbl_unpack (x, &xh, &xl); ++ ++ /* Return Inf, Nan, +/-0 unchanged. */ ++ if (__builtin_expect (xh != 0.0 ++ && __builtin_isless (__builtin_fabs (xh), ++ __builtin_inf ()), 1)) + { +- double high, low, 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. */ +- if (u.dd[0] > 0.0) +- { +- if (u.dd[1] > 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] < 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- +- tau = nextafter (u.dd[0], 0.0); +- tau = (u.dd[0] - tau) * 2.0; +- high = u.dd[0] - tau; +- low = u.dd[1] + tau; +- } +- low += TWO52; +- low -= TWO52; +- } +- else if (u.dd[0] < 0.0) ++ double orig_xh; ++ int save_round = fegetround (); ++ ++ /* Long double arithmetic, including the canonicalisation below, ++ only works in round-to-nearest mode. */ ++ fesetround (FE_TONEAREST); ++ ++ /* Convert the high double to integer. */ ++ orig_xh = xh; ++ hi = ldbl_nearbyint (xh); ++ ++ /* Subtract integral high part from the value. If the low double ++ happens to be exactly 0.5 or -0.5, you might think that this ++ subtraction could result in an incorrect conversion. For ++ instance, subtracting an odd number would cause this function ++ to round in the wrong direction. However, if we have a ++ canonical long double with the low double 0.5 or -0.5, then the ++ high double must be even. */ ++ xh -= hi; ++ ldbl_canonicalize (&xh, &xl); ++ ++ /* Now convert the low double, adjusted for any remainder from the ++ high double. */ ++ lo = ldbl_nearbyint (xh); ++ ++ xh -= lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ switch (save_round) + { +- if (u.dd[1] < 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] > 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- tau = nextafter (u.dd[0], 0.0); +- tau = (u.dd[0] - tau) * 2.0; +- high = u.dd[0] - tau; +- low = u.dd[1] + tau; +- } +- low = TWO52 - low; +- low = -(low - TWO52); ++ case FE_TONEAREST: ++ if (xl > 0.0 && xh == 0.5) ++ lo += 1.0; ++ else if (xl < 0.0 && -xh == 0.5) ++ lo -= 1.0; ++ break; ++ ++ case FE_TOWARDZERO: ++ if (orig_xh < 0.0) ++ goto do_up; ++ /* Fall thru */ ++ ++ case FE_DOWNWARD: ++ if (xh < 0.0 || (xh == 0.0 && xl < 0.0)) ++ lo -= 1.0; ++ break; ++ ++ case FE_UPWARD: ++ do_up: ++ if (xh > 0.0 || (xh == 0.0 && xl > 0.0)) ++ lo += 1.0; ++ break; + } +- u.dd[0] = high + low; +- u.dd[1] = high - u.dd[0] + low; ++ ++ /* Ensure the final value is canonical. In certain cases, ++ rounding causes hi,lo calculated so far to be non-canonical. */ ++ xh = hi; ++ xl = lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ /* Ensure we return -0 rather than +0 when appropriate. */ ++ if (orig_xh < 0.0) ++ xh = -__builtin_fabs (xh); ++ ++ fesetround (save_round); + } + +- return u.d; ++ return ldbl_pack (xh, xl); + } + + long_double_symbol (libm, __rintl, rintl); +--- glibc-20060306T1239/sysdeps/ieee754/ldbl-128ibm/s_roundl.c 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20060306T1239-fedora/sysdeps/ieee754/ldbl-128ibm/s_roundl.c 7 Mar 2006 08:24:12 -0000 1.1.2.2 +@@ -22,7 +22,7 @@ + when it's coded in C. */ + + #include +-#include ++#include + #include + #include + #include +@@ -37,84 +37,62 @@ __roundl (x) + long double x; + #endif + { +- static const double TWO52 = 4503599627370496.0; +- static const double HALF = 0.5; +- int mode = fegetround(); +- union ibm_extended_long_double u; +- u.d = x; +- +- if (fabs (u.dd[0]) < TWO52) +- { +- fesetround(FE_TOWARDZERO); +- if (u.dd[0] > 0.0) +- { +- u.dd[0] += HALF; +- u.dd[0] += TWO52; +- u.dd[0] -= TWO52; +- } +- else if (u.dd[0] < 0.0) +- { +- u.dd[0] = TWO52 - (u.dd[0] - HALF); +- u.dd[0] = -(u.dd[0] - TWO52); +- } +- u.dd[1] = 0.0; +- fesetround(mode); +- } +- else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) ++ double xh, xl, hi, lo; ++ ++ ldbl_unpack (x, &xh, &xl); ++ ++ /* Return Inf, Nan, +/-0 unchanged. */ ++ if (__builtin_expect (xh != 0.0 ++ && __builtin_isless (__builtin_fabs (xh), ++ __builtin_inf ()), 1)) + { +- double high, low; +- /* 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. */ +- if (u.dd[0] > 0.0) ++ double orig_xh; ++ int save_round = fegetround (); ++ ++ /* Long double arithmetic, including the canonicalisation below, ++ only works in round-to-nearest mode. */ ++ fesetround (FE_TONEAREST); ++ ++ /* Convert the high double to integer. */ ++ orig_xh = xh; ++ hi = ldbl_nearbyint (xh); ++ ++ /* Subtract integral high part from the value. */ ++ xh -= hi; ++ ldbl_canonicalize (&xh, &xl); ++ ++ /* Now convert the low double, adjusted for any remainder from the ++ high double. */ ++ lo = ldbl_nearbyint (xh); ++ ++ /* Adjust the result when the remainder is exactly 0.5. nearbyint ++ rounds values halfway between integers to the nearest even ++ integer. roundl must round away from zero. ++ Also correct cases where nearbyint returns an incorrect value ++ for LO. */ ++ xh -= lo; ++ ldbl_canonicalize (&xh, &xl); ++ if (xh == 0.5) + { +- if (u.dd[1] > 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] < 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- high = nextafter (u.dd[0], 0.0); +- low = u.dd[1] + (u.dd[0] - high); +- } +- fesetround(FE_TOWARDZERO); +- low += HALF; +- low += TWO52; +- low -= TWO52; ++ if (xl > 0.0 || (xl == 0.0 && orig_xh > 0.0)) ++ lo += 1.0; + } +- else if (u.dd[0] < 0.0) ++ else if (-xh == 0.5) + { +- if (u.dd[1] < 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] > 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- high = nextafter (u.dd[0], 0.0); +- low = u.dd[1] + (u.dd[0] - high); +- } +- fesetround(FE_TOWARDZERO); +- low -= HALF; +- low = TWO52 - low; +- low = -(low - TWO52); ++ if (xl < 0.0 || (xl == 0.0 && orig_xh < 0.0)) ++ lo -= 1.0; + } +- fesetround(mode); +- u.dd[0] = high + low; +- u.dd[1] = high - u.dd[0] + low; ++ ++ /* Ensure the final value is canonical. In certain cases, ++ rounding causes hi,lo calculated so far to be non-canonical. */ ++ xh = hi; ++ xl = lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ fesetround (save_round); + } +- return u.d; ++ ++ return ldbl_pack (xh, xl); + } + + long_double_symbol (libm, __roundl, roundl); +--- glibc-20060306T1239/sysdeps/ieee754/ldbl-128ibm/s_truncl.c 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20060306T1239-fedora/sysdeps/ieee754/ldbl-128ibm/s_truncl.c 7 Mar 2006 08:24:12 -0000 1.1.2.2 +@@ -22,7 +22,7 @@ + when it's coded in C. */ + + #include +-#include ++#include + #include + #include + #include +@@ -37,83 +37,66 @@ __truncl (x) + long double x; + #endif + { +- static const double TWO52 = 4503599627370496.0L; +- int mode = fegetround(); +- union ibm_extended_long_double u; +- +- u.d = x; +- +- if (fabs (u.dd[0]) < TWO52) +- { +- fesetround(FE_TOWARDZERO); +- if (u.dd[0] > 0.0) +- { +- u.dd[0] += TWO52; +- u.dd[0] -= TWO52; +- } +- else if (u.dd[0] < 0.0) +- { +- u.dd[0] = TWO52 - u.dd[0]; +- u.dd[0] = -(u.dd[0] - TWO52); +- } +- u.dd[1] = 0.0; +- fesetround(mode); +- } +- else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) ++ double xh, xl, hi, lo; ++ ++ ldbl_unpack (x, &xh, &xl); ++ ++ /* Return Inf, Nan, +/-0 unchanged. */ ++ if (__builtin_expect (xh != 0.0 ++ && __builtin_isless (__builtin_fabs (xh), ++ __builtin_inf ()), 1)) + { +- double high, low; +- /* 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. */ +- if (u.dd[0] > 0.0) ++ double orig_xh; ++ int save_round = fegetround (); ++ ++ /* Long double arithmetic, including the canonicalisation below, ++ only works in round-to-nearest mode. */ ++ fesetround (FE_TONEAREST); ++ ++ /* Convert the high double to integer. */ ++ orig_xh = xh; ++ hi = ldbl_nearbyint (xh); ++ ++ /* Subtract integral high part from the value. */ ++ xh -= hi; ++ ldbl_canonicalize (&xh, &xl); ++ ++ /* Now convert the low double, adjusted for any remainder from the ++ high double. */ ++ lo = ldbl_nearbyint (xh); ++ ++ /* Adjust the result when the remainder is non-zero. nearbyint ++ rounds values to the nearest integer, and values halfway ++ between integers to the nearest even integer. floorl must ++ round towards -Inf. */ ++ xh -= lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ if (orig_xh < 0.0) + { +- if (u.dd[1] > 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] < 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- high = nextafter (u.dd[0], 0.0); +- low = u.dd[1] + (u.dd[0] - high); +- } +- fesetround(FE_TOWARDZERO); +- low += TWO52; +- low -= TWO52; +- fesetround(mode); ++ if (xh > 0.0 || (xh == 0.0 && xl > 0.0)) ++ lo += 1.0; + } +- else if (u.dd[0] < 0.0) ++ else + { +- if (u.dd[1] < 0.0) +- { +- /* If the high/low doubles are the same sign then simply +- round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; +- } +- else if (u.dd[1] > 0.0) +- { +- /* Else the high double is pre rounded and we need to +- adjust for that. */ +- high = nextafter (u.dd[0], 0.0); +- low = u.dd[1] + (u.dd[0] - high); +- } +- fesetround(FE_TOWARDZERO); +- low = TWO52 - low; +- low = -(low - TWO52); +- fesetround(mode); ++ if (xh < 0.0 || (xh == 0.0 && xl < 0.0)) ++ lo -= 1.0; + } +- u.dd[0] = high + low; +- u.dd[1] = high - u.dd[0] + low; ++ ++ /* Ensure the final value is canonical. In certain cases, ++ rounding causes hi,lo calculated so far to be non-canonical. */ ++ xh = hi; ++ xl = lo; ++ ldbl_canonicalize (&xh, &xl); ++ ++ /* Ensure we return -0 rather than +0 when appropriate. */ ++ if (orig_xh < 0.0) ++ xh = -__builtin_fabs (xh); ++ ++ fesetround (save_round); + } + +- return u.d; ++ return ldbl_pack (xh, xl); + } + + long_double_symbol (libm, __truncl, truncl); +--- glibc-20060306T1239/sysdeps/powerpc/fpu/fegetround.c 6 Jul 2001 04:56:02 -0000 1.2 ++++ glibc-20060306T1239-fedora/sysdeps/powerpc/fpu/fegetround.c 7 Mar 2006 08:24:12 -0000 1.2.4.1 +@@ -23,7 +23,5 @@ + int + fegetround (void) + { +- int result; +- asm ("mcrfs 7,7 ; mfcr %0" : "=r"(result) : : "cr7"); \ +- return result & 3; ++ return __fegetround(); + } +--- glibc-20060306T1239/sysdeps/powerpc/fpu/fenv_libc.h 6 Jul 2001 04:56:02 -0000 1.2 ++++ glibc-20060306T1239-fedora/sysdeps/powerpc/fpu/fenv_libc.h 7 Mar 2006 08:24:12 -0000 1.2.4.1 +@@ -1,5 +1,5 @@ + /* Internal libc stuff for floating point environment routines. +- Copyright (C) 1997 Free Software Foundation, Inc. ++ Copyright (C) 1997, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -54,6 +54,41 @@ typedef union + unsigned int l[2]; + } fenv_union_t; + ++ ++static inline int ++__fegetround (void) ++{ ++ int result; ++ asm volatile ("mcrfs 7,7\n\t" ++ "mfcr %0" : "=r"(result) : : "cr7"); ++ return result & 3; ++} ++#define fegetround() __fegetround() ++ ++static inline int ++__fesetround (int round) ++{ ++ if ((unsigned int) round < 2) ++ { ++ asm volatile ("mtfsb0 30"); ++ if ((unsigned int) round == 0) ++ asm volatile ("mtfsb0 31"); ++ else ++ asm volatile ("mtfsb1 31"); ++ } ++ else ++ { ++ asm volatile ("mtfsb1 30"); ++ if ((unsigned int) round == 2) ++ asm volatile ("mtfsb0 31"); ++ else ++ asm volatile ("mtfsb1 31"); ++ } ++ ++ return 0; ++} ++#define fesetround(mode) __fesetround(mode) ++ + /* Definitions of all the FPSCR bit numbers */ + enum { + FPSCR_FX = 0, /* exception summary */ +--- glibc-20060306T1239/sysdeps/powerpc/fpu/fesetround.c 8 Jul 2005 18:52:46 -0000 1.4 ++++ glibc-20060306T1239-fedora/sysdeps/powerpc/fpu/fesetround.c 7 Mar 2006 08:24:12 -0000 1.3.4.2 +@@ -1,5 +1,5 @@ + /* Set current rounding direction. +- Copyright (C) 1997, 2005 Free Software Foundation, Inc. ++ Copyright (C) 1997, 2005, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + +@@ -20,23 +20,13 @@ + + #include + ++#undef fesetround + int + fesetround (int round) + { +- fenv_union_t u; +- + if ((unsigned int) round > 3) + return 1; +- +- /* Get the current state. */ +- u.fenv = fegetenv_register (); +- +- /* Set the relevant bits. */ +- u.l[1] = (u.l[1] & ~3) | (round & 3); +- +- /* Put the new state in effect. */ +- fesetenv_register (u.fenv); +- +- return 0; ++ else ++ return __fesetround(round); + } + libm_hidden_def (fesetround) +--- glibc-20060306T1239/sysdeps/powerpc/fpu/math_ldbl.h 1 Jan 1970 00:00:00 -0000 ++++ glibc-20060306T1239-fedora/sysdeps/powerpc/fpu/math_ldbl.h 7 Mar 2006 08:24:12 -0000 1.1.2.1 +@@ -0,0 +1,189 @@ ++#ifndef _MATH_PRIVATE_H_ ++#error "Never use directly; include instead." ++#endif ++ ++#include ++#include ++ ++static inline void ++ldbl_extract_mantissa (int64_t *hi64, u_int64_t *lo64, int *exp, long double x) ++{ ++ /* We have 105 bits of mantissa plus one implicit digit. Since ++ 106 bits are representable we use the first implicit digit for ++ the number before the decimal point and the second implicit bit ++ as bit 53 of the mantissa. */ ++ unsigned long long hi, lo; ++ int ediff; ++ union ibm_extended_long_double eldbl; ++ eldbl.d = x; ++ *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ ++ lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; ++ hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; ++ /* If the lower double is not a denomal or zero then set the hidden ++ 53rd bit. */ ++ if (eldbl.ieee.exponent2 > 0x001) ++ { ++ lo |= (1ULL << 52); ++ lo = lo << 7; /* pre-shift lo to match ieee854. */ ++ /* The lower double is normalized separately from the upper. We ++ may need to adjust the lower manitissa to reflect this. */ ++ ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; ++ if (ediff > 53) ++ lo = lo >> (ediff-53); ++ } ++ hi |= (1ULL << 52); ++ ++ if ((eldbl.ieee.negative != eldbl.ieee.negative2) ++ && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL))) ++ { ++ hi--; ++ lo = (1ULL << 60) - lo; ++ if (hi < (1ULL << 52)) ++ { ++ /* we have a borrow from the hidden bit, so shift left 1. */ ++ hi = (hi << 1) | (lo >> 59); ++ lo = 0xfffffffffffffffLL & (lo << 1); ++ *exp = *exp - 1; ++ } ++ } ++ *lo64 = (hi << 60) | lo; ++ *hi64 = hi >> 4; ++} ++ ++static inline long double ++ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) ++{ ++ union ibm_extended_long_double u; ++ unsigned long hidden2, lzcount; ++ unsigned long long hi, lo; ++ ++ u.ieee.negative = sign; ++ u.ieee.negative2 = sign; ++ u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ /* Expect 113 bits (112 bits + hidden) right justified in two longs. ++ The low order 53 bits (52 + hidden) go into the lower double */ ++ lo = (lo64 >> 7)& ((1ULL << 53) - 1); ++ hidden2 = (lo64 >> 59) & 1ULL; ++ /* The high order 53 bits (52 + hidden) go into the upper double */ ++ hi = (lo64 >> 60) & ((1ULL << 11) - 1); ++ hi |= (hi64 << 4); ++ ++ if (lo != 0LL) ++ { ++ /* hidden2 bit of low double controls rounding of the high double. ++ If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) ++ plus change the sign of the low double to compensate. */ ++ if (hidden2) ++ { ++ hi++; ++ u.ieee.negative2 = !sign; ++ lo = (1ULL << 53) - lo; ++ } ++ /* The hidden bit of the lo mantissa is zero so we need to ++ normalize the it for the low double. Shift it left until the ++ hidden bit is '1' then adjust the 2nd exponent accordingly. */ ++ ++ if (sizeof (lo) == sizeof (long)) ++ lzcount = __builtin_clzl (lo); ++ else if ((lo >> 32) != 0) ++ lzcount = __builtin_clzl ((long) (lo >> 32)); ++ else ++ lzcount = __builtin_clzl ((long) lo) + 32; ++ lzcount = lzcount - 11; ++ if (lzcount > 0) ++ { ++ int expnt2 = u.ieee.exponent2 - lzcount; ++ if (expnt2 >= 1) ++ { ++ /* Not denormal. Normalize and set low exponent. */ ++ lo = lo << lzcount; ++ u.ieee.exponent2 = expnt2; ++ } ++ else ++ { ++ /* Is denormal. */ ++ lo = lo << (lzcount + expnt2); ++ u.ieee.exponent2 = 0; ++ } ++ } ++ } ++ else ++ { ++ u.ieee.negative2 = 0; ++ u.ieee.exponent2 = 0; ++ } ++ ++ u.ieee.mantissa3 = lo & ((1ULL << 32) - 1); ++ u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1); ++ u.ieee.mantissa1 = hi & ((1ULL << 32) - 1); ++ u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); ++ return u.d; ++} ++ ++/* gcc generates disgusting code to pack and unpack long doubles. ++ This tells gcc that pack/unpack is really a nop. We use fr1/fr2 ++ because those are the regs used to pass/return a single ++ long double arg. */ ++static inline long double ++ldbl_pack (double a, double aa) ++{ ++ register long double x __asm__ ("fr1"); ++ register double xh __asm__ ("fr1"); ++ register double xl __asm__ ("fr2"); ++ xh = a; ++ xl = aa; ++ __asm__ ("" : "=f" (x) : "f" (xh), "f" (xl)); ++ return x; ++} ++ ++static inline void ++ldbl_unpack (long double l, double *a, double *aa) ++{ ++ register long double x __asm__ ("fr1"); ++ register double xh __asm__ ("fr1"); ++ register double xl __asm__ ("fr2"); ++ x = l; ++ __asm__ ("" : "=f" (xh), "=f" (xl) : "f" (x)); ++ *a = xh; ++ *aa = xl; ++} ++ ++ ++/* Convert a finite long double to canonical form. ++ Does not handle +/-Inf properly. */ ++static inline void ++ldbl_canonicalize (double *a, double *aa) ++{ ++ double xh, xl; ++ ++ xh = *a + *aa; ++ xl = (*a - xh) + *aa; ++ *a = xh; ++ *aa = xl; ++} ++ ++/* Simple inline nearbyint (double) function . ++ Only works in the default rounding mode ++ but is useful in long double rounding functions. */ ++static inline double ++ldbl_nearbyint (double a) ++{ ++ double two52 = 0x10000000000000LL; ++ ++ if (__builtin_expect ((__builtin_fabs (a) < two52), 1)) ++ { ++ if (__builtin_expect ((a > 0.0), 1)) ++ { ++ a += two52; ++ a -= two52; ++ } ++ else if (__builtin_expect ((a < 0.0), 1)) ++ { ++ a = two52 - a; ++ a = -(a - two52); ++ } ++ } ++ return a; ++} --- glibc-20060306T1239/sysdeps/unix/nice.c 28 Sep 2002 19:13:13 -0000 1.6 +++ glibc-20060306T1239-fedora/sysdeps/unix/nice.c 22 Sep 2004 21:21:08 -0000 1.6.2.1 @@ -41,7 +41,12 @@ nice (int incr) diff --git a/glibc.spec b/glibc.spec index 8f9803b..aa4fe4e 100644 --- a/glibc.spec +++ b/glibc.spec @@ -3,7 +3,7 @@ %define glibcsrcdir glibc-20060306T1239 %define glibc_release_tarballs 0 %define glibcversion 2.4 -%define glibcrelease 1 +%define glibcrelease 2 %define auxarches i586 i686 athlon sparcv9 alphaev6 %define prelinkarches noarch %define xenarches i686 athlon @@ -56,6 +56,15 @@ BuildPreReq: gcc >= 3.2 Conflicts: rpm <= 4.0-0.65 Conflicts: glibc-devel < 2.2.3 Conflicts: gcc4 <= 4.0.0-0.6 +%ifarch x86_64 +# Need gdb that understands DW_CFA_val_expression +Conflicts: gdb < 6.3.0.0-1.111 +%endif +%ifarch %{ix86} +# Need gdb that understands DW_CFA_val_expression and handles two frames +# with the same entry point and CFA, but different PC +Conflicts: gdb < 6.3.0.0-1.115 +%endif # Earlier shadow-utils packages had too restrictive permissions on # /etc/default Conflicts: shadow-utils < 2:4.0.3-20 @@ -694,10 +703,10 @@ touch locale/programs/*-kw.h GCC=gcc GXX=g++ %ifarch %{ix86} -BuildFlags="-march=%{_target_cpu}" +BuildFlags="-march=%{_target_cpu} -DUSE_CFA_VAL_EXPRESSION" %endif %ifarch i686 -BuildFlags="-march=i686 -mtune=pentium4" +BuildFlags="-march=i686 -mtune=pentium4 -DUSE_CFA_VAL_EXPRESSION" %endif %ifarch x86_64 BuildFlags="-DUSE_CFA_VAL_EXPRESSION" @@ -1340,6 +1349,10 @@ rm -f *.filelist* %endif %changelog +* Tue Mar 7 2006 Jakub Jelinek 2.4-2 +- accurate unwind info for lowlevellock.h stubs on %%{ix86} +- fix ppc/ppc64 ceill, floorl, rintl, roundl and truncl (BZ#2423) + * Mon Mar 6 2006 Jakub Jelinek 2.4-1 - update from CVS - glibc 2.4 release diff --git a/sources b/sources index 694c072..a93398a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ c3bd549b42829d73aad876a10435ae73 glibc-20060306T1239.tar.bz2 -505133aab642c0cf807ddb498458c1c4 glibc-fedora-20060306T1239.tar.bz2 +ad9e233a573f227fb9efd93e2f387fdf glibc-fedora-20060306T1239.tar.bz2