about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-31 13:33:18 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-31 13:33:18 +0000
commit32c075e1f01849e161724bbd400ba77244e482cc (patch)
tree5f083a3f352104f32bb6c902d57fa3f294bd8d4d /sysdeps
parentd6220e9ee38c1c9285221b023346201ec5f511b3 (diff)
downloadglibc-32c075e1f01849e161724bbd400ba77244e482cc.tar.gz
glibc-32c075e1f01849e161724bbd400ba77244e482cc.tar.xz
glibc-32c075e1f01849e161724bbd400ba77244e482cc.zip
.
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, 1287 insertions, 1371 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 29f500b2d0..88c357ea07 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-2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1996-2002, 2003, 2004, 2005 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 RTLD_BOOTSTRAP || USE___THREAD
-# define elf_machine_type_class(type)	\
+#if defined USE_TLS && (!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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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 */
       else
 	_dl_reloc_bad_type (map, r_type, 0);
     }
diff --git a/sysdeps/alpha/libc-tls.c b/sysdeps/alpha/libc-tls.c
index 7e02769171..24629e9aca 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
@@ -20,6 +20,8 @@
 #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
@@ -31,3 +33,5 @@ __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 dda91bb806..eee6141c6a 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-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1995-2006, 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
@@ -38,7 +38,6 @@
 #include <bits/libc-lock.h>
 #include <hp-timing.h>
 #include <tls.h>
-#include <rtld-lowlevel.h>
 
 __BEGIN_DECLS
 
@@ -439,18 +438,23 @@ 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;
 
-  /* Highest dtv index currently needed.  */
-  EXTERN size_t _dl_tls_max_dtv_idx;
+  /* 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;
   /* Information about the dtv slots.  */
   EXTERN struct dtv_slotinfo_list
   {
@@ -474,10 +478,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;
@@ -485,18 +489,31 @@ 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_SDATA_SECTION
-#   define __rtld_local_attribute__ \
+#  ifdef HAVE_VISIBILITY_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")))
+#    undef __rtld_global_attribute__
+#    define __rtld_global_attribute__ __attribute__ ((section (".sdata")))
+#   else
+#    define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
+#   endif
 #  else
-#   define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
+#   define __rtld_local_attribute__
 #  endif
 extern struct rtld_global _rtld_local __rtld_local_attribute__;
 #  undef __rtld_local_attribute__
@@ -532,15 +549,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;
 
@@ -569,9 +586,6 @@ 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;
 
@@ -655,10 +669,17 @@ 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
-#  define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
+#  ifdef HAVE_VISIBILITY_ATTRIBUTE
+#   define __rtld_local_attribute__ __attribute__ ((visibility ("hidden")))
+#  else
+#   define __rtld_local_attribute__
+#  endif
 extern struct rtld_global_ro _rtld_local_ro
     attribute_relro __rtld_local_attribute__;
 extern struct rtld_global_ro _rtld_global_ro
@@ -1023,7 +1044,9 @@ 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;
@@ -1046,6 +1069,11 @@ 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;
 
@@ -1057,6 +1085,8 @@ 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 06e41ad121..6a23ec05e1 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002 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,6 +17,11 @@
    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 307c4d7020..ab67a18f64 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, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2004 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,18 +92,16 @@ 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 "declare_symbol_alias (__sys_errlist_%s, _sys_errlist_internal,", \
-      old;
-    printf " object, __WORDSIZE/8*%d)\n", 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 "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 "declare_symbol_alias (___sys_errlist_%s, _sys_errlist_internal,", \
-      old;
-    printf " object, __WORDSIZE/8*%d)\n", n;
+    printf "strong_alias (__sys_errlist_%s, ___sys_errlist_%s)\n", old, old;
     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 2c04ec9b7f..87099ec14a 100644
--- a/sysdeps/gnu/netinet/tcp.h
+++ b/sysdeps/gnu/netinet/tcp.h
@@ -49,7 +49,6 @@
 #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 3005f867f0..cb1875f9eb 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-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
@@ -40,30 +40,27 @@ 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)
-declare_symbol_alias (__old_sys_siglist, __new_sys_siglist, object,
-		      OLD_SIGLIST_SIZE * __WORDSIZE / 8)
+strong_alias (_sys_siglist_internal, __old_sys_siglist)
+declare_symbol (__old_sys_siglist, 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 (_sys_sigabbrev_internal, __old_sys_sigabbrev)
+declare_symbol (__old_sys_sigabbrev, 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
-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_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)
+strong_alias (_sys_sigabbrev_internal, __old2_sys_sigabbrev)
+declare_symbol (__old2_sys_sigabbrev, 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 bed27559c5..7f2ddc2dc5 100644
--- a/sysdeps/i386/bits/byteswap.h
+++ b/sysdeps/i386/bits/byteswap.h
@@ -1,5 +1,6 @@
 /* Macros to swap the order of bytes in integer values.
-   Copyright (C) 1997,1998,2000,2002,2003,2006 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2000, 2002, 2003, 2006, 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
@@ -66,7 +67,8 @@ __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 __k6__ && !defined __nocona__ && !defined __core2__ \
+      && !defined __geode__ && !defined __amdfam10__
 #   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 04296d2a9a..df3edf5460 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-2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2004, 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
@@ -34,7 +34,9 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
 }
 
 
-#ifdef PI_STATIC_AND_HIDDEN
+#if defined PI_STATIC_AND_HIDDEN \
+    && defined HAVE_VISIBILITY_ATTRIBUTE && defined HAVE_HIDDEN \
+    && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
 
 /* Return the link-time address of _DYNAMIC.  Conveniently, this is the
    first element of the GOT, a special entry that is never relocated.  */
@@ -242,7 +244,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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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	      \
@@ -350,7 +352,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
 	  *reloc_addr = value;
 	  break;
 
-#if !defined RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
 	case R_386_TLS_DTPMOD32:
 # ifdef RTLD_BOOTSTRAP
 	  /* During startup the dynamic linker is always the module
@@ -474,6 +476,7 @@ 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.  */
@@ -510,6 +513,7 @@ 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 5604e638f5..ce55b72292 100644
--- a/sysdeps/i386/fpu/e_log.S
+++ b/sysdeps/i386/fpu/e_log.S
@@ -36,11 +36,15 @@ 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)
-	fsubl	MO(one)		// x-1 : x : log(2)
+	sahf
+	jc	3f		// in case x is NaN or +-Inf
+4:	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)
@@ -54,4 +58,9 @@ 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 128bb2754c..cd4538b594 100644
--- a/sysdeps/i386/fpu/e_logf.S
+++ b/sysdeps/i386/fpu/e_logf.S
@@ -37,11 +37,15 @@ 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)
-	fsubl	MO(one)		// x-1 : x : log(2)
+	sahf
+	jc	3f		// in case x is NaN or +-Inf
+4:	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)
@@ -55,4 +59,9 @@ 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 5023d3012f..551dcf1e46 100644
--- a/sysdeps/i386/fpu/e_logl.S
+++ b/sysdeps/i386/fpu/e_logl.S
@@ -37,11 +37,15 @@ 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)
-	fsubl	MO(one)		// x-1 : x : log(2)
+	sahf
+	jc	3f		// in case x is NaN or +-Inf
+4:	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)
@@ -55,4 +59,9 @@ 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 c554ca4ecb..792f926902 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
+   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -161,10 +161,11 @@ ENTRY(__ieee754_pow)
 2:	/* y is a real number.  */
 	fxch			// x : y
 	fldl	MO(one)		// 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
+	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
 	fnstsw
 	fxch			// x : 1.0 : y
 	sahf
@@ -197,9 +198,10 @@ ENTRY(__ieee754_pow)
 	// y == ħinf
 	.align ALIGNARG(4)
 12:	fstp	%st(0)		// pop y
-	fldl	4(%esp)		// x
-	fabs
-	fcompl	MO(one)		// < 1, == 1, or > 1
+	fldl	MO(one)		// 1
+	fldl	4(%esp)		// x : 1
+	fabs			// abs(x) : 1
+	fucompp			// < 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 c835b978b9..c91545418d 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
+   Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -155,10 +155,11 @@ ENTRY(__ieee754_powf)
 2:	/* y is a real number.  */
 	fxch			// x : y
 	fldl	MO(one)		// 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
+	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
 	fnstsw
 	fxch			// x : 1.0 : y
 	sahf
@@ -191,9 +192,10 @@ ENTRY(__ieee754_powf)
 	// y == ħinf
 	.align ALIGNARG(4)
 12:	fstp	%st(0)		// pop y
-	flds	4(%esp)		// x
-	fabs
-	fcompl	MO(one)		// < 1, == 1, or > 1
+	fldl	MO(one)		// 1
+	flds	4(%esp)		// x : 1
+	fabs			// abs(x) : 1
+	fucompp			// < 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 74f422816a..6215496207 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
+   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -161,10 +161,11 @@ ENTRY(__ieee754_powl)
 2:	/* y is a real number.  */
 	fxch			// x : y
 	fldl	MO(one)		// 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
+	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
 	fnstsw
 	fxch			// x : 1.0 : y
 	sahf
@@ -210,9 +211,10 @@ ENTRY(__ieee754_powl)
 	// y == ħinf
 	.align ALIGNARG(4)
 12:	fstp	%st(0)		// pop y
-	fldt	4(%esp)		// x
-	fabs
-	fcompl	MO(one)		// < 1, == 1, or > 1
+	fldl	MO(one)		// 1
+	fldt	4(%esp)		// x : 1
+	fabs			// abs(x) : 1
+	fucompp			// < 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
new file mode 100644
index 0000000000..a426788ef1
--- /dev/null
+++ b/sysdeps/i386/fpu/math_private.h
@@ -0,0 +1,18 @@
+#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 5b617cb4e7..aef0a144e5 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,9 +52,12 @@ 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 */
-	    y = x*x;
-	    if(y==x) return y; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(esx>=0) {			/* x > 0 */
 	    if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
@@ -109,12 +112,9 @@ static char rcsid[] = "$NetBSD: $";
 	}
 	esy = esx&0x7fff;
 	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;
-	    }
+	if(esy==0) {
+	    long double u = x*x;		/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	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 2bd768e448..9bd86a3724 100644
--- a/sysdeps/i386/fpu/s_nexttoward.c
+++ b/sysdeps/i386/fpu/s_nexttoward.c
@@ -27,7 +27,8 @@ static char rcsid[] = "$NetBSD: $";
  */
 
 #include "math.h"
-#include "math_private.h"
+#include <math_private.h>
+#include <float.h>
 
 #ifdef __STDC__
 	double __nexttoward(double x, long double y)
@@ -52,10 +53,12 @@ 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 x2;
+	    double u;
 	    INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
-	    x2 = x*x;
-	    if(x2==x) return x2; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
@@ -85,16 +88,14 @@ static char rcsid[] = "$NetBSD: $";
 	hy = hx&0x7ff00000;
 	if(hy>=0x7ff00000) {
 	  x = x+x;	/* overflow  */
-	  /* Force conversion to double.  */
-	  asm ("" : "=m"(x) : "m"(x));
+	  if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
+	    /* Force conversion to double.  */
+	    asm ("" : "+m"(x));
 	  return x;
 	}
-	if(hy<0x00100000) {		/* underflow */
-	    double x2 = x*x;
-	    if(x2!=x) {		/* raise underflow flag */
-	        INSERT_WORDS(x2,hx,lx);
-		return x2;
-	    }
+	if(hy<0x00100000) {
+	    double u = x*x;			/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	INSERT_WORDS(x,hx,lx);
 	return x;
diff --git a/sysdeps/i386/fpu/s_nexttowardf.c b/sysdeps/i386/fpu/s_nexttowardf.c
index 3fbe53c338..25f70e4f4d 100644
--- a/sysdeps/i386/fpu/s_nexttowardf.c
+++ b/sysdeps/i386/fpu/s_nexttowardf.c
@@ -19,7 +19,8 @@ static char rcsid[] = "$NetBSD: $";
 #endif
 
 #include "math.h"
-#include "math_private.h"
+#include <math_private.h>
+#include <float.h>
 
 #ifdef __STDC__
 	float __nexttowardf(float x, long double y)
@@ -44,10 +45,12 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if(ix==0) {				/* x == 0 */
-	    float x2;
+	    float u;
 	    SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
-	    x2 = x*x;
-	    if(x2==x) return x2; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
@@ -69,16 +72,14 @@ static char rcsid[] = "$NetBSD: $";
 	hy = hx&0x7f800000;
 	if(hy>=0x7f800000) {
 	  x = x+x;	/* overflow  */
-	  /* Force conversion to float.  */
-	  asm ("" : "=m"(x) : "m"(x));
+	  if (FLT_EVAL_METHOD != 0)
+	    /* Force conversion to float.  */
+	    asm ("" : "+m"(x));
 	  return x;
 	}
-	if(hy<0x00800000) {		/* underflow */
-	    float x2 = x*x;
-	    if(x2!=x) {		/* raise underflow flag */
-	        SET_FLOAT_WORD(x2,hx);
-		return x2;
-	    }
+	if(hy<0x00800000) {
+	    float u = x*x;			/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	SET_FLOAT_WORD(x,hx);
 	return x;
diff --git a/sysdeps/i386/i486/bits/atomic.h b/sysdeps/i386/i486/bits/atomic.h
index a27734c37e..c748761758 100644
--- a/sysdeps/i386/i486/bits/atomic.h
+++ b/sysdeps/i386/i486/bits/atomic.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,7 +18,6 @@
    02111-1307 USA.  */
 
 #include <stdint.h>
-#include <tls.h>	/* For tcbhead_t.  */
 
 
 typedef int8_t atomic8_t;
@@ -77,40 +76,6 @@ 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
@@ -120,8 +85,6 @@ 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) \
@@ -137,24 +100,6 @@ 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;						      \
@@ -167,22 +112,6 @@ 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
 
@@ -210,24 +139,21 @@ typedef uintmax_t uatomic_max_t;
      result; })
 
 
-#define __arch_exchange_and_add_body(lock, pfx, mem, value) \
+#define atomic_exchange_and_add(mem, value) \
   ({ __typeof (*mem) __result;						      \
      __typeof (value) __addval = (value);				      \
      if (sizeof (*mem) == 1)						      \
-       __asm __volatile (lock "xaddb %b0, %1"				      \
+       __asm __volatile (LOCK_PREFIX "xaddb %b0, %1"			      \
 			 : "=r" (__result), "=m" (*mem)			      \
-			 : "0" (__addval), "m" (*mem),			      \
-			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
+			 : "0" (__addval), "m" (*mem));			      \
      else if (sizeof (*mem) == 2)					      \
-       __asm __volatile (lock "xaddw %w0, %1"				      \
+       __asm __volatile (LOCK_PREFIX "xaddw %w0, %1"			      \
 			 : "=r" (__result), "=m" (*mem)			      \
-			 : "0" (__addval), "m" (*mem),			      \
-			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
+			 : "0" (__addval), "m" (*mem));			      \
      else if (sizeof (*mem) == 4)					      \
-       __asm __volatile (lock "xaddl %0, %1"				      \
+       __asm __volatile (LOCK_PREFIX "xaddl %0, %1"			      \
 			 : "=r" (__result), "=m" (*mem)			      \
-			 : "0" (__addval), "m" (*mem),			      \
-			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
+			 : "0" (__addval), "m" (*mem));			      \
      else								      \
        {								      \
 	 __typeof (mem) __memp = (mem);					      \
@@ -235,64 +161,41 @@ typedef uintmax_t uatomic_max_t;
 	 __result = *__memp;						      \
 	 do								      \
 	   __tmpval = __result;						      \
-	 while ((__result = pfx##_compare_and_exchange_val_64_acq	      \
+	 while ((__result = __arch_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) \
-  __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)
+  (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); \
+	      }								      \
+	    })
 
 
 #define atomic_add_negative(mem, value) \
@@ -333,42 +236,30 @@ typedef uintmax_t uatomic_max_t;
      __result; })
 
 
-#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(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 atomic_increment_and_test(mem) \
@@ -390,42 +281,30 @@ typedef uintmax_t uatomic_max_t;
      __result; })
 
 
-#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(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 atomic_decrement_and_test(mem) \
@@ -448,22 +327,21 @@ typedef uintmax_t uatomic_max_t;
 
 
 #define atomic_bit_set(mem, bit) \
-  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)
+  (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 ();							      \
+	    })
 
 
 #define atomic_bit_test_set(mem, bit) \
@@ -486,51 +364,3 @@ 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 4fa6adea98..4bd5394bec 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004, 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
@@ -44,9 +44,13 @@
      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:
@@ -380,38 +384,38 @@ END (BP_SYM (memcmp))
 	.section	.rodata
 	ALIGN (2)
 L(table_32bytes) :
-	.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)
+	.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
 
 
 #undef bcmp
diff --git a/sysdeps/i386/ldbl2mpn.c b/sysdeps/i386/ldbl2mpn.c
index bf4e4ff43f..01be777270 100644
--- a/sysdeps/i386/ldbl2mpn.c
+++ b/sysdeps/i386/ldbl2mpn.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 2000, 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
@@ -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] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
+  res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1;
   #define N 1
 #else
   #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
@@ -109,6 +109,13 @@ __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
new file mode 100644
index 0000000000..ed71ae418a
--- /dev/null
+++ b/sysdeps/i386/soft-fp/sfp-machine.h
@@ -0,0 +1,89 @@
+#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 e03a8e926d..2739cb00b3 100644
--- a/sysdeps/i386/sysdep.h
+++ b/sysdeps/i386/sysdep.h
@@ -1,6 +1,5 @@
 /* Assembler macros for i386.
-   Copyright (C) 1991-93,95,96,98,2002,2003,2005,2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1991-93,95,96,98,2002,2003,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
@@ -133,7 +132,15 @@ lose: SYSCALL_PIC_SETUP							      \
     cfi_adjust_cfa_offset (-4);						      \
     addl $_GLOBAL_OFFSET_TABLE+[.-0b], %ebx;
 
-# define SETUP_PIC_REG(reg) \
+# 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) \
   .ifndef __i686.get_pc_thunk.reg;					      \
   .section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits;	      \
   .globl __i686.get_pc_thunk.reg;					      \
@@ -146,6 +153,7 @@ __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 61b4ea99a7..55349690e3 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1995-1997, 2000-2004, 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
@@ -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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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 RTLD_BOOTSTRAP || defined USE___THREAD
+#if defined USE_TLS && (!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 351bcc2f10..13801c848b 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 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2005, 2007 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 0;
+    return 1;
 
   /* 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 1;
+  return 0;
 }
 libm_hidden_def (fesetround)
diff --git a/sysdeps/ia64/ldbl2mpn.c b/sysdeps/ia64/ldbl2mpn.c
new file mode 100644
index 0000000000..641b789cd4
--- /dev/null
+++ b/sysdeps/ia64/ldbl2mpn.c
@@ -0,0 +1 @@
+#include "../i386/ldbl2mpn.c"
diff --git a/sysdeps/ia64/libc-tls.c b/sysdeps/ia64/libc-tls.c
index 9751284008..2c0eeae86f 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
@@ -19,6 +19,8 @@
 
 #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
@@ -30,3 +32,5 @@ __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 d9bd8b479f..1e159f2c0b 100644
--- a/sysdeps/ieee754/dbl-64/e_pow.c
+++ b/sysdeps/ieee754/dbl-64/e_pow.c
@@ -106,20 +106,28 @@ 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 ((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] == 0) {
+      if (qy == 0x7ff00000) {
 	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 (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
+      else if (qx == 0x7ff00000)
 	return y < 0 ? 0.0 : INF.x;
       return NaNQ.x;                              /* y not integer and x<0 */
     }
-    else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
+    else if (qx == 0x7ff00000)
       {
 	if (k < 0)
 	  return y < 0 ? nZERO.x : nINF.x;
@@ -129,14 +137,6 @@ 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 e1568e24c9..600c14621f 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,9 +40,12 @@ 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 */
-	    y = x*x;
-	    if(y==x) return y; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u*u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(hx>hy) {				/* x > y, x -= ulp */
@@ -61,15 +64,12 @@ 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) : "m"(x));
+	    asm ("" : "+m"(x));
 	  return x;	/* overflow  */
 	}
-	if(hy<0x00800000) {		/* underflow */
-	    y = x*x;
-	    if(y!=x) {		/* raise underflow flag */
-	        SET_FLOAT_WORD(y,hx);
-		return y;
-	    }
+	if(hy<0x00800000) {
+	    float u = x*x;			/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	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 d3df668178..7bc869a518 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,9 +47,12 @@ 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 */
-	    y = x*x;
-	    if(y==x) return y; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {			/* x > 0 */
 	    if(hx>hy||((hx==hy)&&(lx>ly))) {	/* x > y, x -= ulp */
@@ -70,12 +73,9 @@ static char rcsid[] = "$NetBSD: $";
 	}
 	hy = hx&0x7fff000000000000LL;
 	if(hy==0x7fff000000000000LL) 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(hy==0) {
+	    long double u = x*x;		/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	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 553e401973..178505c58f 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,10 +53,12 @@ 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 x2;
+	    double u;
 	    INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
-	    x2 = x*x;
-	    if(x2==x) return x2; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if (hy<0||(ix>>20)>(iy>>48)-0x3c00
@@ -87,16 +89,13 @@ static char rcsid[] = "$NetBSD: $";
 	if(hy>=0x7ff00000) {
 	  x = x+x;	/* overflow  */
 	  if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
-	    /* Force conversion to float.  */
-	    asm ("" : "=m"(x) : "m"(x));
+	    /* Force conversion to double.  */
+	    asm ("" : "+m"(x));
 	  return x;
 	}
-	if(hy<0x00100000) {		/* underflow */
-	    double x2 = x*x;
-	    if(x2!=x) {		/* raise underflow flag */
-	        INSERT_WORDS(x2,hx,lx);
-		return x2;
-	    }
+	if(hy<0x00100000) {
+	    double u = x*x;			/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	INSERT_WORDS(x,hx,lx);
 	return x;
diff --git a/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c b/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c
index 8a2d45e2d8..21d1e62dab 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
+/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006, 2007
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -31,19 +31,20 @@ long double
 __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
 {
   union ibm_extended_long_double u;
-  unsigned long hidden2, lzcount;
+  unsigned long 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 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS;
+  u.ieee.exponent2 = 0;
+  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;
@@ -51,7 +52,6 @@ __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,14 +59,62 @@ __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' then round up hi and adjust lo (2nd mantissa)
+	 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)
 	 plus change the sign of the low double to compensate.  */
-      if (hidden2)
+      if ((lo & (1LL << 52)) != 0
+	  && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1))))
 	{
 	  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;
 	}
@@ -85,17 +133,18 @@ __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign)
       if (lzcount > 0)
 	{
 	  lo = lo << lzcount;
-	  u.ieee.exponent2 = u.ieee.exponent2 - lzcount;
+	  exponent2 = exponent2 - lzcount;
 	}
+      if (exponent2 > 0)
+	u.ieee.exponent2 = exponent2;
+      else
+	lo >>= 1 - exponent2;
     }
   else
-    {
-      u.ieee.negative2 = 0;
-      u.ieee.exponent2 = 0;
-    }
+    u.ieee.negative2 = 0;
 
   u.ieee.mantissa3 = lo & 0xffffffffLL;
-  u.ieee.mantissa2 = (lo >> 32) & 0xffffff;
+  u.ieee.mantissa2 = (lo >> 32) & 0xfffff;
   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 2a7b70fabf..b2ad25e31f 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
+   Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006,2007
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -35,21 +35,24 @@ do {									      \
 									      \
       lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3;    \
       hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1;    \
-   /* If the lower double is not a denomal or zero then set the hidden	      \
-      53rd bit.  */							      \
-      if (eldbl.ieee.exponent2 > 0x001)					      \
-	{								      \
-	  lo |= (1ULL << 52);						      \
-	  lo = lo << 7; /* pre-shift lo to match ieee854.  */		      \
-	  /* The lower double is normalized separately from the upper.  We    \
-	     may need to adjust the lower manitissa to reflect this.  */      \
-	  ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2;		      \
-	  if (ediff > 53)						      \
-	    lo = lo >> (ediff-53);					      \
-	}								      \
-  									      \
-      if ((eldbl.ieee.negative != eldbl.ieee.negative2)			      \
-	  && ((eldbl.ieee.exponent2 != 0) && (lo != 0L)))		      \
+      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))			      \
 	{								      \
 	  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 3ca178a3c5..6999abc250 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 Free Software Foundation, Inc.
+   Copyright (C) 1997,1999,2002,2004,2006,2007 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,14 +30,16 @@
    * -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
-   * -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
+   * +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
    */
 
 int
@@ -59,12 +61,23 @@ ___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 {
-	      /* +/- denormal */
-	      retval = FP_SUBNORMAL;
+	      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;
+	      }
 	  }
       } else {
 	  /* +/- zero */
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
index e35ce50829..39d0e6a5e3 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,ily;
+	int64_t hx,hy,ihx,ihy,ilx;
 	u_int64_t lx,ly;
 
 	GET_LDOUBLE_WORDS64(hx,lx,x);
@@ -43,7 +43,6 @@ 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 */
@@ -53,55 +52,67 @@ static char rcsid[] = "$NetBSD: $";
 	if(x==y)
 	    return y;		/* x=y, return y */
 	if(ihx == 0 && ilx == 0) {			/* x == 0 */
-	    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;
+	    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;
 	}
-	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++;
+	
+	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;
 	    }
-	} 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)
+		  || (hx < 0 && (int64_t) lx > 1)) {
+		u = u * u;
+		math_force_eval (u);		/* raise underflow flag */
+	      }
+	      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;
+	} 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;
+	    }
+	    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;
 	    }
+	    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 3335100592..e2f6521f57 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,10 +55,12 @@ 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 x2;
+	    double u;
 	    INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
-	    x2 = x*x;
-	    if(x2==x) return x2; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if (hy<0||(ix>>20)>(iy>>52)
@@ -89,16 +91,13 @@ static char rcsid[] = "$NetBSD: $";
 	if(hy>=0x7ff00000) {
 	  x = x+x;	/* overflow  */
 	  if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
-	    /* Force conversion to float.  */
-	    asm ("" : "=m"(x) : "m"(x));
+	    /* Force conversion to double.  */
+	    asm ("" : "+m"(x));
 	  return x;
 	}
-	if(hy<0x00100000) {		/* underflow */
-	    double x2 = x*x;
-	    if(x2!=x) {		/* raise underflow flag */
-	        INSERT_WORDS(x2,hx,lx);
-		return x2;
-	    }
+	if(hy<0x00100000) {
+	    double u = x*x;			/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	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 a9373ff822..cf655fad16 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
@@ -19,8 +19,9 @@ 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)
@@ -46,10 +47,12 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if(ix==0) {				/* x == 0 */
-	    float x2;
+	    float u;
 	    SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/
-	    x2 = x*x;
-	    if(x2==x) return x2; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(hy<0||(ix>>23)>(iy>>52)-0x380
@@ -69,13 +72,16 @@ static char rcsid[] = "$NetBSD: $";
 	    }
 	}
 	hy = hx&0x7f800000;
-	if(hy>=0x7f800000) return x+x;	/* overflow  */
+	if(hy>=0x7f800000) {
+	  x = x+x;	/* overflow  */
+	  if (FLT_EVAL_METHOD != 0)
+	    /* Force conversion to float.  */
+	    asm ("" : "+m"(x));
+	  return x;
+	}
 	if(hy<0x00800000) {		/* underflow */
-	    float x2 = x*x;
-	    if(x2!=x) {		/* raise underflow flag */
-	        SET_FLOAT_WORD(x2,hx);
-		return x2;
-	    }
+	    float u = x*x;
+	    math_force_eval (u);	/* raise underflow flag */
 	}
 	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 1798261b28..ed0877d6dd 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,9 +48,12 @@ 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 */
-	    y = x*x;
-	    if(y==x) return y; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(esx<0x8000) {			/* x > 0 */
 	    if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
@@ -85,13 +88,10 @@ static char rcsid[] = "$NetBSD: $";
 	    }
 	}
 	esy = esx&0x7fff;
-	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;
-	    }
+	if(esy==0x7fff) return x+x;		/* overflow  */
+	if(esy==0) {
+	    long double u = x*x;		/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	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 7945cb5cb1..e30438482c 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,10 +50,12 @@ 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 x2;
+	    double u;
 	    INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
-	    x2 = x*x;
-	    if(x2==x) return x2; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
@@ -84,16 +86,13 @@ static char rcsid[] = "$NetBSD: $";
 	if(hy>=0x7ff00000) {
 	  x = x+x;	/* overflow  */
 	  if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
-	    /* Force conversion to float.  */
-	    asm ("" : "=m"(x) : "m"(x));
+	    /* Force conversion to double.  */
+	    asm ("" : "+m"(x));
 	  return x;
 	}
-	if(hy<0x00100000) {		/* underflow */
-	    double x2 = x*x;
-	    if(x2!=x) {		/* raise underflow flag */
-	        INSERT_WORDS(x2,hx,lx);
-		return x2;
-	    }
+	if(hy<0x00100000) {
+	    double u = x*x;			/* underflow */
+	    math_force_eval (u);		/* raise underflow flag */
 	}
 	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 a1c38b5d4c..6357975ffc 100644
--- a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
+++ b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
@@ -18,7 +18,8 @@ static char rcsid[] = "$NetBSD: $";
 #endif
 
 #include "math.h"
-#include "math_private.h"
+#include <math_private.h>
+#include <float.h>
 
 #ifdef __STDC__
 	float __nexttowardf(float x, long double y)
@@ -41,10 +42,12 @@ static char rcsid[] = "$NetBSD: $";
 	   return x+y;
 	if((long double) x==y) return y;	/* x=y, return y */
 	if(ix==0) {				/* x == 0 */
-	    float x2;
+	    float u;
 	    SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
-	    x2 = x*x;
-	    if(x2==x) return x2; else return x;	/* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
@@ -64,13 +67,16 @@ static char rcsid[] = "$NetBSD: $";
 	    }
 	}
 	hy = hx&0x7f800000;
-	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;
-	    }
+	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 */
 	}
 	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 d52526f719..68027f26fa 100644
--- a/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
+++ b/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
@@ -20,7 +20,10 @@
  *   Special cases:
  */
 
+#include <math.h>
+#include <math_private.h>
 #include <math_ldbl_opt.h>
+#include <float.h>
 
 float __nldbl_nexttowardf(float x, double y);
 
@@ -39,10 +42,12 @@ 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 x2;
+	    float u;
 	    SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/
-	    x2 = x*x;
-	    if(x2==x) return x2; else return x; /* raise underflow flag */
+	    u = math_opt_barrier (x);
+	    u = u * u;
+	    math_force_eval (u);		/* raise underflow flag */
+	    return x;
 	}
 	if(hx>=0) {				/* x > 0 */
 	    if(hy<0||(ix>>23)>(iy>>20)-0x380
@@ -60,13 +65,16 @@ float __nldbl_nexttowardf(float x, double y)
 		hx += 1;
 	}
 	hy = hx&0x7f800000;
-	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;
-	    }
+	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 */
 	}
 	SET_FLOAT_WORD(x,hx);
 	return x;
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index 3288f186e5..fa7da60204 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,2006
+/* Copyright (C) 1994,1995,1996,1997,1999,2001,2002,2004,2005
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -532,9 +532,11 @@ __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 4628eee2c3..ca687b8bdf 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002 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,24 +28,20 @@
 int
 __futimes (int fd, const struct timeval tvp[2])
 {
-  union tv
-  {
-    struct timeval tv;
-    time_value_t tvt;
-  };
-  const union tv *u = (const union tv *) tvp;
-  union tv nulltv[2];
+  struct timeval timevals[2];
   error_t err;
 
   if (tvp == NULL)
     {
       /* Setting the number of microseconds to `-1' tells the
          underlying filesystems to use the current time.  */
-      nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
-      u = nulltv;
+      timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
+      tvp = timevals;
     }
 
-  err = HURD_DPORT_USE (fd, __file_utimes (port, u[0].tvt, u[1].tvt));
+  err = HURD_DPORT_USE (fd, __file_utimes (port,
+					   *(time_value_t *) &tvp[0],
+					   *(time_value_t *) &tvp[1]));
   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 972cac57a1..223a47d2f2 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004 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,6 +25,9 @@
 /* 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 bf5610c467..cf89d8862f 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002 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,13 +28,7 @@
 int
 __lutimes (const char *file, const struct timeval tvp[2])
 {
-  union tv
-  {
-    struct timeval tv;
-    time_value_t tvt;
-  };
-  const union tv *u = (const union tv *) tvp;
-  union tv nulltv[2];
+  struct timeval timevals[2];
   error_t err;
   file_t port;
 
@@ -42,14 +36,15 @@ __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.  */
-      nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
-      u = nulltv;
+      timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
+      tvp = timevals;
     }
 
   port = __file_name_lookup (file, O_NOLINK, 0);
   if (port == MACH_PORT_NULL)
     return -1;
-  err = __file_utimes (port, u[0].tvt, u[1].tvt);
+  err = __file_utimes (port,
+		       *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
   __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 fdc1427feb..74f3a342f4 100644
--- a/sysdeps/mach/hurd/utimes.c
+++ b/sysdeps/mach/hurd/utimes.c
@@ -1,5 +1,4 @@
-/* Copyright (C) 1991-1995,1997,1999,2000,2006
-	Free Software Foundation, Inc.
+/* Copyright (C) 1991-1995, 97, 99, 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
@@ -29,13 +28,7 @@ __utimes (file, tvp)
      const char *file;
      const struct timeval tvp[2];
 {
-  union tv
-  {
-    struct timeval tv;
-    time_value_t tvt;
-  };
-  const union tv *u = (const union tv *) tvp;
-  union tv nulltv[2];
+  struct timeval timevals[2];
   error_t err;
   file_t port;
 
@@ -43,17 +36,19 @@ __utimes (file, tvp)
     {
       /* Setting the number of microseconds to `-1' tells the
          underlying filesystems to use the current time.  */
-      nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
-      u = nulltv;
+      timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
+      tvp = timevals;
     }
 
   port = __file_name_lookup (file, 0, 0);
   if (port == MACH_PORT_NULL)
     return -1;
-  err = __file_utimes (port, u[0].tvt, u[1].tvt);
+  err = __file_utimes (port,
+		       *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
   __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 76a09d455d..333870cdde 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 Free Software Foundation, Inc.
+   Copyright (C) 1990,1991,1995-2001,2005,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
@@ -128,10 +128,6 @@ 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)
     {
@@ -162,6 +158,10 @@ 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 b4966852a7..a7e1459c9c 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] == 16)
+      else if (addr[0] == 10 || (addr[0] == 172 && (addr[1] & 0xf0) == 16)
 	       || (addr[0] == 192 && addr[1] == 168))
 	scope = 5;
       else
@@ -1218,6 +1218,10 @@ 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 }
@@ -2085,12 +2089,10 @@ getaddrinfo (const char *name, const char *service,
 
 		  if (q->ai_family == PF_INET6 && in6ai != NULL)
 		    {
-		      /* See whether the source address is the list of
-			 deprecated or temporary addresses.  */
+		      /* See whether the address is the list of deprecated
+			 or temporary addresses.  */
 		      struct in6addrinfo tmp;
-		      struct sockaddr_in6 *sin6p
-			= (struct sockaddr_in6 *) &results[i].source_addr;
-		      memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
+		      memcpy (tmp.addr, q->ai_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 04478309d9..aed899e882 100644
--- a/sysdeps/powerpc/fpu/bits/mathinline.h
+++ b/sysdeps/powerpc/fpu/bits/mathinline.h
@@ -121,4 +121,62 @@ __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
deleted file mode 100644
index 90021c6d3c..0000000000
--- a/sysdeps/powerpc/fpu/math_private.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* 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 fc460993b1..4120a02382 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1995-2003, 2004, 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
@@ -564,12 +564,13 @@ __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.  */			      \
@@ -608,6 +609,7 @@ __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 a50ffdd1c2..496fa71ecc 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 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
@@ -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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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 RTLD_BOOTSTRAP || USE___THREAD) \
+#if defined USE_TLS && (!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
+#endif /* USE_TLS etc. */
 
     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 88cfe71e0b..8fc624ebd9 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 NO_HIDDEN
+    && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE && !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 89a69e1a23..cec271bb3a 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -1,6 +1,7 @@
 /* Machine-dependent ELF dynamic relocation inline functions.
    PowerPC64 version.
-   Copyright 1995-2005, 2006 Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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
@@ -259,7 +260,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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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)	      \
@@ -494,7 +495,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-#if !defined RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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,
@@ -561,7 +562,7 @@ elf_machine_rela (struct link_map *map,
 #endif
       return;
 
-#if !defined RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
     case R_PPC64_DTPMOD64:
 # ifdef RTLD_BOOTSTRAP
       /* During startup the dynamic linker is always index 1.  */
@@ -644,7 +645,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
+#endif /* USE_TLS etc. */
 
 #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 766d565a9c..f177f436e9 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 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
@@ -20,9 +20,11 @@
 #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.  */
 
@@ -31,3 +33,5 @@ __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 64bf3423b6..8bbf858fbf 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, 2006
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    Contributed by Carl Pederson & Martin Schwidefsky.
    This file is part of the GNU C Library.
@@ -209,11 +209,17 @@ _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.  */
-#define elf_machine_type_class(type) \
+#ifdef USE_TLS
+# 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
@@ -309,7 +315,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 	  *reloc_addr = value + reloc->r_addend;
 	  break;
 
-#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+#if defined USE_TLS && (!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 fa893befdf..5026a2edad 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-2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
    This file is part of the GNU C Library.
 
@@ -192,11 +192,17 @@ _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.  */
-#define elf_machine_type_class(type) \
+#ifdef USE_TLS
+# 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
@@ -288,7 +294,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
 	  *reloc_addr = value + reloc->r_addend;
 	  break;
 
-#if (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+#if defined USE_TLS && (!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 78f70e3880..e73c6d79c3 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, 2006
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
    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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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 19aac6a7fe..02dabaabb4 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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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 RTLD_BOOTSTRAP || USE___THREAD) \
+#if defined USE_TLS && (!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 3eee672912..314a784dbc 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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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 RTLD_BOOTSTRAP || USE___THREAD) \
+#if defined USE_TLS && (!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 137b44c2b8..7c015b1d62 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -126,9 +126,6 @@ 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 84717c3d96..cca0871ac0 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,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2000, 2001, 2002 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,9 +101,7 @@ 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 13ccd7acb4..46161a806a 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 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006, 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
@@ -71,17 +71,38 @@ 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)
-    return -1;
+    goto out_fail;
 
   *seen_ipv4 = false;
   *seen_ipv6 = false;
 
   bool done = false;
-  char buf[4096];
-  struct iovec iov = { buf, sizeof (buf) };
   struct in6ailist
   {
     struct in6addrinfo info;
@@ -101,10 +122,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)
-	return -1;
+	goto out_fail;
 
       if (msg.msg_flags & MSG_TRUNC)
-	return -1;
+	goto out_fail;
 
       struct nlmsghdr *nlmh;
       for (nlmh = (struct nlmsghdr *) buf;
@@ -186,7 +207,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
     {
       *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
       if (*in6ai == NULL)
-	return -1;
+	goto out_fail;
 
       *in6ailen = in6ailistlen;
 
@@ -198,7 +219,14 @@ 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 f73a4b5195..54524ec120 100644
--- a/sysdeps/unix/sysv/linux/i386/clone.S
+++ b/sysdeps/unix/sysv/linux/i386/clone.S
@@ -120,9 +120,6 @@ 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
@@ -155,7 +152,6 @@ 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 f69baf943b..b7a0a4efd4 100644
--- a/sysdeps/unix/sysv/linux/i386/getgroups.c
+++ b/sysdeps/unix/sysv/linux/i386/getgroups.c
@@ -52,6 +52,8 @@ __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)
 	{
@@ -67,9 +69,6 @@ __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 b5c1b98573..299574dac4 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-2005,2006 Free Software Foundation, Inc.
+   Copyright (C) 1991,1995-2000,2002-2004,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
@@ -46,10 +46,18 @@ int __libc_missing_rt_sigs;
 
 /* Using the hidden attribute here does not change the code but it
    helps to avoid warnings.  */
-#ifdef __NR_rt_sigaction
+#if defined HAVE_HIDDEN && defined HAVE_VISIBILITY_ATTRIBUTE \
+    && !defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
+# ifdef __NR_rt_sigaction
 extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
-#endif
+# 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
 
 
 /* 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 82495de03e..02e6935538 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 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 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
@@ -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;
-  bool use_malloc = false;
 
-  if (__netlink_sendreq (h, type) < 0)
-    return -1;
+#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;
 
-  size_t this_buf_size = buf_size;
-  if (__libc_use_alloca (this_buf_size))
-    buf = alloca (this_buf_size);
+  if (__libc_use_alloca (buf_size))
+    buf = alloca (buf_size);
   else
     {
-      buf = malloc (this_buf_size);
+      buf = malloc (buf_size);
       if (buf != NULL)
 	use_malloc = true;
       else
 	goto out_fail;
     }
 
-  struct iovec iov = { buf, this_buf_size };
+  struct iovec iov = { buf, buf_size };
 
-  if (h->nlm_list != NULL)
-    new_nlm_list = &h->end_ptr->next;
-  else
-    new_nlm_list = &h->nlm_list;
+  if (__netlink_sendreq (h, type) < 0)
+    goto out_fail;
 
   while (! done)
     {
@@ -171,48 +171,7 @@ __netlink_request (struct netlink_handle *h, int type)
 	continue;
 
       if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
-	{
-	  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;
-	}
+	goto out_fail;
 
       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 28c1cb691f..73317ecafd 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, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -156,8 +156,6 @@ __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
new file mode 100644
index 0000000000..880b17ef31
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/posix_madvise.c
@@ -0,0 +1,38 @@
+/* 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
deleted file mode 100644
index 189179394b..0000000000
--- a/sysdeps/unix/sysv/linux/sh/bits/shm.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* 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
new file mode 100644
index 0000000000..6fdc44ff89
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/sys/io.h
@@ -0,0 +1,48 @@
+/* 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 d8901f7d53..68f173a04d 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, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 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
@@ -22,14 +22,6 @@
 #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
   {
@@ -113,16 +105,6 @@ 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 5776673733..e16110480f 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -10,8 +10,7 @@ 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
-epoll_pwait	EXTRA	epoll_pwait	Ci:ipiipi	epoll_pwait
-fdatasync	-	fdatasync	i:i	fdatasync
+fdatasync	-	fdatasync	Ci: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
@@ -32,7 +31,6 @@ 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 bdad5063df..0f20367236 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),csu)
+ifeq ($(subdir),stdlib)
 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 db42f209c9..8a12b09035 100644
--- a/sysdeps/unix/sysv/linux/x86_64/clone.S
+++ b/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -89,9 +89,6 @@ 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
@@ -116,7 +113,6 @@ 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 ab10123858..d6f4558cef 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 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
@@ -33,14 +33,17 @@
    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.
@@ -92,95 +95,18 @@ 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.
-
-   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:"
+   appropriate GDB maintainer.  */
 
 #define RESTORE(name, syscall) RESTORE2 (name, syscall)
 # define RESTORE2(name, syscall) \
-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"							\
+asm						\
+  (						\
+   ".align 16\n"				\
+   CFI_STARTPROC "\n"				\
+   "__" #name ":\n"				\
+   "	movq $" #syscall ", %rax\n"		\
+   "	syscall\n"				\
+   CFI_ENDPROC "\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 af3e0e544b..b3cfe9aa4c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
+++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.sym
@@ -18,8 +18,6 @@ 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)
@@ -30,7 +28,6 @@ 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 65d6b02008..133a68d192 100644
--- a/sysdeps/x86_64/bits/atomic.h
+++ b/sysdeps/x86_64/bits/atomic.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -18,7 +18,6 @@
    02111-1307 USA.  */
 
 #include <stdint.h>
-#include <tls.h>	/* For tcbhead_t.  */
 
 
 typedef int8_t atomic8_t;
@@ -81,54 +80,8 @@ typedef uintmax_t uatomic_max_t;
   ({ __typeof (*mem) ret;						      \
      __asm __volatile (LOCK_PREFIX "cmpxchgq %q2, %1"			      \
 		       : "=a" (ret), "=m" (*mem)			      \
-		       : "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)));	      \
+		       : "r" ((long) (newval)), "m" (*mem),		      \
+			 "0" ((long) (oldval)));			      \
      ret; })
 
 
@@ -154,76 +107,49 @@ typedef uintmax_t uatomic_max_t;
      result; })
 
 
-#define __arch_exchange_and_add_body(lock, mem, value)			      \
+#define atomic_exchange_and_add(mem, value) \
   ({ __typeof (*mem) result;						      \
      if (sizeof (*mem) == 1)						      \
-       __asm __volatile (lock "xaddb %b0, %1"				      \
+       __asm __volatile (LOCK_PREFIX "xaddb %b0, %1"			      \
 			 : "=r" (result), "=m" (*mem)			      \
-			 : "0" (value), "m" (*mem),			      \
-			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
+			 : "0" (value), "m" (*mem));			      \
      else if (sizeof (*mem) == 2)					      \
-       __asm __volatile (lock "xaddw %w0, %1"				      \
+       __asm __volatile (LOCK_PREFIX "xaddw %w0, %1"			      \
 			 : "=r" (result), "=m" (*mem)			      \
-			 : "0" (value), "m" (*mem),			      \
-			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
+			 : "0" (value), "m" (*mem));			      \
      else if (sizeof (*mem) == 4)					      \
-       __asm __volatile (lock "xaddl %0, %1"				      \
+       __asm __volatile (LOCK_PREFIX "xaddl %0, %1"			      \
 			 : "=r" (result), "=m" (*mem)			      \
-			 : "0" (value), "m" (*mem),			      \
-			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
+			 : "0" (value), "m" (*mem));			      \
      else								      \
-       __asm __volatile (lock "xaddq %q0, %1"				      \
+       __asm __volatile (LOCK_PREFIX "xaddq %q0, %1"			      \
 			 : "=r" (result), "=m" (*mem)			      \
-			 : "0" ((long) (value)), "m" (*mem),		      \
-			   "i" (offsetof (tcbhead_t, multiple_threads)));     \
+			 : "0" ((long) (value)), "m" (*mem));		      \
      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) \
-  __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)
+  (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));	      \
+	    })
 
 
 #define atomic_add_negative(mem, value) \
@@ -268,37 +194,24 @@ typedef uintmax_t uatomic_max_t;
      __result; })
 
 
-#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(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 atomic_increment_and_test(mem) \
@@ -322,37 +235,24 @@ typedef uintmax_t uatomic_max_t;
      __result; })
 
 
-#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(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 atomic_decrement_and_test(mem) \
@@ -377,28 +277,27 @@ typedef uintmax_t uatomic_max_t;
 
 
 #define atomic_bit_set(mem, 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)
+  (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)));	      \
+	    })
 
 
 #define atomic_bit_test_set(mem, bit) \
@@ -423,56 +322,3 @@ 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 e1c861c75f..ec2b17889d 100644
--- a/sysdeps/x86_64/bits/byteswap.h
+++ b/sysdeps/x86_64/bits/byteswap.h
@@ -1,5 +1,6 @@
 /* Macros to swap the order of bytes in integer values.
-   Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2000, 2002, 2003, 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
@@ -59,7 +60,9 @@
 # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__	      \
 			  || defined __pentiumpro__ || defined __pentium4__   \
 			  || defined __k8__ || defined __athlon__	      \
-			  || defined __k6__)
+			  || defined __k6__ || defined __nocona__	      \
+			  || defined __core2__ || defined __geode__	      \
+			  || defined __amdfam10__)
 /* 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 31a7013d50..73e271775a 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-2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 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 RTLD_BOOTSTRAP || USE___THREAD
+#if defined USE_TLS && (!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;
 
-#ifndef RESOLVE_CONFLICT_FIND_MAP
+#if defined USE_TLS && !defined 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
+#endif	/* use TLS */
 
 #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 b4343bef45..633234b744 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)
-	andb	$1,%ah
+	testb	$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,7 +59,8 @@ ENTRY(__ieee754_log10l)
 	fyl2x			// log10(x)
 	ret
 
-3:	jp	4b		// in case x is ħInf
+3:	testb	$4, %ah
+	jnz	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 7a89b94d9f..f04d30a05a 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
-	andb	$1,%ah
+	testb	$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,7 +56,8 @@ ENTRY(__ieee754_log2l)
 	fyl2x			// log(x)
 	ret
 
-3:	jp	4b		// in case x is ħInf
+3:	testb	$4, %ah
+	jnz	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 a0bed663c8..2ba91eedfd 100644
--- a/sysdeps/x86_64/fpu/e_logl.S
+++ b/sysdeps/x86_64/fpu/e_logl.S
@@ -38,8 +38,12 @@ limit:	.double 0.29
 ENTRY(__ieee754_logl)
 	fldln2			// log(2)
 	fldt	8(%rsp)		// x : log(2)
+	fxam
+	fnstsw
 	fld	%st		// x : x : log(2)
-	fsubl	MO(one)		// x-1 : x : log(2)
+	testb	$1, %ah
+	jnz	3f		// in case x is NaN or +-Inf
+4:	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)
@@ -53,4 +57,10 @@ 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 85f4deb3c7..4959bea7ac 100644
--- a/sysdeps/x86_64/fpu/e_powl.S
+++ b/sysdeps/x86_64/fpu/e_powl.S
@@ -1,5 +1,6 @@
 /* ix87 specific implementation of pow function.
-   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -146,10 +147,11 @@ ENTRY(__ieee754_powl)
 2:	/* y is a real number.  */
 	fxch			// x : y
 	fldl	MO(one)		// 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
+	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
 	fnstsw
 	fxch			// x : 1.0 : y
 	test	$4500,%eax
@@ -190,9 +192,10 @@ ENTRY(__ieee754_powl)
 	// y == ħinf
 	.align ALIGNARG(4)
 12:	fstp	%st(0)		// pop y
-	fldt	8(%rsp)		// x
-	fabs
-	fcompl	MO(one)		// < 1, == 1, or > 1
+	fldl	MO(one)		// 1
+	fldt	8(%rsp)		// x : 1
+	fabs			// abs(x) : 1
+	fucompp			// < 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
new file mode 100644
index 0000000000..4febcbb5ec
--- /dev/null
+++ b/sysdeps/x86_64/fpu/math_private.h
@@ -0,0 +1,21 @@
+#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 f3d9b0cbb4..f1ebcf8bf1 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 2002.
 
@@ -31,8 +31,6 @@
 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
@@ -44,7 +42,6 @@ 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 0fbe1d4c96..f5dc5f78ad 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, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 2002.
 
@@ -38,7 +38,6 @@ 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 7fbd0e5aaa..ac2bd22a4f 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
-	andb	$1,%ah
+	testb	$1, %ah
 	jnz	3f		// in case x is NaN or ħInf
 4:
 	fabs
@@ -62,7 +62,8 @@ ENTRY(__log1pl)
 2:	fyl2xp1
 	ret
 
-3:	jp	4b		// in case x is ħInf
+3:	testb	$4, %ah
+	jnz	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
new file mode 100644
index 0000000000..641b789cd4
--- /dev/null
+++ b/sysdeps/x86_64/ldbl2mpn.c
@@ -0,0 +1 @@
+#include "../i386/ldbl2mpn.c"
diff --git a/sysdeps/x86_64/soft-fp/sfp-machine.h b/sysdeps/x86_64/soft-fp/sfp-machine.h
new file mode 100644
index 0000000000..77df02380c
--- /dev/null
+++ b/sysdeps/x86_64/soft-fp/sfp-machine.h
@@ -0,0 +1,51 @@
+#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
+