summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog52
-rw-r--r--NEWS25
-rw-r--r--nptl/DESIGN-sem.txt46
-rw-r--r--nptl/Makefile5
-rw-r--r--nptl/sem_getvalue.c26
-rw-r--r--nptl/sem_init.c35
-rw-r--r--nptl/sem_open.c9
-rw-r--r--nptl/sem_post.c67
-rw-r--r--nptl/sem_timedwait.c96
-rw-r--r--nptl/sem_trywait.c50
-rw-r--r--nptl/sem_wait.c101
-rw-r--r--nptl/sem_waitcommon.c467
-rw-r--r--nptl/structsem.sym12
-rw-r--r--nptl/tst-sem11.c9
-rw-r--r--nptl/tst-sem13.c18
-rw-r--r--sysdeps/nptl/internaltypes.h24
-rw-r--r--sysdeps/unix/sysv/linux/alpha/sem_post.c5
-rw-r--r--sysdeps/unix/sysv/linux/i386/i486/sem_post.S150
-rw-r--r--sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S327
-rw-r--r--sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S67
-rw-r--r--sysdeps/unix/sysv/linux/i386/i486/sem_wait.S343
-rw-r--r--sysdeps/unix/sysv/linux/i386/i586/sem_post.S19
-rw-r--r--sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S19
-rw-r--r--sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S19
-rw-r--r--sysdeps/unix/sysv/linux/i386/i586/sem_wait.S19
-rw-r--r--sysdeps/unix/sysv/linux/i386/i686/sem_post.S19
-rw-r--r--sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S19
-rw-r--r--sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S19
-rw-r--r--sysdeps/unix/sysv/linux/i386/i686/sem_wait.S19
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sem_post.c71
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sem_post.S75
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S380
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sem_trywait.S47
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sem_wait.S176
34 files changed, 732 insertions, 2103 deletions
diff --git a/ChangeLog b/ChangeLog
index b343f7e344..030491a270 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2015-01-21  Torvald Riegel  <triegel@redhat.com>
+	    Carlos O'Donell  <carlos@redhat.com>
+
+	[BZ #12674]
+	* nptl/sem_waitcommon.c: New file.
+	* nptl/sem_wait.c: Include sem_waitcommon.c.
+	(__sem_wait_cleanup, do_futex_wait): Remove.
+	(__new_sem_wait): Adapt.
+	(__new_sem_trywait): New function.
+	(__old_sem_trywait): Moved here from nptl/sem_trywait.c.
+	* nptl/sem_timedwait.c: Include sem_waitcommon.c.
+	(__sem_wait_cleanup, do_futex_timed_wait): Remove.
+	(sem_timedwait): Adapt.
+	* nptl/sem_post.c (__new_sem_post): Adapt.
+	(futex_wake): New function.
+	(__old_sem_post): Add release MO fence.
+	* nptl/sem_open.c (sem_open): Adapt.
+	* nptl/sem_init.c (__new_sem_init): Adapt.
+	(futex_private_if_supported): New function.
+	* nptl/sem_getvalue.c (__new_sem_getvalue): Adapt.
+	(__old_sem_getvalue): Add using previous code.
+	* sysdeps/nptl/internaltypes.h: Adapt.
+	* nptl/tst-sem13.c (do_test): Adapt.
+	* nptl/tst-sem11.c (main): Adapt.
+	* nptl/sem_trywait.c: Remove.
+	* nptl/DESIGN-sem.txt: Remove.
+	* nptl/Makefile (libpthread-routines): Remove sem_trywait.
+	(gen-as-const-headers): Remove structsem.sym.
+	* nptl/structsem.sym: Remove.
+	* sysdeps/unix/sysv/linux/alpha/sem_post.c: Remove.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i586/sem_post.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i586/sem_wait.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i686/sem_post.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S: Remove.
+	* sysdeps/unix/sysv/linux/i386/i686/sem_wait.S: Remove.
+	* sysdeps/unix/sysv/linux/powerpc/sem_post.c: Remove.
+	* sysdeps/unix/sysv/linux/sh/sem_post.S: Remove.
+	* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Remove.
+	* sysdeps/unix/sysv/linux/sh/sem_trywait.S: Remove.
+	* sysdeps/unix/sysv/linux/sh/sem_wait.S: Remove.
+	* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Remove.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Remove.
+	* sysdeps/unix/sysv/linux/x86_64/sem_trywait.S: Remove.
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Remove.
+
 2015-01-20  Carlos O'Donell  <carlos@redhat.com>
 
 	* INSTALL: Regenerated.
diff --git a/NEWS b/NEWS
index 9086b7ed17..db1c28261e 100644
--- a/NEWS
+++ b/NEWS
@@ -9,15 +9,22 @@ Version 2.21
 
 * The following bugs are resolved with this release:
 
-  6652, 10672, 12847, 12926, 13862, 14132, 14138, 14171, 14498, 15215,
-  15884, 16009, 16191, 16469, 16617, 16619, 16657, 16740, 16857, 17192,
-  17266, 17273, 17344, 17363, 17370, 17371, 17411, 17460, 17475, 17485,
-  17501, 17506, 17508, 17522, 17555, 17570, 17571, 17572, 17573, 17574,
-  17582, 17583, 17584, 17585, 17589, 17594, 17601, 17608, 17616, 17625,
-  17630, 17633, 17634, 17635, 17647, 17653, 17657, 17658, 17664, 17665,
-  17668, 17682, 17717, 17719, 17722, 17723, 17724, 17725, 17732, 17733,
-  17744, 17745, 17746, 17747, 17748, 17775, 17777, 17780, 17781, 17782,
-  17791, 17793, 17796, 17797, 17803, 17806, 17834, 17844, 17848
+  6652, 10672, 12674, 12847, 12926, 13862, 14132, 14138, 14171, 14498,
+  15215, 15884, 16009, 16191, 16469, 16617, 16619, 16657, 16740, 16857,
+  17192, 17266, 17273, 17344, 17363, 17370, 17371, 17411, 17460, 17475,
+  17485, 17501, 17506, 17508, 17522, 17555, 17570, 17571, 17572, 17573,
+  17574, 17582, 17583, 17584, 17585, 17589, 17594, 17601, 17608, 17616,
+  17625, 17630, 17633, 17634, 17635, 17647, 17653, 17657, 17658, 17664,
+  17665, 17668, 17682, 17717, 17719, 17722, 17723, 17724, 17725, 17732,
+  17733, 17744, 17745, 17746, 17747, 17748, 17775, 17777, 17780, 17781,
+  17782, 17791, 17793, 17796, 17797, 17803, 17806, 17834, 17844, 17848
+
+* A new semaphore algorithm has been implemented in generic C code for all
+  machines. Previous custom assembly implementations of semaphore were
+  difficult to reason about or ensure that they were safe. The new version
+  of semaphore supports machines with 64-bit or 32-bit atomic operations.
+  The new semaphore algorithm is used by sem_init, sem_open, sem_post,
+  sem_wait, sem_timedwait, sem_trywait, and sem_getvalue.
 
 * Port to Altera Nios II has been contributed by Mentor Graphics.
 
diff --git a/nptl/DESIGN-sem.txt b/nptl/DESIGN-sem.txt
deleted file mode 100644
index 17eb0c11c8..0000000000
--- a/nptl/DESIGN-sem.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-Semaphores pseudocode
-==============================
-
-       int sem_wait(sem_t * sem);
-       int sem_trywait(sem_t * sem);
-       int sem_post(sem_t * sem);
-       int sem_getvalue(sem_t * sem, int * sval);
-
-struct sem_t {
-
-   unsigned int count;
-         - current semaphore count, also used as a futex
-}
-
-sem_wait(sem_t *sem)
-{
-  for (;;) {
-
-    if (atomic_decrement_if_positive(sem->count))
-      break;
-
-    futex_wait(&sem->count, 0)
-  }
-}
-
-sem_post(sem_t *sem)
-{
-  n = atomic_increment(sem->count);
-  // Pass the new value of sem->count
-  futex_wake(&sem->count, n + 1);
-}
-
-sem_trywait(sem_t *sem)
-{
-  if (atomic_decrement_if_positive(sem->count)) {
-    return 0;
-  } else {
-    return EAGAIN;
-  }
-}
-
-sem_getvalue(sem_t *sem, int *sval)
-{
-  *sval = sem->count;
-  read_barrier();
-}
diff --git a/nptl/Makefile b/nptl/Makefile
index ce2d0e4ddd..43d85103f8 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -100,7 +100,7 @@ libpthread-routines = nptl-init vars events version \
 		      sem_init sem_destroy \
 		      sem_open sem_close sem_unlink \
 		      sem_getvalue \
-		      sem_wait sem_trywait sem_timedwait sem_post \
+		      sem_wait sem_timedwait sem_post \
 		      cleanup cleanup_defer cleanup_compat \
 		      cleanup_defer_compat unwind \
 		      pt-longjmp pt-cleanup\
@@ -283,8 +283,7 @@ tests-nolibpthread = tst-unload
 gen-as-const-headers = pthread-errnos.sym \
 		       lowlevelcond.sym lowlevelrwlock.sym \
 		       lowlevelbarrier.sym unwindbuf.sym \
-		       lowlevelrobustlock.sym pthread-pi-defines.sym \
-		       structsem.sym
+		       lowlevelrobustlock.sym pthread-pi-defines.sym
 
 
 LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
diff --git a/nptl/sem_getvalue.c b/nptl/sem_getvalue.c
index c3c91e1f33..1432cc795e 100644
--- a/nptl/sem_getvalue.c
+++ b/nptl/sem_getvalue.c
@@ -19,23 +19,37 @@
 #include <semaphore.h>
 #include <shlib-compat.h>
 #include "semaphoreP.h"
+#include <atomic.h>
 
 
 int
-__new_sem_getvalue (sem, sval)
-     sem_t *sem;
-     int *sval;
+__new_sem_getvalue (sem_t *sem, int *sval)
 {
   struct new_sem *isem = (struct new_sem *) sem;
 
   /* XXX Check for valid SEM parameter.  */
-
-  *sval = isem->value;
+  /* FIXME This uses relaxed MO, even though POSIX specifies that this function
+     should be linearizable.  However, its debatable whether linearizability
+     is the right requirement.  We need to follow up with POSIX and, if
+     necessary, use a stronger MO here and elsewhere (e.g., potentially
+     release MO in all places where we consume a token).  */
+
+#if __HAVE_64B_ATOMICS
+  *sval = atomic_load_relaxed (&isem->data) & SEM_VALUE_MASK;
+#else
+  *sval = atomic_load_relaxed (&isem->value) >> SEM_VALUE_SHIFT;
+#endif
 
   return 0;
 }
 versioned_symbol (libpthread, __new_sem_getvalue, sem_getvalue, GLIBC_2_1);
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_getvalue, __old_sem_getvalue)
+int
+__old_sem_getvalue (sem_t *sem, int *sval)
+{
+  struct old_sem *isem = (struct old_sem *) sem;
+  *sval = isem->value;
+  return 0;
+}
 compat_symbol (libpthread, __old_sem_getvalue, sem_getvalue, GLIBC_2_0);
 #endif
diff --git a/nptl/sem_init.c b/nptl/sem_init.c
index 5350f16a19..575b661f62 100644
--- a/nptl/sem_init.c
+++ b/nptl/sem_init.c
@@ -18,17 +18,29 @@
 
 #include <errno.h>
 #include <semaphore.h>
-#include <lowlevellock.h>
 #include <shlib-compat.h>
 #include "semaphoreP.h"
 #include <kernel-features.h>
 
+/* Returns FUTEX_PRIVATE if pshared is zero and private futexes are supported;
+   returns FUTEX_SHARED otherwise.
+   TODO Remove when cleaning up the futex API throughout glibc.  */
+static __always_inline int
+futex_private_if_supported (int pshared)
+{
+  if (pshared != 0)
+    return LLL_SHARED;
+#ifdef __ASSUME_PRIVATE_FUTEX
+  return LLL_PRIVATE;
+#else
+  return THREAD_GETMEM (THREAD_SELF, header.private_futex)
+      ^ FUTEX_PRIVATE_FLAG;
+#endif
+}
+
 
 int
-__new_sem_init (sem, pshared, value)
-     sem_t *sem;
-     int pshared;
-     unsigned int value;
+__new_sem_init (sem_t *sem, int pshared, unsigned int value)
 {
   /* Parameter sanity check.  */
   if (__glibc_unlikely (value > SEM_VALUE_MAX))
@@ -40,16 +52,15 @@ __new_sem_init (sem, pshared, value)
   /* Map to the internal type.  */
   struct new_sem *isem = (struct new_sem *) sem;
 
-  /* Use the values the user provided.  */
-  isem->value = value;
-#ifdef __ASSUME_PRIVATE_FUTEX
-  isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
+  /* Use the values the caller provided.  */
+#if __HAVE_64B_ATOMICS
+  isem->data = value;
 #else
-  isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
-					       header.private_futex);
+  isem->value = value << SEM_VALUE_SHIFT;
+  isem->nwaiters = 0;
 #endif
 
-  isem->nwaiters = 0;
+  isem->private = futex_private_if_supported (pshared);
 
   return 0;
 }
diff --git a/nptl/sem_open.c b/nptl/sem_open.c
index b5a5de4eeb..bfd2dea94e 100644
--- a/nptl/sem_open.c
+++ b/nptl/sem_open.c
@@ -193,9 +193,14 @@ sem_open (const char *name, int oflag, ...)
 	struct new_sem newsem;
       } sem;
 
-      sem.newsem.value = value;
-      sem.newsem.private = 0;
+#if __HAVE_64B_ATOMICS
+      sem.newsem.data = value;
+#else
+      sem.newsem.value = value << SEM_VALUE_SHIFT;
       sem.newsem.nwaiters = 0;
+#endif
+      /* This always is a shared semaphore.  */
+      sem.newsem.private = LLL_SHARED;
 
       /* Initialize the remaining bytes as well.  */
       memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0',
diff --git a/nptl/sem_post.c b/nptl/sem_post.c
index d1c39ffe05..9162e4c8a6 100644
--- a/nptl/sem_post.c
+++ b/nptl/sem_post.c
@@ -26,34 +26,78 @@
 
 #include <shlib-compat.h>
 
+/* Wrapper for lll_futex_wake, with error checking.
+   TODO Remove when cleaning up the futex API throughout glibc.  */
+static __always_inline void
+futex_wake (unsigned int* futex, int processes_to_wake, int private)
+{
+  int res = lll_futex_wake (futex, processes_to_wake, private);
+  /* No error.  Ignore the number of woken processes.  */
+  if (res >= 0)
+    return;
+  switch (res)
+    {
+    case -EFAULT: /* Could have happened due to memory reuse.  */
+    case -EINVAL: /* Could be either due to incorrect alignment (a bug in
+		     glibc or in the application) or due to memory being
+		     reused for a PI futex.  We cannot distinguish between the
+		     two causes, and one of them is correct use, so we do not
+		     act in this case.  */
+      return;
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
+    /* No other errors are documented at this time.  */
+    default:
+      abort ();
+    }
+}
+
+
+/* See sem_wait for an explanation of the algorithm.  */
 int
 __new_sem_post (sem_t *sem)
 {
   struct new_sem *isem = (struct new_sem *) sem;
+  int private = isem->private;
 
-  __typeof (isem->value) cur;
+#if __HAVE_64B_ATOMICS
+  /* Add a token to the semaphore.  We use release MO to make sure that a
+     thread acquiring this token synchronizes with us and other threads that
+     added tokens before (the release sequence includes atomic RMW operations
+     by other threads).  */
+  /* TODO Use atomic_fetch_add to make it scale better than a CAS loop?  */
+  unsigned long int d = atomic_load_relaxed (&isem->data);
   do
     {
-      cur = isem->value;
-      if (isem->value == SEM_VALUE_MAX)
+      if ((d & SEM_VALUE_MASK) == SEM_VALUE_MAX)
 	{
 	  __set_errno (EOVERFLOW);
 	  return -1;
 	}
     }
-  while (atomic_compare_and_exchange_bool_rel (&isem->value, cur + 1, cur));
+  while (!atomic_compare_exchange_weak_release (&isem->data, &d, d + 1));
 
-  atomic_full_barrier ();
-  if (isem->nwaiters > 0)
+  /* If there is any potentially blocked waiter, wake one of them.  */
+  if ((d >> SEM_NWAITERS_SHIFT) > 0)
+    futex_wake (((unsigned int *) &isem->data) + SEM_VALUE_OFFSET, 1, private);
+#else
+  /* Add a token to the semaphore.  Similar to 64b version.  */
+  unsigned int v = atomic_load_relaxed (&isem->value);
+  do
     {
-      int err = lll_futex_wake (&isem->value, 1,
-				isem->private ^ FUTEX_PRIVATE_FLAG);
-      if (__builtin_expect (err, 0) < 0)
+      if ((v << SEM_VALUE_SHIFT) == SEM_VALUE_MAX)
 	{
-	  __set_errno (-err);
+	  __set_errno (EOVERFLOW);
 	  return -1;
 	}
     }
+  while (!atomic_compare_exchange_weak_release (&isem->value,
+      &v, v + (1 << SEM_VALUE_SHIFT)));
+
+  /* If there is any potentially blocked waiter, wake one of them.  */
+  if ((v & SEM_NWAITERS_MASK) != 0)
+    futex_wake (&isem->value, 1, private);
+#endif
+
   return 0;
 }
 versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
@@ -66,6 +110,9 @@ __old_sem_post (sem_t *sem)
 {
   int *futex = (int *) sem;
 
+  /* We must need to synchronize with consumers of this token, so the atomic
+     increment must have release MO semantics.  */
+  atomic_write_barrier ();
   (void) atomic_increment_val (futex);
   /* We always have to assume it is a shared semaphore.  */
   int err = lll_futex_wake (futex, 1, LLL_SHARED);
diff --git a/nptl/sem_timedwait.c b/nptl/sem_timedwait.c
index d04bcdf38b..042b0acd58 100644
--- a/nptl/sem_timedwait.c
+++ b/nptl/sem_timedwait.c
@@ -1,4 +1,4 @@
-/* sem_timedwait -- wait on a semaphore.  Generic futex-using version.
+/* sem_timedwait -- wait on a semaphore with timeout.
    Copyright (C) 2003-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
@@ -17,101 +17,21 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <sysdep.h>
-#include <lowlevellock.h>
-#include <internaltypes.h>
-#include <semaphore.h>
-#include <sys/time.h>
-
-#include <pthreadP.h>
-#include <shlib-compat.h>
-
-
-extern void __sem_wait_cleanup (void *arg) attribute_hidden;
-
-/* This is in a seperate function in order to make sure gcc
-   puts the call site into an exception region, and thus the
-   cleanups get properly run.  */
-static int
-__attribute__ ((noinline))
-do_futex_timed_wait (struct new_sem *isem, struct timespec *rt)
-{
-  int err, oldtype = __pthread_enable_asynccancel ();
-
-  err = lll_futex_timed_wait (&isem->value, 0, rt,
-			      isem->private ^ FUTEX_PRIVATE_FLAG);
-
-  __pthread_disable_asynccancel (oldtype);
-  return err;
-}
+#include "sem_waitcommon.c"
 
+/* This is in a separate file because because sem_timedwait is only provided
+   if __USE_XOPEN2K is defined.  */
 int
 sem_timedwait (sem_t *sem, const struct timespec *abstime)
 {
-  struct new_sem *isem = (struct new_sem *) sem;
-  int err;
-
-  if (atomic_decrement_if_positive (&isem->value) > 0)
-    return 0;
-
   if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
     {
       __set_errno (EINVAL);
       return -1;
     }
 
-  atomic_increment (&isem->nwaiters);
-
-  pthread_cleanup_push (__sem_wait_cleanup, isem);
-
-  while (1)
-    {
-      struct timeval tv;
-      struct timespec rt;
-      int sec, nsec;
-
-      /* Get the current time.  */
-      __gettimeofday (&tv, NULL);
-
-      /* Compute relative timeout.  */
-      sec = abstime->tv_sec - tv.tv_sec;
-      nsec = abstime->tv_nsec - tv.tv_usec * 1000;
-      if (nsec < 0)
-	{
-	  nsec += 1000000000;
-	  --sec;
-	}
-
-      /* Already timed out?  */
-      if (sec < 0)
-	{
-	  __set_errno (ETIMEDOUT);
-	  err = -1;
-	  break;
-	}
-
-      /* Do wait.  */
-      rt.tv_sec = sec;
-      rt.tv_nsec = nsec;
-      err = do_futex_timed_wait(isem, &rt);
-      if (err != 0 && err != -EWOULDBLOCK)
-	{
-	  __set_errno (-err);
-	  err = -1;
-	  break;
-	}
-
-      if (atomic_decrement_if_positive (&isem->value) > 0)
-	{
-	  err = 0;
-	  break;
-	}
-    }
-
-  pthread_cleanup_pop (0);
-
-  atomic_decrement (&isem->nwaiters);
-
-  return err;
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
+    return 0;
+  else
+    return __new_sem_wait_slow((struct new_sem *) sem, abstime);
 }
diff --git a/nptl/sem_trywait.c b/nptl/sem_trywait.c
deleted file mode 100644
index d4340988c4..0000000000
--- a/nptl/sem_trywait.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* sem_trywait -- wait on a semaphore.  Generic futex-using version.
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <sysdep.h>
-#include <lowlevellock.h>
-#include <internaltypes.h>
-#include <semaphore.h>
-#include <atomic.h>
-
-#include <shlib-compat.h>
-
-
-int
-__new_sem_trywait (sem_t *sem)
-{
-  int *futex = (int *) sem;
-  int val;
-
-  if (*futex > 0)
-    {
-      val = atomic_decrement_if_positive (futex);
-      if (val > 0)
-	return 0;
-    }
-
-  __set_errno (EAGAIN);
-  return -1;
-}
-versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1);
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_trywait, __old_sem_trywait)
-compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
-#endif
diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c
index df11933b69..c1fd10c9d0 100644
--- a/nptl/sem_wait.c
+++ b/nptl/sem_wait.c
@@ -17,80 +17,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
-#include <sysdep.h>
-#include <lowlevellock.h>
-#include <internaltypes.h>
-#include <semaphore.h>
-
-#include <pthreadP.h>
-#include <shlib-compat.h>
-#include <atomic.h>
-
-
-void
-attribute_hidden
-__sem_wait_cleanup (void *arg)
-{
-  struct new_sem *isem = (struct new_sem *) arg;
-
-  atomic_decrement (&isem->nwaiters);
-}
-
-/* This is in a seperate function in order to make sure gcc
-   puts the call site into an exception region, and thus the
-   cleanups get properly run.  */
-static int
-__attribute__ ((noinline))
-do_futex_wait (struct new_sem *isem)
-{
-  int err, oldtype = __pthread_enable_asynccancel ();
-
-  err = lll_futex_wait (&isem->value, 0, isem->private ^ FUTEX_PRIVATE_FLAG);
-
-  __pthread_disable_asynccancel (oldtype);
-  return err;
-}
+#include "sem_waitcommon.c"
 
 int
 __new_sem_wait (sem_t *sem)
 {
-  struct new_sem *isem = (struct new_sem *) sem;
-  int err;
-
-  if (atomic_decrement_if_positive (&isem->value) > 0)
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
     return 0;
-
-  atomic_increment (&isem->nwaiters);
-
-  pthread_cleanup_push (__sem_wait_cleanup, isem);
-
-  while (1)
-    {
-      err = do_futex_wait(isem);
-      if (err != 0 && err != -EWOULDBLOCK)
-	{
-	  __set_errno (-err);
-	  err = -1;
-	  break;
-	}
-
-      if (atomic_decrement_if_positive (&isem->value) > 0)
-	{
-	  err = 0;
-	  break;
-	}
-    }
-
-  pthread_cleanup_pop (0);
-
-  atomic_decrement (&isem->nwaiters);
-
-  return err;
+  else
+    return __new_sem_wait_slow((struct new_sem *) sem, NULL);
 }
 versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
 
-
 #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
 int
 attribute_compat_text_section
@@ -121,3 +59,34 @@ __old_sem_wait (sem_t *sem)
 
 compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
 #endif
+
+int
+__new_sem_trywait (sem_t *sem)
+{
+  /* We must not fail spuriously, so require a definitive result even if this
+     may lead to a long execution time.  */
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 1) == 0)
+    return 0;
+  __set_errno (EAGAIN);
+  return -1;
+}
+versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1);
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+__old_sem_trywait (sem_t *sem)
+{
+  int *futex = (int *) sem;
+  int val;
+
+  if (*futex > 0)
+    {
+      val = atomic_decrement_if_positive (futex);
+      if (val > 0)
+	return 0;
+    }
+
+  __set_errno (EAGAIN);
+  return -1;
+}
+compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0);
+#endif
diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
new file mode 100644
index 0000000000..96848d7ac5
--- /dev/null
+++ b/nptl/sem_waitcommon.c
@@ -0,0 +1,467 @@
+/* sem_waitcommon -- wait on a semaphore, shared code.
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
+
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <internaltypes.h>
+#include <semaphore.h>
+#include <sys/time.h>
+
+#include <pthreadP.h>
+#include <shlib-compat.h>
+#include <atomic.h>
+
+/* Wrapper for lll_futex_wait with absolute timeout and error checking.
+   TODO Remove when cleaning up the futex API throughout glibc.  */
+static __always_inline int
+futex_abstimed_wait (unsigned int* futex, unsigned int expected,
+		     const struct timespec* abstime, int private, bool cancel)
+{
+  int err, oldtype;
+  if (abstime == NULL)
+    {
+      if (cancel)
+	oldtype = __pthread_enable_asynccancel ();
+      err = lll_futex_wait (futex, expected, private);
+      if (cancel)
+	__pthread_disable_asynccancel (oldtype);
+    }
+  else
+    {
+      struct timeval tv;
+      struct timespec rt;
+      int sec, nsec;
+
+      /* Get the current time.  */
+      __gettimeofday (&tv, NULL);
+
+      /* Compute relative timeout.  */
+      sec = abstime->tv_sec - tv.tv_sec;
+      nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      if (nsec < 0)
+        {
+          nsec += 1000000000;
+          --sec;
+        }
+
+      /* Already timed out?  */
+      if (sec < 0)
+        return ETIMEDOUT;
+
+      /* Do wait.  */
+      rt.tv_sec = sec;
+      rt.tv_nsec = nsec;
+      if (cancel)
+	oldtype = __pthread_enable_asynccancel ();
+      err = lll_futex_timed_wait (futex, expected, &rt, private);
+      if (cancel)
+	__pthread_disable_asynccancel (oldtype);
+    }
+  switch (err)
+    {
+    case 0:
+    case -EAGAIN:
+    case -EINTR:
+    case -ETIMEDOUT:
+      return -err;
+
+    case -EFAULT: /* Must have been caused by a glibc or application bug.  */
+    case -EINVAL: /* Either due to wrong alignment or due to the timeout not
+		     being normalized.  Must have been caused by a glibc or
+		     application bug.  */
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
+    /* No other errors are documented at this time.  */
+    default:
+      abort ();
+    }
+}
+
+/* Wrapper for lll_futex_wake, with error checking.
+   TODO Remove when cleaning up the futex API throughout glibc.  */
+static __always_inline void
+futex_wake (unsigned int* futex, int processes_to_wake, int private)
+{
+  int res = lll_futex_wake (futex, processes_to_wake, private);
+  /* No error.  Ignore the number of woken processes.  */
+  if (res >= 0)
+    return;
+  switch (res)
+    {
+    case -EFAULT: /* Could have happened due to memory reuse.  */
+    case -EINVAL: /* Could be either due to incorrect alignment (a bug in
+		     glibc or in the application) or due to memory being
+		     reused for a PI futex.  We cannot distinguish between the
+		     two causes, and one of them is correct use, so we do not
+		     act in this case.  */
+      return;
+    case -ENOSYS: /* Must have been caused by a glibc bug.  */
+    /* No other errors are documented at this time.  */
+    default:
+      abort ();
+    }
+}
+
+
+/* The semaphore provides two main operations: sem_post adds a token to the
+   semaphore; sem_wait grabs a token from the semaphore, potentially waiting
+   until there is a token available.  A sem_wait needs to synchronize with
+   the sem_post that provided the token, so that whatever lead to the sem_post
+   happens before the code after sem_wait.
+
+   Conceptually, available tokens can simply be counted; let's call that the
+   value of the semaphore.  However, we also want to know whether there might
+   be a sem_wait that is blocked on the value because it was zero (using a
+   futex with the value being the futex variable); if there is no blocked
+   sem_wait, sem_post does not need to execute a futex_wake call.  Therefore,
+   we also need to count the number of potentially blocked sem_wait calls
+   (which we call nwaiters).
+
+   What makes this tricky is that POSIX requires that a semaphore can be
+   destroyed as soon as the last remaining sem_wait has returned, and no
+   other sem_wait or sem_post calls are executing concurrently.  However, the
+   sem_post call whose token was consumed by the last sem_wait is considered
+   to have finished once it provided the token to the sem_wait.
+   Thus, sem_post must not access the semaphore struct anymore after it has
+   made a token available; IOW, it needs to be able to atomically provide
+   a token and check whether any blocked sem_wait calls might exist.
+
+   This is straightforward to do if the architecture provides 64b atomics
+   because we can just put both the value and nwaiters into one variable that
+   we access atomically: This is the data field, the value is in the
+   least-significant 32 bits, and nwaiters in the other bits.  When sem_post
+   makes a value available, it can atomically check nwaiters.
+
+   If we have only 32b atomics available, we cannot put both nwaiters and
+   value into one 32b value because then we might have too few bits for both
+   of those counters.  Therefore, we need to use two distinct fields.
+
+   To allow sem_post to atomically make a token available and check for
+   blocked sem_wait calls, we use one bit in value to indicate whether
+   nwaiters is nonzero.  That allows sem_post to use basically the same
+   algorithm as with 64b atomics, but requires sem_wait to update the bit; it
+   can't do this atomically with another access to nwaiters, but it can compute
+   a conservative value for the bit because it's benign if the bit is set
+   even if nwaiters is zero (all we get is an unnecessary futex wake call by
+   sem_post).
+   Specifically, sem_wait will unset the bit speculatively if it believes that
+   there is no other concurrently executing sem_wait.  If it misspeculated,
+   it will have to clean up by waking any other sem_wait call (i.e., what
+   sem_post would do otherwise).  This does not conflict with the destruction
+   requirement because the semaphore must not be destructed while any sem_wait
+   is still executing.  */
+
+/* Set this to true if you assume that, in contrast to current Linux futex
+   documentation, lll_futex_wake can return -EINTR only if interrupted by a
+   signal, not spuriously due to some other reason.
+   TODO Discuss EINTR conditions with the Linux kernel community.  For
+   now, we set this to true to not change behavior of semaphores compared
+   to previous glibc builds.  */
+static const int sem_assume_only_signals_cause_futex_EINTR = 1;
+
+#if !__HAVE_64B_ATOMICS
+static void
+__sem_wait_32_finish (struct new_sem *sem);
+#endif
+
+static void
+__sem_wait_cleanup (void *arg)
+{
+  struct new_sem *sem = (struct new_sem *) arg;
+
+#if __HAVE_64B_ATOMICS
+  /* Stop being registered as a waiter.  See below for MO.  */
+  atomic_fetch_add_relaxed (&sem->data, -(1UL << SEM_NWAITERS_SHIFT));
+#else
+  __sem_wait_32_finish (sem);
+#endif
+}
+
+/* Wait until at least one token is available, possibly with a timeout.
+   This is in a separate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  TODO still necessary?  Other futex_wait
+   users don't seem to need it.  */
+static int
+__attribute__ ((noinline))
+do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
+{
+  int err;
+
+#if __HAVE_64B_ATOMICS
+  err = futex_abstimed_wait ((unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0,
+			     abstime, sem->private, true);
+#else
+  err = futex_abstimed_wait (&sem->value, SEM_NWAITERS_MASK, abstime,
+			     sem->private, true);
+#endif
+
+  return err;
+}
+
+/* Fast path: Try to grab a token without blocking.  */
+static int
+__new_sem_wait_fast (struct new_sem *sem, int definitive_result)
+{
+  /* We need acquire MO if we actually grab a token, so that this
+     synchronizes with all token providers (i.e., the RMW operation we read
+     from or all those before it in modification order; also see sem_post).
+     We do not need to guarantee any ordering if we observed that there is
+     no token (POSIX leaves it unspecified whether functions that fail
+     synchronize memory); thus, relaxed MO is sufficient for the initial load
+     and the failure path of the CAS.  If the weak CAS fails and we need a
+     definitive result, retry.  */
+#if __HAVE_64B_ATOMICS
+  unsigned long d = atomic_load_relaxed (&sem->data);
+  do
+    {
+      if ((d & SEM_VALUE_MASK) == 0)
+	break;
+      if (atomic_compare_exchange_weak_acquire (&sem->data, &d, d - 1))
+	return 0;
+    }
+  while (definitive_result);
+  return -1;
+#else
+  unsigned int v = atomic_load_relaxed (&sem->value);
+  do
+    {
+      if ((v >> SEM_VALUE_SHIFT) == 0)
+	break;
+      if (atomic_compare_exchange_weak_acquire (&sem->value,
+	  &v, v - (1 << SEM_VALUE_SHIFT)))
+	return 0;
+    }
+  while (definitive_result);
+  return -1;
+#endif
+}
+
+/* Slow path that blocks.  */
+static int
+__attribute__ ((noinline))
+__new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
+{
+  int err = 0;
+
+#if __HAVE_64B_ATOMICS
+  /* Add a waiter.  Relaxed MO is sufficient because we can rely on the
+     ordering provided by the RMW operations we use.  */
+  unsigned long d = atomic_fetch_add_relaxed (&sem->data,
+      1UL << SEM_NWAITERS_SHIFT);
+
+  pthread_cleanup_push (__sem_wait_cleanup, sem);
+
+  /* Wait for a token to be available.  Retry until we can grab one.  */
+  for (;;)
+    {
+      /* If there is no token available, sleep until there is.  */
+      if ((d & SEM_VALUE_MASK) == 0)
+	{
+	  err = do_futex_wait (sem, abstime);
+	  /* A futex return value of 0 or EAGAIN is due to a real or spurious
+	     wake-up, or due to a change in the number of tokens.  We retry in
+	     these cases.
+	     If we timed out, forward this to the caller.
+	     EINTR could be either due to being interrupted by a signal, or
+	     due to a spurious wake-up.  Thus, we cannot distinguish between
+	     both, and are not allowed to return EINTR to the caller but have
+	     to retry; this is because we may not have been interrupted by a
+	     signal.  However, if we assume that only signals cause a futex
+	     return of EINTR, we forward EINTR to the caller.
+
+	     Retrying on EINTR is technically always allowed because to
+	     reliably interrupt sem_wait with a signal, the signal handler
+	     must call sem_post (which is AS-Safe).  In executions where the
+	     signal handler does not do that, the implementation can correctly
+	     claim that sem_wait hadn't actually started to execute yet, and
+	     thus the signal never actually interrupted sem_wait.  We make no
+	     timing guarantees, so the program can never observe that sem_wait
+	     actually did start to execute.  Thus, in a correct program, we
+	     can expect a signal that wanted to interrupt the sem_wait to have
+	     provided a token, and can just try to grab this token if
+	     futex_wait returns EINTR.  */
+	  if (err == ETIMEDOUT ||
+	      (err == EINTR && sem_assume_only_signals_cause_futex_EINTR))
+	    {
+	      __set_errno (err);
+	      err = -1;
+	      /* Stop being registered as a waiter.  */
+	      atomic_fetch_add_relaxed (&sem->data,
+		  -(1UL << SEM_NWAITERS_SHIFT));
+	      break;
+	    }
+	  /* Relaxed MO is sufficient; see below.  */
+	  d = atomic_load_relaxed (&sem->data);
+	}
+      else
+	{
+	  /* Try to grab both a token and stop being a waiter.  We need
+	     acquire MO so this synchronizes with all token providers (i.e.,
+	     the RMW operation we read from or all those before it in
+	     modification order; also see sem_post).  On the failure path,
+	     relaxed MO is sufficient because we only eventually need the
+	     up-to-date value; the futex_wait or the CAS perform the real
+	     work.  */
+	  if (atomic_compare_exchange_weak_acquire (&sem->data,
+	      &d, d - 1 - (1UL << SEM_NWAITERS_SHIFT)))
+	    {
+	      err = 0;
+	      break;
+	    }
+	}
+    }
+
+  pthread_cleanup_pop (0);
+#else
+  /* The main difference to the 64b-atomics implementation is that we need to
+     access value and nwaiters in separate steps, and that the nwaiters bit
+     in the value can temporarily not be set even if nwaiters is nonzero.
+     We work around incorrectly unsetting the nwaiters bit by letting sem_wait
+     set the bit again and waking the number of waiters that could grab a
+     token.  There are two additional properties we need to ensure:
+     (1) We make sure that whenever unsetting the bit, we see the increment of
+     nwaiters by the other thread that set the bit.  IOW, we will notice if
+     we make a mistake.
+     (2) When setting the nwaiters bit, we make sure that we see the unsetting
+     of the bit by another waiter that happened before us.  This avoids having
+     to blindly set the bit whenever we need to block on it.  We set/unset
+     the bit while having incremented nwaiters (i.e., are a registered
+     waiter), and the problematic case only happens when one waiter indeed
+     followed another (i.e., nwaiters was never larger than 1); thus, this
+     works similarly as with a critical section using nwaiters (see the MOs
+     and related comments below).
+
+     An alternative approach would be to unset the bit after decrementing
+     nwaiters; however, that would result in needing Dekker-like
+     synchronization and thus full memory barriers.  We also would not be able
+     to prevent misspeculation, so this alternative scheme does not seem
+     beneficial.  */
+  unsigned int v;
+
+  /* Add a waiter.  We need acquire MO so this synchronizes with the release
+     MO we use when decrementing nwaiters below; it ensures that if another
+     waiter unset the bit before us, we see that and set it again.  Also see
+     property (2) above.  */
+  atomic_fetch_add_acquire (&sem->nwaiters, 1);
+
+  pthread_cleanup_push (__sem_wait_cleanup, sem);
+
+  /* Wait for a token to be available.  Retry until we can grab one.  */
+  /* We do not need any ordering wrt. to this load's reads-from, so relaxed
+     MO is sufficient.  The acquire MO above ensures that in the problematic
+     case, we do see the unsetting of the bit by another waiter.  */
+  v = atomic_load_relaxed (&sem->value);
+  do
+    {
+      do
+	{
+	  /* We are about to block, so make sure that the nwaiters bit is
+	     set.  We need release MO on the CAS to ensure that when another
+	     waiter unsets the nwaiters bit, it will also observe that we
+	     incremented nwaiters in the meantime (also see the unsetting of
+	     the bit below).  Relaxed MO on CAS failure is sufficient (see
+	     above).  */
+	  do
+	    {
+	      if ((v & SEM_NWAITERS_MASK) != 0)
+		break;
+	    }
+	  while (!atomic_compare_exchange_weak_release (&sem->value,
+	      &v, v | SEM_NWAITERS_MASK));
+	  /* If there is no token, wait.  */
+	  if ((v >> SEM_VALUE_SHIFT) == 0)
+	    {
+	      /* See __HAVE_64B_ATOMICS variant.  */
+	      err = do_futex_wait(sem, abstime);
+	      if (err == ETIMEDOUT ||
+		  (err == EINTR && sem_assume_only_signals_cause_futex_EINTR))
+		{
+		  __set_errno (err);
+		  err = -1;
+		  goto error;
+		}
+	      err = 0;
+	      /* We blocked, so there might be a token now.  Relaxed MO is
+		 sufficient (see above).  */
+	      v = atomic_load_relaxed (&sem->value);
+	    }
+	}
+      /* If there is no token, we must not try to grab one.  */
+      while ((v >> SEM_VALUE_SHIFT) == 0);
+    }
+  /* Try to grab a token.  We need acquire MO so this synchronizes with
+     all token providers (i.e., the RMW operation we read from or all those
+     before it in modification order; also see sem_post).  */
+  while (!atomic_compare_exchange_weak_acquire (&sem->value,
+      &v, v - (1 << SEM_VALUE_SHIFT)));
+
+error:
+  pthread_cleanup_pop (0);
+
+  __sem_wait_32_finish (sem);
+#endif
+
+  return err;
+}
+
+/* Stop being a registered waiter (non-64b-atomics code only).  */
+#if !__HAVE_64B_ATOMICS
+static void
+__sem_wait_32_finish (struct new_sem *sem)
+{
+  /* The nwaiters bit is still set, try to unset it now if this seems
+     necessary.  We do this before decrementing nwaiters so that the unsetting
+     is visible to other waiters entering after us.  Relaxed MO is sufficient
+     because we are just speculating here; a stronger MO would not prevent
+     misspeculation.  */
+  unsigned int wguess = atomic_load_relaxed (&sem->nwaiters);
+  if (wguess == 1)
+    /* We might be the last waiter, so unset.  This needs acquire MO so that
+       it syncronizes with the release MO when setting the bit above; if we
+       overwrite someone else that set the bit, we'll read in the following
+       decrement of nwaiters at least from that release sequence, so we'll
+       see if the other waiter is still active or if another writer entered
+       in the meantime (i.e., using the check below).  */
+    atomic_fetch_and_acquire (&sem->value, ~SEM_NWAITERS_MASK);
+
+  /* Now stop being a waiter, and see whether our guess was correct.
+     This needs release MO so that it synchronizes with the acquire MO when
+     a waiter increments nwaiters; this makes sure that newer writers see that
+     we reset the waiters_present bit.  */
+  unsigned int wfinal = atomic_fetch_add_release (&sem->nwaiters, -1);
+  if (wfinal > 1 && wguess == 1)
+    {
+      /* We guessed wrong, and so need to clean up after the mistake and
+         unblock any waiters that could have not been woken.  There is no
+         additional ordering that we need to set up, so relaxed MO is
+         sufficient.  */
+      unsigned int v = atomic_fetch_or_relaxed (&sem->value,
+						SEM_NWAITERS_MASK);
+      /* If there are available tokens, then wake as many waiters.  If there
+         aren't any, then there is no need to wake anyone because there is
+         none to grab for another waiter.  If tokens become available
+         subsequently, then the respective sem_post calls will do the wake-up
+         due to us having set the nwaiters bit again.  */
+      v >>= SEM_VALUE_SHIFT;
+      if (v > 0)
+	futex_wake (&sem->value, v, sem->private);
+    }
+}
+#endif
diff --git a/nptl/structsem.sym b/nptl/structsem.sym
deleted file mode 100644
index 0e2a15f2b5..0000000000
--- a/nptl/structsem.sym
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <limits.h>
-#include <stddef.h>
-#include <sched.h>
-#include <bits/pthreadtypes.h>
-#include "internaltypes.h"
-
---
-
-VALUE		offsetof (struct new_sem, value)
-PRIVATE		offsetof (struct new_sem, private)
-NWAITERS	offsetof (struct new_sem, nwaiters)
-SEM_VALUE_MAX	SEM_VALUE_MAX
diff --git a/nptl/tst-sem11.c b/nptl/tst-sem11.c
index 5248eba05d..1a2dbafd89 100644
--- a/nptl/tst-sem11.c
+++ b/nptl/tst-sem11.c
@@ -34,8 +34,11 @@ main (void)
       puts ("sem_init failed");
       return 1;
     }
-
+#if __HAVE_64B_ATOMICS
+  if ((u.ns.data >> SEM_NWAITERS_SHIFT) != 0)
+#else
   if (u.ns.nwaiters != 0)
+#endif
     {
       puts ("nwaiters not initialized");
       return 1;
@@ -68,7 +71,11 @@ main (void)
       goto again;
     }
 
+#if __HAVE_64B_ATOMICS
+  if ((u.ns.data >> SEM_NWAITERS_SHIFT) != 0)
+#else
   if (u.ns.nwaiters != 0)
+#endif
     {
       puts ("nwaiters not reset");
       return 1;
diff --git a/nptl/tst-sem13.c b/nptl/tst-sem13.c
index 068d79e85e..1560e91443 100644
--- a/nptl/tst-sem13.c
+++ b/nptl/tst-sem13.c
@@ -33,9 +33,14 @@ do_test (void)
       perror ("sem_timedwait did not fail with EINVAL");
       return 1;
     }
-  if (u.ns.nwaiters != 0)
+#if __HAVE_64B_ATOMICS
+  unsigned int nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT);
+#else
+  unsigned int nwaiters = u.ns.nwaiters;
+#endif
+  if (nwaiters != 0)
     {
-      printf ("sem_timedwait modified nwaiters: %ld\n", u.ns.nwaiters);
+      printf ("sem_timedwait modified nwaiters: %d\n", nwaiters);
       return 1;
     }
 
@@ -52,9 +57,14 @@ do_test (void)
       perror ("2nd sem_timedwait did not fail with ETIMEDOUT");
       return 1;
     }
-  if (u.ns.nwaiters != 0)
+#if __HAVE_64B_ATOMICS
+  nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT);
+#else
+  nwaiters = u.ns.nwaiters;
+#endif
+  if (nwaiters != 0)
     {
-      printf ("2nd sem_timedwait modified nwaiters: %ld\n", u.ns.nwaiters);
+      printf ("2nd sem_timedwait modified nwaiters: %d\n", nwaiters);
       return 1;
     }
 
diff --git a/sysdeps/nptl/internaltypes.h b/sysdeps/nptl/internaltypes.h
index 2f105459ee..7c0d2402a3 100644
--- a/sysdeps/nptl/internaltypes.h
+++ b/sysdeps/nptl/internaltypes.h
@@ -20,6 +20,8 @@
 #define _INTERNALTYPES_H	1
 
 #include <stdint.h>
+#include <atomic.h>
+#include <endian.h>
 
 
 struct pthread_attr
@@ -141,9 +143,29 @@ struct pthread_key_struct
 /* Semaphore variable structure.  */
 struct new_sem
 {
+#if __HAVE_64B_ATOMICS
+  /* The data field holds both value (in the least-significant 32 bytes) and
+     nwaiters.  */
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define SEM_VALUE_OFFSET 0
+# elif __BYTE_ORDER == __BIG_ENDIAN
+#  define SEM_VALUE_OFFSET 1
+# else
+# error Unsupported byte order.
+# endif
+# define SEM_NWAITERS_SHIFT 32
+# define SEM_VALUE_MASK (~(unsigned int)0)
+  unsigned long int data;
+  int private;
+  int pad;
+#else
+# define SEM_VALUE_SHIFT 1
+# define SEM_NWAITERS_MASK ((unsigned int)1)
   unsigned int value;
   int private;
-  unsigned long int nwaiters;
+  int pad;
+  unsigned int nwaiters;
+#endif
 };
 
 struct old_sem
diff --git a/sysdeps/unix/sysv/linux/alpha/sem_post.c b/sysdeps/unix/sysv/linux/alpha/sem_post.c
deleted file mode 100644
index 9d4495312e..0000000000
--- a/sysdeps/unix/sysv/linux/alpha/sem_post.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* ??? This is an ass-backwards way to do this.  We should simply define
-   the acquire/release semantics of atomic_exchange_and_add.  And even if
-   we don't do this, we should be using atomic_full_barrier or otherwise.  */
-#define __lll_rel_instr  "mb"
-#include <nptl/sem_post.c>
diff --git a/sysdeps/unix/sysv/linux/i386/i486/sem_post.S b/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
deleted file mode 100644
index 7b553bb478..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <shlib-compat.h>
-#include <pthread-errnos.h>
-#include <structsem.h>
-#include <lowlevellock.h>
-
-
-	.text
-
-	.globl	__new_sem_post
-	.type	__new_sem_post,@function
-	.align	16
-__new_sem_post:
-	cfi_startproc
-	pushl	%ebx
-	cfi_adjust_cfa_offset(4)
-	cfi_offset(%ebx, -8)
-
-	movl	8(%esp), %ebx
-
-#if VALUE == 0
-	movl	(%ebx), %eax
-#else
-	movl	VALUE(%ebx), %eax
-#endif
-0:	cmpl	$SEM_VALUE_MAX, %eax
-	je	3f
-	leal	1(%eax), %edx
-	LOCK
-#if VALUE == 0
-	cmpxchgl %edx, (%ebx)
-#else
-	cmpxchgl %edx, VALUE(%ebx)
-#endif
-	jnz	0b
-
-	cmpl	$0, NWAITERS(%ebx)
-	je	2f
-
-	movl	$FUTEX_WAKE, %ecx
-	orl	PRIVATE(%ebx), %ecx
-	movl	$1, %edx
-	movl	$SYS_futex, %eax
-	ENTER_KERNEL
-
-	testl	%eax, %eax
-	js	1f
-
-2:	xorl	%eax, %eax
-	popl	%ebx
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(%ebx)
-	ret
-
-	cfi_adjust_cfa_offset(4)
-	cfi_offset(%ebx, -8)
-1:
-#ifdef PIC
-	SETUP_PIC_REG(bx)
-#else
-	movl	$4f, %ebx
-4:
-#endif
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-#ifdef NO_TLS_DIRECT_SEG_REFS
-	movl	errno@gotntpoff(%ebx), %edx
-	addl	%gs:0, %edx
-	movl	$EINVAL, (%edx)
-#else
-	movl	errno@gotntpoff(%ebx), %edx
-	movl	$EINVAL, %gs:(%edx)
-#endif
-
-	orl	$-1, %eax
-	popl	%ebx
-	ret
-
-3:
-#ifdef PIC
-	SETUP_PIC_REG(bx)
-#else
-	movl	$5f, %ebx
-5:
-#endif
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-#ifdef NO_TLS_DIRECT_SEG_REFS
-	movl	errno@gotntpoff(%ebx), %edx
-	addl	%gs:0, %edx
-	movl	$EOVERFLOW, (%edx)
-#else
-	movl	errno@gotntpoff(%ebx), %edx
-	movl	$EOVERFLOW, %gs:(%edx)
-#endif
-
-	orl	$-1, %eax
-	popl	%ebx
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(%ebx)
-	ret
-	cfi_endproc
-	.size	__new_sem_post,.-__new_sem_post
-	versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1)
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-	.global	__old_sem_post
-	.type	__old_sem_post,@function
-__old_sem_post:
-	cfi_startproc
-	pushl	%ebx
-	cfi_adjust_cfa_offset(4)
-	cfi_offset(%ebx, -8)
-
-	movl	8(%esp), %ebx
-	LOCK
-	addl	$1, (%ebx)
-
-	movl	$SYS_futex, %eax
-	movl	$FUTEX_WAKE, %ecx
-	movl	$1, %edx
-	ENTER_KERNEL
-
-	testl	%eax, %eax
-	js	1b
-
-	xorl	%eax, %eax
-	popl	%ebx
-	cfi_adjust_cfa_offset(-4)
-	cfi_restore(%ebx)
-	ret
-	cfi_endproc
-	.size	__old_sem_post,.-__old_sem_post
-	compat_symbol(libpthread, __old_sem_post, sem_post, GLIBC_2_0)
-#endif
diff --git a/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S b/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
deleted file mode 100644
index a8b9164a9f..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
+++ /dev/null
@@ -1,327 +0,0 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <shlib-compat.h>
-#include <pthread-errnos.h>
-#include <structsem.h>
-#include <lowlevellock.h>
-
-
-#if VALUE != 0
-# error "code needs to be rewritten for VALUE != 0"
-#endif
-
-
-	.text
-
-	.globl	sem_timedwait
-	.type	sem_timedwait,@function
-	.align	16
-sem_timedwait:
-.LSTARTCODE:
-	movl	4(%esp), %ecx
-
-	movl	(%ecx), %eax
-2:	testl	%eax, %eax
-	je	1f
-
-	leal	-1(%eax), %edx
-	LOCK
-	cmpxchgl %edx, (%ecx)
-	jne	2b
-
-	xorl	%eax, %eax
-	ret
-
-	/* Check whether the timeout value is valid.  */
-1:	pushl	%esi
-.Lpush_esi:
-	pushl	%edi
-.Lpush_edi:
-	pushl	%ebx
-.Lpush_ebx:
-	subl	$12, %esp
-.Lsub_esp:
-
-	movl	32(%esp), %edi
-
-	/* Check for invalid nanosecond field.  */
-	cmpl	$1000000000, 4(%edi)
-	movl	$EINVAL, %esi
-	jae	.Lerrno_exit
-
-	LOCK
-	incl	NWAITERS(%ecx)
-
-7:	xorl	%ecx, %ecx
-	movl	%esp, %ebx
-	movl	%ecx, %edx
-	movl	$__NR_gettimeofday, %eax
-	ENTER_KERNEL
-
-	/* Compute relative timeout.  */
-	movl	4(%esp), %eax
-	movl	$1000, %edx
-	mul	%edx		/* Milli seconds to nano seconds.  */
-	movl	(%edi), %ecx
-	movl	4(%edi), %edx
-	subl	(%esp), %ecx
-	subl	%eax, %edx
-	jns	5f
-	addl	$1000000000, %edx
-	subl	$1, %ecx
-5:	testl	%ecx, %ecx
-	movl	$ETIMEDOUT, %esi
-	js	6f		/* Time is already up.  */
-
-	movl	%ecx, (%esp)	/* Store relative timeout.  */
-	movl	%edx, 4(%esp)
-
-.LcleanupSTART:
-	call	__pthread_enable_asynccancel
-	movl	%eax, 8(%esp)
-
-	movl	28(%esp), %ebx	/* Load semaphore address.  */
-#if FUTEX_WAIT == 0
-	movl	PRIVATE(%ebx), %ecx
-#else
-	movl	$FUTEX_WAIT, %ecx
-	orl	PRIVATE(%ebx), %ecx
-#endif
-	movl	%esp, %esi
-	xorl	%edx, %edx
-	movl	$SYS_futex, %eax
-	ENTER_KERNEL
-	movl	%eax, %esi
-
-	movl	8(%esp), %eax
-	call	__pthread_disable_asynccancel
-.LcleanupEND:
-
-	testl	%esi, %esi
-	je	9f
-	cmpl	$-EWOULDBLOCK, %esi
-	jne	3f
-
-9:	movl	(%ebx), %eax
-8:	testl	%eax, %eax
-	je	7b
-
-	leal	-1(%eax), %ecx
-	LOCK
-	cmpxchgl %ecx, (%ebx)
-	jne	8b
-
-	xorl	%eax, %eax
-
-	LOCK
-	decl	NWAITERS(%ebx)
-
-10:	addl	$12, %esp
-.Ladd_esp:
-	popl	%ebx
-.Lpop_ebx:
-	popl	%edi
-.Lpop_edi:
-	popl	%esi
-.Lpop_esi:
-	ret
-
-.Lafter_ret:
-3:	negl	%esi
-6:
-	movl	28(%esp), %ebx	/* Load semaphore address.  */
-	LOCK
-	decl	NWAITERS(%ebx)
-.Lerrno_exit:
-#ifdef PIC
-	SETUP_PIC_REG(bx)
-#else
-	movl	$4f, %ebx
-4:
-#endif
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-#ifdef NO_TLS_DIRECT_SEG_REFS
-	movl	errno@gotntpoff(%ebx), %edx
-	addl	%gs:0, %edx
-	movl	%esi, (%edx)
-#else
-	movl	errno@gotntpoff(%ebx), %edx
-	movl	%esi, %gs:(%edx)
-#endif
-
-	orl	$-1, %eax
-	jmp	10b
-	.size	sem_timedwait,.-sem_timedwait
-
-
-	.type	sem_wait_cleanup,@function
-sem_wait_cleanup:
-	LOCK
-	decl	NWAITERS(%ebx)
-	movl	%eax, (%esp)
-.LcallUR:
-	call	_Unwind_Resume@PLT
-	hlt
-.LENDCODE:
-	.size	sem_wait_cleanup,.-sem_wait_cleanup
-
-
-	.section .gcc_except_table,"a",@progbits
-.LexceptSTART:
-	.byte	0xff				# @LPStart format (omit)
-	.byte	0xff				# @TType format (omit)
-	.byte	0x01				# call-site format
-						# DW_EH_PE_uleb128
-	.uleb128 .Lcstend-.Lcstbegin
-.Lcstbegin:
-	.uleb128 .LcleanupSTART-.LSTARTCODE
-	.uleb128 .LcleanupEND-.LcleanupSTART
-	.uleb128 sem_wait_cleanup-.LSTARTCODE
-	.uleb128  0
-	.uleb128 .LcallUR-.LSTARTCODE
-	.uleb128 .LENDCODE-.LcallUR
-	.uleb128 0
-	.uleb128  0
-.Lcstend:
-
-
-	.section .eh_frame,"a",@progbits
-.LSTARTFRAME:
-	.long	.LENDCIE-.LSTARTCIE		# Length of the CIE.
-.LSTARTCIE:
-	.long	0				# CIE ID.
-	.byte	1				# Version number.
-#ifdef SHARED
-	.string	"zPLR"				# NUL-terminated augmentation
-						# string.
-#else
-	.string	"zPL"				# NUL-terminated augmentation
-						# string.
-#endif
-	.uleb128 1				# Code alignment factor.
-	.sleb128 -4				# Data alignment factor.
-	.byte	8				# Return address register
-						# column.
-#ifdef SHARED
-	.uleb128 7				# Augmentation value length.
-	.byte	0x9b				# Personality: DW_EH_PE_pcrel
-						# + DW_EH_PE_sdata4
-						# + DW_EH_PE_indirect
-	.long	DW.ref.__gcc_personality_v0-.
-	.byte	0x1b				# LSDA Encoding: DW_EH_PE_pcrel
-						# + DW_EH_PE_sdata4.
-	.byte	0x1b				# FDE Encoding: DW_EH_PE_pcrel
-						# + DW_EH_PE_sdata4.
-#else
-	.uleb128 6				# Augmentation value length.
-	.byte	0x0				# Personality: absolute
-	.long	__gcc_personality_v0
-	.byte	0x0				# LSDA Encoding: absolute
-#endif
-	.byte 0x0c				# DW_CFA_def_cfa
-	.uleb128 4
-	.uleb128 4
-	.byte	0x88				# DW_CFA_offset, column 0x10
-	.uleb128 1
-	.align 4
-.LENDCIE:
-
-	.long	.LENDFDE-.LSTARTFDE		# Length of the FDE.
-.LSTARTFDE:
-	.long	.LSTARTFDE-.LSTARTFRAME		# CIE pointer.
-#ifdef SHARED
-	.long	.LSTARTCODE-.			# PC-relative start address
-						# of the code.
-#else
-	.long	.LSTARTCODE			# Start address of the code.
-#endif
-	.long	.LENDCODE-.LSTARTCODE		# Length of the code.
-	.uleb128 4				# Augmentation size
-#ifdef SHARED
-	.long	.LexceptSTART-.
-#else
-	.long	.LexceptSTART
-#endif
-
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpush_esi-.LSTARTCODE
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 8
-	.byte   0x86				# DW_CFA_offset %esi
-	.uleb128 2
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpush_edi-.Lpush_esi
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 12
-	.byte   0x87				# DW_CFA_offset %edi
-	.uleb128 3
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpush_ebx-.Lpush_edi
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 16
-	.byte   0x83				# DW_CFA_offset %ebx
-	.uleb128 4
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lsub_esp-.Lpush_ebx
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 28
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Ladd_esp-.Lsub_esp
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 16
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpop_ebx-.Ladd_esp
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 12
-	.byte	0xc3				# DW_CFA_restore %ebx
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpop_edi-.Lpop_ebx
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 8
-	.byte	0xc7				# DW_CFA_restore %edi
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpop_esi-.Lpop_edi
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 4
-	.byte	0xc6				# DW_CFA_restore %esi
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lafter_ret-.Lpop_esi
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 28
-	.byte   0x86				# DW_CFA_offset %esi
-	.uleb128 2
-	.byte   0x87				# DW_CFA_offset %edi
-	.uleb128 3
-	.byte   0x83				# DW_CFA_offset %ebx
-	.uleb128 4
-	.align	4
-.LENDFDE:
-
-
-#ifdef SHARED
-	.hidden	DW.ref.__gcc_personality_v0
-	.weak	DW.ref.__gcc_personality_v0
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
-	.align	4
-	.type	DW.ref.__gcc_personality_v0, @object
-	.size	DW.ref.__gcc_personality_v0, 4
-DW.ref.__gcc_personality_v0:
-	.long	__gcc_personality_v0
-#endif
diff --git a/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S b/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
deleted file mode 100644
index 2524d96aea..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <shlib-compat.h>
-#include <pthread-errnos.h>
-#include <lowlevellock.h>
-
-	.text
-
-	.globl	__new_sem_trywait
-	.type	__new_sem_trywait,@function
-	.align	16
-__new_sem_trywait:
-	movl	4(%esp), %ecx
-
-	movl	(%ecx), %eax
-2:	testl	%eax, %eax
-	jz	1f
-
-	leal	-1(%eax), %edx
-	LOCK
-	cmpxchgl %edx, (%ecx)
-	jne	2b
-	xorl	%eax, %eax
-	ret
-
-1:
-#ifdef PIC
-	SETUP_PIC_REG(cx)
-#else
-	movl	$3f, %ecx
-3:
-#endif
-	addl	$_GLOBAL_OFFSET_TABLE_, %ecx
-#ifdef NO_TLS_DIRECT_SEG_REFS
-	movl	errno@gotntpoff(%ecx), %edx
-	addl	%gs:0, %edx
-	movl	$EAGAIN, (%edx)
-#else
-	movl	errno@gotntpoff(%ecx), %edx
-	movl	$EAGAIN, %gs:(%edx)
-#endif
-	orl	$-1, %eax
-	ret
-	.size	__new_sem_trywait,.-__new_sem_trywait
-	versioned_symbol(libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1)
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-	.global	__old_sem_trywait
-__old_sem_trywait = __new_sem_trywait
-	compat_symbol(libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0)
-#endif
diff --git a/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S b/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
deleted file mode 100644
index 9121041ecc..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
+++ /dev/null
@@ -1,343 +0,0 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <shlib-compat.h>
-#include <pthread-errnos.h>
-#include <structsem.h>
-#include <lowlevellock.h>
-
-
-#if VALUE != 0
-# error "code needs to be rewritten for VALUE != 0"
-#endif
-
-	.text
-
-	.globl	__new_sem_wait
-	.type	__new_sem_wait,@function
-	.align	16
-__new_sem_wait:
-.LSTARTCODE:
-	pushl	%ebx
-.Lpush_ebx:
-	pushl	%esi
-.Lpush_esi:
-	subl	$4, %esp
-.Lsub_esp:
-
-	movl	16(%esp), %ebx
-
-	movl	(%ebx), %eax
-2:	testl	%eax, %eax
-	je	1f
-
-	leal	-1(%eax), %edx
-	LOCK
-	cmpxchgl %edx, (%ebx)
-	jne	2b
-7:	xorl	%eax, %eax
-
-9:	movl	4(%esp), %esi
-	movl	8(%esp), %ebx
-	addl	$12, %esp
-.Ladd_esp:
-	ret
-
-.Lafter_ret:
-1:	LOCK
-	incl	NWAITERS(%ebx)
-
-.LcleanupSTART:
-6:	call	__pthread_enable_asynccancel
-	movl	%eax, (%esp)
-
-#if FUTEX_WAIT == 0
-	movl	PRIVATE(%ebx), %ecx
-#else
-	movl	$FUTEX_WAIT, %ecx
-	orl	PRIVATE(%ebx), %ecx
-#endif
-	xorl	%esi, %esi
-	xorl	%edx, %edx
-	movl	$SYS_futex, %eax
-	ENTER_KERNEL
-	movl	%eax, %esi
-
-	movl	(%esp), %eax
-	call	__pthread_disable_asynccancel
-.LcleanupEND:
-
-	testl	%esi, %esi
-	je	3f
-	cmpl	$-EWOULDBLOCK, %esi
-	jne	4f
-
-3:
-	movl	(%ebx), %eax
-5:	testl	%eax, %eax
-	je	6b
-
-	leal	-1(%eax), %edx
-	LOCK
-	cmpxchgl %edx, (%ebx)
-	jne	5b
-
-	LOCK
-	decl	NWAITERS(%ebx)
-	jmp	7b
-
-4:	LOCK
-	decl	NWAITERS(%ebx)
-
-	negl	%esi
-#ifdef PIC
-	SETUP_PIC_REG(bx)
-#else
-	movl	$8f, %ebx
-8:
-#endif
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-#ifdef NO_TLS_DIRECT_SEG_REFS
-	movl	errno@gotntpoff(%ebx), %edx
-	addl	%gs:0, %edx
-	movl	%esi, (%edx)
-#else
-	movl	errno@gotntpoff(%ebx), %edx
-	movl	%esi, %gs:(%edx)
-#endif
-	orl	$-1, %eax
-
-	jmp	9b
-	.size	__new_sem_wait,.-__new_sem_wait
-	versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
-
-
-	.type	sem_wait_cleanup,@function
-sem_wait_cleanup:
-	LOCK
-	decl	NWAITERS(%ebx)
-	movl	%eax, (%esp)
-.LcallUR:
-	call	_Unwind_Resume@PLT
-	hlt
-.LENDCODE:
-	.size	sem_wait_cleanup,.-sem_wait_cleanup
-
-
-	.section .gcc_except_table,"a",@progbits
-.LexceptSTART:
-	.byte	0xff				# @LPStart format (omit)
-	.byte	0xff				# @TType format (omit)
-	.byte	0x01				# call-site format
-						# DW_EH_PE_uleb128
-	.uleb128 .Lcstend-.Lcstbegin
-.Lcstbegin:
-	.uleb128 .LcleanupSTART-.LSTARTCODE
-	.uleb128 .LcleanupEND-.LcleanupSTART
-	.uleb128 sem_wait_cleanup-.LSTARTCODE
-	.uleb128  0
-	.uleb128 .LcallUR-.LSTARTCODE
-	.uleb128 .LENDCODE-.LcallUR
-	.uleb128 0
-	.uleb128  0
-.Lcstend:
-
-
-	.section .eh_frame,"a",@progbits
-.LSTARTFRAME:
-	.long	.LENDCIE-.LSTARTCIE		# Length of the CIE.
-.LSTARTCIE:
-	.long	0				# CIE ID.
-	.byte	1				# Version number.
-#ifdef SHARED
-	.string	"zPLR"				# NUL-terminated augmentation
-						# string.
-#else
-	.string	"zPL"				# NUL-terminated augmentation
-						# string.
-#endif
-	.uleb128 1				# Code alignment factor.
-	.sleb128 -4				# Data alignment factor.
-	.byte	8				# Return address register
-						# column.
-#ifdef SHARED
-	.uleb128 7				# Augmentation value length.
-	.byte	0x9b				# Personality: DW_EH_PE_pcrel
-						# + DW_EH_PE_sdata4
-						# + DW_EH_PE_indirect
-	.long	DW.ref.__gcc_personality_v0-.
-	.byte	0x1b				# LSDA Encoding: DW_EH_PE_pcrel
-						# + DW_EH_PE_sdata4.
-	.byte	0x1b				# FDE Encoding: DW_EH_PE_pcrel
-						# + DW_EH_PE_sdata4.
-#else
-	.uleb128 6				# Augmentation value length.
-	.byte	0x0				# Personality: absolute
-	.long	__gcc_personality_v0
-	.byte	0x0				# LSDA Encoding: absolute
-#endif
-	.byte 0x0c				# DW_CFA_def_cfa
-	.uleb128 4
-	.uleb128 4
-	.byte	0x88				# DW_CFA_offset, column 0x10
-	.uleb128 1
-	.align 4
-.LENDCIE:
-
-	.long	.LENDFDE-.LSTARTFDE		# Length of the FDE.
-.LSTARTFDE:
-	.long	.LSTARTFDE-.LSTARTFRAME		# CIE pointer.
-#ifdef SHARED
-	.long	.LSTARTCODE-.			# PC-relative start address
-						# of the code.
-#else
-	.long	.LSTARTCODE			# Start address of the code.
-#endif
-	.long	.LENDCODE-.LSTARTCODE		# Length of the code.
-	.uleb128 4				# Augmentation size
-#ifdef SHARED
-	.long	.LexceptSTART-.
-#else
-	.long	.LexceptSTART
-#endif
-
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpush_ebx-.LSTARTCODE
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 8
-	.byte   0x83				# DW_CFA_offset %ebx
-	.uleb128 2
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lpush_esi-.Lpush_ebx
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 12
-	.byte   0x86				# DW_CFA_offset %esi
-	.uleb128 3
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lsub_esp-.Lpush_esi
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 16
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Ladd_esp-.Lsub_esp
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 4
-	.byte	0xc3				# DW_CFA_restore %ebx
-	.byte	0xc6				# DW_CFA_restore %esi
-	.byte	4				# DW_CFA_advance_loc4
-	.long	.Lafter_ret-.Ladd_esp
-	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 16
-	.byte   0x83				# DW_CFA_offset %ebx
-	.uleb128 2
-	.byte   0x86				# DW_CFA_offset %esi
-	.uleb128 3
-	.align	4
-.LENDFDE:
-
-
-#ifdef SHARED
-	.hidden	DW.ref.__gcc_personality_v0
-	.weak	DW.ref.__gcc_personality_v0
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
-	.align	4
-	.type	DW.ref.__gcc_personality_v0, @object
-	.size	DW.ref.__gcc_personality_v0, 4
-DW.ref.__gcc_personality_v0:
-	.long	__gcc_personality_v0
-#endif
-
-
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-	.section ".text.compat", "ax"
-	.global	__old_sem_wait
-	.type	__old_sem_wait,@function
-	.align	16
-	cfi_startproc
-__old_sem_wait:
-	pushl	%ebx
-	cfi_adjust_cfa_offset(4)
-	pushl	%esi
-	cfi_adjust_cfa_offset(4)
-	subl	$4, %esp
-	cfi_adjust_cfa_offset(4)
-
-	movl	16(%esp), %ebx
-	cfi_offset(ebx, -8)
-
-	cfi_offset(esi, -12)
-3:	movl	(%ebx), %eax
-2:	testl	%eax, %eax
-	je	1f
-
-	leal	-1(%eax), %edx
-	LOCK
-	cmpxchgl %edx, (%ebx)
-	jne	2b
-	xorl	%eax, %eax
-
-5:	movl	4(%esp), %esi
-	movl	8(%esp), %ebx
-	addl	$12, %esp
-	cfi_restore(ebx)
-	cfi_restore(esi)
-	cfi_adjust_cfa_offset(-12)
-	ret
-
-	cfi_adjust_cfa_offset(12)
-	cfi_offset(ebx, -8)
-	cfi_offset(esi, -12)
-1:	call	__pthread_enable_asynccancel
-	movl	%eax, (%esp)
-
-	xorl	%esi, %esi
-	movl	$SYS_futex, %eax
-	movl	%esi, %ecx
-	movl	%esi, %edx
-	ENTER_KERNEL
-	movl	%eax, %esi
-
-	movl	(%esp), %eax
-	call	__pthread_disable_asynccancel
-
-	testl	%esi, %esi
-	je	3b
-	cmpl	$-EWOULDBLOCK, %esi
-	je	3b
-	negl	%esi
-#ifdef PIC
-	SETUP_PIC_REG(bx)
-#else
-	movl	$4f, %ebx
-4:
-#endif
-	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
-#ifdef NO_TLS_DIRECT_SEG_REFS
-	movl	errno@gotntpoff(%ebx), %edx
-	addl	%gs:0, %edx
-	movl	%esi, (%edx)
-#else
-	movl	errno@gotntpoff(%ebx), %edx
-	movl	%esi, %gs:(%edx)
-#endif
-	orl	$-1, %eax
-	jmp	5b
-	cfi_endproc
-	.size	__old_sem_wait,.-__old_sem_wait
-	compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
-#endif
diff --git a/sysdeps/unix/sysv/linux/i386/i586/sem_post.S b/sysdeps/unix/sysv/linux/i386/i586/sem_post.S
deleted file mode 100644
index 4534d567d8..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i586/sem_post.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include "../i486/sem_post.S"
diff --git a/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S b/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S
deleted file mode 100644
index fa4ad496e5..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include "../i486/sem_timedwait.S"
diff --git a/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S b/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S
deleted file mode 100644
index 6f3a690d77..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include "../i486/sem_trywait.S"
diff --git a/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S b/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S
deleted file mode 100644
index 718d50d680..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include "../i486/sem_wait.S"
diff --git a/sysdeps/unix/sysv/linux/i386/i686/sem_post.S b/sysdeps/unix/sysv/linux/i386/i686/sem_post.S
deleted file mode 100644
index 4534d567d8..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i686/sem_post.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include "../i486/sem_post.S"
diff --git a/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S b/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S
deleted file mode 100644
index fa4ad496e5..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include "../i486/sem_timedwait.S"
diff --git a/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S b/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S
deleted file mode 100644
index 6f3a690d77..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include "../i486/sem_trywait.S"
diff --git a/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S b/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S
deleted file mode 100644
index 718d50d680..0000000000
--- a/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include "../i486/sem_wait.S"
diff --git a/sysdeps/unix/sysv/linux/powerpc/sem_post.c b/sysdeps/unix/sysv/linux/powerpc/sem_post.c
deleted file mode 100644
index 6a4e46fb9d..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/sem_post.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* sem_post -- post to a POSIX semaphore.  Powerpc version.
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <sysdep.h>
-#include <lowlevellock.h>
-#include <internaltypes.h>
-#include <semaphore.h>
-
-#include <shlib-compat.h>
-
-int
-__new_sem_post (sem_t *sem)
-{
-  struct new_sem *isem = (struct new_sem *) sem;
-
-  __asm __volatile (__ARCH_REL_INSTR ::: "memory");
-  atomic_increment (&isem->value);
-  __asm __volatile (__ARCH_ACQ_INSTR ::: "memory");
-  if (isem->nwaiters > 0)
-    {
-      int err = lll_futex_wake (&isem->value, 1,
-				isem->private ^ FUTEX_PRIVATE_FLAG);
-      if (__builtin_expect (err, 0) < 0)
-	{
-	  __set_errno (-err);
-	  return -1;
-	}
-    }
-  return 0;
-}
-versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
-
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
-
-int
-attribute_compat_text_section
-__old_sem_post (sem_t *sem)
-{
-  int *futex = (int *) sem;
-
-  __asm __volatile (__ARCH_REL_INSTR ::: "memory");
-  (void) atomic_increment_val (futex);
-  /* We always have to assume it is a shared semaphore.  */
-  int err = lll_futex_wake (futex, 1, LLL_SHARED);
-  if (__builtin_expect (err, 0) < 0)
-    {
-      __set_errno (-err);
-      return -1;
-    }
-  return 0;
-}
-
-compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
-#endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/sem_post.S b/sysdeps/unix/sysv/linux/x86_64/sem_post.S
deleted file mode 100644
index f5dfb0536e..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/sem_post.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <lowlevellock.h>
-#include <shlib-compat.h>
-#include <pthread-errnos.h>
-#include <structsem.h>
-
-
-	.text
-
-	.globl	sem_post
-	.type	sem_post,@function
-	.align	16
-sem_post:
-#if VALUE == 0
-	movl	(%rdi), %eax
-#else
-	movl	VALUE(%rdi), %eax
-#endif
-0:	cmpl	$SEM_VALUE_MAX, %eax
-	je	3f
-	leal	1(%rax), %esi
-	LOCK
-#if VALUE == 0
-	cmpxchgl %esi, (%rdi)
-#else
-	cmpxchgl %esi, VALUE(%rdi)
-#endif
-	jnz	0b
-
-	LP_OP(cmp) $0, NWAITERS(%rdi)
-	je	2f
-
-	movl	$SYS_futex, %eax
-	movl	$FUTEX_WAKE, %esi
-	orl	PRIVATE(%rdi), %esi
-	movl	$1, %edx
-	syscall
-
-	testq	%rax, %rax
-	js	1f
-
-2:	xorl	%eax, %eax
-	retq
-
-1:
-	movl	$EINVAL, %eax
-	jmp	4f
-
-3:
-	movl	$EOVERFLOW, %eax
-
-4:
-	movq	errno@gottpoff(%rip), %rdx
-	movl	%eax, %fs:(%rdx)
-	orl	$-1, %eax
-	retq
-	.size	sem_post,.-sem_post
diff --git a/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
deleted file mode 100644
index 091b2411b4..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+++ /dev/null
@@ -1,380 +0,0 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <kernel-features.h>
-#include <lowlevellock.h>
-#include <shlib-compat.h>
-#include <pthread-errnos.h>
-#include <structsem.h>
-
-	.text
-
-	.globl	sem_timedwait
-	.type	sem_timedwait,@function
-	.align	16
-sem_timedwait:
-.LSTARTCODE:
-	cfi_startproc
-#ifdef SHARED
-	cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
-			DW.ref.__gcc_personality_v0)
-	cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
-#else
-	cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
-	cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
-#endif
-#if VALUE == 0
-	movl	(%rdi), %eax
-#else
-	movl	VALUE(%rdi), %eax
-#endif
-2:	testl	%eax, %eax
-	je	1f
-
-	leaq	-1(%rax), %rdx
-	LOCK
-#if VALUE == 0
-	cmpxchgl %edx, (%rdi)
-#else
-	cmpxchgl %edx, VALUE(%rdi)
-#endif
-	jne	2b
-
-	xorl	%eax, %eax
-	retq
-
-	/* Check whether the timeout value is valid.  */
-1:	cmpq	$1000000000, 8(%rsi)
-	jae	6f
-
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
-#  ifdef PIC
-	cmpl	$0, __have_futex_clock_realtime(%rip)
-#  else
-	cmpl	$0, __have_futex_clock_realtime
-#  endif
-	je	.Lreltmo
-#endif
-
-	cmpq	$0, (%rsi)
-	js	16f
-
-	/* This push is only needed to store the sem_t pointer for the
-	   exception handler.  */
-	pushq	%rdi
-	cfi_adjust_cfa_offset(8)
-
-	movq	%rsi, %r10
-
-	LOCK
-	LP_OP(add) $1, NWAITERS(%rdi)
-
-.LcleanupSTART:
-13:	call	__pthread_enable_asynccancel
-	movl	%eax, %r8d
-
-#if VALUE != 0
-	leaq	VALUE(%rdi), %rdi
-#endif
-	movl	$0xffffffff, %r9d
-	movl	$FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
-	orl	PRIVATE(%rdi), %esi
-	movl	$SYS_futex, %eax
-	xorl	%edx, %edx
-	syscall
-	movq	%rax, %r9
-#if VALUE != 0
-	leaq	-VALUE(%rdi), %rdi
-#endif
-
-	xchgq	%r8, %rdi
-	call	__pthread_disable_asynccancel
-.LcleanupEND:
-	movq	%r8, %rdi
-
-	testq	%r9, %r9
-	je	11f
-	cmpq	$-EWOULDBLOCK, %r9
-	jne	3f
-
-11:
-#if VALUE == 0
-	movl	(%rdi), %eax
-#else
-	movl	VALUE(%rdi), %eax
-#endif
-14:	testl	%eax, %eax
-	je	13b
-
-	leaq	-1(%rax), %rcx
-	LOCK
-#if VALUE == 0
-	cmpxchgl %ecx, (%rdi)
-#else
-	cmpxchgl %ecx, VALUE(%rdi)
-#endif
-	jne	14b
-
-	xorl	%eax, %eax
-
-15:	LOCK
-	LP_OP(sub) $1, NWAITERS(%rdi)
-
-	leaq	8(%rsp), %rsp
-	cfi_adjust_cfa_offset(-8)
-	retq
-
-	cfi_adjust_cfa_offset(8)
-3:	negq	%r9
-	movq	errno@gottpoff(%rip), %rdx
-	movl	%r9d, %fs:(%rdx)
-
-	orl	$-1, %eax
-	jmp	15b
-
-	cfi_adjust_cfa_offset(-8)
-6:
-	movq	errno@gottpoff(%rip), %rdx
-	movl	$EINVAL, %fs:(%rdx)
-
-	orl	$-1, %eax
-
-	retq
-
-16:
-	movq	errno@gottpoff(%rip), %rdx
-	movl	$ETIMEDOUT, %fs:(%rdx)
-
-	orl	$-1, %eax
-
-	retq
-
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
-.Lreltmo:
-	pushq	%r12
-	cfi_adjust_cfa_offset(8)
-	cfi_rel_offset(%r12, 0)
-	pushq	%r13
-	cfi_adjust_cfa_offset(8)
-	cfi_rel_offset(%r13, 0)
-	pushq	%r14
-	cfi_adjust_cfa_offset(8)
-	cfi_rel_offset(%r14, 0)
-
-#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
-# define STACKFRAME 8
-#else
-# define STACKFRAME 24
-#endif
-	subq	$STACKFRAME, %rsp
-	cfi_adjust_cfa_offset(STACKFRAME)
-
-	movq	%rdi, %r12
-	movq	%rsi, %r13
-
-	LOCK
-	LP_OP(add) $1, NWAITERS(%r12)
-
-7:	xorl	%esi, %esi
-	movq	%rsp,%rdi
-	/* This call works because we directly jump to a system call entry
-	   which preserves all the registers.  */
-	call	JUMPTARGET(__gettimeofday)
-
-	/* Compute relative timeout.  */
-	movq	8(%rsp), %rax
-	movl	$1000, %edi
-	mul	%rdi		/* Milli seconds to nano seconds.  */
-	movq	(%r13), %rdi
-	movq	8(%r13), %rsi
-	subq	(%rsp), %rdi
-	subq	%rax, %rsi
-	jns	5f
-	addq	$1000000000, %rsi
-	decq	%rdi
-5:	testq	%rdi, %rdi
-	movl	$ETIMEDOUT, %r14d
-	js	36f		/* Time is already up.  */
-
-	movq	%rdi, (%rsp)	/* Store relative timeout.  */
-	movq	%rsi, 8(%rsp)
-
-.LcleanupSTART2:
-	call	__pthread_enable_asynccancel
-	movl	%eax, 16(%rsp)
-
-	movq	%rsp, %r10
-# if VALUE == 0
-	movq	%r12, %rdi
-# else
-	leaq	VALUE(%r12), %rdi
-# endif
-# if FUTEX_WAIT == 0
-	movl	PRIVATE(%rdi), %esi
-# else
-	movl	$FUTEX_WAIT, %esi
-	orl	PRIVATE(%rdi), %esi
-# endif
-	movl	$SYS_futex, %eax
-	xorl	%edx, %edx
-	syscall
-	movq	%rax, %r14
-
-	movl	16(%rsp), %edi
-	call	__pthread_disable_asynccancel
-.LcleanupEND2:
-
-	testq	%r14, %r14
-	je	9f
-	cmpq	$-EWOULDBLOCK, %r14
-	jne	33f
-
-9:
-# if VALUE == 0
-	movl	(%r12), %eax
-# else
-	movl	VALUE(%r12), %eax
-# endif
-8:	testl	%eax, %eax
-	je	7b
-
-	leaq	-1(%rax), %rcx
-	LOCK
-# if VALUE == 0
-	cmpxchgl %ecx, (%r12)
-# else
-	cmpxchgl %ecx, VALUE(%r12)
-# endif
-	jne	8b
-
-	xorl	%eax, %eax
-
-45:	LOCK
-	LP_OP(sub) $1, NWAITERS(%r12)
-
-	addq	$STACKFRAME, %rsp
-	cfi_adjust_cfa_offset(-STACKFRAME)
-	popq	%r14
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(%r14)
-	popq	%r13
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(%r13)
-	popq	%r12
-	cfi_adjust_cfa_offset(-8)
-	cfi_restore(%r12)
-	retq
-
-	cfi_adjust_cfa_offset(STACKFRAME + 3 * 8)
-	cfi_rel_offset(%r12, STACKFRAME + 2 * 8)
-	cfi_rel_offset(%r13, STACKFRAME + 1 * 8)
-	cfi_rel_offset(%r14, STACKFRAME)
-33:	negq	%r14
-36:
-	movq	errno@gottpoff(%rip), %rdx
-	movl	%r14d, %fs:(%rdx)
-
-	orl	$-1, %eax
-	jmp	45b
-#endif
-	cfi_endproc
-	.size	sem_timedwait,.-sem_timedwait
-
-
-	.type	sem_timedwait_cleanup,@function
-sem_timedwait_cleanup:
-	cfi_startproc
-	cfi_adjust_cfa_offset(8)
-
-	movq	(%rsp), %rdi
-	LOCK
-	LP_OP(sub) $1, NWAITERS(%rdi)
-	movq	%rax, %rdi
-.LcallUR:
-	call	_Unwind_Resume@PLT
-	hlt
-.LENDCODE:
-	cfi_endproc
-	.size	sem_timedwait_cleanup,.-sem_timedwait_cleanup
-
-
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
-	.type	sem_timedwait_cleanup2,@function
-sem_timedwait_cleanup2:
-	cfi_startproc
-	cfi_adjust_cfa_offset(STACKFRAME + 3 * 8)
-	cfi_rel_offset(%r12, STACKFRAME + 2 * 8)
-	cfi_rel_offset(%r13, STACKFRAME + 1 * 8)
-	cfi_rel_offset(%r14, STACKFRAME)
-
-	LOCK
-	LP_OP(sub) $1, NWAITERS(%r12)
-	movq	%rax, %rdi
-	movq	STACKFRAME(%rsp), %r14
-	movq	STACKFRAME+8(%rsp), %r13
-	movq	STACKFRAME+16(%rsp), %r12
-.LcallUR2:
-	call	_Unwind_Resume@PLT
-	hlt
-.LENDCODE2:
-	cfi_endproc
-	.size	sem_timedwait_cleanup2,.-sem_timedwait_cleanup2
-#endif
-
-
-	.section .gcc_except_table,"a",@progbits
-.LexceptSTART:
-	.byte	DW_EH_PE_omit			# @LPStart format
-	.byte	DW_EH_PE_omit			# @TType format
-	.byte	DW_EH_PE_uleb128		# call-site format
-	.uleb128 .Lcstend-.Lcstbegin
-.Lcstbegin:
-	.uleb128 .LcleanupSTART-.LSTARTCODE
-	.uleb128 .LcleanupEND-.LcleanupSTART
-	.uleb128 sem_timedwait_cleanup-.LSTARTCODE
-	.uleb128  0
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
-	.uleb128 .LcleanupSTART2-.LSTARTCODE
-	.uleb128 .LcleanupEND2-.LcleanupSTART2
-	.uleb128 sem_timedwait_cleanup2-.LSTARTCODE
-	.uleb128  0
-#endif
-	.uleb128 .LcallUR-.LSTARTCODE
-	.uleb128 .LENDCODE-.LcallUR
-	.uleb128 0
-	.uleb128  0
-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
-	.uleb128 .LcallUR2-.LSTARTCODE
-	.uleb128 .LENDCODE2-.LcallUR2
-	.uleb128 0
-	.uleb128  0
-#endif
-.Lcstend:
-
-
-#ifdef SHARED
-	.hidden	DW.ref.__gcc_personality_v0
-	.weak	DW.ref.__gcc_personality_v0
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
-	.align	LP_SIZE
-	.type	DW.ref.__gcc_personality_v0, @object
-	.size	DW.ref.__gcc_personality_v0, LP_SIZE
-DW.ref.__gcc_personality_v0:
-	ASM_ADDR __gcc_personality_v0
-#endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S b/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
deleted file mode 100644
index 1838e96223..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <lowlevellock.h>
-#include <shlib-compat.h>
-#include <pthread-errnos.h>
-
-	.text
-
-	.globl	sem_trywait
-	.type	sem_trywait,@function
-	.align	16
-sem_trywait:
-	movl	(%rdi), %eax
-2:	testl	%eax, %eax
-	jz	1f
-
-	leal	-1(%rax), %edx
-	LOCK
-	cmpxchgl %edx, (%rdi)
-	jne	2b
-
-	xorl	%eax, %eax
-	retq
-
-1:
-	movq	errno@gottpoff(%rip), %rdx
-	movl	$EAGAIN, %fs:(%rdx)
-	orl	$-1, %eax
-	retq
-	.size	sem_trywait,.-sem_trywait
diff --git a/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
deleted file mode 100644
index 2e7b131923..0000000000
--- a/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-
-   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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <lowlevellock.h>
-#include <shlib-compat.h>
-#include <pthread-errnos.h>
-#include <structsem.h>
-
-
-	.text
-
-	.globl	sem_wait
-	.type	sem_wait,@function
-	.align	16
-sem_wait:
-.LSTARTCODE:
-	cfi_startproc
-#ifdef SHARED
-	cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
-			DW.ref.__gcc_personality_v0)
-	cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
-#else
-	cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
-	cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
-#endif
-
-#if VALUE == 0
-	movl	(%rdi), %eax
-#else
-	movl	VALUE(%rdi), %eax
-#endif
-2:	testl	%eax, %eax
-	je	1f
-
-	leal	-1(%rax), %edx
-	LOCK
-#if VALUE == 0
-	cmpxchgl %edx, (%rdi)
-#else
-	cmpxchgl %edx, VALUE(%rdi)
-#endif
-	jne	2b
-
-	xorl	%eax, %eax
-	retq
-
-	/* This push is only needed to store the sem_t pointer for the
-	   exception handler.  */
-1:	pushq	%rdi
-	cfi_adjust_cfa_offset(8)
-
-	LOCK
-	LP_OP(add) $1, NWAITERS(%rdi)
-
-.LcleanupSTART:
-6:	call	__pthread_enable_asynccancel
-	movl	%eax, %r8d
-
-	xorq	%r10, %r10
-	movl	$SYS_futex, %eax
-#if FUTEX_WAIT == 0
-	movl	PRIVATE(%rdi), %esi
-#else
-	movl	$FUTEX_WAIT, %esi
-	orl	PRIVATE(%rdi), %esi
-#endif
-	xorl	%edx, %edx
-	syscall
-	movq	%rax, %rcx
-
-	xchgq	%r8, %rdi
-	call	__pthread_disable_asynccancel
-.LcleanupEND:
-	movq	%r8, %rdi
-
-	testq	%rcx, %rcx
-	je	3f
-	cmpq	$-EWOULDBLOCK, %rcx
-	jne	4f
-
-3:
-#if VALUE == 0
-	movl	(%rdi), %eax
-#else
-	movl	VALUE(%rdi), %eax
-#endif
-5:	testl	%eax, %eax
-	je	6b
-
-	leal	-1(%rax), %edx
-	LOCK
-#if VALUE == 0
-	cmpxchgl %edx, (%rdi)
-#else
-	cmpxchgl %edx, VALUE(%rdi)
-#endif
-	jne	5b
-
-	xorl	%eax, %eax
-
-9:	LOCK
-	LP_OP(sub) $1, NWAITERS(%rdi)
-
-	leaq	8(%rsp), %rsp
-	cfi_adjust_cfa_offset(-8)
-
-	retq
-
-	cfi_adjust_cfa_offset(8)
-4:	negq	%rcx
-	movq	errno@gottpoff(%rip), %rdx
-	movl	%ecx, %fs:(%rdx)
-	orl	$-1, %eax
-
-	jmp 9b
-	.size	sem_wait,.-sem_wait
-
-
-	.type	sem_wait_cleanup,@function
-sem_wait_cleanup:
-	movq	(%rsp), %rdi
-	LOCK
-	LP_OP(sub) $1, NWAITERS(%rdi)
-	movq	%rax, %rdi
-.LcallUR:
-	call	_Unwind_Resume@PLT
-	hlt
-.LENDCODE:
-	cfi_endproc
-	.size	sem_wait_cleanup,.-sem_wait_cleanup
-
-
-	.section .gcc_except_table,"a",@progbits
-.LexceptSTART:
-	.byte	DW_EH_PE_omit			# @LPStart format
-	.byte	DW_EH_PE_omit			# @TType format
-	.byte	DW_EH_PE_uleb128		# call-site format
-	.uleb128 .Lcstend-.Lcstbegin
-.Lcstbegin:
-	.uleb128 .LcleanupSTART-.LSTARTCODE
-	.uleb128 .LcleanupEND-.LcleanupSTART
-	.uleb128 sem_wait_cleanup-.LSTARTCODE
-	.uleb128  0
-	.uleb128 .LcallUR-.LSTARTCODE
-	.uleb128 .LENDCODE-.LcallUR
-	.uleb128 0
-	.uleb128  0
-.Lcstend:
-
-
-#ifdef SHARED
-	.hidden	DW.ref.__gcc_personality_v0
-	.weak	DW.ref.__gcc_personality_v0
-	.section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
-	.align	LP_SIZE
-	.type	DW.ref.__gcc_personality_v0, @object
-	.size	DW.ref.__gcc_personality_v0, LP_SIZE
-DW.ref.__gcc_personality_v0:
-	ASM_ADDR __gcc_personality_v0
-#endif