about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/sh
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-05-29 05:38:43 +0000
committerUlrich Drepper <drepper@redhat.com>2003-05-29 05:38:43 +0000
commitea2630c63292c4c376c392dcbc6625a6aefa0d1e (patch)
tree7b2cfc0e31180b1de468f82bc1fa98ff0fb9b392 /nptl/sysdeps/unix/sysv/linux/sh
parent5a77f1501d9031c0fd8bad1d5a04b0379a99c029 (diff)
downloadglibc-ea2630c63292c4c376c392dcbc6625a6aefa0d1e.tar.gz
glibc-ea2630c63292c4c376c392dcbc6625a6aefa0d1e.tar.xz
glibc-ea2630c63292c4c376c392dcbc6625a6aefa0d1e.zip
Update.
2003-05-28  Kaz Kojima  <kkojima@rr.iij4u.or.jp>

	* sysdeps/sh/tcb-offsets.sym: Define MUTEX_FUTEX.
	* sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h (pthread_cond_t):
        Add __mutex field.
	* sysdeps/unix/sysv/linux/sh/lowlevellock.h (SYSCALL_WITH_INST_PAD):
	Define.
	(lll_futex_wait, lll_futex_wake): Define.
	* sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h: New file.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S: Try using
	FUTEX_REQUEUE instead of FUTEX_WAIT.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S: Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Remember
	mutex which was used in condvar structure.  Call
	__pthread_mutex_cond_lock instead of __pthread_mutex_lock_internal.
	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Likewise.

	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Don't
	include tcb-offsets.h.  Read wakeup value in locked region.
	Use the value of gbr register as THREAD_ID.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: Likewise.
	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: Likewise.

	* sysdeps/unix/sysv/linux/sh/sem_trywait.S: Remove futex related
	macros.
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/sh')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h58
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S27
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S18
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S27
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h4
12 files changed, 146 insertions, 57 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
index 09890d3a19..1eeae708e1 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/bits/pthreadtypes.h
@@ -79,6 +79,7 @@ typedef union
     unsigned long long int __total_seq;
     unsigned long long int __wakeup_seq;
     unsigned long long int __woken_seq;
+    void *__mutex;
   } __data;
   char __size[__SIZEOF_PTHREAD_COND_T];
   long long int __align;
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index 7e00fd01da..8ac8416011 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -73,6 +73,24 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	    if (__result) \
 	      __lll_mutex_lock_wait (__result, __futex); })
 
+/* Special version of lll_mutex_lock which causes the unlock function to
+   always wakeup waiters.  */
+#define lll_mutex_cond_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" (2) \
+		: "r0", "r1", "memory"); \
+	    if (__result) \
+	      __lll_mutex_lock_wait (__result, __futex); })
+
 #define lll_mutex_timedlock(futex, timeout) \
   ({ int __result, val, *__futex = &(futex); \
      __asm __volatile ("\
@@ -121,6 +139,46 @@ typedef int lll_lock_t;
 #define LLL_LOCK_INITIALIZER_LOCKED	(0)
 
 
+# ifdef NEED_SYSCALL_INST_PAD
+#  define SYSCALL_WITH_INST_PAD "\
+	trapa #0x14; or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0"
+# else
+#  define SYSCALL_WITH_INST_PAD "\
+	trapa #0x14"
+# endif
+
+#define lll_futex_wait(futex, val) \
+  do { \
+    int __ignore; \
+    register unsigned long __r3 asm ("r3") = SYS_futex; \
+    register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
+    register unsigned long __r5 asm ("r5") = FUTEX_WAIT; \
+    register unsigned long __r6 asm ("r6") = (unsigned long) (val); \
+    register unsigned long __r7 asm ("r7") = 0; \
+    __asm __volatile (SYSCALL_WITH_INST_PAD \
+		      : "=z" (__ignore) \
+		      : "r" (__r3), "r" (__r4), "r" (__r5), \
+			"r" (__r6), "r" (__r7) \
+		      : "memory", "t"); \
+  } while (0)
+
+
+#define lll_futex_wake(futex, nr) \
+  do { \
+    int __ignore; \
+    register unsigned long __r3 asm ("r3") = SYS_futex; \
+    register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
+    register unsigned long __r5 asm ("r5") = FUTEX_WAKE; \
+    register unsigned long __r6 asm ("r6") = (unsigned long) (nr); \
+    register unsigned long __r7 asm ("r7") = 0; \
+    __asm __volatile (SYSCALL_WITH_INST_PAD \
+		      : "=z" (__ignore) \
+		      : "r" (__r3), "r" (__r4), "r" (__r5), \
+			"r" (__r6), "r" (__r7) \
+		      : "memory", "t"); \
+  } while (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;
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
index 8dd31aac29..3aba58de14 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
@@ -19,12 +19,15 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
+#include <kernel-features.h>
 #include "lowlevel-atomic.h"
 
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_REQUEUE		3
 
+#define EINVAL			22
 
 	.text
 
@@ -33,6 +36,7 @@
 	.type	__pthread_cond_broadcast, @function
 	.align	5
 __pthread_cond_broadcast:
+	mov.l   r9, @-r15
 	mov.l	r8, @-r15
 	sts.l	pr, @-r15
 	mov	r4, r8
@@ -64,6 +68,9 @@ __pthread_cond_broadcast:
 	mov.l	r1, @(wakeup_seq,r8)
 	mov.l	r0, @(wakeup_seq+4,r8)
 
+	/* Get the address of the mutex used.  */
+	mov.l	@(dep_mutex,r8), r9
+
 	/* Unlock.  */
 #if cond_lock != 0
 	DEC (@(cond_lock,r8), r2)
@@ -76,6 +83,19 @@ __pthread_cond_broadcast:
 	/* Wake up all threads.  */
 	mov	r8, r4
 	add	#wakeup_seq, r4
+#ifdef __ASSUME_FUTEX_REQUEUE
+	mov	#FUTEX_REQUEUE, r5
+	mov	#1, r6
+	mov	#-1, r7
+	shlr	r7		/* r7 = 0x7fffffff */
+	mov	r9, r0
+# if MUTEX_FUTEX != 0
+	add	#MUTEX_FUTEX, r0
+# endif
+	mov	#SYS_futex, r3
+	extu.b	r3, r3
+	trapa	#0x15
+#else
 	mov	#FUTEX_WAKE, r5
 	mov	#-1, r6
 	shlr	r6		/* r6 = 0x7fffffff */
@@ -83,12 +103,14 @@ __pthread_cond_broadcast:
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
+#endif
 	SYSCALL_INST_PAD
 
 	mov	#0, r0
 	lds.l	@r15+, pr
+	mov.l	@r15+, r8
 	rts
-	 mov.l	@r15+, r8
+	 mov.l	@r15+, r9
 
 4:
 	/* Unlock.  */
@@ -102,8 +124,9 @@ __pthread_cond_broadcast:
 6:
 	mov	#0, r0
 	lds.l	@r15+, pr
+	mov.l	@r15+, r8
 	rts
-	 mov.l	@r15+, r8
+	 mov.l	@r15+, r9
 
 1:
 	/* Initial locking failed.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
index a00064153f..8248b3b415 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_signal.S
@@ -19,12 +19,15 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
+#include <kernel-features.h>
 #include "lowlevel-atomic.h"
 
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_REQUEUE		3
 
+#define EINVAL			22
 
 	.text
 
@@ -70,15 +73,28 @@ __pthread_cond_signal:
 	mov.l	r0,@(wakeup_seq,r8)
 	mov.l	r1,@(wakeup_seq+4,r8)
 
-	/* Wake up one thread.  */
 	mov	r8, r4
 	add	#wakeup_seq, r4
+#ifdef __ASSUME_FUTEX_REQUEUE
+	/* Wake up one thread by moving it to the internal lock futex.  */
+	mov	#FUTEX_REQUEUE, r5
+	mov	#0, r6
+	mov	#1, r7
+	mov	r8, r0
+# if cond_lock != 0
+	add	#cond_lock, r0
+# endif
+	mov	#SYS_futex, r3
+	extu.b	r3, r3
+	trapa	#0x15
+#else
 	mov	#FUTEX_WAKE, r5
 	mov	#1, r6
 	mov	#0, r7
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
+#endif
 	SYSCALL_INST_PAD
 
 4:
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
index 6ad987d005..5de20dd799 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
@@ -58,6 +58,10 @@ __pthread_cond_timedwait:
 	bra	1f
 	 nop
 2:
+	/* Store the reference to the mutex.  If there is already a
+	   different value in there this is a bad user bug.  */
+	mov.l	r9, @(dep_mutex,r8)
+	
 	/* Unlock the mutex.  */
 	mov.l	.Lmunlock1, r1
 	bsrf	r1
@@ -117,12 +121,11 @@ __pthread_cond_timedwait:
 	bra	3f
 	 nop
 4:
-	mov	r15, r4
 	mov.l	.Lenable1, r1
 	bsrf	r1
-	 add	#8, r4
-
+	 nop
 .Lenable1b:
+	mov.l	r0, @(8,r15)
 
 	/* Get current time.  */
 	mov	r15, r4
@@ -258,7 +261,7 @@ __pthread_cond_timedwait:
 	mov	r9, r4
 	mov.l	.Lmlocki1, r1
 	bsrf	r1
-	 mov	#0, r5
+	 nop
 .Lmlocki1b:
 
 	/* We return the result of the mutex_lock operation if it failed.  */
@@ -293,13 +296,13 @@ __pthread_cond_timedwait:
 .Lccpush1:
 	.long	__pthread_cleanup_push-.Lccpush1b
 .Lenable1:
-	.long	__pthread_enable_asynccancel_2-.Lenable1b
+	.long	__pthread_enable_asynccancel-.Lenable1b
 .Ldisable1:
 	.long	__pthread_disable_asynccancel-.Ldisable1b
 .Lcpop1:
 	.long	__pthread_cleanup_pop-.Lcpop1b
 .Lmlocki1:
-	.long	__pthread_mutex_lock_internal-.Lmlocki1b
+	.long	__pthread_mutex_cond_lock-.Lmlocki1b
 .L1g:
 	.long	1000000000
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
index a32df21f29..f4f0edb0e6 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
@@ -108,18 +108,11 @@ __condvar_cleanup:
 	trapa	#0x14
 	SYSCALL_INST_PAD
 
-	/* Lock the mutex unless asynchronous cancellation is in effect.  */
-	mov.l	@(8,r9), r0
-	and	#2, r0
-	tst	r0, r0
-	bf	3f
-
 	mov.l	.Lmlocki1, r1
 	bsrf	r1
-	 mov.l	@r9, r4
+	 mov.l	@(8,r9), r4
 .Lmlocki1b:
 
-3:
 	lds.l	@r15+, pr
 	mov.l	@r15+, r9
 	rts
@@ -131,7 +124,7 @@ __condvar_cleanup:
 .Lwake0:
 	.long	__lll_mutex_unlock_wake-.Lwake0b
 .Lmlocki1:
-	.long	__pthread_mutex_lock_internal-.Lmlocki1b
+	.long	__pthread_mutex_cond_lock-.Lmlocki1b
 	.size	__condvar_cleanup, .-__condvar_cleanup
 
 
@@ -157,7 +150,11 @@ __pthread_cond_wait:
 #endif
 	tst	r2, r2
 	bf	1f
-2:	
+
+	/* Store the reference to the mutex.  If there is already a
+	   different value in there this is a bad user bug.  */
+	mov.l	r9, @(dep_mutex,r8)
+
 	/* Unlock the mutex.  */
 	mov.l	.Lmunlock0, r1
 	bsrf	r1
@@ -215,11 +212,11 @@ __pthread_cond_wait:
 	tst	r2, r2
 	bf	3f
 4:
-	mov	r15, r4
 	mov.l	.Lenable0, r1
 	bsrf	r1
-	 add	#8, r4
+	 nop
 .Lenable0b:
+	mov.l	r0, @(8,r15)
 
 	mov	#0, r7
 	mov	#FUTEX_WAIT, r5
@@ -300,7 +297,7 @@ __pthread_cond_wait:
 	mov	r9, r4
 	mov.l	.Lmlocki0, r1
 	bsrf	r1
-	 mov	#0, r5
+	 nop
 .Lmlocki0b:
 	/* We return the result of the mutex_lock operation.  */
 
@@ -327,13 +324,13 @@ __pthread_cond_wait:
 .Lccpush0:
 	.long	__pthread_cleanup_push-.Lccpush0b
 .Lenable0:
-	.long	__pthread_enable_asynccancel_2-.Lenable0b
+	.long	__pthread_enable_asynccancel-.Lenable0b
 .Ldisable0:
 	.long	__pthread_disable_asynccancel-.Ldisable0b
 .Lcpop0:
 	.long	__pthread_cleanup_pop-.Lcpop0b
 .Lmlocki0:
-	.long	__pthread_mutex_lock_internal-.Lmlocki0b
+	.long	__pthread_mutex_cond_lock-.Lmlocki0b
 
 1:
 	/* Initial locking failed.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
index 27aecad314..14da24ec86 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
@@ -18,7 +18,6 @@
 
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
-#include <tcb-offsets.h>
 #include <pthread-errnos.h>
 #include "lowlevel-atomic.h"
 
@@ -34,6 +33,7 @@
 	.align	5
 __pthread_rwlock_rdlock:
 	mov.l	r12, @-r15
+	mov.l	r9, @-r15
 	mov.l	r8, @-r15
 	sts.l	pr, @-r15
 	mov	r4, r8
@@ -64,6 +64,8 @@ __pthread_rwlock_rdlock:
 	tst	r0, r0
 	bt	4f
 
+	mov.l	@(READERS_WAKEUP,r8), r9
+
 #if MUTEX == 0
 	DEC (@r8, r2)
 #else
@@ -75,7 +77,7 @@ __pthread_rwlock_rdlock:
 	mov	r8, r4
 	add	#READERS_WAKEUP, r4
 	mov	#FUTEX_WAIT, r5
-	mov.l	@(READERS_WAKEUP,r8), r6
+	mov	r9, r6
 	mov	#0, r7
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
@@ -116,6 +118,7 @@ __pthread_rwlock_rdlock:
 7:
 	lds.l	@r15+, pr
 	mov.l	@r15+, r8
+	mov.l	@r15+, r9
 	mov.l	@r15+, r12
 	rts
 	 mov	r3, r0
@@ -134,8 +137,6 @@ __pthread_rwlock_rdlock:
 	 nop
 14:
 	stc	gbr, r1
-	mov.w	.Ltcboff,r2
-	sub	r2,r1
 	cmp/eq	r1, r0
 	bf	3b
 	/* Deadlock detected.  */
@@ -195,8 +196,6 @@ __pthread_rwlock_rdlock:
 	bra	13b
 	 nop
 
-.Ltcboff:
-	.word	TLS_PRE_TCB_SIZE
 	.align	2
 .Lwait0:
 	.long	__lll_mutex_lock_wait-.Lwait0b
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
index 6f3f67e07b..5f1c1f739a 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
@@ -18,7 +18,6 @@
 
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
-#include <tcb-offsets.h>
 #include <pthread-errnos.h>
 #include "lowlevel-atomic.h"
 
@@ -35,6 +34,7 @@
 	.align	5
 pthread_rwlock_timedrdlock:
 	mov.l	r12, @-r15
+	mov.l	r10, @-r15
 	mov.l	r9, @-r15
 	mov.l	r8, @-r15
 	sts.l	pr, @-r15
@@ -74,6 +74,8 @@ pthread_rwlock_timedrdlock:
 	tst	r0, r0
 	bt	4f
 
+	mov.l	@(READERS_WAKEUP,r8), r10
+
 #if MUTEX == 0
 	DEC (@r8, r2)
 #else
@@ -115,7 +117,7 @@ pthread_rwlock_timedrdlock:
 	/* Futex call.  */
 	mov	r15, r7
 	mov	#FUTEX_WAIT, r5
-	mov.l	@(READERS_WAKEUP,r8), r6
+	mov	r10, r6
 	mov	r8, r4
 	add	#READERS_WAKEUP, r4
 	mov	#SYS_futex, r3
@@ -169,6 +171,7 @@ pthread_rwlock_timedrdlock:
 	lds.l	@r15+, pr
 	mov.l	@r15+, r8
 	mov.l	@r15+, r9
+	mov.l	@r15+, r10
 	mov.l	@r15+, r12
 	rts
 	 mov	r3, r0
@@ -193,8 +196,6 @@ pthread_rwlock_timedrdlock:
 	 nop
 14:
 	stc	gbr, r1
-	mov.w	.Ltcboff,r2
-	sub	r2,r1
 	cmp/eq	r1, r0
 	bf	3b
 	/* Deadlock detected.  */
@@ -262,8 +263,6 @@ pthread_rwlock_timedrdlock:
 	bra	9b
 	 mov	#EINVAL, r3
 
-.Ltcboff:
-	.word	TLS_PRE_TCB_SIZE
 	.align	2
 .Lwait2:
 	.long	__lll_mutex_lock_wait-.Lwait2b
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
index 89bdc76d37..36febf484e 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
@@ -18,7 +18,6 @@
 
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
-#include <tcb-offsets.h>
 #include <pthread-errnos.h>
 #include "lowlevel-atomic.h"
 
@@ -35,6 +34,7 @@
 	.align	5
 pthread_rwlock_timedwrlock:
 	mov.l	r12, @-r15
+	mov.l	r10, @-r15
 	mov.l	r9, @-r15
 	mov.l	r8, @-r15
 	sts.l	pr, @-r15
@@ -71,6 +71,8 @@ pthread_rwlock_timedwrlock:
 	tst	r0, r0
 	bt	4f
 
+	mov.l	@(WRITERS_WAKEUP,r8), r10
+
 #if MUTEX == 0
 	DEC (@r8, r2)
 #else
@@ -112,7 +114,7 @@ pthread_rwlock_timedwrlock:
 	/* Futex call.  */
 	mov	r15, r7
 	mov	#FUTEX_WAIT, r5
-	mov.l	@(WRITERS_WAKEUP,r8), r6
+	mov	r10, r6
 	mov	r8, r4
 	add	#WRITERS_WAKEUP, r4
 	mov	#SYS_futex, r3
@@ -152,8 +154,6 @@ pthread_rwlock_timedwrlock:
 5:
 	mov	#0, r3
 	stc	gbr, r0
-	mov.w	.Ltcboff,r2
-	sub	r2,r0
 	mov.l	r0, @(WRITER,r8)
 9:
 #if MUTEX == 0
@@ -168,6 +168,7 @@ pthread_rwlock_timedwrlock:
 	lds.l	@r15+, pr
 	mov.l	@r15+, r8
 	mov.l	@r15+, r9
+	mov.l	@r15+, r10
 	mov.l	@r15+, r12
 	rts
 	 mov	r3, r0
@@ -192,8 +193,6 @@ pthread_rwlock_timedwrlock:
 	 nop
 14:
 	stc	gbr, r1
-	mov.w	.Ltcboff,r2
-	sub	r2,r1
 	cmp/eq	r1, r0
 	bf	3b
 	bra	9b
@@ -247,8 +246,6 @@ pthread_rwlock_timedwrlock:
 	bra	17b
 	 mov	#-ETIMEDOUT, r3
 
-.Ltcboff:
-	.word	TLS_PRE_TCB_SIZE
 	.align	2
 .Lwait6:
 	.long	__lll_mutex_lock_wait-.Lwait6b
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
index 1456292a73..b923c8846b 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
@@ -18,7 +18,6 @@
 
 #include <sysdep.h>
 #include <lowlevelrwlock.h>
-#include <tcb-offsets.h>
 #include <pthread-errnos.h>
 #include "lowlevel-atomic.h"
 
@@ -34,6 +33,7 @@
 	.align	5
 __pthread_rwlock_wrlock:
 	mov.l	r12, @-r15
+	mov.l	r9, @-r15
 	mov.l	r8, @-r15
 	sts.l	pr, @-r15
 	mov	r4, r8
@@ -61,6 +61,8 @@ __pthread_rwlock_wrlock:
 	tst	r0, r0
 	bt	4f
 
+	mov.l	@(WRITERS_WAKEUP,r8), r9
+
 #if MUTEX == 0
 	DEC (@r8, r2)
 #else
@@ -72,7 +74,7 @@ __pthread_rwlock_wrlock:
 	mov	r8, r4
 	add	#WRITERS_WAKEUP, r4
 	mov	#FUTEX_WAIT, r5
-	mov.l	@(WRITERS_WAKEUP,r8), r6
+	mov	r9, r6
 	mov	#0, r7
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
@@ -97,8 +99,6 @@ __pthread_rwlock_wrlock:
 5:
 	mov	#0, r3
 	stc	gbr, r0
-	mov.w	.Ltcboff,r2
-	sub	r2,r0
 	mov.l	r0, @(WRITER,r8)
 9:
 #if MUTEX == 0
@@ -111,6 +111,7 @@ __pthread_rwlock_wrlock:
 7:
 	lds.l	@r15+, pr
 	mov.l	@r15+, r8
+	mov.l	@r15+, r9
 	mov.l	@r15+, r12
 	rts
 	 mov	r3, r0
@@ -129,8 +130,6 @@ __pthread_rwlock_wrlock:
 	 nop
 14:
 	stc	gbr, r1
-	mov.w	.Ltcboff,r2
-	sub	r2,r1
 	cmp/eq	r1, r0
 	bf	3b
 	bra	9b
@@ -179,8 +178,6 @@ __pthread_rwlock_wrlock:
 	bra	13b
 	 nop
 
-.Ltcboff:
-	.word	TLS_PRE_TCB_SIZE
 	.align	2
 .Lwait4:
 	.long	__lll_mutex_lock_wait-.Lwait4b
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
index fc505b4af5..0091e53e7c 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
@@ -22,11 +22,6 @@
 #include "lowlevel-atomic.h"
 
 
-#define SYS_gettimeofday	__NR_gettimeofday
-#define SYS_futex		240
-#define FUTEX_WAIT		0
-#define FUTEX_WAKE		1
-
 	.text
 
 	.globl	__new_sem_trywait
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
new file mode 100644
index 0000000000..8cdcac5560
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sh4/lowlevellock.h
@@ -0,0 +1,4 @@
+/*  4 instruction cycles not accessing cache and TLB are needed after
+    trapa instruction to avoid an SH-4 silicon bug.  */
+#define NEED_SYSCALL_INST_PAD
+#include <sysdeps/unix/sysv/linux/sh/lowlevellock.h>