summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2007-03-02 06:11:55 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2007-03-02 06:11:55 +0000
commitb598146d1a6495e37a541155e84a68656e8d417c (patch)
tree5ac40829b66e0ddccc3d7c1058e48a3485307e3a /lib
parent5b3f6165185fde0cfa60cbcb08f04c98bc07b4ce (diff)
Move landisk to hardware floating point. At the moment the FPU context is
always saved upon context switches, as FPU registers are heavily used for long long computations (don't ask). Gcc default to -m4. Credits to drahn@ otto@ and deraadt@ for feedback and help testing. Upgrade procedure if you don't want to use the damn snapshots: - build and install new kernel, reboot off it - build new gcc, do not install it yet - make includes - install new gcc - build and install lib/csu and lib/libc - make build
Diffstat (limited to 'lib')
-rw-r--r--lib/csu/sh/crt0.c10
-rw-r--r--lib/libc/arch/sh/Makefile.inc7
-rw-r--r--lib/libc/arch/sh/gen/Makefile.inc7
-rw-r--r--lib/libc/arch/sh/gen/_setjmp.S91
-rw-r--r--lib/libc/arch/sh/gen/fabs.c4
-rw-r--r--lib/libc/arch/sh/gen/fpsetmask.c7
-rw-r--r--lib/libc/arch/sh/gen/fpsetround.c9
-rw-r--r--lib/libc/arch/sh/gen/fpsetsticky.c7
-rw-r--r--lib/libc/arch/sh/gen/setjmp.S128
-rw-r--r--lib/libc/arch/sh/gen/sigsetjmp.S141
-rw-r--r--lib/libpthread/arch/sh/uthread_machdep.c30
-rw-r--r--lib/libpthread/arch/sh/uthread_machdep_asm.S56
12 files changed, 351 insertions, 146 deletions
diff --git a/lib/csu/sh/crt0.c b/lib/csu/sh/crt0.c
index af87c4d7bf0..01be7a702a5 100644
--- a/lib/csu/sh/crt0.c
+++ b/lib/csu/sh/crt0.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crt0.c,v 1.1 2006/10/10 22:07:10 miod Exp $ */
+/* $OpenBSD: crt0.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/* $NetBSD: crt0.c,v 1.10 2004/08/26 21:16:41 thorpej Exp $ */
/*
@@ -76,6 +76,14 @@ ___start(int argc, char **argv, char **envp, void *ps_strings,
{
char *s;
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ extern void __set_fpscr(unsigned int);
+ extern unsigned int __fpscr_values[2];
+
+ __set_fpscr(0);
+ __asm__ __volatile__ ("lds %0, fpscr" : : "r" (__fpscr_values[1]));
+#endif
+
environ = envp;
if ((__progname = argv[0]) != NULL) { /* NULL ptr if argc = 0 */
diff --git a/lib/libc/arch/sh/Makefile.inc b/lib/libc/arch/sh/Makefile.inc
index c66a4959bb4..69a13eed486 100644
--- a/lib/libc/arch/sh/Makefile.inc
+++ b/lib/libc/arch/sh/Makefile.inc
@@ -1,6 +1 @@
-# $OpenBSD: Makefile.inc,v 1.3 2006/11/07 17:38:49 drahn Exp $
-
-CPPFLAGS += -DSOFTFLOAT
-
-SOFTFLOAT_BITS=32
-.include <arch/sh/softfloat/Makefile.inc>
+# $OpenBSD: Makefile.inc,v 1.4 2007/03/02 06:11:54 miod Exp $
diff --git a/lib/libc/arch/sh/gen/Makefile.inc b/lib/libc/arch/sh/gen/Makefile.inc
index fb4af29eb92..8616cd7fff9 100644
--- a/lib/libc/arch/sh/gen/Makefile.inc
+++ b/lib/libc/arch/sh/gen/Makefile.inc
@@ -1,8 +1,7 @@
-# $OpenBSD: Makefile.inc,v 1.4 2006/11/06 15:14:50 drahn Exp $
+# $OpenBSD: Makefile.inc,v 1.5 2007/03/02 06:11:54 miod Exp $
SRCS+= flt_rounds.c isinf.c isnan.c infinity.c setjmp.S _setjmp.S sigsetjmp.S \
modf.c ldexp.c
-#hardfloat only pieces
-#SRCS+= fabs.c fpgetmask.c fpgetround.c fpgetsticky.c \
-# fpsetmask.c fpsetround.c fpsetsticky.c \
+SRCS+= fabs.c fpgetmask.c fpgetround.c fpgetsticky.c \
+ fpsetmask.c fpsetround.c fpsetsticky.c
diff --git a/lib/libc/arch/sh/gen/_setjmp.S b/lib/libc/arch/sh/gen/_setjmp.S
index 09e4f3785d9..a04fcb6cfb7 100644
--- a/lib/libc/arch/sh/gen/_setjmp.S
+++ b/lib/libc/arch/sh/gen/_setjmp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: _setjmp.S,v 1.1 2006/10/10 22:07:10 miod Exp $ */
+/* $OpenBSD: _setjmp.S,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/* $NetBSD: _setjmp.S,v 1.7 2006/01/05 02:04:41 uwe Exp $ */
/*-
@@ -49,37 +49,76 @@
*/
ENTRY(_setjmp)
- add #((_JB_HAS_MASK + 1) * 4), r4
- mov #0, r0
- mov.l r0, @-r4 /* no saved signal mask */
- mov.l r15, @-r4
- mov.l r14, @-r4
- mov.l r13, @-r4
- mov.l r12, @-r4
- mov.l r11, @-r4
- mov.l r10, @-r4
- mov.l r9, @-r4
- mov.l r8, @-r4
- sts.l pr, @-r4
+ xor r0, r0
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ add #(_JBLEN * 4), r4
+ sts fpscr, r1
+ mov.l r1, @-r4
+ lds r0, fpscr
+ sts.l fpul, @-r4
+ fmov.s fr15, @-r4
+ fmov.s fr14, @-r4
+ fmov.s fr13, @-r4
+ fmov.s fr12, @-r4
+ frchg
+ fmov.s fr15, @-r4
+ fmov.s fr14, @-r4
+ fmov.s fr13, @-r4
+ fmov.s fr12, @-r4
+ lds r1, fpscr
+#else
+ add #((_JBLEN - 10) * 4), r4
+#endif
+ sts.l mach, @-r4
+ sts.l macl, @-r4
+ mov.l r15, @-r4
+ mov.l r14, @-r4
+ mov.l r13, @-r4
+ mov.l r12, @-r4
+ mov.l r11, @-r4
+ mov.l r10, @-r4
+ mov.l r9, @-r4
+ mov.l r8, @-r4
+ sts.l pr, @-r4
+ mov.l r0, @-r4 /* dummy signal mask */
rts
- xor r0, r0
+ mov.l r0, @-r4 /* no saved signal mask */
SET_ENTRY_SIZE(_setjmp)
ENTRY(_longjmp)
- lds.l @r4+, pr
- mov.l @r4+, r8
- mov.l @r4+, r9
- mov.l @r4+, r10
- mov.l @r4+, r11
- mov.l @r4+, r12
- mov.l @r4+, r13
- mov.l @r4+, r14
- mov.l @r4+, r15
+ add #8, r4
+ lds.l @r4+, pr
+ mov.l @r4+, r8
+ mov.l @r4+, r9
+ mov.l @r4+, r10
+ mov.l @r4+, r11
+ mov.l @r4+, r12
+ mov.l @r4+, r13
+ mov.l @r4+, r14
+ mov.l @r4+, r15
+ lds.l @r4+, macl
+ lds.l @r4+, mach
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ xor r0, r0
+ lds r0, fpscr
+ frchg
+ fmov.s @r4+, fr12
+ fmov.s @r4+, fr13
+ fmov.s @r4+, fr14
+ fmov.s @r4+, fr15
+ frchg
+ fmov.s @r4+, fr12
+ fmov.s @r4+, fr13
+ fmov.s @r4+, fr14
+ fmov.s @r4+, fr15
+ lds.l @r4+, fpul
+ lds.l @r4+, fpscr
+#endif
- mov r5, r0
- tst r0, r0
+ mov r5, r0
+ tst r0, r0
bf .L0
- add #1, r0
+ add #1, r0
.L0:
rts
nop
diff --git a/lib/libc/arch/sh/gen/fabs.c b/lib/libc/arch/sh/gen/fabs.c
index b31405a29d5..116e8b4139a 100644
--- a/lib/libc/arch/sh/gen/fabs.c
+++ b/lib/libc/arch/sh/gen/fabs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fabs.c,v 1.2 2006/11/06 15:14:50 drahn Exp $ */
+/* $OpenBSD: fabs.c,v 1.3 2007/03/02 06:11:54 miod Exp $ */
/*
* Copyright (c) 2006 Miodrag Vallat.
*
@@ -21,7 +21,7 @@
double
fabs(double x)
{
-#ifdef __SH4__
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
__asm__ __volatile__("fabs %0" : "=f"(x));
#else
if (x < 0)
diff --git a/lib/libc/arch/sh/gen/fpsetmask.c b/lib/libc/arch/sh/gen/fpsetmask.c
index 7e93cae3ef7..122d9d36e70 100644
--- a/lib/libc/arch/sh/gen/fpsetmask.c
+++ b/lib/libc/arch/sh/gen/fpsetmask.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fpsetmask.c,v 1.1 2006/10/10 22:07:10 miod Exp $ */
+/* $OpenBSD: fpsetmask.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/*
* Copyright (c) 2006 Miodrag Vallat.
*
@@ -23,7 +23,12 @@ fp_except
fpsetmask(fp_except mask)
{
register_t fpscr, nfpscr;
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ extern register_t __fpscr_values[2];
+ __fpscr_values[0] = (__fpscr_values[0] & ~(0x1f << 7)) | (mask << 7);
+ __fpscr_values[1] = (__fpscr_values[1] & ~(0x1f << 7)) | (mask << 7);
+#endif
__asm__ __volatile__ ("sts fpscr, %0" : "=r" (fpscr));
nfpscr = (fpscr & ~(0x1f << 7)) | (mask << 7);
__asm__ __volatile__ ("lds %0, fpscr" : : "r" (nfpscr));
diff --git a/lib/libc/arch/sh/gen/fpsetround.c b/lib/libc/arch/sh/gen/fpsetround.c
index dafac3f72be..9090f647fce 100644
--- a/lib/libc/arch/sh/gen/fpsetround.c
+++ b/lib/libc/arch/sh/gen/fpsetround.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fpsetround.c,v 1.1 2006/10/10 22:07:10 miod Exp $ */
+/* $OpenBSD: fpsetround.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/*
* Copyright (c) 2006 Miodrag Vallat.
*
@@ -23,10 +23,17 @@ fp_rnd
fpsetround(fp_rnd rnd_dir)
{
register_t fpscr, nfpscr;
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ extern register_t __fpscr_values[2];
+#endif
__asm__ __volatile__ ("sts fpscr, %0" : "=r" (fpscr));
if (rnd_dir == FP_RN || rnd_dir == FP_RZ) {
nfpscr = (fpscr & ~0x03) | rnd_dir;
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ __fpscr_values[0] = (__fpscr_values[0] & ~0x03) | rnd_dir;
+ __fpscr_values[1] = (__fpscr_values[1] & ~0x03) | rnd_dir;
+#endif
__asm__ __volatile__ ("lds %0, fpscr" : : "r" (nfpscr));
}
/* else how report an error? */
diff --git a/lib/libc/arch/sh/gen/fpsetsticky.c b/lib/libc/arch/sh/gen/fpsetsticky.c
index 07c1f3be480..09f13bb94b5 100644
--- a/lib/libc/arch/sh/gen/fpsetsticky.c
+++ b/lib/libc/arch/sh/gen/fpsetsticky.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fpsetsticky.c,v 1.1 2006/10/10 22:07:10 miod Exp $ */
+/* $OpenBSD: fpsetsticky.c,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/*
* Copyright (c) 2006 Miodrag Vallat.
*
@@ -23,7 +23,12 @@ fp_except
fpsetsticky(fp_except mask)
{
register_t fpscr, nfpscr;
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ extern register_t __fpscr_values[2];
+ __fpscr_values[0] = (__fpscr_values[0] & ~(0x1f << 2)) | (mask << 2);
+ __fpscr_values[1] = (__fpscr_values[1] & ~(0x1f << 2)) | (mask << 2);
+#endif
__asm__ __volatile__ ("sts fpscr, %0" : "=r" (fpscr));
nfpscr = (fpscr & ~(0x1f << 2)) | (mask << 2);
__asm__ __volatile__ ("lds %0, fpscr" : : "r" (nfpscr));
diff --git a/lib/libc/arch/sh/gen/setjmp.S b/lib/libc/arch/sh/gen/setjmp.S
index e2d1eff9d16..67f33974420 100644
--- a/lib/libc/arch/sh/gen/setjmp.S
+++ b/lib/libc/arch/sh/gen/setjmp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: setjmp.S,v 1.1 2006/10/10 22:07:10 miod Exp $ */
+/* $OpenBSD: setjmp.S,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/* $NetBSD: setjmp.S,v 1.10 2006/01/05 19:21:37 uwe Exp $ */
/*-
@@ -50,73 +50,113 @@
ENTRY(setjmp)
PIC_PROLOGUE(.L_got_1)
- sts.l pr, @-sp
- mov.l r4, @-sp
+ sts.l pr, @-sp
+ mov.l r4, @-sp
mov.l .L_sigprocmask_1, r0
- mov r4, r6
- mov #1, r4 /* how = SIG_BLOCK */
- mov #0, r5 /* new = NULL */
+ mov r4, r6
+ mov #1, r4 /* how = SIG_BLOCK */
+ mov #0, r5 /* new = NULL */
1: CALL r0
- add #(_JB_SIGMASK * 4), r6 /* old = &sigmask */
+ add #4, r6 /* old = &sigmask */
- mov.l @sp+, r4
- lds.l @sp+, pr
+ mov.l @sp+, r4
+ lds.l @sp+, pr
PIC_EPILOGUE
- /* identical to _setjmp except that _JB_HAS_MASK is non-zero */
- add #((_JB_HAS_MASK + 1) * 4), r4
- mov #1, r0
- mov.l r0, @-r4 /* has signal mask */
- mov.l r15, @-r4
- mov.l r14, @-r4
- mov.l r13, @-r4
- mov.l r12, @-r4
- mov.l r11, @-r4
- mov.l r10, @-r4
- mov.l r9, @-r4
- mov.l r8, @-r4
- sts.l pr, @-r4
+ /* identical to _setjmp except that the first word is non-zero */
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ add #(_JBLEN * 4), r4
+ sts fpscr, r1
+ xor r0, r0
+ mov.l r1, @-r4
+ lds r0, fpscr
+ sts.l fpul, @-r4
+ fmov.s fr15, @-r4
+ fmov.s fr14, @-r4
+ fmov.s fr13, @-r4
+ fmov.s fr12, @-r4
+ frchg
+ fmov.s fr15, @-r4
+ fmov.s fr14, @-r4
+ fmov.s fr13, @-r4
+ fmov.s fr12, @-r4
+ lds r1, fpscr
+#else
+ add #((_JBLEN - 10) * 4), r4
+#endif
+ sts.l mach, @-r4
+ sts.l macl, @-r4
+ mov.l r15, @-r4
+ mov.l r14, @-r4
+ mov.l r13, @-r4
+ mov.l r12, @-r4
+ mov.l r11, @-r4
+ mov.l r10, @-r4
+ mov.l r9, @-r4
+ mov.l r8, @-r4
+ sts.l pr, @-r4
+ add #-4, r4 /* skip signal mask */
+ mov #1, r0
+ mov.l r0, @-r4 /* has signal mask */
rts
- xor r0, r0
+ xor r0, r0
.align 2
.L_got_1: PIC_GOT_DATUM
.L_sigprocmask_1: CALL_DATUM(_C_LABEL(sigprocmask), 1b)
SET_ENTRY_SIZE(setjmp)
-
ENTRY(longjmp)
/* we won't return here, so we don't need to save pr and r12 */
PIC_PROLOGUE_NOSAVE(.L_got_2)
- mov.l r5, @-sp
- mov.l r4, @-sp
+ mov.l r5, @-sp
+ mov.l r4, @-sp
mov.l .L_sigprocmask_2, r0
- mov r4, r5
- mov #3, r4 /* how = SIG_SETMASK */
- add #(_JB_SIGMASK * 4), r5 /* new = &sigmask */
+ mov r4, r5
+ mov #3, r4 /* how = SIG_SETMASK */
+ add #4, r5 /* new = &sigmask */
1: CALL r0
- mov #0, r6 /* old = NULL */
+ mov #0, r6 /* old = NULL */
- mov.l @sp+, r4
- mov.l @sp+, r5
+ mov.l @sp+, r4
+ mov.l @sp+, r5
/* identical to _longjmp */
- lds.l @r4+, pr
- mov.l @r4+, r8
- mov.l @r4+, r9
- mov.l @r4+, r10
- mov.l @r4+, r11
- mov.l @r4+, r12
- mov.l @r4+, r13
- mov.l @r4+, r14
- mov.l @r4+, r15
+ add #8, r4
+ lds.l @r4+, pr
+ mov.l @r4+, r8
+ mov.l @r4+, r9
+ mov.l @r4+, r10
+ mov.l @r4+, r11
+ mov.l @r4+, r12
+ mov.l @r4+, r13
+ mov.l @r4+, r14
+ mov.l @r4+, r15
+ lds.l @r4+, macl
+ lds.l @r4+, mach
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ xor r0, r0
+ lds r0, fpscr
+ frchg
+ fmov.s @r4+, fr12
+ fmov.s @r4+, fr13
+ fmov.s @r4+, fr14
+ fmov.s @r4+, fr15
+ frchg
+ fmov.s @r4+, fr12
+ fmov.s @r4+, fr13
+ fmov.s @r4+, fr14
+ fmov.s @r4+, fr15
+ lds.l @r4+, fpul
+ lds.l @r4+, fpscr
+#endif
- mov r5, r0
- tst r0, r0 /* make sure return value is non-zero */
+ mov r5, r0
+ tst r0, r0 /* make sure return value is non-zero */
bf .L0
- add #1, r0
+ add #1, r0
.L0:
rts
nop
diff --git a/lib/libc/arch/sh/gen/sigsetjmp.S b/lib/libc/arch/sh/gen/sigsetjmp.S
index 2467a3f707b..f88913a73f1 100644
--- a/lib/libc/arch/sh/gen/sigsetjmp.S
+++ b/lib/libc/arch/sh/gen/sigsetjmp.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: sigsetjmp.S,v 1.1 2006/10/10 22:07:10 miod Exp $ */
+/* $OpenBSD: sigsetjmp.S,v 1.2 2007/03/02 06:11:54 miod Exp $ */
/* $NetBSD: sigsetjmp.S,v 1.9 2006/01/05 19:21:37 uwe Exp $ */
/*-
@@ -39,84 +39,123 @@
#include <machine/setjmp.h>
ENTRY(sigsetjmp)
- tst r5, r5
- bt 2f /* if (savemask == 0) */
+ tst r5, r5 /* if (savemask == 0) */
+ bt 2f
- /* identical to longjmp except that _JB_HAS_MASK is in the argument */
+ /* identical to setjmp */
PIC_PROLOGUE(.L_got_1)
- sts.l pr, @-sp
- mov.l r4, @-sp
- mov.l r5, @-sp
+ sts.l pr, @-sp
+ mov.l r4, @-sp
+ mov.l r5, @-sp
mov.l .L_sigprocmask_1, r0
- mov r4, r6
- mov #1, r4 /* how = SIG_BLOCK */
- mov #0, r5 /* new = NULL */
+ mov r4, r6
+ mov #1, r4 /* how = SIG_BLOCK */
+ mov #0, r5 /* new = NULL */
1: CALL r0
- add #(_JB_SIGMASK * 4), r6 /* old = &sigmask */
+ add #4, r6 /* old = &sigmask */
- mov.l @sp+, r5
- mov.l @sp+, r4
- lds.l @sp+, pr
+ mov.l @sp+, r5
+ mov.l @sp+, r4
+ lds.l @sp+, pr
PIC_EPILOGUE
-2: /* identical to _setjmp except that _JB_HAS_MASK is in the argument */
- add #((_JB_HAS_MASK + 1) * 4), r4
- mov.l r5, @-r4 /* has signal mask? */
- mov.l r15, @-r4
- mov.l r14, @-r4
- mov.l r13, @-r4
- mov.l r12, @-r4
- mov.l r11, @-r4
- mov.l r10, @-r4
- mov.l r9, @-r4
- mov.l r8, @-r4
- sts.l pr, @-r4
+2: /* identical to _setjmp except that first word is in r5 */
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ add #(_JBLEN * 4), r4
+ sts fpscr, r1
+ xor r0, r0
+ mov.l r1, @-r4
+ lds r0, fpscr
+ sts.l fpul, @-r4
+ fmov.s fr15, @-r4
+ fmov.s fr14, @-r4
+ fmov.s fr13, @-r4
+ fmov.s fr12, @-r4
+ frchg
+ fmov.s fr15, @-r4
+ fmov.s fr14, @-r4
+ fmov.s fr13, @-r4
+ fmov.s fr12, @-r4
+ lds r1, fpscr
+#else
+ add #((_JBLEN - 10) * 4), r4
+#endif
+ sts.l mach, @-r4
+ sts.l macl, @-r4
+ mov.l r15, @-r4
+ mov.l r14, @-r4
+ mov.l r13, @-r4
+ mov.l r12, @-r4
+ mov.l r11, @-r4
+ mov.l r10, @-r4
+ mov.l r9, @-r4
+ mov.l r8, @-r4
+ sts.l pr, @-r4
+ add #-4, r4 /* skip signal mask */
+ mov.l r5, @-r4 /* has signal mask? */
rts
- xor r0, r0
+ xor r0, r0
.align 2
.L_got_1: PIC_GOT_DATUM
.L_sigprocmask_1: CALL_DATUM(_C_LABEL(sigprocmask), 1b)
SET_ENTRY_SIZE(sigsetjmp)
-
ENTRY(siglongjmp)
- mov.l @(_JB_HAS_MASK * 4, r4), r0
- tst r0, r0
+ mov.l @r4+, r0
+ tst r0, r0
bt 2f /* if no mask */
/* identical to longjmp */
/* we won't return here, so we don't need to save pr and r12 */
PIC_PROLOGUE_NOSAVE(.L_got_2)
- mov.l r5, @-sp
- mov.l r4, @-sp
+ mov.l r5, @-sp
+ mov.l r4, @-sp
mov.l .L_sigprocmask_2, r0
- mov r4, r5
- mov #3, r4 /* how = SIG_SETMASK */
- add #(_JB_SIGMASK * 4), r5 /* new = &sigmask */
+ mov r4, r5 /* new = &sigmask */
+ mov #3, r4 /* how = SIG_SETMASK */
1: CALL r0
- mov #0, r6 /* old = NULL */
+ mov #0, r6 /* old = NULL */
- mov.l @sp+, r4
- mov.l @sp+, r5
+ mov.l @sp+, r4
+ mov.l @sp+, r5
2: /* identical to _longjmp */
- lds.l @r4+, pr
- mov.l @r4+, r8
- mov.l @r4+, r9
- mov.l @r4+, r10
- mov.l @r4+, r11
- mov.l @r4+, r12
- mov.l @r4+, r13
- mov.l @r4+, r14
- mov.l @r4+, r15
-
- mov r5, r0
- tst r0, r0 /* make sure return value is non-zero */
+ add #4, r4
+ lds.l @r4+, pr
+ mov.l @r4+, r8
+ mov.l @r4+, r9
+ mov.l @r4+, r10
+ mov.l @r4+, r11
+ mov.l @r4+, r12
+ mov.l @r4+, r13
+ mov.l @r4+, r14
+ mov.l @r4+, r15
+ lds.l @r4+, macl
+ lds.l @r4+, mach
+#if defined(__SH4__) && !defined(__SH4_NOFPU__)
+ xor r0, r0
+ lds r0, fpscr
+ frchg
+ fmov.s @r4+, fr12
+ fmov.s @r4+, fr13
+ fmov.s @r4+, fr14
+ fmov.s @r4+, fr15
+ frchg
+ fmov.s @r4+, fr12
+ fmov.s @r4+, fr13
+ fmov.s @r4+, fr14
+ fmov.s @r4+, fr15
+ lds.l @r4+, fpul
+ lds.l @r4+, fpscr
+#endif
+
+ mov r5, r0
+ tst r0, r0 /* make sure return value is non-zero */
bf .L0
- add #1, r0
+ add #1, r0
.L0:
rts
nop
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