diff options
Diffstat (limited to 'lib/libpthread/arch')
-rw-r--r-- | lib/libpthread/arch/sh/uthread_machdep.c | 30 | ||||
-rw-r--r-- | lib/libpthread/arch/sh/uthread_machdep_asm.S | 56 |
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 |