about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog172
-rw-r--r--elf/Makefile17
-rw-r--r--elf/dl-load.c25
-rw-r--r--elf/rtld.c40
-rw-r--r--elf/tst-audit2.c50
-rw-r--r--elf/tst-leaks1.c25
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in8
-rwxr-xr-xmath/gen-libm-test.pl11
-rw-r--r--math/libm-test.inc1079
-rw-r--r--nis/nss_nisplus/nisplus-alias.c5
-rw-r--r--nis/nss_nisplus/nisplus-ethers.c4
-rw-r--r--nis/nss_nisplus/nisplus-grp.c5
-rw-r--r--nis/nss_nisplus/nisplus-hosts.c4
-rw-r--r--nis/nss_nisplus/nisplus-network.c4
-rw-r--r--nis/nss_nisplus/nisplus-proto.c5
-rw-r--r--nis/nss_nisplus/nisplus-pwd.c5
-rw-r--r--nis/nss_nisplus/nisplus-rpc.c5
-rw-r--r--nis/nss_nisplus/nisplus-service.c5
-rw-r--r--nptl/ChangeLog32
-rw-r--r--nptl/Makefile2
-rw-r--r--nptl/allocatestack.c24
-rw-r--r--nptl/descr.h45
-rw-r--r--nptl/init.c28
-rw-r--r--nptl/pthreadP.h31
-rw-r--r--nptl/pthread_create.c46
-rw-r--r--nptl/pthread_mutex_consistent.c2
-rw-r--r--nptl/pthread_mutex_destroy.c12
-rw-r--r--nptl/pthread_mutex_init.c17
-rw-r--r--nptl/pthread_mutex_lock.c50
-rw-r--r--nptl/pthread_mutex_timedlock.c44
-rw-r--r--nptl/pthread_mutex_trylock.c51
-rw-r--r--nptl/pthread_mutex_unlock.c16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h4
-rw-r--r--nptl/tst-robust8.c264
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_llrintl.c168
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_llroundl.c158
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/fprsave.S18
-rw-r--r--sysdeps/powerpc/powerpc32/gprsave0.S19
-rw-r--r--sysdeps/powerpc/powerpc64/dl-trampoline.S2
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_llrintl.S94
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_llroundl.S167
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_lrintl.S2
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_lroundl.S2
-rw-r--r--sysdeps/powerpc/powerpc64/memcpy.S3
-rw-r--r--sysdeps/sparc/sparc32/bits/atomic.h2
-rw-r--r--sysdeps/sparc/sparc32/sparcv9/bits/atomic.h4
-rw-r--r--sysdeps/sparc/sparc64/bits/atomic.h6
-rw-r--r--sysdeps/unix/sysv/linux/alpha/getcontext.S4
-rw-r--r--sysdeps/unix/sysv/linux/bits/poll.h6
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h39
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S4
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S4
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S5
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/poll.h9
-rw-r--r--wcsmbs/wchar.h14
58 files changed, 2018 insertions, 855 deletions
diff --git a/ChangeLog b/ChangeLog
index 8943e8ccd7..1efd878662 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,139 @@
+2006-03-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/kernel-features.h: Remove support for
+	architectures which moved to ports.
+
+	* sysdeps/unix/sysv/linux/kernel-features.h: Add
+	__ASSUME_SET_ROBUST_LIST.
+
+2006-03-27  Jakub Jelinek  <jakub@redhat.com>
+
+	* wcsmbs/wchar.h (btowc, wctob): Don't optimize in C++.
+
+2006-03-24  David S. Miller  <davem@sunset.davemloft.net>
+
+	* sysdeps/sparc/sparc32/bits/atomic.h
+	(__v9_compare_and_exchange_val_32_acq): Add "memory" clobber.
+	* sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
+	(__arch_compare_and_exchange_val_32_acq, atomic_exchange_acq):
+	Likewise.
+	* sysdeps/sparc/sparc64/bits/atomic.h
+	(__arch_compare_and_exchange_val_32_acq,
+	__arch_compare_and_exchange_val_64_acq, atomic_exchange_acq): Likewise.
+
+2006-03-24  Jakub Jelinek  <jakub@redhat.com>
+
+	* nis/nss_nisplus/nisplus-proto.c (_nss_create_tablename): Check the
+	return value of malloc rather than the static var again.
+	* nis/nss_nisplus/nisplus-grp.c (_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-network.c (_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-ethers.c (_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-rpc.c (_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-service.c (_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-hosts.c (_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-alias.c (_nss_create_tablename): Likewise.
+	* nis/nss_nisplus/nisplus-pwd.c (_nss_pwd_create_tablename): Likewise.
+
+2006-03-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/bits/poll.h: Add POLLMSG,
+	POLLREMOVE, and POLLRDHUP.
+	* sysdeps/unix/sysv/linux/bits/poll.h: Add POLLREMOVE and POLLRDHUP.
+
+2006-03-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/sparc/bits/fcntl.h: Define
+	LINUX_FADV_ASYNC_WRITE and LINUX_FADV_WRITE_WAIT.
+	* sysdeps/unix/sysv/linux/ia64/bits/fcntl.h: Likewise.
+	* sysdeps/unix/sysv/linux/sh/bits/fcntl.h: Likewise.
+	* sysdeps/unix/sysv/linux/i386/bits/fcntl.h: Likewise.
+	* sysdeps/unix/sysv/linux/s390/bits/fcntl.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h: Likewise.
+	* sysdeps/unix/sysv/linux/alpha/bits/fcntl.h: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h: Likewise.
+
+2006-03-17  Roland McGrath  <roland@redhat.com>
+
+	* elf/rtld.c (dl_main): Run final self-relocation after setting up TLS.
+	From Alexandre Oliva <aoliva@redhat.com>.
+
+	* elf/tst-audit2.c: New file.
+	* elf/Makefile (tests): Add it.
+	($(objpfx)tst-audit2.out): New target.
+	(tst-audit2-ENV): New variable.
+
+	* elf/tst-leaks1.c: Include <stdio.h>.
+
+2006-03-16  Roland McGrath  <roland@redhat.com>
+
+	* sysdeps/unix/sysv/linux/alpha/getcontext.S (__getcontext_x):
+	Use .set noat to quiet assembler warning.
+
+	* math/gen-libm-test.pl (parse_args): Take function name for pretty
+	output as an argument.
+	(generate_testfile): Pass it the name given in the START macro.
+
+	[BZ #2466]
+	* math/libm-test.inc (llrint_test, llround_test): Fix last change to
+	protect large-precision cases with [LDBL_MANT_DIG > 100].
+	(llrint_test_tonearest, llrint_test_towardzero): Likewise.
+	(llrint_test_downward, llrint_test_upward): Likewise.
+
+2006-03-15  Steven Munroe  <sjmunroe@us.ibm.com>
+	    Alan Modra  <amodra@bigpond.net.au>
+
+	[BZ #2466]
+	* math/libm-test.inc (llrint_test, llround_test) [TEST_LDOUBLE]:
+	Add new test values.
+	(llrint_test_tonearest, llrint_test_towardzero, llrint_test_downward,
+	llrint_test_upward): New functions.
+	(main): Call them.
+
+	* sysdeps/ieee754/ldbl-128ibm/s_llrintl.c (__llrintl): Handle
+	rounding that spans doubles in IBM long double format.
+	* sysdeps/ieee754/ldbl-128ibm/s_llroundl.c (__llroundl): Likewise.
+	* sysdeps/powerpc/powerpc64/fpu/s_llrintl.S: Removed.
+	* sysdeps/powerpc/powerpc64/fpu/s_llroundl.S: Removed.
+	* sysdeps/powerpc/powerpc64/fpu/s_lrintl.S: Removed.
+	* sysdeps/powerpc/powerpc64/fpu/s_lroundl.S: Removed.
+
+2006-03-16  Roland McGrath  <roland@redhat.com>
+
+	* wcsmbs/wchar.h (__wcstol_internal, __wcstoul_internal): Declare these
+	 only when we will use them, under [__OPTIMIZE__ && __GNUC__ >= 2].
+	(__wcstoll_internal, __wcstoull_internal_defined): Likewise.
+
+2006-03-06  Steven Munroe  <sjmunroe@us.ibm.com>
+
+	* sysdeps/powerpc/powerpc32/fpu/fprsave.S: Add cfi_offset for spilling
+	of non-volatile floating-point registers to the stack (fp14-fp31).
+	* sysdeps/powerpc/powerpc32/gprsave0.S: Add cfi_offset for spilling of
+	non-volatile general-purpose registers to the stack (gpr13-gpr31).
+	* sysdeps/powerpc/powerpc64/dl-trampoline.S: Add cfi_offset
+	for non-volatiles gpr30 - grp31 spilled to the stack.
+	* sysdeps/powerpc/powerpc64/memcpy.S: Add cfi_offset for non-volatile
+	gpr31 spill to the stack.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S:
+	Add cfi_offset for non-volatile gpr31 spill to the stack.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Add cfi_offset
+	for non-volatiles gpr28 - grp31 spilled to the stack.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S: Add
+	cfi_adjust_cfa_offset when a frame is stacked.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S:
+	(__novec_setcontext) : Add cfi_offset for non-volatile gpr31 spill
+	add LR saved to the stack.  Add cfi_adjust_cfa_offset when frame is
+	stacked.
+	(__setcontext) : Add cfi_offset for non-volatile gpr31 spill to
+	the stack.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S:
+	(__novec_swapcontext) : Add cfi_offset for non-volatile gpr31 spill
+	add LR saved to the stack.
+	(__swapcontext) : Add cfi_offset for non-volatile gpr31 spill add LR
+	saved to the stack.  Add cfi_adjust_cfa_offset when frame is stacked.
+
 2006-03-07  Jakub Jelinek  <jakub@redhat.com>
 
+	[BZ #2423]
 	* math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test,
 	round_test, trunc_test): Only run some of the new tests if
 	LDBL_MANT_DIG > 100.
@@ -7,36 +141,50 @@
 2006-03-03  Steven Munroe  <sjmunroe@us.ibm.com>
 	    Alan Modra  <amodra@bigpond.net.au>
 
-	[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/powerpc/fpu/math_ldbl.h: New file.
+
+	[BZ #2423]
+	* math/libm-test.inc [TEST_LDOUBLE] (ceil_test, floor_test, rint_test,
+	round_test, trunc_test): Add new tests.
 	* sysdeps/ieee754/ldbl-128ibm/math_ldbl.h
-	(EXTRACT_IBM_EXTENDED_MANTISSA, INSERT_IBM_EXTENDED_MANTISSA): 
-	Removed, replaced with.
+	(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.
+	ldbl_canonicalise, ldbl_nearbyint): New functions.
 	* 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.
-
+	(ldbl_extract_mantissa, ldbl_insert_mantissa): New inline functions.
 	* 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.
+	* sysdeps/powerpc/powerpc64/fpu/s_rintl.S: File removed.
+
+2004-12-09  Randolph Chung  <tausq@debian.org>
+
+	* sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_UTIMES): Don't
+	define for hppa, which doesn't support this syscall.
+
+2006-03-13  Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #2451]
+	* elf/dl-load.c (open_verify): Add free_name argument, if true, free
+	name before calling lose.
+	(open_path): Adjust caller.
+	(_dl_map_object): Adjust callers.  Free name_copy before calling
+	_dl_signal_error.
+	* elf/Makefile: Add rules to build and run tst-leaks1.
+	* elf/tst-leaks1.c: New test.
 
 2006-03-06  Roland McGrath  <roland@redhat.com>
 
diff --git a/elf/Makefile b/elf/Makefile
index 791341758e..3b4ef26d45 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -91,7 +91,7 @@ distribute	:= rtld-Rules \
 		   order2mod1.c order2mod2.c order2mod3.c order2mod4.c \
 		   tst-stackguard1.c tst-stackguard1-static.c \
 		   tst-array5.c tst-array5-static.c tst-array5dep.c \
-		   tst-array5.exp
+		   tst-array5.exp tst-leaks1.c
 
 CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
@@ -139,7 +139,7 @@ vpath %.c ../locale/programs
 endif
 endif
 
-tests = tst-tls1 tst-tls2 tst-tls9
+tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1
 ifeq (yes,$(have-initfini-array))
 tests += tst-array1 tst-array2 tst-array3 tst-array4 tst-array5
 endif
@@ -168,7 +168,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
 	 tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
 	 tst-dlmodcount tst-dlopenrpath tst-deep1 \
 	 tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
-	 unload3 unload4 unload5 unload6 tst-audit1 tst-global1 order2 \
+	 unload3 unload4 unload5 unload6 tst-global1 order2 \
+	 tst-audit1 tst-audit2 \
 	 tst-stackguard1
 #	 reldep9
 test-srcs = tst-pathopt
@@ -180,6 +181,7 @@ endif
 ifeq (yesyes,$(have-fpie)$(build-shared))
 tests: $(objpfx)tst-pie1.out
 endif
+tests: $(objpfx)tst-leaks1-mem
 modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
 		testobj1_1 failobj constload2 constload3 unloadmod \
 		dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \
@@ -878,6 +880,9 @@ $(objpfx)tst-dlmopen3.out: $(objpfx)tst-dlmopen1mod.so
 $(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so
 tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
 
+$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so
+tst-audit2-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
+
 $(objpfx)tst-global1: $(libdl)
 $(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so
 
@@ -895,3 +900,9 @@ order2mod2.so-no-z-defs = yes
 
 tst-stackguard1-ARGS = --command "$(built-program-cmd) --child"
 tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child"
+
+$(objpfx)tst-leaks1: $(libdl)
+$(objpfx)tst-leaks1-mem: $(objpfx)tst-leaks1.out
+	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@
+
+tst-leaks1-ENV = MALLOC_TRACE=$(objpfx)tst-leaks1.mtrace
diff --git a/elf/dl-load.c b/elf/dl-load.c
index bba1c83ba0..088954a04f 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1,5 +1,6 @@
 /* Map in a shared object's segments from the file.
-   Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 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
@@ -1554,7 +1555,7 @@ print_search_path (struct r_search_path_elem **list,
    user might want to know about this.  */
 static int
 open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
-	     int whatcode, bool *found_other_class)
+	     int whatcode, bool *found_other_class, bool free_name)
 {
   /* This is the expected ELF header.  */
 #define ELF32_CLASS ELFCLASS32
@@ -1635,6 +1636,12 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
 	  errstring = (errval == 0
 		       ? N_("file too short") : N_("cannot read file data"));
 	call_lose:
+	  if (free_name)
+	    {
+	      char *realname = (char *) name;
+	      name = strdupa (realname);
+	      free (realname);
+	    }
 	  lose (errval, fd, name, NULL, NULL, errstring);
 	}
 
@@ -1821,7 +1828,8 @@ open_path (const char *name, size_t namelen, int preloaded,
 	  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
 	    _dl_debug_printf ("  trying file=%s\n", buf);
 
-	  fd = open_verify (buf, fbp, loader, whatcode, found_other_class);
+	  fd = open_verify (buf, fbp, loader, whatcode, found_other_class,
+			    false);
 	  if (this_dir->status[cnt] == unknown)
 	    {
 	      if (fd != -1)
@@ -2098,7 +2106,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 		{
 		  fd = open_verify (cached,
 				    &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
-				    LA_SER_CONFIG, &found_other_class);
+				    LA_SER_CONFIG, &found_other_class, false);
 		  if (__builtin_expect (fd != -1, 1))
 		    {
 		      realname = local_strdup (cached);
@@ -2136,7 +2144,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 	{
 	  fd = open_verify (realname, &fb,
 			    loader ?: GL(dl_ns)[nsid]._ns_loaded, 0,
-			    &found_other_class);
+			    &found_other_class, true);
 	  if (__builtin_expect (fd, 0) == -1)
 	    free (realname);
 	}
@@ -2166,8 +2174,11 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
 	  if ((name_copy = local_strdup (name)) == NULL
 	      || (l = _dl_new_object (name_copy, name, type, loader,
 				      mode, nsid)) == NULL)
-	    _dl_signal_error (ENOMEM, name, NULL,
-			      N_("cannot create shared object descriptor"));
+	    {
+	      free (name_copy);
+	      _dl_signal_error (ENOMEM, name, NULL,
+				N_("cannot create shared object descriptor"));
+	    }
 	  /* Signal that this is a faked entry.  */
 	  l->l_faked = 1;
 	  /* Since the descriptor is initialized with zero we do not
diff --git a/elf/rtld.c b/elf/rtld.c
index 76d129a0a0..68fe809700 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1,5 +1,5 @@
 /* Run time dynamic linker.
-   Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2004, 2005, 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
@@ -2200,7 +2200,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 #ifndef HP_TIMING_NONAVAIL
       hp_timing_t start;
       hp_timing_t stop;
-      hp_timing_t add;
 #endif
 
       /* If we are profiling we also must do lazy reloaction.  */
@@ -2255,19 +2254,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
       if (__builtin_expect (GL(dl_profile_map) != NULL, 0))
 	/* We must prepare the profiling.  */
 	_dl_start_profile ();
-
-      if (rtld_multiple_ref)
-	{
-	  /* There was an explicit ref to the dynamic linker as a shared lib.
-	     Re-relocate ourselves with user-controlled symbol definitions.  */
-	  HP_TIMING_NOW (start);
-	  /* Mark the link map as not yet relocated again.  */
-	  GL(dl_rtld_map).l_relocated = 0;
-	  _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
-	  HP_TIMING_NOW (stop);
-	  HP_TIMING_DIFF (add, start, stop);
-	  HP_TIMING_ACCUM_NT (relocate_time, add);
-	}
     }
 
 #ifndef NONTLS_INIT_TP
@@ -2296,6 +2282,30 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
   NONTLS_INIT_TP;
 #endif
 
+  if (! prelinked && rtld_multiple_ref)
+    {
+      /* There was an explicit ref to the dynamic linker as a shared lib.
+	 Re-relocate ourselves with user-controlled symbol definitions.
+
+	 We must do this after TLS initialization in case after this
+	 re-relocation, we might call a user-supplied function
+	 (e.g. calloc from _dl_relocate_object) that uses TLS data.  */
+
+#ifndef HP_TIMING_NONAVAIL
+      hp_timing_t start;
+      hp_timing_t stop;
+      hp_timing_t add;
+#endif
+
+      HP_TIMING_NOW (start);
+      /* Mark the link map as not yet relocated again.  */
+      GL(dl_rtld_map).l_relocated = 0;
+      _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
+      HP_TIMING_NOW (stop);
+      HP_TIMING_DIFF (add, start, stop);
+      HP_TIMING_ACCUM_NT (relocate_time, add);
+    }
+
 #ifdef SHARED
   /* Auditing checkpoint: we have added all objects.  */
   if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
diff --git a/elf/tst-audit2.c b/elf/tst-audit2.c
new file mode 100644
index 0000000000..fd089b6f64
--- /dev/null
+++ b/elf/tst-audit2.c
@@ -0,0 +1,50 @@
+/* Test case for early TLS initialization in dynamic linker.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE___THREAD
+# define MAGIC1 0xabcdef72
+# define MAGIC2 0xd8675309
+static __thread unsigned int magic[] = { MAGIC1, MAGIC2 };
+#endif
+
+#undef calloc
+
+/* This calloc definition will be called by the dynamic linker itself.
+   We test that it has initialized our TLS block by the time it does so.  */
+
+void *
+calloc (size_t n, size_t m)
+{
+#if HAVE___THREAD
+  if (magic[0] != MAGIC1 || magic[1] != MAGIC2)
+    {
+      printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC1, MAGIC2);
+      abort ();
+    }
+  magic[0] = MAGIC2;
+  magic[1] = MAGIC1;
+#endif
+
+  n *= m;
+  void *ptr = malloc (n);
+  if (ptr != NULL)
+    memset (ptr, '\0', n);
+  return ptr;
+}
+
+int
+main (void)
+{
+#if HAVE___THREAD
+  if (magic[1] != MAGIC1 || magic[0] != MAGIC2)
+    {
+      printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC2, MAGIC1);
+      return 1;
+    }
+#endif
+
+  return 0;
+}
diff --git a/elf/tst-leaks1.c b/elf/tst-leaks1.c
new file mode 100644
index 0000000000..36e4aee9cf
--- /dev/null
+++ b/elf/tst-leaks1.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <dlfcn.h>
+#include <mcheck.h>
+#include <stdlib.h>
+
+int
+main (void)
+{
+  mtrace ();
+
+  int ret = 0;
+  for (int i = 0; i < 10; i++)
+    {
+      void *h = dlopen (i < 5 ? "./tst-leaks1.c"
+			      : "$ORIGIN/tst-leaks1.o", RTLD_LAZY);
+      if (h != NULL)
+	{
+	  puts ("dlopen unexpectedly succeeded");
+	  ret = 1;
+	  dlclose (h);
+	}
+    }
+
+  return ret;
+}
diff --git a/fedora/branch.mk b/fedora/branch.mk
index e3f3348c17..9f35fe0f79 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-fc4
-fedora-sync-date := 2006-03-06 12:39 UTC
-fedora-sync-tag := fedora-glibc-20060306T1239
+fedora-sync-date := 2006-03-28 09:00 UTC
+fedora-sync-tag := fedora-glibc-20060328T0900
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index c3c2c0de58..987ee270cb 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 4
+%define glibcrelease 5
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define prelinkarches noarch
 %define xenarches i686 athlon
@@ -1336,6 +1336,12 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Tue Mar 28 Jakub Jelinek <jakub@redhat.com> 2.4-5
+- update from CVS
+  - pshared robust mutex support
+  - fix btowc and bwtoc in C++ (#186410)
+  - fix NIS+ (#186592)
+  - don't declare __wcsto*l_internal for non-GCC or if not -O1+ (#185667)
 - don't mention nscd failures on 2.0 kernels (#185335)
 
 * Tue Mar  7 2006 Roland McGrath <roland@redhat.com> 2.4-4
diff --git a/math/gen-libm-test.pl b/math/gen-libm-test.pl
index 26f819a884..a63f62a1cb 100755
--- a/math/gen-libm-test.pl
+++ b/math/gen-libm-test.pl
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# Copyright (C) 1999 Free Software Foundation, Inc.
+# Copyright (C) 1999, 2006 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Andreas Jaeger <aj@suse.de>, 1999.
 
@@ -234,7 +234,7 @@ sub special_functions {
 
 # Parse the arguments to TEST_x_y
 sub parse_args {
-  my ($file, $descr, $args) = @_;
+  my ($file, $descr, $fct, $args) = @_;
   my (@args, $str, $descr_args, $descr_res, @descr);
   my ($current_arg, $cline, $i);
   my ($pre, $post, @special);
@@ -248,7 +248,7 @@ sub parse_args {
 
   @args = split /,\s*/, $args;
 
-  $call = "$args[0] (";
+  $call = "$fct (";
 
   # Generate first the string that's shown to the user
   $current_arg = 1;
@@ -423,7 +423,7 @@ sub parse_args {
 sub generate_testfile {
   my ($input, $output) = @_;
   my ($lasttext);
-  my (@args, $i, $str);
+  my (@args, $i, $str, $thisfct);
 
   open INPUT, $input or die ("Can't open $input: $!");
   open OUTPUT, ">$output" or die ("Can't open $output: $!");
@@ -436,11 +436,12 @@ sub generate_testfile {
       my ($descr, $args);
       chop;
       ($descr, $args) = ($_ =~ /TEST_(\w+)\s*\((.*)\)/);
-      &parse_args (\*OUTPUT, $descr, $args);
+      &parse_args (\*OUTPUT, $descr, $thisfct, $args);
       next;
     }
     # START (function)
     if (/START/) {
+      ($thisfct) = ($_ =~ /START\s*\((.*)\)/);
       print OUTPUT "  init_max_error ();\n";
       next;
     }
diff --git a/math/libm-test.inc b/math/libm-test.inc
index b144796f2a..58ab2f5e59 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -3331,6 +3331,22 @@ llrint_test (void)
   TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
   TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
 
+# if LDBL_MANT_DIG > 100
+  TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+  TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+  TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+  TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+  TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+  TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+  TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+  TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+  TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+  TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+  TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+  TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+#endif
+
   TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
   TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
   TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
@@ -3343,6 +3359,22 @@ llrint_test (void)
   TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
   TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
 
+# if LDBL_MANT_DIG > 100
+  TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+  TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+  TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+  TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+  TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+  TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+  TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+  TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+  TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+  TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+  TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+  TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+#endif
+
   TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
   TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
   TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
@@ -3354,11 +3386,570 @@ llrint_test (void)
   TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
   TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
   TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+  TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+  TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+  TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+  TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+  TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+  TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+  TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+  TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+  TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+  TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+  TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+  TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
 #endif
 
   END (llrint);
 }
 
+static void
+llrint_test_tonearest (void)
+{
+  int save_round_mode;
+  START (llrint_tonearest);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_TONEAREST))
+    {
+      TEST_f_L (llrint, 0.0, 0);
+      TEST_f_L (llrint, minus_zero, 0);
+      TEST_f_L (llrint, 0.2L, 0);
+      TEST_f_L (llrint, -0.2L, 0);
+
+      TEST_f_L (llrint, 1.4L, 1);
+      TEST_f_L (llrint, -1.4L, -1);
+
+      TEST_f_L (llrint, 8388600.3L, 8388600);
+      TEST_f_L (llrint, -8388600.3L, -8388600);
+
+      TEST_f_l (llrint, 1071930.0008, 1071930);
+
+      /* Test boundary conditions.  */
+      /* 0x1FFFFF */
+      TEST_f_L (llrint, 2097151.0,2097151LL);
+      /* 0x800000 */
+      TEST_f_L (llrint, 8388608.0, 8388608LL);
+      /* 0x1000000 */
+      TEST_f_L (llrint, 16777216.0, 16777216LL);
+      /* 0x20000000000 */
+      TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+      /* 0x40000000000 */
+      TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+      /* 0x1000000000000 */
+      TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+      /* 0x10000000000000 */
+      TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+      /* 0x10000080000000 */
+      TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+      /* 0x20000000000000 */
+      TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+      /* 0x80000000000000 */
+      TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+      /* 0x100000000000000 */
+      TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+      /* The input can only be represented in long double.  */
+      TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL);
+      TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL);
+
+      TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
+      TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
+
+# if LDBL_MANT_DIG > 100
+      TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+      TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+      TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+      TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+#endif
+
+      TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL);
+
+      TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
+
+# if LDBL_MANT_DIG > 100
+      TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+      TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+      TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+      TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+#endif
+
+      TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL);
+      TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL);
+
+      TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
+      TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+      TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+      TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+      TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+      TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+      TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+    }
+
+  fesetround (save_round_mode);
+
+  END (llrint_tonearest);
+}
+
+static void
+llrint_test_towardzero (void)
+{
+  int save_round_mode;
+  START (llrint_towardzero);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_TOWARDZERO))
+    {
+      TEST_f_L (llrint, 0.0, 0);
+      TEST_f_L (llrint, minus_zero, 0);
+      TEST_f_L (llrint, 0.2L, 0);
+      TEST_f_L (llrint, -0.2L, 0);
+
+      TEST_f_L (llrint, 1.4L, 1);
+      TEST_f_L (llrint, -1.4L, -1);
+
+      TEST_f_L (llrint, 8388600.3L, 8388600);
+      TEST_f_L (llrint, -8388600.3L, -8388600);
+
+      TEST_f_l (llrint, 1071930.0008, 1071930);
+
+      /* Test boundary conditions.  */
+      /* 0x1FFFFF */
+      TEST_f_L (llrint, 2097151.0,2097151LL);
+      /* 0x800000 */
+      TEST_f_L (llrint, 8388608.0, 8388608LL);
+      /* 0x1000000 */
+      TEST_f_L (llrint, 16777216.0, 16777216LL);
+      /* 0x20000000000 */
+      TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+      /* 0x40000000000 */
+      TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+      /* 0x1000000000000 */
+      TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+      /* 0x10000000000000 */
+      TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+      /* 0x10000080000000 */
+      TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+      /* 0x20000000000000 */
+      TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+      /* 0x80000000000000 */
+      TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+      /* 0x100000000000000 */
+      TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+      /* The input can only be represented in long double.  */
+      TEST_f_L (llrint, 4503599627370495.5L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.75L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370497.5L, 4503599627370497LL);
+
+      TEST_f_L (llrint, -4503599627370495.5L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.75L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370497.5L, -4503599627370497LL);
+
+# if LDBL_MANT_DIG > 100
+      TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+      TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370494LL);
+      TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370496LL);
+
+      TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+      TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370494LL);
+      TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370496LL);
+#endif
+
+      TEST_f_L (llrint, 9007199254740991.5L, 9007199254740991LL);
+      TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.75L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740993.5L, 9007199254740993LL);
+
+      TEST_f_L (llrint, -9007199254740991.5L, -9007199254740991LL);
+      TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.75L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740993.5L, -9007199254740993LL);
+
+# if LDBL_MANT_DIG > 100
+      TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+      TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740991LL);
+      TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740993LL);
+
+      TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+      TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740991LL);
+      TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740993LL);
+#endif
+
+      TEST_f_L (llrint, 72057594037927935.5L, 72057594037927935LL);
+      TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927936.75L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927937.5L, 72057594037927937LL);
+
+      TEST_f_L (llrint, -72057594037927935.5L, -72057594037927935LL);
+      TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927936.75L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927937.5L, -72057594037927937LL);
+
+# if LDBL_MANT_DIG > 100
+      TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775805LL);
+      TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775805LL);
+      TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+      TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+      TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+    }
+
+  fesetround (save_round_mode);
+
+  END (llrint_towardzero);
+}
+
+static void
+llrint_test_downward (void)
+{
+  int save_round_mode;
+  START (llrint_downward);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_DOWNWARD))
+    {
+      TEST_f_L (llrint, 0.0, 0);
+      TEST_f_L (llrint, minus_zero, 0);
+      TEST_f_L (llrint, 0.2L, 0);
+      TEST_f_L (llrint, -0.2L, -1);
+
+      TEST_f_L (llrint, 1.4L, 1);
+      TEST_f_L (llrint, -1.4L, -2);
+
+      TEST_f_L (llrint, 8388600.3L, 8388600);
+      TEST_f_L (llrint, -8388600.3L, -8388601);
+
+      TEST_f_l (llrint, 1071930.0008, 1071930);
+
+      /* Test boundary conditions.  */
+      /* 0x1FFFFF */
+      TEST_f_L (llrint, 2097151.0,2097151LL);
+      /* 0x800000 */
+      TEST_f_L (llrint, 8388608.0, 8388608LL);
+      /* 0x1000000 */
+      TEST_f_L (llrint, 16777216.0, 16777216LL);
+      /* 0x20000000000 */
+      TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+      /* 0x40000000000 */
+      TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+      /* 0x1000000000000 */
+      TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+      /* 0x10000000000000 */
+      TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+      /* 0x10000080000000 */
+      TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+      /* 0x20000000000000 */
+      TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+      /* 0x80000000000000 */
+      TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+      /* 0x100000000000000 */
+      TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+      /* The input can only be represented in long double.  */
+      TEST_f_L (llrint, 4503599627370495.5L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370496.25L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.5L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.75L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370497.5L, 4503599627370497LL);
+
+      TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370497LL);
+      TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370494LL);
+      TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370496LL);
+
+      TEST_f_L (llrint, -4503599627370495.5L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.25L, -4503599627370497LL);
+      TEST_f_L (llrint, -4503599627370496.5L, -4503599627370497LL);
+      TEST_f_L (llrint, -4503599627370496.75L, -4503599627370497LL);
+      TEST_f_L (llrint, -4503599627370497.5L, -4503599627370498LL);
+
+      TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370497LL);
+      TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370498LL);
+      TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370497LL);
+
+      TEST_f_L (llrint, 9007199254740991.5L, 9007199254740991LL);
+      TEST_f_L (llrint, 9007199254740992.25L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.5L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.75L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740993.5L, 9007199254740993LL);
+
+      TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740991LL);
+      TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740991LL);
+      TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740993LL);
+
+      TEST_f_L (llrint, -9007199254740991.5L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.25L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740992.5L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740992.75L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740993.5L, -9007199254740994LL);
+
+      TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740994LL);
+      TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740994LL);
+
+      TEST_f_L (llrint, 72057594037927935.5L, 72057594037927935LL);
+      TEST_f_L (llrint, 72057594037927936.25L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927936.5L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927936.75L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927937.5L, 72057594037927937LL);
+
+      TEST_f_L (llrint, -72057594037927935.5L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927936.25L, -72057594037927937LL);
+      TEST_f_L (llrint, -72057594037927936.5L, -72057594037927937LL);
+      TEST_f_L (llrint, -72057594037927936.75L, -72057594037927937LL);
+      TEST_f_L (llrint, -72057594037927937.5L, -72057594037927938LL);
+
+# if LDBL_MANT_DIG > 100
+      TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775805LL);
+      TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775807LL);
+      TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775806L);
+      TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775807LL);
+      TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775807LL);
+      TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+      TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+    }
+
+  fesetround (save_round_mode);
+
+  END (llrint_downward);
+}
+
+static void
+llrint_test_upward (void)
+{
+  int save_round_mode;
+  START (llrint_upward);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_UPWARD))
+    {
+      TEST_f_L (llrint, 0.0, 0);
+      TEST_f_L (llrint, minus_zero, 0);
+      TEST_f_L (llrint, 0.2L, 1);
+      TEST_f_L (llrint, -0.2L, 0);
+
+      TEST_f_L (llrint, 1.4L, 2);
+      TEST_f_L (llrint, -1.4L, -1);
+
+      TEST_f_L (llrint, 8388600.3L, 8388601);
+      TEST_f_L (llrint, -8388600.3L, -8388600);
+#ifndef TEST_FLOAT
+      TEST_f_l (llrint, 1071930.0008, 1071931);
+#endif
+      /* Test boundary conditions.  */
+      /* 0x1FFFFF */
+      TEST_f_L (llrint, 2097151.0,2097151LL);
+      /* 0x800000 */
+      TEST_f_L (llrint, 8388608.0, 8388608LL);
+      /* 0x1000000 */
+      TEST_f_L (llrint, 16777216.0, 16777216LL);
+      /* 0x20000000000 */
+      TEST_f_L (llrint, 2199023255552.0, 2199023255552LL);
+      /* 0x40000000000 */
+      TEST_f_L (llrint, 4398046511104.0, 4398046511104LL);
+      /* 0x1000000000000 */
+      TEST_f_L (llrint, 281474976710656.0, 281474976710656LL);
+      /* 0x10000000000000 */
+      TEST_f_L (llrint, 4503599627370496.0, 4503599627370496LL);
+      /* 0x10000080000000 */
+      TEST_f_L (llrint, 4503601774854144.0, 4503601774854144LL);
+      /* 0x20000000000000 */
+      TEST_f_L (llrint, 9007199254740992.0, 9007199254740992LL);
+      /* 0x80000000000000 */
+      TEST_f_L (llrint, 36028797018963968.0, 36028797018963968LL);
+      /* 0x100000000000000 */
+      TEST_f_L (llrint, 72057594037927936.0, 72057594037927936LL);
+#ifdef TEST_LDOUBLE
+      /* The input can only be represented in long double.  */
+      TEST_f_L (llrint, 4503599627370495.5L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.25L, 4503599627370497LL);
+      TEST_f_L (llrint, 4503599627370496.5L, 4503599627370497LL);
+      TEST_f_L (llrint, 4503599627370496.75L, 4503599627370497LL);
+      TEST_f_L (llrint, 4503599627370497.5L, 4503599627370498LL);
+
+      TEST_f_L (llrint, 4503599627370495.4999999999999L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.4999999999999L, 4503599627370497LL);
+      TEST_f_L (llrint, 4503599627370497.4999999999999L, 4503599627370498LL);
+      TEST_f_L (llrint, 4503599627370494.5000000000001L, 4503599627370495LL);
+      TEST_f_L (llrint, 4503599627370495.5000000000001L, 4503599627370496LL);
+      TEST_f_L (llrint, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+      TEST_f_L (llrint, -4503599627370495.5L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370496.25L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.5L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370496.75L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370497.5L, -4503599627370497LL);
+
+      TEST_f_L (llrint, -4503599627370495.4999999999999L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370496.4999999999999L, -4503599627370496LL);
+      TEST_f_L (llrint, -4503599627370497.4999999999999L, -4503599627370497LL);
+      TEST_f_L (llrint, -4503599627370494.5000000000001L, -4503599627370494LL);
+      TEST_f_L (llrint, -4503599627370495.5000000000001L, -4503599627370495LL);
+      TEST_f_L (llrint, -4503599627370496.5000000000001L, -4503599627370496LL);
+
+      TEST_f_L (llrint, 9007199254740991.5L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.25L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740992.5L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740992.75L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740993.5L, 9007199254740994LL);
+
+      TEST_f_L (llrint, 9007199254740991.4999999999999L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.4999999999999L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740993.4999999999999L, 9007199254740994LL);
+      TEST_f_L (llrint, 9007199254740991.5000000000001L, 9007199254740992LL);
+      TEST_f_L (llrint, 9007199254740992.5000000000001L, 9007199254740993LL);
+      TEST_f_L (llrint, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+      TEST_f_L (llrint, -9007199254740991.5L, -9007199254740991LL);
+      TEST_f_L (llrint, -9007199254740992.25L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.5L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740992.75L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740993.5L, -9007199254740993LL);
+
+      TEST_f_L (llrint, -9007199254740991.4999999999999L, -9007199254740991LL);
+      TEST_f_L (llrint, -9007199254740992.4999999999999L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740993.4999999999999L, -9007199254740993LL);
+      TEST_f_L (llrint, -9007199254740991.5000000000001L, -9007199254740991LL);
+      TEST_f_L (llrint, -9007199254740992.5000000000001L, -9007199254740992LL);
+      TEST_f_L (llrint, -9007199254740993.5000000000001L, -9007199254740993LL);
+
+      TEST_f_L (llrint, 72057594037927935.5L, 72057594037927936LL);
+      TEST_f_L (llrint, 72057594037927936.25L, 72057594037927937LL);
+      TEST_f_L (llrint, 72057594037927936.5L, 72057594037927937LL);
+      TEST_f_L (llrint, 72057594037927936.75L, 72057594037927937LL);
+      TEST_f_L (llrint, 72057594037927937.5L, 72057594037927938LL);
+
+      TEST_f_L (llrint, -72057594037927935.5L, -72057594037927935LL);
+      TEST_f_L (llrint, -72057594037927936.25L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927936.5L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927936.75L, -72057594037927936LL);
+      TEST_f_L (llrint, -72057594037927937.5L, -72057594037927937LL);
+
+# if LDBL_MANT_DIG > 100
+      TEST_f_L (llrint, 9223372036854775805.5L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775805.5L, -9223372036854775805LL);
+      TEST_f_L (llrint, 9223372036854775806.0L, 9223372036854775806LL);
+      TEST_f_L (llrint, -9223372036854775806.0L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.25L, 9223372036854775807LL);
+      TEST_f_L (llrint, -9223372036854775806.25L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.5L, 9223372036854775807L);
+      TEST_f_L (llrint, -9223372036854775806.5L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775806.75L, 9223372036854775807LL);
+      TEST_f_L (llrint, -9223372036854775806.75L, -9223372036854775806LL);
+      TEST_f_L (llrint, 9223372036854775807.0L, 9223372036854775807LL);
+      TEST_f_L (llrint, -9223372036854775807.0L, -9223372036854775807LL);
+# endif
+#endif
+    }
+
+  fesetround (save_round_mode);
+
+  END (llrint_upward);
+}
+
 
 static void
 log_test (void)
@@ -3597,6 +4188,22 @@ llround_test (void)
   TEST_f_L (llround, 4503599627370496.75L, 4503599627370497LL);
   TEST_f_L (llround, 4503599627370497.5L, 4503599627370498LL);
 
+# if LDBL_MANT_DIG > 100
+  TEST_f_L (llround, 4503599627370495.4999999999999L, 4503599627370495LL);
+  TEST_f_L (llround, 4503599627370496.4999999999999L, 4503599627370496LL);
+  TEST_f_L (llround, 4503599627370497.4999999999999L, 4503599627370497LL);
+  TEST_f_L (llround, 4503599627370494.5000000000001L, 4503599627370495LL);
+  TEST_f_L (llround, 4503599627370495.5000000000001L, 4503599627370496LL);
+  TEST_f_L (llround, 4503599627370496.5000000000001L, 4503599627370497LL);
+
+  TEST_f_L (llround, -4503599627370495.4999999999999L, -4503599627370495LL);
+  TEST_f_L (llround, -4503599627370496.4999999999999L, -4503599627370496LL);
+  TEST_f_L (llround, -4503599627370497.4999999999999L, -4503599627370497LL);
+  TEST_f_L (llround, -4503599627370494.5000000000001L, -4503599627370495LL);
+  TEST_f_L (llround, -4503599627370495.5000000000001L, -4503599627370496LL);
+  TEST_f_L (llround, -4503599627370496.5000000000001L, -4503599627370497LL);
+# endif
+
   TEST_f_L (llround, -4503599627370495.5L, -4503599627370496LL);
   TEST_f_L (llround, -4503599627370496.25L, -4503599627370496LL);
   TEST_f_L (llround, -4503599627370496.5L, -4503599627370497LL);
@@ -3609,6 +4216,22 @@ llround_test (void)
   TEST_f_L (llround, 9007199254740992.75L, 9007199254740993LL);
   TEST_f_L (llround, 9007199254740993.5L, 9007199254740994LL);
 
+# if LDBL_MANT_DIG > 100
+  TEST_f_L (llround, 9007199254740991.4999999999999L, 9007199254740991LL);
+  TEST_f_L (llround, 9007199254740992.4999999999999L, 9007199254740992LL);
+  TEST_f_L (llround, 9007199254740993.4999999999999L, 9007199254740993LL);
+  TEST_f_L (llround, 9007199254740991.5000000000001L, 9007199254740992LL);
+  TEST_f_L (llround, 9007199254740992.5000000000001L, 9007199254740993LL);
+  TEST_f_L (llround, 9007199254740993.5000000000001L, 9007199254740994LL);
+
+  TEST_f_L (llround, -9007199254740991.4999999999999L, -9007199254740991LL);
+  TEST_f_L (llround, -9007199254740992.4999999999999L, -9007199254740992LL);
+  TEST_f_L (llround, -9007199254740993.4999999999999L, -9007199254740993LL);
+  TEST_f_L (llround, -9007199254740991.5000000000001L, -9007199254740992LL);
+  TEST_f_L (llround, -9007199254740992.5000000000001L, -9007199254740993LL);
+  TEST_f_L (llround, -9007199254740993.5000000000001L, -9007199254740994LL);
+# endif
+
   TEST_f_L (llround, -9007199254740991.5L, -9007199254740992LL);
   TEST_f_L (llround, -9007199254740992.25L, -9007199254740992LL);
   TEST_f_L (llround, -9007199254740992.5L, -9007199254740993LL);
@@ -4051,6 +4674,12 @@ rint_test (void)
   TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
 # endif
 
+# if LDBL_MANT_DIG > 100
+  TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L);
+  TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+  TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
+# endif
+
   TEST_f_f (rint, -4503599627370495.5L, -4503599627370496.0L);
   TEST_f_f (rint, -4503599627370496.25L, -4503599627370496.0L);
   TEST_f_f (rint, -4503599627370496.5L, -4503599627370496.0L);
@@ -4077,6 +4706,26 @@ rint_test (void)
   TEST_f_f (rint, -9007199254740993.5000000000001L, -9007199254740994.0L);
 # endif
 
+# if LDBL_MANT_DIG > 100
+  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
+
   TEST_f_f (rint, 9007199254740991.5L, 9007199254740992.0L);
   TEST_f_f (rint, 9007199254740992.25L, 9007199254740992.0L);
   TEST_f_f (rint, 9007199254740992.5L, 9007199254740992.0L);
@@ -4117,66 +4766,66 @@ rint_test_tonearest (void)
   int save_round_mode;
   START (rint_tonearest);
 
-  save_round_mode = fegetround();
+  save_round_mode = fegetround ();
 
   if (!fesetround (FE_TONEAREST))
-  {
-    TEST_f_f (rint, 2.0, 2.0);
-    TEST_f_f (rint, 1.5, 2.0);
-    TEST_f_f (rint, 1.0, 1.0);
-    TEST_f_f (rint, 0.5, 0.0);
-    TEST_f_f (rint, 0.0, 0.0);
-    TEST_f_f (rint, minus_zero, minus_zero);
-    TEST_f_f (rint, -0.5, -0.0);
-    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);
+    {
+      TEST_f_f (rint, 2.0, 2.0);
+      TEST_f_f (rint, 1.5, 2.0);
+      TEST_f_f (rint, 1.0, 1.0);
+      TEST_f_f (rint, 0.5, 0.0);
+      TEST_f_f (rint, 0.0, 0.0);
+      TEST_f_f (rint, minus_zero, minus_zero);
+      TEST_f_f (rint, -0.5, -0.0);
+      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);
+      /* 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);
 # if LDBL_MANT_DIG > 100
-    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, 4503599627370494.5000000000001L, 4503599627370495.0L);
+      TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+      TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
 # endif
-    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, -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);
 # if LDBL_MANT_DIG > 100
-    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, -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
 #endif
-  }
+    }
 
-  fesetround(save_round_mode);
+  fesetround (save_round_mode);
 
   END (rint_tonearest);
 }
@@ -4187,66 +4836,66 @@ rint_test_towardzero (void)
   int save_round_mode;
   START (rint_towardzero);
 
-  save_round_mode = fegetround();
+  save_round_mode = fegetround ();
 
   if (!fesetround (FE_TOWARDZERO))
-  {
-    TEST_f_f (rint, 2.0, 2.0);
-    TEST_f_f (rint, 1.5, 1.0);
-    TEST_f_f (rint, 1.0, 1.0);
-    TEST_f_f (rint, 0.5, 0.0);
-    TEST_f_f (rint, 0.0, 0.0);
-    TEST_f_f (rint, minus_zero, minus_zero);
-    TEST_f_f (rint, -0.5, -0.0);
-    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);
+    {
+      TEST_f_f (rint, 2.0, 2.0);
+      TEST_f_f (rint, 1.5, 1.0);
+      TEST_f_f (rint, 1.0, 1.0);
+      TEST_f_f (rint, 0.5, 0.0);
+      TEST_f_f (rint, 0.0, 0.0);
+      TEST_f_f (rint, minus_zero, minus_zero);
+      TEST_f_f (rint, -0.5, -0.0);
+      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);
+      /* 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);
 # if LDBL_MANT_DIG > 100
-    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, 4503599627370494.5000000000001L, 4503599627370494.0L);
+      TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L);
+      TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L);
 # endif
-    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, -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);
 # if LDBL_MANT_DIG > 100
-    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);
+      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
 #endif
-  }
+    }
 
-  fesetround(save_round_mode);
+  fesetround (save_round_mode);
 
   END (rint_towardzero);
 }
@@ -4257,66 +4906,66 @@ rint_test_downward (void)
   int save_round_mode;
   START (rint_downward);
 
-  save_round_mode = fegetround();
+  save_round_mode = fegetround ();
 
   if (!fesetround (FE_DOWNWARD))
-  {
-    TEST_f_f (rint, 2.0, 2.0);
-    TEST_f_f (rint, 1.5, 1.0);
-    TEST_f_f (rint, 1.0, 1.0);
-    TEST_f_f (rint, 0.5, 0.0);
-    TEST_f_f (rint, 0.0, 0.0);
-    TEST_f_f (rint, minus_zero, minus_zero);
-    TEST_f_f (rint, -0.5, -1.0);
-    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);
+    {
+      TEST_f_f (rint, 2.0, 2.0);
+      TEST_f_f (rint, 1.5, 1.0);
+      TEST_f_f (rint, 1.0, 1.0);
+      TEST_f_f (rint, 0.5, 0.0);
+      TEST_f_f (rint, 0.0, 0.0);
+      TEST_f_f (rint, minus_zero, minus_zero);
+      TEST_f_f (rint, -0.5, -1.0);
+      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);
+      /* 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);
 # if LDBL_MANT_DIG > 100
-    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, 4503599627370494.5000000000001L, 4503599627370494.0L);
+      TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L);
+      TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L);
 # endif
-    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, -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);
 # if LDBL_MANT_DIG > 100
-    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);
+      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
 #endif
-  }
+    }
 
-  fesetround(save_round_mode);
+  fesetround (save_round_mode);
 
   END (rint_downward);
 }
@@ -4327,66 +4976,66 @@ rint_test_upward (void)
   int save_round_mode;
   START (rint_upward);
 
-  save_round_mode = fegetround();
+  save_round_mode = fegetround ();
 
   if (!fesetround (FE_UPWARD))
-  {
-    TEST_f_f (rint, 2.0, 2.0);
-    TEST_f_f (rint, 1.5, 2.0);
-    TEST_f_f (rint, 1.0, 1.0);
-    TEST_f_f (rint, 0.5, 1.0);
-    TEST_f_f (rint, 0.0, 0.0);
-    TEST_f_f (rint, minus_zero, minus_zero);
-    TEST_f_f (rint, -0.5, -0.0);
-    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);
+    {
+      TEST_f_f (rint, 2.0, 2.0);
+      TEST_f_f (rint, 1.5, 2.0);
+      TEST_f_f (rint, 1.0, 1.0);
+      TEST_f_f (rint, 0.5, 1.0);
+      TEST_f_f (rint, 0.0, 0.0);
+      TEST_f_f (rint, minus_zero, minus_zero);
+      TEST_f_f (rint, -0.5, -0.0);
+      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);
+      /* 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);
 # if LDBL_MANT_DIG > 100
-    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, 4503599627370494.5000000000001L, 4503599627370495.0L);
+      TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L);
+      TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L);
 # endif
-    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, -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);
 # if LDBL_MANT_DIG > 100
-    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);
+      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
 #endif
-  }
+    }
 
-  fesetround(save_round_mode);
+  fesetround (save_round_mode);
 
   END (rint_upward);
 }
@@ -4419,7 +5068,7 @@ round_test (void)
   /* The result can only be represented in long double.  */
   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.5L, 4503599627370497.0L);
   TEST_f_f (round, 4503599627370496.75L, 4503599627370497.0L);
   TEST_f_f (round, 4503599627370497.5L, 4503599627370498.0L);
 # if LDBL_MANT_DIG > 100
@@ -4428,10 +5077,10 @@ round_test (void)
   TEST_f_f (round, 4503599627370496.5000000000001L, 4503599627370497.0L);
 # endif
 
-  TEST_f_f (round, -4503599627370495.5L, -4503599627370496.0L); 
-  TEST_f_f (round, -4503599627370496.25L, -4503599627370496.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, -4503599627370496.75L, -4503599627370497.0L);
   TEST_f_f (round, -4503599627370497.5L, -4503599627370498.0L);
 # if LDBL_MANT_DIG > 100
   TEST_f_f (round, -4503599627370494.5000000000001L, -4503599627370495.0L);
@@ -4870,7 +5519,7 @@ trunc_test (void)
   TEST_f_f (trunc, 4503599627370495.5000000000001L, 4503599627370495.0L);
   TEST_f_f (trunc, 4503599627370496.5000000000001L, 4503599627370496.0L);
 # endif
-  
+
   TEST_f_f (trunc, -4503599627370495.5L, -4503599627370495.0L);
   TEST_f_f (trunc, -4503599627370496.25L, -4503599627370496.0L);
   TEST_f_f (trunc, -4503599627370496.5L, -4503599627370496.0L);
@@ -4883,6 +5532,12 @@ trunc_test (void)
   TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L);
 # endif
 
+# if LDBL_MANT_DIG > 100
+  TEST_f_f (trunc, -4503599627370494.5000000000001L, -4503599627370494.0L);
+  TEST_f_f (trunc, -4503599627370495.5000000000001L, -4503599627370495.0L);
+  TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L);
+# endif
+
   TEST_f_f (trunc, 9007199254740991.5L, 9007199254740991.0L);
   TEST_f_f (trunc, 9007199254740992.25L, 9007199254740992.0L);
   TEST_f_f (trunc, 9007199254740992.5L, 9007199254740992.0L);
@@ -4929,7 +5584,7 @@ trunc_test (void)
   TEST_f_f (trunc, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L);
   TEST_f_f (trunc, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L);
   TEST_f_f (trunc, 10141204801825835211973625643008.75L, 10141204801825835211973625643008.0L);
-  TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L); 
+  TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L);
 #endif
 
   END (trunc);
@@ -5315,6 +5970,10 @@ main (int argc, char **argv)
   rint_test_upward ();
   lrint_test ();
   llrint_test ();
+  llrint_test_tonearest ();
+  llrint_test_towardzero ();
+  llrint_test_downward ();
+  llrint_test_upward ();
   round_test ();
   lround_test ();
   llround_test ();
diff --git a/nis/nss_nisplus/nisplus-alias.c b/nis/nss_nisplus/nisplus-alias.c
index 6aa93ab3bc..d7926e1566 100644
--- a/nis/nss_nisplus/nisplus-alias.c
+++ b/nis/nss_nisplus/nisplus-alias.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
 
@@ -51,7 +52,7 @@ _nss_create_tablename (int *errnop)
       static const char prefix[] = "mail_aliases.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c
index fcc550e743..ca0a9e2481 100644
--- a/nis/nss_nisplus/nisplus-ethers.c
+++ b/nis/nss_nisplus/nisplus-ethers.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997,1998,2000-2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997,1998,2000-2003,2005,2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
 
@@ -94,7 +94,7 @@ _nss_create_tablename (int *errnop)
       static const char prefix[] = "ethers.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-grp.c b/nis/nss_nisplus/nisplus-grp.c
index 423f7e7291..624b20610a 100644
--- a/nis/nss_nisplus/nisplus-grp.c
+++ b/nis/nss_nisplus/nisplus-grp.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2001, 2002, 2003, 2005, 2006
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
 
@@ -47,7 +48,7 @@ _nss_create_tablename (int *errnop)
       static const char prefix[] = "group.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c
index 81f8a984dc..bf002d6dd7 100644
--- a/nis/nss_nisplus/nisplus-hosts.c
+++ b/nis/nss_nisplus/nisplus-hosts.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997-2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997-2002, 2003, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
 
@@ -186,7 +186,7 @@ _nss_create_tablename (int *errnop)
       static const char prefix[] = "hosts.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-network.c b/nis/nss_nisplus/nisplus-network.c
index dc6b99e505..960c0558e9 100644
--- a/nis/nss_nisplus/nisplus-network.c
+++ b/nis/nss_nisplus/nisplus-network.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997,1998,2000-2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997,1998,2000-2003,2005,2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
 
@@ -148,7 +148,7 @@ _nss_create_tablename (int *errnop)
       static const char prefix[] = "networks.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-proto.c b/nis/nss_nisplus/nisplus-proto.c
index 585a4844ad..a3370aa85e 100644
--- a/nis/nss_nisplus/nisplus-proto.c
+++ b/nis/nss_nisplus/nisplus-proto.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
 
@@ -147,7 +148,7 @@ _nss_create_tablename (int *errnop)
       static const char prefix[] = "protocols.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c
index 97679dd349..6c222ede02 100644
--- a/nis/nss_nisplus/nisplus-pwd.c
+++ b/nis/nss_nisplus/nisplus-pwd.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997,1999,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1999, 2001, 2002, 2003, 2005, 2006
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
 
@@ -44,7 +45,7 @@ _nss_pwd_create_tablename (int *errnop)
       static const char prefix[] = "passwd.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (pwd_tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-rpc.c b/nis/nss_nisplus/nisplus-rpc.c
index 98baa5f7fc..f6ab3fbd87 100644
--- a/nis/nss_nisplus/nisplus-rpc.c
+++ b/nis/nss_nisplus/nisplus-rpc.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997,1998,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2001, 2002, 2003, 2005, 2006
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
 
@@ -144,7 +145,7 @@ _nss_create_tablename (int *errnop)
       static const char prefix[] = "rpc.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nis/nss_nisplus/nisplus-service.c b/nis/nss_nisplus/nisplus-service.c
index 848e5f4dd8..c47dc09a06 100644
--- a/nis/nss_nisplus/nisplus-service.c
+++ b/nis/nss_nisplus/nisplus-service.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2005, 2006
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
 
@@ -151,7 +152,7 @@ _nss_create_tablename (int *errnop)
       static const char prefix[] = "services.org_dir.";
 
       char *p = malloc (sizeof (prefix) + local_dir_len);
-      if (tablename_val == NULL)
+      if (p == NULL)
 	{
 	  *errnop = errno;
 	  return NSS_STATUS_TRYAGAIN;
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 678a419aca..64cea204e3 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,35 @@
+2006-03-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* allocatestack.c (allocate_stack): Always initialize robust_head.
+	* descr.h: Define struct robust_list_head.
+	(struct pthread): Use robust_list_head in robust mutex list definition.
+	Adjust ENQUEUE_MUTEX and DEQUEUE_MUTEX.
+	* init.c [!__ASSUME_SET_ROBUST_LIST] (__set_robust_list_avail): Define.
+	(__pthread_initialize_minimal_internal): Register robust_list with
+	the kernel.
+	* pthreadP.h: Remove PRIVATE_ from PTHREAD_MUTEX_ROBUST_* names.
+	Declare __set_robust_list_avail.
+	* pthread_create.c (start_thread): Register robust_list of new thread.
+	[!__ASSUME_SET_ROBUST_LIST]: If robust_list is not empty wake up
+	waiters.
+	* pthread_mutex_destroy.c: For robust mutexes don't look at the
+	number of users, it's unreliable.
+	* pthread_mutex_init.c: Allow use of pshared robust mutexes if
+	set_robust_list syscall is available.
+	* pthread_mutex_consistent.c: Adjust for PTHREAD_MUTEX_ROBUST_* rename.
+	* pthread_mutex_lock.c: Simplify robust mutex code a bit.
+	Set robust_head.list_op_pending before trying to lock a robust mutex.
+	* pthread_mutex_timedlock.c: Likewise.
+	* pthread_mutex_trylock.c: Likewise.
+	* pthread_mutex_unlock.c: Likewise for unlocking.
+	* Makefile (tests): Add tst-robust8.
+	* tst-robust8.c: New file.
+
+2006-03-08  Andreas Schwab  <schwab@suse.de>
+
+	* sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
+	(DL_SYSINFO_IMPLEMENTATION): Add missing newline.
+
 2006-03-05  Roland McGrath  <roland@redhat.com>
 
 	* configure (libc_add_on): Disable add-on when $add_ons_automatic = yes
diff --git a/nptl/Makefile b/nptl/Makefile
index 31b5ace92e..e430b8d6cb 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -206,7 +206,7 @@ tests = tst-typesizes \
 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
 	tst-cond20 tst-cond21 \
 	tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
-	tst-robust6 tst-robust7 \
+	tst-robust6 tst-robust7 tst-robust8 \
 	tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
 	tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
 	tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 046a2470fc..a3ed1a33d3 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -365,12 +365,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
       /* The process ID is also the same as that of the caller.  */
       pd->pid = THREAD_GETMEM (THREAD_SELF, pid);
 
-      /* List of robust mutexes.  */
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
-      pd->robust_list.__prev = &pd->robust_list;
-#endif
-      pd->robust_list.__next = &pd->robust_list;
-
       /* Allocate the DTV for this thread.  */
       if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL)
 	{
@@ -505,12 +499,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	  /* The process ID is also the same as that of the caller.  */
 	  pd->pid = THREAD_GETMEM (THREAD_SELF, pid);
 
-	  /* List of robust mutexes.  */
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
-	  pd->robust_list.__prev = &pd->robust_list;
-#endif
-	  pd->robust_list.__next = &pd->robust_list;
-
 	  /* Allocate the DTV for this thread.  */
 	  if (_dl_allocate_tls (TLS_TPADJ (pd)) == NULL)
 	    {
@@ -634,6 +622,18 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
      stillborn thread could be canceled while the lock is taken.  */
   pd->lock = LLL_LOCK_INITIALIZER;
 
+  /* The robust mutex lists also need to be initialized
+     unconditionally because the cleanup for the previous stack owner
+     might have happened in the kernel.  */
+  pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock)
+				  - offsetof (pthread_mutex_t,
+					      __data.__list.__next));
+  pd->robust_head.list_op_pending = NULL;
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+  pd->robust_prev = &pd->robust_head;
+#endif
+  pd->robust_head.list = &pd->robust_head;
+
   /* We place the thread descriptor at the end of the stack.  */
   *pdp = pd;
 
diff --git a/nptl/descr.h b/nptl/descr.h
index 80251b920b..f89d3240da 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -102,6 +102,15 @@ struct xid_command
 };
 
 
+/* Data structure used by the kernel to find robust futexes.  */
+struct robust_list_head
+{
+  void *list;
+  long int futex_offset;
+  void *list_op_pending;
+};
+
+
 /* Thread descriptor data structure.  */
 struct pthread
 {
@@ -136,25 +145,43 @@ struct pthread
 
   /* List of robust mutexes the thread is holding.  */
 #ifdef __PTHREAD_MUTEX_HAVE_PREV
-  __pthread_list_t robust_list;
+  void *robust_prev;
+  struct robust_list_head robust_head;
+
+  /* The list above is strange.  It is basically a double linked list
+     but the pointer to the next/previous element of the list points
+     in the middle of the object, the __next element.  Whenever
+     casting to __pthread_list_t we need to adjust the pointer
+     first.  */
+# define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next))
 
 # define ENQUEUE_MUTEX(mutex) \
   do {									      \
-    __pthread_list_t *next = THREAD_GETMEM (THREAD_SELF, robust_list.__next); \
-    next->__prev = &mutex->__data.__list;				      \
-    mutex->__data.__list.__next = next;					      \
-    mutex->__data.__list.__prev = &THREAD_SELF->robust_list;		      \
-    THREAD_SETMEM (THREAD_SELF, robust_list.__next, &mutex->__data.__list);   \
+    __pthread_list_t *next = (THREAD_GETMEM (THREAD_SELF, robust_head.list)   \
+			      - QUEUE_PTR_ADJUST);			      \
+    next->__prev = (void *) &mutex->__data.__list.__next;		      \
+    mutex->__data.__list.__next = (void *) &next->__next;		      \
+    mutex->__data.__list.__prev = (void *) &THREAD_SELF->robust_head;	      \
+    THREAD_SETMEM (THREAD_SELF, robust_head.list,			      \
+		   &mutex->__data.__list.__next);			      \
   } while (0)
 # define DEQUEUE_MUTEX(mutex) \
   do {									      \
-    mutex->__data.__list.__next->__prev = mutex->__data.__list.__prev;	      \
-    mutex->__data.__list.__prev->__next = mutex->__data.__list.__next;	      \
+    __pthread_list_t *next = (__pthread_list_t *)			      \
+      ((char *) mutex->__data.__list.__next - QUEUE_PTR_ADJUST);	      \
+    next->__prev = mutex->__data.__list.__prev;				      \
+    __pthread_list_t *prev = (__pthread_list_t *)			      \
+      ((char *) mutex->__data.__list.__prev - QUEUE_PTR_ADJUST);	      \
+    prev->__next = mutex->__data.__list.__next;				      \
     mutex->__data.__list.__prev = NULL;					      \
     mutex->__data.__list.__next = NULL;					      \
   } while (0)
 #else
-  __pthread_slist_t robust_list;
+  union
+  {
+    __pthread_slist_t robust_list;
+    struct robust_list_head robust_head;
+  };
 
 # define ENQUEUE_MUTEX(mutex) \
   do {									      \
diff --git a/nptl/init.c b/nptl/init.c
index cb63ff7a6d..4db3e0c828 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -60,6 +60,15 @@
 size_t __static_tls_size;
 size_t __static_tls_align_m1;
 
+#ifndef __ASSUME_SET_ROBUST_LIST
+/* Negative if we do not have the system call and we can use it.  */
+int __set_robust_list_avail;
+# define set_robust_list_not_avail() \
+  __set_robust_list_avail = -1
+#else
+# define set_robust_list_not_avail() do { } while (0)
+#endif
+
 /* Version of the library, used in libthread_db to detect mismatches.  */
 static const char nptl_version[] __attribute_used__ = VERSION;
 
@@ -247,10 +256,6 @@ __pthread_initialize_minimal_internal (void)
   struct pthread *pd = THREAD_SELF;
   INTERNAL_SYSCALL_DECL (err);
   pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid);
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
-  pd->robust_list.__prev = &pd->robust_list;
-#endif
-  pd->robust_list.__next = &pd->robust_list;
   THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]);
   THREAD_SETMEM (pd, user_stack, true);
   if (LLL_LOCK_INITIALIZER != 0)
@@ -259,6 +264,21 @@ __pthread_initialize_minimal_internal (void)
   THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
 #endif
 
+  /* Initialize the robust mutex data.  */
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+  pd->robust_prev = &pd->robust_head;
+#endif
+  pd->robust_head.list = &pd->robust_head;
+#ifdef __NR_set_robust_list
+  pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock)
+				  - offsetof (pthread_mutex_t,
+					      __data.__list.__next));
+  int res = INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
+			      sizeof (struct robust_list_head));
+  if (INTERNAL_SYSCALL_ERROR_P (res, err))
+#endif
+    set_robust_list_not_avail ();
+
   /* Set initial thread's stack block from 0 up to __libc_stack_end.
      It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
      purposes this is good enough.  */
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index a4d6d1a1ae..7b3da83786 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -31,6 +31,7 @@
 #include <internaltypes.h>
 #include <pthread-functions.h>
 #include <atomic.h>
+#include <kernel-features.h>
 
 
 /* Atomic operations on TLS memory.  */
@@ -60,13 +61,13 @@
 /* Internal mutex type value.  */
 enum
 {
-  PTHREAD_MUTEX_ROBUST_PRIVATE_NP = 16,
-  PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP
-  = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_RECURSIVE_NP,
-  PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP
-  = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
-  PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP
-  = PTHREAD_MUTEX_ROBUST_PRIVATE_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
+  PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16,
+  PTHREAD_MUTEX_ROBUST_RECURSIVE_NP
+  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP,
+  PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP
+  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
+  PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP
+  = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
   PTHREAD_MUTEX_PRIO_INHERIT_PRIVATE_NP = 32,
   PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP = 64
 };
@@ -128,6 +129,11 @@ hidden_proto (__pthread_keys)
 /* Number of threads running.  */
 extern unsigned int __nptl_nthreads attribute_hidden;
 
+#ifndef __ASSUME_SET_ROBUST_LIST
+/* Negative if we do not have the system call and we can use it.  */
+extern int __set_robust_list_avail attribute_hidden;
+#endif
+
 /* The library can run in debugging mode where it performs a lot more
    tests.  */
 extern int __pthread_debug attribute_hidden;
@@ -504,4 +510,15 @@ extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
 # define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name);
 #endif
 
+
+#ifndef __NR_set_robust_list
+/* XXX For the time being...  Once we can rely on the kernel headers
+   having the definition remove these lines.  */
+# if defined __i386__
+#  define __NR_set_robust_list  311
+# elif defined __x86_64__
+#  define __NR_set_robust_list  273
+# endif
+#endif
+
 #endif	/* pthreadP.h */
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index f3d90ecebf..71365a17e8 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -229,6 +229,19 @@ start_thread (void *arg)
   /* Initialize resolver state pointer.  */
   __resp = &pd->res;
 
+#ifdef __NR_set_robust_list
+# ifndef __ASSUME_SET_ROBUST_LIST
+  if (__set_robust_list_avail >= 0)
+# endif
+    {
+      INTERNAL_SYSCALL_DECL (err);
+      /* This call should never fail because the initial call in init.c
+	 succeeded.  */
+      INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
+			sizeof (struct robust_list_head));
+    }
+#endif
+
   /* This is where the try/finally block should be created.  For
      compilers without that support we do use setjmp.  */
   struct pthread_unwind_buf unwind_buf;
@@ -310,35 +323,34 @@ start_thread (void *arg)
      the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE.  */
   atomic_bit_set (&pd->cancelhandling, EXITING_BIT);
 
+#ifndef __ASSUME_SET_ROBUST_LIST
   /* If this thread has any robust mutexes locked, handle them now.  */
-#if __WORDSIZE == 64
-  __pthread_list_t *robust = pd->robust_list.__next;
-#else
+# if __WORDSIZE == 64
+  void *robust = pd->robust_head.list;
+# else
   __pthread_slist_t *robust = pd->robust_list.__next;
-#endif
-  if (__builtin_expect (robust != &pd->robust_list, 0))
+# endif
+/* We let the kernel do the notification if it is able to do so.  */
+  if (__set_robust_list_avail < 0
+      && __builtin_expect (robust != &pd->robust_head, 0))
     {
       do
 	{
 	  struct __pthread_mutex_s *this = (struct __pthread_mutex_s *)
-	    ((char *) robust - offsetof (struct __pthread_mutex_s, __list));
-	  robust = robust->__next;
+	    ((char *) robust - offsetof (struct __pthread_mutex_s,
+					 __list.__next));
+	  robust = *((void **) robust);
 
-	  this->__list.__next = NULL;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
+# ifdef __PTHREAD_MUTEX_HAVE_PREV
 	  this->__list.__prev = NULL;
-#endif
+# endif
+	  this->__list.__next = NULL;
 
 	  lll_robust_mutex_dead (this->__lock);
 	}
-      while (robust != &pd->robust_list);
-
-      /* Clean up so that the thread descriptor can be reused.  */
-      pd->robust_list.__next = &pd->robust_list;
-#ifdef __PTHREAD_MUTEX_HAVE_PREV
-      pd->robust_list.__prev = &pd->robust_list;
-#endif
+      while (robust != &pd->robust_head);
     }
+#endif
 
   /* If the thread is detached free the TCB.  */
   if (IS_DETACHED (pd))
diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c
index 0cfe972da0..d4f287b755 100644
--- a/nptl/pthread_mutex_consistent.c
+++ b/nptl/pthread_mutex_consistent.c
@@ -26,7 +26,7 @@ pthread_mutex_consistent_np (mutex)
      pthread_mutex_t *mutex;
 {
   /* Test whether this is a robust mutex with a dead owner.  */
-  if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_PRIVATE_NP) == 0
+  if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
       || mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT)
     return EINVAL;
 
diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c
index 19a647a846..7829979f35 100644
--- a/nptl/pthread_mutex_destroy.c
+++ b/nptl/pthread_mutex_destroy.c
@@ -25,15 +25,9 @@ int
 __pthread_mutex_destroy (mutex)
      pthread_mutex_t *mutex;
 {
-  if (mutex->__data.__nusers != 0)
-    {
-      if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_PRIVATE_NP) != 0
-	  && (mutex->__data.__lock & FUTEX_OWNER_DIED) != 0
-	  && mutex->__data.__nusers == 1)
-	goto dead_robust_mutex;
-
-      return EBUSY;
-    }
+  if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
+      && mutex->__data.__nusers != 0)
+    return EBUSY;
 
   /* Set to an invalid value.  */
  dead_robust_mutex:
diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
index f984d90ae4..c25e4035e5 100644
--- a/nptl/pthread_mutex_init.c
+++ b/nptl/pthread_mutex_init.c
@@ -22,7 +22,6 @@
 #include <string.h>
 #include "pthreadP.h"
 
-
 static const struct pthread_mutexattr default_attr =
   {
     /* Default is a normal mutex, not shared between processes.  */
@@ -42,10 +41,6 @@ __pthread_mutex_init (mutex, mutexattr)
   imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
 
   /* Sanity checks.  */
-  // XXX For now we cannot implement robust mutexes if they are shared.
-  if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0
-      && (imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0)
-    return ENOTSUP;
   // XXX For now we don't support priority inherited or priority protected
   // XXX mutexes.
   if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
@@ -57,8 +52,18 @@ __pthread_mutex_init (mutex, mutexattr)
 
   /* Copy the values from the attribute.  */
   mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
+
   if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0)
-    mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_PRIVATE_NP;
+    {
+#ifndef __ASSUME_SET_ROBUST_LIST
+      if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0
+	  && __set_robust_list_avail < 0)
+	return ENOTSUP;
+#endif
+
+      mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+    }
+
   switch ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
 	  >> PTHREAD_MUTEXATTR_PROTOCOL_SHIFT)
     {
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index dd22567c71..06eef49c71 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -108,25 +108,33 @@ __pthread_mutex_lock (mutex)
       assert (mutex->__data.__owner == 0);
       break;
 
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+		     &mutex->__data.__list.__next);
+
       oldval = mutex->__data.__lock;
       do
 	{
+	again:
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
 	    {
 	      /* The previous owner died.  Try locking the mutex.  */
-	      int newval;
-	      while ((newval
-		      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
-							     id, oldval))
-		     != oldval)
+	      int newval = id;
+#ifdef NO_INCR
+	      newval |= FUTEX_WAITERS;
+#endif
+
+	      newval
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						       newval, oldval);
+
+	      if (newval != oldval)
 		{
-		  if ((newval & FUTEX_OWNER_DIED) == 0)
-		    goto normal;
 		  oldval = newval;
+		  goto again;
 		}
 
 	      /* We got the mutex.  */
@@ -135,6 +143,7 @@ __pthread_mutex_lock (mutex)
 	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
 
 	      ENQUEUE_MUTEX (mutex);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 
 	      /* Note that we deliberately exit here.  If we fall
 		 through to the end of the function __nusers would be
@@ -149,18 +158,23 @@ __pthread_mutex_lock (mutex)
 	      return EOWNERDEAD;
 	    }
 
-	normal:
 	  /* Check whether we already hold the mutex.  */
-	  if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK)
-				== id, 0))
+	  if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
 	    {
 	      if (mutex->__data.__kind
-		  == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP)
-		return EDEADLK;
+		  == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+		  return EDEADLK;
+		}
 
 	      if (mutex->__data.__kind
-		  == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP)
+		  == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
 		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+
 		  /* Just bump the counter.  */
 		  if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
 		    /* Overflow of the counter.  */
@@ -180,6 +194,7 @@ __pthread_mutex_lock (mutex)
 	      /* This mutex is now not recoverable.  */
 	      mutex->__data.__count = 0;
 	      lll_mutex_unlock (mutex->__data.__lock);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 	      return ENOTRECOVERABLE;
 	    }
 	}
@@ -187,6 +202,7 @@ __pthread_mutex_lock (mutex)
 
       mutex->__data.__count = 1;
       ENQUEUE_MUTEX (mutex);
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
     default:
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index b69caedc7c..7c48c7ce6b 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -103,25 +103,27 @@ pthread_mutex_timedlock (mutex, abstime)
 	}
       break;
 
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+		     &mutex->__data.__list.__next);
+
       oldval = mutex->__data.__lock;
       do
 	{
+	again:
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
 	    {
 	      /* The previous owner died.  Try locking the mutex.  */
-	      int newval;
-	      while ((newval
-		      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
-							     id, oldval))
-		     != oldval)
+	      int newval
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						       id, oldval);
+	      if (newval != oldval)
 		{
-		  if ((newval & FUTEX_OWNER_DIED) == 0)
-		    goto normal;
 		  oldval = newval;
+		  goto again;
 		}
 
 	      /* We got the mutex.  */
@@ -130,6 +132,7 @@ pthread_mutex_timedlock (mutex, abstime)
 	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
 
 	      ENQUEUE_MUTEX (mutex);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 
 	      /* Note that we deliberately exist here.  If we fall
 		 through to the end of the function __nusers would be
@@ -138,18 +141,23 @@ pthread_mutex_timedlock (mutex, abstime)
 	      return EOWNERDEAD;
 	    }
 
-	normal:
 	  /* Check whether we already hold the mutex.  */
-	  if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK)
-				== id, 0))
+	  if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
 	    {
 	      if (mutex->__data.__kind
-		  == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP)
-		return EDEADLK;
+		  == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+		  return EDEADLK;
+		}
 
 	      if (mutex->__data.__kind
-		  == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP)
+		  == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
 		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+
 		  /* Just bump the counter.  */
 		  if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
 		    /* Overflow of the counter.  */
@@ -170,6 +178,7 @@ pthread_mutex_timedlock (mutex, abstime)
 	      /* This mutex is now not recoverable.  */
 	      mutex->__data.__count = 0;
 	      lll_mutex_unlock (mutex->__data.__lock);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 	      return ENOTRECOVERABLE;
 	    }
 
@@ -182,6 +191,7 @@ pthread_mutex_timedlock (mutex, abstime)
 
       mutex->__data.__count = 1;
       ENQUEUE_MUTEX (mutex);
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
     default:
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 5a13ea6925..148a6e919f 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -77,25 +77,28 @@ __pthread_mutex_trylock (mutex)
       return 0;
 
 
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+		     &mutex->__data.__list.__next);
+
       oldval = mutex->__data.__lock;
       do
 	{
+	again:
 	  if ((oldval & FUTEX_OWNER_DIED) != 0)
 	    {
 	      /* The previous owner died.  Try locking the mutex.  */
-	      int newval;
-	      while ((newval
-		      = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
-							     id, oldval))
-		     != oldval)
+	      int newval
+		= atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+						       id, oldval);
+
+	      if (newval != oldval)
 		{
-		  if ((newval & FUTEX_OWNER_DIED) == 0)
-		    goto normal;
 		  oldval = newval;
+		  goto again;
 		}
 
 	      /* We got the mutex.  */
@@ -104,6 +107,7 @@ __pthread_mutex_trylock (mutex)
 	      mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
 
 	      ENQUEUE_MUTEX (mutex);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 
 	      /* Note that we deliberately exist here.  If we fall
 		 through to the end of the function __nusers would be
@@ -112,18 +116,23 @@ __pthread_mutex_trylock (mutex)
 	      return EOWNERDEAD;
 	    }
 
-	normal:
 	  /* Check whether we already hold the mutex.  */
-	  if (__builtin_expect ((mutex->__data.__lock & FUTEX_TID_MASK)
-				== id, 0))
+	  if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
 	    {
 	      if (mutex->__data.__kind
-		  == PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP)
-		return EDEADLK;
+		  == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+		  return EDEADLK;
+		}
 
 	      if (mutex->__data.__kind
-		  == PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP)
+		  == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
 		{
+		  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+				 NULL);
+
 		  /* Just bump the counter.  */
 		  if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
 		    /* Overflow of the counter.  */
@@ -137,7 +146,11 @@ __pthread_mutex_trylock (mutex)
 
 	  oldval = lll_robust_mutex_trylock (mutex->__data.__lock, id);
 	  if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
-	    return EBUSY;
+	    {
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+	      return EBUSY;
+	    }
 
 	robust:
 	  if (__builtin_expect (mutex->__data.__owner
@@ -147,12 +160,14 @@ __pthread_mutex_trylock (mutex)
 	      mutex->__data.__count = 0;
 	      if (oldval == id)
 		lll_mutex_unlock (mutex->__data.__lock);
+	      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 	      return ENOTRECOVERABLE;
 	    }
 	}
       while ((oldval & FUTEX_OWNER_DIED) != 0);
 
       ENQUEUE_MUTEX (mutex);
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 
       mutex->__data.__owner = id;
       ++mutex->__data.__nusers;
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index d41eefe34c..bf9aa7625f 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -63,10 +63,12 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
       lll_mutex_unlock (mutex->__data.__lock);
       break;
 
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_RECURSIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
       /* Recursive mutex.  */
       if ((mutex->__data.__lock & FUTEX_TID_MASK)
-	  == THREAD_GETMEM (THREAD_SELF, tid))
+	  == THREAD_GETMEM (THREAD_SELF, tid)
+	  && __builtin_expect (mutex->__data.__owner
+			       == PTHREAD_MUTEX_INCONSISTENT, 0))
 	{
 	  if (--mutex->__data.__count != 0)
 	    /* We still hold the mutex.  */
@@ -84,9 +86,9 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
 
       goto robust;
 
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_ERRORCHECK_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_NP:
-    case PTHREAD_MUTEX_ROBUST_PRIVATE_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
       if ((mutex->__data.__lock & FUTEX_TID_MASK)
 	  != THREAD_GETMEM (THREAD_SELF, tid)
 	  || ! lll_mutex_islocked (mutex->__data.__lock))
@@ -102,6 +104,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
 
     robust:
       /* Remove mutex from the list.  */
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+		     &mutex->__data.__list.__next);
       DEQUEUE_MUTEX (mutex);
 
       mutex->__data.__owner = newowner;
@@ -111,6 +115,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
 
       /* Unlock.  */
       lll_robust_mutex_unlock (mutex->__data.__lock);
+
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
     default:
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
index af835c44b1..525b622a68 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
@@ -1,5 +1,5 @@
 /* System-specific settings for dynamic linker code.  IA-64 version.
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 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
@@ -57,7 +57,7 @@ extern int _dl_sysinfo_break attribute_hidden;
        ".body\n\t"				\
        "break 0x100000;\n\t"			\
        "br.ret.sptk.many b6;\n\t"		\
-       ".endp _dl_sysinfo_break"		\
+       ".endp _dl_sysinfo_break\n\t"		\
        ".previous");
 #endif
 
diff --git a/nptl/tst-robust8.c b/nptl/tst-robust8.c
new file mode 100644
index 0000000000..19682e594f
--- /dev/null
+++ b/nptl/tst-robust8.c
@@ -0,0 +1,264 @@
+#include <pthread.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+
+
+
+static void prepare (void);
+#define PREPARE(argc, argv) prepare ()
+static int do_test (void);
+#define TEST_FUNCTION do_test ()
+#define TIMEOUT 3
+#include "../test-skeleton.c"
+
+
+static int fd;
+#define N 100
+
+static void
+prepare (void)
+{
+  fd = create_temp_file ("tst-robust8", NULL);
+  if (fd == -1)
+    exit (1);
+}
+
+
+#define THESIGNAL SIGKILL
+#define ROUNDS 5
+#define THREADS 9
+
+
+static const struct timespec before = { 0, 0 };
+
+
+static pthread_mutex_t *map;
+
+
+static void *
+tf (void *arg)
+{
+  long int nr = (long int) arg;
+  int fct = nr % 3;
+
+  uint8_t state[N];
+  memset (state, '\0', sizeof (state));
+
+  while (1)
+    {
+      int r = random () % N;
+      if (state[r] == 0)
+	{
+	  int e;
+
+	  switch (fct)
+	    {
+	    case 0:
+	      e = pthread_mutex_lock (&map[r]);
+	      if (e != 0)
+		{
+		  printf ("mutex_lock of %d in thread %ld failed with %d\n",
+			  r, nr, e);
+		  exit (1);
+		}
+	      state[r] = 1;
+	      break;
+	    case 1:
+	      e = pthread_mutex_timedlock (&map[r], &before);
+	      if (e != 0 && e != ETIMEDOUT)
+		{
+		  printf ("\
+mutex_timedlock of %d in thread %ld failed with %d\n",
+			  r, nr, e);
+		  exit (1);
+		}
+	      break;
+	    default:
+	      e = pthread_mutex_trylock (&map[r]);
+	      if (e != 0 && e != EBUSY)
+		{
+		  printf ("mutex_trylock of %d in thread %ld failed with %d\n",
+			  r, nr, e);
+		  exit (1);
+		}
+	      break;
+	    }
+
+	  if (e == EOWNERDEAD)
+	    pthread_mutex_consistent_np (&map[r]);
+
+	  if (e == 0 || e == EOWNERDEAD)
+	    state[r] = 1;
+	}
+      else
+	{
+	  int e = pthread_mutex_unlock (&map[r]);
+	  if (e != 0)
+	    {
+	      printf ("mutex_unlock of %d in thread %ld failed with %d\n",
+		      r, nr, e);
+	      exit (1);
+	    }
+
+	  state[r] = 0;
+	}
+    }
+}
+
+
+static void
+child (int round)
+{
+  for (int thread = 1; thread <= THREADS; ++thread)
+    {
+      pthread_t th;
+      if (pthread_create (&th, NULL, tf, (void *) (long int) thread) != 0)
+	{
+	  printf ("cannot create thread %d in round %d\n", thread, round);
+	  exit (1);
+	}
+    }
+
+  struct timespec ts;
+  ts.tv_sec = 0;
+  ts.tv_nsec = 1000000000 / ROUNDS;
+  while (nanosleep (&ts, &ts) != 0)
+    /* nothing */;
+
+  /* Time to die.  */
+  kill (getpid (), THESIGNAL);
+
+  /* We better never get here.  */
+  abort ();
+}
+
+
+static int
+do_test (void)
+{
+  if (ftruncate (fd, N * sizeof (pthread_mutex_t)) != 0)
+    {
+      puts ("cannot size new file");
+      return 1;
+    }
+
+  map = mmap (NULL, N * sizeof (pthread_mutex_t), PROT_READ | PROT_WRITE,
+	      MAP_SHARED, fd, 0);
+  if (map == MAP_FAILED)
+    {
+      puts ("mapping failed");
+      return 1;
+    }
+
+  pthread_mutexattr_t ma;
+  if (pthread_mutexattr_init (&ma) != 0)
+    {
+      puts ("mutexattr_init failed");
+      return 0;
+    }
+  if (pthread_mutexattr_setrobust_np (&ma, PTHREAD_MUTEX_ROBUST_NP) != 0)
+    {
+      puts ("mutexattr_setrobust failed");
+      return 1;
+    }
+  if (pthread_mutexattr_setpshared (&ma, PTHREAD_PROCESS_SHARED) != 0)
+    {
+      puts ("mutexattr_setpshared failed");
+      return 1;
+    }
+
+  for (int round = 1; round <= ROUNDS; ++round)
+    {
+      for (int n = 0; n < N; ++n)
+	{
+	  int e = pthread_mutex_init (&map[n], &ma);
+	  if (e == ENOTSUP)
+	    {
+	      puts ("cannot support pshared robust mutexes");
+	      return 0;
+	    }
+	  if (e != 0)
+	    {
+	      printf ("mutex_init %d in round %d failed\n", n + 1, round);
+	      return 1;
+	    }
+	}
+
+      pid_t p = fork ();
+      if (p == -1)
+	{
+	  printf ("fork in round %d failed\n", round);
+	  return 1;
+	}
+      if (p == 0)
+	child (round);
+
+      int status;
+      if (TEMP_FAILURE_RETRY (waitpid (p, &status, 0)) != p)
+	{
+	  printf ("waitpid in round %d failed\n", round);
+	  return 1;
+	}
+      if (!WIFSIGNALED (status))
+	{
+	  printf ("child did not die of a signal in round %d\n", round);
+	  return 1;
+	}
+      if (WTERMSIG (status) != THESIGNAL)
+	{
+	  printf ("child did not die of signal %d in round %d\n",
+		  THESIGNAL, round);
+	  return 1;
+	}
+
+      for (int n = 0; n < N; ++n)
+	{
+	  int e = pthread_mutex_lock (&map[n]);
+	  if (e != 0 && e != EOWNERDEAD)
+	    {
+	      printf ("mutex_lock %d failed in round %d\n", n + 1, round);
+	      return 1;
+	    }
+	}
+
+      for (int n = 0; n < N; ++n)
+	if (pthread_mutex_unlock (&map[n]) != 0)
+	  {
+	    printf ("mutex_unlock %d failed in round %d\n", n + 1, round);
+	    return 1;
+	  }
+
+      for (int n = 0; n < N; ++n)
+	{
+	  int e = pthread_mutex_destroy (&map[n]);
+	  if (e != 0)
+	    {
+	      printf ("mutex_destroy %d in round %d failed with %d\n",
+		      n + 1, round, e);
+	      printf("nusers = %d\n", (int) map[n].__data.__nusers);
+	      return 1;
+	    }
+	}
+    }
+
+  if (pthread_mutexattr_destroy (&ma) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
+  if (munmap (map, N * sizeof (pthread_mutex_t)) != 0)
+    {
+      puts ("munmap failed");
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c b/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c
index bacf1bee0d..7228489098 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_llrintl.c
@@ -22,6 +22,7 @@
    when it's coded in C.  */
 
 #include <math.h>
+#include <fenv_libc.h>
 #include <math_ldbl_opt.h>
 #include <float.h>
 #include <ieee754.h>
@@ -36,89 +37,114 @@ __llrintl (x)
      long double x;
 #endif
 {
-  static const double TWO52 = 4503599627370496.0L;
-  union ibm_extended_long_double u;
-  long long result = __LONG_LONG_MAX__;
+  double xh, xl;
+  long long res, hi, lo;
+  int save_round;
 
-  u.d = x;
+  ldbl_unpack (x, &xh, &xl);
 
-  if (fabs (u.dd[0]) < TWO52)
+  /* Limit the range of values handled by the conversion to long long.
+     We do this because we aren't sure whether that conversion properly
+     raises FE_INVALID.  */
+  if (__builtin_expect
+      ((__builtin_fabs (xh) <= -(double) (-__LONG_LONG_MAX__ - 1)), 1)
+#if !defined (FE_INVALID)
+      || 1
+#endif
+    )
     {
-      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)
+      save_round = fegetround ();
+
+      if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0))
 	{
-	  high -= TWO52;
-	  high += TWO52;
-          if (high == 0.0) high = -0.0;
+	  /* When XH is 9223372036854775808.0, converting to long long will
+	     overflow, resulting in an invalid operation.  However, XL might
+	     be negative and of sufficient magnitude that the overall long
+	     double is in fact in range.  Avoid raising an exception.  In any
+	     case we need to convert this value specially, because
+	     the converted value is not exactly represented as a double
+	     thus subtracting HI from XH suffers rounding error.  */
+	  hi = __LONG_LONG_MAX__;
+	  xh = 1.0;
 	}
-      result = high;
-    }
-  else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0)
-    {
-      double high, low, tau;
-      long long lowint;
-      /* 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)
+      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.  */
-	      
-	      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;
+	  hi = (long long) xh;
+	  xh -= hi;
 	}
-      else if (u.dd[0] < 0.0)
+      ldbl_canonicalize (&xh, &xl);
+
+      lo = (long long) xh;
+
+      /* Peg at max/min values, assuming that the above conversions do so.
+         Strictly speaking, we can return anything for values that overflow,
+         but this is more useful.  */
+      res = hi + lo;
+
+      /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi).  */
+      if (__builtin_expect (((~(hi ^ lo) & (res ^ hi)) < 0), 0))
+	goto overflow;
+
+      xh -= lo;
+      ldbl_canonicalize (&xh, &xl);
+
+      hi = res;
+      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 (fabs (xh) < 0.5
+	      || (fabs (xh) == 0.5
+		  && ((xh > 0.0 && xl < 0.0)
+		      || (xh < 0.0 && xl > 0.0)
+		      || (xl == 0.0 && (res & 1) == 0))))
+	    return res;
+
+	  if (xh < 0.0)
+	    res -= 1;
+	  else
+	    res += 1;
+	  break;
+
+	case FE_TOWARDZERO:
+	  if (res > 0 && (xh < 0.0 || (xh == 0.0 && xl < 0.0)))
+	    res -= 1;
+	  else if (res < 0 && (xh > 0.0 || (xh == 0.0 && xl > 0.0)))
+	    res += 1;
+	  return res;
+	  break;
+
+	case FE_UPWARD:
+	  if (xh > 0.0 || (xh == 0.0 && xl > 0.0))
+	    res += 1;
+	  break;
+
+	case FE_DOWNWARD:
+	  if (xh < 0.0 || (xh == 0.0 && xl < 0.0))
+	    res -= 1;
+	  break;
 	}
-      lowint = low;
-      result = high;
-      result += lowint;
+
+      if (__builtin_expect (((~(hi ^ (res - hi)) & (res ^ hi)) < 0), 0))
+	goto overflow;
+
+      return res;
     }
   else
-   result = u.dd[0];     
+    {
+      if (xh > 0.0)
+	hi = __LONG_LONG_MAX__;
+      else if (xh < 0.0)
+	hi = -__LONG_LONG_MAX__ - 1;
+      else
+	/* Nan */
+	hi = 0;
+    }
 
-  return result;
+overflow:
+#ifdef FE_INVALID
+  feraiseexcept (FE_INVALID);
+#endif
+  return hi;
 }
 
 long_double_symbol (libm, __llrintl, llrintl);
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
index 567e7ecc07..103529d5a1 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
@@ -22,12 +22,11 @@
    when it's coded in C.  */
 
 #include <math.h>
-#include <fenv.h>
+#include <fenv_libc.h>
 #include <math_ldbl_opt.h>
 #include <float.h>
 #include <ieee754.h>
 
-
 #ifdef __STDC__
 long long
 __llroundl (long double x)
@@ -37,92 +36,95 @@ __llroundl (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;
-  long long result = __LONG_LONG_MAX__;
-
-  u.d = x;
-
-  if (fabs (u.dd[0]) < TWO52)
-    {      
-      fesetround(FE_TOWARDZERO);
-      if (u.dd[0] > 0.0)
+  double xh, xl;
+  long long res, hi, lo;
+
+  ldbl_unpack (x, &xh, &xl);
+
+  /* Limit the range of values handled by the conversion to long long.
+     We do this because we aren't sure whether that conversion properly
+     raises FE_INVALID.  */
+  if (__builtin_expect
+      ((__builtin_fabs (xh) <= -(double) (-__LONG_LONG_MAX__ - 1)), 1)
+#if !defined (FE_INVALID)
+      || 1
+#endif
+    )
+    {
+      if (__builtin_expect ((xh == -(double) (-__LONG_LONG_MAX__ - 1)), 0))
 	{
-	  u.dd[0] += HALF;
-	  u.dd[0] += TWO52;
-	  u.dd[0] -= TWO52;
+	  /* When XH is 9223372036854775808.0, converting to long long will
+	     overflow, resulting in an invalid operation.  However, XL might
+	     be negative and of sufficient magnitude that the overall long
+	     double is in fact in range.  Avoid raising an exception.  In any
+	     case we need to convert this value specially, because
+	     the converted value is not exactly represented as a double
+	     thus subtracting HI from XH suffers rounding error.  */
+	  hi = __LONG_LONG_MAX__;
+	  xh = 1.0;
 	}
-      else if (u.dd[0] < 0.0)
+      else
 	{
-	  u.dd[0] = TWO52 - (u.dd[0] - HALF);
-	  u.dd[0] = -(u.dd[0] - TWO52);
+	  hi = (long long) xh;
+	  xh -= hi;
 	}
-      fesetround(mode);
-      result = u.dd[0];
-    }
-  else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0)
-    {
-      double high, low;
-      long long lowint;
-      /* 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)
+      ldbl_canonicalize (&xh, &xl);
+
+      lo = (long long) xh;
+
+      /* Peg at max/min values, assuming that the above conversions do so.
+         Strictly speaking, we can return anything for values that overflow,
+         but this is more useful.  */
+      res = hi + lo;
+
+      /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi).  */
+      if (__builtin_expect (((~(hi ^ lo) & (res ^ hi)) < 0), 0))
+	goto overflow;
+
+      xh -= lo;
+      ldbl_canonicalize (&xh, &xl);
+
+      hi = res;
+      if (xh > 0.5)
+	{
+	  res += 1;
+	}
+      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 -= TWO52;
+	  if (xl > 0.0 || (xl == 0.0 && res >= 0))
+	    res += 1;
 	}
-      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);
+	  res -= 1;
 	}
-      fesetround(mode);
-      lowint = low;
-      result = high;
-      result += lowint;
+      else if (-xh == 0.5)
+	{
+	  if (xl < 0.0 || (xl == 0.0 && res <= 0))
+	    res -= 1;
+	}
+
+      if (__builtin_expect (((~(hi ^ (res - hi)) & (res ^ hi)) < 0), 0))
+	goto overflow;
+
+      return res;
     }
   else
-   {
-      result = u.dd[0];     
-   }
-  return result;
+    {
+      if (xh > 0.0)
+	hi = __LONG_LONG_MAX__;
+      else if (xh < 0.0)
+	hi = -__LONG_LONG_MAX__ - 1;
+      else
+	/* Nan */
+	hi = 0;
+    }
+
+overflow:
+#ifdef FE_INVALID
+  feraiseexcept (FE_INVALID);
+#endif
+  return hi;
 }
 
 long_double_symbol (libm, __llroundl, llroundl);
diff --git a/sysdeps/powerpc/powerpc32/fpu/fprsave.S b/sysdeps/powerpc/powerpc32/fpu/fprsave.S
index 597c3e611f..c05178775d 100644
--- a/sysdeps/powerpc/powerpc32/fpu/fprsave.S
+++ b/sysdeps/powerpc/powerpc32/fpu/fprsave.S
@@ -27,68 +27,86 @@ ENTRY(_savefpr_all)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_14)
 C_TEXT(_savef14):
 C_TEXT(_savefpr_14):	stfd	fp14,-144(r1)
+			cfi_offset(fp14,-144)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef15)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_15)
 C_TEXT(_savef15):
 C_TEXT(_savefpr_15):	stfd	fp15,-136(r1)
+			cfi_offset(fp15,-136)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef16)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_16)
 C_TEXT(_savef16):
 C_TEXT(_savefpr_16):	stfd	fp16,-128(r1)
+			cfi_offset(fp16,-128)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef17)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_17)
 C_TEXT(_savef17):
 C_TEXT(_savefpr_17):	stfd	fp17,-120(r1)
+			cfi_offset(fp17,-120)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef18)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_18)
 C_TEXT(_savef18):
 C_TEXT(_savefpr_18):	stfd	fp18,-112(r1)
+			cfi_offset(fp18,-112)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef19)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_19)
 C_TEXT(_savef19):
 C_TEXT(_savefpr_19):	stfd	fp19,-104(r1)
+			cfi_offset(fp19,-104)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef20)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_20)
 C_TEXT(_savef20):
 C_TEXT(_savefpr_20):	stfd	fp20,-96(r1)
+			cfi_offset(fp20,-96)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef21)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_21)
 C_TEXT(_savef21):
 C_TEXT(_savefpr_21):	stfd	fp21,-88(r1)
+			cfi_offset(fp21,-88)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef22)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_22)
 C_TEXT(_savef22):
 C_TEXT(_savefpr_22):	stfd	fp22,-80(r1)
+			cfi_offset(fp22,-80)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef23)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_23)
 C_TEXT(_savef23):
 C_TEXT(_savefpr_23):	stfd	fp23,-72(r1)
+			cfi_offset(fp23,-72)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef24)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_24)
 C_TEXT(_savef24):
 C_TEXT(_savefpr_24):	stfd	fp24,-64(r1)
+			cfi_offset(fp24,-64)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef25)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_25)
 C_TEXT(_savef25):
 C_TEXT(_savefpr_25):	stfd	fp25,-56(r1)
+			cfi_offset(fp25,-56)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef26)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_26)
 C_TEXT(_savef26):
 C_TEXT(_savefpr_26):	stfd	fp26,-48(r1)
+			cfi_offset(fp26,-48)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef27)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_27)
 C_TEXT(_savef27):
 C_TEXT(_savefpr_27):	stfd	fp27,-40(r1)
+			cfi_offset(fp27,-40)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef28)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_28)
 C_TEXT(_savef28):
 C_TEXT(_savefpr_28):	stfd	fp28,-32(r1)
+			cfi_offset(fp28,-32)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef29)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_29)
 C_TEXT(_savef29):
 C_TEXT(_savefpr_29):	stfd	fp29,-24(r1)	#save f29
 			stfd	fp30,-16(r1)	#save f30
 			stfd	fp31,-8(r1)	#save f31
+			cfi_offset(fp29,-24)
+			cfi_offset(fp30,-16)
+			cfi_offset(fp31,-8)
 			stw	r0,8(r1)	#save LR in callers frame
 			blr			#return
 END (_savefpr_all)
diff --git a/sysdeps/powerpc/powerpc32/gprsave0.S b/sysdeps/powerpc/powerpc32/gprsave0.S
index 8b81647dd7..c74272b56d 100644
--- a/sysdeps/powerpc/powerpc32/gprsave0.S
+++ b/sysdeps/powerpc/powerpc32/gprsave0.S
@@ -30,40 +30,59 @@
 ENTRY(_savegpr0_all)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_13)
 C_TEXT(_savegpr0_13):	stw	r13,-76(r1)
+			cfi_offset(r13,-76)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_14)
 C_TEXT(_savegpr0_14):	stw	r14,-72(r1)
+			cfi_offset(r14,-72)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_15)
 C_TEXT(_savegpr0_15):	stw	r15,-68(r1)
+			cfi_offset(r15,-68)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_16)
 C_TEXT(_savegpr0_16):	stw	r16,-64(r1)
+			cfi_offset(r16,-64)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_17)
 C_TEXT(_savegpr0_17):	stw	r17,-60(r1)
+			cfi_offset(r17,-60)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_18)
 C_TEXT(_savegpr0_18):	stw	r18,-56(r1)
+			cfi_offset(r18,-56)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_19)
 C_TEXT(_savegpr0_19):	stw	r19,-52(r1)
+			cfi_offset(r19,-52)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_20)
 C_TEXT(_savegpr0_20):	stw	r20,-48(r1)
+			cfi_offset(r20,-48)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_21)
 C_TEXT(_savegpr0_21):	stw	r21,-44(r1)
+			cfi_offset(r21,-44)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_22)
 C_TEXT(_savegpr0_22):	stw	r22,-40(r1)
+			cfi_offset(r22,-40)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_23)
 C_TEXT(_savegpr0_23):	stw	r23,-36(r1)
+			cfi_offset(r23,-36)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_24)
 C_TEXT(_savegpr0_24):	stw	r24,-32(r1)
+			cfi_offset(r24,-32)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_25)
 C_TEXT(_savegpr0_25):	stw	r25,-28(r1)
+			cfi_offset(r25,-28)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_26)
 C_TEXT(_savegpr0_26):	stw	r26,-24(r1)
+			cfi_offset(r26,-24)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_27)
 C_TEXT(_savegpr0_27):	stw	r27,-20(r1)
+			cfi_offset(r27,-20)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_28)
 C_TEXT(_savegpr0_28):	stw	r28,-16(r1)
+			cfi_offset(r28,-16)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_29)
 C_TEXT(_savegpr0_29):	stw	r29,-12(r1) #save r29
 			stw	r30,-8(r1)  #save r30
 			stw	r31,-4(r1)  #save r31
+			cfi_offset(r29,-12)
+			cfi_offset(r30,-8)
+			cfi_offset(r31,-4)
 			stw	r0,8(r1)    #save LR in callers frame
 			blr		    #return
 END (_savegpr0_all)
diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S
index c5afe5a3fa..9ca394dda2 100644
--- a/sysdeps/powerpc/powerpc64/dl-trampoline.S
+++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S
@@ -176,7 +176,9 @@ EALIGN(_dl_profile_resolve, 4, 0)
 /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
    need to call _dl_call_pltexit.  */
 	std	r31,-8(r1)
+	cfi_offset(r31,-8)
 	std	r30,-16(r1)
+	cfi_offset(r30,-16)
 /* We need to save the registers used to pass parameters, ie. r3 thru
    r10; the registers are saved in a stack frame.  */
 	stdu	r1,-FRAME_SIZE(r1)
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S b/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S
deleted file mode 100644
index aa487775d4..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_llrintl.S
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Round long double to long int.
-   IBM extended format long double version.
-   Copyright (C) 2004,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
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <sysdep.h>
-#include <math_ldbl_opt.h>
-
-	.section	".toc","aw"
-.LC0:	/* 2**52 */
-	.tc FD_43300000_0[TC],0x4330000000000000
-.LC1:	/* 2**63 */
-	.tc FD_43E00000_0[TC],0x43e0000000000000
-	.section	".text"
-
-/* long long int[r3] __llrintl (long double x[fp1,fp2])  */
-ENTRY (__llrintl)
-	lfd	fp13,.LC0@toc(2)
-	lfd	fp10,.LC1@toc(2)
-	fabs	fp0,fp1
-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO52)  */
-	fcmpu	cr6,fp0,fp10	/* if (fabs(x) > TWO63)  */
-	beq-	cr6,.L2
-	fctid	fp11,fp1	/* must delay this opperation to here  */
-	fctid	fp12,fp2	/* and avoid setting "invalid operation".  */
-	li	r0,0
-	stfd	fp11,-16(r1)
-	bgt-	cr6,.L9		/* if > TWO63 return  "invalid operation".  */
-	ble+	cr7,.L9		/* If < TWO52 only thy high double is used.  */
-	stfd	fp12,-8(r1)
-	nop	/* Insure the following load is in a different dispatch group */
-	nop	/* to avoid pipe stall on POWER4&5.  */
-	nop
-.L8:
-	ld	r0,-8(r1)
-.L9:
-	ld	r3,-16(r1)
-	add	r3,r3,r0
-	blr
-
-/* The high double is >= TWO63 so it looks like we are "out of range".
-   But this may be caused by rounding of the high double and the
-   negative low double may bring it back into range. So we need to
-   de-round the high double and invert the low double without changing
-   the effective long double value. To do this we compute a special
-   value (tau) that we can subtract from the high double and add to
-   the low double before conversion. The resulting integers can be
-   summed to get the total value.
-
-   tau = floor(x_high/TWO52);
-   x0 = x_high - tau;
-   x1 = x_low + tau;  */
-.L2:
-	fdiv	fp8,fp1,fp13	/* x_high/TWO52  */
-	fctidz	fp0,fp8
-	fcfid	fp8,fp0		/* tau = floor(x_high/TWO52);  */
-	fsub	fp3,fp1,fp8	/* x0 = x_high - tau;  */
-	fadd	fp4,fp2,fp8	/* x1 = x_low + tau;  */
-	fctid	fp11,fp3
-	fctid	fp12,fp4
-	stfd	fp11,-16(r1)
-	stfd	fp12,-8(r1)
-	nop	/* Insure the following load is in a different dispatch group */
-	nop	/* to avoid pipe stall on POWER4&5.  */
-	nop
-	ld	r3,-16(r1)
-	ld	r0,-8(r1)
-	addo.	r3,r3,r0
-	bnslr+  cr0		/* if the sum does not overflow, return.  */
-	fctid	fp11,fp1	/* Otherwise we want to set "invalid operation".  */
-	li	r0,0
-	stfd	fp11,-16(r1)
-	b	.L9
-
-END (__llrintl)
-
-strong_alias (__llrintl, __lrintl)
-long_double_symbol (libm, __llrintl, llrintl)
-long_double_symbol (libm, __lrintl, lrintl)
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S b/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S
deleted file mode 100644
index 29eca11093..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_llroundl.S
+++ /dev/null
@@ -1,167 +0,0 @@
-/* llroundl function.
-   IBM extended format long double version.
-   Copyright (C) 2004, 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
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <sysdep.h>
-#include <math_ldbl_opt.h>
-
-	.section	".toc","aw"
-.LC0:	/* 0.0 */
-	.tc FD_00000000_0[TC],0x0000000000000000
-.LC1:	/* 0.5 */
-	.tc FD_3fe00000_0[TC],0x3fe0000000000000
-.LC2:	/* 2**52 */
-	.tc FD_43300000_0[TC],0x4330000000000000
-.LC3:	/* 2**63 */
-	.tc FD_43E00000_0[TC],0x43e0000000000000
-	.section	".text"
-
-/* long long [r3] llround (long double x [fp1,fp2])
-   IEEE 1003.1 llroundl function.  IEEE specifies "round to the nearest
-   integer value, rounding halfway cases away from zero, regardless of
-   the current rounding mode."  However PowerPC Architecture defines
-   "round to Nearest" as "Choose the best approximation. In case of a
-   tie, choose the one that is even (least significant bit o).".
-   So we can't use the PowerPC "round to Nearest" mode. Instead we set
-   "round toward Zero" mode and round by adding +-0.5 before rounding
-   toward zero. The "Floating Convert To Integer Doubleword with round
-   toward zero" instruction handles the conversion including the
-   overflow cases and signalling "Invalid Operation".
-
-   PowerPC64 long double uses the IBM extended format which is
-   represented two 64-floating point double values. The values are
-   non-overlapping giving an effective precision of 106 bits. The first
-   double contains the high order bits of mantisa and is always rounded
-   to represent a normal rounding of long double to double. Since the
-   long double value is sum of the high and low values, the low double
-   normally has the opposite sign to compensate for the this rounding.
-
-   For long double there is 4 cases:
-   1) |x| < 2**52, all the integer bits are in the high double.
-      Round and convert the high double to long long.
-   2) 2**52 <= |x|< 2**63, Still fits but need bits from both doubles.
-      Round the low double, convert both, then sum the long long values.
-   3) |x| == 2**63, Looks like an overflow but may not be due to rounding
-      of the high double.
-      See the description following lable L2.
-   4) |x| > 2**63, This will overflow the 64-bit signed integer.
-      Treat like case #1. The fctidz instruction will generate the
-      appropriate and signal "invalid operation".
-
-   */
-
-ENTRY (__llroundl)
-	mffs	fp7		/* Save current FPU rounding mode.  */
-	fabs	fp0,fp1
-	lfd	fp13,.LC2@toc(2)	/* 2**52 */
-	lfd	fp12,.LC3@toc(2)	/* 2**63 */
-	lfd	fp11,.LC0@toc(2)	/* 0.0 */
-	lfd	fp10,.LC1@toc(2)	/* 0.5 */
-	fabs	fp9,fp2
-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO52)  */
-	fcmpu	cr6,fp1,fp11	/* if (x > 0.0)  */
-	bnl-	cr7,.L2
-	mtfsfi	7,1		/* Set rounding mode toward 0.  */
-	ble-	cr6,.L1
-	fadd	fp9,fp1,fp10	/* x+= 0.5;  */
-	b	.L0
-.L1:
-	fsub	fp9,fp1,fp10	/* x-= 0.5;  */
-.L0:
-	fctid	fp0,fp9
-	stfd	fp0,-16(r1)
-	mtfsf	0x01,fp7	/* restore previous rounding mode.  */
-	nop	/* Insure the following load is in a different dispatch group */
-	nop	/* to avoid pipe stall on POWER4&5.  */
-	nop
-	ld	r3,-16(r1)
-	blr
-
-/* The high double is > TWO52 so we need to round the low double and
-   perhaps the high double.  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.This gets a bit tricky so we use the
-   following algorithm:
-
-   tau = trunc(x_high/TWO52);
-   x0 = x_high - tau;
-   x1 = x_low + tau;
-   r1 = round(x1);
-   y_high = x0 + r1;
-   y_low = x0 - y_high + r1;
-   return y;  */
-.L2:
-	fcmpu	cr7,fp0,fp12	/* if (|x_high| > TWO63)  */
-	fcmpu	cr0,fp9,fp11	/* || (|x_low| == 0.0)  */
-	fmr	fp9,fp1
-	fcmpu	cr5,fp2,fp11	/* if (x_low > 0.0)  */
-	bgt-	cr7,.L0		/*   return llround(x);	*/
-	mtfsfi	7,1		/* Set rounding mode toward 0.  */
-	fdiv	fp8,fp1,fp13	/* x_high/TWO52  */
-	
-	bng-	cr6,.L6		/* if (x > 0.0)  */
-	fctidz	fp0,fp8
-	fcfid	fp8,fp0		/* tau = trunc(x_high/TWO52);  */
-	bng	cr5,.L4		/* if (x_low > 0.0)  */
-	fmr	fp3,fp1
-	fmr	fp4,fp2
-	b	.L5
-.L4:				/* if (x_low < 0.0)  */
-	fsub	fp3,fp1,fp8	/* x0 = x_high - tau;  */
-	fadd	fp4,fp2,fp8	/* x1 = x_low + tau;  */
-.L5:
-	fadd	fp5,fp4,fp10	/* r1 = x1 + 0.5;  */
-	b	.L9
-.L6:				/* if (x < 0.0)  */
-	fctidz	fp0,fp8
-	fcfid	fp8,fp0		/* tau = trunc(x_high/TWO52);  */	
-	bnl	cr5,.L7		/* if (x_low < 0.0)  */
-	fmr	fp3,fp1
-	fmr	fp4,fp2
-	b	.L8
-.L7:				/* if (x_low > 0.0)  */
-	fsub	fp3,fp1,fp8	/* x0 = x_high - tau;  */
-	fadd	fp4,fp2,fp8	/* x1 = x_low + tau;  */
-.L8:
-	fsub	fp5,fp4,fp10	/* r1 = x1 - 0.5;  */
-.L9:
-	fctid.	fp11,fp3
-	fctid	fp12,fp5
-	stfd	fp11,-16(r1)
-	stfd	fp12,-8(r1)
-	mtfsf	0x01,fp7	/* restore previous rounding mode.  */
-	nop	/* Insure the following load is in a different dispatch group */
-	nop	/* to avoid pipe stall on POWER4&5.  */
-	nop
-	ld	r3,-16(r1)
-	bunlr   cr1		/* if not overflow, return.  */
-	ld	r0,-8(r1)
-	addo.	r3,r3,r0
-	bnslr	cr0
-	fmr	fp9,fp12
-	bng	cr6,.L0
-	fneg	fp9,fp12
-	b	.L0
-END (__llroundl)
-
-strong_alias (__llroundl, __lroundl)
-long_double_symbol (libm, __llroundl, llroundl)
-long_double_symbol (libm, __lroundl, lroundl)
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S b/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S
deleted file mode 100644
index 6c82d2e222..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_lrintl.S
+++ /dev/null
@@ -1,2 +0,0 @@
-/* __lrintl is in s_llrintl.c  */
-/* __lrintl is in s_llrintl.c  */
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S b/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S
deleted file mode 100644
index b24dfd8ded..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_lroundl.S
+++ /dev/null
@@ -1,2 +0,0 @@
-/* __lroundl is in s_llroundl.S  */
-/* __lroundl is in s_llroundl.S  */
diff --git a/sysdeps/powerpc/powerpc64/memcpy.S b/sysdeps/powerpc/powerpc64/memcpy.S
index 9df5bb42b6..f395de9066 100644
--- a/sysdeps/powerpc/powerpc64/memcpy.S
+++ b/sysdeps/powerpc/powerpc64/memcpy.S
@@ -1,5 +1,5 @@
 /* Optimized memcpy implementation for PowerPC64.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
@@ -43,6 +43,7 @@ EALIGN (BP_SYM (memcpy), 5, 0)
     neg   0,3
     std   3,-16(1)
     std   31,-8(1)
+    cfi_offset(31,-8)
     andi. 11,3,7	/* check alignement of dst.  */
     clrldi 0,0,61	/* Number of bytes until the 1st doubleword of dst.  */
     clrldi 10,4,61	/* check alignement of src.  */
diff --git a/sysdeps/sparc/sparc32/bits/atomic.h b/sysdeps/sparc/sparc32/bits/atomic.h
index 707a4b0a52..ef553f7270 100644
--- a/sysdeps/sparc/sparc32/bits/atomic.h
+++ b/sysdeps/sparc/sparc32/bits/atomic.h
@@ -122,7 +122,7 @@ volatile unsigned char __sparc32_atomic_locks[64]
   __asm __volatile (".word 0xcde05005"					      \
 		    : "+r" (__acev_tmp), "=m" (*__acev_mem)		      \
 		    : "r" (__acev_oldval), "m" (*__acev_mem),		      \
-		      "r" (__acev_mem));				      \
+		      "r" (__acev_mem) : "memory");			      \
   __acev_tmp; })
 #endif
 
diff --git a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
index 36959a9926..7b9d61d468 100644
--- a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
+++ b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
@@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t;
   __asm __volatile ("cas [%4], %2, %0"					      \
 		    : "=r" (__acev_tmp), "=m" (*__acev_mem)		      \
 		    : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem),      \
-		      "0" (newval));					      \
+		      "0" (newval) : "memory");				      \
   __acev_tmp; })
 
 /* This can be implemented if needed.  */
@@ -74,7 +74,7 @@ typedef uintmax_t uatomic_max_t;
      if (sizeof (*(mem)) == 4)						      \
        __asm ("swap %0, %1"						      \
 	      : "=m" (*__memp), "=r" (__oldval)				      \
-	      : "m" (*__memp), "1" (__value));				      \
+	      : "m" (*__memp), "1" (__value) : "memory");		      \
      else								      \
        abort ();							      \
      __oldval; })
diff --git a/sysdeps/sparc/sparc64/bits/atomic.h b/sysdeps/sparc/sparc64/bits/atomic.h
index 2fb377810e..d0a64afce8 100644
--- a/sysdeps/sparc/sparc64/bits/atomic.h
+++ b/sysdeps/sparc/sparc64/bits/atomic.h
@@ -59,7 +59,7 @@ typedef uintmax_t uatomic_max_t;
   __asm __volatile ("cas [%4], %2, %0"					      \
 		    : "=r" (__acev_tmp), "=m" (*__acev_mem)		      \
 		    : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem),      \
-		      "0" (newval));					      \
+		      "0" (newval) : "memory");				      \
   __acev_tmp; })
 
 #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
@@ -69,7 +69,7 @@ typedef uintmax_t uatomic_max_t;
   __asm __volatile ("casx [%4], %2, %0"					      \
 		    : "=r" (__acev_tmp), "=m" (*__acev_mem)		      \
 		    : "r" ((long) (oldval)), "m" (*__acev_mem),		      \
-		      "r" (__acev_mem), "0" ((long) (newval)));		      \
+		      "r" (__acev_mem), "0" ((long) (newval)) : "memory");    \
   __acev_tmp; })
 
 #define atomic_exchange_acq(mem, newvalue) \
@@ -80,7 +80,7 @@ typedef uintmax_t uatomic_max_t;
      if (sizeof (*(mem)) == 4)						      \
        __asm ("swap %0, %1"						      \
 	      : "=m" (*__memp), "=r" (__oldval)				      \
-	      : "m" (*__memp), "1" (__value));				      \
+	      : "m" (*__memp), "1" (__value) : "memory");		      \
      else								      \
        {								      \
 	 __val = *__memp;						      \
diff --git a/sysdeps/unix/sysv/linux/alpha/getcontext.S b/sysdeps/unix/sysv/linux/alpha/getcontext.S
index bf9820ac73..f010f337e6 100644
--- a/sysdeps/unix/sysv/linux/alpha/getcontext.S
+++ b/sysdeps/unix/sysv/linux/alpha/getcontext.S
@@ -1,5 +1,5 @@
 /* Save current context.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 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
@@ -57,6 +57,8 @@ weak_alias (__getcontext, getcontext)
 __getcontext_x:
 	cfi_register (64, 0)
 
+	.set noat
+
 	/* Return value of getcontext.  $0 is the only register
 	   whose value is not preserved. */
 	stq	$31, UC_SIGCTX+SC_REGS($16)
diff --git a/sysdeps/unix/sysv/linux/bits/poll.h b/sysdeps/unix/sysv/linux/bits/poll.h
index dccb8b6665..d7996b46c5 100644
--- a/sysdeps/unix/sysv/linux/bits/poll.h
+++ b/sysdeps/unix/sysv/linux/bits/poll.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2001, 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
@@ -36,8 +36,10 @@
 #endif
 
 #ifdef __USE_GNU
-/* This is an extension for Linux.  */
+/* These are extensions for Linux.  */
 # define POLLMSG	0x400
+# define POLLREMOVE	0x1000
+# define POLLRDHUP	0x2000
 #endif
 
 /* Event types always implicitly polled for.  These bits need not be set in
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 9f3f3965f4..37d25b1a5c 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -105,10 +105,10 @@
 # define __ASSUME_STAT64_SYSCALL	1
 #endif
 
-/* On sparc and ARM the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64
+/* On sparc the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64
    syscalls were introduced in 2.3.35.  */
 #if __LINUX_KERNEL_VERSION >= 131875 \
-    && ((defined __sparc__ && !defined __arch64__) || defined __arm__)
+    && (defined __sparc__ && !defined __arch64__)
 # define __ASSUME_TRUNCATE64_SYSCALL	1
 # define __ASSUME_MMAP2_SYSCALL		1
 # define __ASSUME_STAT64_SYSCALL	1
@@ -191,7 +191,7 @@
    don't know when it got introduced).  But PowerPC64 does not support
    separate FCNTL64 call, FCNTL is already 64-bit */
 #if __LINUX_KERNEL_VERSION >= 132100 \
-    && (defined __arm__ || defined __powerpc__ || defined __sh__) \
+    && (defined __powerpc__ || defined __sh__) \
     && !defined __powerpc64__
 # define __ASSUME_FCNTL64		1
 #endif
@@ -260,24 +260,10 @@
 #endif
 
 /* The vfork syscall on x86 and arm was definitely available in 2.4.  */
-#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __arm__)
+#if __LINUX_KERNEL_VERSION >= 132097 && defined __i386__
 # define __ASSUME_VFORK_SYSCALL		1
 #endif
 
-/* There are an infinite number of PA-RISC kernel versions numbered
-   2.4.0.  But they've not really been released as such.  We require
-   and expect the final version here.  */
-#ifdef __hppa__
-# define __ASSUME_32BITUIDS		1
-# define __ASSUME_TRUNCATE64_SYSCALL	1
-# define __ASSUME_MMAP2_SYSCALL		1
-# define __ASSUME_STAT64_SYSCALL	1
-# define __ASSUME_IPC64			1
-# define __ASSUME_ST_INO_64_BIT		1
-# define __ASSUME_FCNTL64		1
-# define __ASSUME_GETDENTS64_SYSCALL	1
-#endif
-
 /* Alpha switched to a 64-bit timeval sometime before 2.2.0.  */
 #if __LINUX_KERNEL_VERSION >= 131584 && defined __alpha__
 # define __ASSUME_TIMEVAL64		1
@@ -296,15 +282,6 @@
 # define __ASSUME_CLONE_THREAD_FLAGS	1
 #endif
 
-/* These features were surely available with 2.4.12.  */
-#if __LINUX_KERNEL_VERSION >= 132108 && defined __mc68000__
-# define __ASSUME_MMAP2_SYSCALL		1
-# define __ASSUME_TRUNCATE64_SYSCALL	1
-# define __ASSUME_STAT64_SYSCALL	1
-# define __ASSUME_FCNTL64		1
-# define __ASSUME_VFORK_SYSCALL		1
-#endif
-
 /* Beginning with 2.5.63 support for realtime and monotonic clocks and
    timers based on them is available.  */
 #if __LINUX_KERNEL_VERSION >= 132415
@@ -359,7 +336,7 @@
 /* The utimes syscall has been available for some architectures
    forever.  For x86 it was introduced after 2.5.75, for x86-64,
    ppc, and ppc64 it was introduced in 2.6.0-test3.  */
-#if defined __alpha__ || defined __ia64__ || defined __hppa__ \
+#if defined __alpha__ || defined __ia64__ \
     || defined __sparc__ \
     || (__LINUX_KERNEL_VERSION > 132427 && defined __i386__) \
     || (__LINUX_KERNEL_VERSION > 132609 && defined __x86_64__) \
@@ -468,3 +445,9 @@
     && (defined __i386__ || defined __x86_64__)
 # define __ASSUME_ATFCTS	1
 #endif
+
+/* Support for inter-process robust mutexes was added in 2.6.17.  */
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+    && (defined __i386__ || defined __x86_64__)
+# define __ASSUME_SET_ROBUST_LIST	1
+#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
index 1a5251d100..40a7a24f19 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
@@ -45,6 +45,7 @@ ENTRY(__CONTEXT_FUNC_NAME)
 	stw	r0,20(r1)
 	cfi_offset (lr, _FRAME_LR_SAVE)
 	stw	r31,12(r1)
+	cfi_offset(r31,-4)
 	lwz	r31,_UC_REGS_PTR(r3)
 
 	/*
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
index a0f018ba41..366206d286 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -52,8 +52,12 @@ ENTRY (BP_SYM (__clone))
 	std	r29,56(r1)
 	std	r30,64(r1)
 	std	r31,72(r1)
+	cfi_offset(r29,-56)
+	cfi_offset(r30,-64)
+	cfi_offset(r31,-72)
 #ifdef RESET_PID
 	std	r28,48(r1)
+	cfi_offset(r28,-48)
 #endif
 
 	/* Set up stack frame for child.  */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
index 98b49ba1dc..8d7c959ff9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
@@ -144,6 +144,7 @@ ENTRY(__novec_getcontext)
   std  r0,FRAME_LR_SAVE(r1)
   cfi_offset (lr, FRAME_LR_SAVE)
   stdu r1,-128(r1)
+  cfi_adjust_cfa_offset(128)
   li   r3,ENOSYS
   bl   JUMPTARGET(__syscall_error)
   nop
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
index 68fec9d2aa..48e9af363d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
@@ -33,6 +33,7 @@ ENTRY(__novec_setcontext)
 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
   mflr  r0
   std   r31,-8(1)
+  cfi_offset(r31,-8)
   std   r0,FRAME_LR_SAVE(r1)
   cfi_offset (lr, FRAME_LR_SAVE)
   stdu  r1,-128(r1)
@@ -169,7 +170,9 @@ L(nv_do_sigret):
   /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub.  */
   mflr r0
   std  r0,FRAME_LR_SAVE(r1)
+  cfi_offset(lr,FRAME_LR_SAVE)
   stdu r1,-128(r1)
+  cfi_adjust_cfa_offset(128)
   li   r3,ENOSYS
   bl   JUMPTARGET(__syscall_error)
   nop
@@ -201,6 +204,7 @@ ENTRY(__setcontext)
 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
   mflr  r0
   std   r31,-8(1)
+  cfi_offset(r31,-8)
   std   r0,FRAME_LR_SAVE(r1)
   cfi_offset (lr, FRAME_LR_SAVE)
   stdu  r1,-128(r1)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
index 5a128606ad..936d641b6b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
@@ -35,6 +35,7 @@ ENTRY(__novec_swapcontext)
   std  r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
   mflr  r0
   std   r31,-8(1)
+  cfi_offset(r31,-8)
   std  r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
   std  r0,FRAME_LR_SAVE(r1)
   cfi_offset (lr, FRAME_LR_SAVE)
@@ -264,6 +265,7 @@ L(nv_do_sigret):
   /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub.  */
   mflr r0
   std  r0,FRAME_LR_SAVE(r1)
+  cfi_offset(lr,FRAME_LR_SAVE)
   stdu r1,-128(r1)
   li   r3,ENOSYS
   bl   JUMPTARGET(__syscall_error)
@@ -298,11 +300,14 @@ ENTRY(__swapcontext)
   std  r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
   mflr  r0
   std   r31,-8(1)
+  cfi_offset(r31,-8)
   std  r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
   std  r0,FRAME_LR_SAVE(r1)
+  cfi_offset (lr, FRAME_LR_SAVE)
   std  r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
   std  r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
   stdu  r1,-128(r1)
+  cfi_adjust_cfa_offset(128)
   std  r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
   std  r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
   std  r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/poll.h b/sysdeps/unix/sysv/linux/sparc/bits/poll.h
index f7a7393154..53b94bc50e 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/poll.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/poll.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 2001, 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
@@ -35,6 +35,13 @@
 # define POLLWRBAND	0x100		/* Priority data may be written.  */
 #endif
 
+#ifdef __USE_GNU
+/* These are extensions for Linux.  */
+# define POLLMSG	0x200
+# define POLLREMOVE	0x400
+# define POLLRDHUP	0x800
+#endif
+
 /* Event types always implicitly polled for.  These bits need not be set in
    `events', but they will appear in `revents' to indicate the status of
    the file descriptor.  */
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index 670dc79c4a..5dc7e19345 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -321,6 +321,7 @@ __END_NAMESPACE_C99
 #ifdef __USE_EXTERN_INLINES
 /* Define inline function as optimization.  */
 
+# ifndef __cplusplus
 /* We can use the BTOWC and WCTOB optimizations since we know that all
    locales must use ASCII encoding for the values in the ASCII range
    and because the wchar_t encoding is always ISO 10646.  */
@@ -335,6 +336,7 @@ extern __inline int
 __NTH (wctob (wint_t __wc))
 { return (__builtin_constant_p (__wc) && __wc >= L'\0' && __wc <= L'\x7f'
 	  ? (int) __wc : __wctob_alias (__wc)); }
+# endif
 
 extern __inline size_t
 __NTH (mbrlen (__const char *__restrict __s, size_t __n,
@@ -507,26 +509,30 @@ extern long double __wcstold_internal (__const wchar_t *__restrict __nptr,
 				       wchar_t **__restrict __endptr,
 				       int __group) __THROW;
 
-#ifndef __wcstol_internal_defined
+#if !defined __wcstol_internal_defined \
+    && defined __OPTIMIZE__ && __GNUC__ >= 2
 extern long int __wcstol_internal (__const wchar_t *__restrict __nptr,
 				   wchar_t **__restrict __endptr,
 				   int __base, int __group) __THROW;
 # define __wcstol_internal_defined	1
 #endif
-#ifndef __wcstoul_internal_defined
+#if !defined __wcstoul_internal_defined \
+    && defined __OPTIMIZE__ && __GNUC__ >= 2
 extern unsigned long int __wcstoul_internal (__const wchar_t *__restrict __npt,
 					     wchar_t **__restrict __endptr,
 					     int __base, int __group) __THROW;
 # define __wcstoul_internal_defined	1
 #endif
-#ifndef __wcstoll_internal_defined
+#if !defined __wcstoll_internal_defined \
+    && defined __OPTIMIZE__ && __GNUC__ >= 2
 __extension__
 extern long long int __wcstoll_internal (__const wchar_t *__restrict __nptr,
 					 wchar_t **__restrict __endptr,
 					 int __base, int __group) __THROW;
 # define __wcstoll_internal_defined	1
 #endif
-#ifndef __wcstoull_internal_defined
+#if !defined __wcstoull_internal_defined \
+    && defined __OPTIMIZE__ && __GNUC__ >= 2
 __extension__
 extern unsigned long long int __wcstoull_internal (__const wchar_t *
 						   __restrict __nptr,