Update.
authorUlrich Drepper <drepper@redhat.com>
Mon, 10 Feb 2003 09:24:12 +0000 (09:24 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 10 Feb 2003 09:24:12 +0000 (09:24 +0000)
2003-02-08  kaz Kojima  <kkojima@rr.iij4u.or.jp>

* sysdeps/sh/Makefile: New file.
* sysdeps/sh/bits/atomic.h: New file.
* sysdeps/sh/pthread_spin_init.c: New file.
* sysdeps/sh/pthread_spin_lock.c: New file.
* sysdeps/sh/pthread_spin_trylock.S: New file.
* sysdeps/sh/pthread_spin_unlock.S: New file.
* sysdeps/sh/pthreaddef.h: New file.
* sysdeps/sh/tcb-offsets.sym: New file.
* sysdeps/sh/td_ta_map_lwp2thr.c: New file.
* sysdeps/sh/tls.h: New file.
* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: New file.
* sysdeps/unix/sysv/linux/sh/bits/semaphore.h: New file.
* sysdeps/unix/sysv/linux/sh/createthread.c: New file.
* sysdeps/unix/sysv/linux/sh/fork.c: New file.
* sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: New file.
* sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S: New file.
* sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h: New file.
* sysdeps/unix/sysv/linux/sh/lowlevelcond.h: New file.
* sysdeps/unix/sysv/linux/sh/lowlevellock.S: New file.
* sysdeps/unix/sysv/linux/sh/lowlevellock.h: New file.
* sysdeps/unix/sysv/linux/sh/lowlevelmutex.S: New file.
* sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h: New file.
* sysdeps/unix/sysv/linux/sh/pt-initfini.c: New file.
* sysdeps/unix/sysv/linux/sh/pt-vfork.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_once.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: New file.
* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: New file.
* sysdeps/unix/sysv/linux/sh/sem_post.S: New file.
* sysdeps/unix/sysv/linux/sh/sem_timedwait.S: New file.
* sysdeps/unix/sysv/linux/sh/sem_trywait.S: New file.
* sysdeps/unix/sysv/linux/sh/sem_wait.S: New file.
* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: New file.

40 files changed:
nptl/ChangeLog
nptl/sysdeps/sh/bits/atomic.h [new file with mode: 0644]
nptl/sysdeps/sh/pthread_spin_init.c [new file with mode: 0644]
nptl/sysdeps/sh/pthread_spin_lock.c [new file with mode: 0644]
nptl/sysdeps/sh/pthread_spin_trylock.S [new file with mode: 0644]
nptl/sysdeps/sh/pthread_spin_unlock.S [new file with mode: 0644]
nptl/sysdeps/sh/pthreaddef.h [new file with mode: 0644]
nptl/sysdeps/sh/tcb-offsets.sym [new file with mode: 0644]
nptl/sysdeps/sh/td_ta_map_lwp2thr.c [new file with mode: 0644]
nptl/sysdeps/sh/tls.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/createthread.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/fork.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/lowlevelcond.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/lowlevelmutex.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/sem_post.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h [new file with mode: 0644]

index a21ecfb..51141e2 100644 (file)
@@ -1,3 +1,46 @@
+2003-02-08  kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/sh/Makefile: New file.
+       * sysdeps/sh/bits/atomic.h: New file.
+       * sysdeps/sh/pthread_spin_init.c: New file.
+       * sysdeps/sh/pthread_spin_lock.c: New file.
+       * sysdeps/sh/pthread_spin_trylock.S: New file.
+       * sysdeps/sh/pthread_spin_unlock.S: New file.
+       * sysdeps/sh/pthreaddef.h: New file.
+       * sysdeps/sh/tcb-offsets.sym: New file.
+       * sysdeps/sh/td_ta_map_lwp2thr.c: New file.
+       * sysdeps/sh/tls.h: New file.
+       * sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h: New file.
+       * sysdeps/unix/sysv/linux/sh/bits/semaphore.h: New file.
+       * sysdeps/unix/sysv/linux/sh/createthread.c: New file.
+       * sysdeps/unix/sysv/linux/sh/fork.c: New file.
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevelcond.h: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevelmutex.S: New file.
+       * sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h: New file.
+       * sysdeps/unix/sysv/linux/sh/pt-initfini.c: New file.
+       * sysdeps/unix/sysv/linux/sh/pt-vfork.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_once.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sem_post.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sem_trywait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sem_wait.S: New file.
+       * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: New file.
+
 2003-02-08  Ulrich Drepper  <drepper@redhat.com>
 
        * tst-cond2.c: Rearrange code to not rely on behavior undefined
diff --git a/nptl/sysdeps/sh/bits/atomic.h b/nptl/sysdeps/sh/bits/atomic.h
new file mode 100644 (file)
index 0000000..de176ca
--- /dev/null
@@ -0,0 +1,405 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdint.h>
+
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int16_t atomic16_t;
+typedef uint16_t uatomic16_t;
+typedef int_fast16_t atomic_fast16_t;
+typedef uint_fast16_t uatomic_fast16_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef int64_t atomic64_t;
+typedef uint64_t uatomic64_t;
+typedef int_fast64_t atomic_fast64_t;
+typedef uint_fast64_t uatomic_fast64_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+
+#define __arch_compare_and_exchange_8_acq(mem, newval, oldval) \
+  ({ unsigned char __result; \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+     0: mov.b @%1,r2\n\
+       cmp/eq r2,%3\n\
+       bf 1f\n\
+       mov.b %2,@%1\n\
+     1: mov r1,r15\n\
+       mov #-1,%0\n\
+       negc %0,%0"\
+       : "=r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     __result; })
+
+#define __arch_compare_and_exchange_16_acq(mem, newval, oldval) \
+  ({ unsigned char __result; \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+     0: mov.w @%1,r2\n\
+       cmp/eq r2,%3\n\
+       bf 1f\n\
+       mov.w %2,@%1\n\
+     1: mov r1,r15\n\
+       mov #-1,%0\n\
+       negc %0,%0"\
+       : "=r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     __result; })
+
+#define __arch_compare_and_exchange_32_acq(mem, newval, oldval) \
+  ({ unsigned char __result; \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+     0: mov.l @%1,r2\n\
+       cmp/eq r2,%3\n\
+       bf 1f\n\
+       mov.l %2,@%1\n\
+     1: mov r1,r15\n\
+       mov #-1,%0\n\
+       negc %0,%0"\
+       : "=r" (__result) : "r" (mem), "r" (newval), "r" (oldval) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     __result; })
+
+/* XXX We do not really need 64-bit compare-and-exchange.  At least
+   not in the moment.  Using it would mean causing portability
+   problems since not many other 32-bit architectures have support for
+   such an operation.  So don't define any code for now.  */
+
+# define __arch_compare_and_exchange_64_acq(mem, newval, oldval) \
+  (abort (), 0)
+
+#define atomic_exchange_and_add(mem, value) \
+  ({ __typeof (*mem) __result; \
+     if (sizeof (*mem) == 1) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.b @%2,%0\n\
+         add %0,%1\n\
+         mov.b %1,@%2\n\
+       1: mov r1,r15"\
+       : "=&r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "memory"); \
+     else if (sizeof (*mem) == 2) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.w @%2,%0\n\
+         add %0,%1\n\
+         mov.w %1,@%2\n\
+       1: mov r1,r15"\
+       : "=&r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "memory"); \
+     else if (sizeof (*mem) == 4) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.l @%2,%0\n\
+         add %0,%1\n\
+         mov.l %1,@%2\n\
+       1: mov r1,r15"\
+       : "=&r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "memory"); \
+     else \
+       { \
+        __typeof (value) addval = (value); \
+        __typeof (*mem) oldval; \
+        __typeof (mem) memp = (mem); \
+        do \
+          __result = (oldval = *memp) + addval; \
+        while (!__arch_compare_and_exchange_64_acq (memp, __result, oldval));\
+        (void) addval; \
+       } \
+     __result; })
+
+#define atomic_add(mem, value) \
+  (void) ({ if (sizeof (*mem) == 1) \
+             __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.b @%1,r2\n\
+               add r2,%0\n\
+               mov.b %0,@%1\n\
+            1: mov r1,r15"\
+               : "=&r" (value) : "r" (mem), "0" (value) \
+               : "r0", "r1", "r2", "memory"); \
+           else if (sizeof (*mem) == 2) \
+             __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.w @%1,r2\n\
+               add r2,%0\n\
+               mov.w %0,@%1\n\
+            1: mov r1,r15"\
+               : "=&r" (value) : "r" (mem), "0" (value) \
+               : "r0", "r1", "r2", "memory"); \
+           else if (sizeof (*mem) == 4) \
+             __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.l @%1,r2\n\
+               add r2,%0\n\
+               mov.l %0,@%1\n\
+            1: mov r1,r15"\
+               : "=&r" (value) : "r" (mem), "0" (value) \
+               : "r0", "r1", "r2", "memory"); \
+           else \
+             { \
+               __typeof (value) addval = (value); \
+               __typeof (*mem) oldval; \
+               __typeof (mem) memp = (mem); \
+               do \
+                 oldval = *memp; \
+               while (! __arch_compare_and_exchange_64_acq (memp, \
+                                                            oldval + addval, \
+                                                            oldval)); \
+               (void) addval; \
+             } \
+           })
+
+#define atomic_add_negative(mem, value) \
+  ({ unsigned char __result; \
+     if (sizeof (*mem) == 1) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.b @%2,r2\n\
+         add r2,%1\n\
+         mov.b %1,@%2\n\
+       1: mov r1,r15\n\
+         shal %1\n\
+         movt %0"\
+       : "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     else if (sizeof (*mem) == 2) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.w @%2,r2\n\
+         add r2,%1\n\
+         mov.w %1,@%2\n\
+       1: mov r1,r15\n\
+         shal %1\n\
+         movt %0"\
+       : "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     else if (sizeof (*mem) == 4) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.l @%2,r2\n\
+         add r2,%1\n\
+         mov.l %1,@%2\n\
+       1: mov r1,r15\n\
+         shal %1\n\
+         movt %0"\
+       : "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     else \
+       abort (); \
+     __result; })
+
+#define atomic_add_zero(mem, value) \
+  ({ unsigned char __result; \
+     if (sizeof (*mem) == 1) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.b @%2,r2\n\
+         add r2,%1\n\
+         mov.b %1,@%2\n\
+       1: mov r1,r15\n\
+         tst %1,%1\n\
+         movt %0"\
+       : "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     else if (sizeof (*mem) == 2) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.w @%2,r2\n\
+         add r2,%1\n\
+         mov.w %1,@%2\n\
+       1: mov r1,r15\n\
+         tst %1,%1\n\
+         movt %0"\
+       : "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     else if (sizeof (*mem) == 4) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         mov r15,r1\n\
+         mov #-6,r15\n\
+       0: mov.l @%2,r2\n\
+         add r2,%1\n\
+         mov.l %1,@%2\n\
+       1: mov r1,r15\n\
+         tst %1,%1\n\
+         movt %0"\
+       : "=r" (__result), "=&r" (value) : "r" (mem), "1" (value) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     else \
+       abort (); \
+     __result; })
+
+#define atomic_increment_and_test(mem) atomic_add_zero((mem), 1)
+#define atomic_decrement_and_test(mem) atomic_add_zero((mem), -1)
+
+#define atomic_bit_set(mem, bit) \
+  (void) ({ unsigned int __mask = 1 << (bit); \
+           if (sizeof (*mem) == 1) \
+             __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.b @%0,r2\n\
+               or %1,r2\n\
+               mov.b r2,@%0\n\
+            1: mov r1,r15"\
+               : : "r" (mem), "r" (__mask) \
+               : "r0", "r1", "r2", "memory"); \
+           else if (sizeof (*mem) == 2) \
+             __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.w @%0,r2\n\
+               or %1,r2\n\
+               mov.w r2,@%0\n\
+            1: mov r1,r15"\
+               : : "r" (mem), "r" (__mask) \
+               : "r0", "r1", "r2", "memory"); \
+           else if (sizeof (*mem) == 4) \
+             __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.l @%0,r2\n\
+               or %1,r2\n\
+               mov.l r2,@%0\n\
+            1: mov r1,r15"\
+               : : "r" (mem), "r" (__mask) \
+               : "r0", "r1", "r2", "memory"); \
+           else \
+             abort (); \
+           })
+
+#define atomic_bit_test_set(mem, bit) \
+  ({ unsigned int __mask = 1 << (bit); \
+     unsigned int __result = __mask; \
+     if (sizeof (*mem) == 1) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         nop\n\
+         mov r15,r1\n\
+         mov #-8,r15\n\
+       0: mov.b @%2,r2\n\
+         or r2,%1\n\
+         and r2,%0\n\
+         mov.b %1,@%2\n\
+       1: mov r1,r15"\
+       : "=&r" (__result), "=&r" (__mask) \
+       : "r" (mem), "0" (__result), "1" (__mask) \
+       : "r0", "r1", "r2", "memory"); \
+     else if (sizeof (*mem) == 2) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         nop\n\
+         mov r15,r1\n\
+         mov #-8,r15\n\
+       0: mov.w @%2,r2\n\
+         or r2,%1\n\
+         and r2,%0\n\
+         mov.w %1,@%2\n\
+       1: mov r1,r15"\
+       : "=&r" (__result), "=&r" (__mask) \
+       : "r" (mem), "0" (__result), "1" (__mask) \
+       : "r0", "r1", "r2", "memory"); \
+     else if (sizeof (*mem) == 4) \
+       __asm __volatile ("\
+         .align 2\n\
+         mova 1f,r0\n\
+         nop\n\
+         mov r15,r1\n\
+         mov #-8,r15\n\
+       0: mov.l @%2,r2\n\
+         or r2,%1\n\
+         and r2,%0\n\
+         mov.l %1,@%2\n\
+       1: mov r1,r15"\
+       : "=&r" (__result), "=&r" (__mask) \
+       : "r" (mem), "0" (__result), "1" (__mask) \
+       : "r0", "r1", "r2", "memory"); \
+     else \
+       abort (); \
+     __result; })
diff --git a/nptl/sysdeps/sh/pthread_spin_init.c b/nptl/sysdeps/sh/pthread_spin_init.c
new file mode 100644 (file)
index 0000000..0a47981
--- /dev/null
@@ -0,0 +1,20 @@
+/* Copyright (C) 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Not needed.  pthread_spin_init is an alias for pthread_spin_unlock.  */
diff --git a/nptl/sysdeps/sh/pthread_spin_lock.c b/nptl/sysdeps/sh/pthread_spin_lock.c
new file mode 100644 (file)
index 0000000..e732641
--- /dev/null
@@ -0,0 +1,35 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "pthreadP.h"
+
+int
+pthread_spin_lock (lock)
+     pthread_spinlock_t *lock;
+{
+  unsigned int val;
+
+  do
+    asm volatile ("tas.b @%1; movt %0"
+                 : "=&r" (val)
+                 : "r" (lock)
+                 : "memory");
+  while (val == 0);
+
+  return 0;
+}
diff --git a/nptl/sysdeps/sh/pthread_spin_trylock.S b/nptl/sysdeps/sh/pthread_spin_trylock.S
new file mode 100644 (file)
index 0000000..63ae4d3
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define EBUSY  16
+
+       .globl  pthread_spin_trylock
+       .type   pthread_spin_trylock,@function
+       .align  5
+pthread_spin_trylock:
+       tas.b   @r4
+       bf/s    1f
+        mov    #EBUSY, r0
+       mov     #0, r0
+1:
+       rts
+        nop
+       .size   pthread_spin_trylock,.-pthread_spin_trylock
diff --git a/nptl/sysdeps/sh/pthread_spin_unlock.S b/nptl/sysdeps/sh/pthread_spin_unlock.S
new file mode 100644 (file)
index 0000000..c77acaf
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+       .globl  pthread_spin_unlock
+       .type   pthread_spin_unlock,@function
+       .align  5
+pthread_spin_unlock:
+       mov     #0,r0
+       rts
+        mov.l  r0,@r4
+       .size   pthread_spin_unlock,.-pthread_spin_unlock
+
+       /* The implementation of pthread_spin_init is identical.  */
+       .globl  pthread_spin_init
+pthread_spin_init = pthread_spin_unlock
diff --git a/nptl/sysdeps/sh/pthreaddef.h b/nptl/sysdeps/sh/pthreaddef.h
new file mode 100644 (file)
index 0000000..c66e838
--- /dev/null
@@ -0,0 +1,52 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+/* Default stack size.  */
+#define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning.  */
+#define STACK_ALIGN            8
+
+/* Minimal stack size after allocating thread descriptor and guard size.  */
+#define MINIMAL_REST_STACK     2048
+
+/* Alignment requirement for TCB.  */
+#define TCB_ALIGNMENT          8
+
+/* The signal used for asynchronous cancelation.  */
+#define SIGCANCEL              __SIGRTMIN
+
+
+/* Location of current stack frame.  */
+#define CURRENT_STACK_FRAME    __builtin_frame_address (0)
+
+
+/* XXX Until we have a better place keep the definitions here.  */
+
+/* While there is no such syscall.  */
+#define __exit_thread_inline(val) \
+  while (1) {                                                                \
+    if (__builtin_constant_p (val) && (val) == 0)                            \
+      asm volatile ("mov #0,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD  \
+                  :: "i" (__NR_exit));  \
+    else                                                                     \
+      asm volatile ("mov %1,r4; mov %0,r3; trapa #0x11\n\t" SYSCALL_INST_PAD  \
+                   :: "i" (__NR_exit), "r" (val));                           \
+  }
diff --git a/nptl/sysdeps/sh/tcb-offsets.sym b/nptl/sysdeps/sh/tcb-offsets.sym
new file mode 100644 (file)
index 0000000..ae14fa0
--- /dev/null
@@ -0,0 +1,5 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET                offsetof (struct pthread, header.data.multiple_threads)
+TLS_PRE_TCB_SIZE               sizeof (struct pthread)
diff --git a/nptl/sysdeps/sh/td_ta_map_lwp2thr.c b/nptl/sysdeps/sh/td_ta_map_lwp2thr.c
new file mode 100644 (file)
index 0000000..7585300
--- /dev/null
@@ -0,0 +1,44 @@
+/* Which thread is running on an LWP?  Stub version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "thread_dbP.h"
+#include <tls.h>
+#include <sys/reg.h>
+
+
+td_err_e
+td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
+{
+  LOG ("td_ta_map_lwp2thr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  prgregset_t regs;
+  if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+    return TD_ERR;
+
+  th->th_unique = regs[REG_GBR];
+
+  /* Found it.  Now complete the `td_thrhandle_t' object.  */
+  th->th_ta_p = (td_thragent_t *) ta;
+
+  return TD_OK;
+}
diff --git a/nptl/sysdeps/sh/tls.h b/nptl/sysdeps/sh/tls.h
new file mode 100644 (file)
index 0000000..b92b0b8
--- /dev/null
@@ -0,0 +1,135 @@
+/* Definition for thread-local data handling.  NPTL/SH version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TLS_H
+#define _TLS_H
+
+# include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+
+/* We require TLS support in the tools.  */
+#ifndef HAVE_TLS_SUPPORT
+# error "TLS support is required."
+#endif
+
+/* Signal that TLS support is available.  */
+# define USE_TLS       1
+
+#ifndef __ASSEMBLER__
+
+/* Get system call information.  */
+# include <sysdep.h>
+
+/* Get the thread descriptor definition.  */
+# include <nptl/descr.h>
+
+/* This is the size of the initial TCB.  */
+# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+# define TLS_TCB_SIZE sizeof (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
+
+/* Alignment requirements for the TCB.  */
+# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+
+/* The TLS blocks start right after the TCB.  */
+# define TLS_DTV_AT_TP 1
+
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+# define INSTALL_DTV(tcbp, dtvp) \
+  ((tcbhead_t *) (tcbp))->dtv = dtvp + 1
+
+/* Install new dtv for current thread.  */
+# define INSTALL_NEW_DTV(dtv) \
+  ({ tcbhead_t *__tcbp;                                                              \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                        \
+     __tcbp->dtv = (dtv);})
+
+/* Return dtv of given thread descriptor.  */
+# define GET_DTV(tcbp) \
+  (((tcbhead_t *) (tcbp))->dtv)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+# define TLS_INIT_TP(tcbp, secondcall) \
+  ({ __asm __volatile ("ldc %0,gbr" : : "r" (tcbp)); 0; })
+
+/* Return the address of the dtv for the current thread.  */
+# define THREAD_DTV() \
+  ({ tcbhead_t *__tcbp;                                                              \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));                        \
+     __tcbp->dtv;})
+
+/* Return the thread descriptor for the current thread.
+   The contained asm must *not* be marked volatile since otherwise
+   assignments like
+        struct pthread *self = thread_self();
+   do not get optimized away.  */
+# define THREAD_SELF \
+  ({ struct pthread *__self;                                                 \
+     __asm ("stc gbr,%0" : "=r" (__self));                                   \
+     __self - 1;})
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) ((THREAD_SELF)->member)
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member, idx) ((THREAD_SELF)->member[idx])
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM(descr, member, value) \
+    (THREAD_SELF)->member = (value)
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+    (THREAD_SELF)->member[idx] = (value)
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
new file mode 100644 (file)
index 0000000..97b94a3
--- /dev/null
@@ -0,0 +1,152 @@
+/* Copyright (C) 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H   1
+
+#define __SIZEOF_PTHREAD_ATTR_T 36
+#define __SIZEOF_PTHREAD_MUTEX_T 24
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_COND_COMPAT_T 12
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 32
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+#define __SIZEOF_PTHREAD_BARRIER_T 20
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+
+
+/* Thread identifiers.  The structure of the attribute type is not
+   exposed on purpose.  */
+typedef struct __opaque_pthread *pthread_t;
+
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_ATTR_T];
+  long int __align;
+} pthread_attr_t;
+
+
+/* Data structures for mutex handling.  The structure of the attribute
+   type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __count;
+    struct pthread *__owner;
+    /* KIND must stay at this position in the structure to maintain
+       binary compatibility.  */
+    int __kind;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_MUTEX_T];
+  long int __align;
+} pthread_mutex_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+  long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling.  The structure of
+   the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned long long int __total_seq;
+    unsigned long long int __wakeup_seq;
+    unsigned long long int __woken_seq;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_COND_T];
+  long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+  long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#ifdef __USE_UNIX98
+/* Data structure for read-write lock variable handling.  The
+   structure of the attribute type is not exposed on purpose.  */
+typedef union
+{
+  struct
+  {
+    int __lock;
+    unsigned int __nr_readers;
+    unsigned int __readers_wakeup;
+    unsigned int __writer_wakeup;
+    unsigned int __nr_readers_queued;
+    unsigned int __nr_writers_queued;
+    /* FLAGS must stay at this position in the structure to maintain
+       binary compatibility.  */
+    unsigned int __flags;
+    pthread_t __writer;
+  } __data;
+  char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+  long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+  long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type.  */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type.  The structure of the type is
+   deliberately not exposed.  */
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIER_T];
+  long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+  int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h b/nptl/sysdeps/unix/sysv/linux/sh/bits/semaphore.h
new file mode 100644 (file)
index 0000000..ab46ac0
--- /dev/null
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+
+#define __SIZEOF_SEM_T 16
+
+
+/* Value returned if `sem_open' failed.  */
+#define SEM_FAILED      ((sem_t *) 0)
+
+/* Maximum value the semaphore can have.  */
+#define SEM_VALUE_MAX   ((int) ((~0u) >> 1))
+
+
+typedef union
+{
+  char __size[__SIZEOF_SEM_T];
+  long int __align;
+} sem_t;
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/createthread.c b/nptl/sysdeps/unix/sysv/linux/sh/createthread.c
new file mode 100644 (file)
index 0000000..8e68215
--- /dev/null
@@ -0,0 +1,24 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Value passed to 'clone' for initialization of the thread register.  */
+#define TLS_VALUE (pd + 1)
+
+
+/* Get the real implementation.  */
+#include <nptl/sysdeps/pthread/createthread.c>
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/fork.c b/nptl/sysdeps/unix/sysv/linux/sh/fork.c
new file mode 100644 (file)
index 0000000..6868b9b
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+/* TLS pointer argument is passed as the 5-th argument.  */
+#define ARCH_FORK() \
+  INLINE_SYSCALL (clone, 5,                                                  \
+                 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,     \
+                 NULL, &THREAD_SELF->tid, NULL)
+
+#include "../fork.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevellock.S
new file mode 100644 (file)
index 0000000..350a935
--- /dev/null
@@ -0,0 +1,221 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#include "lowlevel-atomic.h"
+
+       .text
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define ETIMEDOUT               110
+
+
+       .globl  __lll_lock_wait
+       .type   __lll_lock_wait,@function
+       .hidden __lll_lock_wait
+       .align  5
+__lll_lock_wait:
+       mov     r4, r6
+       mov     r5, r4
+       mov     #0, r7          /* No timeout.  */
+       mov     #FUTEX_WAIT, r5
+2:
+       add     #-1, r6         /* account for the preceeded xadd.  */
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     #-1, r3
+       XADD (r3, @r4, r2)
+       tst     r3, r3
+       bf/s    2b
+        mov    r2, r6
+
+       mov     #-1, r1
+       mov.l   r1, @r4
+       rts
+        mov    r2, r0
+       .size   __lll_lock_wait,.-__lll_lock_wait
+
+
+       .type   lll_unlock_wake_cb,@function
+       .align  5
+lll_unlock_wake_cb:
+
+       .align  2
+       mova    1f, r0
+       mov     r15, r1
+       mov     #-6, r15
+0:
+       mov.l   @r4, r2
+       add     #1, r2
+       mov.l   r2, @r4
+1:
+       mov     r1, r15
+       cmp/pl  r2
+       bf      2f
+       rts
+        nop
+       .size   lll_unlock_wake_cb,.-lll_unlock_wake_cb
+
+
+       .globl  __lll_unlock_wake
+       .type   __lll_unlock_wake,@function
+       .hidden __lll_unlock_wake
+__lll_unlock_wake:
+2:
+       mov     #FUTEX_WAKE, r5
+       mov     #1, r6          /* Wake one thread.  */
+       mov     #0, r7
+       mov.l   r6, @r4         /* Stores 1.  */
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       rts
+        nop
+       .size   __lll_unlock_wake,.-__lll_unlock_wake
+
+
+       .globl  __lll_wait_tid
+       .type   __lll_wait_tid,@function
+       .hidden __lll_wait_tid
+__lll_wait_tid:
+       mov.l   @r4, r6
+1:
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     r0, r1
+
+       mov.l   @r4, r0
+       tst     r0, r0
+       bf/s    1b
+        mov    r0, r6
+       rts
+        nop
+       .size   __lll_wait_tid,.-__lll_wait_tid
+
+       
+       .globl  __lll_timedwait_tid
+       .type   __lll_timedwait_tid,@function
+       .hidden __lll_timedwait_tid
+__lll_timedwait_tid:
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       mov     r4, r8
+       mov     r5, r9
+       add     #-8, r15
+
+2:
+       /* Get current time.  */
+       mov     r15, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       /* Compute relative timeout.  */
+       mov.l   @(4,r15), r0
+       mov.w   .L1k, r1
+       dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
+       mov.l   @r9, r2
+       mov.l   @(4,r9), r3
+       mov.l   @r15, r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      5f
+       mov.l   .L1g, r1
+       add     r1, r3
+       add     #-1, r2
+5:
+       cmp/pz  r2
+       bf      6f              /* Time is already up.  */
+
+       mov.l   r2, @r15        /* Store relative timeout.  */
+       mov.l   r3, @(4,r15)
+
+       mov.l   @r8, r6
+       tst     r6, r6
+       bt      4f
+
+       mov     r8, r4
+       mov     #FUTEX_WAIT, r5
+       mov     r15, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     r0, r1
+
+       mov.l   @r8, r0
+       tst     r0, r0
+       bf      1f
+4:
+       mov     #0, r0
+3:
+       add     #8, r15
+       mov.l   @r15+, r8
+       rts
+        mov.l  @r15+, r9
+
+1:
+       mov     #-ETIMEDOUT, r1
+       cmp/eq  r0, r1
+       bf      2b
+6:
+       bra     3b
+        mov    #ETIMEDOUT, r0
+
+.L1k:
+       .word   1000
+       .align  2
+.L1g:
+       .long   1000000000
+
+       .size   __lll_timedwait_tid,.-__lll_timedwait_tid
+
+
+       .globl  __lll_wake_tid
+       .type   __lll_wake_tid,@function
+       .hidden __lll_wake_tid
+__lll_wake_tid:
+       mov     #FUTEX_WAKE, r5
+       mov     #-1, r6
+       shlr    r6              /* r6 = 0x7fffffff */
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       rts
+        nop
+       .size   __lll_wake_tid,.-__lll_wake_tid
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/sh/libc-lowlevelmutex.S
new file mode 100644 (file)
index 0000000..8a837de
--- /dev/null
@@ -0,0 +1,174 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "lowlevel-atomic.h"
+
+       .text
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EWOULDBLOCK            11
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+
+       .globl  __lll_mutex_lock_wait
+       .type   __lll_mutex_lock_wait,@function
+       .hidden __lll_mutex_lock_wait
+       .align  5
+__lll_mutex_lock_wait:
+       mov     r4, r6
+       mov     r5, r4
+       mov     #0, r7          /* No timeout.  */
+       mov     #FUTEX_WAIT, r5
+1:
+       add     #1, r6          /* account for the preceeded xadd.  */
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     #1, r3
+       XADD (r3, @r4, r6)
+       tst     r6, r6
+       bf      1b
+       mov     #2, r1
+       mov.l   r1, @r4
+       ret
+        mov    #0, r0
+       .size   __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
+
+
+       .globl  __lll_mutex_timedlock_wait
+       .type   __lll_mutex_timedlock_wait,@function
+       .hidden __lll_mutex_timedlock_wait
+       .align  5
+__lll_mutex_timedlock_wait:
+       /* Check for a valid timeout value.  */
+       mov.l   @(4,r6), r1
+       mov.l   .L1g, r0
+       cmp/hs  r0, r1
+       bt      3f
+
+       mov.l   r10, @-r15
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       mov     r5, r8
+       mov     r6, r9
+       mov     r4, r10
+       add     #1, r10
+
+       /* Stack frame for the timespec and timeval structs.  */
+       add     #-8, r15
+
+1:
+       /* Get current time.  */
+       mov     r15, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       /* Compute relative timeout.  */
+       mov.l   @(4,r15), r0
+       mov.w   .L1k, r1
+       dmulu.l r0, r1          /* Micro seconds to nano seconds.  */
+       mov.l   @r9, r2
+       mov.l   @(4,r9), r3
+       mov.l   @r15, r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      4f
+       mov.l   .L1g, r1
+       add     r1, r3
+       add     #-1, r2
+4:
+       cmp/pz  r2
+       bf      5f              /* Time is already up.  */
+
+       mov.l   r2, @r15        /* Store relative timeout.  */
+       mov.l   r3, @(4,r15)
+
+       mov     r8, r4
+       mov     #FUTEX_WAIT, r5
+       mov     r10, r6
+       mov     r15, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     #1, r3
+       XADD (r3, @r8, r10)
+       tst     r10, r10
+       bf      7f
+
+       mov     #2, r1
+       mov.l   r1, @r8
+       mov     #0, r0
+6:
+       add     #8, r15
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       rts
+        mov.l  @r15+, r10
+7:
+       /* Check whether the time expired.  */
+       mov     #-ETIMEDOUT, r1
+       cmp/eq  r0, r1
+       bt      5f
+       bra     1b
+        nop
+3:
+       rts
+        mov    #EINVAL, r0
+5:
+       bra     6b
+        mov    #ETIMEDOUT, r0
+
+.L1k:
+       .word   1000
+       .align  2
+.L1g:
+       .long   1000000000
+
+       .size   __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
+
+
+       .globl  __lll_mutex_unlock_wake
+       .type   __lll_mutex_unlock_wake,@function
+       .hidden __lll_mutex_unlock_wake
+       .align  5
+__lll_mutex_unlock_wake:
+       mov     #FUTEX_WAKE, r5
+       mov     #1, r6          /* Wake one thread.  */
+       mov     #0, r7
+       mov.l   r7, @r4         /* Stores 0.  */
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       rts
+        nop
+       .size   __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevel-atomic.h
new file mode 100644 (file)
index 0000000..3a80ec8
--- /dev/null
@@ -0,0 +1,68 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifdef __ASSEMBLER__
+
+#define _IMP1 #1
+#define _IMM1 #-1
+#define _IMM6 #-6
+#define _IMM8 #-8
+
+#define        INC(mem, reg) \
+       .align  2; \
+       mova    99f, r0; \
+       mov     r15, r1; \
+       mov     _IMM6, r15; \
+98:    mov.l   mem, reg; \
+       add     _IMP1, reg; \
+       mov.l   reg, mem; \
+99:    mov     r1, r15
+
+#define        DEC(mem, reg) \
+       .align  2; \
+       mova    99f, r0; \
+       mov     r15, r1; \
+       mov     _IMM6, r15; \
+98:    mov.l   mem, reg; \
+       add     _IMM1, reg; \
+       mov.l   reg, mem; \
+99:    mov     r1, r15
+
+#define        XADD(reg, mem, old) \
+       .align  2; \
+       mova    99f, r0; \
+       mov     r15, r1; \
+       mov     _IMM6, r15; \
+98:    mov.l   mem, old; \
+       add     old, reg; \
+       mov.l   reg, mem; \
+99:    mov     r1, r15
+
+#define        CMPXCHG(reg, mem, new, old) \
+       .align  2; \
+       mova    99f, r0; \
+       nop; \
+       mov     r15, r1; \
+       mov     _IMM8, r15; \
+98:    mov.l   mem, old; \
+       cmp/eq  old, reg; \
+       bf      99f; \
+       mov.l   new, mem; \
+99:    mov     r1, r15
+
+#endif  /* __ASSEMBLER__ */
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelcond.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelcond.h
new file mode 100644 (file)
index 0000000..78e585f
--- /dev/null
@@ -0,0 +1,23 @@
+/* Copyright (C) 2002, 2003 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define cond_lock      0
+#define total_seq      4
+#define wakeup_seq     12
+#define woken_seq      20
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
new file mode 100644 (file)
index 0000000..8352ef0
--- /dev/null
@@ -0,0 +1,224 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "lowlevel-atomic.h"
+
+       .text
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define ETIMEDOUT               110
+
+
+       .globl  __lll_lock_wait
+       .type   __lll_lock_wait,@function
+       .hidden __lll_lock_wait
+       .align  5
+__lll_lock_wait:
+       mov     r4, r6
+       mov     r5, r4
+       mov     #0, r7          /* No timeout.  */
+       mov     #FUTEX_WAIT, r5
+2:
+       add     #-1, r6         /* account for the preceeded xadd.  */
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     #-1, r3
+       XADD (r3, @r4, r2)
+       tst     r3, r3
+       bf/s    2b
+        mov    r2, r6
+
+       mov     #-1, r1
+       mov.l   r1, @r4
+       rts
+        mov    r2, r0
+       .size   __lll_lock_wait,.-__lll_lock_wait
+
+
+       .globl  lll_unlock_wake_cb
+       .type   lll_unlock_wake_cb,@function
+       .hidden lll_unlock_wake_cb
+       .align  5
+lll_unlock_wake_cb:
+
+       .align  2
+       mova    1f, r0
+       mov     r15, r1
+       mov     #-6, r15
+0:
+       mov.l   @r4, r2
+       add     #1, r2
+       mov.l   r2, @r4
+1:
+       mov     r1, r15
+       cmp/pl  r2
+       bf      2f
+       rts
+        nop
+       .size   lll_unlock_wake_cb,.-lll_unlock_wake_cb
+
+
+       .globl  __lll_unlock_wake
+       .type   __lll_unlock_wake,@function
+       .hidden __lll_unlock_wake
+__lll_unlock_wake:
+2:
+       mov     #FUTEX_WAKE, r5
+       mov     #1, r6          /* Wake one thread.  */
+       mov     #0, r7
+       mov.l   r6, @r4         /* Stores 1.  */
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       rts
+        nop
+       .size   __lll_unlock_wake,.-__lll_unlock_wake
+
+
+       .globl  __lll_wait_tid
+       .type   __lll_wait_tid,@function
+       .hidden __lll_wait_tid
+__lll_wait_tid:
+       mov.l   @r4, r6
+1:
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     r0, r1
+
+       mov.l   @r4, r0
+       tst     r0, r0
+       bf/s    1b
+        mov    r0, r6
+       rts
+        nop
+       .size   __lll_wait_tid,.-__lll_wait_tid
+
+       
+       .globl  __lll_timedwait_tid
+       .type   __lll_timedwait_tid,@function
+       .hidden __lll_timedwait_tid
+__lll_timedwait_tid:
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       mov     r4, r8
+       mov     r5, r9
+       add     #-8, r15
+
+2:
+       /* Get current time.  */
+       mov     r15, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       /* Compute relative timeout.  */
+       mov.l   @(4,r15), r0
+       mov.w   .L1k, r1
+       dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
+       mov.l   @r9, r2
+       mov.l   @(4,r9), r3
+       mov.l   @r15, r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      5f
+       mov.l   .L1g, r1
+       add     r1, r3
+       add     #-1, r2
+5:
+       cmp/pz  r2
+       bf      6f              /* Time is already up.  */
+
+       mov.l   r2, @r15        /* Store relative timeout.  */
+       mov.l   r3, @(4,r15)
+
+       mov.l   @r8, r6
+       tst     r6, r6
+       bt      4f
+
+       mov     r8, r4
+       mov     #FUTEX_WAIT, r5
+       mov     r15, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     r0, r1
+
+       mov.l   @r8, r0
+       tst     r0, r0
+       bf      1f
+4:
+       mov     #0, r0
+3:
+       add     #8, r15
+       mov.l   @r15+, r8
+       rts
+        mov.l  @r15+, r9
+
+1:
+       mov     #-ETIMEDOUT, r1
+       cmp/eq  r0, r1
+       bf      2b
+6:
+       bra     3b
+        mov    #ETIMEDOUT, r0
+
+.L1k:
+       .word   1000
+       .align  2
+.L1g:
+       .long   1000000000
+
+       .size   __lll_timedwait_tid,.-__lll_timedwait_tid
+
+
+       .globl  __lll_wake_tid
+       .type   __lll_wake_tid,@function
+       .hidden __lll_wake_tid
+__lll_wake_tid:
+       mov     #FUTEX_WAKE, r5
+       mov     #-1, r6
+       shlr    r6              /* r6 = 0x7fffffff */
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       rts
+        nop
+       .size   __lll_wake_tid,.-__lll_wake_tid
+
+
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
new file mode 100644 (file)
index 0000000..d9a69c7
--- /dev/null
@@ -0,0 +1,245 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H        1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+
+/* Initializer for compatibility lock.  */
+#define LLL_MUTEX_LOCK_INITIALIZER (0)
+
+extern int __lll_mutex_lock_wait (int val, int *__futex) attribute_hidden;
+extern int __lll_mutex_timedlock_wait (int val, int *__futex,
+                                      const struct timespec *abstime)
+     attribute_hidden;
+extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
+
+
+#define lll_mutex_trylock(futex) \
+  ({ unsigned char __result; \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+     0: mov.l @%1,r2\n\
+       cmp/eq r2,%3\n\
+       bf 1f\n\
+       mov.l %2,@%1\n\
+     1: mov r1,r15\n\
+       mov #-1,%0\n\
+       negc %0,%0"\
+       : "=r" (__result) : "r" (&(futex)), "r" (1), "r" (0) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     __result; })
+
+#define lll_mutex_lock(futex) \
+  (void) ({ int __result, val, *__futex = &(futex); \
+           __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.l @%2,%0\n\
+               add %0,%1\n\
+               mov.l %1,@%2\n\
+            1: mov r1,r15"\
+               : "=&r" (__result), "=&r" (val) : "r" (__futex), "1" (1) \
+               : "r0", "r1", "memory"); \
+           if (__result) \
+             __lll_mutex_lock_wait (__result, __futex); })
+
+#define lll_mutex_timedlock(futex, timeout) \
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       mov r15,r1\n\
+       mov #-6,r15\n\
+     0: mov.l @%2,%0\n\
+       add %0,%1\n\
+       mov.l %1,@%2\n\
+     1: mov r1,r15"\
+       : "=&r" (__result), "=&r" (val) : "r" (__futex), "1" (1) \
+       : "r0", "r1", "memory"); \
+    if (__result) \
+      __result = __lll_mutex_timedlock_wait (__result, __futex, timeout); \
+    __result; })
+
+#define lll_mutex_unlock(futex) \
+  (void) ({ int __result, *__futex = &(futex); \
+           __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.l @%1,%0\n\
+               add #-1,%0\n\
+               mov.l %0,@%1\n\
+            1: mov r1,r15"\
+               : "=&r" (__result) : "r" (__futex) \
+               : "r0", "r1", "memory"); \
+           if (__result) \
+             __lll_mutex_unlock_wake (__futex); })
+
+#define lll_mutex_islocked(futex) \
+  (futex != 0)
+
+
+/* We have a separate internal lock implementation which is not tied
+   to binary compatibility.  */
+
+/* Type for lock object.  */
+typedef int lll_lock_t;
+
+/* Initializers for lock.  */
+#define LLL_LOCK_INITIALIZER           (1)
+#define LLL_LOCK_INITIALIZER_LOCKED    (0)
+
+
+extern int __lll_lock_wait (int val, int *__futex) attribute_hidden;
+extern int __lll_unlock_wake (int *__futex) attribute_hidden;
+extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
+
+
+/* The states of a lock are:
+    1  -  untaken
+    0  -  taken by one user
+   <0  -  taken by more users */
+
+
+#define lll_trylock(futex) \
+  ({ unsigned char __result; \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+     0: mov.l @%1,r2\n\
+       cmp/eq r2,%3\n\
+       bf 1f\n\
+       mov.l %2,@%1\n\
+     1: mov r1,r15\n\
+       mov #-1,%0\n\
+       negc %0,%0"\
+       : "=r" (__result) : "r" (&(futex)), "r" (0), "r" (1) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     __result; })
+
+#define lll_lock(futex) \
+  (void) ({ int __result, val, *__futex = &(futex); \
+           __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.l @%2,%0\n\
+               add %0,%1\n\
+               mov.l %1,@%2\n\
+            1: mov r1,r15"\
+               : "=&r" (__result), "=&r" (val) : "r" (__futex), "1" (-1) \
+               : "r0", "r1", "memory"); \
+           if (val < 0) \
+             __lll_lock_wait (__result, __futex); })
+
+#define lll_unlock(futex) \
+  (void) ({ int __result, *__futex = &(futex); \
+           __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.l @%1,%0\n\
+               add #1,%0\n\
+               mov.l %0,@%1\n\
+            1: mov r1,r15"\
+               : "=&r" (__result) : "r" (__futex) \
+               : "r0", "r1", "memory"); \
+           if (__result <= 0) \
+             __lll_unlock_wake (__futex); })
+
+#define lll_islocked(futex) \
+  (futex <= 0)
+
+
+/* The kernel notifies a process with uses CLONE_CLEARTID via futex
+   wakeup when the clone terminates.  The memory location contains the
+   thread ID while the clone is running and is reset to zero
+   afterwards.  */
+
+extern int __lll_wait_tid (int *tid) attribute_hidden;
+#define lll_wait_tid(tid) \
+  do { \
+    __typeof (tid) *__tid = &(tid); \
+    if (*__tid != 0) \
+      __lll_wait_tid (__tid); \
+  } while (0)
+
+extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
+     attribute_hidden;
+#define lll_timedwait_tid(tid, abstime) \
+  ({ \
+    int __result = 0; \
+    if (tid != 0) \
+      {        \
+       if (abstime == NULL || abstime->tv_nsec >= 1000000000) \
+         __result = EINVAL; \
+       else \
+         __result = __lll_timedwait_tid (&tid, abstime); \
+      }        \
+    __result; })
+
+
+extern int __lll_wake_tid (int *tid) attribute_hidden;
+#define lll_wake_tid(tid) \
+  do { \
+    (tid) = 0; \
+    ___lll_wake_tid (&tid); \
+  } while (0)
+
+
+/* Conditional variable handling.  */
+
+extern void __lll_cond_wait (pthread_cond_t *cond) attribute_hidden;
+extern int __lll_cond_timedwait (pthread_cond_t *cond,
+                                const struct timespec *abstime)
+     attribute_hidden;
+extern void __lll_cond_wake (pthread_cond_t *cond) attribute_hidden;
+extern void __lll_cond_broadcast (pthread_cond_t *cond) attribute_hidden;
+
+
+#define lll_cond_wait(cond) \
+  __lll_cond_wait (cond)
+#define lll_cond_timedwait(cond, abstime) \
+  __lll_cond_timedwait (cond, abstime)
+#define lll_cond_wake(cond) \
+  __lll_cond_wake (cond)
+#define lll_cond_broadcast(cond) \
+  __lll_cond_broadcast (cond)
+
+#endif  /* lowlevellock.h */
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelmutex.S
new file mode 100644 (file)
index 0000000..8a837de
--- /dev/null
@@ -0,0 +1,174 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "lowlevel-atomic.h"
+
+       .text
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EWOULDBLOCK            11
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+
+       .globl  __lll_mutex_lock_wait
+       .type   __lll_mutex_lock_wait,@function
+       .hidden __lll_mutex_lock_wait
+       .align  5
+__lll_mutex_lock_wait:
+       mov     r4, r6
+       mov     r5, r4
+       mov     #0, r7          /* No timeout.  */
+       mov     #FUTEX_WAIT, r5
+1:
+       add     #1, r6          /* account for the preceeded xadd.  */
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     #1, r3
+       XADD (r3, @r4, r6)
+       tst     r6, r6
+       bf      1b
+       mov     #2, r1
+       mov.l   r1, @r4
+       ret
+        mov    #0, r0
+       .size   __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
+
+
+       .globl  __lll_mutex_timedlock_wait
+       .type   __lll_mutex_timedlock_wait,@function
+       .hidden __lll_mutex_timedlock_wait
+       .align  5
+__lll_mutex_timedlock_wait:
+       /* Check for a valid timeout value.  */
+       mov.l   @(4,r6), r1
+       mov.l   .L1g, r0
+       cmp/hs  r0, r1
+       bt      3f
+
+       mov.l   r10, @-r15
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       mov     r5, r8
+       mov     r6, r9
+       mov     r4, r10
+       add     #1, r10
+
+       /* Stack frame for the timespec and timeval structs.  */
+       add     #-8, r15
+
+1:
+       /* Get current time.  */
+       mov     r15, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       /* Compute relative timeout.  */
+       mov.l   @(4,r15), r0
+       mov.w   .L1k, r1
+       dmulu.l r0, r1          /* Micro seconds to nano seconds.  */
+       mov.l   @r9, r2
+       mov.l   @(4,r9), r3
+       mov.l   @r15, r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      4f
+       mov.l   .L1g, r1
+       add     r1, r3
+       add     #-1, r2
+4:
+       cmp/pz  r2
+       bf      5f              /* Time is already up.  */
+
+       mov.l   r2, @r15        /* Store relative timeout.  */
+       mov.l   r3, @(4,r15)
+
+       mov     r8, r4
+       mov     #FUTEX_WAIT, r5
+       mov     r10, r6
+       mov     r15, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov     #1, r3
+       XADD (r3, @r8, r10)
+       tst     r10, r10
+       bf      7f
+
+       mov     #2, r1
+       mov.l   r1, @r8
+       mov     #0, r0
+6:
+       add     #8, r15
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       rts
+        mov.l  @r15+, r10
+7:
+       /* Check whether the time expired.  */
+       mov     #-ETIMEDOUT, r1
+       cmp/eq  r0, r1
+       bt      5f
+       bra     1b
+        nop
+3:
+       rts
+        mov    #EINVAL, r0
+5:
+       bra     6b
+        mov    #ETIMEDOUT, r0
+
+.L1k:
+       .word   1000
+       .align  2
+.L1g:
+       .long   1000000000
+
+       .size   __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
+
+
+       .globl  __lll_mutex_unlock_wake
+       .type   __lll_mutex_unlock_wake,@function
+       .hidden __lll_mutex_unlock_wake
+       .align  5
+__lll_mutex_unlock_wake:
+       mov     #FUTEX_WAKE, r5
+       mov     #1, r6          /* Wake one thread.  */
+       mov     #0, r7
+       mov.l   r7, @r4         /* Stores 0.  */
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       rts
+        nop
+       .size   __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrwlock.h
new file mode 100644 (file)
index 0000000..4357e80
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright (C) 2002, 2003 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Offsets in the pthread_rwlock_t structure.  */
+#define MUTEX          0
+#define NR_READERS     4
+#define READERS_WAKEUP 8
+#define WRITERS_WAKEUP 12
+#define READERS_QUEUED 16
+#define WRITERS_QUEUED 20
+#define FLAGS          24
+#define WRITER 28
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c b/nptl/sysdeps/unix/sysv/linux/sh/pt-initfini.c
new file mode 100644 (file)
index 0000000..5391d5c
--- /dev/null
@@ -0,0 +1,143 @@
+/* Special .init and .fini section support for SH. NPTL version.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it
+   and/or modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Library General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Library General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   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 Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This file is compiled into assembly code which is then munged by a sed
+   script into two files: crti.s and crtn.s.
+
+   * crti.s puts a function prologue at the beginning of the
+   .init and .fini sections and defines global symbols for
+   those addresses, so they can be called as functions.
+
+   * crtn.s puts the corresponding function epilogues
+   in the .init and .fini sections. */
+
+__asm__ ("\n\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@TESTS_BEGIN*/\n\
+\n\
+/*@TESTS_END*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+       .section .init\n\
+       .align 5\n\
+       .global _init\n\
+       .type   _init,@function\n\
+_init:\n\
+       mov.l   r12,@-r15\n\
+       mov.l   r14,@-r15\n\
+       sts.l   pr,@-r15\n\
+       mova    .L22,r0\n\
+       mov.l   .L22,r12\n\
+       add     r0,r12\n\
+       mova    .L24,r0\n\
+       mov.l   .L24,r1\n\
+       add     r0,r1\n\
+       jsr     @r1\n\
+        nop\n\
+       mova    .L23,r0\n\
+       mov.l   .L23,r1\n\
+       add     r0,r1\n\
+       jsr     @r1\n\
+        mov    r15,r14\n\
+       bra     1f\n\
+        nop\n\
+       .align 2\n\
+.L22:\n\
+       .long   _GLOBAL_OFFSET_TABLE_\n\
+.L23:\n\
+       .long   __gmon_start__@PLT\n\
+.L24:\n\
+       .long   __pthread_initialize_minimal_internal@PLT\n\
+1:\n\
+       ALIGN\n\
+       END_INIT\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+       .section .init\n\
+       mov     r14,r15\n\
+       lds.l   @r15+,pr\n\
+       mov.l   @r15+,r14\n\
+       rts     \n\
+       mov.l   @r15+,r12\n\
+       END_INIT\n\
+       .section .text\n\
+       .align 5\n\
+       .weak   __gmon_start__\n\
+       .type   __gmon_start__,@function\n\
+__gmon_start__:\n\
+       mov.l   r14,@-r15\n\
+       mov     r15,r14\n\
+       mov     r14,r15\n\
+       rts     \n\
+       mov.l   @r15+,r14\n\
+       \n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+       .section .fini\n\
+       .align 5\n\
+       .global _fini\n\
+       .type   _fini,@function\n\
+_fini:\n\
+       mov.l   r12,@-r15\n\
+       mov.l   r14,@-r15\n\
+       sts.l   pr,@-r15\n\
+       mova    .L27,r0\n\
+       mov.l   .L27,r12\n\
+       add     r0,r12\n\
+       mov     r15,r14\n\
+       ALIGN\n\
+       END_FINI\n\
+       bra     1f\n\
+        nop\n\
+       .align  2\n\
+.L27:\n\
+       .long   _GLOBAL_OFFSET_TABLE_\n\
+1:\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+       .section .fini\n\
+       mov     r14,r15\n\
+       lds.l   @r15+,pr\n\
+       mov.l   @r15+,r14\n\
+       rts     \n\
+       mov.l   @r15+,r12\n\
+\n\
+       END_FINI\n\
+       \n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\n\
+");
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S b/nptl/sysdeps/unix/sysv/linux/sh/pt-vfork.S
new file mode 100644 (file)
index 0000000..5b13639
--- /dev/null
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/sh/vfork.S>
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_barrier_wait.S
new file mode 100644 (file)
index 0000000..eead7c6
--- /dev/null
@@ -0,0 +1,164 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_futex      240
+#define FUTEX_WAIT     0
+#define FUTEX_WAKE     1
+
+#define CURR_EVENT     0
+#define MUTEX          4
+#define LEFT           8
+#define        INIT_COUNT      12
+
+
+       .text
+
+       .globl  pthread_barrier_wait
+       .type   pthread_barrier_wait,@function
+       .align  5
+pthread_barrier_wait:
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+
+       /* Get the mutex.  */
+       mov     #-1, r3
+       XADD (r3, @(MUTEX,r8), r2)
+       tst     r3, r3
+       bf      1f
+
+       /* One less waiter.  If this was the last one needed wake
+          everybody.  */
+2:
+       mov.l   @(LEFT,r8), r0
+       add     #-1, r0
+       mov.l   r0, @(LEFT,r8)
+       tst     r0, r0
+       bt      3f
+
+       /* There are more threads to come.  */
+       mov.l   @(CURR_EVENT,r8), r6
+
+       /* Release the mutex.  */
+       INC (@(MUTEX,r8), r2)
+       cmp/pl  r2
+       bf      6f
+7:
+       /* Wait for the remaining threads.  The call will return immediately
+          if the CURR_EVENT memory has meanwhile been changed.  */
+       mov     r8, r4
+#if CURR_EVENT != 0
+       add     #CURR_EVENT, r4
+#endif
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r7
+8:
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       /* Don't return on spurious wakeups.  The syscall does not change
+          any register except r0 so there is no need to reload any of
+          them.  */
+       mov.l   @(CURR_EVENT,r8), r0
+       cmp/eq  r0, r6
+       bt      8b
+
+       mov     #0, r0          /* != PTHREAD_BARRIER_SERIAL_THREAD */
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       rts
+        mov.l  @r15+, r9
+
+3:     
+       /* The necessary number of threads arrived.  */
+       mov.l   @(INIT_COUNT,r8), r0
+       mov.l   r0, @(LEFT,r8)
+       mov.l   @(CURR_EVENT,r8), r1
+       add     #1, r1
+       mov.l   r1, @(CURR_EVENT,r8)
+
+       /* Wake up all waiters.  The count is a signed number in the kernel
+          so 0x7fffffff is the highest value.  */
+       mov.l   .Lall, r6
+       mov     r8, r4
+#if CURR_EVENT != 0
+       add     #CURR_EVENT, r4
+#endif
+       mov     #0, r7
+       mov     #FUTEX_WAKE, r5
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       /* Release the mutex.  */
+       INC (@(MUTEX,r8), r2)
+       cmp/pl  r2
+       bf      4f
+5:
+       mov     #-1, r0         /* == PTHREAD_BARRIER_SERIAL_THREAD */
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       ret
+        mov.l  @r15+, r9
+
+1:
+       mov     r2, r4
+       mov     r8, r5
+       mov.l   .Lwait0, r1
+       bsrf    r1
+        add    #MUTEX, r5
+.Lwait0b:
+       bra     2b
+        nop
+
+4:
+       mov     r8, r4
+       mov.l   .Lwake0, r1
+       bsrf    r1
+        add    #MUTEX, r4
+.Lwake0b:
+       bra     5b
+        nop
+
+6:
+       mov     r6, r9
+       mov     r8, r4
+       mov.l   .Lwake1, r1
+       bsrf    r1
+        add    #MUTEX, r4
+.Lwake1b:
+       bra     7b
+        mov    r9, r6
+
+       .align  2
+.Lall:
+       .long   0x7fffffff
+.Lwait0:
+       .long   __lll_lock_wait-.Lwait0b
+.Lwake0:
+       .long   __lll_unlock_wake-.Lwake0b
+.Lwake1:
+       .long   __lll_unlock_wake-.Lwake1b      
+       .size   pthread_barrier_wait,.-pthread_barrier_wait
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
new file mode 100644 (file)
index 0000000..93818f9
--- /dev/null
@@ -0,0 +1,126 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include <lowlevelcond.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+
+       .text
+
+       /* int pthread_cond_broadcast (pthread_cond_t *cond) */
+       .globl  __pthread_cond_broadcast
+       .type   __pthread_cond_broadcast, @function
+       .align  5
+__pthread_cond_broadcast:
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+
+       /* Get internal lock.  */
+       mov     #1, r3
+#if cond_lock != 0
+       XADD (r3, @(cond_lock,r8), r2)
+#else
+       XADD (r3, @r8, r2)
+#endif
+       tst     r2, r2
+       bf      1f
+2:
+       mov.l   @(total_seq+4,r8),r0
+       mov.l   @(total_seq,r8),r1
+       mov.l   @(wakeup_seq+4,r8), r2
+       cmp/hi  r2, r0
+       bt      3f
+       cmp/hi  r0, r2
+       bt      4f
+       mov.l   @(wakeup_seq,r8), r2
+       cmp/hi  r2, r1
+       bf      4f
+
+3:
+       /* Case all currently waiting threads to wake up.  */
+       mov.l   r1, @(wakeup_seq,r8)
+       mov.l   r0, @(wakeup_seq+4,r8)
+
+       /* Wake up all threads.  */
+       mov     r8, r4
+       add     #wakeup_seq, r4
+       mov     #FUTEX_WAKE, r5
+       mov     #-1, r6
+       shlr    r6              /* r6 = 0x7fffffff */
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+4:
+       /* Unlock.  */
+#if cond_lock != 0
+       DEC (@(cond_lock,r8), r2)
+#else
+       DEC (@r8, r2)
+#endif
+       tst     r2, r2
+       bf      5f
+6:
+       mov     #0, r0
+       lds.l   @r15+, pr
+       rts
+        mov.l  @r15+, r8
+
+1:
+       /* Initial locking failed.  */
+       mov     r8, r5
+#if cond_lock != 0
+       add     #cond_lock, r5
+#endif
+       mov.l   .Lmwait5, r1
+       bsrf    r1
+        mov    r2, r4
+.Lmwait5b:
+       bra     2b
+        nop
+
+5:
+       /* Unlock in loop requires waekup.  */
+       mov     r8, r4
+#if cond_lock != 0
+       add     #cond_lock, r4
+#endif
+       mov.l   .Lmwake5, r1
+       bsrf    r1
+        nop
+.Lmwake5b:
+       bra     6b
+        nop
+
+       .align  2
+.Lmwait5:
+       .long   __lll_mutex_lock_wait-.Lmwait5b
+.Lmwake5:
+       .long   __lll_mutex_unlock_wake-.Lmwake5b
+       .size   __pthread_cond_broadcast, .-__pthread_cond_broadcast
+versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
+                 GLIBC_2_3_2)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
new file mode 100644 (file)
index 0000000..a000641
--- /dev/null
@@ -0,0 +1,133 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include <lowlevelcond.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+
+       .text
+
+       /* int pthread_cond_signal (pthread_cond_t *cond) */
+       .globl  __pthread_cond_signal
+       .type   __pthread_cond_signal, @function
+       .align  5
+__pthread_cond_signal:
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+
+       /* Get internal lock.  */
+       mov     #1, r3
+#if cond_lock != 0
+       XADD (r3, @(cond_lock,r8), r2)
+#else
+       XADD (r3, @r8, r2)
+#endif
+       tst     r2, r2
+       bf      1f
+2:
+       mov.l   @(total_seq+4,r8),r0
+       mov.l   @(total_seq,r8),r1
+       mov.l   @(wakeup_seq+4,r8), r2
+       cmp/hi  r2, r0
+       bt      3f
+       cmp/hi  r0, r2
+       bt      4f
+       mov.l   @(wakeup_seq,r8), r2
+       cmp/hi  r2, r1
+       bf      4f
+
+3:
+       /* Bump the wakeup number.  */
+       mov     #1, r2
+       mov     #0, r3
+       clrt
+       mov.l   @(wakeup_seq,r8),r0
+       mov.l   @(wakeup_seq+4,r8),r1
+       addc    r2, r0
+       addc    r3, r1
+       mov.l   r0,@(wakeup_seq,r8)
+       mov.l   r1,@(wakeup_seq+4,r8)
+
+       /* Wake up one thread.  */
+       mov     r8, r4
+       add     #wakeup_seq, r4
+       mov     #FUTEX_WAKE, r5
+       mov     #1, r6
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+4:
+       /* Unlock.  */
+#if cond_lock != 0
+       DEC (@(cond_lock,r8), r2)
+#else
+       DEC (@r8, r2)
+#endif
+       tst     r2, r2
+       bf      5f
+6:
+       mov     #0, r0
+       lds.l   @r15+, pr
+       rts
+        mov.l  @r15+, r8
+
+1:
+       /* Initial locking failed.  */
+       mov     r8, r5
+#if cond_lock != 0
+       add     #cond_lock, r5
+#endif
+       mov.l   .Lmwait4, r1
+       bsrf    r1
+        mov    r2, r4
+.Lmwait4b:
+       bra     2b
+        nop
+
+5:
+       /* Unlock in loop requires wakeup.  */
+       mov     r8, r4
+#if cond_lock != 0
+       add     #cond_lock, r4
+#endif
+       mov.l   .Lmwake4, r1
+       bsrf    r1
+        nop
+.Lmwake4b:
+       bra     6b
+        nop
+
+       .align  2
+.Lmwait4:
+       .long   __lll_mutex_lock_wait-.Lmwait4b
+.Lmwake4:
+       .long   __lll_mutex_unlock_wake-.Lmwake4b
+       .size   __pthread_cond_signal, .-__pthread_cond_signal
+versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
+                 GLIBC_2_3_2)
+
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
new file mode 100644 (file)
index 0000000..f0be38a
--- /dev/null
@@ -0,0 +1,361 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include <lowlevelcond.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define ETIMEDOUT              110
+
+
+       .text
+
+/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
+                              const struct timespec *abstime)  */
+       .globl  __pthread_cond_timedwait
+       .type   __pthread_cond_timedwait, @function
+       .align  5
+__pthread_cond_timedwait:
+       mov.l   r12, @-r15
+       mov.l   r10, @-r15
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       add     #-48, r15
+       mov     r4, r8
+       mov     r5, r9
+       mov     r6, r10
+
+       /* Get internal lock.  */
+       mov     #1, r3
+#if cond_lock != 0
+       XADD (r3, @(cond_lock,r8), r2)
+#else
+       XADD (r3, @r8, r2)
+#endif
+       tst     r2, r2
+       bt      2f
+       bra     1f
+        nop
+2:
+       /* Unlock the mutex.  */
+       mov.l   .Lmunlock1, r1
+       bsrf    r1
+        mov    r9, r4
+.Lmunlock1b:
+
+       mov     #1, r2
+       mov     #0, r3
+
+       clrt
+       mov.l   @(total_seq,r8),r0
+       mov.l   @(total_seq+4,r8),r1
+       addc    r2, r0
+       addc    r3, r1
+       mov.l   r0,@(total_seq,r8)
+       mov.l   r1,@(total_seq+4,r8)
+
+       /* Install cancellation handler.  */
+#ifdef PIC
+       mova    .Lgot1, r0
+       mov.l   .Lgot1, r12
+       add     r0, r12
+       mov.l   .Lccleanup1, r5
+       add     r12, r5
+#else
+       mov.l   .Lccleanup1, r5
+#endif
+       mov     r15, r4
+       add     #28, r4
+
+       mov.l   .Lccpush1, r1
+       bsrf    r1
+        mov    r8, r6
+.Lccpush1b:
+
+       /* Get and store current wakeup_seq value.  */
+       mov.l   @(wakeup_seq,r8), r0
+       mov.l   @(wakeup_seq+4,r8), r1
+       mov.l   r0, @(12,r15)
+       mov.l   r1, @(16,r15)
+
+       /* Unlock.  */
+8:
+#if cond_lock != 0
+       DEC (@(cond_lock,r8), r2)
+#else
+       DEC (@r8, r2)
+#endif
+       tst     r2, r2
+       bt      4f
+       bra     3f
+        nop
+4:
+       mov.l   .Lenable1, r1
+       bsrf    r1
+        nop
+.Lenable1b:
+       mov.l   r0, @r15
+
+       /* Get current time.  */
+       mov     r15, r4
+       add     #4, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       /* Compute relative timeout.  */
+       mov.l   @(8,r15), r0
+       mov.w   .L1k, r1
+       dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
+       mov.l   @r10, r2
+       mov.l   @(4,r10), r3
+       mov.l   @(4,r15), r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      12f
+       mov.l   .L1g, r1
+       add     r1, r3
+       add     #-1, r2
+12:
+       cmp/pz  r2
+       bf      13f             /* Time is already up.  */
+
+       /* Store relative timeout.  */
+       mov.l   r2, @(4,r15)
+       mov.l   r3, @(8,r15)
+
+       mov     r15, r7
+       add     #4, r7
+       mov     #FUTEX_WAIT, r5
+       mov.l   @(12,r15), r6
+       mov     r8, r4
+       add     #wakeup_seq, r4
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       mov.l   r0, @(20,r15)
+
+       mov.l   .Ldisable1, r1
+       bsrf    r1
+        mov.l  @r15, r4
+.Ldisable1b:   
+
+       /* Lock.  */
+       mov     #1, r3
+#if cond_lock != 0
+       XADD (r3, @(cond_lock,r8), r2)
+#else
+       XADD (r3, @r8, r2)
+#endif
+       tst     r2, r2
+       bf      5f
+6:
+       mov.l   @(woken_seq,r8), r0
+       mov.l   @(woken_seq+4,r8), r1
+
+       mov.l   @(wakeup_seq,r8), r2
+       mov.l   @(wakeup_seq+4,r8), r3
+
+       mov.l   @(16,r15), r5
+       cmp/hi  r5, r1
+       bt      7f
+       cmp/hi  r1, r5
+       bt      15f
+
+       mov.l   @(12,r15), r5
+       cmp/hi  r0, r5
+       bt      15f
+7:
+       cmp/hi  r1, r3
+       bt      9f
+       cmp/hi  r3, r1
+       bt      15f
+       cmp/hi  r0, r2
+       bt      9f
+15:
+       mov.l   @(20,r15),r0
+       cmp/eq  #-ETIMEDOUT, r0
+       bf      8b
+13:
+       mov     #1, r2
+       mov     #0, r3
+
+       clrt
+       mov.l   @(wakeup_seq,r8),r0
+       mov.l   @(wakeup_seq+4,r8),r1
+       addc    r2, r0
+       addc    r3, r1
+       mov.l   r0,@(wakeup_seq,r8)
+       mov.l   r1,@(wakeup_seq+4,r8)
+       mov     #ETIMEDOUT, r0
+       bra     14f
+        mov.l  r0, @(24,r15)
+
+9:
+       mov     #0, r0
+       mov.l   r0, @(24,r15)
+14:
+       mov     #1, r2
+       mov     #0, r3
+
+       clrt
+       mov.l   @(woken_seq,r8),r0
+       mov.l   @(woken_seq+4,r8),r1
+       addc    r2, r0
+       addc    r3, r1
+       mov.l   r0,@(woken_seq,r8)
+       mov.l   r1,@(woken_seq+4,r8)
+
+#if cond_lock != 0
+       DEC (@(cond_lock,r8), r2)
+#else
+       DEC (@r8, r2)
+#endif
+       tst     r2, r2
+       bf      10f
+
+11:
+       /* Remove cancellation handler.  */
+       mov     r15, r4
+       add     #28, r4
+       mov.l   .Lcpop1, r1
+       bsrf    r1
+        mov    #0, r5
+.Lcpop1b:
+
+       mov     r9, r4
+       mov.l   .Lmlocki1, r1
+       bsrf    r1
+        mov    #0, r5
+.Lmlocki1b:
+
+       mov.l   @(24,r15), r0
+
+       add     #48, r15
+
+       /* We return the result of the mutex_lock operation.  */
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       mov.l   @r15+, r10
+       rts
+        mov.l  @r15+, r12
+       ret
+
+.L1k:
+       .word   1000
+       .align  2
+.Lmunlock1:
+       .long   __pthread_mutex_unlock_internal-.Lmunlock1b
+#ifdef PIC
+.Lgot1:
+       .long   _GLOBAL_OFFSET_TABLE_
+.Lccleanup1:
+       .long   __condvar_cleanup@GOTOFF
+#else
+.Lccleanup1:
+       .long   __condvar_cleanup
+#endif
+.Lccpush1:
+       .long   __pthread_cleanup_push-.Lccpush1b
+.Lenable1:
+       .long   __pthread_enable_asynccancel-.Lenable1b
+.Ldisable1:
+       .long   __pthread_disable_asynccancel-.Ldisable1b
+.Lcpop1:
+       .long   __pthread_cleanup_pop-.Lcpop1b
+.Lmlocki1:
+       .long   __pthread_mutex_lock_internal-.Lmlocki1b
+.L1g:
+       .long   1000000000
+
+1:
+       /* Initial locking failed.  */
+       mov     r8, r5
+#if cond_lock != 0
+       add     #cond_lock, r5
+#endif
+       mov.l   .Lmwait2, r1
+       bsrf    r1
+        mov    r2, r4
+.Lmwait2b:
+       bra     2b
+        nop
+
+3:
+       /* Unlock in loop requires waekup.  */
+       mov     r8, r4
+#if cond_lock != 0
+       add     #cond_lock, r4
+#endif
+       mov.l   .Lmwake2, r1
+       bsrf    r1
+        nop
+.Lmwake2b:
+       bra     4b
+        nop
+
+5:
+       /* Locking in loop failed.  */
+       mov     r8, r5
+#if cond_lock != 0
+       add     #cond_lock, r5
+#endif
+       mov.l   .Lmwait3, r1
+       bsrf    r1
+        mov    r2, r4
+.Lmwait3b:
+       bra     6b
+        nop
+
+10:
+       /* Unlock after loop requires waekup.  */
+       mov     r8, r4
+#if cond_lock != 0
+       add     #cond_lock, r4
+#endif
+       mov.l   .Lmwake3, r1
+       bsrf    r1
+        nop
+.Lmwake3b:
+       bra     11b
+        nop
+
+       .align  2
+.Lmwait2:
+       .long   __lll_mutex_lock_wait-.Lmwait2b
+.Lmwake2:
+       .long   __lll_mutex_unlock_wake-.Lmwake2b
+.Lmwait3:
+       .long   __lll_mutex_lock_wait-.Lmwait3b
+.Lmwake3:
+       .long   __lll_mutex_unlock_wake-.Lmwake3b
+       .size   __pthread_cond_timedwait, .-__pthread_cond_timedwait
+versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
+                 GLIBC_2_3_2)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
new file mode 100644 (file)
index 0000000..342e78e
--- /dev/null
@@ -0,0 +1,364 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include <lowlevelcond.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+
+       .text
+
+       .align  5
+       .type   __condvar_cleanup, @function
+       .globl  __condvar_cleanup
+       .hidden __condvar_cleanup
+__condvar_cleanup:
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+
+       /* Get internal lock.  */
+       mov     #1, r3
+#if cond_lock != 0
+       XADD (r3, @(cond_lock,r8), r2)
+#else
+       XADD (r3, @r8, r2)
+#endif
+       tst     r2, r2
+       bt      1f
+       mov     r8, r5
+#if cond_lock != 0
+       add     #cond_lock, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait0, r1
+       bsrf    r1
+        nop
+.Lwait0b:
+1:
+       mov     #1, r2
+       mov     #0, r3
+
+       clrt
+       mov.l   @(wakeup_seq,r8),r0
+       mov.l   @(wakeup_seq+4,r8),r1
+       addc    r2, r0
+       addc    r3, r1
+       mov.l   r0,@(wakeup_seq,r8)
+       mov.l   r1,@(wakeup_seq+4,r8)
+
+       clrt
+       mov.l   @(woken_seq,r8),r0
+       mov.l   @(woken_seq+4,r8),r1
+       addc    r2, r0
+       addc    r3, r1
+       mov.l   r0,@(woken_seq,r8)
+       mov.l   r1,@(woken_seq+4,r8)
+
+       /* Release internal lock.  */
+#if cond_lock != 0
+       DEC (@(cond_lock,r8), r2)
+#else
+       DEC (@r8, r2)
+#endif
+       tst     r2, r2
+       bt      2f
+
+       mov     r8, r4
+#if cond_lock != 0
+       add     #cond_lock, r4
+#endif
+       mov.l   .Lwake0, r1
+       bsrf    r1
+        nop
+.Lwake0b:
+2:
+       lds.l   @r15+, pr
+       rts
+        mov.l  @r15+, r8
+
+       .align  2
+.Lwait0:       
+       .long   __lll_mutex_lock_wait-.Lwait0b
+.Lwake0:
+       .long   __lll_mutex_unlock_wake-.Lwake0b
+       .size   __condvar_cleanup, .-__condvar_cleanup
+
+
+/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)  */
+       .globl  __pthread_cond_wait
+       .type   __pthread_cond_wait, @function
+       .align  5
+__pthread_cond_wait:
+       mov.l   r12, @-r15
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       add     #-32, r15
+       mov     r4, r8
+       mov     r5, r9
+
+       /* Get internal lock.  */
+       mov     #1, r3
+#if cond_lock != 0
+       XADD (r3, @(cond_lock,r8), r2)
+#else
+       XADD (r3, @r8, r2)
+#endif
+       tst     r2, r2
+       bf      1f
+2:     
+       /* Unlock the mutex.  */
+       mov.l   .Lmunlock0, r1
+       bsrf    r1
+        mov    r9, r4
+.Lmunlock0b:
+
+       mov     #1, r2
+       mov     #0, r3
+
+       clrt
+       mov.l   @(total_seq,r8),r0
+       mov.l   @(total_seq+4,r8),r1
+       addc    r2, r0
+       addc    r3, r1
+       mov.l   r0,@(total_seq,r8)
+       mov.l   r1,@(total_seq+4,r8)
+
+       /* Install cancellation handler.  */
+#ifdef PIC
+       mova    .Lgot0, r0
+       mov.l   .Lgot0, r12
+       add     r0, r12
+       mov.l   .Lccleanup0, r5
+       add     r12, r5
+#else
+       mov.l   .Lccleanup0, r5
+#endif
+       mov     r15, r4
+       add     #12, r4
+
+       mov.l   .Lccpush0, r1
+       bsrf    r1
+        mov    r8, r6
+.Lccpush0b:
+
+       /* Get and store current wakeup_seq value.  */
+       mov.l   @(wakeup_seq,r8), r0
+       mov.l   @(wakeup_seq+4,r8), r1
+       mov.l   r0, @(4,r15)
+       mov.l   r1, @(8,r15)
+
+8:
+       /* Unlock.  */
+#if cond_lock != 0
+       DEC (@(cond_lock,r8), r2)
+#else
+       DEC (@r8, r2)
+#endif
+       tst     r2, r2
+       bf      3f
+4:
+       mov.l   .Lenable0, r1
+       bsrf    r1
+        nop
+.Lenable0b:
+       mov.l   r0, @r15
+
+       mov     #0, r7
+       mov     #FUTEX_WAIT, r5
+       mov.l   @(4,r15), r6
+       mov     r8, r4
+       add     #wakeup_seq, r4
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov.l   .Ldisable0, r1
+       bsrf    r1
+        mov.l  @r15, r4
+.Ldisable0b:   
+
+       /* Lock.  */
+       mov     #1, r3
+#if cond_lock != 0
+       XADD (r3, @(cond_lock,r8), r2)
+#else
+       XADD (r3, @r8, r2)
+#endif
+       tst     r2, r2
+       bf      5f
+6:
+       mov.l   @(woken_seq,r8), r0
+       mov.l   @(woken_seq+4,r8), r1
+
+       mov.l   @(wakeup_seq,r8), r2
+       mov.l   @(wakeup_seq+4,r8), r3
+
+       mov.l   @(8,r15), r5
+       cmp/hi  r5, r1
+       bt      7f
+       cmp/hi  r1, r5
+       bt      8b
+
+       mov.l   @(4,r15), r5
+       cmp/hi  r0, r5
+       bt      8b
+7:
+       cmp/hi  r1, r3
+       bt      9f
+       cmp/hi  r3, r1
+       bt      8b
+       cmp/hi  r0, r2
+       bf      8b
+9:
+       mov     #1, r2
+       mov     #0, r3
+
+       clrt
+       mov.l   @(woken_seq,r8),r0
+       mov.l   @(woken_seq+4,r8),r1
+       addc    r2, r0
+       addc    r3, r1
+       mov.l   r0,@(woken_seq,r8)
+       mov.l   r1,@(woken_seq+4,r8)
+
+#if cond_lock != 0
+       DEC (@(cond_lock,r8), r2)
+#else
+       DEC (@r8, r2)
+#endif
+       tst     r2, r2
+       bf      10f
+
+11:
+       /* Remove cancellation handler.  */
+       mov     r15, r4
+       add     #12, r4
+       mov.l   .Lcpop0, r1
+       bsrf    r1
+        mov    #0, r5
+.Lcpop0b:
+
+       mov     r9, r4
+       mov.l   .Lmlocki0, r1
+       bsrf    r1
+        mov    #0, r5
+.Lmlocki0b:
+
+       add     #32, r15
+
+       /* We return the result of the mutex_lock operation.  */
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       rts
+        mov.l  @r15+, r12
+
+       .align  2
+.Lmunlock0:
+       .long   __pthread_mutex_unlock_internal-.Lmunlock0b
+#ifdef PIC
+.Lgot0:
+       .long   _GLOBAL_OFFSET_TABLE_
+.Lccleanup0:
+       .long   __condvar_cleanup@GOTOFF
+#else
+.Lccleanup0:
+       .long   __condvar_cleanup
+#endif
+.Lccpush0:
+       .long   __pthread_cleanup_push-.Lccpush0b
+.Lenable0:
+       .long   __pthread_enable_asynccancel-.Lenable0b
+.Ldisable0:
+       .long   __pthread_disable_asynccancel-.Ldisable0b
+.Lcpop0:
+       .long   __pthread_cleanup_pop-.Lcpop0b
+.Lmlocki0:
+       .long   __pthread_mutex_lock_internal-.Lmlocki0b
+
+1:
+       /* Initial locking failed.  */
+       mov     r8, r5
+#if cond_lock != 0
+       add     #cond_lock, r5
+#endif
+       mov.l   .Lmwait0, r1
+       bsrf    r1
+        mov    r2, r4
+.Lmwait0b:
+       bra     2b
+        nop
+3:
+       /* Unlock in loop requires waekup.  */
+       mov     r8, r4
+#if cond_lock != 0
+       add     #cond_lock, r4
+#endif
+       mov.l   .Lmwake0, r1
+       bsrf    r1
+        nop
+.Lmwake0b:
+       bra     4b
+        nop
+
+5:
+       /* Locking in loop failed.  */
+       mov     r8, r5
+#if cond_lock != 0
+       add     #cond_lock, r5
+#endif
+       mov.l   .Lmwait1, r1
+       bsrf    r1
+        mov    r2, r4
+.Lmwait1b:
+       bra     6b
+        nop
+
+10:
+       /* Unlock after loop requires wakeup.  */
+       mov     r8, r4
+#if cond_lock != 0
+       add     #cond_lock, r4
+#endif
+       mov.l   .Lmwake1, r1
+       bsrf    r1
+        nop
+.Lmwake1b:
+       bra     11b
+        nop
+
+       .align  2
+.Lmwait0:
+       .long   __lll_mutex_lock_wait-.Lmwait0b
+.Lmwake0:
+       .long   __lll_mutex_unlock_wake-.Lmwake0b
+.Lmwait1:
+       .long   __lll_mutex_lock_wait-.Lmwait1b
+.Lmwake1:
+       .long   __lll_mutex_unlock_wake-.Lmwake1b
+       .size   __pthread_cond_wait, .-__pthread_cond_wait
+versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
+                 GLIBC_2_3_2)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
new file mode 100644 (file)
index 0000000..c17701c
--- /dev/null
@@ -0,0 +1,197 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_futex      240
+#define FUTEX_WAIT     0
+#define FUTEX_WAKE     1
+
+       .comm   __fork_generation, 4, 4
+
+       .text
+       .globl  __pthread_once
+       .type   __pthread_once,@function
+       .align  5
+__pthread_once:
+       mov.l   @r4, r0
+       tst     #2, r0
+       bt      1f
+       rts
+        mov    #0, r0
+
+1:
+       mov.l   r12, @-r15
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r5, r8
+
+       /* Not yet initialized or initialization in progress.
+          Get the fork generation counter now.  */
+6:
+       mov.l   @r4, r1
+#ifdef PIC
+       mova    .Lgot, r0
+       mov.l   .Lgot, r12
+       add     r0, r12
+#endif
+
+5:
+       mov     r1, r0
+
+       tst     #2, r0
+       bf      4f
+
+       and     #3, r0
+       mov.l   .Lfgen, r2
+#ifdef PIC
+       add     r12, r2
+#endif
+       mov.l   @r2, r3
+       or      r3, r0  
+       or      #1, r0
+       mov     r0, r3
+       mov     r1, r5
+
+       CMPXCHG (r5, @r4, r3, r2)
+       bf      5b
+
+       /* Check whether another thread already runs the initializer.  */
+       mov     r2, r0
+       tst     #1, r0
+       bt      3f      /* No -> do it.  */
+
+       /* Check whether the initializer execution was interrupted
+          by a fork.  */
+       xor     r3, r0
+       mov     #-4, r1 /* -4 = 0xfffffffc */
+       tst     r1, r0
+       bf      3f      /* Different for generation -> run initializer.  */
+
+       /* Somebody else got here first.  Wait.  */
+       mov     #FUTEX_WAIT, r5
+       mov     r3, r6
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       bra     6b
+        nop
+
+       .align  2
+#ifdef PIC
+.Lgot:
+       .long   _GLOBAL_OFFSET_TABLE_
+.Lfgen:        
+       .long   __fork_generation@GOTOFF
+#else
+.Lfgen:        
+       .long   __fork_generation
+#endif
+
+3:
+       /* Call the initializer function after setting up the
+          cancellation handler.  */
+       /* Allocate a _pthread_cleanup_buffer on stack.  */
+       add     #-16, r15
+
+       /* Push the cleanup handler.  */
+       mov     r4, r9
+       mov     r15, r4
+       mov.l   .Lconce, r5
+#ifdef PIC
+       add     r12, r5
+#endif
+       mov.l   .Lcpush, r1
+       bsrf    r1
+        mov    r3, r6
+.Lcpush0:
+       jsr     @r8
+        nop
+
+       /* Pop the cleanup handler.  */
+       mov     r15, r4
+       mov.l   .Lcpop, r1
+       bsrf    r1
+        mov    #0, r5
+.Lcpop0:
+       add     #16, r15
+
+       /* Sucessful run of the initializer.  Signal that we are done.  */
+       INC (@r9, r2)
+       /* Wake up all other threads.  */
+       mov     r9, r4
+       mov     #FUTEX_WAKE, r5
+       mov     #-1, r6
+       shlr    r6              /* r6 = 0x7fffffff */
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+4:
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       mov.l   @r15+, r12
+       rts
+        mov    #0, r0
+
+       .align  2
+.Lconce:
+#ifdef PIC
+       .long   clear_once_control@GOTOFF
+#else
+       .long   clear_once_control
+#endif
+.Lcpush:
+       .long   __pthread_cleanup_push - .Lcpush0       /* Note: no @PLT.  */
+.Lcpop:
+       .long   __pthread_cleanup_pop - .Lcpop0         /* Note: no @PLT.  */
+
+       .size   __pthread_once,.-__pthread_once
+
+       .globl  __pthread_once_internal
+__pthread_once_internal = __pthread_once
+
+       .globl  pthread_once
+pthread_once = __pthread_once
+
+
+       .type   clear_once_control,@function
+       .align  5
+clear_once_control:
+       mov     #0, r0
+       mov.l   r0, @r4
+
+       mov     #FUTEX_WAKE, r5
+       mov     #-1, r6
+       shlr    r6              /* r6 = 0x7fffffff */
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       rts
+        nop
+       .size   clear_once_control,.-clear_once_control
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
new file mode 100644 (file)
index 0000000..2c6adf8
--- /dev/null
@@ -0,0 +1,220 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <lowlevelrwlock.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EAGAIN         11
+#define EDEADLK                35
+
+
+       .text
+
+       .globl  __pthread_rwlock_rdlock
+       .type   __pthread_rwlock_rdlock,@function
+       .align  5
+__pthread_rwlock_rdlock:
+       mov.l   r12, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+
+       /* Get the lock.  */
+       mov     #1, r3
+#if MUTEX == 0
+       XADD    (r3, @r4, r2)
+#else
+       XADD    (r3, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      1f
+2:
+       mov.l   @(WRITER,r8), r0
+       tst     r0, r0
+       bf      14f
+       mov.l   @(WRITERS_QUEUED,r8), r0
+       tst     r0, r0
+       bt      5f
+       mov.l   @(FLAGS,r8), r0
+       tst     r0, r0
+       bt      5f
+3:
+       mov.l   @(READERS_QUEUED,r8), r0
+       add     #1, r0
+       mov.l   r0, @(READERS_QUEUED,r8)
+       tst     r0, r0
+       bt      4f
+
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      10f
+11:
+       mov     r8, r4
+       add     #READERS_WAKEUP, r4
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r6
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       /* Reget the lock.  */
+       mov     #1, r3
+#if MUTEX == 0
+       XADD    (r3, @r4, r2)
+#else
+       XADD    (r3, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      12f
+13:
+       mov.l   @(READERS_QUEUED,r8), r0
+       add     #-1, r0
+       mov.l   r0, @(READERS_QUEUED,r8)
+       tst     r0, r0
+       bf      2b
+       bra     2b
+        mov.l  r0, @(READERS_WAKEUP,r8)
+
+5:
+       mov     #0, r3
+       mov.l   @(NR_READERS,r8), r0
+       add     #1, r0
+       mov.l   r0, @(NR_READERS,r8)
+       tst     r0, r0
+       bt      8f
+
+9:
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      6f
+7:
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r12
+       rts
+        mov    r3, r0
+
+1:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait0, r1
+       bsrf    r1
+        nop
+.Lwait0b:
+       bra     2b
+        nop
+14:
+       stc     gbr, r1
+       mov.w   .Ltcboff,r2
+       sub     r2,r1
+       mov.l   @(8,r1),r1
+       cmp/eq  r1, r0
+       bf      3b
+       /* Deadlock detected.  */
+       bra     9b
+        mov    #EDEADLK, r3
+
+6:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake0, r1
+       bsrf    r1
+        nop
+.Lwake0b:
+       bra     7b
+        mov    #0, r3
+
+8:
+       /* Overflow.  */
+       mov.l   @(NR_READERS,r8), r1
+       add     #-1, r1
+       mov.l   r1, @(NR_READERS,r8)
+       bra     9b
+        mov    #EAGAIN, r3
+
+4:
+       /* Overflow.  */
+       mov.l   @(READERS_QUEUED,r8), r1
+       add     #-1, r1
+       mov.l   r1, @(READERS_QUEUED,r8)
+       bra     9b
+        mov    #EAGAIN, r3
+
+10:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake1, r1
+       bsrf    r1
+        nop
+.Lwake1b:
+       bra     11b
+        nop
+
+12:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait1, r1
+       bsrf    r1
+        nop
+.Lwait1b:
+       bra     13b
+        nop
+
+.Ltcboff:
+       .word   TLS_PRE_TCB_SIZE
+       .align  2
+.Lwait0:
+       .long   __lll_mutex_lock_wait-.Lwait0b
+.Lwake0:
+       .long   __lll_mutex_unlock_wake-.Lwake0b
+.Lwait1:       
+       .long   __lll_mutex_lock_wait-.Lwait1b
+.Lwake1:
+       .long   __lll_mutex_unlock_wake-.Lwake1b
+       .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
+
+       .globl  pthread_rwlock_rdlock
+pthread_rwlock_rdlock = __pthread_rwlock_rdlock
+
+       .globl  __pthread_rwlock_rdlock_internal
+__pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
new file mode 100644 (file)
index 0000000..b287dd4
--- /dev/null
@@ -0,0 +1,274 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <lowlevelrwlock.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EAGAIN         11
+#define EDEADLK                35
+#define ETIMEDOUT      110
+
+
+       .text
+
+       .globl  pthread_rwlock_timedrdlock
+       .type   pthread_rwlock_timedrdlock,@function
+       .align  5
+pthread_rwlock_timedrdlock:
+       mov.l   r12, @-r15
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       add     #-8, r15
+       mov     r4, r8
+       mov     r5, r9
+
+       /* Get the lock.  */
+       mov     #1, r3
+#if MUTEX == 0
+       XADD    (r3, @r4, r2)
+#else
+       XADD    (r3, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      1f
+2:
+       mov.l   @(WRITER,r8), r0
+       tst     r0, r0
+       bf      14f
+       mov.l   @(WRITERS_QUEUED,r8), r0
+       tst     r0, r0
+       bt      5f
+       mov.l   @(FLAGS,r8), r0
+       tst     r0, r0
+       bt      5f
+3:
+       mov.l   @(READERS_QUEUED,r8), r0
+       add     #1, r0
+       mov.l   r0, @(READERS_QUEUED,r8)
+       tst     r0, r0
+       bt      4f
+
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      10f
+
+11:
+       /* Get current time.  */
+       mov     r15, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       mov.l   @(4,r15), r0
+       mov.w   .L1k0, r1
+       dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
+       mov.l   @r9, r2
+       mov.l   @(4,r9), r3
+       mov.l   @r15, r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      15f
+       mov.l   .L1g0, r1
+       add     r1, r3
+       add     #-1, r2
+15:
+       cmp/pz  r2
+       bf      16f             /* Time is already up.  */
+
+       /* Store relative timeout.  */
+       mov.l   r2, @r15
+       mov.l   r3, @(4,r15)
+
+       /* Futex call.  */
+       mov     r15, r7
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r6
+       mov     r8, r4
+       add     #READERS_WAKEUP, r4
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       mov     r0, r3
+
+17:
+       /* Reget the lock.  */
+       mov     r8, r4
+       mov     #1, r5
+#if MUTEX == 0
+       XADD    (r5, @r4, r2)
+#else
+       XADD    (r5, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      12f
+
+13:
+       mov     #-ETIMEDOUT, r0
+       cmp/eq  r0, r3
+       bt      18f
+       mov.l   @(READERS_QUEUED,r8), r0
+       add     #-1, r0
+       mov.l   r0, @(READERS_QUEUED,r8)
+       tst     r0, r0
+       bf      2b
+       bra     2b
+        mov.l  r0, @(READERS_WAKEUP,r8)
+
+5:
+       mov     #0, r3
+       mov.l   @(NR_READERS,r8), r0
+       add     #1, r0
+       mov.l   r0, @(NR_READERS,r8)
+       tst     r0, r0
+       bt      8f
+
+9:
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      6f
+7:
+       add     #8,r15
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       mov.l   @r15+, r12
+       rts
+        mov    r3, r0
+
+       .align  2
+.L1k0:
+       .long   1000
+.L1g0:
+       .long   1000000000
+
+1:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait2, r1
+       bsrf    r1
+        nop
+.Lwait2b:
+       bra     2b
+        nop
+14:
+       stc     gbr, r1
+       mov.w   .Ltcboff,r2
+       sub     r2,r1
+       mov.l   @(8,r1),r1
+       cmp/eq  r1, r0
+       bf      3b
+       /* Deadlock detected.  */
+       bra     9b
+        mov    #EDEADLK, r3
+
+6:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake2, r1
+       bsrf    r1
+        nop
+.Lwake2b:
+       bra     7b
+        mov    #0, r3
+
+8:
+       /* Overflow.  */
+       mov.l   @(NR_READERS,r8), r1
+       add     #-1, r1
+       mov.l   r1, @(NR_READERS,r8)
+       bra     9b
+        mov    #EAGAIN, r3
+
+4:
+       /* Overflow.  */
+       mov.l   @(READERS_QUEUED,r8), r1
+       add     #-1, r1
+       mov.l   r1, @(READERS_QUEUED,r8)
+       bra     9b
+        mov    #EAGAIN, r3
+
+10:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake3, r1
+       bsrf    r1
+        nop
+.Lwake3b:
+       bra     11b
+        nop
+
+12:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait3, r1
+       bsrf    r1
+        nop
+.Lwait3b:
+       bra     13b
+        nop
+
+16:
+       bra     17b
+        mov    #-ETIMEDOUT, r3
+
+18:
+       bra     9b
+        mov    #ETIMEDOUT, r3
+
+.Ltcboff:
+       .word   TLS_PRE_TCB_SIZE
+       .align  2
+.Lwait2:       
+       .long   __lll_mutex_lock_wait-.Lwait2b
+.Lwake2:
+       .long   __lll_mutex_unlock_wake-.Lwake2b
+.Lwait3:       
+       .long   __lll_mutex_lock_wait-.Lwait3b
+.Lwake3:
+       .long   __lll_mutex_unlock_wake-.Lwake3b
+       .size   pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
new file mode 100644 (file)
index 0000000..2e9bf05
--- /dev/null
@@ -0,0 +1,259 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <lowlevelrwlock.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EAGAIN         11
+#define EDEADLK                35
+#define ETIMEDOUT      110
+
+
+       .text
+
+       .globl  pthread_rwlock_timedwrlock
+       .type   pthread_rwlock_timedwrlock,@function
+       .align  5
+pthread_rwlock_timedwrlock:
+       mov.l   r12, @-r15
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       add     #-8, r15
+       mov     r4, r8
+       mov     r5, r9
+
+       /* Get the lock.  */
+       mov     #1, r3
+#if MUTEX == 0
+       XADD    (r3, @r4, r2)
+#else
+       XADD    (r3, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      1f
+2:
+       mov.l   @(WRITER,r8), r0
+       tst     r0, r0
+       bf      14f
+       mov.l   @(NR_READERS,r8), r0
+       tst     r0, r0
+       bt      5f
+3:
+       mov.l   @(WRITERS_QUEUED,r8), r0
+       add     #1, r0
+       mov.l   r0, @(WRITERS_QUEUED,r8)
+       tst     r0, r0
+       bt      4f
+
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      10f
+
+11:
+       /* Get current time.  */
+       mov     r15, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       mov.l   @(4,r15), r0
+       mov.w   .L1k1, r1
+       dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
+       mov.l   @r9, r2
+       mov.l   @(4,r9), r3
+       mov.l   @r15, r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      15f
+       mov.l   .L1g1, r1
+       add     r1, r3
+       add     #-1, r2
+15:
+       cmp/pz  r2
+       bf      16f             /* Time is already up.  */
+
+       /* Store relative timeout.  */
+       mov.l   r2, @r15
+       mov.l   r3, @(4,r15)
+
+       /* Futex call.  */
+       mov     r15, r7
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r6
+       mov     r8, r4
+       add     #WRITERS_WAKEUP, r4
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       mov     r0, r3
+
+17:
+       /* Reget the lock.  */
+       mov     r8, r4
+       mov     #1, r5
+#if MUTEX == 0
+       XADD    (r5, @r4, r2)
+#else
+       XADD    (r5, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      12f
+
+13:
+       mov     #-ETIMEDOUT, r0
+       cmp/eq  r0, r3
+       bt      18f
+       mov.l   @(WRITERS_QUEUED,r8), r0
+       add     #-1, r0
+       mov.l   r0, @(WRITERS_QUEUED,r8)
+       mov     #0, r0
+       bra     2b
+        mov.l  r0, @(WRITERS_WAKEUP,r8)
+
+5:
+       mov     #0, r3
+       stc     gbr, r1
+       mov.w   .Ltcboff,r2
+       sub     r2,r1
+       mov.l   @(8,r1),r0
+       mov.l   r0, @(WRITER,r8)
+9:
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      6f
+7:
+       add     #8,r15
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       mov.l   @r15+, r12
+       rts
+        mov    r3, r0
+
+.L1k1:
+       .word   1000
+       .align  2
+.L1g1:
+       .long   1000000000
+
+1:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait6, r1
+       bsrf    r1
+        nop
+.Lwait6b:
+       bra     2b
+        nop
+14:
+       stc     gbr, r1
+       mov.w   .Ltcboff,r2
+       sub     r2,r1
+       mov.l   @(8,r1),r1
+       cmp/eq  r1, r0
+       bf      3b
+       bra     9b
+        mov    #EDEADLK, r3
+6:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake6, r1
+       bsrf    r1
+        nop
+.Lwake6b:
+       bra     7b
+        mov    #0, r3
+
+4:
+       /* Overflow.  */
+       mov.l   @(WRITERS_QUEUED,r8), r1
+       add     #-1, r1
+       mov.l   r1, @(WRITERS_QUEUED,r8)
+       bra     9b
+        mov    #EAGAIN, r3
+
+10:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake7, r1
+       bsrf    r1
+        nop
+.Lwake7b:
+       bra     11b
+        nop
+
+12:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait7, r1
+       bsrf    r1
+        nop
+.Lwait7b:
+       bra     13b
+        nop
+
+16:
+       bra     17b
+        mov    #-ETIMEDOUT, r3
+
+18:
+       bra     9b
+        mov    #ETIMEDOUT, r3
+
+.Ltcboff:
+       .word   TLS_PRE_TCB_SIZE
+       .align  2
+.Lwait6:       
+       .long   __lll_mutex_lock_wait-.Lwait6b
+.Lwake6:
+       .long   __lll_mutex_unlock_wake-.Lwake6b
+.Lwait7:       
+       .long   __lll_mutex_lock_wait-.Lwait7b
+.Lwake7:
+       .long   __lll_mutex_unlock_wake-.Lwake7b
+       .size   pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
new file mode 100644 (file)
index 0000000..af046aa
--- /dev/null
@@ -0,0 +1,128 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <lowlevelrwlock.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+
+       .text
+
+       .globl  __pthread_rwlock_unlock
+       .type   __pthread_rwlock_unlock,@function
+       .align  5
+__pthread_rwlock_unlock:
+       mov.l   r12, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+
+       /* Get the lock.  */
+       mov     #1, r3
+#if MUTEX == 0
+       XADD    (r3, @r4, r2)
+#else
+       XADD    (r3, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      1f
+2:
+       mov.l   @(WRITER,r8), r0
+       tst     r0, r0
+       bf      5f
+       mov.l   @(NR_READERS,r8), r0
+       add     #-1, r0
+       mov.l   r0, @(NR_READERS,r8)
+       tst     r0, r0
+       bf      6f
+5:
+       mov     #0, r0
+       mov.l   r0, @(WRITER,r8)
+       mov     r8, r4
+       mov.l   @(WRITERS_QUEUED,r8), r0
+       tst     r0, r0
+       bf      9f
+       mov     #-1, r6
+       shlr    r6              /* r6 = 0x7fffffff */
+       bra     0f
+        add    #READERS_WAKEUP, r4
+9:
+       mov     #1, r6
+       add     #WRITERS_WAKEUP, r4
+0:
+       mov     #FUTEX_WAKE, r5
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+6:
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      3f
+4:
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r12
+       rts
+        mov    #0, r0
+
+1:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait8, r1
+       bsrf    r1
+        nop
+.Lwait8b:
+       bra     2b
+        nop
+3:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake8, r1
+       bsrf    r1
+        nop
+.Lwake8b:
+       bra     4b
+        nop
+
+       .align  2
+.Lwait8:       
+       .long   __lll_mutex_lock_wait-.Lwait8b
+.Lwake8:
+       .long   __lll_mutex_unlock_wake-.Lwake8b
+       .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
+
+       .globl  pthread_rwlock_unlock
+pthread_rwlock_unlock = __pthread_rwlock_unlock
+
+       .globl  __pthread_rwlock_unlock_internal
+__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
new file mode 100644 (file)
index 0000000..20c8423
--- /dev/null
@@ -0,0 +1,202 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <lowlevelrwlock.h>
+#include <tcb-offsets.h>
+#include "lowlevel-atomic.h"
+
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EAGAIN         11
+#define EDEADLK                35
+
+
+       .text
+
+       .globl  __pthread_rwlock_wrlock
+       .type   __pthread_rwlock_wrlock,@function
+       .align  5
+__pthread_rwlock_wrlock:
+       mov.l   r12, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+
+       /* Get the lock.  */
+       mov     #1, r3
+#if MUTEX == 0
+       XADD    (r3, @r4, r2)
+#else
+       XADD    (r3, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      1f
+2:
+       mov.l   @(WRITER,r8), r0
+       tst     r0, r0
+       bf      14f
+       mov.l   @(NR_READERS,r8), r0
+       tst     r0, r0
+       bt      5f
+3:
+       mov.l   @(WRITERS_QUEUED,r8), r0
+       add     #1, r0
+       mov.l   r0, @(WRITERS_QUEUED,r8)
+       tst     r0, r0
+       bt      4f
+
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      10f
+11:
+       mov     r8, r4
+       add     #WRITERS_WAKEUP, r4
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r6
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       /* Reget the lock.  */
+       mov     #1, r3
+#if MUTEX == 0
+       XADD    (r3, @r4, r2)
+#else
+       XADD    (r3, @(MUTEX,r4), r2)
+#endif
+       tst     r2, r2
+       bf      12f
+13:
+       mov.l   @(READERS_QUEUED,r8), r0
+       add     #-1, r0
+       mov.l   r0, @(READERS_QUEUED,r8)
+       mov     #0, r0
+       bra     2b
+        mov.l  r0, @(WRITERS_WAKEUP,r8)
+
+5:
+       mov     #0, r3
+       stc     gbr, r1
+       mov.w   .Ltcboff,r2
+       sub     r2,r1
+       mov.l   @(8,r1),r0
+       mov.l   r0, @(WRITER,r8)
+9:
+#if MUTEX == 0
+       DEC (@r8, r2)
+#else
+       DEC (@(MUTEX,r8), r2)
+#endif
+       tst     r2, r2
+       bf      6f
+7:
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r12
+       rts
+        mov    r3, r0
+
+1:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait4, r1
+       bsrf    r1
+        nop
+.Lwait4b:
+       bra     2b
+        nop
+14:
+       stc     gbr, r1
+       mov.w   .Ltcboff,r2
+       sub     r2,r1
+       mov.l   @(8,r1),r1
+       cmp/eq  r1, r0
+       bf      3b
+       bra     9b
+        mov    #EDEADLK, r3
+6:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake4, r1
+       bsrf    r1
+        nop
+.Lwake4b:
+       bra     7b
+        mov    #0, r3
+
+4:
+       mov.l   @(WRITERS_QUEUED,r8), r1
+       add     #-1, r1
+       mov.l   r1, @(WRITERS_QUEUED,r8)
+       bra     9b
+        mov    #EAGAIN, r3
+
+10:
+       mov     r8, r4
+#if MUTEX != 0
+       add     #MUTEX, r4
+#endif
+       mov.l   .Lwake5, r1
+       bsrf    r1
+        nop
+.Lwake5b:
+       bra     11b
+        nop
+
+12:
+       mov     r8, r5
+#if MUTEX != 0
+       add     #MUTEX, r5
+#endif
+       mov     r2, r4
+       mov.l   .Lwait5, r1
+       bsrf    r1
+        nop
+.Lwait5b:
+       bra     13b
+        nop
+
+.Ltcboff:
+       .word   TLS_PRE_TCB_SIZE
+       .align  2
+.Lwait4:       
+       .long   __lll_mutex_lock_wait-.Lwait4b
+.Lwake4:
+       .long   __lll_mutex_unlock_wake-.Lwake4b
+.Lwait5:       
+       .long   __lll_mutex_lock_wait-.Lwait5b
+.Lwake5:
+       .long   __lll_mutex_unlock_wake-.Lwake5b
+       .globl  pthread_rwlock_wrlock
+pthread_rwlock_wrlock = __pthread_rwlock_wrlock
+
+       .globl  __pthread_rwlock_wrlock_internal
+__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
new file mode 100644 (file)
index 0000000..9f33847
--- /dev/null
@@ -0,0 +1,92 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include "lowlevel-atomic.h"
+
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EINTR                  4
+#define EAGAIN                 11
+#define EWOULDBLOCK            EAGAIN
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+       .text
+
+       .globl  __new_sem_post
+       .type   __new_sem_post,@function
+       .align  5
+__new_sem_post:
+       mov     #1, r3
+       XADD (r3, @r4, r2)
+
+       mov     #FUTEX_WAKE, r5
+       mov     r2, r6
+       add     #1, r6
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       cmp/pz  r0
+       bf      1f
+       rts
+        mov    #0, r0
+
+1:
+       mov     #EAGAIN, r2
+       mova    .Lgot3, r0
+       mov.l   .Lgot3, r12
+       add     r0, r12
+
+#if USE___THREAD
+       mov.l   .Lerrno3, r0
+       stc     gbr, r1
+       mov.l   @(r0, r12), r0
+       add     r1, r0
+#else
+       mov.l   .Lerrloc3, r1
+       bsrf    r1
+        nop
+.Lerrloc3b:
+#endif
+       mov.l   r2, @r0
+       lds.l   @r15+, pr
+       mov.l   @r15+, r12
+       rts
+        mov    #-1, r0
+
+       .align  2
+.Lgot3:
+       .long   _GLOBAL_OFFSET_TABLE_
+#if USE___THREAD
+.Lerrno3:
+       .long   errno@GOTTPOFF
+#else
+.Lerrloc3:
+       .long   __errno_location@PLT-(.Lerrloc3b+2-.)
+#endif
+       .size   __new_sem_post,.-__new_sem_post
+       .symver __new_sem_post, sem_post@@GLIBC_2.2
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
new file mode 100644 (file)
index 0000000..741d663
--- /dev/null
@@ -0,0 +1,178 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include "lowlevel-atomic.h"
+
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EINTR                  4
+#define EAGAIN                 11
+#define EWOULDBLOCK            EAGAIN
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+       .text
+
+       .globl  sem_timedwait
+       .type   sem_timedwait,@function
+       .align  5
+sem_timedwait:
+       mov.l   @r4, r0
+2:
+       tst     r0, r0
+       bt      1f
+       mov     r0, r3
+       mov     r0, r6
+       add     #-1, r3
+       CMPXCHG (r6, @r4, r3, r2)
+       bf/s    2b
+        mov    r2, r0
+       rts
+        mov    #0, r0
+
+1:
+       /* Check whether the timeout value is valid.  */
+       mov.l   r12, @-r15
+       mov.l   r9, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       add     #-8, r15
+       mov     r4, r8
+       mov     r5, r9
+
+       /* Check for invalid nanosecond field.  */
+       mov.l   @(4,r9), r0
+       mov.l   .L1g, r1
+       cmp/hs  r1, r0
+       bt/s    6f
+        mov    #EINVAL, r0
+7:
+       /* Compute relative timeout.  */
+       mov     r15, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       mov.l   @(4,r15), r0
+       mov.w   .L1k, r1
+       dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
+       mov.l   @r9, r2
+       mov.l   @(4,r9), r3
+       mov.l   @r15, r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      5f
+       mov.l   .L1g, r1
+       add     r1, r3
+       add     #-1, r2
+5:
+       cmp/pz  r2
+       bf      6f              /* Time is already up.  */
+
+       /* Store relative timeout.  */
+       mov.l   r2, @r15
+       mov.l   r3, @(4,r15)
+
+       /* Futex call.  */
+       mov     r8, r4
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r6
+       mov     r15, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       tst     r0, r0
+       bt      9f
+       cmp/eq  #-EWOULDBLOCK, r0
+       bf      3f
+9:
+       mov.l   @r8, r0
+8:
+       tst     r0, r0
+       bt      7b
+
+       mov     r0, r3
+       mov     r0, r4
+       add     #-1, r3
+       CMPXCHG (r4, @r8, r3, r2)
+       bf/s    8b
+        mov    r2, r0
+
+       add     #8, r15
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       mov.l   @r15+, r12
+       rts
+        mov    #0, r0
+
+3:
+       neg     r0, r0
+6:
+       mov     r0, r8
+       mova    .Lgot2, r0
+       mov.l   .Lgot2, r12
+       add     r0, r12
+
+#if USE___THREAD
+       mov.l   .Lerrno2, r0
+       stc     gbr, r1
+       mov.l   @(r0, r12), r0
+       add     r1, r0
+       mov.l   r8, @r0
+#else
+       mov.l   .Lerrloc2, r1
+       bsrf    r1
+        nop
+.Lerrloc2b:
+       mov.l   r8, @r0
+#endif
+       add     #8, r15
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       mov.l   @r15+, r12
+       rts
+        mov    #-1, r0
+
+.L1k:
+       .word   1000
+       .align  2
+.L1g:
+       .long   1000000000
+.Lgot2:
+       .long   _GLOBAL_OFFSET_TABLE_
+#if USE___THREAD
+.Lerrno2:
+       .long   errno@GOTTPOFF
+#else
+.Lerrloc2:
+       .long   __errno_location@PLT-(.Lerrloc2b+2-.)
+#endif
+       .size   sem_timedwait,.-sem_timedwait
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
new file mode 100644 (file)
index 0000000..1305362
--- /dev/null
@@ -0,0 +1,99 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include "lowlevel-atomic.h"
+
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EINTR                  4
+#define EAGAIN                 11
+#define EWOULDBLOCK            EAGAIN
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+       .text
+
+       .globl  __new_sem_trywait
+       .type   __new_sem_trywait,@function
+       .align  5
+__new_sem_trywait:
+       mov.l   r12, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+       mov.l   @r8, r0
+2:
+       tst     r0, r0
+       bt      1f
+
+       mov     r0, r3
+       mov     r0, r4
+       add     #-1, r3
+       CMPXCHG (r4, @r8, r3, r2)
+       bf/s    2b
+        mov    r2, r0
+
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r12
+       rts
+        mov    #0, r0
+
+1:
+       mov     #EAGAIN, r8
+       mova    .Lgot1, r0
+       mov.l   .Lgot1, r12
+       add     r0, r12
+
+#if USE___THREAD
+       mov.l   .Lerrno1, r0
+       stc     gbr, r1
+       mov.l   @(r0, r12), r0
+       add     r1, r0
+       mov.l   r8, @r0
+#else
+       mov.l   .Lerrloc1, r1
+       bsrf    r1
+        nop
+.Lerrloc1b:
+       mov.l   r8, @r0
+#endif
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r12
+       rts
+        mov    #-1, r0
+
+       .align  2
+.Lgot1:
+       .long   _GLOBAL_OFFSET_TABLE_
+#if USE___THREAD
+.Lerrno1:
+       .long   errno@GOTTPOFF
+#else
+.Lerrloc1:
+       .long   __errno_location@PLT-(.Lerrloc1b+2-.)
+#endif
+       .size   __new_sem_trywait,.-__new_sem_trywait
+       .symver __new_sem_trywait, sem_trywait@@GLIBC_2.2
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
new file mode 100644 (file)
index 0000000..c275f20
--- /dev/null
@@ -0,0 +1,112 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include "lowlevel-atomic.h"
+
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+
+#define EINTR                  4
+#define EAGAIN                 11
+#define EWOULDBLOCK            EAGAIN
+#define EINVAL                 22
+#define ETIMEDOUT              110
+
+       .text
+
+       .globl  __new_sem_wait
+       .type   __new_sem_wait,@function
+       .align  5
+__new_sem_wait:
+       mov.l   r12, @-r15
+       mov.l   r8, @-r15
+       sts.l   pr, @-r15
+       mov     r4, r8
+3:
+       mov.l   @r8, r0
+2:
+       tst     r0, r0
+       bt      1f
+       mov     r0, r3
+       mov     r0, r4
+       add     #-1, r3
+       CMPXCHG (r4, @r8, r3, r2)
+       bf      2b
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r12
+       rts
+        mov    #0, r0
+
+1:
+       mov     r8, r4
+       mov     #FUTEX_WAIT, r5
+       mov     #0, r6
+       mov     #0, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       tst     r0, r0
+       bt      3b
+       cmp/eq  #-EWOULDBLOCK, r0
+       bt      3b
+       neg     r0, r0
+
+       mov     r0, r8
+       mova    .Lgot0, r0
+       mov.l   .Lgot0, r12
+       add     r0, r12
+
+#if USE___THREAD
+       mov.l   .Lerrno0, r0
+       stc     gbr, r1
+       mov.l   @(r0, r12), r0
+       add     r1, r0
+       mov.l   r8, @r0
+#else
+       mov.l   .Lerrloc0, r1
+       bsrf    r1
+        nop
+.Lerrloc0b:
+       mov.l   r8, @r0
+#endif
+       lds.l   @r15+, pr
+       mov.l   @r15+, r8
+       mov.l   @r15+, r12
+       rts
+        mov    #-1, r0
+
+       .align  2
+.Lgot0:
+       .long   _GLOBAL_OFFSET_TABLE_
+#if USE___THREAD
+.Lerrno0:
+       .long   errno@GOTTPOFF
+#else
+.Lerrloc0:
+       .long   __errno_location@PLT-(.Lerrloc0b+2-.)
+#endif
+       .size   __new_sem_wait,.-__new_sem_wait
+       .symver __new_sem_wait, sem_wait@@GLIBC_2.2
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
new file mode 100644 (file)
index 0000000..07bac6d
--- /dev/null
@@ -0,0 +1,140 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# define _IMM12 #-12
+# define _IMM16 #-16
+# define _IMP16 #16
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+  .text; \
+  ENTRY (name); \
+    SINGLE_THREAD_P; \
+    bf .Lpseudo_cancel; \
+    DO_CALL (syscall_name, args); \
+    mov r0,r1; \
+    mov _IMM12,r2; \
+    shad r2,r1; \
+    not r1,r1; \
+    tst r1,r1; \
+    bt .Lsyscall_error; \
+    bra .Lpseudo_end; \
+     nop; \
+ .Lpseudo_cancel: \
+    sts.l pr,@-r15; \
+    add _IMM16,r15; \
+    SAVE_ARGS_##args; \
+    CENABLE; \
+    LOAD_ARGS_##args; \
+    add _IMP16,r15; \
+    lds.l @r15+,pr; \
+    DO_CALL(syscall_name, args); \
+    SYSCALL_INST_PAD; \
+    sts.l pr,@-r15; \
+    mov.l r0,@-r15; \
+    CDISABLE; \
+    mov.l @r15+,r0; \
+    lds.l @r15+,pr; \
+    mov r0,r1; \
+    mov _IMM12,r2; \
+    shad r2,r1; \
+    not r1,r1; \
+    tst r1,r1; \
+    bf .Lpseudo_end; \
+ .Lsyscall_error: \
+    SYSCALL_ERROR_HANDLER; \
+ .Lpseudo_end:
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) \
+  END (sym)
+
+# define SAVE_ARGS_0   /* Nothing.  */
+# define SAVE_ARGS_1   SAVE_ARGS_0; mov.l r4,@(0,r15)
+# define SAVE_ARGS_2   SAVE_ARGS_1; mov.l r5,@(4,r15)
+# define SAVE_ARGS_3   SAVE_ARGS_2; mov.l r6,@(8,r15)
+# define SAVE_ARGS_4   SAVE_ARGS_3; mov.l r7,@(12,r15)
+# define SAVE_ARGS_5   SAVE_ARGS_4
+# define SAVE_ARGS_6   SAVE_ARGS_5
+
+# define LOAD_ARGS_0   /* Nothing.  */
+# define LOAD_ARGS_1   LOAD_ARGS_0; mov.l @(0,r15),r4
+# define LOAD_ARGS_2   LOAD_ARGS_1; mov.l @(4,r15),r5
+# define LOAD_ARGS_3   LOAD_ARGS_2; mov.l @(8,r15),r6
+# define LOAD_ARGS_4   LOAD_ARGS_3; mov.l @(12,r15),r7
+# define LOAD_ARGS_5   LOAD_ARGS_4
+# define LOAD_ARGS_6   LOAD_ARGS_5
+
+# ifdef IS_IN_libpthread
+#  define __local_enable_asynccancel   __pthread_enable_asynccancel
+#  define __local_disable_asynccancel  __pthread_disable_asynccancel
+# else
+#  define __local_enable_asynccancel   __libc_enable_asynccancel
+#  define __local_disable_asynccancel  __libc_disable_asynccancel
+# endif
+
+# define CENABLE \
+       mov.l 1f,r0; \
+       bsrf r0; \
+        nop; \
+     0: bra 2f; \
+        nop; \
+       .align 2; \
+     1: .long __local_enable_asynccancel - 0b; \
+     2:
+
+# define CDISABLE \
+       mov.l 1f,r0; \
+       bsrf r0; \
+        nop; \
+     0: bra 2f; \
+        nop; \
+       .align 2; \
+     1: .long __local_disable_asynccancel - 0b; \
+     2:
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+                                  header.data.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P \
+       stc gbr,r0; \
+       mov.w 0f,r1; \
+       sub r1,r0; \
+       mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
+       bra 1f; \
+        tst r0,r0; \
+     0: .word TLS_PRE_TCB_SIZE; \
+     1:
+
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif