about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/alpha/dl-machine.h28
-rw-r--r--sysdeps/alpha/libc-tls.c6
-rw-r--r--sysdeps/generic/ldsodefs.h72
-rw-r--r--sysdeps/generic/tls.h7
-rw-r--r--sysdeps/gnu/errlist-compat.awk12
-rw-r--r--sysdeps/gnu/netinet/tcp.h1
-rw-r--r--sysdeps/gnu/siglist.c27
-rw-r--r--sysdeps/i386/bits/byteswap.h6
-rw-r--r--sysdeps/i386/dl-machine.h12
-rw-r--r--sysdeps/i386/fpu/e_log.S11
-rw-r--r--sysdeps/i386/fpu/e_logf.S11
-rw-r--r--sysdeps/i386/fpu/e_logl.S11
-rw-r--r--sysdeps/i386/fpu/e_pow.S18
-rw-r--r--sysdeps/i386/fpu/e_powf.S18
-rw-r--r--sysdeps/i386/fpu/e_powl.S18
-rw-r--r--sysdeps/i386/fpu/math_private.h18
-rw-r--r--sysdeps/i386/fpu/s_nextafterl.c18
-rw-r--r--sysdeps/i386/fpu/s_nexttoward.c25
-rw-r--r--sysdeps/i386/fpu/s_nexttowardf.c25
-rw-r--r--sysdeps/i386/i486/bits/atomic.h370
-rw-r--r--sysdeps/i386/i686/memcmp.S70
-rw-r--r--sysdeps/i386/ldbl2mpn.c13
-rw-r--r--sysdeps/i386/soft-fp/sfp-machine.h89
-rw-r--r--sysdeps/i386/sysdep.h14
-rw-r--r--sysdeps/ia64/dl-machine.h6
-rw-r--r--sysdeps/ia64/fpu/fesetround.c6
-rw-r--r--sysdeps/ia64/ldbl2mpn.c1
-rw-r--r--sysdeps/ia64/libc-tls.c6
-rw-r--r--sysdeps/ieee754/dbl-64/e_pow.c22
-rw-r--r--sysdeps/ieee754/flt-32/s_nextafterf.c20
-rw-r--r--sysdeps/ieee754/ldbl-128/s_nextafterl.c18
-rw-r--r--sysdeps/ieee754/ldbl-128/s_nexttoward.c23
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c75
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/printf_fphex.c35
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c37
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c107
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c23
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c26
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nextafterl.c20
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nexttoward.c23
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nexttowardf.c28
-rw-r--r--sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c28
-rw-r--r--sysdeps/mach/hurd/fork.c4
-rw-r--r--sysdeps/mach/hurd/futimes.c18
-rw-r--r--sysdeps/mach/hurd/i386/tls.h5
-rw-r--r--sysdeps/mach/hurd/lutimes.c17
-rw-r--r--sysdeps/mach/hurd/utimes.c19
-rw-r--r--sysdeps/posix/euidaccess.c10
-rw-r--r--sysdeps/posix/getaddrinfo.c14
-rw-r--r--sysdeps/powerpc/fpu/bits/mathinline.h58
-rw-r--r--sysdeps/powerpc/fpu/math_private.h83
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.c6
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h8
-rw-r--r--sysdeps/powerpc/powerpc32/sysdep.h2
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.h11
-rw-r--r--sysdeps/s390/libc-tls.c8
-rw-r--r--sysdeps/s390/s390-32/dl-machine.h12
-rw-r--r--sysdeps/s390/s390-64/dl-machine.h12
-rw-r--r--sysdeps/sh/dl-machine.h6
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h4
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h4
-rw-r--r--sysdeps/unix/sysv/linux/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/bits/statvfs.h6
-rw-r--r--sysdeps/unix/sysv/linux/check_pf.c42
-rw-r--r--sysdeps/unix/sysv/linux/i386/clone.S4
-rw-r--r--sysdeps/unix/sysv/linux/i386/getgroups.c5
-rw-r--r--sysdeps/unix/sysv/linux/i386/sigaction.c14
-rw-r--r--sysdeps/unix/sysv/linux/ifaddrs.c75
-rw-r--r--sysdeps/unix/sysv/linux/internal_statvfs.c4
-rw-r--r--sysdeps/unix/sysv/linux/posix_madvise.c38
-rw-r--r--sysdeps/unix/sysv/linux/sh/bits/shm.h101
-rw-r--r--sysdeps/unix/sysv/linux/sh/sys/io.h48
-rw-r--r--sysdeps/unix/sysv/linux/sys/epoll.h20
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list4
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/clone.S4
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sigaction.c104
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym3
-rw-r--r--sysdeps/x86_64/bits/atomic.h334
-rw-r--r--sysdeps/x86_64/bits/byteswap.h7
-rw-r--r--sysdeps/x86_64/dl-machine.h8
-rw-r--r--sysdeps/x86_64/fpu/e_log10l.S5
-rw-r--r--sysdeps/x86_64/fpu/e_log2l.S5
-rw-r--r--sysdeps/x86_64/fpu/e_logl.S12
-rw-r--r--sysdeps/x86_64/fpu/e_powl.S19
-rw-r--r--sysdeps/x86_64/fpu/math_private.h21
-rw-r--r--sysdeps/x86_64/fpu/s_copysign.S5
-rw-r--r--sysdeps/x86_64/fpu/s_copysignf.S3
-rw-r--r--sysdeps/x86_64/fpu/s_log1pl.S5
-rw-r--r--sysdeps/x86_64/ldbl2mpn.c1
-rw-r--r--sysdeps/x86_64/soft-fp/sfp-machine.h51
91 files changed, 1371 insertions, 1287 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 88c357ea07..29f500b2d0 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  Alpha version.
-   Copyright (C) 1996-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson <rth@tamu.edu>.
 
@@ -232,14 +232,14 @@ $fixup_stack:							\n\
    to one of the main executable's symbols, as for a COPY reloc.
    This is unused on Alpha.  */
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
-#define elf_machine_type_class(type)	\
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
+# define elf_machine_type_class(type)	\
   (((type) == R_ALPHA_JMP_SLOT		\
     || (type) == R_ALPHA_DTPMOD64	\
     || (type) == R_ALPHA_DTPREL64	\
     || (type) == R_ALPHA_TPREL64) * ELF_RTYPE_CLASS_PLT)
 #else
-#define elf_machine_type_class(type)	\
+# define elf_machine_type_class(type)	\
   (((type) == R_ALPHA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
 #endif
 
@@ -439,40 +439,40 @@ elf_machine_rela (struct link_map *map,
 	  memcpy (reloc_addr_arg, &sym_value, 8);
 	}
 #endif
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
       else if (r_type == R_ALPHA_DTPMOD64)
 	{
-#ifdef RTLD_BOOTSTRAP
+# ifdef RTLD_BOOTSTRAP
 	  /* During startup the dynamic linker is always index 1.  */
 	  *reloc_addr = 1;
-#else
+# else
 	  /* Get the information from the link map returned by the
 	     resolv function.  */
 	  if (sym_map != NULL)
 	    *reloc_addr = sym_map->l_tls_modid;
-#endif
+# endif
 	}
       else if (r_type == R_ALPHA_DTPREL64)
 	{
-#ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
 	  /* During relocation all TLS symbols are defined and used.
 	     Therefore the offset is already correct.  */
 	  *reloc_addr = sym_raw_value;
-#endif
+# endif
 	}
       else if (r_type == R_ALPHA_TPREL64)
 	{
-#ifdef RTLD_BOOTSTRAP
+# ifdef RTLD_BOOTSTRAP
 	  *reloc_addr = sym_raw_value + map->l_tls_offset;
-#else
+# else
 	  if (sym_map)
 	    {
 	      CHECK_STATIC_TLS (map, sym_map);
 	      *reloc_addr = sym_raw_value + sym_map->l_tls_offset;
 	    }
-#endif
+# endif
 	}
-#endif /* USE_TLS */
+#endif
       else
 	_dl_reloc_bad_type (map, r_type, 0);
     }
diff --git a/sysdeps/alpha/libc-tls.c b/sysdeps/alpha/libc-tls.c
index 24629e9aca..7e02769171 100644
--- a/sysdeps/alpha/libc-tls.c
+++ b/sysdeps/alpha/libc-tls.c
@@ -1,5 +1,5 @@
 /* Thread-local storage handling in the ELF dynamic linker.  Alpha version.
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
@@ -20,8 +20,6 @@
 #include <csu/libc-tls.c>
 #include <dl-tls.h>
 
-#if USE_TLS
-
 /* On Alpha, linker optimizations are not required, so __tls_get_addr
    can be called even in statically linked binaries.  In this case module
    must be always 1 and PT_TLS segment exist in the binary, otherwise it
@@ -33,5 +31,3 @@ __tls_get_addr (tls_index *ti)
   dtv_t *dtv = THREAD_DTV ();
   return (char *) dtv[1].pointer.val + ti->ti_offset;
 }
-
-#endif
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index eee6141c6a..dda91bb806 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1,5 +1,5 @@
 /* Run-time dynamic linker data structures for loaded ELF shared objects.
-   Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1995-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
@@ -38,6 +38,7 @@
 #include <bits/libc-lock.h>
 #include <hp-timing.h>
 #include <tls.h>
+#include <rtld-lowlevel.h>
 
 __BEGIN_DECLS
 
@@ -438,23 +439,18 @@ struct rtld_global
   EXTERN void (*_dl_rtld_unlock_recursive) (void *);
 #endif
 
+  /* Prevailing state of the stack, PF_X indicating it's executable.  */
+  EXTERN ElfW(Word) _dl_stack_flags;
+
   /* If loading a shared object requires that we make the stack executable
      when it was not, we do it by calling this function.
      It returns an errno code or zero on success.  */
   EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;
 
-  /* Prevailing state of the stack, PF_X indicating it's executable.  */
-  EXTERN ElfW(Word) _dl_stack_flags;
-
-  /* Keep the conditional TLS members at the end so the layout of the
-     structure used by !USE_TLS code matches the prefix of the layout in
-     the USE_TLS rtld.  Note that `struct link_map' is conditionally
-     defined as well, so _dl_rtld_map needs to be last before this.  */
-#ifdef USE_TLS
-  /* Flag signalling whether there are gaps in the module ID allocation.  */
-  EXTERN bool _dl_tls_dtv_gaps;
   /* Highest dtv index currently needed.  */
   EXTERN size_t _dl_tls_max_dtv_idx;
+  /* Flag signalling whether there are gaps in the module ID allocation.  */
+  EXTERN bool _dl_tls_dtv_gaps;
   /* Information about the dtv slots.  */
   EXTERN struct dtv_slotinfo_list
   {
@@ -478,10 +474,10 @@ struct rtld_global
 /* Number of additional entries in the slotinfo array of each slotinfo
    list element.  A large number makes it almost certain take we never
    have to iterate beyond the first element in the slotinfo list.  */
-# define TLS_SLOTINFO_SURPLUS (62)
+#define TLS_SLOTINFO_SURPLUS (62)
 
 /* Number of additional slots in the dtv allocated.  */
-# define DTV_SURPLUS	(14)
+#define DTV_SURPLUS	(14)
 
   /* Initial dtv of the main thread, not allocated with normal malloc.  */
   EXTERN void *_dl_initial_dtv;
@@ -489,31 +485,18 @@ struct rtld_global
   EXTERN size_t _dl_tls_generation;
 
   EXTERN void (*_dl_init_static_tls) (struct link_map *);
-#endif
-
-  EXTERN void (*_dl_wait_lookup_done) (void);
 
-  /* Scopes to free after next THREAD_GSCOPE_WAIT ().  */
-  EXTERN struct dl_scope_free_list
-  {
-    size_t count;
-    struct r_scope_elem **list[50];
-  } *_dl_scope_free_list;
 #ifdef SHARED
 };
 # define __rtld_global_attribute__
 # ifdef IS_IN_rtld
-#  ifdef HAVE_VISIBILITY_ATTRIBUTE
-#   ifdef HAVE_SDATA_SECTION
-#    define __rtld_local_attribute__ \
+#  ifdef HAVE_SDATA_SECTION
+#   define __rtld_local_attribute__ \
 	    __attribute__ ((visibility ("hidden"), section (".sdata")))
-#    undef __rtld_global_attribute__
-#    define __rtld_global_attribute__ __attribute__ ((section (".sdata")))
-#   else
-#    define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
-#   endif
+#   undef __rtld_global_attribute__
+#   define __rtld_global_attribute__ __attribute__ ((section (".sdata")))
 #  else
-#   define __rtld_local_attribute__
+#   define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
 #  endif
 extern struct rtld_global _rtld_local __rtld_local_attribute__;
 #  undef __rtld_local_attribute__
@@ -549,15 +532,15 @@ struct rtld_global_ro
 #define DL_DEBUG_HELP       (1 << 9)
 #define DL_DEBUG_PRELINK    (1 << 10)
 
+  /* Cached value of `getpagesize ()'.  */
+  EXTERN size_t _dl_pagesize;
+
   /* OS version.  */
   EXTERN unsigned int _dl_osversion;
   /* Platform name.  */
   EXTERN const char *_dl_platform;
   EXTERN size_t _dl_platformlen;
 
-  /* Cached value of `getpagesize ()'.  */
-  EXTERN size_t _dl_pagesize;
-
   /* Copy of the content of `_dl_main_searchlist' at startup time.  */
   EXTERN struct r_scope_elem _dl_initial_searchlist;
 
@@ -586,6 +569,9 @@ struct rtld_global_ro
   /* Expected cache ID.  */
   EXTERN int _dl_correct_cache_id;
 
+  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
+  EXTERN int _dl_pointer_guard;
+
   /* Mask for hardware capabilities that are available.  */
   EXTERN uint64_t _dl_hwcap;
 
@@ -669,17 +655,10 @@ struct rtld_global_ro
   /* List of auditing interfaces.  */
   struct audit_ifaces *_dl_audit;
   unsigned int _dl_naudit;
-
-  /* 0 if internal pointer values should not be guarded, 1 if they should.  */
-  EXTERN int _dl_pointer_guard;
 };
 # define __rtld_global_attribute__
 # ifdef IS_IN_rtld
-#  ifdef HAVE_VISIBILITY_ATTRIBUTE
-#   define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
-#  else
-#   define __rtld_local_attribute__
-#  endif
+#  define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
 extern struct rtld_global_ro _rtld_local_ro
     attribute_relro __rtld_local_attribute__;
 extern struct rtld_global_ro _rtld_global_ro
@@ -1044,9 +1023,7 @@ rtld_hidden_proto (_dl_allocate_tls_init)
 extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function;
 rtld_hidden_proto (_dl_deallocate_tls)
 
-#if defined USE_TLS
 extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden;
-#endif
 
 /* Find origin of the executable.  */
 extern const char *_dl_get_origin (void) attribute_hidden;
@@ -1069,11 +1046,6 @@ extern void *_dl_open (const char *name, int mode, const void *caller,
 		       Lmid_t nsid, int argc, char *argv[], char *env[])
      attribute_hidden;
 
-/* Free or queue for freeing scope OLD.  If other threads might be
-   in the middle of _dl_fixup, _dl_profile_fixup or dl*sym using the
-   old scope, OLD can't be freed until no thread is using it.  */
-extern int _dl_scope_free (struct r_scope_elem **old) attribute_hidden;
-
 /* Add module to slot information data.  */
 extern void _dl_add_to_slotinfo (struct link_map  *l) attribute_hidden;
 
@@ -1085,8 +1057,6 @@ extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid);
    but never touch anything.  Return null if it's not allocated yet.  */
 extern void *_dl_tls_get_addr_soft (struct link_map *l) internal_function;
 
-extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
-     internal_function attribute_hidden;
 
 __END_DECLS
 
diff --git a/sysdeps/generic/tls.h b/sysdeps/generic/tls.h
index 6a23ec05e1..06e41ad121 100644
--- a/sysdeps/generic/tls.h
+++ b/sysdeps/generic/tls.h
@@ -1,5 +1,5 @@
 /* Definition for thread-local data handling.  Generic version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 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
@@ -17,11 +17,6 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* By default no TLS support is available.  This is signaled by the
-   absence of the symbol USE_TLS.  */
-#undef USE_TLS
-
-
 /* An architecture-specific version of this file has to defined a
    number of symbols:
 
diff --git a/sysdeps/gnu/errlist-compat.awk b/sysdeps/gnu/errlist-compat.awk
index ab67a18f64..307c4d7020 100644
--- a/sysdeps/gnu/errlist-compat.awk
+++ b/sysdeps/gnu/errlist-compat.awk
@@ -1,5 +1,5 @@
 # awk script to generate errlist-compat.c
-# Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+# Copyright (C) 2002, 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
@@ -92,16 +92,18 @@ END {
     printf "# include <bits/wordsize.h>\n";
     printf "extern const char *const __sys_errlist_%s[NERR];\n", old;
     printf "const int __sys_nerr_%s = %d;\n", old, n;
-    printf "strong_alias (_sys_errlist_internal, __sys_errlist_%s)\n", old;
-    printf "declare_symbol (__sys_errlist_%s, object, __WORDSIZE/8*%d)\n", \
-      old, n;
+    printf "declare_symbol_alias (__sys_errlist_%s, _sys_errlist_internal,", \
+      old;
+    printf " object, __WORDSIZE/8*%d)\n", n;
     printf "compat_symbol (libc, __sys_errlist_%s, sys_errlist, %s);\n", \
       old, old;
     printf "compat_symbol (libc, __sys_nerr_%s, sys_nerr, %s);\n", old, old;
 
     printf "extern const char *const ___sys_errlist_%s[NERR];\n", old;
     printf "extern const int __sys_nerr_%s;\n", old;
-    printf "strong_alias (__sys_errlist_%s, ___sys_errlist_%s)\n", old, old;
+    printf "declare_symbol_alias (___sys_errlist_%s, _sys_errlist_internal,", \
+      old;
+    printf " object, __WORDSIZE/8*%d)\n", n;
     printf "strong_alias (__sys_nerr_%s, ___sys_nerr_%s)\n", old, old;
     printf "compat_symbol (libc, ___sys_errlist_%s, _sys_errlist, %s);\n", \
       old, old;
diff --git a/sysdeps/gnu/netinet/tcp.h b/sysdeps/gnu/netinet/tcp.h
index 87099ec14a..2c04ec9b7f 100644
--- a/sysdeps/gnu/netinet/tcp.h
+++ b/sysdeps/gnu/netinet/tcp.h
@@ -49,6 +49,7 @@
 #define TCP_WINDOW_CLAMP 10	/* Bound advertised window */
 #define TCP_INFO	 11	/* Information about this connection. */
 #define	TCP_QUICKACK	 12	/* Bock/reenable quick ACKs.  */
+#define TCP_CONGESTION	 13	/* Congestion control algorithm.  */
 
 #ifdef __USE_MISC
 # include <sys/types.h>
diff --git a/sysdeps/gnu/siglist.c b/sysdeps/gnu/siglist.c
index cb1875f9eb..3005f867f0 100644
--- a/sysdeps/gnu/siglist.c
+++ b/sysdeps/gnu/siglist.c
@@ -1,5 +1,5 @@
 /* Define list of all signal numbers and their names.
-   Copyright (C) 1997-2000, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1997-2000, 2002, 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
@@ -40,27 +40,30 @@ const char *const __new_sys_sigabbrev[NSIG] =
 strong_alias (__new_sys_sigabbrev, _sys_sigabbrev_internal)
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
-strong_alias (_sys_siglist_internal, __old_sys_siglist)
-declare_symbol (__old_sys_siglist, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8)
+declare_symbol_alias (__old_sys_siglist, __new_sys_siglist, object,
+		      OLD_SIGLIST_SIZE * __WORDSIZE / 8)
 
-strong_alias (_sys_sigabbrev_internal, __old_sys_sigabbrev)
-declare_symbol (__old_sys_sigabbrev, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8)
+declare_symbol_alias (__old_sys_sigabbrev, __new_sys_sigabbrev, object,
+		      OLD_SIGLIST_SIZE * __WORDSIZE / 8)
+
+declare_symbol_alias (_old_sys_siglist, __new_sys_siglist, object,
+		      OLD_SIGLIST_SIZE * __WORDSIZE / 8)
 
-strong_alias (__old_sys_siglist, _old_sys_siglist)
 compat_symbol (libc, __old_sys_siglist, _sys_siglist, GLIBC_2_0);
 compat_symbol (libc, _old_sys_siglist, sys_siglist, GLIBC_2_0);
 compat_symbol (libc, __old_sys_sigabbrev, sys_sigabbrev, GLIBC_2_0);
 #endif
 
 #if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3) && defined OLD2_SIGLIST_SIZE
-strong_alias (_sys_siglist_internal, __old2_sys_siglist)
-declare_symbol (__old2_sys_siglist, object, OLD2_SIGLIST_SIZE * __WORDSIZE / 8)
+declare_symbol_alias (__old2_sys_siglist, __new_sys_siglist, object,
+		      OLD2_SIGLIST_SIZE * __WORDSIZE / 8)
+
+declare_symbol_alias (__old2_sys_sigabbrev, __new_sys_sigabbrev, object,
+		      OLD2_SIGLIST_SIZE * __WORDSIZE / 8)
 
-strong_alias (_sys_sigabbrev_internal, __old2_sys_sigabbrev)
-declare_symbol (__old2_sys_sigabbrev, object,
-		OLD2_SIGLIST_SIZE * __WORDSIZE / 8)
+declare_symbol_alias (_old2_sys_siglist, __new_sys_siglist, object,
+		      OLD2_SIGLIST_SIZE * __WORDSIZE / 8)
 
-strong_alias (__old2_sys_siglist, _old2_sys_siglist)
 compat_symbol (libc, __old2_sys_siglist, _sys_siglist, GLIBC_2_1);
 compat_symbol (libc, _old2_sys_siglist, sys_siglist, GLIBC_2_1);
 compat_symbol (libc, __old2_sys_sigabbrev, sys_sigabbrev, GLIBC_2_1);
diff --git a/sysdeps/i386/bits/byteswap.h b/sysdeps/i386/bits/byteswap.h
index 7f2ddc2dc5..bed27559c5 100644
--- a/sysdeps/i386/bits/byteswap.h
+++ b/sysdeps/i386/bits/byteswap.h
@@ -1,6 +1,5 @@
 /* Macros to swap the order of bytes in integer values.
-   Copyright (C) 1997, 1998, 2000, 2002, 2003, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1997,1998,2000,2002,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
@@ -67,8 +66,7 @@ __bswap_16 (unsigned short int __bsx)
    `bswap' opcode.  On i386 we have to use three instructions.  */
 #  if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
       && !defined __pentium4__ && !defined __k8__ && !defined __athlon__ \
-      && !defined __k6__ && !defined __nocona__ && !defined __core2__ \
-      && !defined __geode__ && !defined __amdfam10__
+      && !defined __k6__
 #   define __bswap_32(x)						      \
      (__extension__							      \
       ({ register unsigned int __v, __x = (x);				      \
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index df3edf5460..04296d2a9a 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  i386 version.
-   Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1995-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
@@ -34,9 +34,7 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
 }
 
 
-#if defined PI_STATIC_AND_HIDDEN \
-    && defined HAVE_VISIBILITY_ATTRIBUTE && defined HAVE_HIDDEN \
-    && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
+#ifdef PI_STATIC_AND_HIDDEN
 
 /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
    first element of the GOT, a special entry that is never relocated.  */
@@ -244,7 +242,7 @@ _dl_start_user:\n\
    define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 # define elf_machine_type_class(type) \
   ((((type) == R_386_JMP_SLOT || (type) == R_386_TLS_DTPMOD32		      \
      || (type) == R_386_TLS_DTPOFF32 || (type) == R_386_TLS_TPOFF32	      \
@@ -352,7 +350,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
 	  *reloc_addr = value;
 	  break;
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 	case R_386_TLS_DTPMOD32:
 # ifdef RTLD_BOOTSTRAP
 	  /* During startup the dynamic linker is always the module
@@ -476,7 +474,6 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  *reloc_addr = (value + reloc->r_addend - (Elf32_Addr) reloc_addr);
 	  break;
 
-#  ifdef USE_TLS
 	case R_386_TLS_DTPMOD32:
 	  /* Get the information from the link map returned by the
 	     resolv function.  */
@@ -513,7 +510,6 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 			    + reloc->r_addend;
 	    }
 	  break;
-#  endif	/* use TLS */
 	case R_386_COPY:
 	  if (sym == NULL)
 	    /* This can happen in trace mode if an object could not be
diff --git a/sysdeps/i386/fpu/e_log.S b/sysdeps/i386/fpu/e_log.S
index ce55b72292..5604e638f5 100644
--- a/sysdeps/i386/fpu/e_log.S
+++ b/sysdeps/i386/fpu/e_log.S
@@ -36,15 +36,11 @@ limit:	.double 0.29
 ENTRY(__ieee754_log)
 	fldln2			// log(2)
 	fldl	4(%esp)		// x : log(2)
-	fxam
-	fnstsw
 #ifdef PIC
 	LOAD_PIC_REG (dx)
 #endif
 	fld	%st		// x : x : log(2)
-	sahf
-	jc	3f		// in case x is NaN or +-Inf
-4:	fsubl	MO(one)		// x-1 : x : log(2)
+	fsubl	MO(one)		// x-1 : x : log(2)
 	fld	%st		// x-1 : x-1 : x : log(2)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
@@ -58,9 +54,4 @@ ENTRY(__ieee754_log)
 2:	fstp	%st(0)		// x : log(2)
 	fyl2x			// log(x)
 	ret
-
-3:	jp	4b		// in case x is +-Inf
-	fstp	%st(1)
-	fstp	%st(1)
-	ret
 END (__ieee754_log)
diff --git a/sysdeps/i386/fpu/e_logf.S b/sysdeps/i386/fpu/e_logf.S
index cd4538b594..128bb2754c 100644
--- a/sysdeps/i386/fpu/e_logf.S
+++ b/sysdeps/i386/fpu/e_logf.S
@@ -37,15 +37,11 @@ limit:	.double 0.29
 ENTRY(__ieee754_logf)
 	fldln2			// log(2)
 	flds	4(%esp)		// x : log(2)
-	fxam
-	fnstsw
 #ifdef PIC
 	LOAD_PIC_REG (dx)
 #endif
 	fld	%st		// x : x : log(2)
-	sahf
-	jc	3f		// in case x is NaN or +-Inf
-4:	fsubl	MO(one)		// x-1 : x : log(2)
+	fsubl	MO(one)		// x-1 : x : log(2)
 	fld	%st		// x-1 : x-1 : x : log(2)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
@@ -59,9 +55,4 @@ ENTRY(__ieee754_logf)
 2:	fstp	%st(0)		// x : log(2)
 	fyl2x			// log(x)
 	ret
-
-3:	jp	4b		// in case x is +-Inf
-	fstp	%st(1)
-	fstp	%st(1)
-	ret
 END (__ieee754_logf)
diff --git a/sysdeps/i386/fpu/e_logl.S b/sysdeps/i386/fpu/e_logl.S
index 551dcf1e46..5023d3012f 100644
--- a/sysdeps/i386/fpu/e_logl.S
+++ b/sysdeps/i386/fpu/e_logl.S
@@ -37,15 +37,11 @@ limit:	.double 0.29
 ENTRY(__ieee754_logl)
 	fldln2			// log(2)
 	fldt	4(%esp)		// x : log(2)
-	fxam
-	fnstsw
 #ifdef PIC
 	LOAD_PIC_REG (dx)
 #endif
 	fld	%st		// x : x : log(2)
-	sahf
-	jc	3f		// in case x is NaN or +-Inf
-4:	fsubl	MO(one)		// x-1 : x : log(2)
+	fsubl	MO(one)		// x-1 : x : log(2)
 	fld	%st		// x-1 : x-1 : x : log(2)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
@@ -59,9 +55,4 @@ ENTRY(__ieee754_logl)
 2:	fstp	%st(0)		// x : log(2)
 	fyl2x			// log(x)
 	ret
-
-3:	jp	4b		// in case x is +-Inf
-	fstp	%st(1)
-	fstp	%st(1)
-	ret
 END (__ieee754_logl)
diff --git a/sysdeps/i386/fpu/e_pow.S b/sysdeps/i386/fpu/e_pow.S
index 792f926902..c554ca4ecb 100644
--- a/sysdeps/i386/fpu/e_pow.S
+++ b/sysdeps/i386/fpu/e_pow.S
@@ -1,5 +1,5 @@
 /* ix87 specific implementation of pow function.
-   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007
+   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -161,11 +161,10 @@ ENTRY(__ieee754_pow)
 2:	/* y is a real number.  */
 	fxch			// x : y
 	fldl	MO(one)		// 1.0 : x : y
-	fldl	MO(limit)	// 0.29 : 1.0 : x : y
-	fld	%st(2)		// x : 0.29 : 1.0 : x : y
-	fsub	%st(2)		// x-1 : 0.29 : 1.0 : x : y
-	fabs			// |x-1| : 0.29 : 1.0 : x : y
-	fucompp			// 1.0 : x : y
+	fld	%st(1)		// x : 1.0 : x : y
+	fsub	%st(1)		// x-1 : 1.0 : x : y
+	fabs			// |x-1| : 1.0 : x : y
+	fcompl	MO(limit)	// 1.0 : x : y
 	fnstsw
 	fxch			// x : 1.0 : y
 	sahf
@@ -198,10 +197,9 @@ ENTRY(__ieee754_pow)
 	// y == ħinf
 	.align ALIGNARG(4)
 12:	fstp	%st(0)		// pop y
-	fldl	MO(one)		// 1
-	fldl	4(%esp)		// x : 1
-	fabs			// abs(x) : 1
-	fucompp			// < 1, == 1, or > 1
+	fldl	4(%esp)		// x
+	fabs
+	fcompl	MO(one)		// < 1, == 1, or > 1
 	fnstsw
 	andb	$0x45, %ah
 	cmpb	$0x45, %ah
diff --git a/sysdeps/i386/fpu/e_powf.S b/sysdeps/i386/fpu/e_powf.S
index c91545418d..c835b978b9 100644
--- a/sysdeps/i386/fpu/e_powf.S
+++ b/sysdeps/i386/fpu/e_powf.S
@@ -1,5 +1,5 @@
 /* ix87 specific implementation of pow function.
-   Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005, 2007
+   Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -155,11 +155,10 @@ ENTRY(__ieee754_powf)
 2:	/* y is a real number.  */
 	fxch			// x : y
 	fldl	MO(one)		// 1.0 : x : y
-	fldl	MO(limit)	// 0.29 : 1.0 : x : y
-	fld	%st(2)		// x : 0.29 : 1.0 : x : y
-	fsub	%st(2)		// x-1 : 0.29 : 1.0 : x : y
-	fabs			// |x-1| : 0.29 : 1.0 : x : y
-	fucompp			// 1.0 : x : y
+	fld	%st(1)		// x : 1.0 : x : y
+	fsub	%st(1)		// x-1 : 1.0 : x : y
+	fabs			// |x-1| : 1.0 : x : y
+	fcompl	MO(limit)	// 1.0 : x : y
 	fnstsw
 	fxch			// x : 1.0 : y
 	sahf
@@ -192,10 +191,9 @@ ENTRY(__ieee754_powf)
 	// y == ħinf
 	.align ALIGNARG(4)
 12:	fstp	%st(0)		// pop y
-	fldl	MO(one)		// 1
-	flds	4(%esp)		// x : 1
-	fabs			// abs(x) : 1
-	fucompp			// < 1, == 1, or > 1
+	flds	4(%esp)		// x
+	fabs
+	fcompl	MO(one)		// < 1, == 1, or > 1
 	fnstsw
 	andb	$0x45, %ah
 	cmpb	$0x45, %ah
diff --git a/sysdeps/i386/fpu/e_powl.S b/sysdeps/i386/fpu/e_powl.S
index 6215496207..74f422816a 100644
--- a/sysdeps/i386/fpu/e_powl.S
+++ b/sysdeps/i386/fpu/e_powl.S
@@ -1,5 +1,5 @@
 /* ix87 specific implementation of pow function.
-   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007
+   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -161,11 +161,10 @@ ENTRY(__ieee754_powl)
 2:	/* y is a real number.  */
 	fxch			// x : y
 	fldl	MO(one)		// 1.0 : x : y
-	fldl	MO(limit)	// 0.29 : 1.0 : x : y
-	fld	%st(2)		// x : 0.29 : 1.0 : x : y
-	fsub	%st(2)		// x-1 : 0.29 : 1.0 : x : y
-	fabs			// |x-1| : 0.29 : 1.0 : x : y
-	fucompp			// 1.0 : x : y
+	fld	%st(1)		// x : 1.0 : x : y
+	fsub	%st(1)		// x-1 : 1.0 : x : y
+	fabs			// |x-1| : 1.0 : x : y
+	fcompl	MO(limit)	// 1.0 : x : y
 	fnstsw
 	fxch			// x : 1.0 : y
 	sahf
@@ -211,10 +210,9 @@ ENTRY(__ieee754_powl)
 	// y == ħinf
 	.align ALIGNARG(4)
 12:	fstp	%st(0)		// pop y
-	fldl	MO(one)		// 1
-	fldt	4(%esp)		// x : 1
-	fabs			// abs(x) : 1
-	fucompp			// < 1, == 1, or > 1
+	fldt	4(%esp)		// x
+	fabs
+	fcompl	MO(one)		// < 1, == 1, or > 1
 	fnstsw
 	andb	$0x45, %ah
 	cmpb	$0x45, %ah
diff --git a/sysdeps/i386/fpu/math_private.h b/sysdeps/i386/fpu/math_private.h
deleted file mode 100644
index a426788ef1..0000000000
--- a/sysdeps/i386/fpu/math_private.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _MATH_PRIVATE_H
-
-#define math_opt_barrier(x) \
-({ __typeof(x) __x;					\
-   __asm ("" : "=t" (__x) : "0" (x));			\
-   __x; })
-#define math_force_eval(x) \
-do							\
-  {							\
-    if (sizeof (x) <= sizeof (double))			\
-      __asm __volatile ("" : : "m" (x));		\
-    else						\
-      __asm __volatile ("" : : "f" (x));		\
-  }							\
-while (0)
-
-#include <math/math_private.h>
-#endif
diff --git a/sysdeps/i386/fpu/s_nextafterl.c b/sysdeps/i386/fpu/s_nextafterl.c
index aef0a144e5..5b617cb4e7 100644
--- a/sysdeps/i386/fpu/s_nextafterl.c
+++ b/sysdeps/i386/fpu/s_nextafterl.c
@@ -27,7 +27,7 @@ static char rcsid[] = "$NetBSD: $";
  */
 
 #include "math.h"
-#include <math_private.h>
+#include "math_private.h"
 
 #ifdef __STDC__
 	long double __nextafterl(long double x, long double y)
@@ -52,12 +52,9 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if(x==y) return y;		/* x=y, return y */
 	if((ix|hx|lx)==0) {			/* x == 0 */
-	    long double u;
 	    SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    y = x*x;
+	    if(y==x) return y; else return x;	/* raise underflow flag */
 	}
 	if(esx>=0) {			/* x > 0 */
 	    if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
@@ -112,9 +109,12 @@ static char rcsid[] = "$NetBSD: $";
 	}
 	esy = esx&0x7fff;
 	if(esy==0x7fff) return x+x;	/* overflow  */
-	if(esy==0) {
-	    long double u = x*x;		/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(esy==0) {			/* underflow */
+	    y = x*x;
+	    if(y!=x) {		/* raise underflow flag */
+	        SET_LDOUBLE_WORDS(y,esx,hx,lx);
+		return y;
+	    }
 	}
 	SET_LDOUBLE_WORDS(x,esx,hx,lx);
 	return x;
diff --git a/sysdeps/i386/fpu/s_nexttoward.c b/sysdeps/i386/fpu/s_nexttoward.c
index 9bd86a3724..2bd768e448 100644
--- a/sysdeps/i386/fpu/s_nexttoward.c
+++ b/sysdeps/i386/fpu/s_nexttoward.c
@@ -27,8 +27,7 @@ static char rcsid[] = "$NetBSD: $";
  */
 
 #include "math.h"
-#include <math_private.h>
-#include <float.h>
+#include "math_private.h"
 
 #ifdef __STDC__
 	double __nexttoward(double x, long double y)
@@ -53,12 +52,10 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if((ix|lx)==0) {			/* x == 0 */
-	    double u;
+	    double x2;
 	    INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    x2 = x*x;
+	    if(x2==x) return x2; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
@@ -88,14 +85,16 @@ static char rcsid[] = "$NetBSD: $";
 	hy = hx&0x7ff00000;
 	if(hy>=0x7ff00000) {
 	  x = x+x;	/* overflow  */
-	  if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
-	    /* Force conversion to double.  */
-	    asm ("" : "+m"(x));
+	  /* Force conversion to double.  */
+	  asm ("" : "=m"(x) : "m"(x));
 	  return x;
 	}
-	if(hy<0x00100000) {
-	    double u = x*x;			/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy<0x00100000) {		/* underflow */
+	    double x2 = x*x;
+	    if(x2!=x) {		/* raise underflow flag */
+	        INSERT_WORDS(x2,hx,lx);
+		return x2;
+	    }
 	}
 	INSERT_WORDS(x,hx,lx);
 	return x;
diff --git a/sysdeps/i386/fpu/s_nexttowardf.c b/sysdeps/i386/fpu/s_nexttowardf.c
index 25f70e4f4d..3fbe53c338 100644
--- a/sysdeps/i386/fpu/s_nexttowardf.c
+++ b/sysdeps/i386/fpu/s_nexttowardf.c
@@ -19,8 +19,7 @@ static char rcsid[] = "$NetBSD: $";
 #endif
 
 #include "math.h"
-#include <math_private.h>
-#include <float.h>
+#include "math_private.h"
 
 #ifdef __STDC__
 	float __nexttowardf(float x, long double y)
@@ -45,12 +44,10 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if(ix==0) {				/* x == 0 */
-	    float u;
+	    float x2;
 	    SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    x2 = x*x;
+	    if(x2==x) return x2; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
@@ -72,14 +69,16 @@ static char rcsid[] = "$NetBSD: $";
 	hy = hx&0x7f800000;
 	if(hy>=0x7f800000) {
 	  x = x+x;	/* overflow  */
-	  if (FLT_EVAL_METHOD != 0)
-	    /* Force conversion to float.  */
-	    asm ("" : "+m"(x));
+	  /* Force conversion to float.  */
+	  asm ("" : "=m"(x) : "m"(x));
 	  return x;
 	}
-	if(hy<0x00800000) {
-	    float u = x*x;			/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy<0x00800000) {		/* underflow */
+	    float x2 = x*x;
+	    if(x2!=x) {		/* raise underflow flag */
+	        SET_FLOAT_WORD(x2,hx);
+		return x2;
+	    }
 	}
 	SET_FLOAT_WORD(x,hx);
 	return x;
diff --git a/sysdeps/i386/i486/bits/atomic.h b/sysdeps/i386/i486/bits/atomic.h
index c748761758..a27734c37e 100644
--- a/sysdeps/i386/i486/bits/atomic.h
+++ b/sysdeps/i386/i486/bits/atomic.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <stdint.h>
+#include <tls.h>	/* For tcbhead_t.  */
 
 
 typedef int8_t atomic8_t;
@@ -76,6 +77,40 @@ typedef uintmax_t uatomic_max_t;
 		       : "r" (newval), "m" (*mem), "0" (oldval));	      \
      ret; })
 
+
+#define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+     __asm __volatile ("cmpl $0, %%gs:%P5\n\t"                                \
+                       "je 0f\n\t"                                            \
+                       "lock\n"                                               \
+                       "0:\tcmpxchgb %b2, %1"				      \
+		       : "=a" (ret), "=m" (*mem)			      \
+		       : "q" (newval), "m" (*mem), "0" (oldval),	      \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
+     ret; })
+
+#define __arch_c_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+     __asm __volatile ("cmpl $0, %%gs:%P5\n\t"                                \
+                       "je 0f\n\t"                                            \
+                       "lock\n"                                               \
+                       "0:\tcmpxchgw %w2, %1"				      \
+		       : "=a" (ret), "=m" (*mem)			      \
+		       : "r" (newval), "m" (*mem), "0" (oldval),	      \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
+     ret; })
+
+#define __arch_c_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+     __asm __volatile ("cmpl $0, %%gs:%P5\n\t"                                \
+                       "je 0f\n\t"                                            \
+                       "lock\n"                                               \
+                       "0:\tcmpxchgl %2, %1"				      \
+		       : "=a" (ret), "=m" (*mem)			      \
+		       : "r" (newval), "m" (*mem), "0" (oldval),	      \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
+     ret; })
+
 /* XXX We do not really need 64-bit compare-and-exchange.  At least
    not in the moment.  Using it would mean causing portability
    problems since not many other 32-bit architectures have support for
@@ -85,6 +120,8 @@ typedef uintmax_t uatomic_max_t;
 #if 1
 # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
   ({ __typeof (*mem) ret = *(mem); abort (); ret = (newval); ret = (oldval); })
+# define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret = *(mem); abort (); ret = (newval); ret = (oldval); })
 #else
 # ifdef __PIC__
 #  define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
@@ -100,6 +137,24 @@ typedef uintmax_t uatomic_max_t;
 					  & 0xffffffff),		      \
 			 "d" (((unsigned long long int) (oldval)) >> 32));    \
      ret; })
+
+#  define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+     __asm __volatile ("xchgl %2, %%ebx\n\t"				      \
+		       "cmpl $0, %%gs:%P7\n\t"				      \
+		       "je 0f\n\t"					      \
+		       "lock\n"						      \
+		       "0:\tcmpxchg8b %1\n\t"				      \
+		       "xchgl %2, %%ebx"				      \
+		       : "=A" (ret), "=m" (*mem)			      \
+		       : "DS" (((unsigned long long int) (newval))	      \
+			       & 0xffffffff),				      \
+			 "c" (((unsigned long long int) (newval)) >> 32),     \
+			 "m" (*mem), "a" (((unsigned long long int) (oldval)) \
+					  & 0xffffffff),		      \
+			 "d" (((unsigned long long int) (oldval)) >> 32),     \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
+     ret; })
 # else
 #  define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
   ({ __typeof (*mem) ret;						      \
@@ -112,6 +167,22 @@ typedef uintmax_t uatomic_max_t;
 					  & 0xffffffff),		      \
 			 "d" (((unsigned long long int) (oldval)) >> 32));    \
      ret; })
+
+#  define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+     __asm __volatile ("cmpl $0, %%gs:%P7\n\t"				      \
+		       "je 0f\n\t"					      \
+		       "lock\n"						      \
+		       "0:\tcmpxchg8b %1"				      \
+		       : "=A" (ret), "=m" (*mem)			      \
+		       : "b" (((unsigned long long int) (newval))	      \
+			      & 0xffffffff),				      \
+			 "c" (((unsigned long long int) (newval)) >> 32),     \
+			 "m" (*mem), "a" (((unsigned long long int) (oldval)) \
+					  & 0xffffffff),		      \
+			 "d" (((unsigned long long int) (oldval)) >> 32),     \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
+     ret; })
 # endif
 #endif
 
@@ -139,21 +210,24 @@ typedef uintmax_t uatomic_max_t;
      result; })
 
 
-#define atomic_exchange_and_add(mem, value) \
+#define __arch_exchange_and_add_body(lock, pfx, mem, value) \
   ({ __typeof (*mem) __result;						      \
      __typeof (value) __addval = (value);				      \
      if (sizeof (*mem) == 1)						      \
-       __asm __volatile (LOCK_PREFIX "xaddb %b0, %1"			      \
+       __asm __volatile (lock "xaddb %b0, %1"				      \
 			 : "=r" (__result), "=m" (*mem)			      \
-			 : "0" (__addval), "m" (*mem));			      \
+			 : "0" (__addval), "m" (*mem),			      \
+			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      else if (sizeof (*mem) == 2)					      \
-       __asm __volatile (LOCK_PREFIX "xaddw %w0, %1"			      \
+       __asm __volatile (lock "xaddw %w0, %1"				      \
 			 : "=r" (__result), "=m" (*mem)			      \
-			 : "0" (__addval), "m" (*mem));			      \
+			 : "0" (__addval), "m" (*mem),			      \
+			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      else if (sizeof (*mem) == 4)					      \
-       __asm __volatile (LOCK_PREFIX "xaddl %0, %1"			      \
+       __asm __volatile (lock "xaddl %0, %1"				      \
 			 : "=r" (__result), "=m" (*mem)			      \
-			 : "0" (__addval), "m" (*mem));			      \
+			 : "0" (__addval), "m" (*mem),			      \
+			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      else								      \
        {								      \
 	 __typeof (mem) __memp = (mem);					      \
@@ -161,41 +235,64 @@ typedef uintmax_t uatomic_max_t;
 	 __result = *__memp;						      \
 	 do								      \
 	   __tmpval = __result;						      \
-	 while ((__result = __arch_compare_and_exchange_val_64_acq	      \
+	 while ((__result = pfx##_compare_and_exchange_val_64_acq	      \
 		 (__memp, __result + __addval, __result)) == __tmpval);	      \
        }								      \
      __result; })
 
+#define atomic_exchange_and_add(mem, value) \
+  __arch_exchange_and_add_body (LOCK_PREFIX, __arch, mem, value)
+
+#define __arch_exchange_and_add_cprefix \
+  "cmpl $0, %%gs:%P4\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_exchange_and_add(mem, value) \
+  __arch_exchange_and_add_body (__arch_exchange_and_add_cprefix, __arch_c,    \
+				mem, value)
+
+
+#define __arch_add_body(lock, pfx, mem, value) \
+  do {									      \
+    if (__builtin_constant_p (value) && (value) == 1)			      \
+      atomic_increment (mem);						      \
+    else if (__builtin_constant_p (value) && (value) == -1)		      \
+      atomic_decrement (mem);						      \
+    else if (sizeof (*mem) == 1)					      \
+      __asm __volatile (lock "addb %b1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (value), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (lock "addw %w1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (value), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (lock "addl %1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (value), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else								      \
+      {									      \
+	__typeof (value) __addval = (value);				      \
+	__typeof (mem) __memp = (mem);					      \
+	__typeof (*mem) __oldval = *__memp;				      \
+	__typeof (*mem) __tmpval;					      \
+	do								      \
+	  __tmpval = __oldval;						      \
+	while ((__oldval = pfx##_compare_and_exchange_val_64_acq	      \
+		(__memp, __oldval + __addval, __oldval)) == __tmpval);	      \
+      }									      \
+  } while (0)
 
 #define atomic_add(mem, value) \
-  (void) ({ if (__builtin_constant_p (value) && (value) == 1)		      \
-	      atomic_increment (mem);					      \
-	    else if (__builtin_constant_p (value) && (value) == -1)	      \
-	      atomic_decrement (mem);					      \
-	    else if (sizeof (*mem) == 1)				      \
-	      __asm __volatile (LOCK_PREFIX "addb %b1, %0"		      \
-				: "=m" (*mem)				      \
-				: "ir" (value), "m" (*mem));		      \
-	    else if (sizeof (*mem) == 2)				      \
-	      __asm __volatile (LOCK_PREFIX "addw %w1, %0"		      \
-				: "=m" (*mem)				      \
-				: "ir" (value), "m" (*mem));		      \
-	    else if (sizeof (*mem) == 4)				      \
-	      __asm __volatile (LOCK_PREFIX "addl %1, %0"		      \
-				: "=m" (*mem)				      \
-				: "ir" (value), "m" (*mem));		      \
-	    else							      \
-	      {								      \
-		__typeof (value) __addval = (value);			      \
-		__typeof (mem) __memp = (mem);				      \
-		__typeof (*mem) __oldval = *__memp;			      \
-		__typeof (*mem) __tmpval;				      \
-		do							      \
-		  __tmpval = __oldval;					      \
-		while ((__oldval = __arch_compare_and_exchange_val_64_acq     \
-		       (__memp, __oldval + __addval, __oldval)) == __tmpval); \
-	      }								      \
-	    })
+  __arch_add_body (LOCK_PREFIX, __arch, mem, value)
+
+#define __arch_add_cprefix \
+  "cmpl $0, %%gs:%P3\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_add(mem, value) \
+  __arch_add_body (__arch_add_cprefix, __arch_c, mem, value)
 
 
 #define atomic_add_negative(mem, value) \
@@ -236,30 +333,42 @@ typedef uintmax_t uatomic_max_t;
      __result; })
 
 
-#define atomic_increment(mem) \
-  (void) ({ if (sizeof (*mem) == 1)					      \
-	      __asm __volatile (LOCK_PREFIX "incb %b0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else if (sizeof (*mem) == 2)				      \
-	      __asm __volatile (LOCK_PREFIX "incw %w0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else if (sizeof (*mem) == 4)				      \
-	      __asm __volatile (LOCK_PREFIX "incl %0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else							      \
-	      {								      \
-		__typeof (mem) __memp = (mem);				      \
-		__typeof (*mem) __oldval = *__memp;			      \
-		__typeof (*mem) __tmpval;				      \
-		do							      \
-		  __tmpval = __oldval;					      \
-		while ((__oldval = __arch_compare_and_exchange_val_64_acq     \
-		       (__memp, __oldval + 1, __oldval)) == __tmpval);	      \
-	      }								      \
-	    })
+#define __arch_increment_body(lock,  pfx, mem) \
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (lock "incb %b0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (lock "incw %w0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (lock "incl %0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else								      \
+      {									      \
+	__typeof (mem) __memp = (mem);					      \
+	__typeof (*mem) __oldval = *__memp;				      \
+	__typeof (*mem) __tmpval;					      \
+	do								      \
+	  __tmpval = __oldval;						      \
+	while ((__oldval = pfx##_compare_and_exchange_val_64_acq	      \
+		(__memp, __oldval + 1, __oldval)) == __tmpval);		      \
+      }									      \
+  } while (0)
+
+#define atomic_increment(mem) __arch_increment_body (LOCK_PREFIX, __arch, mem)
+
+#define __arch_increment_cprefix \
+  "cmpl $0, %%gs:%P2\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_increment(mem) \
+  __arch_increment_body (__arch_increment_cprefix, __arch_c, mem)
 
 
 #define atomic_increment_and_test(mem) \
@@ -281,30 +390,42 @@ typedef uintmax_t uatomic_max_t;
      __result; })
 
 
-#define atomic_decrement(mem) \
-  (void) ({ if (sizeof (*mem) == 1)					      \
-	      __asm __volatile (LOCK_PREFIX "decb %b0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else if (sizeof (*mem) == 2)				      \
-	      __asm __volatile (LOCK_PREFIX "decw %w0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else if (sizeof (*mem) == 4)				      \
-	      __asm __volatile (LOCK_PREFIX "decl %0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else							      \
-	      {								      \
-		__typeof (mem) __memp = (mem);				      \
-		__typeof (*mem) __oldval = *__memp;			      \
-		__typeof (*mem) __tmpval;				      \
-		do							      \
-		  __tmpval = __oldval;					      \
-		while ((__oldval = __arch_compare_and_exchange_val_64_acq     \
-		       (__memp, __oldval - 1, __oldval)) == __tmpval); 	      \
-	      }								      \
-	    })
+#define __arch_decrement_body(lock, pfx, mem) \
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (lock "decb %b0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (lock "decw %w0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (lock "decl %0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else								      \
+      {									      \
+	__typeof (mem) __memp = (mem);					      \
+	__typeof (*mem) __oldval = *__memp;				      \
+	__typeof (*mem) __tmpval;					      \
+	do								      \
+	  __tmpval = __oldval;						      \
+	while ((__oldval = pfx##_compare_and_exchange_val_64_acq	      \
+		(__memp, __oldval - 1, __oldval)) == __tmpval); 	      \
+      }									      \
+  } while (0)
+
+#define atomic_decrement(mem) __arch_decrement_body (LOCK_PREFIX, __arch, mem)
+
+#define __arch_decrement_cprefix \
+  "cmpl $0, %%gs:%P2\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_decrement(mem) \
+  __arch_decrement_body (__arch_decrement_cprefix, __arch_c, mem)
 
 
 #define atomic_decrement_and_test(mem) \
@@ -327,21 +448,22 @@ typedef uintmax_t uatomic_max_t;
 
 
 #define atomic_bit_set(mem, bit) \
-  (void) ({ if (sizeof (*mem) == 1)					      \
-	      __asm __volatile (LOCK_PREFIX "orb %b2, %0"		      \
-				: "=m" (*mem)				      \
-				: "m" (*mem), "ir" (1 << (bit)));	      \
-	    else if (sizeof (*mem) == 2)				      \
-	      __asm __volatile (LOCK_PREFIX "orw %w2, %0"		      \
-				: "=m" (*mem)				      \
-				: "m" (*mem), "ir" (1 << (bit)));	      \
-	    else if (sizeof (*mem) == 4)				      \
-	      __asm __volatile (LOCK_PREFIX "orl %2, %0"		      \
-				: "=m" (*mem)				      \
-				: "m" (*mem), "ir" (1 << (bit)));	      \
-	    else							      \
-	      abort ();							      \
-	    })
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (LOCK_PREFIX "orb %b2, %0"			      \
+			: "=m" (*mem)					      \
+			: "m" (*mem), "ir" (1 << (bit)));		      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (LOCK_PREFIX "orw %w2, %0"			      \
+			: "=m" (*mem)					      \
+			: "m" (*mem), "ir" (1 << (bit)));		      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (LOCK_PREFIX "orl %2, %0"			      \
+			: "=m" (*mem)					      \
+			: "m" (*mem), "ir" (1 << (bit)));		      \
+    else								      \
+      abort ();								      \
+  } while (0)
 
 
 #define atomic_bit_test_set(mem, bit) \
@@ -364,3 +486,51 @@ typedef uintmax_t uatomic_max_t;
 
 
 #define atomic_delay() asm ("rep; nop")
+
+
+#define atomic_and(mem, mask) \
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (LOCK_PREFIX "andb %1, %b0"			      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem));			      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (LOCK_PREFIX "andw %1, %w0"			      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem));			      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (LOCK_PREFIX "andl %1, %0"			      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem));			      \
+    else								      \
+      abort ();								      \
+  } while (0)
+
+
+#define __arch_or_body(lock, mem, mask) \
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (lock "orb %1, %b0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (lock "orw %1, %w0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (lock "orl %1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else								      \
+      abort ();								      \
+  } while (0)
+
+#define atomic_or(mem, mask) __arch_or_body (LOCK_PREFIX, mem, mask)
+
+#define __arch_or_cprefix \
+  "cmpl $0, %%gs:%P3\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_or(mem, mask) __arch_or_body (__arch_or_cprefix, mem, mask)
diff --git a/sysdeps/i386/i686/memcmp.S b/sysdeps/i386/i686/memcmp.S
index 4bd5394bec..4fa6adea98 100644
--- a/sysdeps/i386/i686/memcmp.S
+++ b/sysdeps/i386/i686/memcmp.S
@@ -1,5 +1,5 @@
 /* Compare two memory blocks for differences in the first COUNT bytes.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -44,13 +44,9 @@
      absolute address.  */						      \
   addl	(%ebx,INDEX,4), %ebx
 
-#ifdef HAVE_HIDDEN
 	.section	.gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
 	.globl	__i686.get_pc_thunk.bx
 	.hidden	__i686.get_pc_thunk.bx
-#else
-        .text
-#endif
 	ALIGN (4)
 	.type	__i686.get_pc_thunk.bx,@function
 __i686.get_pc_thunk.bx:
@@ -384,38 +380,38 @@ END (BP_SYM (memcmp))
 	.section	.rodata
 	ALIGN (2)
 L(table_32bytes) :
-	.long	L(0bytes) - . + 0x0
-	.long	L(1bytes) - . + 0x4
-	.long	L(2bytes) - . + 0x8
-	.long	L(3bytes) - . + 0xc
-	.long	L(4bytes) - . + 0x10
-	.long	L(5bytes) - . + 0x14
-	.long	L(6bytes) - . + 0x18
-	.long	L(7bytes) - . + 0x1c
-	.long	L(8bytes) - . + 0x20
-	.long	L(9bytes) - . + 0x24
-	.long	L(10bytes) - . + 0x28
-	.long	L(11bytes) - . + 0x2c
-	.long	L(12bytes) - . + 0x30
-	.long	L(13bytes) - . + 0x34
-	.long	L(14bytes) - . + 0x38
-	.long	L(15bytes) - . + 0x3c
-	.long	L(16bytes) - . + 0x40
-	.long	L(17bytes) - . + 0x44
-	.long	L(18bytes) - . + 0x48
-	.long	L(19bytes) - . + 0x4c
-	.long	L(20bytes) - . + 0x50
-	.long	L(21bytes) - . + 0x54
-	.long	L(22bytes) - . + 0x58
-	.long	L(23bytes) - . + 0x5c
-	.long	L(24bytes) - . + 0x60
-	.long	L(25bytes) - . + 0x64
-	.long	L(26bytes) - . + 0x68
-	.long	L(27bytes) - . + 0x6c
-	.long	L(28bytes) - . + 0x70
-	.long	L(29bytes) - . + 0x74
-	.long	L(30bytes) - . + 0x78
-	.long	L(31bytes) - . + 0x7c
+	.long	L(0bytes) - L(table_32bytes)
+	.long	L(1bytes) - L(table_32bytes)
+	.long	L(2bytes) - L(table_32bytes)
+	.long	L(3bytes) - L(table_32bytes)
+	.long	L(4bytes) - L(table_32bytes)
+	.long	L(5bytes) - L(table_32bytes)
+	.long	L(6bytes) - L(table_32bytes)
+	.long	L(7bytes) - L(table_32bytes)
+	.long	L(8bytes) - L(table_32bytes)
+	.long	L(9bytes) - L(table_32bytes)
+	.long	L(10bytes) - L(table_32bytes)
+	.long	L(11bytes) - L(table_32bytes)
+	.long	L(12bytes) - L(table_32bytes)
+	.long	L(13bytes) - L(table_32bytes)
+	.long	L(14bytes) - L(table_32bytes)
+	.long	L(15bytes) - L(table_32bytes)
+	.long	L(16bytes) - L(table_32bytes)
+	.long	L(17bytes) - L(table_32bytes)
+	.long	L(18bytes) - L(table_32bytes)
+	.long	L(19bytes) - L(table_32bytes)
+	.long	L(20bytes) - L(table_32bytes)
+	.long	L(21bytes) - L(table_32bytes)
+	.long	L(22bytes) - L(table_32bytes)
+	.long	L(23bytes) - L(table_32bytes)
+	.long	L(24bytes) - L(table_32bytes)
+	.long	L(25bytes) - L(table_32bytes)
+	.long	L(26bytes) - L(table_32bytes)
+	.long	L(27bytes) - L(table_32bytes)
+	.long	L(28bytes) - L(table_32bytes)
+	.long	L(29bytes) - L(table_32bytes)
+	.long	L(30bytes) - L(table_32bytes)
+	.long	L(31bytes) - L(table_32bytes)
 
 
 #undef bcmp
diff --git a/sysdeps/i386/ldbl2mpn.c b/sysdeps/i386/ldbl2mpn.c
index 01be777270..bf4e4ff43f 100644
--- a/sysdeps/i386/ldbl2mpn.c
+++ b/sysdeps/i386/ldbl2mpn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 2000, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 2000 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
@@ -19,7 +19,7 @@
 #include "gmp.h"
 #include "gmp-impl.h"
 #include "longlong.h"
-#include <ieee754.h>
+#include "ieee754.h"
 #include <float.h>
 #include <stdlib.h>
 
@@ -46,7 +46,7 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
 #elif BITS_PER_MP_LIMB == 64
   /* Hopefully the compiler will combine the two bitfield extracts
      and this composition into just the original quadword extract.  */
-  res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+  res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
   #define N 1
 #else
   #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
@@ -109,13 +109,6 @@ __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
 	    }
 	}
     }
-  else if (u.ieee.exponent < 0x7fff
-#if N == 2
-	   && res_ptr[0] == 0
-#endif
-	   && res_ptr[N - 1] == 0)
-    /* Pseudo zero.  */
-    *expt = 0;
 
   return N;
 }
diff --git a/sysdeps/i386/soft-fp/sfp-machine.h b/sysdeps/i386/soft-fp/sfp-machine.h
deleted file mode 100644
index ed71ae418a..0000000000
--- a/sysdeps/i386/soft-fp/sfp-machine.h
+++ /dev/null
@@ -1,89 +0,0 @@
-#define _FP_W_TYPE_SIZE		32
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)				\
-  __asm__("addl %5,%1; adcl %3,%0"					\
-	  : "=r"(rh), "=r"(rl)						\
-	  : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl)			\
-	  : "cc")
-
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
-  do { 									\
-    __asm__ volatile("addl %5,%1; adcl %3,%0"				\
-		     : "=r"(r1), "=r"(r0)				\
-		     : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0)		\
-		     : "cc");						\
-    __asm__ volatile("adcl %5,%1; adcl %3,%0"				\
-		     : "=r"(r3), "=r"(r2)				\
-		     : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2)		\
-		     : "cc");						\
-  } while (0)
-
-#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)				\
-  __asm__("subl %5,%1; sbbl %4,%0"					\
-	  : "=r"(rh), "=r"(rl)						\
-	  : "0"(xh), "1"(xl), "g"(yh), "g"(yl)				\
-	  : "cc")
-
-#define __FP_CLZ(r, x)							\
-  do {									\
-    __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc");			\
-    r ^= 31;								\
-  } while (0)
-
-#define _i386_mul_32_64(rh, rl, x, y)					\
-  __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc")
-
-#define _i386_div_64_32(q, r, nh, nl, d)				\
-  __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")
-
-
-#define _FP_MUL_MEAT_S(R,X,Y)					\
-  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64)
-#define _FP_MUL_MEAT_D(R,X,Y)					\
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64)
-
-#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID           (1 << 0)
-#define FP_EX_DENORM		(1 << 1)
-#define FP_EX_DIVZERO           (1 << 2)
-#define FP_EX_OVERFLOW          (1 << 3)
-#define FP_EX_UNDERFLOW         (1 << 4)
-#define FP_EX_INEXACT           (1 << 5)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		3
-#define FP_RND_PINF		2
-#define FP_RND_MINF		1
diff --git a/sysdeps/i386/sysdep.h b/sysdeps/i386/sysdep.h
index 2739cb00b3..e03a8e926d 100644
--- a/sysdeps/i386/sysdep.h
+++ b/sysdeps/i386/sysdep.h
@@ -1,5 +1,6 @@
 /* Assembler macros for i386.
-   Copyright (C) 1991-93,95,96,98,2002,2003,2005 Free Software Foundation, Inc.
+   Copyright (C) 1991-93,95,96,98,2002,2003,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
@@ -132,15 +133,7 @@ lose: SYSCALL_PIC_SETUP							      \
     cfi_adjust_cfa_offset (-4);						      \
     addl $_GLOBAL_OFFSET_TABLE+[.-0b], %ebx;
 
-# ifndef HAVE_HIDDEN
-#  define SETUP_PIC_REG(reg) \
-  call 1f;								      \
-  .subsection 1;							      \
-1:movl (%esp), %e##reg;							      \
-  ret;									      \
-  .previous
-# else
-#  define SETUP_PIC_REG(reg) \
+# define SETUP_PIC_REG(reg) \
   .ifndef __i686.get_pc_thunk.reg;					      \
   .section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits;	      \
   .globl __i686.get_pc_thunk.reg;					      \
@@ -153,7 +146,6 @@ __i686.get_pc_thunk.reg:						      \
   .previous;								      \
   .endif;								      \
   call __i686.get_pc_thunk.reg
-# endif
 
 # define LOAD_PIC_REG(reg) \
   SETUP_PIC_REG(reg); addl $_GLOBAL_OFFSET_TABLE_, %e##reg
diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h
index 55349690e3..61b4ea99a7 100644
--- a/sysdeps/ia64/dl-machine.h
+++ b/sysdeps/ia64/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  IA-64 version.
-   Copyright (C) 1995-1997, 2000-2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1995-1997, 2000-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
@@ -311,7 +311,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
    of the main executable's symbols, as for a COPY reloc, which we don't
    use.  */
 /* ??? Ignore *MSB for now.  */
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 #define elf_machine_type_class(type) \
   (((type) == R_IA64_IPLTLSB || (type) == R_IA64_DTPMOD64LSB		      \
     || (type) == R_IA64_DTPREL64LSB || (type) == R_IA64_TPREL64LSB)	      \
@@ -432,7 +432,7 @@ elf_machine_rela (struct link_map *map,
 	    value = _dl_make_fptr (sym_map, sym, value);
 	  else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_PCREL64LSB))
 	    value -= (Elf64_Addr) reloc_addr & -16;
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || defined USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || defined USE___THREAD
 	  else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_DTPMOD64LSB))
 # ifdef RTLD_BOOTSTRAP
 	    /* During startup the dynamic linker is always index 1.  */
diff --git a/sysdeps/ia64/fpu/fesetround.c b/sysdeps/ia64/fpu/fesetround.c
index 13801c848b..351bcc2f10 100644
--- a/sysdeps/ia64/fpu/fesetround.c
+++ b/sysdeps/ia64/fpu/fesetround.c
@@ -1,5 +1,5 @@
 /* Set current rounding direction.
-   Copyright (C) 1999, 2000, 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
 
@@ -26,7 +26,7 @@ fesetround (int round)
   fenv_t fpsr;
 
   if (round & ~3)
-    return 1;
+    return 0;
 
   /* Get the current state.  */
   __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
@@ -37,6 +37,6 @@ fesetround (int round)
   /* Put the new state in effect.  */
   __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr) : "memory");
 
-  return 0;
+  return 1;
 }
 libm_hidden_def (fesetround)
diff --git a/sysdeps/ia64/ldbl2mpn.c b/sysdeps/ia64/ldbl2mpn.c
deleted file mode 100644
index 641b789cd4..0000000000
--- a/sysdeps/ia64/ldbl2mpn.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../i386/ldbl2mpn.c"
diff --git a/sysdeps/ia64/libc-tls.c b/sysdeps/ia64/libc-tls.c
index 2c0eeae86f..9751284008 100644
--- a/sysdeps/ia64/libc-tls.c
+++ b/sysdeps/ia64/libc-tls.c
@@ -1,5 +1,5 @@
 /* Thread-local storage handling in the ELF dynamic linker.  IA-64 version.
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
@@ -19,8 +19,6 @@
 
 #include <csu/libc-tls.c>
 
-#if USE_TLS
-
 /* On IA-64, as it lacks linker optimizations, __tls_get_addr can be
    called even in statically linked binaries.
    In this case module must be always 1 and PT_TLS segment
@@ -32,5 +30,3 @@ __tls_get_addr (size_t m, size_t offset)
   dtv_t *dtv = THREAD_DTV ();
   return (char *) dtv[1].pointer.val + offset;
 }
-
-#endif
diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c
index 1e159f2c0b..d9bd8b479f 100644
--- a/sysdeps/ieee754/dbl-64/e_pow.c
+++ b/sysdeps/ieee754/dbl-64/e_pow.c
@@ -106,28 +106,20 @@ double __ieee754_pow(double x, double y) {
     else
       return y < 0 ? 1.0/ABS(x) : 0.0;                               /* return 0 */
   }
-
-  qx = u.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
-  qy = v.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
-
-  if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) return NaNQ.x;
-  if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0))
-    return x == 1.0 ? 1.0 : NaNQ.x;
-
   /* if x<0 */
   if (u.i[HIGH_HALF] < 0) {
     k = checkint(y);
     if (k==0) {
-      if (qy == 0x7ff00000) {
+      if ((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] == 0) {
 	if (x == -1.0) return 1.0;
 	else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.0;
 	else return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x;
       }
-      else if (qx == 0x7ff00000)
+      else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
 	return y < 0 ? 0.0 : INF.x;
       return NaNQ.x;                              /* y not integer and x<0 */
     }
-    else if (qx == 0x7ff00000)
+    else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
       {
 	if (k < 0)
 	  return y < 0 ? nZERO.x : nINF.x;
@@ -137,6 +129,14 @@ double __ieee754_pow(double x, double y) {
     return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */
   }
   /* x>0 */
+  qx = u.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
+  qy = v.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
+
+  if (qx > 0x7ff00000 || (qx == 0x7ff00000 && u.i[LOW_HALF] != 0)) return NaNQ.x;
+                                                                 /*  if 0<x<2^-0x7fe */
+  if (qy > 0x7ff00000 || (qy == 0x7ff00000 && v.i[LOW_HALF] != 0))
+    return x == 1.0 ? 1.0 : NaNQ.x;
+                                                                 /*  if y<2^-0x7fe   */
 
   if (qx == 0x7ff00000)                              /* x= 2^-0x3ff */
     {if (y == 0) return NaNQ.x;
diff --git a/sysdeps/ieee754/flt-32/s_nextafterf.c b/sysdeps/ieee754/flt-32/s_nextafterf.c
index 600c14621f..e1568e24c9 100644
--- a/sysdeps/ieee754/flt-32/s_nextafterf.c
+++ b/sysdeps/ieee754/flt-32/s_nextafterf.c
@@ -18,7 +18,7 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp
 #endif
 
 #include "math.h"
-#include <math_private.h>
+#include "math_private.h"
 #include <float.h>
 
 #ifdef __STDC__
@@ -40,12 +40,9 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp
 	   return x+y;
 	if(x==y) return y;		/* x=y, return y */
 	if(ix==0) {				/* x == 0 */
-	    float u;
 	    SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
-	    u = math_opt_barrier (x);
-	    u = u*u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    y = x*x;
+	    if(y==x) return y; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(hx>hy) {				/* x > y, x -= ulp */
@@ -64,12 +61,15 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp
 	if(hy>=0x7f800000) {
 	  x = x+x;	/* overflow  */
 	  if (FLT_EVAL_METHOD != 0)
-	    asm ("" : "+m"(x));
+	    asm ("" : "=m"(x) : "m"(x));
 	  return x;	/* overflow  */
 	}
-	if(hy<0x00800000) {
-	    float u = x*x;			/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy<0x00800000) {		/* underflow */
+	    y = x*x;
+	    if(y!=x) {		/* raise underflow flag */
+	        SET_FLOAT_WORD(y,hx);
+		return y;
+	    }
 	}
 	SET_FLOAT_WORD(x,hx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-128/s_nextafterl.c b/sysdeps/ieee754/ldbl-128/s_nextafterl.c
index 7bc869a518..d3df668178 100644
--- a/sysdeps/ieee754/ldbl-128/s_nextafterl.c
+++ b/sysdeps/ieee754/ldbl-128/s_nextafterl.c
@@ -25,7 +25,7 @@ static char rcsid[] = "$NetBSD: $";
  */
 
 #include "math.h"
-#include <math_private.h>
+#include "math_private.h"
 
 #ifdef __STDC__
 	long double __nextafterl(long double x, long double y)
@@ -47,12 +47,9 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if(x==y) return y;		/* x=y, return y */
 	if((ix|lx)==0) {			/* x == 0 */
-	    long double u;
 	    SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    y = x*x;
+	    if(y==x) return y; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {			/* x > 0 */
 	    if(hx>hy||((hx==hy)&&(lx>ly))) {	/* x > y, x -= ulp */
@@ -73,9 +70,12 @@ static char rcsid[] = "$NetBSD: $";
 	}
 	hy = hx&0x7fff000000000000LL;
 	if(hy==0x7fff000000000000LL) return x+x;/* overflow  */
-	if(hy==0) {
-	    long double u = x*x;		/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy==0) {				/* underflow */
+	    y = x*x;
+	    if(y!=x) {		/* raise underflow flag */
+	        SET_LDOUBLE_WORDS64(y,hx,lx);
+		return y;
+	    }
 	}
 	SET_LDOUBLE_WORDS64(x,hx,lx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-128/s_nexttoward.c b/sysdeps/ieee754/ldbl-128/s_nexttoward.c
index 178505c58f..553e401973 100644
--- a/sysdeps/ieee754/ldbl-128/s_nexttoward.c
+++ b/sysdeps/ieee754/ldbl-128/s_nexttoward.c
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $";
  */
 
 #include "math.h"
-#include <math_private.h>
+#include "math_private.h"
 #include <float.h>
 
 #ifdef __STDC__
@@ -53,12 +53,10 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if((ix|lx)==0) {			/* x == 0 */
-	    double u;
+	    double x2;
 	    INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    x2 = x*x;
+	    if(x2==x) return x2; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if (hy<0||(ix>>20)>(iy>>48)-0x3c00
@@ -89,13 +87,16 @@ static char rcsid[] = "$NetBSD: $";
 	if(hy>=0x7ff00000) {
 	  x = x+x;	/* overflow  */
 	  if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
-	    /* Force conversion to double.  */
-	    asm ("" : "+m"(x));
+	    /* Force conversion to float.  */
+	    asm ("" : "=m"(x) : "m"(x));
 	  return x;
 	}
-	if(hy<0x00100000) {
-	    double u = x*x;			/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy<0x00100000) {		/* underflow */
+	    double x2 = x*x;
+	    if(x2!=x) {		/* raise underflow flag */
+	        INSERT_WORDS(x2,hx,lx);
+		return x2;
+	    }
 	}
 	INSERT_WORDS(x,hx,lx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c b/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
index 21d1e62dab..8a2d45e2d8 100644
--- a/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006, 2007
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -31,20 +31,19 @@ long double
 __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
 {
   union ibm_extended_long_double u;
-  unsigned long lzcount;
+  unsigned long hidden2, lzcount;
   unsigned long long hi, lo;
-  int exponent2;
 
   u.ieee.negative = sign;
   u.ieee.negative2 = sign;
   u.ieee.exponent = expt + IBM_EXTENDED_LONG_DOUBLE_BIAS;
-  u.ieee.exponent2 = 0;
-  exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+  u.ieee.exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS;
 
 #if BITS_PER_MP_LIMB == 32
   /* The low order 53 bits (52 + hidden) go into the lower double */
   lo = frac_ptr[0];
   lo |= (frac_ptr[1] & ((1LL << (53 - 32)) - 1)) << 32;
+  hidden2 = (frac_ptr[1] >> (52 - 32)) & ((mp_limb_t) 1);
   /* The high order 53 bits (52 + hidden) go into the upper double */
   hi = (frac_ptr[1] >> (53 - 32)) & ((1 << 11) - 1);
   hi |= ((unsigned long long) frac_ptr[2]) << 11;
@@ -52,6 +51,7 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
 #elif BITS_PER_MP_LIMB == 64
   /* The low order 53 bits (52 + hidden) go into the lower double */
   lo = frac_ptr[0] & (((mp_limb_t) 1 << 53) - 1);
+  hidden2 = (frac_ptr[0] >> 52) & ((mp_limb_t) 1);
   /* The high order 53 bits (52 + hidden) go into the upper double */
   hi = (frac_ptr[0] >> 53) & (((mp_limb_t) 1 << 11) - 1);
   hi |= (frac_ptr[1] << 11);
@@ -59,62 +59,14 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
   #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
 #endif
 
-  if ((hi & (1LL << 52)) == 0 && (hi | lo) != 0)
-    {
-      /* denormal number  */
-      unsigned long long val = hi ? hi : lo;
-
-      if (sizeof (val) == sizeof (long))
-	lzcount = __builtin_clzl (val);
-      else if ((val >> 32) != 0)
-	lzcount = __builtin_clzl ((long) (val >> 32));
-      else
-	lzcount = __builtin_clzl ((long) val) + 32;
-      if (hi)
-	lzcount = lzcount - 11;
-      else
-	lzcount = lzcount + 42;
-
-      if (lzcount > u.ieee.exponent)
-	{
-	  lzcount = u.ieee.exponent;
-	  u.ieee.exponent = 0;
-	  exponent2 -= lzcount;
-	}
-      else
-	{
-	  u.ieee.exponent -= (lzcount - 1);
-	  exponent2 -= (lzcount - 1);
-	}
-
-      if (lzcount <= 53)
-	{
-	  hi = (hi << lzcount) | (lo >> (53 - lzcount));
-	  lo = (lo << lzcount) & ((1LL << 53) - 1);
-	}
-      else
-	{
-	  hi = lo << (lzcount - 53);
-	  lo = 0;
-	}
-    }
-
   if (lo != 0L)
     {
       /* hidden2 bit of low double controls rounding of the high double.
-	 If hidden2 is '1' and either the explicit mantissa is non-zero
-	 or hi is odd, then round up hi and adjust lo (2nd mantissa)
+	 If hidden2 is '1' then round up hi and adjust lo (2nd mantissa)
 	 plus change the sign of the low double to compensate.  */
-      if ((lo & (1LL << 52)) != 0
-	  && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1))))
+      if (hidden2)
 	{
 	  hi++;
-	  if ((hi & ((1LL << 52) - 1)) == 0)
-	    {
-	      if ((hi & (1LL << 53)) != 0)
-		hi -= 1LL << 52;
-	      u.ieee.exponent++;
-	    }
 	  u.ieee.negative2 = !sign;
 	  lo = (1LL << 53) - lo;
 	}
@@ -133,18 +85,17 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
       if (lzcount > 0)
 	{
 	  lo = lo << lzcount;
-	  exponent2 = exponent2 - lzcount;
+	  u.ieee.exponent2 = u.ieee.exponent2 - lzcount;
 	}
-      if (exponent2 > 0)
-	u.ieee.exponent2 = exponent2;
-      else
-	lo >>= 1 - exponent2;
     }
   else
-    u.ieee.negative2 = 0;
+    {
+      u.ieee.negative2 = 0;
+      u.ieee.exponent2 = 0;
+    }
 
   u.ieee.mantissa3 = lo & 0xffffffffLL;
-  u.ieee.mantissa2 = (lo >> 32) & 0xfffff;
+  u.ieee.mantissa2 = (lo >> 32) & 0xffffff;
   u.ieee.mantissa1 = hi & 0xffffffffLL;
   u.ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1);
 
diff --git a/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c b/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
index b2ad25e31f..2a7b70fabf 100644
--- a/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
+++ b/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c
@@ -1,5 +1,5 @@
 /* Print floating point number in hexadecimal notation according to ISO C99.
-   Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006,2007
+   Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -35,24 +35,21 @@ do {									      \
 									      \
       lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3;    \
       hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1;    \
-      lo <<= 7; /* pre-shift lo to match ieee854.  */			      \
-      /* If the lower double is not a denomal or zero then set the hidden     \
-	 53rd bit.  */							      \
-      if (eldbl.ieee.exponent2 != 0)					      \
-	lo |= (1ULL << (52 + 7));					      \
-      else								      \
-	lo <<= 1;							      \
-      /* The lower double is normalized separately from the upper.  We	      \
-	 may need to adjust the lower manitissa to reflect this.  */	      \
-      ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2;		      \
-      if (ediff > 53 + 63)						      \
-	lo = 0;								      \
-      else if (ediff > 53)						      \
-	lo = lo >> (ediff - 53);					      \
-      else if (eldbl.ieee.exponent2 == 0 && ediff < 53)			      \
-	lo = lo << (53 - ediff);					      \
-      if (eldbl.ieee.negative != eldbl.ieee.negative2			      \
-	  && (eldbl.ieee.exponent2 != 0 || lo != 0L))			      \
+   /* If the lower double is not a denomal or zero then set the hidden	      \
+      53rd bit.  */							      \
+      if (eldbl.ieee.exponent2 > 0x001)					      \
+	{								      \
+	  lo |= (1ULL << 52);						      \
+	  lo = lo << 7; /* pre-shift lo to match ieee854.  */		      \
+	  /* The lower double is normalized separately from the upper.  We    \
+	     may need to adjust the lower manitissa to reflect this.  */      \
+	  ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2;		      \
+	  if (ediff > 53)						      \
+	    lo = lo >> (ediff-53);					      \
+	}								      \
+  									      \
+      if ((eldbl.ieee.negative != eldbl.ieee.negative2)			      \
+	  && ((eldbl.ieee.exponent2 != 0) && (lo != 0L)))		      \
 	{								      \
 	  lo = (1ULL << 60) - lo;					      \
 	  if (hi == 0L)							      \
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c b/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c
index 6999abc250..3ca178a3c5 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c
@@ -1,5 +1,5 @@
 /* Return classification value corresponding to argument.
-   Copyright (C) 1997,1999,2002,2004,2006,2007 Free Software Foundation, Inc.
+   Copyright (C) 1997,1999,2002,2004,2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
    		  Jakub Jelinek <jj@ultra.linux.cz>, 1999.
@@ -30,16 +30,14 @@
    * -NaN	fffn nnnn nnnn nnnn xxxx xxxx xxxx xxxx
    * +Inf	7ff0 0000 0000 0000 xxxx xxxx xxxx xxxx
    * -Inf	fff0 0000 0000 0000 xxxx xxxx xxxx xxxx
-   * +0		0000 0000 0000 0000 xxxx xxxx xxxx xxxx
-   * -0		8000 0000 0000 0000 xxxx xxxx xxxx xxxx
-   * +normal	0360 0000 0000 0000 0000 0000 0000 0000 (smallest)
-   * -normal	8360 0000 0000 0000 0000 0000 0000 0000 (smallest)
-   * +normal	7fef ffff ffff ffff 7c8f ffff ffff fffe (largest)
-   * +normal	ffef ffff ffff ffff fc8f ffff ffff fffe (largest)
-   * +denorm	0360 0000 0000 0000 8000 0000 0000 0001 (largest)
-   * -denorm	8360 0000 0000 0000 0000 0000 0000 0001 (largest)
-   * +denorm	000n nnnn nnnn nnnn xxxx xxxx xxxx xxxx
-   * -denorm	800n nnnn nnnn nnnn xxxx xxxx xxxx xxxx
+   * +0		0000 0000 0000 0000
+   * -0		8000 0000 0000 0000
+   * +normal	001n nnnn nnnn nnnn (smallest)
+   * -normal	801n nnnn nnnn nnnn (smallest)
+   * +normal	7fen nnnn nnnn nnnn (largest)
+   * -normal	ffen nnnn nnnn nnnn (largest)
+   * +denorm	000n nnnn nnnn nnnn
+   * -denorm	800n nnnn nnnn nnnn
    */
 
 int
@@ -61,23 +59,12 @@ ___fpclassifyl (long double x)
       /* +/-zero or +/- normal or +/- denormal */
       if (hx & 0x7fffffffffffffffULL) {
 	  /* +/- normal or +/- denormal */
-	  if ((hx & 0x7ff0000000000000ULL) > 0x0360000000000000ULL) {
+	  if ((hx & 0x7ff0000000000000ULL) >= 0x0360000000000000ULL) {
 	      /* +/- normal */
 	      retval = FP_NORMAL;
 	  } else {
-	      if ((hx & 0x7ff0000000000000ULL) == 0x0360000000000000ULL) {
-		  if ((lx & 0x7fffffffffffffff)	/* lower is non-zero */
-		  && ((lx^hx) & 0x8000000000000000ULL)) { /* and sign differs */
-		      /* +/- denormal */
-		      retval = FP_SUBNORMAL;
-		  } else {
-		      /* +/- normal */
-		      retval = FP_NORMAL;
-		  }
-	      } else {
-		  /* +/- denormal */
-		  retval = FP_SUBNORMAL;
-	      }
+	      /* +/- denormal */
+	      retval = FP_SUBNORMAL;
 	  }
       } else {
 	  /* +/- zero */
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
index 39d0e6a5e3..e35ce50829 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
@@ -24,8 +24,8 @@ static char rcsid[] = "$NetBSD: $";
  *   Special cases:
  */
 
-#include <math.h>
-#include <math_private.h>
+#include "math.h"
+#include "math_private.h"
 #include <math_ldbl_opt.h>
 
 #ifdef __STDC__
@@ -35,7 +35,7 @@ static char rcsid[] = "$NetBSD: $";
 	long double x,y;
 #endif
 {
-	int64_t hx,hy,ihx,ihy,ilx;
+	int64_t hx,hy,ihx,ihy,ilx,ily;
 	u_int64_t lx,ly;
 
 	GET_LDOUBLE_WORDS64(hx,lx,x);
@@ -43,6 +43,7 @@ static char rcsid[] = "$NetBSD: $";
 	ihx = hx&0x7fffffffffffffffLL;		/* |hx| */
 	ilx = lx&0x7fffffffffffffffLL;		/* |lx| */
 	ihy = hy&0x7fffffffffffffffLL;		/* |hy| */
+	ily = ly&0x7fffffffffffffffLL;		/* |ly| */
 
 	if((((ihx&0x7ff0000000000000LL)==0x7ff0000000000000LL)&&
 	    ((ihx&0x000fffffffffffffLL)!=0)) ||   /* x is nan */
@@ -52,67 +53,55 @@ static char rcsid[] = "$NetBSD: $";
 	if(x==y)
 	    return y;		/* x=y, return y */
 	if(ihx == 0 && ilx == 0) {			/* x == 0 */
-	    long double u;
-	    hy = (hy & 0x8000000000000000ULL) | 1;
-	    SET_LDOUBLE_WORDS64(x,hy,0ULL);/* return +-minsubnormal */
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */
+	    y = x*x;
+	    if(y==x) return y; else return x;	/* raise underflow flag */
 	}
-	
-	long double u;
-	if(x > y) {	/* x > y, x -= ulp */
-	    if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL))
-	      return x+x;	/* overflow, return -inf */
-	    if (hx >= 0x7ff0000000000000LL) {
-	      SET_LDOUBLE_WORDS64(u,0x7fefffffffffffffLL,0x7c8ffffffffffffeLL);
-	      return u;
-	    }
-	    if(ihx <= 0x0360000000000000LL) {  /* x <= LDBL_MIN */
-	      u = math_opt_barrier (x);
-	      x -= __LDBL_DENORM_MIN__;
-	      if (ihx < 0x0360000000000000LL
-		  || (hx > 0 && (int64_t) lx <= 0)
-		  || (hx < 0 && (int64_t) lx > 1)) {
-		u = u * u;
-		math_force_eval (u);		/* raise underflow flag */
-	      }
-	      return x;
+	if(ihx>=0) {			/* x > 0 */
+	    if(ihx>ihy||((ihx==ihy)&&(ilx>ily))) {	/* x > y, x -= ulp */
+
+	        if(ilx==0)
+		    hx--;
+		else
+		    lx--;
+	    } else {				/* x < y, x += ulp */
+	        if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL))
+		  {
+		    SET_LDOUBLE_WORDS64(x,0x7ff0000000000000,0x8000000000000000);
+		    return x;
+		  }
+	        else if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL))
+		  {
+		    SET_LDOUBLE_WORDS64(x,0xfff0000000000000,0x8000000000000000);
+		    return x;
+		  }
+		else if((lx&0x7fffffffffffffff)==0) hx++;
+		else
+		  lx++;
 	    }
-	    if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
-	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL);
-	      u *= 0x1.0000000000000p-105L;
-	    } else
-	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL);
-	    return x - u;
-	} else {				/* x < y, x += ulp */
-	    if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL))
-	      return x+x;	/* overflow, return +inf */
-	    if ((u_int64_t) hx >= 0xfff0000000000000ULL) {
-	      SET_LDOUBLE_WORDS64(u,0xffefffffffffffffLL,0xfc8ffffffffffffeLL);
-	      return u;
+	} else {				/* x < 0 */
+	    if(ihy>=0||ihx>ihy||((ihx==ihy)&&(ilx>ily))){/* x < y, x -= ulp */
+		if((lx&0x7fffffffffffffff)==0)
+		    hx--;
+		else
+		    lx--;
+	    } else {				/* x > y, x += ulp */
+		if((lx&0x7fffffffffffffff)==0) hx++;
+		else
+		  lx++;
 	    }
-	    if(ihx <= 0x0360000000000000LL) {  /* x <= LDBL_MIN */
-	      u = math_opt_barrier (x);
-	      x += __LDBL_DENORM_MIN__;
-	      if (ihx < 0x0360000000000000LL
-		  || (hx > 0 && (int64_t) lx < 0 && lx != 0x8000000000000001LL)
-		  || (hx < 0 && (int64_t) lx >= 0)) {
-		u = u * u;
-		math_force_eval (u);		/* raise underflow flag */
-	      }
-	      if (x == 0.0L)	/* handle negative __LDBL_DENORM_MIN__ case */
-		x = -0.0L;
-	      return x;
+	}
+	hy = hx&0x7ff0000000000000LL;
+	if(hy==0x7ff0000000000000LL) return x+x;/* overflow  */
+	if(hy==0) {				/* underflow */
+	    y = x*x;
+	    if(y!=x) {		/* raise underflow flag */
+	        SET_LDOUBLE_WORDS64(y,hx,lx);
+		return y;
 	    }
-	    if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
-	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL);
-	      u *= 0x1.0000000000000p-105L;
-	    } else
-	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL);
-	    return x + u;
 	}
+	SET_LDOUBLE_WORDS64(x,hx,lx);
+	return x;
 }
 strong_alias (__nextafterl, __nexttowardl)
 long_double_symbol (libm, __nextafterl, nextafterl);
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c b/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
index e2f6521f57..3335100592 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $";
  */
 
 #include "math.h"
-#include <math_private.h>
+#include "math_private.h"
 #include <math_ldbl_opt.h>
 #include <float.h>
 
@@ -55,12 +55,10 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if((ix|lx)==0) {			/* x == 0 */
-	    double u;
+	    double x2;
 	    INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    x2 = x*x;
+	    if(x2==x) return x2; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if (hy<0||(ix>>20)>(iy>>52)
@@ -91,13 +89,16 @@ static char rcsid[] = "$NetBSD: $";
 	if(hy>=0x7ff00000) {
 	  x = x+x;	/* overflow  */
 	  if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
-	    /* Force conversion to double.  */
-	    asm ("" : "+m"(x));
+	    /* Force conversion to float.  */
+	    asm ("" : "=m"(x) : "m"(x));
 	  return x;
 	}
-	if(hy<0x00100000) {
-	    double u = x*x;			/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy<0x00100000) {		/* underflow */
+	    double x2 = x*x;
+	    if(x2!=x) {		/* raise underflow flag */
+	        INSERT_WORDS(x2,hx,lx);
+		return x2;
+	    }
 	}
 	INSERT_WORDS(x,hx,lx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
index cf655fad16..a9373ff822 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
@@ -19,9 +19,8 @@ static char rcsid[] = "$NetBSD: $";
 #endif
 
 #include "math.h"
-#include <math_private.h>
+#include "math_private.h"
 #include <math_ldbl_opt.h>
-#include <float.h>
 
 #ifdef __STDC__
 	float __nexttowardf(float x, long double y)
@@ -47,12 +46,10 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if(ix==0) {				/* x == 0 */
-	    float u;
+	    float x2;
 	    SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    x2 = x*x;
+	    if(x2==x) return x2; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(hy<0||(ix>>23)>(iy>>52)-0x380
@@ -72,16 +69,13 @@ static char rcsid[] = "$NetBSD: $";
 	    }
 	}
 	hy = hx&0x7f800000;
-	if(hy>=0x7f800000) {
-	  x = x+x;	/* overflow  */
-	  if (FLT_EVAL_METHOD != 0)
-	    /* Force conversion to float.  */
-	    asm ("" : "+m"(x));
-	  return x;
-	}
+	if(hy>=0x7f800000) return x+x;	/* overflow  */
 	if(hy<0x00800000) {		/* underflow */
-	    float u = x*x;
-	    math_force_eval (u);	/* raise underflow flag */
+	    float x2 = x*x;
+	    if(x2!=x) {		/* raise underflow flag */
+	        SET_FLOAT_WORD(x2,hx);
+		return x2;
+	    }
 	}
 	SET_FLOAT_WORD(x,hx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-96/s_nextafterl.c b/sysdeps/ieee754/ldbl-96/s_nextafterl.c
index ed0877d6dd..1798261b28 100644
--- a/sysdeps/ieee754/ldbl-96/s_nextafterl.c
+++ b/sysdeps/ieee754/ldbl-96/s_nextafterl.c
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $";
  */
 
 #include "math.h"
-#include <math_private.h>
+#include "math_private.h"
 
 #ifdef __STDC__
 	long double __nextafterl(long double x, long double y)
@@ -48,12 +48,9 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if(x==y) return y;		/* x=y, return y */
 	if((ix|hx|lx)==0) {			/* x == 0 */
-	    long double u;
 	    SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    y = x*x;
+	    if(y==x) return y; else return x;	/* raise underflow flag */
 	}
 	if(esx<0x8000) {			/* x > 0 */
 	    if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
@@ -88,10 +85,13 @@ static char rcsid[] = "$NetBSD: $";
 	    }
 	}
 	esy = esx&0x7fff;
-	if(esy==0x7fff) return x+x;		/* overflow  */
-	if(esy==0) {
-	    long double u = x*x;		/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(esy==0x7fff) return x+x;	/* overflow  */
+	if(esy==0) {			/* underflow */
+	    y = x*x;
+	    if(y!=x) {		/* raise underflow flag */
+	        SET_LDOUBLE_WORDS(y,esx,hx,lx);
+		return y;
+	    }
 	}
 	SET_LDOUBLE_WORDS(x,esx,hx,lx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-96/s_nexttoward.c b/sysdeps/ieee754/ldbl-96/s_nexttoward.c
index e30438482c..7945cb5cb1 100644
--- a/sysdeps/ieee754/ldbl-96/s_nexttoward.c
+++ b/sysdeps/ieee754/ldbl-96/s_nexttoward.c
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $";
  */
 
 #include "math.h"
-#include <math_private.h>
+#include "math_private.h"
 #include <float.h>
 
 #ifdef __STDC__
@@ -50,12 +50,10 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if((ix|lx)==0) {			/* x == 0 */
-	    double u;
+	    double x2;
 	    INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    x2 = x*x;
+	    if(x2==x) return x2; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
@@ -86,13 +84,16 @@ static char rcsid[] = "$NetBSD: $";
 	if(hy>=0x7ff00000) {
 	  x = x+x;	/* overflow  */
 	  if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
-	    /* Force conversion to double.  */
-	    asm ("" : "+m"(x));
+	    /* Force conversion to float.  */
+	    asm ("" : "=m"(x) : "m"(x));
 	  return x;
 	}
-	if(hy<0x00100000) {
-	    double u = x*x;			/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy<0x00100000) {		/* underflow */
+	    double x2 = x*x;
+	    if(x2!=x) {		/* raise underflow flag */
+	        INSERT_WORDS(x2,hx,lx);
+		return x2;
+	    }
 	}
 	INSERT_WORDS(x,hx,lx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
index 6357975ffc..a1c38b5d4c 100644
--- a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
+++ b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
@@ -18,8 +18,7 @@ static char rcsid[] = "$NetBSD: $";
 #endif
 
 #include "math.h"
-#include <math_private.h>
-#include <float.h>
+#include "math_private.h"
 
 #ifdef __STDC__
 	float __nexttowardf(float x, long double y)
@@ -42,12 +41,10 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if(ix==0) {				/* x == 0 */
-	    float u;
+	    float x2;
 	    SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    x2 = x*x;
+	    if(x2==x) return x2; else return x;	/* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
@@ -67,16 +64,13 @@ static char rcsid[] = "$NetBSD: $";
 	    }
 	}
 	hy = hx&0x7f800000;
-	if(hy>=0x7f800000) {
-	  x = x+x;	/* overflow  */
-	  if (FLT_EVAL_METHOD != 0)
-	    /* Force conversion to float.  */
-	    asm ("" : "+m"(x));
-	  return x;
-	}
-	if(hy<0x00800000) {
-	    float u = x*x;			/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy>=0x7f800000) return x+x;	/* overflow  */
+	if(hy<0x00800000) {		/* underflow */
+	    float x2 = x*x;
+	    if(x2!=x) {		/* raise underflow flag */
+	        SET_FLOAT_WORD(x2,hx);
+		return x2;
+	    }
 	}
 	SET_FLOAT_WORD(x,hx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c b/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
index 68027f26fa..d52526f719 100644
--- a/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
+++ b/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
@@ -20,10 +20,7 @@
  *   Special cases:
  */
 
-#include <math.h>
-#include <math_private.h>
 #include <math_ldbl_opt.h>
-#include <float.h>
 
 float __nldbl_nexttowardf(float x, double y);
 
@@ -42,12 +39,10 @@ float __nldbl_nexttowardf(float x, double y)
 	   return x+y;
 	if((double) x==y) return y;		/* x=y, return y */
 	if(ix==0) {				/* x == 0 */
-	    float u;
+	    float x2;
 	    SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/
-	    u = math_opt_barrier (x);
-	    u = u * u;
-	    math_force_eval (u);		/* raise underflow flag */
-	    return x;
+	    x2 = x*x;
+	    if(x2==x) return x2; else return x; /* raise underflow flag */
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(hy<0||(ix>>23)>(iy>>20)-0x380
@@ -65,16 +60,13 @@ float __nldbl_nexttowardf(float x, double y)
 		hx += 1;
 	}
 	hy = hx&0x7f800000;
-	if(hy>=0x7f800000) {
-	  x = x+x;	/* overflow  */
-	  if (FLT_EVAL_METHOD != 0)
-	    /* Force conversion to float.  */
-	    asm ("" : "+m"(x));
-	  return x;
-	}
-	if(hy<0x00800000) {
-	    float u = x*x;			/* underflow */
-	    math_force_eval (u);		/* raise underflow flag */
+	if(hy>=0x7f800000) return x+x;	/* overflow  */
+	if(hy<0x00800000) {		/* underflow */
+	    float x2 = x*x;
+	    if(x2!=x) {		/* raise underflow flag */
+		SET_FLOAT_WORD(x2,hx);
+		return x2;
+	    }
 	}
 	SET_FLOAT_WORD(x,hx);
 	return x;
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index fa7da60204..3288f186e5 100644
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/fork.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994,1995,1996,1997,1999,2001,2002,2004,2005
+/* Copyright (C) 1994,1995,1996,1997,1999,2001,2002,2004,2005,2006
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -532,11 +532,9 @@ __fork (void)
       /* Set the child user thread up to return 1 from the setjmp above.  */
       _hurd_longjmp_thread_state (&state, env, 1);
 
-#if USE_TLS
       /* Do special thread setup for TLS if needed.  */
       if (err = _hurd_tls_fork (thread, &state))
 	LOSE;
-#endif
 
       if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
 				    (natural_t *) &state, statecount))
diff --git a/sysdeps/mach/hurd/futimes.c b/sysdeps/mach/hurd/futimes.c
index ca687b8bdf..4628eee2c3 100644
--- a/sysdeps/mach/hurd/futimes.c
+++ b/sysdeps/mach/hurd/futimes.c
@@ -1,5 +1,5 @@
 /* futimes -- change access and modification times of open file.  Hurd version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 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
@@ -28,20 +28,24 @@
 int
 __futimes (int fd, const struct timeval tvp[2])
 {
-  struct timeval timevals[2];
+  union tv
+  {
+    struct timeval tv;
+    time_value_t tvt;
+  };
+  const union tv *u = (const union tv *) tvp;
+  union tv nulltv[2];
   error_t err;
 
   if (tvp == NULL)
     {
       /* Setting the number of microseconds to `-1' tells the
          underlying filesystems to use the current time.  */
-      timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
-      tvp = timevals;
+      nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+      u = nulltv;
     }
 
-  err = HURD_DPORT_USE (fd, __file_utimes (port,
-					   *(time_value_t *) &tvp[0],
-					   *(time_value_t *) &tvp[1]));
+  err = HURD_DPORT_USE (fd, __file_utimes (port, u[0].tvt, u[1].tvt));
   return err ? __hurd_dfail (fd, err) : 0;
 }
 weak_alias (__futimes, futimes)
diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
index 223a47d2f2..972cac57a1 100644
--- a/sysdeps/mach/hurd/i386/tls.h
+++ b/sysdeps/mach/hurd/i386/tls.h
@@ -1,5 +1,5 @@
 /* Definitions for thread-local data handling.  Hurd/i386 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
@@ -25,9 +25,6 @@
 /* Some things really need not be machine-dependent.  */
 # include <sysdeps/mach/hurd/tls.h>
 
-/* Indiciate that TLS support is available.  */
-# define USE_TLS	1
-
 /* The TCB can have any size and the memory following the address the
    thread pointer points to is unspecified.  Allocate the TCB there.  */
 # define TLS_TCB_AT_TP	1
diff --git a/sysdeps/mach/hurd/lutimes.c b/sysdeps/mach/hurd/lutimes.c
index cf89d8862f..bf5610c467 100644
--- a/sysdeps/mach/hurd/lutimes.c
+++ b/sysdeps/mach/hurd/lutimes.c
@@ -1,5 +1,5 @@
 /* lutimes -- change access and modification times of a symlink.  Hurd version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 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
@@ -28,7 +28,13 @@
 int
 __lutimes (const char *file, const struct timeval tvp[2])
 {
-  struct timeval timevals[2];
+  union tv
+  {
+    struct timeval tv;
+    time_value_t tvt;
+  };
+  const union tv *u = (const union tv *) tvp;
+  union tv nulltv[2];
   error_t err;
   file_t port;
 
@@ -36,15 +42,14 @@ __lutimes (const char *file, const struct timeval tvp[2])
     {
       /* Setting the number of microseconds to `-1' tells the
          underlying filesystems to use the current time.  */
-      timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
-      tvp = timevals;
+      nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+      u = nulltv;
     }
 
   port = __file_name_lookup (file, O_NOLINK, 0);
   if (port == MACH_PORT_NULL)
     return -1;
-  err = __file_utimes (port,
-		       *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
+  err = __file_utimes (port, u[0].tvt, u[1].tvt);
   __mach_port_deallocate (__mach_task_self (), port);
   if (err)
     return __hurd_fail (err);
diff --git a/sysdeps/mach/hurd/utimes.c b/sysdeps/mach/hurd/utimes.c
index 74f3a342f4..fdc1427feb 100644
--- a/sysdeps/mach/hurd/utimes.c
+++ b/sysdeps/mach/hurd/utimes.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-1995, 97, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1995,1997,1999,2000,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
@@ -28,7 +29,13 @@ __utimes (file, tvp)
      const char *file;
      const struct timeval tvp[2];
 {
-  struct timeval timevals[2];
+  union tv
+  {
+    struct timeval tv;
+    time_value_t tvt;
+  };
+  const union tv *u = (const union tv *) tvp;
+  union tv nulltv[2];
   error_t err;
   file_t port;
 
@@ -36,19 +43,17 @@ __utimes (file, tvp)
     {
       /* Setting the number of microseconds to `-1' tells the
          underlying filesystems to use the current time.  */
-      timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
-      tvp = timevals;
+      nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+      u = nulltv;
     }
 
   port = __file_name_lookup (file, 0, 0);
   if (port == MACH_PORT_NULL)
     return -1;
-  err = __file_utimes (port,
-		       *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
+  err = __file_utimes (port, u[0].tvt, u[1].tvt);
   __mach_port_deallocate (__mach_task_self (), port);
   if (err)
     return __hurd_fail (err);
   return 0;
 }
-
 weak_alias (__utimes, utimes)
diff --git a/sysdeps/posix/euidaccess.c b/sysdeps/posix/euidaccess.c
index 333870cdde..76a09d455d 100644
--- a/sysdeps/posix/euidaccess.c
+++ b/sysdeps/posix/euidaccess.c
@@ -1,5 +1,5 @@
 /* Check if effective user id can access file
-   Copyright (C) 1990,1991,1995-2001,2005,2007 Free Software Foundation, Inc.
+   Copyright (C) 1990,1991,1995-2001,2005 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
@@ -128,6 +128,10 @@ euidaccess (path, mode)
 #ifdef	_LIBC
   uid_t euid;
   gid_t egid;
+
+  if (! __libc_enable_secure)
+    /* If we are not set-uid or set-gid, access does the same.  */
+    return __access (path, mode);
 #else
   if (have_ids == 0)
     {
@@ -158,10 +162,6 @@ euidaccess (path, mode)
   /* Now we need the IDs.  */
   euid = __geteuid ();
   egid = __getegid ();
-
-  if (__getuid () == euid && __getgid () == egid)
-    /* If we are not set-uid or set-gid, access does the same.  */
-    return __access (path, mode);
 #endif
 
   /* The super-user can read and write any file, and execute any file
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index a7e1459c9c..b4966852a7 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1157,7 +1157,7 @@ get_scope (const struct sockaddr_storage *ss)
 	 169.254/16 and 127/8 are link-local.  */
       if ((addr[0] == 169 && addr[1] == 254) || addr[0] == 127)
 	scope = 2;
-      else if (addr[0] == 10 || (addr[0] == 172 && (addr[1] & 0xf0) == 16)
+      else if (addr[0] == 10 || (addr[0] == 172 && addr[1] == 16)
 	       || (addr[0] == 192 && addr[1] == 168))
 	scope = 5;
       else
@@ -1218,10 +1218,6 @@ static const struct prefixentry default_labels[] =
 			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
       7, 6 },
     { { .in6_u
-	= { .u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
-      32, 7 },
-    { { .in6_u
 	= { .u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
       0, 1 }
@@ -2089,10 +2085,12 @@ getaddrinfo (const char *name, const char *service,
 
 		  if (q->ai_family == PF_INET6 && in6ai != NULL)
 		    {
-		      /* See whether the address is the list of deprecated
-			 or temporary addresses.  */
+		      /* See whether the source address is the list of
+			 deprecated or temporary addresses.  */
 		      struct in6addrinfo tmp;
-		      memcpy (tmp.addr, q->ai_addr, IN6ADDRSZ);
+		      struct sockaddr_in6 *sin6p
+			= (struct sockaddr_in6 *) &results[i].source_addr;
+		      memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
 
 		      struct in6addrinfo *found
 			= bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
diff --git a/sysdeps/powerpc/fpu/bits/mathinline.h b/sysdeps/powerpc/fpu/bits/mathinline.h
index aed899e882..04478309d9 100644
--- a/sysdeps/powerpc/fpu/bits/mathinline.h
+++ b/sysdeps/powerpc/fpu/bits/mathinline.h
@@ -121,62 +121,4 @@ __NTH (fdimf (float __x, float __y))
 
 #endif /* __USE_ISOC99 */
 #endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
-
-/* This code is used internally in the GNU libc.  */
-#ifdef __LIBC_INTERNAL_MATH_INLINES
-
-#include <sysdep.h>
-#include <ldsodefs.h>
-#include <dl-procinfo.h>
-
-# if __WORDSIZE == 64 || defined _ARCH_PWR4
-#  define __CPU_HAS_FSQRT 1
-# else
-#  define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
-# endif
-
-extern double __slow_ieee754_sqrt (double);
-__MATH_INLINE double
-__NTH (__ieee754_sqrt (double __x))
-{
-  double __z;
-
-  /* If the CPU is 64-bit we can use the optional FP instructions.  */
-  if (__CPU_HAS_FSQRT)
-  {
-    /* Volatile is required to prevent the compiler from moving the
-       fsqrt instruction above the branch.  */
-     __asm __volatile (
-	"	fsqrt	%0,%1\n"
-		: "=f" (__z)
-		: "f" (__x));
-  }
-  else
-     __z = __slow_ieee754_sqrt(__x);
-
-  return __z;
-}
-
-extern float __slow_ieee754_sqrtf (float);
-__MATH_INLINE float
-__NTH (__ieee754_sqrtf (float __x))
-{
-  float __z;
-
-  /* If the CPU is 64-bit we can use the optional FP instructions.  */
-  if (__CPU_HAS_FSQRT)
-  {
-    /* Volatile is required to prevent the compiler from moving the
-       fsqrts instruction above the branch.  */
-     __asm __volatile (
-	"	fsqrts	%0,%1\n"
-		: "=f" (__z)
-		: "f" (__x));
-  }
-  else
-     __z = __slow_ieee754_sqrtf(__x);
-
-  return __z;
-}
-#endif /* __LIBC_INTERNAL_MATH_INLINES */
 #endif /* __GNUC__ && !_SOFT_FLOAT */
diff --git a/sysdeps/powerpc/fpu/math_private.h b/sysdeps/powerpc/fpu/math_private.h
new file mode 100644
index 0000000000..90021c6d3c
--- /dev/null
+++ b/sysdeps/powerpc/fpu/math_private.h
@@ -0,0 +1,83 @@
+/* Private inline math functions for powerpc.
+   Copyright (C) 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., 51 Franklin St - Fifth Floor, Boston,
+   MA 02110-1301 USA  */
+
+#ifndef _PPC_MATH_PRIVATE_H_
+#define _PPC_MATH_PRIVATE_H_
+
+#include <sysdep.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+# if __WORDSIZE == 64 || defined _ARCH_PWR4
+#  define __CPU_HAS_FSQRT 1
+# else
+#  define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
+# endif
+
+# ifndef __LIBC_INTERNAL_MATH_INLINES
+extern double __slow_ieee754_sqrt (double);
+__inline double
+__ieee754_sqrt (double __x)
+{
+  double __z;
+
+  /* If the CPU is 64-bit we can use the optional FP instructions.  */
+  if (__CPU_HAS_FSQRT)
+  {
+    /* Volatile is required to prevent the compiler from moving the
+       fsqrt instruction above the branch.  */
+     __asm __volatile (
+	"	fsqrt	%0,%1\n"
+		: "=f" (__z)
+		: "f" (__x));
+  }
+  else
+     __z = __slow_ieee754_sqrt(__x);
+
+  return __z;
+}
+
+extern float __slow_ieee754_sqrtf (float);
+
+__inline float
+__ieee754_sqrtf (float __x)
+{
+  float __z;
+
+  /* If the CPU is 64-bit we can use the optional FP instructions.  */
+  if (__CPU_HAS_FSQRT)
+  {
+    /* Volatile is required to prevent the compiler from moving the
+       fsqrts instruction above the branch.  */
+     __asm __volatile (
+	"	fsqrts	%0,%1\n"
+		: "=f" (__z)
+		: "f" (__x));
+  }
+  else
+     __z = __slow_ieee754_sqrtf(__x);
+
+  return __z;
+}
+#endif /* __LIBC_INTERNAL_MATH_INLINES */
+
+#include <math/math_private.h>
+
+#endif /* _PPC_MATH_PRIVATE_H_ */
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index 4120a02382..fc460993b1 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation functions.  PowerPC version.
-   Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1995-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
@@ -564,13 +564,12 @@ __process_machine_rela (struct link_map *map,
       }
       break;
 
-#ifdef USE_TLS
 #define CHECK_STATIC_TLS(map, sym_map)					      \
     do {								      \
       if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0))     \
 	_dl_allocate_static_tls (sym_map);				      \
     } while (0)
-# define DO_TLS_RELOC(suffix)						      \
+#define DO_TLS_RELOC(suffix)						      \
     case R_PPC_DTPREL##suffix:						      \
       /* During relocation all TLS symbols are defined and used.	      \
 	 Therefore the offset is already correct.  */			      \
@@ -609,7 +608,6 @@ __process_machine_rela (struct link_map *map,
     DO_TLS_RELOC (16_LO)
     DO_TLS_RELOC (16_HI)
     DO_TLS_RELOC (16_HA)
-#endif
 
     default:
       _dl_reloc_bad_type (map, rinfo, 0);
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index 496fa71ecc..a50ffdd1c2 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  PowerPC version.
-   Copyright (C) 1995-2002, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 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
@@ -138,7 +138,7 @@ __elf_preferred_address(struct link_map *loader, size_t maplength,
 /* We never want to use a PLT entry as the destination of a
    reloc, when what is being relocated is a branch. This is
    partly for efficiency, but mostly so we avoid loops.  */
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 #define elf_machine_type_class(type)			\
   ((((type) == R_PPC_JMP_SLOT				\
     || (type) == R_PPC_REL24				\
@@ -330,7 +330,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
       *reloc_addr = value;
       break;
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \
     && !defined RESOLVE_CONFLICT_FIND_MAP
 # ifdef RTLD_BOOTSTRAP
 #  define NOT_BOOTSTRAP 0
@@ -361,7 +361,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
 	}
       break;
-#endif /* USE_TLS etc. */
+#endif
 
     case R_PPC_JMP_SLOT:
 #ifdef RESOLVE_CONFLICT_FIND_MAP
diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
index 8fc624ebd9..88cfe71e0b 100644
--- a/sysdeps/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/powerpc/powerpc32/sysdep.h
@@ -96,7 +96,7 @@
 #endif
 
 #if defined SHARED && defined DO_VERSIONING && defined PIC \
-    && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE && !defined NO_HIDDEN
+    && !defined NO_HIDDEN
 # undef HIDDEN_JUMPTARGET
 # define HIDDEN_JUMPTARGET(name) __GI_##name##@local
 #endif
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index cec271bb3a..89a69e1a23 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -1,7 +1,6 @@
 /* Machine-dependent ELF dynamic relocation inline functions.
    PowerPC64 version.
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright 1995-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
@@ -260,7 +259,7 @@ BODY_PREFIX "_dl_start_user:\n"						\
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 #define elf_machine_type_class(type)					      \
   /* This covers all the TLS relocs, though most won't appear.  */	      \
   (((((type) >= R_PPC64_DTPMOD64 && (type) <= R_PPC64_TPREL16_HIGHESTA)	      \
@@ -495,7 +494,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 /* This computes the value used by TPREL* relocs.  */
 auto inline Elf64_Addr __attribute__ ((always_inline, const))
 elf_machine_tprel (struct link_map *map,
@@ -562,7 +561,7 @@ elf_machine_rela (struct link_map *map,
 #endif
       return;
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
     case R_PPC64_DTPMOD64:
 # ifdef RTLD_BOOTSTRAP
       /* During startup the dynamic linker is always index 1.  */
@@ -645,7 +644,7 @@ elf_machine_rela (struct link_map *map,
       value = elf_machine_tprel (map, sym_map, sym, reloc);
       *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value);
       break;
-#endif /* USE_TLS etc. */
+#endif
 
 #ifndef RTLD_BOOTSTRAP /* None of the following appear in ld.so */
     case R_PPC64_ADDR16_LO_DS:
diff --git a/sysdeps/s390/libc-tls.c b/sysdeps/s390/libc-tls.c
index f177f436e9..766d565a9c 100644
--- a/sysdeps/s390/libc-tls.c
+++ b/sysdeps/s390/libc-tls.c
@@ -1,5 +1,5 @@
 /* Thread-local storage handling in the ELF dynamic linker.  S390 version.
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
@@ -20,11 +20,9 @@
 #include <stdlib.h>
 #include <csu/libc-tls.c>
 
-#if USE_TLS
-
 /* On s390, the literal pool entry that refers to __tls_get_offset
    is not removed, even if all branches that use the literal pool
-   entry gets removed by TLS optimizations. To get binaries
+   entry gets removed by TLS optimizations.  To get binaries
    statically linked __tls_get_offset is defined here but
    aborts if it is used.  */
 
@@ -33,5 +31,3 @@ __tls_get_offset (size_t m, size_t offset)
 {
   abort ();
 }
-
-#endif
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 8bbf858fbf..64bf3423b6 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  S390 Version.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Contributed by Carl Pederson & Martin Schwidefsky.
    This file is part of the GNU C Library.
@@ -209,17 +209,11 @@ _dl_start_user:\n\
    define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
-#ifdef USE_TLS
-# define elf_machine_type_class(type) \
+#define elf_machine_type_class(type) \
   ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD		      \
      || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF)	      \
     * ELF_RTYPE_CLASS_PLT)						      \
    | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
-#else
-# define elf_machine_type_class(type) \
-  ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)	\
-   | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
-#endif
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
 #define ELF_MACHINE_JMP_SLOT    R_390_JMP_SLOT
@@ -315,7 +309,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  *reloc_addr = value + reloc->r_addend;
 	  break;
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \
     && !defined RESOLVE_CONFLICT_FIND_MAP
 	case R_390_TLS_DTPMOD:
 # ifdef RTLD_BOOTSTRAP
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index 5026a2edad..fa893befdf 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -1,6 +1,6 @@
 /* Machine-dependent ELF dynamic relocation inline functions.
    64 bit S/390 Version.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001-2005, 2006 Free Software Foundation, Inc.
    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
    This file is part of the GNU C Library.
 
@@ -192,17 +192,11 @@ _dl_start_user:\n\
    define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
-#ifdef USE_TLS
-# define elf_machine_type_class(type) \
+#define elf_machine_type_class(type) \
   ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD		      \
      || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF)	      \
     * ELF_RTYPE_CLASS_PLT)						      \
    | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
-#else
-# define elf_machine_type_class(type) \
-  ((((type) == R_390_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)	\
-   | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY))
-#endif
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
 #define ELF_MACHINE_JMP_SLOT	R_390_JMP_SLOT
@@ -294,7 +288,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 	  *reloc_addr = value + reloc->r_addend;
 	  break;
 
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \
     && !defined RESOLVE_CONFLICT_FIND_MAP
 	case R_390_TLS_DTPMOD:
 # ifdef RTLD_BOOTSTRAP
diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index e73c6d79c3..78f70e3880 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  SH version.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -208,7 +208,7 @@ __fpscr_values:\n\
    define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 # define elf_machine_type_class(type) \
   ((((type) == R_SH_JMP_SLOT || (type) == R_SH_TLS_DTPMOD32		      \
      || (type) == R_SH_TLS_DTPOFF32 || (type) == R_SH_TLS_TPOFF32)	      \
@@ -354,7 +354,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  /* These addresses are always aligned.  */
 	  *reloc_addr = value;
 	  break;
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 	  /* XXX Remove TLS relocations which are not needed.  */
 	case R_SH_TLS_DTPMOD32:
 # ifdef RTLD_BOOTSTRAP
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 02dabaabb4..19aac6a7fe 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -188,7 +188,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
    PLT entries should not be allowed to define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 # define elf_machine_type_class(type) \
   ((((type) == R_SPARC_JMP_SLOT						      \
      || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64))     \
@@ -459,7 +459,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	 so we can optimize the first instruction of .plt out.  */
       sparc_fixup_plt (reloc, reloc_addr, value, 0);
       break;
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \
     && !defined RESOLVE_CONFLICT_FIND_MAP
     case R_SPARC_TLS_DTPMOD32:
       /* Get the information from the link map returned by the
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 314a784dbc..3eee672912 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -240,7 +240,7 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
    PLT entries should not be allowed to define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 # define elf_machine_type_class(type) \
   ((((type) == R_SPARC_JMP_SLOT						      \
      || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64))     \
@@ -589,7 +589,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
       sparc64_fixup_plt (map, reloc, reloc_addr, value, reloc->r_addend, 0);
 #endif
       break;
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \
     && !defined RESOLVE_CONFLICT_FIND_MAP
     case R_SPARC_TLS_DTPMOD64:
       /* Get the information from the link map returned by the
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 7c015b1d62..137b44c2b8 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -126,6 +126,9 @@ libc {
   GLIBC_2.5 {
     splice; sync_file_range; tee; vmsplice;
   }
+  GLIBC_2.6 {
+    epoll_pwait;
+  }
   GLIBC_PRIVATE {
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/bits/statvfs.h b/sysdeps/unix/sysv/linux/bits/statvfs.h
index cca0871ac0..84717c3d96 100644
--- a/sysdeps/unix/sysv/linux/bits/statvfs.h
+++ b/sysdeps/unix/sysv/linux/bits/statvfs.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1997,1998,2000,2001,2002,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
@@ -101,7 +101,9 @@ enum
 # define ST_IMMUTABLE	ST_IMMUTABLE
   ST_NOATIME = 1024,		/* Do not update access times.  */
 # define ST_NOATIME	ST_NOATIME
-  ST_NODIRATIME = 2048		/* Do not update directory access times.  */
+  ST_NODIRATIME = 2048,		/* Do not update directory access times.  */
 # define ST_NODIRATIME	ST_NODIRATIME
+  ST_RELATIME = 4096		/* Update atime relative to mtime/ctime.  */
+# define ST_RELATIME	ST_RELATIME
 #endif	/* Use GNU.  */
 };
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index 46161a806a..13ccd7acb4 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -1,5 +1,5 @@
 /* Determine protocol families for which interfaces exist.  Linux version.
-   Copyright (C) 2003, 2006, 2007 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
@@ -71,38 +71,17 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
   memset (&nladdr, '\0', sizeof (nladdr));
   nladdr.nl_family = AF_NETLINK;
 
-#ifdef PAGE_SIZE
-  /* Help the compiler optimize out the malloc call if PAGE_SIZE
-     is constant and smaller or equal to PTHREAD_STACK_MIN/4.  */
-  const size_t buf_size = PAGE_SIZE;
-#else
-  const size_t buf_size = __getpagesize ();
-#endif
-  bool use_malloc = false;
-  char *buf;
-
-  if (__libc_use_alloca (buf_size))
-    buf = alloca (buf_size);
-  else
-    {
-      buf = malloc (buf_size);
-      if (buf != NULL)
-	use_malloc = true;
-      else
-	goto out_fail;
-    }
-
-  struct iovec iov = { buf, buf_size };
-
   if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
 				    (struct sockaddr *) &nladdr,
 				    sizeof (nladdr))) < 0)
-    goto out_fail;
+    return -1;
 
   *seen_ipv4 = false;
   *seen_ipv6 = false;
 
   bool done = false;
+  char buf[4096];
+  struct iovec iov = { buf, sizeof (buf) };
   struct in6ailist
   {
     struct in6addrinfo info;
@@ -122,10 +101,10 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
 
       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
       if (read_len < 0)
-	goto out_fail;
+	return -1;
 
       if (msg.msg_flags & MSG_TRUNC)
-	goto out_fail;
+	return -1;
 
       struct nlmsghdr *nlmh;
       for (nlmh = (struct nlmsghdr *) buf;
@@ -207,7 +186,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
     {
       *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
       if (*in6ai == NULL)
-	goto out_fail;
+	return -1;
 
       *in6ailen = in6ailistlen;
 
@@ -219,14 +198,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
       while (in6ailist != NULL);
     }
 
-  if (use_malloc)
-    free (buf);
   return 0;
-
-out_fail:
-  if (use_malloc)
-    free (buf);
-  return -1;
 }
 
 
diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S
index 54524ec120..f73a4b5195 100644
--- a/sysdeps/unix/sysv/linux/i386/clone.S
+++ b/sysdeps/unix/sysv/linux/i386/clone.S
@@ -120,6 +120,9 @@ L(pseudo_end):
 	ret
 
 L(thread_start):
+	cfi_startproc;
+	/* Clearing frame pointer is insufficient, use CFI.  */
+	cfi_undefined (eip);
 	/* Note: %esi is zero.  */
 	movl	%esi,%ebp	/* terminate the stack frame */
 #ifdef RESET_PID
@@ -152,6 +155,7 @@ L(nomoregetpid):
 	jmp	L(haspid)
 	.previous
 #endif
+	cfi_endproc;
 
 	cfi_startproc
 PSEUDO_END (BP_SYM (__clone))
diff --git a/sysdeps/unix/sysv/linux/i386/getgroups.c b/sysdeps/unix/sysv/linux/i386/getgroups.c
index b7a0a4efd4..f69baf943b 100644
--- a/sysdeps/unix/sysv/linux/i386/getgroups.c
+++ b/sysdeps/unix/sysv/linux/i386/getgroups.c
@@ -52,8 +52,6 @@ __getgroups (int n, gid_t *groups)
     }
   else
     {
-      int i, ngids;
-      __kernel_gid_t kernel_groups[n = MIN (n, __sysconf (_SC_NGROUPS_MAX))];
 # ifdef __NR_getgroups32
       if (__libc_missing_32bit_uids <= 0)
 	{
@@ -69,6 +67,9 @@ __getgroups (int n, gid_t *groups)
 	}
 # endif /* __NR_getgroups32 */
 
+      int i, ngids;
+      __kernel_gid_t kernel_groups[n = MIN (n, __sysconf (_SC_NGROUPS_MAX))];
+
       ngids = INLINE_SYSCALL (getgroups, 2, n, CHECK_N (kernel_groups, n));
       if (n != 0 && ngids > 0)
 	for (i = 0; i < ngids; i++)
diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c
index 299574dac4..b5c1b98573 100644
--- a/sysdeps/unix/sysv/linux/i386/sigaction.c
+++ b/sysdeps/unix/sysv/linux/i386/sigaction.c
@@ -1,5 +1,5 @@
 /* POSIX.1 `sigaction' call for Linux/i386.
-   Copyright (C) 1991,1995-2000,2002-2004,2005 Free Software Foundation, Inc.
+   Copyright (C) 1991,1995-2000,2002-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
@@ -46,18 +46,10 @@ int __libc_missing_rt_sigs;
 
 /* Using the hidden attribute here does not change the code but it
    helps to avoid warnings.  */
-#if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \
-    && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
-# ifdef __NR_rt_sigaction
+#ifdef __NR_rt_sigaction
 extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
-# endif
-extern void restore (void) asm ("__restore") attribute_hidden;
-#else
-# ifdef __NR_rt_sigaction
-static void restore_rt (void) asm ("__restore_rt");
-# endif
-static void restore (void) asm ("__restore");
 #endif
+extern void restore (void) asm ("__restore") attribute_hidden;
 
 
 /* If ACT is not NULL, change the action for SIG to *ACT.
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index 02e6935538..82495de03e 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -1,5 +1,5 @@
 /* getifaddrs -- get names and addresses of all network interfaces
-   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 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
@@ -122,36 +122,36 @@ int
 __netlink_request (struct netlink_handle *h, int type)
 {
   struct netlink_res *nlm_next;
+  struct netlink_res **new_nlm_list;
+  static volatile size_t buf_size = 4096;
+  char *buf;
   struct sockaddr_nl nladdr;
   struct nlmsghdr *nlmh;
   ssize_t read_len;
   bool done = false;
-
-#ifdef PAGE_SIZE
-  /* Help the compiler optimize out the malloc call if PAGE_SIZE
-     is constant and smaller or equal to PTHREAD_STACK_MIN/4.  */
-  const size_t buf_size = PAGE_SIZE;
-#else
-  const size_t buf_size = __getpagesize ();
-#endif
   bool use_malloc = false;
-  char *buf;
 
-  if (__libc_use_alloca (buf_size))
-    buf = alloca (buf_size);
+  if (__netlink_sendreq (h, type) < 0)
+    return -1;
+
+  size_t this_buf_size = buf_size;
+  if (__libc_use_alloca (this_buf_size))
+    buf = alloca (this_buf_size);
   else
     {
-      buf = malloc (buf_size);
+      buf = malloc (this_buf_size);
       if (buf != NULL)
 	use_malloc = true;
       else
 	goto out_fail;
     }
 
-  struct iovec iov = { buf, buf_size };
+  struct iovec iov = { buf, this_buf_size };
 
-  if (__netlink_sendreq (h, type) < 0)
-    goto out_fail;
+  if (h->nlm_list != NULL)
+    new_nlm_list = &h->end_ptr->next;
+  else
+    new_nlm_list = &h->nlm_list;
 
   while (! done)
     {
@@ -171,7 +171,48 @@ __netlink_request (struct netlink_handle *h, int type)
 	continue;
 
       if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
-	goto out_fail;
+	{
+	  if (this_buf_size >= SIZE_MAX / 2)
+	    goto out_fail;
+
+	  nlm_next = *new_nlm_list;
+	  while (nlm_next != NULL)
+	    {
+	      struct netlink_res *tmpptr;
+
+	      tmpptr = nlm_next->next;
+	      free (nlm_next);
+	      nlm_next = tmpptr;
+	    }
+	  *new_nlm_list = NULL;
+
+	  if (__libc_use_alloca (2 * this_buf_size))
+	    buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size);
+	  else
+	    {
+	      this_buf_size *= 2;
+
+	      char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size);
+	      if (new_buf == NULL)
+		goto out_fail;
+	      new_buf = buf;
+
+	      use_malloc = true;
+	    }
+	  buf_size = this_buf_size;
+
+	  iov.iov_base = buf;
+	  iov.iov_len = this_buf_size;
+
+	  /* Increase sequence number, so that we can distinguish
+	     between old and new request messages.  */
+	  h->seq++;
+
+	  if (__netlink_sendreq (h, type) < 0)
+	    goto out_fail;
+
+	  continue;
+	}
 
       size_t count = 0;
       size_t remaining_len = read_len;
diff --git a/sysdeps/unix/sysv/linux/internal_statvfs.c b/sysdeps/unix/sysv/linux/internal_statvfs.c
index 73317ecafd..28c1cb691f 100644
--- a/sysdeps/unix/sysv/linux/internal_statvfs.c
+++ b/sysdeps/unix/sysv/linux/internal_statvfs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -156,6 +156,8 @@ __statvfs_getflags (const char *name, int fstype, struct stat64 *st)
 		  result |= ST_NOATIME;
 		else if (strcmp (opt, "nodiratime") == 0)
 		  result |= ST_NODIRATIME;
+		else if (strcmp (opt, "relatime") == 0)
+		  result |= ST_RELATIME;
 
 	      /* We can stop looking for more entries.  */
 	      success = true;
diff --git a/sysdeps/unix/sysv/linux/posix_madvise.c b/sysdeps/unix/sysv/linux/posix_madvise.c
deleted file mode 100644
index 880b17ef31..0000000000
--- a/sysdeps/unix/sysv/linux/posix_madvise.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 2007 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 <sys/mman.h>
-
-
-int
-posix_madvise (void *addr, size_t len, int advice)
-{
-  /* We have one problem: the kernel's MADV_DONTNEED does not
-     correspond to POSIX's POSIX_MADV_DONTNEED.  The former simply
-     discards changes made to the memory without writing it back to
-     disk, if this would be necessary.  The POSIX behavior does not
-     allow this.  There is no functionality mapping the POSIX behavior
-     so far so we ignore that advice for now.  */
-  if (advice == POSIX_MADV_DONTNEED)
-    return 0;
-
-  INTERNAL_SYSCALL_DECL (err);
-  int result = INTERNAL_SYSCALL (madvise, err, 3, addr, len, advice);
-  return INTERNAL_SYSCALL_ERRNO (result, err);
-}
diff --git a/sysdeps/unix/sysv/linux/sh/bits/shm.h b/sysdeps/unix/sysv/linux/sh/bits/shm.h
new file mode 100644
index 0000000000..189179394b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/bits/shm.h
@@ -0,0 +1,101 @@
+/* Copyright (C) 1995,1996,1997,2000,2002,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.  */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+
+/* Permission flag for shmget.  */
+#define SHM_R		0400		/* or S_IRUGO from <linux/stat.h> */
+#define SHM_W		0200		/* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'.  */
+#define SHM_RDONLY	010000		/* attach read-only else read-write */
+#define SHM_RND		020000		/* round attach address to SHMLBA */
+#define SHM_REMAP	040000		/* take-over region on attach */
+
+/* Commands for `shmctl'.  */
+#define SHM_LOCK	11		/* lock segment (root only) */
+#define SHM_UNLOCK	12		/* unlock segment (root only) */
+
+__BEGIN_DECLS
+
+/* Segment low boundary address multiple.  */
+#define SHMLBA		0x4000
+
+/* Type to count number of attaches.  */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a set of semaphores.  */
+struct shmid_ds
+  {
+    struct ipc_perm shm_perm;		/* operation permission struct */
+    size_t shm_segsz;			/* size of segment in bytes */
+    __time_t shm_atime;			/* time of last shmat() */
+    unsigned long int __unused1;
+    __time_t shm_dtime;			/* time of last shmdt() */
+    unsigned long int __unused2;
+    __time_t shm_ctime;			/* time of last change by shmctl() */
+    unsigned long int __unused3;
+    __pid_t shm_cpid;			/* pid of creator */
+    __pid_t shm_lpid;			/* pid of last shmop */
+    shmatt_t shm_nattch;		/* number of current attaches */
+    unsigned long int __unused4;
+    unsigned long int __unused5;
+  };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 	13
+# define SHM_INFO 	14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST	01000	/* segment will be destroyed on last detach */
+# define SHM_LOCKED	02000   /* segment will not be swapped */
+# define SHM_HUGETLB	04000	/* segment is mapped via hugetlb */
+# define SHM_NORESERVE	010000	/* don't check for reservations */
+
+struct	shminfo
+  {
+    unsigned long int shmmax;
+    unsigned long int shmmin;
+    unsigned long int shmmni;
+    unsigned long int shmseg;
+    unsigned long int shmall;
+    unsigned long int __unused1;
+    unsigned long int __unused2;
+    unsigned long int __unused3;
+    unsigned long int __unused4;
+  };
+
+struct shm_info
+  {
+    int used_ids;
+    unsigned long int shm_tot;	/* total allocated shm */
+    unsigned long int shm_rss;	/* total resident shm */
+    unsigned long int shm_swp;	/* total swapped shm */
+    unsigned long int swap_attempts;
+    unsigned long int swap_successes;
+  };
+
+#endif /* __USE_MISC */
+
+__END_DECLS
diff --git a/sysdeps/unix/sysv/linux/sh/sys/io.h b/sysdeps/unix/sysv/linux/sh/sys/io.h
deleted file mode 100644
index 6fdc44ff89..0000000000
--- a/sysdeps/unix/sysv/linux/sh/sys/io.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (C) 1996, 1998, 1999, 2000 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.  */
-
-#ifndef	_SYS_IO_H
-
-#define	_SYS_IO_H	1
-#include <features.h>
-
-__BEGIN_DECLS
-
-/* If TURN_ON is TRUE, request for permission to do direct i/o on the
-   port numbers in the range [FROM,FROM+NUM-1].  Otherwise, turn I/O
-   permission off for that range.  This call requires root privileges.  */
-extern int ioperm (unsigned long int __from, unsigned long int __num,
-		   int __turn_on) __THROW;
-
-/* Set the I/O privilege level to LEVEL.  If LEVEL is nonzero,
-   permission to access any I/O port is granted.  This call requires
-   root privileges. */
-extern int iopl (int __level) __THROW;
-
-/* The functions that actually perform reads and writes.  */
-extern unsigned char inb (unsigned long int port) __THROW;
-extern unsigned short int inw (unsigned long int port) __THROW;
-extern unsigned long int inl (unsigned long int port) __THROW;
-
-extern void outb (unsigned char value, unsigned long int port) __THROW;
-extern void outw (unsigned short value, unsigned long int port) __THROW;
-extern void outl (unsigned long value, unsigned long int port) __THROW;
-
-__END_DECLS
-
-#endif /* _SYS_IO_H */
diff --git a/sysdeps/unix/sysv/linux/sys/epoll.h b/sysdeps/unix/sysv/linux/sys/epoll.h
index 68f173a04d..d8901f7d53 100644
--- a/sysdeps/unix/sysv/linux/sys/epoll.h
+++ b/sysdeps/unix/sysv/linux/sys/epoll.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 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
@@ -22,6 +22,14 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+/* Get __sigset_t.  */
+#include <bits/sigset.h>
+
+#ifndef __sigset_t_defined
+# define __sigset_t_defined
+typedef __sigset_t sigset_t;
+#endif
+
 
 enum EPOLL_EVENTS
   {
@@ -105,6 +113,16 @@ extern int epoll_ctl (int __epfd, int __op, int __fd,
 extern int epoll_wait (int __epfd, struct epoll_event *__events,
 		       int __maxevents, int __timeout);
 
+
+/* Same as epoll_wait, but the thread's signal mask is temporarily
+   and atomically replaced with the one provided as parameter.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW.  */
+extern int epoll_pwait (int __epfd, struct epoll_event *__events,
+			int __maxevents, int __timeout,
+			__const __sigset_t *__ss);
+
 __END_DECLS
 
 #endif /* sys/epoll.h */
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index e16110480f..5776673733 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -10,7 +10,8 @@ delete_module	EXTRA	delete_module	3	delete_module
 epoll_create	EXTRA	epoll_create	i:i	epoll_create
 epoll_ctl	EXTRA	epoll_ctl	i:iiip	epoll_ctl
 epoll_wait	EXTRA	epoll_wait	Ci:ipii	epoll_wait
-fdatasync	-	fdatasync	Ci:i	fdatasync
+epoll_pwait	EXTRA	epoll_pwait	Ci:ipiipi	epoll_pwait
+fdatasync	-	fdatasync	i:i	fdatasync
 flock		-	flock		i:ii	__flock		flock
 fork		-	fork		i:	__libc_fork	__fork fork
 get_kernel_syms	EXTRA	get_kernel_syms	i:p	get_kernel_syms
@@ -31,6 +32,7 @@ ioperm		-	ioperm		i:iii	ioperm
 iopl		-	iopl		i:i	iopl
 klogctl		EXTRA	syslog		i:isi	klogctl
 lchown		-	lchown		i:sii	__lchown	lchown
+posix_madvise	-	madvise		Vi:pii	posix_madvise
 madvise		-	madvise		i:pii	madvise
 mincore		-	mincore		i:anV	mincore
 mlock		-	mlock		i:bn	mlock
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index 0f20367236..bdad5063df 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -10,6 +10,6 @@ ifeq ($(subdir),stdlib)
 sysdep_routines += __start_context
 endif
 
-ifeq ($(subdir),stdlib)
+ifeq ($(subdir),csu)
 gen-as-const-headers += ucontext_i.sym
 endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S
index 8a12b09035..db42f209c9 100644
--- a/sysdeps/unix/sysv/linux/x86_64/clone.S
+++ b/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -89,6 +89,9 @@ L(pseudo_end):
 	ret
 
 L(thread_start):
+	cfi_startproc;
+	/* Clearing frame pointer is insufficient, use CFI.  */
+	cfi_undefined (rip);
 	/* Clear the frame pointer.  The ABI suggests this be done, to mark
 	   the outermost frame obviously.  */
 	xorl	%ebp, %ebp
@@ -113,6 +116,7 @@ L(thread_start):
 	/* Call exit with return value from function call. */
 	movq	%rax, %rdi
 	call	HIDDEN_JUMPTARGET (_exit)
+	cfi_endproc;
 
 	cfi_startproc;
 PSEUDO_END (BP_SYM (__clone))
diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
index d6f4558cef..ab10123858 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c
+++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
@@ -1,5 +1,5 @@
 /* POSIX.1 `sigaction' call for Linux/x86-64.
-   Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 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
@@ -33,17 +33,14 @@
    translate it here.  */
 #include <kernel_sigaction.h>
 
+#include "ucontext_i.h"
+
 /* We do not globally define the SA_RESTORER flag so do it here.  */
 #define SA_RESTORER 0x04000000
 
 /* Using the hidden attribute here does not change the code but it
    helps to avoid warnings.  */
-#if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \
-    && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
 extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
-#else
-static void restore_rt (void) asm ("__restore_rt");
-#endif
 
 
 /* If ACT is not NULL, change the action for SIG to *ACT.
@@ -95,18 +92,95 @@ weak_alias (__libc_sigaction, sigaction)
    signal handlers work right.  Important are both the names
    (__restore_rt) and the exact instruction sequence.
    If you ever feel the need to make any changes, please notify the
-   appropriate GDB maintainer.  */
+   appropriate GDB maintainer.
+
+   The unwind information starts a byte before __restore_rt, so that
+   it is found when unwinding, to get an address the unwinder assumes
+   will be in the middle of a call instruction.  See the Linux kernel
+   (the i386 vsyscall, in particular) for an explanation of the complex
+   unwind information used here in order to get the traditional CFA.
+   We do not restore cs - it's only stored as two bytes here so that's
+   a bit tricky.  We don't use the gas cfi directives, so that we can
+   reliably add .cfi_signal_frame.  */
+
+#define do_cfa_expr						\
+  "	.byte 0x0f\n"		/* DW_CFA_def_cfa_expression */	\
+  "	.uleb128 2f-1f\n"	/* length */			\
+  "1:	.byte 0x77\n"		/* DW_OP_breg7 */		\
+  "	.sleb128 " CFI_STRINGIFY (oRSP) "\n"			\
+  "	.byte 0x06\n"		/* DW_OP_deref */		\
+  "2:"
+
+#define do_expr(regno, offset)					\
+  "	.byte 0x10\n"		/* DW_CFA_expression */		\
+  "	.uleb128 " CFI_STRINGIFY (regno) "\n"			\
+  "	.uleb128 2f-1f\n"	/* length */			\
+  "1:	.byte 0x77\n"		/* DW_OP_breg7 */		\
+  "	.sleb128 " CFI_STRINGIFY (offset) "\n"			\
+  "2:"
 
 #define RESTORE(name, syscall) RESTORE2 (name, syscall)
 # define RESTORE2(name, syscall) \
-asm						\
-  (						\
-   ".align 16\n"				\
-   CFI_STARTPROC "\n"				\
-   "__" #name ":\n"				\
-   "	movq $" #syscall ", %rax\n"		\
-   "	syscall\n"				\
-   CFI_ENDPROC "\n"				\
+asm									\
+  (									\
+   /* `nop' for debuggers assuming `call' should not disalign the code.  */ \
+   "	nop\n"								\
+   ".align 16\n"							\
+   ".LSTART_" #name ":\n"						\
+   "	.type __" #name ",@function\n"					\
+   "__" #name ":\n"							\
+   "	movq $" #syscall ", %rax\n"					\
+   "	syscall\n"							\
+   ".LEND_" #name ":\n"							\
+   ".section .eh_frame,\"a\",@progbits\n"				\
+   ".LSTARTFRAME_" #name ":\n"						\
+   "	.long .LENDCIE_" #name "-.LSTARTCIE_" #name "\n"		\
+   ".LSTARTCIE_" #name ":\n"						\
+   "	.long 0\n"	/* CIE ID */					\
+   "	.byte 1\n"	/* Version number */				\
+   "	.string \"zRS\"\n" /* NUL-terminated augmentation string */	\
+   "	.uleb128 1\n"	/* Code alignment factor */			\
+   "	.sleb128 -8\n"	/* Data alignment factor */			\
+   "	.uleb128 16\n"	/* Return address register column (rip) */	\
+   /* Augmentation value length */					\
+   "	.uleb128 .LENDAUGMNT_" #name "-.LSTARTAUGMNT_" #name "\n"	\
+   ".LSTARTAUGMNT_" #name ":\n"						\
+   "	.byte 0x1b\n"	/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */		\
+   ".LENDAUGMNT_" #name ":\n"						\
+   "	.align 8\n"							\
+   ".LENDCIE_" #name ":\n"						\
+   "	.long .LENDFDE_" #name "-.LSTARTFDE_" #name "\n" /* FDE len */	\
+   ".LSTARTFDE_" #name ":\n"						\
+   "	.long .LSTARTFDE_" #name "-.LSTARTFRAME_" #name "\n" /* CIE */	\
+   /* `LSTART_' is subtracted 1 as debuggers assume a `call' here.  */	\
+   "	.long (.LSTART_" #name "-1)-.\n" /* PC-relative start addr.  */	\
+   "	.long .LEND_" #name "-(.LSTART_" #name "-1)\n"			\
+   "	.uleb128 0\n"			/* FDE augmentation length */	\
+   do_cfa_expr								\
+   do_expr (8 /* r8 */, oR8)						\
+   do_expr (9 /* r9 */, oR9)						\
+   do_expr (10 /* r10 */, oR10)						\
+   do_expr (11 /* r11 */, oR11)						\
+   do_expr (12 /* r12 */, oR12)						\
+   do_expr (13 /* r13 */, oR13)						\
+   do_expr (14 /* r14 */, oR14)						\
+   do_expr (15 /* r15 */, oR15)						\
+   do_expr (5 /* rdi */, oRDI)						\
+   do_expr (4 /* rsi */, oRSI)						\
+   do_expr (6 /* rbp */, oRBP)						\
+   do_expr (3 /* rbx */, oRBX)						\
+   do_expr (1 /* rdx */, oRDX)						\
+   do_expr (0 /* rax */, oRAX)						\
+   do_expr (2 /* rcx */, oRCX)						\
+   do_expr (7 /* rsp */, oRSP)						\
+   do_expr (16 /* rip */, oRIP)						\
+   /* libgcc-4.1.1 has only `DWARF_FRAME_REGISTERS == 17'.  */		\
+   /* do_expr (49 |* rflags *|, oEFL) */				\
+   /* `cs'/`ds'/`fs' are unaligned and a different size.  */		\
+   /* gas: Error: register save offset not a multiple of 8  */		\
+   "	.align 8\n"							\
+   ".LENDFDE_" #name ":\n"						\
+   "	.previous\n"							\
    );
 /* The return code for realtime-signals.  */
 RESTORE (restore_rt, __NR_rt_sigreturn)
diff --git a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
index b3cfe9aa4c..af3e0e544b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
+++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
@@ -18,6 +18,8 @@ oRSP		mreg (RSP)
 oRBX		mreg (RBX)
 oR8		mreg (R8)
 oR9		mreg (R9)
+oR10		mreg (R10)
+oR11		mreg (R11)
 oR12		mreg (R12)
 oR13		mreg (R13)
 oR14		mreg (R14)
@@ -28,6 +30,7 @@ oRDX		mreg (RDX)
 oRAX		mreg (RAX)
 oRCX		mreg (RCX)
 oRIP		mreg (RIP)
+oEFL		mreg (EFL)
 oFPREGS		mcontext (fpregs)
 oSIGMASK	ucontext (uc_sigmask)
 oFPREGSMEM	ucontext (__fpregs_mem)
diff --git a/sysdeps/x86_64/bits/atomic.h b/sysdeps/x86_64/bits/atomic.h
index 133a68d192..65d6b02008 100644
--- a/sysdeps/x86_64/bits/atomic.h
+++ b/sysdeps/x86_64/bits/atomic.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <stdint.h>
+#include <tls.h>	/* For tcbhead_t.  */
 
 
 typedef int8_t atomic8_t;
@@ -80,8 +81,54 @@ typedef uintmax_t uatomic_max_t;
   ({ __typeof (*mem) ret;						      \
      __asm __volatile (LOCK_PREFIX "cmpxchgq %q2, %1"			      \
 		       : "=a" (ret), "=m" (*mem)			      \
-		       : "r" ((long) (newval)), "m" (*mem),		      \
-			 "0" ((long) (oldval)));			      \
+		       : "r" ((long int) (newval)), "m" (*mem),		      \
+			 "0" ((long int) (oldval)));			      \
+     ret; })
+
+
+#define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+    __asm __volatile ("cmpl $0, %%fs:%P5\n\t"				      \
+		      "je 0f\n\t"					      \
+		      "lock\n"						      \
+		       "0:\tcmpxchgb %b2, %1"				      \
+		       : "=a" (ret), "=m" (*mem)			      \
+		       : "q" (newval), "m" (*mem), "0" (oldval),	      \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
+     ret; })
+
+#define __arch_c_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+    __asm __volatile ("cmpl $0, %%fs:%P5\n\t"				      \
+		      "je 0f\n\t"					      \
+		      "lock\n"						      \
+		       "0:\tcmpxchgw %w2, %1"				      \
+		       : "=a" (ret), "=m" (*mem)			      \
+		       : "q" (newval), "m" (*mem), "0" (oldval),	      \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
+     ret; })
+
+#define __arch_c_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+    __asm __volatile ("cmpl $0, %%fs:%P5\n\t"				      \
+		      "je 0f\n\t"					      \
+		      "lock\n"						      \
+		       "0:\tcmpxchgl %2, %1"				      \
+		       : "=a" (ret), "=m" (*mem)			      \
+		       : "q" (newval), "m" (*mem), "0" (oldval),	      \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
+     ret; })
+
+#define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+  ({ __typeof (*mem) ret;						      \
+     __asm __volatile ("cmpl $0, %%fs:%P5\n\t"				      \
+		       "je 0f\n\t"					      \
+		       "lock\n"						      \
+		       "0:\tcmpxchgq %q2, %1"				      \
+		       : "=a" (ret), "=m" (*mem)			      \
+		       : "q" ((long int) (newval)), "m" (*mem),		      \
+			 "0" ((long int)oldval),			      \
+			 "i" (offsetof (tcbhead_t, multiple_threads)));	      \
      ret; })
 
 
@@ -107,49 +154,76 @@ typedef uintmax_t uatomic_max_t;
      result; })
 
 
-#define atomic_exchange_and_add(mem, value) \
+#define __arch_exchange_and_add_body(lock, mem, value)			      \
   ({ __typeof (*mem) result;						      \
      if (sizeof (*mem) == 1)						      \
-       __asm __volatile (LOCK_PREFIX "xaddb %b0, %1"			      \
+       __asm __volatile (lock "xaddb %b0, %1"				      \
 			 : "=r" (result), "=m" (*mem)			      \
-			 : "0" (value), "m" (*mem));			      \
+			 : "0" (value), "m" (*mem),			      \
+			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      else if (sizeof (*mem) == 2)					      \
-       __asm __volatile (LOCK_PREFIX "xaddw %w0, %1"			      \
+       __asm __volatile (lock "xaddw %w0, %1"				      \
 			 : "=r" (result), "=m" (*mem)			      \
-			 : "0" (value), "m" (*mem));			      \
+			 : "0" (value), "m" (*mem),			      \
+			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      else if (sizeof (*mem) == 4)					      \
-       __asm __volatile (LOCK_PREFIX "xaddl %0, %1"			      \
+       __asm __volatile (lock "xaddl %0, %1"				      \
 			 : "=r" (result), "=m" (*mem)			      \
-			 : "0" (value), "m" (*mem));			      \
+			 : "0" (value), "m" (*mem),			      \
+			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      else								      \
-       __asm __volatile (LOCK_PREFIX "xaddq %q0, %1"			      \
+       __asm __volatile (lock "xaddq %q0, %1"				      \
 			 : "=r" (result), "=m" (*mem)			      \
-			 : "0" ((long) (value)), "m" (*mem));		      \
+			 : "0" ((long) (value)), "m" (*mem),		      \
+			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
      result; })
 
+#define atomic_exchange_and_add(mem, value) \
+  __arch_exchange_and_add_body (LOCK_PREFIX, mem, value)
+
+#define __arch_exchange_and_add_cprefix \
+  "cmpl $0, %%fs:%P4\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_exchange_and_add(mem, value) \
+  __arch_exchange_and_add_body (__arch_exchange_and_add_cprefix, mem, value)
+
+
+#define __arch_add_body(lock, pfx, mem, value)				      \
+  do {									      \
+    if (__builtin_constant_p (value) && (value) == 1)			      \
+      pfx##_increment (mem);						      \
+    else if (__builtin_constant_p (value) && (value) == -1)		      \
+      pfx##_decrement (mem);						      \
+    else if (sizeof (*mem) == 1)					      \
+      __asm __volatile (lock "addb %b1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (value), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (lock "addw %w1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (value), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (lock "addl %1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (value), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else								      \
+      __asm __volatile (lock "addq %q1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" ((long) (value)), "m" (*mem),		      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+  } while (0)
 
 #define atomic_add(mem, value) \
-  (void) ({ if (__builtin_constant_p (value) && (value) == 1)		      \
-	      atomic_increment (mem);					      \
-	    else if (__builtin_constant_p (value) && (value) == 1)	      \
-	      atomic_decrement (mem);					      \
-	    else if (sizeof (*mem) == 1)				      \
-	      __asm __volatile (LOCK_PREFIX "addb %b1, %0"		      \
-				: "=m" (*mem)				      \
-				: "ir" (value), "m" (*mem));		      \
-	    else if (sizeof (*mem) == 2)				      \
-	      __asm __volatile (LOCK_PREFIX "addw %w1, %0"		      \
-				: "=m" (*mem)				      \
-				: "ir" (value), "m" (*mem));		      \
-	    else if (sizeof (*mem) == 4)				      \
-	      __asm __volatile (LOCK_PREFIX "addl %1, %0"		      \
-				: "=m" (*mem)				      \
-				: "ir" (value), "m" (*mem));		      \
-	    else							      \
-	      __asm __volatile (LOCK_PREFIX "addq %q1, %0"		      \
-				: "=m" (*mem)				      \
-				: "ir" ((long) (value)), "m" (*mem));	      \
-	    })
+  __arch_add_body (LOCK_PREFIX, atomic, mem, value)
+
+#define __arch_add_cprefix \
+  "cmpl $0, %%fs:%P3\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_add(mem, value) \
+  __arch_add_body (__arch_add_cprefix, catomic, mem, value)
 
 
 #define atomic_add_negative(mem, value) \
@@ -194,24 +268,37 @@ typedef uintmax_t uatomic_max_t;
      __result; })
 
 
-#define atomic_increment(mem) \
-  (void) ({ if (sizeof (*mem) == 1)					      \
-	      __asm __volatile (LOCK_PREFIX "incb %b0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else if (sizeof (*mem) == 2)				      \
-	      __asm __volatile (LOCK_PREFIX "incw %w0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else if (sizeof (*mem) == 4)				      \
-	      __asm __volatile (LOCK_PREFIX "incl %0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else							      \
-	      __asm __volatile (LOCK_PREFIX "incq %q0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    })
+#define __arch_increment_body(lock, mem) \
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (lock "incb %b0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (lock "incw %w0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (lock "incl %0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else								      \
+      __asm __volatile (lock "incq %q0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+  } while (0)
+
+#define atomic_increment(mem) __arch_increment_body (LOCK_PREFIX, mem)
+
+#define __arch_increment_cprefix \
+  "cmpl $0, %%fs:%P2\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_increment(mem) \
+  __arch_increment_body (__arch_increment_cprefix, mem)
 
 
 #define atomic_increment_and_test(mem) \
@@ -235,24 +322,37 @@ typedef uintmax_t uatomic_max_t;
      __result; })
 
 
-#define atomic_decrement(mem) \
-  (void) ({ if (sizeof (*mem) == 1)					      \
-	      __asm __volatile (LOCK_PREFIX "decb %b0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else if (sizeof (*mem) == 2)				      \
-	      __asm __volatile (LOCK_PREFIX "decw %w0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else if (sizeof (*mem) == 4)				      \
-	      __asm __volatile (LOCK_PREFIX "decl %0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    else							      \
-	      __asm __volatile (LOCK_PREFIX "decq %q0"			      \
-				: "=m" (*mem)				      \
-				: "m" (*mem));				      \
-	    })
+#define __arch_decrement_body(lock, mem) \
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (lock "decb %b0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (lock "decw %w0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (lock "decl %0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else								      \
+      __asm __volatile (lock "decq %q0"					      \
+			: "=m" (*mem)					      \
+			: "m" (*mem),					      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+  } while (0)
+
+#define atomic_decrement(mem) __arch_decrement_body (LOCK_PREFIX, mem)
+
+#define __arch_decrement_cprefix \
+  "cmpl $0, %%fs:%P2\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_decrement(mem) \
+  __arch_decrement_body (__arch_decrement_cprefix, mem)
 
 
 #define atomic_decrement_and_test(mem) \
@@ -277,27 +377,28 @@ typedef uintmax_t uatomic_max_t;
 
 
 #define atomic_bit_set(mem, bit) \
-  (void) ({ if (sizeof (*mem) == 1)					      \
-	      __asm __volatile (LOCK_PREFIX "orb %b2, %0"		      \
-				: "=m" (*mem)				      \
-				: "m" (*mem), "ir" (1L << (bit)));	      \
-	    else if (sizeof (*mem) == 2)				      \
-	      __asm __volatile (LOCK_PREFIX "orw %w2, %0"		      \
-				: "=m" (*mem)				      \
-				: "m" (*mem), "ir" (1L << (bit)));	      \
-	    else if (sizeof (*mem) == 4)				      \
-	      __asm __volatile (LOCK_PREFIX "orl %2, %0"		      \
-				: "=m" (*mem)				      \
-				: "m" (*mem), "ir" (1L << (bit)));	      \
-	    else if (__builtin_constant_p (bit) && (bit) < 32)		      \
-	      __asm __volatile (LOCK_PREFIX "orq %2, %0"		      \
-				: "=m" (*mem)				      \
-				: "m" (*mem), "i" (1L << (bit)));	      \
-	    else							      \
-	      __asm __volatile (LOCK_PREFIX "orq %q2, %0"		      \
-				: "=m" (*mem)				      \
-				: "m" (*mem), "r" (1UL << (bit)));	      \
-	    })
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (LOCK_PREFIX "orb %b2, %0"			      \
+			: "=m" (*mem)					      \
+			: "m" (*mem), "ir" (1L << (bit)));		      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (LOCK_PREFIX "orw %w2, %0"			      \
+			: "=m" (*mem)					      \
+			: "m" (*mem), "ir" (1L << (bit)));		      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (LOCK_PREFIX "orl %2, %0"			      \
+			: "=m" (*mem)					      \
+			: "m" (*mem), "ir" (1L << (bit)));		      \
+    else if (__builtin_constant_p (bit) && (bit) < 32)			      \
+      __asm __volatile (LOCK_PREFIX "orq %2, %0"			      \
+			: "=m" (*mem)					      \
+			: "m" (*mem), "i" (1L << (bit)));		      \
+    else								      \
+      __asm __volatile (LOCK_PREFIX "orq %q2, %0"			      \
+			: "=m" (*mem)					      \
+			: "m" (*mem), "r" (1UL << (bit)));		      \
+  } while (0)
 
 
 #define atomic_bit_test_set(mem, bit) \
@@ -322,3 +423,56 @@ typedef uintmax_t uatomic_max_t;
 
 
 #define atomic_delay() asm ("rep; nop")
+
+
+#define atomic_and(mem, mask) \
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (LOCK_PREFIX "andb %1, %b0"			      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem));			      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (LOCK_PREFIX "andw %1, %w0"			      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem));			      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (LOCK_PREFIX "andl %1, %0"			      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem));			      \
+    else								      \
+      __asm __volatile (LOCK_PREFIX "andq %1, %q0"			      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem));			      \
+  } while (0)
+
+
+#define __arch_or_body(lock, mem, mask)					      \
+  do {									      \
+    if (sizeof (*mem) == 1)						      \
+      __asm __volatile (lock "orb %1, %b0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 2)					      \
+      __asm __volatile (lock "orw %1, %w0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else if (sizeof (*mem) == 4)					      \
+      __asm __volatile (lock "orl %1, %0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+    else								      \
+      __asm __volatile (lock "orq %1, %q0"				      \
+			: "=m" (*mem)					      \
+			: "ir" (mask), "m" (*mem),			      \
+			  "i" (offsetof (tcbhead_t, multiple_threads)));      \
+  } while (0)
+
+#define atomic_or(mem, mask) __arch_or_body (LOCK_PREFIX, mem, mask)
+
+#define __arch_or_cprefix \
+  "cmpl $0, %%fs:%P3\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_or(mem, mask) __arch_or_body (__arch_or_cprefix, mem, mask)
diff --git a/sysdeps/x86_64/bits/byteswap.h b/sysdeps/x86_64/bits/byteswap.h
index ec2b17889d..e1c861c75f 100644
--- a/sysdeps/x86_64/bits/byteswap.h
+++ b/sysdeps/x86_64/bits/byteswap.h
@@ -1,6 +1,5 @@
 /* Macros to swap the order of bytes in integer values.
-   Copyright (C) 1997, 1998, 2000, 2002, 2003, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2000, 2002, 2003 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
@@ -60,9 +59,7 @@
 # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__	      \
 			  || defined __pentiumpro__ || defined __pentium4__   \
 			  || defined __k8__ || defined __athlon__	      \
-			  || defined __k6__ || defined __nocona__	      \
-			  || defined __core2__ || defined __geode__	      \
-			  || defined __amdfam10__)
+			  || defined __k6__)
 /* To swap the bytes in a word the i486 processors and up provide the
    `bswap' opcode.  On i386 we have to use three instructions.  */
 #  define __bswap_32(x) \
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 73e271775a..31a7013d50 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  x86-64 version.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001-2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>.
 
@@ -190,7 +190,7 @@ _dl_start_user:\n\
    define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+#if !defined RTLD_BOOTSTRAP || USE___THREAD
 # define elf_machine_type_class(type)					      \
   ((((type) == R_X86_64_JUMP_SLOT					      \
      || (type) == R_X86_64_DTPMOD64					      \
@@ -300,7 +300,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 	  *reloc_addr = value + reloc->r_addend;
 	  break;
 
-#if defined USE_TLS && !defined RESOLVE_CONFLICT_FIND_MAP
+#ifndef RESOLVE_CONFLICT_FIND_MAP
 	case R_X86_64_DTPMOD64:
 # ifdef RTLD_BOOTSTRAP
 	  /* During startup the dynamic linker is always the module
@@ -339,7 +339,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 			     - sym_map->l_tls_offset);
 	    }
 	  break;
-#endif	/* use TLS */
+#endif
 
 #ifndef RTLD_BOOTSTRAP
 	case R_X86_64_64:
diff --git a/sysdeps/x86_64/fpu/e_log10l.S b/sysdeps/x86_64/fpu/e_log10l.S
index 633234b744..b4343bef45 100644
--- a/sysdeps/x86_64/fpu/e_log10l.S
+++ b/sysdeps/x86_64/fpu/e_log10l.S
@@ -42,7 +42,7 @@ ENTRY(__ieee754_log10l)
 	fxam
 	fnstsw
 	fld	%st		// x : x : log10(2)
-	testb	$1, %ah
+	andb	$1,%ah
 	jnz	3f		// in case x is NaN or ħInf
 4:	fsubl	MO(one)		// x-1 : x : log10(2)
 	fld	%st		// x-1 : x-1 : x : log10(2)
@@ -59,8 +59,7 @@ ENTRY(__ieee754_log10l)
 	fyl2x			// log10(x)
 	ret
 
-3:	testb	$4, %ah
-	jnz	4b		// in case x is ħInf
+3:	jp	4b		// in case x is ħInf
 	fstp	%st(1)
 	fstp	%st(1)
 	ret
diff --git a/sysdeps/x86_64/fpu/e_log2l.S b/sysdeps/x86_64/fpu/e_log2l.S
index f04d30a05a..7a89b94d9f 100644
--- a/sysdeps/x86_64/fpu/e_log2l.S
+++ b/sysdeps/x86_64/fpu/e_log2l.S
@@ -39,7 +39,7 @@ ENTRY(__ieee754_log2l)
 	fxam
 	fnstsw
 	fld	%st		// x : x : 1
-	testb	$1, %ah
+	andb	$1,%ah
 	jnz	3f		// in case x is NaN or ħInf
 4:	fsub	%st(2), %st	// x-1 : x : 1
 	fld	%st		// x-1 : x-1 : x : 1
@@ -56,8 +56,7 @@ ENTRY(__ieee754_log2l)
 	fyl2x			// log(x)
 	ret
 
-3:	testb	$4, %ah
-	jnz	4b		// in case x is ħInf
+3:	jp	4b		// in case x is ħInf
 	fstp	%st(1)
 	fstp	%st(1)
 	ret
diff --git a/sysdeps/x86_64/fpu/e_logl.S b/sysdeps/x86_64/fpu/e_logl.S
index 2ba91eedfd..a0bed663c8 100644
--- a/sysdeps/x86_64/fpu/e_logl.S
+++ b/sysdeps/x86_64/fpu/e_logl.S
@@ -38,12 +38,8 @@ limit:	.double 0.29
 ENTRY(__ieee754_logl)
 	fldln2			// log(2)
 	fldt	8(%rsp)		// x : log(2)
-	fxam
-	fnstsw
 	fld	%st		// x : x : log(2)
-	testb	$1, %ah
-	jnz	3f		// in case x is NaN or +-Inf
-4:	fsubl	MO(one)		// x-1 : x : log(2)
+	fsubl	MO(one)		// x-1 : x : log(2)
 	fld	%st		// x-1 : x-1 : x : log(2)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
@@ -57,10 +53,4 @@ ENTRY(__ieee754_logl)
 2:	fstp	%st(0)		// x : log(2)
 	fyl2x			// log(x)
 	ret
-
-3:	testb	$4, %ah
-	jnz	4b		// in case x is +-Inf
-	fstp	%st(1)
-	fstp	%st(1)
-	ret
 END (__ieee754_logl)
diff --git a/sysdeps/x86_64/fpu/e_powl.S b/sysdeps/x86_64/fpu/e_powl.S
index 4959bea7ac..85f4deb3c7 100644
--- a/sysdeps/x86_64/fpu/e_powl.S
+++ b/sysdeps/x86_64/fpu/e_powl.S
@@ -1,6 +1,5 @@
 /* ix87 specific implementation of pow function.
-   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -147,11 +146,10 @@ ENTRY(__ieee754_powl)
 2:	/* y is a real number.  */
 	fxch			// x : y
 	fldl	MO(one)		// 1.0 : x : y
-	fldl	MO(limit)	// 0.29 : 1.0 : x : y
-	fld	%st(2)		// x : 0.29 : 1.0 : x : y
-	fsub	%st(2)		// x-1 : 0.29 : 1.0 : x : y
-	fabs			// |x-1| : 0.29 : 1.0 : x : y
-	fucompp			// 1.0 : x : y
+	fld	%st(1)		// x : 1.0 : x : y
+	fsub	%st(1)		// x-1 : 1.0 : x : y
+	fabs			// |x-1| : 1.0 : x : y
+	fcompl	MO(limit)	// 1.0 : x : y
 	fnstsw
 	fxch			// x : 1.0 : y
 	test	$4500,%eax
@@ -192,10 +190,9 @@ ENTRY(__ieee754_powl)
 	// y == ħinf
 	.align ALIGNARG(4)
 12:	fstp	%st(0)		// pop y
-	fldl	MO(one)		// 1
-	fldt	8(%rsp)		// x : 1
-	fabs			// abs(x) : 1
-	fucompp			// < 1, == 1, or > 1
+	fldt	8(%rsp)		// x
+	fabs
+	fcompl	MO(one)		// < 1, == 1, or > 1
 	fnstsw
 	andb	$0x45, %ah
 	cmpb	$0x45, %ah
diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h
deleted file mode 100644
index 4febcbb5ec..0000000000
--- a/sysdeps/x86_64/fpu/math_private.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _MATH_PRIVATE_H
-
-#define math_opt_barrier(x) \
-({ __typeof(x) __x;					\
-   if (sizeof (x) <= sizeof (double))			\
-     __asm ("" : "=x" (__x) : "0" (x));			\
-   else							\
-     __asm ("" : "=t" (__x) : "0" (x));			\
-   __x; })
-#define math_force_eval(x) \
-do							\
-  {							\
-    if (sizeof (x) <= sizeof (double))			\
-      __asm __volatile ("" : : "x" (x));		\
-    else						\
-      __asm __volatile ("" : : "f" (x));		\
-  }							\
-while (0)
-
-#include <math/math_private.h>
-#endif
diff --git a/sysdeps/x86_64/fpu/s_copysign.S b/sysdeps/x86_64/fpu/s_copysign.S
index f1ebcf8bf1..f3d9b0cbb4 100644
--- a/sysdeps/x86_64/fpu/s_copysign.S
+++ b/sysdeps/x86_64/fpu/s_copysign.S
@@ -1,5 +1,5 @@
 /* copy sign, double version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 2002.
 
@@ -31,6 +31,8 @@
 signmask:
 	.byte 0, 0, 0, 0, 0, 0, 0, 0x80
 	.byte 0, 0, 0, 0, 0, 0, 0, 0
+	ASM_SIZE_DIRECTIVE(signmask)
+	ASM_TYPE_DIRECTIVE(othermask,@object)
 othermask:
 	.byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
 	.byte 0, 0, 0, 0, 0, 0, 0, 0
@@ -42,6 +44,7 @@ othermask:
 #define MO(op) op
 #endif
 
+	.text
 ENTRY(__copysign)
 	andpd MO(othermask),%xmm0
 	andpd MO(signmask),%xmm1
diff --git a/sysdeps/x86_64/fpu/s_copysignf.S b/sysdeps/x86_64/fpu/s_copysignf.S
index f5dc5f78ad..0fbe1d4c96 100644
--- a/sysdeps/x86_64/fpu/s_copysignf.S
+++ b/sysdeps/x86_64/fpu/s_copysignf.S
@@ -1,5 +1,5 @@
 /* copy sign, double version.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 2002.
 
@@ -38,6 +38,7 @@ mask:
 #define MO(op) op
 #endif
 
+	.text
 ENTRY(__copysignf)
 	movss	MO(mask),%xmm3
 	andps	%xmm3,%xmm0
diff --git a/sysdeps/x86_64/fpu/s_log1pl.S b/sysdeps/x86_64/fpu/s_log1pl.S
index ac2bd22a4f..7fbd0e5aaa 100644
--- a/sysdeps/x86_64/fpu/s_log1pl.S
+++ b/sysdeps/x86_64/fpu/s_log1pl.S
@@ -45,7 +45,7 @@ ENTRY(__log1pl)
 	fxam
 	fnstsw
 	fld	%st
-	testb	$1, %ah
+	andb	$1,%ah
 	jnz	3f		// in case x is NaN or ħInf
 4:
 	fabs
@@ -62,8 +62,7 @@ ENTRY(__log1pl)
 2:	fyl2xp1
 	ret
 
-3:	testb	$4, %ah
-	jnz	4b		// in case x is ħInf
+3:	jp	4b		// in case x is ħInf
 	fstp	%st(1)
 	fstp	%st(1)
 	ret
diff --git a/sysdeps/x86_64/ldbl2mpn.c b/sysdeps/x86_64/ldbl2mpn.c
deleted file mode 100644
index 641b789cd4..0000000000
--- a/sysdeps/x86_64/ldbl2mpn.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../i386/ldbl2mpn.c"
diff --git a/sysdeps/x86_64/soft-fp/sfp-machine.h b/sysdeps/x86_64/soft-fp/sfp-machine.h
deleted file mode 100644
index 77df02380c..0000000000
--- a/sysdeps/x86_64/soft-fp/sfp-machine.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-#define __FP_CLZ(r, x)							\
-  do {									\
-    __asm__("bsrq %1,%0" : "=r"(r) : "g"(x) : "cc");			\
-    r ^= 63;								\
-  } while (0)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID           (1 << 0)
-#define FP_EX_DENORM		(1 << 1)
-#define FP_EX_DIVZERO           (1 << 2)
-#define FP_EX_OVERFLOW          (1 << 3)
-#define FP_EX_UNDERFLOW         (1 << 4)
-#define FP_EX_INEXACT           (1 << 5)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		3
-#define FP_RND_PINF		2
-#define FP_RND_MINF		1
-