summaryrefslogtreecommitdiff
path: root/lib/libpthread/arch
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpthread/arch')
-rw-r--r--lib/libpthread/arch/sh/uthread_machdep.c30
-rw-r--r--lib/libpthread/arch/sh/uthread_machdep_asm.S56
2 files changed, 77 insertions, 9 deletions
diff --git a/lib/libpthread/arch/sh/uthread_machdep.c b/lib/libpthread/arch/sh/uthread_machdep.c
index 675b4ce89c4..b507e01e440 100644
--- a/lib/libpthread/arch/sh/uthread_machdep.c
+++ b/lib/libpthread/arch/sh/uthread_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_machdep.c,v 1.1 2007/02/19 21:03:50 miod Exp $ */
+/* $OpenBSD: uthread_machdep.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/*
* Copyright (c) 2007 Miodrag Vallat.
@@ -20,10 +20,12 @@
#include <pthread.h>
#include "pthread_private.h"
-#define STACK_ALIGNMENT 8
+#define STACK_ALIGNMENT 4
struct regframe {
+ /* return address */
register_t pr;
+ /* call-saved general registers */
register_t r14;
register_t r13;
register_t r12;
@@ -31,6 +33,22 @@ struct regframe {
register_t r10;
register_t r9;
register_t r8;
+ register_t macl;
+ register_t mach;
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ /* call-saved floating point registers */
+ register_t fr12;
+ register_t fr13;
+ register_t fr14;
+ register_t fr15;
+ register_t xd12;
+ register_t xd13;
+ register_t xd14;
+ register_t xd15;
+ /* floating point control registers */
+ register_t fpul;
+ register_t fpscr;
+#endif
};
void
@@ -42,10 +60,18 @@ _thread_machdep_init(struct _machdep_state* statep, void *base, int len,
regs = (struct regframe *)
(((u_int32_t)base + len - sizeof *regs) & ~(STACK_ALIGNMENT - 1));
regs->pr = (register_t)entry;
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ __asm__ __volatile__ ("sts fpscr, %0" : "=r" (regs->fpscr));
+#endif
statep->sp = (u_int)regs;
}
+/*
+ * Floating point state is saved with the general registers in
+ * _thread_machdep_switch().
+ */
+
void
_thread_machdep_save_float_state(struct _machdep_state* statep)
{
diff --git a/lib/libpthread/arch/sh/uthread_machdep_asm.S b/lib/libpthread/arch/sh/uthread_machdep_asm.S
index 702d5c04434..13b7111a692 100644
--- a/lib/libpthread/arch/sh/uthread_machdep_asm.S
+++ b/lib/libpthread/arch/sh/uthread_machdep_asm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_machdep_asm.S,v 1.1 2007/02/19 21:03:50 miod Exp $ */
+/* $OpenBSD: uthread_machdep_asm.S,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/*
* Copyright (c) 2007 Miodrag Vallat.
@@ -27,7 +27,26 @@ ENTRY(_thread_machdep_switch)
* On entry: r4 = new, r5 = oldsave
*/
- /* save caller-saved context on stack */
+ /*
+ * Save current context on the stack.
+ */
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ sts.l fpscr, @-r15
+ mov #0, r1
+ sts.l fpul, @-r15
+ lds r1, fpscr
+ fmov.s fr15, @-r15 /* note that we can't do double stores... */
+ fmov.s fr14, @-r15 /* ...as we don't control stack alignment. */
+ fmov.s fr13, @-r15
+ fmov.s fr12, @-r15
+ frchg
+ fmov.s fr15, @-r15
+ fmov.s fr14, @-r15
+ fmov.s fr13, @-r15
+ fmov.s fr12, @-r15
+#endif
+ sts.l mach, @-r15
+ sts.l macl, @-r15
mov.l r8, @-r15
mov.l r9, @-r15
mov.l r10, @-r15
@@ -37,13 +56,15 @@ ENTRY(_thread_machdep_switch)
mov.l r14, @-r15
sts.l pr, @-r15
- /* save old stack */
+ /*
+ * Switch stacks.
+ */
mov.l r15, @r5
-
- /* switch stacks */
mov.l @r4, r15
- /* restore new context */
+ /*
+ * Restore new context.
+ */
lds.l @r15+, pr
mov.l @r15+, r14
mov.l @r15+, r13
@@ -51,5 +72,26 @@ ENTRY(_thread_machdep_switch)
mov.l @r15+, r11
mov.l @r15+, r10
mov.l @r15+, r9
+ mov.l @r15+, r8
+ lds.l @r15+, macl
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ mov #0, r1
+ lds.l @r15+, mach
+ lds r1, fpscr
+ frchg
+ fmov.s @r15+, fr12
+ fmov.s @r15+, fr13
+ fmov.s @r15+, fr14
+ fmov.s @r15+, fr15
+ frchg
+ fmov.s @r15+, fr12
+ fmov.s @r15+, fr13
+ fmov.s @r15+, fr14
+ fmov.s @r15+, fr15
+ lds.l @r15+, fpul
+ rts
+ lds.l @r15+, fpscr
+#else
rts
- mov.l @r15+, r8
+ lds.l @r15+, mach
+#endif