diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./bin/ksh/tree.c src-sh4-fpu/./bin/ksh/tree.c --- src.orig/./bin/ksh/tree.c 2005-06-27 04:09:00.000000000 +0900 +++ src-sh4-fpu/./bin/ksh/tree.c 2009-07-21 21:41:00.000000000 +0900 @@ -423,7 +423,7 @@ register struct shf *shf; int indent; const char *fmt; - register va_list va; + va_list va; { register int c; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./crypto/external/bsd/openssl/lib/libcrypto/Makefile src-sh4-fpu/./crypto/external/bsd/openssl/lib/libcrypto/Makefile --- src.orig/./crypto/external/bsd/openssl/lib/libcrypto/Makefile 2009-07-20 08:30:42.000000000 +0900 +++ src-sh4-fpu/./crypto/external/bsd/openssl/lib/libcrypto/Makefile 2009-07-21 19:55:24.000000000 +0900 @@ -121,6 +121,10 @@ COPTS.eng_padlock.c = -Wno-stack-protector +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +COPTS.asn1_par.c+= -O0 +.endif + INCSDIR=/usr/include/openssl .include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./distrib/sets/lists/comp/ad.sh3 src-sh4-fpu/./distrib/sets/lists/comp/ad.sh3 --- src.orig/./distrib/sets/lists/comp/ad.sh3 2008-09-10 08:01:37.000000000 +0900 +++ src-sh4-fpu/./distrib/sets/lists/comp/ad.sh3 2009-07-21 20:23:43.000000000 +0900 @@ -17,6 +17,7 @@ ./usr/include/sh3/endian.h comp-c-include ./usr/include/sh3/endian_machdep.h comp-c-include ./usr/include/sh3/float.h comp-c-include +./usr/include/sh3/fpu.h comp-c-include ./usr/include/sh3/frame.h comp-c-include ./usr/include/sh3/ieee.h comp-c-include ./usr/include/sh3/ieeefp.h comp-c-include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./external/ibm-public/postfix/libexec/smtpd/Makefile src-sh4-fpu/./external/ibm-public/postfix/libexec/smtpd/Makefile --- src.orig/./external/ibm-public/postfix/libexec/smtpd/Makefile 2009-06-26 03:21:55.000000000 +0900 +++ src-sh4-fpu/./external/ibm-public/postfix/libexec/smtpd/Makefile 2009-07-21 21:32:49.000000000 +0900 @@ -24,4 +24,8 @@ DPADD+= ${LIBPUTIL} LDADD+= ${LIBPUTIL} +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +COPTS.smtpd_check.c+= -O0 +.endif + .include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./gnu/dist/gcc4/gcc/config/sh/lib1funcs.asm src-sh4-fpu/./gnu/dist/gcc4/gcc/config/sh/lib1funcs.asm --- src.orig/./gnu/dist/gcc4/gcc/config/sh/lib1funcs.asm 2006-04-20 18:49:36.000000000 +0900 +++ src-sh4-fpu/./gnu/dist/gcc4/gcc/config/sh/lib1funcs.asm 2009-07-23 20:30:29.000000000 +0900 @@ -41,8 +41,13 @@ #ifdef __ELF__ #define LOCAL(X) .L_##X #define FUNC(X) .type X,@function +#ifdef PIC #define HIDDEN_FUNC(X) FUNC(X); .hidden X #define HIDDEN_ALIAS(X,Y) ALIAS (X,Y); .hidden GLOBAL(X) +#else +#define HIDDEN_FUNC(X) FUNC(X); +#define HIDDEN_ALIAS(X,Y) ALIAS (X,Y); +#endif #define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X #define ENDFUNC(X) ENDFUNC0(X) #else @@ -1035,7 +1040,7 @@ #ifdef L_sdivsi3 /* __SH4_SINGLE_ONLY__ keeps this part for link compatibility with sh2e/sh3e code. */ -#if (! defined(__SH4__) && ! defined (__SH4_SINGLE__)) || defined (__linux__) +#if (! defined(__SH4__) && ! defined (__SH4_SINGLE__)) || defined (__linux__) || defined(__NetBSD__) !! !! Steve Chamberlain !! sac@cygnus.com @@ -1486,7 +1491,7 @@ #ifdef L_udivsi3 /* __SH4_SINGLE_ONLY__ keeps this part for link compatibility with sh2e/sh3e code. */ -#if (! defined(__SH4__) && ! defined (__SH4_SINGLE__)) || defined (__linux__) +#if (! defined(__SH4__) && ! defined (__SH4_SINGLE__)) || defined (__linux__) || defined(__NetBSD__) !! args in r4 and r5, result in r0, clobbers r4, pr, and t bit .global GLOBAL(udivsi3) diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./gnu/dist/gcc4/gcc/config/sh/sh.h src-sh4-fpu/./gnu/dist/gcc4/gcc/config/sh/sh.h --- src.orig/./gnu/dist/gcc4/gcc/config/sh/sh.h 2006-04-20 18:49:59.000000000 +0900 +++ src-sh4-fpu/./gnu/dist/gcc4/gcc/config/sh/sh.h 2009-07-23 18:26:29.000000000 +0900 @@ -618,7 +618,7 @@ } \ if (sh_divsi3_libfunc[0]) \ ; /* User supplied - leave it alone. */ \ - else if (TARGET_HARD_SH4 && TARGET_SH2E) \ + else if (0 && TARGET_HARD_SH4 && TARGET_SH2E) \ sh_divsi3_libfunc = "__sdivsi3_i4"; \ else if (TARGET_SH5) \ { \ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./gnu/dist/gcc4/gcc/config/sh/sh.md src-sh4-fpu/./gnu/dist/gcc4/gcc/config/sh/sh.md --- src.orig/./gnu/dist/gcc4/gcc/config/sh/sh.md 2008-02-03 15:43:32.000000000 +0900 +++ src-sh4-fpu/./gnu/dist/gcc4/gcc/config/sh/sh.md 2009-07-23 18:29:27.000000000 +0900 @@ -1655,7 +1655,7 @@ (clobber (reg:SI PR_REG)) (clobber (reg:SI R4_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] - "TARGET_SH1 && ! TARGET_SH4" + "TARGET_SH1" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) @@ -1761,7 +1761,7 @@ operands[3] = gen_reg_rtx (Pmode); /* Emit the move of the address to a pseudo outside of the libcall. */ - if (TARGET_HARD_SH4 && TARGET_SH2E) + if (0 && TARGET_HARD_SH4 && TARGET_SH2E) { function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC); if (TARGET_FPU_SINGLE) @@ -1829,7 +1829,7 @@ (clobber (reg:SI R2_REG)) (clobber (reg:SI R3_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] - "TARGET_SH1 && ! TARGET_SH4" + "TARGET_SH1" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) @@ -1999,7 +1999,7 @@ operands[3] = gen_reg_rtx (Pmode); /* Emit the move of the address to a pseudo outside of the libcall. */ - if (TARGET_HARD_SH4 && TARGET_SH2E) + if (0 && TARGET_HARD_SH4 && TARGET_SH2E) { function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC); if (TARGET_FPU_SINGLE) diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/csu/sh3/crt0.c src-sh4-fpu/./lib/csu/sh3/crt0.c --- src.orig/./lib/csu/sh3/crt0.c 2008-06-21 12:07:06.000000000 +0900 +++ src-sh4-fpu/./lib/csu/sh3/crt0.c 2009-07-22 18:40:23.000000000 +0900 @@ -105,6 +105,15 @@ #include "common.c" +#if defined(__SH4__) +#include + +int __fpscr_values[2] = { + SH4_FPSCR_INIT & ~FPSCR_PR, /* float */ + SH4_FPSCR_INIT | FPSCR_PR, /* double */ +}; +#endif /* __SH4__ */ + #ifdef MCRT0 __asm(" .text diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/Makefile.inc src-sh4-fpu/./lib/libc/arch/sh3/Makefile.inc --- src.orig/./lib/libc/arch/sh3/Makefile.inc 2006-06-18 03:04:23.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/Makefile.inc 2009-07-22 18:47:32.000000000 +0900 @@ -2,5 +2,8 @@ SRCS+= __sigaction14_sigtramp.c __sigtramp2.S +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +.else CPPFLAGS+= -DSOFTFLOAT # -DSOFTFLOAT_NEED_FIXUNS .include +.endif diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gdtoa/gd_qnan.h src-sh4-fpu/./lib/libc/arch/sh3/gdtoa/gd_qnan.h --- src.orig/./lib/libc/arch/sh3/gdtoa/gd_qnan.h 2006-01-26 00:33:28.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gdtoa/gd_qnan.h 2009-07-22 20:34:24.000000000 +0900 @@ -2,6 +2,7 @@ #include +/* XXXNONAKA */ #define f_QNAN 0x7fa00000 #if BYTE_ORDER == BIG_ENDIAN #define d_QNAN0 0x7ff40000 diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/Makefile.inc src-sh4-fpu/./lib/libc/arch/sh3/gen/Makefile.inc --- src.orig/./lib/libc/arch/sh3/gen/Makefile.inc 2006-06-28 23:46:32.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gen/Makefile.inc 2009-07-22 18:48:53.000000000 +0900 @@ -18,6 +18,11 @@ SRCS+= nanf.c +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +SRCS+= fpgetmask.c fpgetround.c fpgetsticky.c +SRCS+= fpsetmask.c fpsetround.c fpsetsticky.c +.endif + SRCS.sh3.gen= Lint__setjmp.c Lint___setjmp14.c Lint___sigsetjmp14.c \ Lint_swapcontext.c diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/fpgetmask.c src-sh4-fpu/./lib/libc/arch/sh3/gen/fpgetmask.c --- src.orig/./lib/libc/arch/sh3/gen/fpgetmask.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gen/fpgetmask.c 2009-07-22 20:12:11.000000000 +0900 @@ -0,0 +1,71 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD$"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpgetmask,_fpgetmask) +#endif + +fp_except +fpgetmask(void) +{ + fp_except mask = 0; + unsigned int r, e; + + r = get_fpscr(); + +#if defined(__SH4__) + if ((r & FPSCR_DN) == 0) + mask |= FP_X_DNML; +#endif + + e = (r >> FP_ENABLE_SHIFT) & FP_ENABLE_MASK; +#if defined(__SH4__) + if (e & FP_I_BIT) + mask |= FP_X_IMP; + if (e & FP_U_BIT) + mask |= FP_X_UFL; + if (e & FP_O_BIT) + mask |= FP_X_OFL; +#endif + if (e & FP_Z_BIT) + mask |= FP_X_DZ; + if (e & FP_V_BIT) + mask |= FP_X_INV; + + return mask; +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/fpgetround.c src-sh4-fpu/./lib/libc/arch/sh3/gen/fpgetround.c --- src.orig/./lib/libc/arch/sh3/gen/fpgetround.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gen/fpgetround.c 2009-07-22 20:14:35.000000000 +0900 @@ -0,0 +1,56 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD$"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpgetround,_fpgetround) +#endif + +fp_rnd +fpgetround(void) +{ +#if defined(__SH4__) + unsigned int r; + + r = get_fpscr(); + + r &= FPSCR_RM; + if (r == RM_NEAREST) + return FP_RN; +#endif + return FP_RZ; +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/fpgetsticky.c src-sh4-fpu/./lib/libc/arch/sh3/gen/fpgetsticky.c --- src.orig/./lib/libc/arch/sh3/gen/fpgetsticky.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gen/fpgetsticky.c 2009-07-22 20:12:43.000000000 +0900 @@ -0,0 +1,71 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD$"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpgetsticky,_fpgetsticky) +#endif + +fp_except +fpgetsticky(void) +{ + fp_except flags = 0; + unsigned int r, f; + + r = get_fpscr(); + +#if 0 /* SH don't have Denormal flag at fpscr. */ + if (0) + flags |= FP_X_DNML; +#endif + + f = (r >> FP_FLAG_SHIFT) & FP_FLAG_MASK; +#if defined(__SH4__) + if (f & FP_I_BIT) + flags |= FP_X_IMP; + if (f & FP_U_BIT) + flags |= FP_X_UFL; + if (f & FP_O_BIT) + flags |= FP_X_OFL; +#endif + if (f & FP_Z_BIT) + flags |= FP_X_DZ; + if (f & FP_V_BIT) + flags |= FP_X_INV; + + return flags; +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/fpsetmask.c src-sh4-fpu/./lib/libc/arch/sh3/gen/fpsetmask.c --- src.orig/./lib/libc/arch/sh3/gen/fpsetmask.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gen/fpsetmask.c 2009-07-22 20:13:06.000000000 +0900 @@ -0,0 +1,103 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD$"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpsetmask,_fpsetmask) +#endif + +void __set_fpscr(int fpscr); + +fp_except +fpsetmask(fp_except mask) +{ + fp_except old = 0; + unsigned int o, n, e; + unsigned int b = 0; + + o = get_fpscr(); + + /* new mask */ + n = o; + n &= ~(FP_ENABLE_MASK << FP_ENABLE_SHIFT); + +#if defined(__SH4__) + if (mask & FP_X_DNML) + n &= ~FPSCR_DN; + else +#endif + n |= FPSCR_DN; + +#if defined(__SH4__) + if (mask & FP_X_IMP) + b |= FP_I_BIT; + if (mask & FP_X_UFL) + b |= FP_U_BIT; + if (mask & FP_X_OFL) + b |= FP_O_BIT; +#endif + if (mask & FP_X_DZ) + b |= FP_Z_BIT; + if (mask & FP_X_INV) + b |= FP_V_BIT; + n |= (b << FP_ENABLE_SHIFT); /* enable FPU exception */ + n &= ~(b << FP_FLAG_SHIFT); /* clear FPU exception flags */ + + __set_fpscr(n); + + /* old mask */ +#if defined(__SH4__) + if ((o & FPSCR_DN) == 0) /* DN */ + old |= FP_X_DNML; +#endif + + e = (o >> FP_ENABLE_SHIFT) & FP_ENABLE_MASK; +#if defined(__SH4__) + if (e & FP_I_BIT) + old |= FP_X_IMP; + if (e & FP_U_BIT) + old |= FP_X_UFL; + if (e & FP_O_BIT) + old |= FP_X_OFL; +#endif + if (e & FP_Z_BIT) + old |= FP_X_DZ; + if (e & FP_V_BIT) + old |= FP_X_INV; + + return old; +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/fpsetround.c src-sh4-fpu/./lib/libc/arch/sh3/gen/fpsetround.c --- src.orig/./lib/libc/arch/sh3/gen/fpsetround.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gen/fpsetround.c 2009-07-22 20:13:39.000000000 +0900 @@ -0,0 +1,80 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD$"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpsetround,_fpsetround) +#endif + +void __set_fpscr(int fpscr); + +fp_rnd +fpsetround(fp_rnd rnd_dir) +{ + unsigned int old, new; + unsigned int r; + + old = get_fpscr(); + + /* new dir */ + new = old & ~FPSCR_RM; + + switch (rnd_dir) { + case FP_RN: +#if defined(__SH4__) + r = RM_NEAREST; + break; +#endif + case FP_RZ: + case FP_RM: + case FP_RP: + default: + r = RM_ZERO; + break; + } + new |= r; + + __set_fpscr(new); + + /* old dir */ +#if defined(__SH4__) + old &= FPSCR_RM; + if (old == RM_NEAREST) + return FP_RN; +#endif + return FP_RZ; +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/fpsetsticky.c src-sh4-fpu/./lib/libc/arch/sh3/gen/fpsetsticky.c --- src.orig/./lib/libc/arch/sh3/gen/fpsetsticky.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gen/fpsetsticky.c 2009-07-22 20:14:22.000000000 +0900 @@ -0,0 +1,95 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD$"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpsetsticky,_fpsetsticky) +#endif + +void __set_fpscr(int fpscr); + +fp_except +fpsetsticky(fp_except sticky) +{ + fp_except old = 0; + unsigned int o, n, f; + unsigned int b = 0; + + o = get_fpscr(); + + /* new flags */ + n = o; + +#if defined(__SH4__) + if (sticky & FP_X_IMP) + b |= FP_I_BIT; + if (sticky & FP_X_UFL) + b |= FP_U_BIT; + if (sticky & FP_X_OFL) + b |= FP_O_BIT; +#endif + if (sticky & FP_X_DZ) + b |= FP_Z_BIT; + if (sticky & FP_X_INV) + b |= FP_V_BIT; + + n &= ~(b << FP_FLAG_SHIFT); + + __set_fpscr(n); + + /* old flags */ +#if 0 /* SH don't have Denormal flag at fpscr. */ + if (0) + flags |= FP_X_DNML; +#endif + + f = (o >> FP_FLAG_SHIFT) & FP_FLAG_MASK; +#if defined(__SH4__) + if (f & FP_I_BIT) + old |= FP_X_IMP; + if (f & FP_U_BIT) + old |= FP_X_UFL; + if (f & FP_O_BIT) + old |= FP_X_OFL; +#endif + if (f & FP_Z_BIT) + old |= FP_X_DZ; + if (f & FP_V_BIT) + old |= FP_X_INV; + + return old; +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/nanf.c src-sh4-fpu/./lib/libc/arch/sh3/gen/nanf.c --- src.orig/./lib/libc/arch/sh3/gen/nanf.c 2009-02-23 16:51:41.000000000 +0900 +++ src-sh4-fpu/./lib/libc/arch/sh3/gen/nanf.c 2009-07-22 20:34:15.000000000 +0900 @@ -8,6 +8,7 @@ #include #include +/* XXXNONAKA */ /* bytes for quiet NaN (IEEE single precision) */ const union __float_u __nanf = #if BYTE_ORDER == BIG_ENDIAN diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libkrb5/Makefile src-sh4-fpu/./lib/libkrb5/Makefile --- src.orig/./lib/libkrb5/Makefile 2009-07-21 15:02:33.000000000 +0900 +++ src-sh4-fpu/./lib/libkrb5/Makefile 2009-07-21 20:16:52.000000000 +0900 @@ -746,5 +746,9 @@ FILESDIR= /usr/share/examples/kerberos .endif +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +COPTS.crypto.c+= -O0 +.endif + .include .include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libwrap/Makefile src-sh4-fpu/./lib/libwrap/Makefile --- src.orig/./lib/libwrap/Makefile 2007-05-28 21:06:22.000000000 +0900 +++ src-sh4-fpu/./lib/libwrap/Makefile 2009-07-21 19:53:32.000000000 +0900 @@ -19,4 +19,8 @@ .include "Makefile.cflags" +.if ${MACHINE_GNU_ARCH} == "sh4le" || ${MACHINE_GNU_ARCH} == "sh4" +COPTS.hosts_access.c+= -O0 +.endif + .include diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./makeBuild.sh src-sh4-fpu/./makeBuild.sh --- src.orig/./makeBuild.sh 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./makeBuild.sh 2009-07-21 15:43:55.000000000 +0900 @@ -0,0 +1,44 @@ +#!/bin/sh + +progname=$0 + +usage() { + echo "Usage: ${progname} " + exit 1 +} + +if [ x"$1" = x ]; then + usage +fi +target_machine="$1" +shift + +if [ x"$1" = x ]; then + usage +fi +build_date=$1 +shift + +if [ x"$1" = x ]; then + usage +fi +operation=$1 +shift + +LANG=C; export LANG +LC_ALL=C; export LC_ALL +LC_CTYPE=C; export LC_CTYPE + +if [ -x /usr/pkg/bin/sudo ]; then + SUDO=/usr/pkg/bin/sudo +fi + +time ${SUDO} ./build.sh -m ${target_machine} \ + -D /home/snapshot/${build_date}/root/${target_machine} \ + -R /home/snapshot/${build_date}/release \ + -T /usr/local/netbsd-tools \ + $@ \ + ${operation} \ + 2>&1 | tee makeBuild-${target_machine}.log +retval=$? +exit ${retval} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./share/mk/bsd.own.mk src-sh4-fpu/./share/mk/bsd.own.mk --- src.orig/./share/mk/bsd.own.mk 2009-07-08 20:59:12.000000000 +0900 +++ src-sh4-fpu/./share/mk/bsd.own.mk 2009-07-21 22:35:48.000000000 +0900 @@ -541,8 +541,13 @@ GCC_CONFIG_TUNE.i386=nocona GCC_CONFIG_TUNE.x86_64=nocona GNU_ARCH.m68000=m68010 +.if ${MACHINE} == "landisk" +GNU_ARCH.sh3eb=sh4 +GNU_ARCH.sh3el=sh4le +.else GNU_ARCH.sh3eb=sh GNU_ARCH.sh3el=shle +.endif GNU_ARCH.mips64eb=mips64 MACHINE_GNU_ARCH=${GNU_ARCH.${MACHINE_ARCH}:U${MACHINE_ARCH}} @@ -557,6 +562,10 @@ ${MACHINE_CPU} == "m68k" || \ ${MACHINE_GNU_ARCH} == "sh" || \ ${MACHINE_GNU_ARCH} == "shle" || \ + ${MACHINE_GNU_ARCH} == "sh4" || \ + ${MACHINE_GNU_ARCH} == "sh4le" || \ + ${MACHINE_GNU_ARCH} == "sh4a" || \ + ${MACHINE_GNU_ARCH} == "sh4ale" || \ ${MACHINE_ARCH} == "sparc" || \ ${MACHINE_ARCH} == "vax") MACHINE_GNU_PLATFORM?=${MACHINE_GNU_ARCH}--netbsdelf diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/conf/files.sh3 src-sh4-fpu/./sys/arch/sh3/conf/files.sh3 --- src.orig/./sys/arch/sh3/conf/files.sh3 2008-11-22 15:00:26.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/conf/files.sh3 2009-07-08 23:14:57.000000000 +0900 @@ -29,6 +29,9 @@ file arch/sh3/sh3/devreg.c sh3 & sh4 file arch/sh3/sh3/exception.c file arch/sh3/sh3/exception_vector.S +file arch/sh3/sh3/fpu.c +file arch/sh3/sh3/fpu_sh3.c sh3 +file arch/sh3/sh3/fpu_sh4.c sh4 file arch/sh3/sh3/interrupt.c file arch/sh3/sh3/kgdb_machdep.c kgdb file arch/sh3/sh3/kobj_machdep.c modular diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/Makefile src-sh4-fpu/./sys/arch/sh3/include/Makefile --- src.orig/./sys/arch/sh3/include/Makefile 2007-02-10 06:55:12.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/Makefile 2009-07-21 20:09:43.000000000 +0900 @@ -7,7 +7,7 @@ cdefs.h coff_machdep.h cpu.h cputypes.h \ disklabel.h \ elf_machdep.h endian.h endian_machdep.h \ - float.h frame.h \ + float.h fpu.h frame.h \ ieee.h ieeefp.h \ int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \ intr.h \ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/cpu.h src-sh4-fpu/./sys/arch/sh3/include/cpu.h --- src.orig/./sys/arch/sh3/include/cpu.h 2008-03-23 13:30:39.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/cpu.h 2009-07-08 22:41:06.000000000 +0900 @@ -60,6 +60,7 @@ int ci_mtx_oldspl; int ci_want_resched; int ci_idepth; + struct lwp *ci_fpulwp; /* current owner of FPU */ }; extern struct cpu_info cpu_info_store; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/fpu.h src-sh4-fpu/./sys/arch/sh3/include/fpu.h --- src.orig/./sys/arch/sh3/include/fpu.h 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/fpu.h 2009-07-23 21:09:41.000000000 +0900 @@ -0,0 +1,163 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SH3_FPU_H_ +#define _SH3_FPU_H_ + +#if defined(_KERNEL) + +struct lwp; +struct ksiginfo; +struct trapframe; + +void sh_fpu_init(void); + +#ifdef SH3 +void sh3_fpu_enable(void); +void sh3_fpu_save_lwp(struct lwp *, bool); +int sh3_fpu_exception(struct lwp *, struct trapframe *, struct ksiginfo *); +#endif + +#ifdef SH4 +void sh4_fpu_enable(void); +void sh4_fpu_save_lwp(struct lwp *, bool); +int sh4_fpu_exception(struct lwp *, struct trapframe *, struct ksiginfo *); +#endif + +#if defined(SH3) && defined(SH4) +extern void (*__sh_fpu_enable)(void); +extern void (*__sh_fpu_save_lwp)(struct lwp *, bool); +extern int (*__sh_fpu_exception)(struct lwp *, struct trapframe *, + struct ksiginfo *); + +#define sh_fpu_enable() (*__sh_fpu_enable)() +#define sh_fpu_save_lwp(l,s) (*__sh_fpu_save_lwp)(l,s) +#define sh_fpu_exception(l,t,s) (*__sh_fpu_exception)(l,t,s) +#define CPU_HAS_FPU (CPU_IS_SH4) + +#elif defined(SH3) + +#define sh_fpu_enable() sh3_fpu_enable() +#define sh_fpu_save_lwp(l,s) sh3_fpu_save_lwp(l,s) +#define sh_fpu_exception(l,t,s) sh3_fpu_exception(l,t,s) +#define CPU_HAS_FPU (0) /* XXX: SH3E */ + +#elif defined(SH4) + +#define sh_fpu_enable() sh4_fpu_enable() +#define sh_fpu_save_lwp(l,s) sh4_fpu_save_lwp(l,s) +#define sh_fpu_exception(l,t,s) sh4_fpu_exception(l,t,s) +#define CPU_HAS_FPU (1) + +#endif /* SH3 && SH4 */ + +#endif /* _KERNEL */ + +#if !defined(__ASSEMBLER__) +/* FPU control register access */ +static __inline int __unused +get_fpscr(void) +{ + int r; + + __asm volatile ("sts fpscr, %0" : "=r"(r)); + + return r; +} + +static __inline void __unused +set_fpscr(int r) +{ + + __asm volatile ("lds %0, fpscr" :: "r"(r)); +} + +static __inline int __unused +get_fpul(void) +{ + int r; + + __asm volatile ("sts fpul, %0" : "=r"(r)); + + return r; +} + +static __inline void __unused +set_fpul(int r) +{ + + __asm volatile ("lds %0, fpul" :: "r"(r)); +} +#endif /* !__ASSEMBLER__ */ + +/* + * FPU register definition + */ +#define FPREGS_PER_BANK 0x10 +#define FP_BANK_BIT 0x10 + +/* fpscr bit */ +#define FPSCR_RM (0x03 << 0) /* Round mode */ +#define RM_NEAREST (0x00 << 0) /* nearest (SH4 only) */ +#define RM_ZERO (0x01 << 0) /* round to zero */ +#define FPSCR_FLAG (0x1f << 2) /* FPU exception flag: VZOUI */ +#define FPSCR_ENABLE (0x1f << 7) /* FPU exception enable: VZOUI */ +#define FPSCR_CAUSE (0x3f << 12) /* FPU exception cause: EVZOUI */ +#define FPSCR_DN (0x01 << 18) /* Denormal mode: 0=denormal (SH4 only), 1=0 */ +#define FPSCR_PR (0x01 << 19) /* precision (SH4 only): 0=float, 1=double */ +#define FPSCR_SZ (0x01 << 20) /* fmov size (SH4 only): 0=32, 1=64 */ +#define FPSCR_FR (0x01 << 21) /* register bank (SH4 only) */ +#define FPSCR_MASK (0x003fffff) + +/* FPU exception flag/enable/cause bit */ +#define FP_I_BIT (1 << 0) /* inexact result (SH4 only) */ +#define FP_U_BIT (1 << 1) /* underflow (SH4 only) */ +#define FP_O_BIT (1 << 2) /* overflow (SH4 only) */ +#define FP_Z_BIT (1 << 3) /* divide by zero */ +#define FP_V_BIT (1 << 4) /* invalid operation */ +#define FP_E_BIT (1 << 5) /* FPU error (SH4 only) */ +#define FP_ALL_BIT (FP_I_BIT|FP_U_BIT|FP_O_BIT|FP_Z_BIT|FP_V_BIT) + +/* FPU exception flag/enable/cause shift bits */ +#define FP_FLAG_SHIFT 2 +#define FP_ENABLE_SHIFT 7 +#define FP_CAUSE_SHIFT 12 + +#define FP_FLAG_MASK FP_ALL_BIT +#define FP_ENABLE_MASK FP_ALL_BIT +#define FP_CAUSE_MASK (FP_ALL_BIT|FP_E_BIT) + +#define FP_FLAG(r) (((r) >> FP_FLAG_SHIFT) & FP_FLAG_MASK) +#define FP_ENABLE(r) (((r) >> FP_ENABLE_SHIFT) & FP_ENABLE_MASK) +#define FP_CAUSE(r) (((r) >> FP_CAUSE_SHIFT) & FP_CAUSE_MASK) + +/* fpscr initial value */ +#define SH3_FPSCR_INIT (RM_ZERO|FPSCR_DN) +#define SH4_FPSCR_INIT (RM_NEAREST|FPSCR_PR) + +#endif /* !_SH3_FPU_H_ */ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/mcontext.h src-sh4-fpu/./sys/arch/sh3/include/mcontext.h --- src.orig/./sys/arch/sh3/include/mcontext.h 2008-06-05 23:46:01.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/mcontext.h 2009-07-08 22:41:43.000000000 +0900 @@ -65,9 +65,43 @@ /* Convenience synonym */ #define _REG_SP _REG_R15 +#define _REG_FPSCR 0 +#define _REG_FPUL 1 +#define _REG_FR0 2 +#define _REG_FR1 3 +#define _REG_FR2 4 +#define _REG_FR3 5 +#define _REG_FR4 6 +#define _REG_FR5 7 +#define _REG_FR6 8 +#define _REG_FR7 9 +#define _REG_FR8 10 +#define _REG_FR9 11 +#define _REG_FR10 12 +#define _REG_FR11 13 +#define _REG_FR12 14 +#define _REG_FR13 15 +#define _REG_FR14 16 +#define _REG_FR15 17 +#define _REG_FR16 18 +#define _REG_FR17 19 +#define _REG_FR18 20 +#define _REG_FR19 21 +#define _REG_FR20 22 +#define _REG_FR21 23 +#define _REG_FR22 24 +#define _REG_FR23 25 +#define _REG_FR24 26 +#define _REG_FR25 27 +#define _REG_FR26 28 +#define _REG_FR27 29 +#define _REG_FR28 30 +#define _REG_FR29 31 +#define _REG_FR30 32 +#define _REG_FR31 33 + /* * FPU state description. - * XXX: kernel doesn't support FPU yet, so this is just a placeholder. */ typedef struct { int __fpr_fpscr; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/pcb.h src-sh4-fpu/./sys/arch/sh3/include/pcb.h --- src.orig/./sys/arch/sh3/include/pcb.h 2008-04-29 11:39:26.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/pcb.h 2009-07-11 03:56:21.000000000 +0900 @@ -33,12 +33,16 @@ #define _SH3_PCB_H_ #include +#include struct pcb { struct switchframe pcb_sf; /* kernel context for resume */ void * pcb_onfault; /* for copyin/out fault */ int pcb_faultbail; /* bail out before call uvm_fault. */ + struct cpu_info * pcb_fpcpu; /* CPU with our FP state */ + __fpregset_t pcb_fpu; /* floating point registers */ }; extern struct pcb *curpcb; + #endif /* !_SH3_PCB_H_ */ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/proc.h src-sh4-fpu/./sys/arch/sh3/include/proc.h --- src.orig/./sys/arch/sh3/include/proc.h 2008-02-16 07:22:38.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/proc.h 2009-07-08 22:42:30.000000000 +0900 @@ -57,7 +57,7 @@ }; /* md_flags */ -#define MDP_USEDFPU 0x0001 /* has used the FPU */ +#define MDL_USEDFPU 0x0001 /* has used the FPU */ struct lwp; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/psl.h src-sh4-fpu/./sys/arch/sh3/include/psl.h --- src.orig/./sys/arch/sh3/include/psl.h 2008-01-05 11:05:53.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/psl.h 2009-07-08 22:43:10.000000000 +0900 @@ -45,16 +45,17 @@ #define PSL_IMASK 0x000000f0 /* Interrupt Mask bit */ #define PSL_QBIT 0x00000100 /* Q bit */ #define PSL_MBIT 0x00000200 /* M bit */ +#define PSL_FDBIT 0x00008000 /* FD bit (SH4 only) */ #define PSL_BL 0x10000000 /* Exception Block bit */ #define PSL_RB 0x20000000 /* Register Bank bit */ #define PSL_MD 0x40000000 /* Processor Mode bit */ /* 1 = kernel, 0 = user */ #define PSL_MBO 0x00000000 /* must be one bits */ -#define PSL_MBZ 0x8ffffc0c /* must be zero bits */ +#define PSL_MBZ 0x8fff7c0c /* must be zero bits */ #define PSL_USERSET 0 -#define PSL_USERSTATIC (PSL_BL|PSL_RB|PSL_MD|PSL_IMASK|PSL_MBO|PSL_MBZ) +#define PSL_USERSTATIC (PSL_BL|PSL_RB|PSL_MD|PSL_FDBIT|PSL_IMASK|PSL_MBO|PSL_MBZ) #define KERNELMODE(sr) ((sr) & PSL_MD) diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/ptrace.h src-sh4-fpu/./sys/arch/sh3/include/ptrace.h --- src.orig/./sys/arch/sh3/include/ptrace.h 2008-10-30 11:36:05.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/ptrace.h 2009-07-08 22:44:09.000000000 +0900 @@ -43,14 +43,17 @@ #define PT_GETREGS (PT_FIRSTMACH + 3) #define PT_SETREGS (PT_FIRSTMACH + 4) +#define PT_GETFPREGS (PT_FIRSTMACH + 5) +#define PT_SETFPREGS (PT_FIRSTMACH + 6) #define PT_MACHDEP_STRINGS \ "(unused)", \ "PT___GETREGS40", \ "PT___SETREGS40", \ "PT_GETREGS", \ - "PT_SETREGS", - + "PT_SETREGS", \ + "PT_GETFPREGS", \ + "PT_SETFPREGS", #ifdef _KERNEL #ifdef _KERNEL_OPT diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/reg.h src-sh4-fpu/./sys/arch/sh3/include/reg.h --- src.orig/./sys/arch/sh3/include/reg.h 2008-10-30 11:36:05.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/include/reg.h 2009-07-09 20:52:23.000000000 +0900 @@ -129,4 +129,17 @@ int r_r0; }; + +/* + * Registers accessible to ptrace(2) syscall for debugger + * The machine-dependent code for PT_FP{SET,GET}REGS needs to + * use whichever order, defined above, is correct, so that it + * is all invisible to the user. + */ +struct fpreg { + int fpr_fpscr; + int fpr_fpul; + int fpr_fr[32]; +}; + #endif /* !_SH3_REG_H_ */ diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/exception.c src-sh4-fpu/./sys/arch/sh3/sh3/exception.c --- src.orig/./sys/arch/sh3/sh3/exception.c 2008-12-20 01:06:35.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/exception.c 2009-07-09 17:09:14.000000000 +0900 @@ -101,6 +101,7 @@ #include #include +#include #include #include #include @@ -219,6 +220,17 @@ ksi.ksi_addr = (void *)tf->tf_spc; goto trapsignal; + case EXPEVT_FPU_DISABLE | EXP_USER: /* FALLTHROUGH */ + case EXPEVT_FPU_SLOT_DISABLE | EXP_USER: + sh_fpu_enable(); + break; + + case EXPEVT_FPU | EXP_USER: + KSI_INIT_TRAP(&ksi); + if (sh_fpu_exception(l, tf, &ksi)) + goto do_panic; + goto trapsignal; + default: goto do_panic; } diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/fpu.c src-sh4-fpu/./sys/arch/sh3/sh3/fpu.c --- src.orig/./sys/arch/sh3/sh3/fpu.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/fpu.c 2009-07-23 21:06:14.000000000 +0900 @@ -0,0 +1,63 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include + +#include + +#if defined(SH3) && defined(SH4) +void (*__sh_fpu_enable)(void); +void (*__sh_fpu_save_lwp)(struct lwp *, bool); +int (*__sh_fpu_exception)(struct lwp *, struct trapframe *, struct ksiginfo *); +#endif /* SH3 && SH4 */ + +void +sh_fpu_init(void) +{ + + /* + * Assign function hooks but only if both SH3 and SH4 are defined. + * They are called directly otherwise. See . + */ +#if defined(SH3) && defined(SH4) + if (CPU_IS_SH3) { + __sh_fpu_enable = sh3_fpu_enable; + __sh_fpu_save_lwp = sh3_fpu_save_lwp; + __sh_fpu_exception = sh3_fpu_exception; + } else if (CPU_IS_SH4) { + __sh_fpu_enable = sh4_fpu_enable; + __sh_fpu_save_lwp = sh4_fpu_save_lwp; + __sh_fpu_exception = sh4_fpu_exception; + } else + panic("sh_fpu_init: unknown CPU type"); +#endif /* SH3 && SH4 */ +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/fpu_sh3.c src-sh4-fpu/./sys/arch/sh3/sh3/fpu_sh3.c --- src.orig/./sys/arch/sh3/sh3/fpu_sh3.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/fpu_sh3.c 2009-07-23 21:06:30.000000000 +0900 @@ -0,0 +1,68 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include + +#include +#include + +/* + * SH3 FPU + */ + +void +sh3_fpu_enable(void) +{ + + /* Nothing to do. */ +} + +/*ARGSUSED*/ +void +sh3_fpu_save_lwp(struct lwp *l, bool save) +{ + + panic("sh3_fpu_save_lwp: not supported"); +} + +/*ARGSUSED*/ +int +sh3_fpu_exception(struct lwp *l, struct trapframe *tf, struct ksiginfo *ksi) +{ + + ksi->ksi_signo = SIGFPE; + ksi->ksi_code = FPE_FLTINV; + ksi->ksi_addr = (void *)tf->tf_spc; + + return 0; /* trapsignal */ +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/fpu_sh4.c src-sh4-fpu/./sys/arch/sh3/sh3/fpu_sh4.c --- src.orig/./sys/arch/sh3/sh3/fpu_sh4.c 1970-01-01 09:00:00.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/fpu_sh4.c 2009-07-28 19:27:21.000000000 +0900 @@ -0,0 +1,310 @@ +/* $NetBSD$ */ +#define FPUDEBUG +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include + +#include + +#if defined(FPUDEBUG) +#define DPRINTF(s) printf s +#else +#define DPRINTF(s) +#endif + +static inline int +get_sr(void) +{ + int r; + + __asm volatile ("stc sr, %0" : "=r"(r)); + + return r; +} + +static inline void +set_sr(int r) +{ + + __asm volatile ("ldc %0, sr" :: "r"(r)); +} + +static void +sh4_fpu_save_regs(__fpregset_t *fp) +{ + int sr; + int fpscr; + + DPRINTF(("%s\n", __func__)); + + sr = get_sr(); + set_sr(sr & ~PSL_FDBIT); + + fpscr = get_fpscr(); + + /* save FPU register */ + set_fpscr((fpscr | FPSCR_FR) & ~FPSCR_SZ); + __asm volatile ( + "mov %0, r4\n\t" + "fmov.s fr15, @-r4\n\t" + "fmov.s fr14, @-r4\n\t" + "fmov.s fr13, @-r4\n\t" + "fmov.s fr12, @-r4\n\t" + "fmov.s fr11, @-r4\n\t" + "fmov.s fr10, @-r4\n\t" + "fmov.s fr9, @-r4\n\t" + "fmov.s fr8, @-r4\n\t" + "fmov.s fr7, @-r4\n\t" + "fmov.s fr6, @-r4\n\t" + "fmov.s fr5, @-r4\n\t" + "fmov.s fr4, @-r4\n\t" + "fmov.s fr3, @-r4\n\t" + "fmov.s fr2, @-r4\n\t" + "fmov.s fr1, @-r4\n\t" + "fmov.s fr0, @-r4\n\t" + "frchg\n\t" + "fmov.s fr15, @-r4\n\t" + "fmov.s fr14, @-r4\n\t" + "fmov.s fr13, @-r4\n\t" + "fmov.s fr12, @-r4\n\t" + "fmov.s fr11, @-r4\n\t" + "fmov.s fr10, @-r4\n\t" + "fmov.s fr9, @-r4\n\t" + "fmov.s fr8, @-r4\n\t" + "fmov.s fr7, @-r4\n\t" + "fmov.s fr6, @-r4\n\t" + "fmov.s fr5, @-r4\n\t" + "fmov.s fr4, @-r4\n\t" + "fmov.s fr3, @-r4\n\t" + "fmov.s fr2, @-r4\n\t" + "fmov.s fr1, @-r4\n\t" + "fmov.s fr0, @-r4\n\t" + :: "r"(&fp->__fpr_regs[32])); + + /* save FPU control register */ + fp->__fpr_fpul = get_fpul(); + fp->__fpr_fpscr = fpscr; + + set_fpscr(fpscr); + + set_sr(sr); +} + +static void +sh4_fpu_load_regs(__fpregset_t *fp) +{ + int sr; + int fpscr; + + DPRINTF(("%s\n", __func__)); + + sr = get_sr(); + set_sr(sr & ~PSL_FDBIT); + + fpscr = get_fpscr(); + + /* load FPU registers */ + set_fpscr(fpscr & ~(FPSCR_FR|FPSCR_SZ)); + __asm volatile ( + "mov %0, r4\n\t" + "fmov.s @r4+, fr0\n\t" + "fmov.s @r4+, fr1\n\t" + "fmov.s @r4+, fr2\n\t" + "fmov.s @r4+, fr3\n\t" + "fmov.s @r4+, fr4\n\t" + "fmov.s @r4+, fr5\n\t" + "fmov.s @r4+, fr6\n\t" + "fmov.s @r4+, fr7\n\t" + "fmov.s @r4+, fr8\n\t" + "fmov.s @r4+, fr9\n\t" + "fmov.s @r4+, fr10\n\t" + "fmov.s @r4+, fr11\n\t" + "fmov.s @r4+, fr12\n\t" + "fmov.s @r4+, fr13\n\t" + "fmov.s @r4+, fr14\n\t" + "fmov.s @r4+, fr15\n\t" + "frchg\n\t" + "fmov.s @r4+, fr0\n\t" + "fmov.s @r4+, fr1\n\t" + "fmov.s @r4+, fr2\n\t" + "fmov.s @r4+, fr3\n\t" + "fmov.s @r4+, fr4\n\t" + "fmov.s @r4+, fr5\n\t" + "fmov.s @r4+, fr6\n\t" + "fmov.s @r4+, fr7\n\t" + "fmov.s @r4+, fr8\n\t" + "fmov.s @r4+, fr9\n\t" + "fmov.s @r4+, fr10\n\t" + "fmov.s @r4+, fr11\n\t" + "fmov.s @r4+, fr12\n\t" + "fmov.s @r4+, fr13\n\t" + "fmov.s @r4+, fr14\n\t" + "fmov.s @r4+, fr15\n\t" + :: "r"(&fp->__fpr_regs[0])); + + /* load FPU control register */ + set_fpul(fp->__fpr_fpul); + set_fpscr(fp->__fpr_fpscr); + + set_sr(sr); +} + +/* + * Save current CPU's FPU state. + */ +static void +sh4_fpu_save_cpu(bool save) +{ + struct cpu_info *ci; + struct lwp *l; + int s; + + s = _cpu_intr_suspend(); + + ci = curcpu(); + DPRINTF(("%s: start: lwp=%p\n", __func__, ci->ci_fpulwp)); + + l = ci->ci_fpulwp; + if (l == NULL) { + DPRINTF(("%s: ci->ci_fpulwp is NULL\n", __func__)); + goto out; + } + + if (save) { + sh4_fpu_save_regs(&l->l_addr->u_pcb.pcb_fpu); + } + + ci->ci_fpulwp->l_md.md_regs->tf_ssr |= PSL_FDBIT; + ci->ci_fpulwp = NULL; + l->l_addr->u_pcb.pcb_fpcpu = NULL; +out: + _cpu_intr_resume(s); + + DPRINTF(("%s: end: lwp=%p\n", __func__, ci->ci_fpulwp)); +} + +void +sh4_fpu_enable(void) +{ + struct cpu_info *ci = curcpu(); + struct lwp *l = curlwp; + struct pcb *pcb = &l->l_addr->u_pcb; + int s; + + DPRINTF(("%s: start: lwp=%p\n", __func__, l)); + + s = _cpu_intr_suspend(); + + if ((l->l_md.md_flags & MDL_USEDFPU) == 0) { + DPRINTF(("%s: !MDL_USEDFPU\n", __func__)); + memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu)); + pcb->pcb_fpu.__fpr_fpscr = SH4_FPSCR_INIT; + l->l_md.md_flags |= MDL_USEDFPU; + } + + /* + * If we own the CPU but FP is disabled, simply enable it and return. + */ + if (ci->ci_fpulwp == l) + goto out; + + if (ci->ci_fpulwp != NULL) + sh4_fpu_save_cpu(true); + sh4_fpu_load_regs(&pcb->pcb_fpu); + + pcb->pcb_fpcpu = ci; + ci->ci_fpulwp = l; +out: + l->l_md.md_regs->tf_ssr &= ~PSL_FDBIT; + _cpu_intr_resume(s); + + DPRINTF(("%s: end: lwp=%p\n", __func__, l)); +} + +void +sh4_fpu_save_lwp(struct lwp *l, bool save) +{ + + DPRINTF(("%s: start: lwp=%p\n", __func__, l)); + + if (l->l_addr->u_pcb.pcb_fpcpu != NULL) { + DPRINTF(("%s: do sh4_fpu_save_cpu\n", __func__)); + sh4_fpu_save_cpu(save); + } + + if (!save) { + DPRINTF(("%s: do clean\n", __func__)); + /* Ensure we restart with a clean slate. */ + l->l_md.md_flags &= ~MDL_USEDFPU; + } + + DPRINTF(("%s: end: lwp=%p\n", __func__, l)); +} + +int +sh4_fpu_exception(struct lwp *l, struct trapframe *tf, struct ksiginfo *ksi) +{ + static const int cause2sigcode[6] = { + FPE_FLTRES, /* FP_I_BIT */ + FPE_FLTUND, /* FP_U_BIT */ + FPE_FLTOVF, /* FP_O_BIT */ + FPE_FLTDIV, /* FP_Z_BIT */ + FPE_FLTINV, /* FP_V_BIT */ + FPE_FLTRES /* FP_E_BIT */ + }; + int fpscr; + int cause; + int i; + + fpscr = get_fpscr(); + + cause = FP_CAUSE(fpscr); + cause &= FP_ENABLE(fpscr) | FP_E_BIT; + + DPRINTF(("%s: fpscr = 0x%x, cause = 0x%x\n", __func__, fpscr, cause)); + + ksi->ksi_signo = SIGFPE; + ksi->ksi_addr = (void *)tf->tf_spc; + + for (i = 0; i < __arraycount(cause2sigcode); i++) { + if (cause & (1 << i)) { + ksi->ksi_code = cause2sigcode[i]; + break; + } + } + if (i == __arraycount(cause2sigcode)) { + ksi->ksi_code = FPE_FLTINV; + } + + return 0; /* trapsignal */ +} diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/process_machdep.c src-sh4-fpu/./sys/arch/sh3/sh3/process_machdep.c --- src.orig/./sys/arch/sh3/sh3/process_machdep.c 2008-10-30 11:36:05.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/process_machdep.c 2009-07-28 19:31:36.000000000 +0900 @@ -88,6 +88,7 @@ #include #include +#include #include #include @@ -142,6 +143,35 @@ return (0); } +int +process_read_fpregs(struct lwp *l, struct fpreg *fpregs) +{ + __fpregset_t *fp; + int i; + + if (CPU_HAS_FPU) { + if ((l->l_md.md_flags & MDL_USEDFPU)) { + sh_fpu_save_lwp(l, true); + } else { + memset(&l->l_addr->u_pcb.pcb_fpu, 0, + sizeof(l->l_addr->u_pcb.pcb_fpu)); + l->l_addr->u_pcb.pcb_fpu.__fpr_fpscr = SH4_FPSCR_INIT; + l->l_md.md_flags |= MDL_USEDFPU; + } + + fp = &l->l_md.md_pcb->pcb_fpu; + fpregs->fpr_fpscr = fp->__fpr_fpscr; + fpregs->fpr_fpul = fp->__fpr_fpul; + for (i = 0; i < __arraycount(fpregs->fpr_fr); i++) { + fpregs->fpr_fr[i] = fp->__fpr_regs[i]; + } + } else { + memset(fpregs, 0, sizeof(struct fpreg)); + } + + return (0); +} + #endif /* PTRACE || COREDUMP */ @@ -186,6 +216,29 @@ return (0); } +int +process_write_fpregs(struct lwp *l, const struct fpreg *fpregs) +{ + __fpregset_t *fp; + int i; + + if (CPU_HAS_FPU) { + if (l->l_md.md_flags & MDL_USEDFPU) { + sh_fpu_save_lwp(l, false); + } else { + l->l_md.md_flags |= MDL_USEDFPU; + } + + fp = &l->l_md.md_pcb->pcb_fpu; + fp->__fpr_fpscr = fpregs->fpr_fpscr; + fp->__fpr_fpul = fpregs->fpr_fpul; + for (i = 0; i < __arraycount(fp->__fpr_regs); i++) { + fp->__fpr_regs[i] = fpregs->fpr_fr[i]; + } + } + + return (0); +} #ifdef __HAVE_PTRACE_MACHDEP diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/sh3_machdep.c src-sh4-fpu/./sys/arch/sh3/sh3/sh3_machdep.c --- src.orig/./sys/arch/sh3/sh3/sh3_machdep.c 2009-03-21 18:58:59.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/sh3_machdep.c 2009-07-28 19:36:42.000000000 +0900 @@ -101,6 +101,7 @@ #include #include #include +#include #include #include #include @@ -160,6 +161,9 @@ /* MMU access ops. */ sh_mmu_init(); + /* FPU access ops. */ + sh_fpu_init(); + /* Hardclock, RTC initialize. */ machine_clock_init(); @@ -414,9 +418,12 @@ cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags) { const struct trapframe *tf = l->l_md.md_regs; + const struct pcb *pcb = &l->l_addr->u_pcb; __greg_t *gr = mcp->__gregs; __greg_t ras_pc; + printf("%s: l=%p\n", __func__, l); + /* Save register context. */ gr[_REG_GBR] = tf->tf_gbr; gr[_REG_PC] = tf->tf_spc; @@ -447,17 +454,31 @@ *flags |= _UC_CPU; - /* FPU context is currently not handled by the kernel. */ - memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs)); + if ((l->l_md.md_flags & MDL_USEDFPU) != 0) { + printf("%s: MDL_USEDFPU: l=%p\n", __func__, l); + /* + * If this process is the current FP owner, dump its + * context to the PCB first. + */ + if (pcb->pcb_fpcpu) { + sh_fpu_save_lwp(l, true); + } + memcpy(&mcp->__fpregs, &pcb->pcb_fpu, sizeof(mcp->__fpregs)); + *flags |= _UC_FPU; + } else + memset(&mcp->__fpregs, 0, sizeof(mcp->__fpregs)); } int cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags) { struct trapframe *tf = l->l_md.md_regs; + struct pcb *pcb = &l->l_addr->u_pcb; const __greg_t *gr = mcp->__gregs; struct proc *p = l->l_proc; + printf("%s: l=%p\n", __func__, l); + /* Restore register context, if any. */ if ((flags & _UC_CPU) != 0) { /* Check for security violations. */ @@ -488,12 +509,19 @@ tf->tf_r15 = gr[_REG_R15]; } -#if 0 - /* XXX: FPU context is currently not handled by the kernel. */ - if (flags & _UC_FPU) { - /* TODO */; + /* + * If we were using the FPU, forget that we were. + */ + if (pcb->pcb_fpcpu) { + sh_fpu_save_lwp(l, false); + } + + /* Restore floating point register context, if any. */ + if ((flags & _UC_FPU) != 0) { + printf("%s: _UC_FPU: l=%p\n", __func__, l); + memcpy(&pcb->pcb_fpu, &mcp->__fpregs, sizeof(pcb->pcb_fpu)); + l->l_md.md_flags |= MDL_USEDFPU; } -#endif mutex_enter(p->p_lock); if (flags & _UC_SETSTACK) @@ -513,11 +541,13 @@ { struct trapframe *tf; - l->l_md.md_flags &= ~MDP_USEDFPU; + l->l_md.md_flags &= ~MDL_USEDFPU; tf = l->l_md.md_regs; tf->tf_ssr = PSL_USERSET; + if (CPU_HAS_FPU) + tf->tf_ssr |= PSL_FDBIT; /* disable FPU */ tf->tf_spc = pack->ep_entry; tf->tf_pr = 0; diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/vm_machdep.c src-sh4-fpu/./sys/arch/sh3/sh3/vm_machdep.c --- src.orig/./sys/arch/sh3/sh3/vm_machdep.c 2008-11-22 06:15:53.000000000 +0900 +++ src-sh4-fpu/./sys/arch/sh3/sh3/vm_machdep.c 2009-07-23 21:34:06.000000000 +0900 @@ -102,6 +102,7 @@ #include #include +#include #include #include #include @@ -135,12 +136,26 @@ cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize, void (*func)(void *), void *arg) { + struct pcb *pcb = &l2->l_addr->u_pcb; struct switchframe *sf; #if 0 /* FIXME: probably wrong for yamt-idlelwp */ KDASSERT(l1 == curlwp || l1 == &lwp0); #endif + /* + * If fpuproc != p1, then the fpu h/w state is irrelevant and the + * state had better already be in the pcb. This is true for forks + * but not for dumps. + * + * If fpuproc == p1, then we have to save the fpu h/w state to + * p1's pcb so that we can copy it. + */ + if (l1->l_addr->u_pcb.pcb_fpcpu != NULL) { + printf("%s: l1=%p, l2=%p\n", __func__, l1, l2); + sh_fpu_save_lwp(l1, true); + } + sh3_setup_uarea(l2); l2->l_md.md_flags = l1->l_md.md_flags; @@ -151,6 +166,10 @@ if (stack != NULL) l2->l_md.md_regs->tf_r15 = (u_int)stack + stacksize; + /* Copy FPU context */ + pcb->pcb_fpcpu = l1->l_addr->u_pcb.pcb_fpcpu; + memcpy(&pcb->pcb_fpu, &l1->l_addr->u_pcb.pcb_fpu, sizeof(pcb->pcb_fpu)); + /* When l2 is switched to, jump to the trampoline */ sf = &l2->l_md.md_pcb->pcb_sf; sf->sf_pr = (int)lwp_trampoline; @@ -175,6 +194,8 @@ sh3_setup_uarea(l); l->l_md.md_regs->tf_ssr = PSL_USERSET; + if (CPU_HAS_FPU) + l->l_md.md_regs->tf_ssr |= PSL_FDBIT; /* disable FPU */ /* When lwp is switched to, jump to the trampoline */ sf = &l->l_md.md_pcb->pcb_sf; @@ -293,18 +314,24 @@ /* - * Exit hook + * cpu_lwp_free is called from exit() to let machine-dependent + * code free machine-dependent resources. Note that this routine + * must not block. */ void cpu_lwp_free(struct lwp *l, int proc) { - /* Nothing to do */ + /* If we were using the FPU, forget about it. */ + if (l->l_addr->u_pcb.pcb_fpcpu != NULL) { + printf("%s: l=%p\n", __func__, l); + sh_fpu_save_lwp(l, false); + } } - /* - * lwp_free() hook + * cpu_lwp_free2 is called when an LWP is being reaped. + * This routine may block. */ void cpu_lwp_free2(struct lwp *l) @@ -313,6 +340,7 @@ /* Nothing to do */ } + /* * Map an IO request into kernel virtual address space. Requests fall into * one of five catagories: