summaryrefslogtreecommitdiff
path: root/lib/libpthread
diff options
context:
space:
mode:
authorscw <scw@NetBSD.org>2003-01-22 13:52:48 +0000
committerscw <scw@NetBSD.org>2003-01-22 13:52:48 +0000
commitb5ca8aee09e4df6cfcc5b1393e36749027a7e452 (patch)
treea439633c4d8547f2b4fb9737f16231d5cf424811 /lib/libpthread
parent04c6e0b1412ebd1232ccd8b4cfff21d80c293db1 (diff)
Yay! Working pthreads for sh5.
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/arch/sh5/_context_u.S17
-rw-r--r--lib/libpthread/arch/sh5/genassym.cf4
-rw-r--r--lib/libpthread/arch/sh5/pthread_md.h4
-rw-r--r--lib/libpthread/arch/sh5/pthread_switch.S184
4 files changed, 103 insertions, 106 deletions
diff --git a/lib/libpthread/arch/sh5/_context_u.S b/lib/libpthread/arch/sh5/_context_u.S
index bed5df55089..a3a4a3e1798 100644
--- a/lib/libpthread/arch/sh5/_context_u.S
+++ b/lib/libpthread/arch/sh5/_context_u.S
@@ -1,4 +1,4 @@
-/* $NetBSD: _context_u.S,v 1.2 2003/01/21 11:31:38 scw Exp $ */
+/* $NetBSD: _context_u.S,v 1.3 2003/01/22 13:52:48 scw Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@@ -50,12 +50,14 @@
*/
#define GETC \
st.q r2, UC_REGS_PC, r18 ;\
+ st.q r2, UC_REGS_R2, r63 ;\
st.q r2, UC_REGS_R10, r10 ;\
st.q r2, UC_REGS_R11, r11 ;\
st.q r2, UC_REGS_R12, r12 ;\
st.q r2, UC_REGS_R13, r13 ;\
st.q r2, UC_REGS_R14, r14 ;\
st.q r2, UC_REGS_SP, r15 ;\
+ st.q r2, UC_REGS_R18, r18 ;\
st.q r2, UC_REGS_R26, r26 ;\
st.q r2, UC_REGS_R27, r27 ;\
st.q r2, UC_REGS_R28, r28 ;\
@@ -89,7 +91,7 @@
st.q r2, UC_REGS_TR6, r0 ;\
gettr tr7, r0 ;\
st.q r2, UC_REGS_TR7, r0 ;\
- pta/l 3f, tr0 ;\
+ pta/l 4f, tr0 ;\
st.q r2, UC_REGS_USR, r1 ;\
fgetscr fr0 ;\
shlri r1, SH5_CONREG_USR_FPRS_SHIFT, r1 ;\
@@ -122,8 +124,10 @@
fst.d r2, UC_FPREGS_DR58, dr58 ;\
fst.d r2, UC_FPREGS_DR60, dr60 ;\
fst.d r2, UC_FPREGS_DR62, dr62 ;\
- ori r3, _UC_FPU, r3 ;\
-3: st.l r2, UC_FLAGS, r3
+3: ori r3, _UC_FPU, r3 ;\
+4: ld.q r2, UC_REGS_USR, r1 ;\
+ st.l r2, UC_FLAGS, r3 ;\
+ putcon r1, usr
/*
* Restore the context pointed to by r2
@@ -139,7 +143,7 @@
* jump to the new context. Which just isn't \
* quite good enough. Sigh.) \
*/ \
- ld.q r2, UC_FLAGS, r3 ;\
+ ld.l r2, UC_FLAGS, r3 ;\
ld.q r2, UC_REGS_R10, r10 ;\
shlri r3, _UC_USER_BIT, r0 ;\
ld.q r2, UC_REGS_R11, r11 ;\
@@ -149,6 +153,7 @@
beq/u r0, r63, tr0 ;\
ld.q r2, UC_REGS_R13, r13 ;\
ld.q r2, UC_REGS_R14, r14 ;\
+ ld.q r2, UC_REGS_R18, r18 ;\
ld.q r2, UC_REGS_R26, r26 ;\
ld.q r2, UC_REGS_R27, r27 ;\
ld.q r2, UC_REGS_R28, r28 ;\
@@ -223,7 +228,7 @@
\
4: pta/l _C_LABEL(setcontext), tr0 ;\
blink tr0, r18 ;\
- trapa r63 /* Catch setcontex() failure */
+ brk /* Catch setcontext() failure */
/*
diff --git a/lib/libpthread/arch/sh5/genassym.cf b/lib/libpthread/arch/sh5/genassym.cf
index f3662c53799..d96a5f201cd 100644
--- a/lib/libpthread/arch/sh5/genassym.cf
+++ b/lib/libpthread/arch/sh5/genassym.cf
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.2 2003/01/21 11:30:52 scw Exp $
+# $NetBSD: genassym.cf,v 1.3 2003/01/22 13:52:48 scw Exp $
# Copyright (c) 2001 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -56,11 +56,13 @@ define UC_FLAGS offsetof(ucontext_t, uc_flags)
define UC_REGS_PC offsetof(ucontext_t, uc_mcontext.__gregs[_REG_PC])
define UC_REGS_SP offsetof(ucontext_t, uc_mcontext.__gregs[_REG_SP])
define UC_REGS_USR offsetof(ucontext_t, uc_mcontext.__gregs[_REG_USR])
+define UC_REGS_R2 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(2)])
define UC_REGS_R10 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(10)])
define UC_REGS_R11 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(11)])
define UC_REGS_R12 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(12)])
define UC_REGS_R13 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(13)])
define UC_REGS_R14 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(14)])
+define UC_REGS_R18 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(18)])
define UC_REGS_R26 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(26)])
define UC_REGS_R27 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(27)])
define UC_REGS_R28 offsetof(ucontext_t, uc_mcontext.__gregs[_REG_R(28)])
diff --git a/lib/libpthread/arch/sh5/pthread_md.h b/lib/libpthread/arch/sh5/pthread_md.h
index 242d877c094..ca02bb64c6d 100644
--- a/lib/libpthread/arch/sh5/pthread_md.h
+++ b/lib/libpthread/arch/sh5/pthread_md.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_md.h,v 1.1 2003/01/21 00:34:56 scw Exp $ */
+/* $NetBSD: pthread_md.h,v 1.2 2003/01/22 13:52:48 scw Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@@ -52,7 +52,7 @@ pthread__sp(void)
#define pthread__uc_pc(ucp) ((ucp)->uc_mcontext.__gregs[_REG_PC])
/*
- * SH5 needs no additional stack space below ucontext_t
+ * SH5 requires no extra stack space
*/
#define STACKSPACE 0
diff --git a/lib/libpthread/arch/sh5/pthread_switch.S b/lib/libpthread/arch/sh5/pthread_switch.S
index 347c5df82b7..25af299a069 100644
--- a/lib/libpthread/arch/sh5/pthread_switch.S
+++ b/lib/libpthread/arch/sh5/pthread_switch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_switch.S,v 1.2 2003/01/21 11:31:38 scw Exp $ */
+/* $NetBSD: pthread_switch.S,v 1.3 2003/01/22 13:52:48 scw Exp $ */
/*-
* Copyright (c) 2001, 2003 The NetBSD Foundation, Inc.
@@ -50,6 +50,13 @@
* as well as some utility code used by these routines.
*/
+/*
+ * Utility macro to switch to the stack of another thread.
+ */
+#define STACK_SWITCH(pt,tmp) \
+ LDPTR pt, PT_UC, tmp ;\
+ addi tmp, -STACKSPACE, r15
+
/*
* void pthread__switch(pthread_t self, pthread_t next);
@@ -59,51 +66,20 @@
* main purpose is to be a basic switch engine when the MI code is
* already dealing with spin-preemption or other gunk.
*/
-
ENTRY(pthread__switch)
- LINK_BIG_FRAME(RND_CTXSIZE) /* Make space for a ucontext_t */
pta/l _C_LABEL(_swapcontext_u), tr0
- STPTR r2, PT_UC, r15 /* self->pt_uc = &ucontext_t */
+ movi RND_CTXSIZE+8, r0
+ sub r15, r0, r15
+ st.q r15, RND_CTXSIZE, r18
+ STPTR r2, PT_UC, r15
+ LDPTR r3, PT_UC, r3
+ or r15, r63, r2
blink tr0, r18
- UNLINK_BIG_FRAME(RND_CTXSIZE)
+ ld.q r15, RND_CTXSIZE, r18
ptabs/l r18, tr0
- blink tr0, r18
-
-
-/*
- * Utility macro to switch to the stack of another thread.
- */
-#define STACK_SWITCH(pt,tmp) \
- LDPTR pt, PT_UC, tmp ;\
- or tmp, r63, r15
-
-/*
- * Helper switch code used by pthread__locked_switch() and
- * pthread__upcall_switch() when they discover spinlock preemption.
- *
- * Call with:
- * r20 = from, r23 = to
- */
-Lpthread__switch_away_decrement:
- STACK_SWITCH(r23,r2)
-
- /* If we're invoked from the switch-to-next provisions of
- * pthread__locked_switch or pthread__upcall_switch, there
- * may be a fake spinlock-count set. If so, we decrement it
- * once we're no longer using the old stack.
- */
- pta/l _C_LABEL(_setcontext_u), tr0
- ld.l r20, PT_SPINLOCKS, r0
- addi r0, -1, r0
- st.l r20, PT_SPINLOCKS, r0
- blink tr0, r63
- /* NOTREACHED */
-
-Lpthread__switch_away_no_decrement:
- STACK_SWITCH(r23,r2)
- pta/l _C_LABEL(_setcontext_u), tr0
+ movi RND_CTXSIZE+8, r0
+ add r15, r0, r15
blink tr0, r63
- /* NOTREACHED */
/*
@@ -115,7 +91,12 @@ Lpthread__switch_away_no_decrement:
* r2 = self, r3 = next, r4 = lock
*/
ENTRY(pthread__locked_switch)
- LINK_BIG_FRAME(RND_CTXSIZE)
+ movi RND_CTXSIZE+32, r0
+ sub r15, r0, r15
+ st.q r15, RND_CTXSIZE, r28
+ st.q r15, RND_CTXSIZE+8, r29
+ st.q r15, RND_CTXSIZE+16, r30
+ st.q r15, RND_CTXSIZE+24, r18
/* Make sure we get continued */
ld.l r3, PT_SPINLOCKS, r0
@@ -124,20 +105,15 @@ ENTRY(pthread__locked_switch)
/*
* Keep r2-r4, and r15 safe for later.
- * We know that r19-r22 are not clobbered by libc's context routines.
- *
- * XXX: This might not remain the case once the dynamic linker gets
- * XXX: in the way of things.
*/
- or r2, r63, r19 /* self */
- or r3, r63, r20 /* next */
- or r4, r63, r21 /* lock */
- or r15, r63, r22 /* Our ucontext_t structure */
- STPTR r2, PT_UC, r22
+ pta/l _C_LABEL(_getcontext_u), tr0
+ or r2, r63, r28 /* self */
+ or r3, r63, r29 /* next */
+ or r4, r63, r30 /* lock */
+ STPTR r2, PT_UC, r15 /* self->pt_uc = ctx */
/* Save the current context */
- pta/l _C_LABEL(_getcontext_u), tr0
- or r22, r63, r2
+ or r15, r63, r2
blink tr0, r18
/*
@@ -146,18 +122,19 @@ ENTRY(pthread__locked_switch)
*/
pta/u Llocked_return_point, tr0
gettr tr0, r0
- st.q r22, UC_REGS_PC, r0
+ st.q r15, UC_REGS_PC, r0
+ or r15, r63 ,r3
- STACK_SWITCH(r20,r2) /* r2 = next->pt_uc */
+ pta/l Llocked_no_old_preempt, tr0
+ STACK_SWITCH(r29, r2) /* r2 = next->pt_uc */
/* Now running on `next's stack. */
/* Check if the original thread was preempted while holding
* its queue lock.
*/
- pta/l Llocked_no_old_preempt, tr0
- LDPTR r19, PT_NEXT, r23 /* self->pt_next == NULL? */
- beq/l r23, r63, tr0 /* Jump if not preempted */
+ LDPTR r28, PT_NEXT, r1 /* self->pt_next == NULL? */
+ beq/l r1, r63, tr0 /* Jump if not preempted */
/* Yes, it was. Stash the thread we were going to
* switch to, the lock the original thread was holding,
@@ -168,61 +145,75 @@ ENTRY(pthread__locked_switch)
* PT_SWITCHTO will be stomped by another switch_lock and
* preemption.
*/
- STPTR r19, PT_SWITCHTO, r20 /* self->pt_switchto = next */
- STPTR r19, PT_SWITCHTOUC, r2 /* self->pt_switchtouc = uc */
- STPTR r19, PT_HELDLOCK, r21 /* self->pt_heldlock = lock */
- ld.l r19, PT_SPINLOCKS, r0
+ STPTR r28, PT_SWITCHTO, r29 /* self->pt_switchto = next */
+ STPTR r28, PT_SWITCHTOUC, r2 /* self->pt_switchtouc = uc */
+ STPTR r28, PT_HELDLOCK, r30 /* self->pt_heldlock = lock */
+ ld.l r28, PT_SPINLOCKS, r0
addi r0, -1, r0
- st.l r19, PT_SPINLOCKS, r0
+ st.l r28, PT_SPINLOCKS, r0
/* Save the context we previously stored in self->pt_uc
* that was overwritten when we were preempted and continued,
* so we need to put it somewhere.
*/
- pta/l Lpthread__switch_away_decrement, tr0
- STPTR r19, PT_SLEEPUC, r22
+ STPTR r28, PT_SLEEPUC, r3
+
+ pta/l _C_LABEL(_setcontext_u), tr0
+ STACK_SWITCH(r1, r2)
+
+ /* If we're invoked from the switch-to-next provisions of
+ * pthread__locked_switch or pthread__upcall_switch, there
+ * may be a fake spinlock-count set. If so, we decrement it
+ * once we're no longer using the old stack.
+ */
+ ld.l r29, PT_SPINLOCKS, r0
+ addi r0, -1, r0
+ st.l r29, PT_SPINLOCKS, r0
blink tr0, r63
/* NOTREACHED */
-
Llocked_no_old_preempt:
- /* r21 = lock, r20 = next, r19 = self, r2 = next->pt_uc */
+ /* r30 = lock, r29 = next, r28 = self, r2 = next->pt_uc */
/* We've moved to the new stack, and the old context has been
* saved. The queue lock can be released.
*/
- ld.l r19, PT_SPINLOCKS, r0 /* self->pt_spinlocks-- */
+ ld.l r28, PT_SPINLOCKS, r0 /* self->pt_spinlocks-- */
addi r0, -1, r0
- st.l r19, PT_SPINLOCKS, r0
+ st.l r28, PT_SPINLOCKS, r0
/* We happen to know that this is the right way to release a lock. */
- st.q r21, 0, r63 /* *lock = 0 */
+ st.q r30, 0, r63 /* *lock = 0 */
+ pta/l _C_LABEL(_setcontext_u), tr0
/* Remove the fake lock */
- ld.l r20, PT_SPINLOCKS, r0 /* next->pt_spinlocks-- */
+ ld.l r29, PT_SPINLOCKS, r0 /* next->pt_spinlocks-- */
addi r0, -1, r0
- st.l r20, PT_SPINLOCKS, r0
+ st.l r29, PT_SPINLOCKS, r0
/* Check if we were preempted while holding the fake lock. */
- pta/l _C_LABEL(_setcontext_u), tr0
- LDPTR r20, PT_NEXT, r23 /* next->pt_next == NULL? */
- beq/l r23, r63, tr0 /* Jump if not preempted */
+ LDPTR r29, PT_NEXT, r1 /* next->pt_next == NULL? */
+ beq/l r1, r63, tr0 /* _setcontext() if not preempted */
/* Yes, we were. Bummer. Go to the next element in the chain. */
- pta/l Lpthread__switch_away_no_decrement, tr0
- STPTR r20, PT_SWITCHTO, r20 /* next->pt_switchto = next */
- STPTR r20, PT_SWITCHTOUC, r2
+ STPTR r29, PT_SWITCHTO, r29 /* next->pt_switchto = next */
+ STPTR r29, PT_SWITCHTOUC, r2
+ STACK_SWITCH(r1, r2)
blink tr0, r63
/* NOTREACHED */
Llocked_return_point:
/* We're back on the original stack. */
- UNLINK_BIG_FRAME(RND_CTXSIZE)
+ ld.q r15, RND_CTXSIZE+24, r18
+ movi RND_CTXSIZE+32, r0
+ ld.q r15, RND_CTXSIZE+16, r30
ptabs/l r18, tr0
+ ld.q r15, RND_CTXSIZE+8, r29
+ ld.q r15, RND_CTXSIZE, r28
+ add r15, r0, r15
blink tr0, r18
-
/*
* void pthread__upcall_switch(pthread_t self, pthread_t next);
*
@@ -233,50 +224,49 @@ Llocked_return_point:
ENTRY(pthread__upcall_switch)
/* Create a `fake' lock count so we are `continued' */
ld.l r3, PT_SPINLOCKS, r0
+ pta/l Lupcall_no_old_preempt, tr0
addi r0, 1, r0
st.l r3, PT_SPINLOCKS, r0
- STACK_SWITCH(r3,r28) /* r28 = next->pt_uc */
-
- /* a4 = r19 */
+ STACK_SWITCH(r3, r28) /* r28 = next->pt_uc */
/* Check if the upcall was preempted and continued. */
- pta/l Lupcall_no_old_preempt, tr0
- LDPTR r2, PT_NEXT, r23
- beq/l r23, r63, tr0
+ pta/l _C_LABEL(pthread__sa_recycle), tr1
+ LDPTR r2, PT_NEXT, r1
+ beq/l r1, r63, tr0
/* Yes, it was. Stash the thread we were going to
* switch to, and go to the next thread in the chain.
*/
+ movi PT_STATE_RECYCLABLE, r0
STPTR r2, PT_SWITCHTO, r3
STPTR r2, PT_SWITCHTOUC, r28
- movi PT_STATE_RECYCLABLE, r0
- pta/l Lpthread__switch_away_decrement, tr0
st.l r2, PT_STATE, r0
- or r3, r63, r20
+ pta/l _C_LABEL(_setcontext_u), tr0
+ STACK_SWITCH(r1, r2)
+ ld.l r3, PT_SPINLOCKS, r0
+ addi r0, -1, r0
+ st.l r3, PT_SPINLOCKS, r0
blink tr0, r63
- /* NOTREACHED */
Lupcall_no_old_preempt:
- pta/l _C_LABEL(pthread__sa_recycle), tr0
or r3, r63, r29
/* pthread__sa_recycle(old, new) */
- blink tr0, r18
+ blink tr1, r18
/* Release the fake lock */
ld.l r29, PT_SPINLOCKS, r0
+ pta/l _C_LABEL(_setcontext_u), tr0
addi r0, -1, r0
st.l r29, PT_SPINLOCKS, r0
/* Check if we were preempted while holding the fake lock. */
- pta/l _C_LABEL(_setcontext_u), tr0
or r28, r63, r2
- LDPTR r29, PT_NEXT, r23
- beq/l r23, r63, tr0
+ LDPTR r29, PT_NEXT, r1
+ beq/l r1, r63, tr0
/* Yes, we were. Bummer. Go to the next element in the chain. */
- pta/l Lpthread__switch_away_no_decrement, tr0
STPTR r29, PT_SWITCHTO, r29
STPTR r29, PT_SWITCHTOUC, r2
+ STACK_SWITCH(r1, r2)
blink tr0, r63
- /* NOTREACHED */