diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./bin/ksh/tree.c src-sh4-fpu-lazy/./bin/ksh/tree.c
--- src.orig/./bin/ksh/tree.c	2005-06-27 04:09:00.000000000 +0900
+++ src-sh4-fpu-lazy/./bin/ksh/tree.c	2009-12-16 19:02:22.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-lazy/./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-lazy/./crypto/external/bsd/openssl/lib/libcrypto/Makefile	2009-12-16 00:39:00.000000000 +0900
@@ -120,6 +120,7 @@
 .endif
 
 COPTS.eng_padlock.c = -Wno-stack-protector
+COPTS.asn1_par.c = -O1
 
 INCSDIR=/usr/include/openssl
 
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./distrib/sets/lists/comp/ad.sh3 src-sh4-fpu-lazy/./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-lazy/./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-lazy/./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-lazy/./external/ibm-public/postfix/libexec/smtpd/Makefile	2009-12-16 19:55:09.000000000 +0900
@@ -24,4 +24,6 @@
 DPADD+=	${LIBPUTIL}
 LDADD+=	${LIBPUTIL}
 
+COPTS.smtpd_check.c+= -O1
+
 .include <bsd.prog.mk>
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-lazy/./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-lazy/./gnu/dist/gcc4/gcc/config/sh/lib1funcs.asm	2009-07-31 20:11:06.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)
@@ -2048,7 +2053,7 @@
 #endif
 
 	ENDFUNC(GLOBAL(set_fpscr))
-#ifndef NO_FPSCR_VALUES
+#if !defined(NO_FPSCR_VALUES) && !defined(__NetBSD__)
 #ifdef __ELF__
         .comm   GLOBAL(fpscr_values),8,4
 #else
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./gnu/usr.bin/gcc4/arch/sh3el/defs.mk src-sh4-fpu-lazy/./gnu/usr.bin/gcc4/arch/sh3el/defs.mk
--- src.orig/./gnu/usr.bin/gcc4/arch/sh3el/defs.mk	2007-06-22 01:58:49.000000000 +0900
+++ src-sh4-fpu-lazy/./gnu/usr.bin/gcc4/arch/sh3el/defs.mk	2009-12-21 12:04:19.000000000 +0900
@@ -35,7 +35,7 @@
 G_host_xm_file=
 G_host_xm_defines=
 G_tm_p_file=
-G_target_cpu_default=SELECT_SH3
+G_target_cpu_default=SELECT_SH4
 G_TM_H=tm.h      options.h ${GNUHOSTDIST}/gcc/config/sh/little.h ${GNUHOSTDIST}/gcc/config/sh/sh.h ${GNUHOSTDIST}/gcc/config/dbxelf.h ${GNUHOSTDIST}/gcc/config/elfos.h ${GNUHOSTDIST}/gcc/config/sh/elf.h ${GNUHOSTDIST}/gcc/config/netbsd.h ${GNUHOSTDIST}/gcc/config/netbsd-elf.h ${GNUHOSTDIST}/gcc/config/sh/netbsd-elf.h ${GNUHOSTDIST}/gcc/defaults.h insn-constants.h insn-flags.h options.h
 G_ALL_OPT_FILES=${GNUHOSTDIST}/gcc/c.opt ${GNUHOSTDIST}/gcc/common.opt ${GNUHOSTDIST}/gcc/config/sh/sh.opt
 G_tm_file_list=options.h ${GNUHOSTDIST}/gcc/config/sh/little.h ${GNUHOSTDIST}/gcc/config/sh/sh.h ${GNUHOSTDIST}/gcc/config/dbxelf.h ${GNUHOSTDIST}/gcc/config/elfos.h ${GNUHOSTDIST}/gcc/config/sh/elf.h ${GNUHOSTDIST}/gcc/config/netbsd.h ${GNUHOSTDIST}/gcc/config/netbsd-elf.h ${GNUHOSTDIST}/gcc/config/sh/netbsd-elf.h ${GNUHOSTDIST}/gcc/defaults.h
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./gnu/usr.bin/gcc4/arch/sh3el/tm.h src-sh4-fpu-lazy/./gnu/usr.bin/gcc4/arch/sh3el/tm.h
--- src.orig/./gnu/usr.bin/gcc4/arch/sh3el/tm.h	2006-06-27 04:54:04.000000000 +0900
+++ src-sh4-fpu-lazy/./gnu/usr.bin/gcc4/arch/sh3el/tm.h	2009-12-21 12:03:18.000000000 +0900
@@ -9,7 +9,7 @@
 # define NETBSD_ENABLE_PTHREADS
 #endif
 #ifndef SH_MULTILIB_CPU_DEFAULT
-# define SH_MULTILIB_CPU_DEFAULT "m3"
+# define SH_MULTILIB_CPU_DEFAULT "m4"
 #endif
 #ifndef SUPPORT_SH3
 # define SUPPORT_SH3 1
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./include/signal.h src-sh4-fpu-lazy/./include/signal.h
--- src.orig/./include/signal.h	2009-01-12 06:24:03.000000000 +0900
+++ src-sh4-fpu-lazy/./include/signal.h	2009-12-14 22:57:57.000000000 +0900
@@ -101,8 +101,12 @@
 #endif
 
 #ifndef _SIGINLINE
+#ifdef __GNUC_STDC_INLINE__
+#define _SIGINLINE extern __inline __attribute__((__gnu_inline__))
+#else
 #define _SIGINLINE extern __inline
 #endif
+#endif
 
 _SIGINLINE int
 sigaddset(sigset_t *set, int signo)
@@ -149,7 +153,7 @@
 	__sigfillset(set);
 	return (0);
 }
-#endif /* (__GNUC__ && __STDC__) || _LIBC */
+#endif /* (__GNUC__ && __STDC__) || _SIGINLINE */
 #endif /* !__LIBC12_SOURCE__ */
 
 /*
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/csu/sh3_elf/crt0.c src-sh4-fpu-lazy/./lib/csu/sh3_elf/crt0.c
--- src.orig/./lib/csu/sh3_elf/crt0.c	2004-08-27 06:16:41.000000000 +0900
+++ src-sh4-fpu-lazy/./lib/csu/sh3_elf/crt0.c	2009-07-28 22:57:29.000000000 +0900
@@ -92,3 +92,12 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include "common.c"
+
+#if defined(__SH4__)
+#include <sh3/fpu.h>
+
+int __fpscr_values[2] = {
+	SH4_FPSCR_INIT & ~FPSCR_PR,	/* float */
+	SH4_FPSCR_INIT | FPSCR_PR,	/* double */
+};
+#endif	/* __SH4__ */
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/Makefile.inc src-sh4-fpu-lazy/./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-lazy/./lib/libc/arch/sh3/Makefile.inc	2009-08-01 21:57:48.000000000 +0900
@@ -2,5 +2,5 @@
 
 SRCS+=	__sigaction14_sigtramp.c __sigtramp2.S
 
-CPPFLAGS+=      -DSOFTFLOAT # -DSOFTFLOAT_NEED_FIXUNS
-.include <softfloat/Makefile.inc>
+#CPPFLAGS+=      -DSOFTFLOAT # -DSOFTFLOAT_NEED_FIXUNS
+#.include <softfloat/Makefile.inc>
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-lazy/./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-lazy/./lib/libc/arch/sh3/gdtoa/gd_qnan.h	2009-07-22 20:34:24.000000000 +0900
@@ -2,6 +2,7 @@
 
 #include <machine/endian.h>
 
+/* 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-lazy/./lib/libc/arch/sh3/gen/Makefile.inc
--- src.orig/./lib/libc/arch/sh3/gen/Makefile.inc	2009-12-07 17:26:03.000000000 +0900
+++ src-sh4-fpu-lazy/./lib/libc/arch/sh3/gen/Makefile.inc	2009-12-07 17:38:15.000000000 +0900
@@ -18,6 +18,9 @@
 
 SRCS+=	nanf.c
 
+SRCS+=	fpgetmask.c fpgetround.c fpgetsticky.c
+SRCS+=	fpsetmask.c fpsetround.c fpsetsticky.c
+
 LSRCS.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/_setjmp.S src-sh4-fpu-lazy/./lib/libc/arch/sh3/gen/_setjmp.S
--- src.orig/./lib/libc/arch/sh3/gen/_setjmp.S	2006-01-05 11:04:41.000000000 +0900
+++ src-sh4-fpu-lazy/./lib/libc/arch/sh3/gen/_setjmp.S	2009-12-21 10:53:01.000000000 +0900
@@ -52,8 +52,32 @@
  */
 
 ENTRY(_setjmp)
-	add	#((_JB_HAS_MASK + 1) * 4), r4
 	mov	#0, r0
+#ifdef __SH4__
+	add	#(_JBLEN * 4), r4
+	sts	fpscr, r1
+	mov.l	r1, @-r4
+	lds	r0, fpscr
+	sts.l	fpul, @-r4
+	frchg
+	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
+
+	sts.l	mach, @-r4
+	sts.l	macl, @-r4
+
+	add	#-(4 * 4), r4		/* skip _JB_SIGMASK */
+#else
+	add	#((_JB_HAS_MASK + 1) * 4), r4
+#endif
 	mov.l	r0, @-r4		/* no saved signal mask */
 	mov.l	r15, @-r4
 	mov.l	r14, @-r4
@@ -78,6 +102,26 @@
 	mov.l	@r4+, r13
 	mov.l	@r4+, r14
 	mov.l	@r4+, r15
+#ifdef __SH4__
+	add	#(5 * 4), r4		/* skip _JB_HAS_MASK/_JB_SIGMASK */
+
+	lds.l	@r4+, macl
+	lds.l	@r4+, mach
+
+	mov	#0, r0
+	lds	r0, fpscr
+	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
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/fpgetmask.c src-sh4-fpu-lazy/./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-lazy/./lib/libc/arch/sh3/gen/fpgetmask.c	2009-12-21 17:16:36.000000000 +0900
@@ -0,0 +1,71 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <ieeefp.h>
+#include <sh3/fpu.h>
+
+#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-lazy/./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-lazy/./lib/libc/arch/sh3/gen/fpgetround.c	2009-12-21 17:16:47.000000000 +0900
@@ -0,0 +1,56 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <ieeefp.h>
+#include <sh3/fpu.h>
+
+#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-lazy/./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-lazy/./lib/libc/arch/sh3/gen/fpgetsticky.c	2009-12-21 17:16:58.000000000 +0900
@@ -0,0 +1,71 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <ieeefp.h>
+#include <sh3/fpu.h>
+
+#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-lazy/./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-lazy/./lib/libc/arch/sh3/gen/fpsetmask.c	2009-12-21 17:17:09.000000000 +0900
@@ -0,0 +1,103 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <ieeefp.h>
+#include <sh3/fpu.h>
+
+#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-lazy/./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-lazy/./lib/libc/arch/sh3/gen/fpsetround.c	2009-12-21 17:17:19.000000000 +0900
@@ -0,0 +1,80 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <ieeefp.h>
+#include <sh3/fpu.h>
+
+#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-lazy/./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-lazy/./lib/libc/arch/sh3/gen/fpsetsticky.c	2009-12-21 17:17:46.000000000 +0900
@@ -0,0 +1,95 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD$");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+
+#include <ieeefp.h>
+#include <sh3/fpu.h>
+
+#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-lazy/./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-lazy/./lib/libc/arch/sh3/gen/nanf.c	2009-07-22 20:34:15.000000000 +0900
@@ -8,6 +8,7 @@
 #include <math.h>
 #include <machine/endian.h>
 
+/* 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/libc/arch/sh3/gen/setjmp.S src-sh4-fpu-lazy/./lib/libc/arch/sh3/gen/setjmp.S
--- src.orig/./lib/libc/arch/sh3/gen/setjmp.S	2006-01-06 04:21:37.000000000 +0900
+++ src-sh4-fpu-lazy/./lib/libc/arch/sh3/gen/setjmp.S	2009-12-21 10:59:44.000000000 +0900
@@ -68,7 +68,32 @@
 	PIC_EPILOGUE
 
 	/* identical to _setjmp except that _JB_HAS_MASK is non-zero */
+#ifdef __SH4__
+	add	#(_JBLEN * 4), r4
+	sts	fpscr, r1
+	mov	#0, r0
+	mov.l	r1, @-r4
+	lds	r0, fpscr
+	sts.l	fpul, @-r4
+	frchg
+	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
+
+	sts.l	mach, @-r4
+	sts.l	macl, @-r4
+
+	add	#-(4 * 4), r4		/* skip _JB_SIGMASK */
+#else
 	add	#((_JB_HAS_MASK + 1) * 4), r4
+#endif
 	mov	#1, r0
 	mov.l	r0, @-r4		/* has signal mask */
 	mov.l	r15, @-r4
@@ -115,6 +140,26 @@
 	mov.l	@r4+, r13
 	mov.l	@r4+, r14
 	mov.l	@r4+, r15
+#ifdef __SH4__
+	add	#(5 * 4), r4		/* skip _JB_HAS_MASK/_JB_SIGMASK */
+
+	lds.l	@r4+, macl
+	lds.l	@r4+, mach
+
+	mov	#0, r0
+	lds	r0, fpscr
+	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 */
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libc/arch/sh3/gen/sigsetjmp.S src-sh4-fpu-lazy/./lib/libc/arch/sh3/gen/sigsetjmp.S
--- src.orig/./lib/libc/arch/sh3/gen/sigsetjmp.S	2006-01-06 04:21:37.000000000 +0900
+++ src-sh4-fpu-lazy/./lib/libc/arch/sh3/gen/sigsetjmp.S	2009-12-21 11:00:23.000000000 +0900
@@ -64,7 +64,32 @@
 	PIC_EPILOGUE
 
 2:	/* identical to _setjmp except that _JB_HAS_MASK is in the argument */
+#ifdef __SH4__
+	add	#(_JBLEN * 4), r4
+	sts	fpscr, r1
+	mov	#0, r0
+	mov.l	r1, @-r4
+	lds	r0, fpscr
+	sts.l	fpul, @-r4
+	frchg
+	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
+
+	sts.l	mach, @-r4
+	sts.l	macl, @-r4
+
+	add	#-(4 * 4), r4		/* skip _JB_SIGMASK */
+#else
 	add	#((_JB_HAS_MASK + 1) * 4), r4
+#endif
 	mov.l	r5, @-r4		/* has signal mask? */
 	mov.l	r15, @-r4
 	mov.l	r14, @-r4
@@ -115,6 +140,26 @@
 	mov.l	@r4+, r13
 	mov.l	@r4+, r14
 	mov.l	@r4+, r15
+#ifdef __SH4__
+	add	#(5 * 4), r4		/* skip _JB_HAS_MASK/_JB_SIGMASK */
+
+	lds.l	@r4+, macl
+	lds.l	@r4+, mach
+
+	mov	#0, r0
+	lds	r0, fpscr
+	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 */
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libkrb5/Makefile src-sh4-fpu-lazy/./lib/libkrb5/Makefile
--- src.orig/./lib/libkrb5/Makefile	2009-07-21 15:02:33.000000000 +0900
+++ src-sh4-fpu-lazy/./lib/libkrb5/Makefile	2009-12-16 00:55:50.000000000 +0900
@@ -724,6 +724,8 @@
 CPPFLAGS+=-DHAVE_IPV6
 .endif
 
+COPTS.crypto.c+= -O1
+
 CLEANFILES=	${ERR_FILES} krb_err.h krb5_err.h heim_err.h k524_err.h
 
 ${SRCS:.c=.o}: krb_err.h krb5_err.h heim_err.h k524_err.h
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./lib/libwrap/Makefile.cflags src-sh4-fpu-lazy/./lib/libwrap/Makefile.cflags
--- src.orig/./lib/libwrap/Makefile.cflags	2005-01-10 11:58:58.000000000 +0900
+++ src-sh4-fpu-lazy/./lib/libwrap/Makefile.cflags	2009-12-21 14:54:05.000000000 +0900
@@ -21,3 +21,5 @@
 .if (${USE_INET6} != "no")
 CPPFLAGS+=-DINET6
 .endif
+
+COPTS.hosts_access.c+= -O1
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./makeBuild.sh src-sh4-fpu-lazy/./makeBuild.sh
--- src.orig/./makeBuild.sh	1970-01-01 09:00:00.000000000 +0900
+++ src-sh4-fpu-lazy/./makeBuild.sh	2009-12-14 20:04:18.000000000 +0900
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+progname=$0
+
+usage() {
+  echo "Usage: ${progname} <machine> <date> <operation>"
+  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/sh4-fpu-${build_date}/root/${target_machine} \
+  -R /home/snapshot/sh4-fpu-${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-lazy/./share/mk/bsd.own.mk
--- src.orig/./share/mk/bsd.own.mk	2009-12-14 16:35:47.000000000 +0900
+++ src-sh4-fpu-lazy/./share/mk/bsd.own.mk	2009-12-16 17:56:09.000000000 +0900
@@ -554,8 +554,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}}
 
@@ -570,6 +575,8 @@
      ${MACHINE_CPU} == "m68k" || \
      ${MACHINE_GNU_ARCH} == "sh" || \
      ${MACHINE_GNU_ARCH} == "shle" || \
+     ${MACHINE_GNU_ARCH} == "sh4" || \
+     ${MACHINE_GNU_ARCH} == "sh4le" || \
      ${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-lazy/./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-lazy/./sys/arch/sh3/conf/files.sh3	2009-12-22 15:41:03.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			sh3 & sh4
+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-lazy/./sys/arch/sh3/include/Makefile
--- src.orig/./sys/arch/sh3/include/Makefile	2007-02-10 06:55:12.000000000 +0900
+++ src-sh4-fpu-lazy/./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-lazy/./sys/arch/sh3/include/cpu.h
--- src.orig/./sys/arch/sh3/include/cpu.h	2009-10-31 23:11:24.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/include/cpu.h	2009-10-31 23:17:13.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-lazy/./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-lazy/./sys/arch/sh3/include/fpu.h	2009-12-22 15:24:29.000000000 +0900
@@ -0,0 +1,164 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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.
+ */
+
+#ifndef _SH3_FPU_H_
+#define _SH3_FPU_H_
+
+#if !defined(__ASSEMBLER__)
+
+#if defined(_KERNEL)
+
+struct lwp;
+struct ksiginfo;
+struct trapframe;
+
+#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 *);
+
+void sh_fpu_init(void);
+#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)
+
+#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 */
+
+/* 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|FPSCR_DN)
+
+#endif /* !_SH3_FPU_H_ */
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/frame.h src-sh4-fpu-lazy/./sys/arch/sh3/include/frame.h
--- src.orig/./sys/arch/sh3/include/frame.h	2008-11-22 15:00:26.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/include/frame.h	2009-12-21 18:40:22.000000000 +0900
@@ -116,6 +116,8 @@
 	int	sf_gbr;
 	int	sf_sr;
 	int	sf_pr;
+	int	sf_macl;
+	int	sf_mach;
 	int	sf_r8;
 	int	sf_r9;
 	int	sf_r10;
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/mcontext.h src-sh4-fpu-lazy/./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-lazy/./sys/arch/sh3/include/mcontext.h	2009-12-22 15:21:39.000000000 +0900
@@ -32,6 +32,8 @@
 #ifndef _SH3_MCONTEXT_H_
 #define _SH3_MCONTEXT_H_
 
+#include <sh3/reg.h>
+
 /*
  * Layout of mcontext_t for the sh3 architecture.
  */
@@ -65,15 +67,46 @@
 /* Convenience synonym */
 #define	_REG_SP		_REG_R15
 
+#define	_REG_FR0	0
+#define	_REG_FR1	1
+#define	_REG_FR2	2
+#define	_REG_FR3	3
+#define	_REG_FR4	4
+#define	_REG_FR5	5
+#define	_REG_FR6	6
+#define	_REG_FR7	7
+#define	_REG_FR8	8
+#define	_REG_FR9	9
+#define	_REG_FR10	10
+#define	_REG_FR11	11
+#define	_REG_FR12	12
+#define	_REG_FR13	13
+#define	_REG_FR14	14
+#define	_REG_FR15	15
+#define	_REG_XR0	16
+#define	_REG_XR1	17
+#define	_REG_XR2	18
+#define	_REG_XR3	19
+#define	_REG_XR4	20
+#define	_REG_XR5	21
+#define	_REG_XR6	22
+#define	_REG_XR7	23
+#define	_REG_XR8	24
+#define	_REG_XR9	25
+#define	_REG_XR10	26
+#define	_REG_XR11	27
+#define	_REG_XR12	28
+#define	_REG_XR13	29
+#define	_REG_XR14	30
+#define	_REG_XR15	31
+#define	_REG_FPUL	32
+#define	_REG_FPSCR	33
+
 /*
  * FPU state description.
- * XXX: kernel doesn't support FPU yet, so this is just a placeholder.
  */
 typedef struct {
-	int		__fpr_fpscr;
-	int		__fpr_fpul;
-	/* XXX: redefine as a union when we do support FPU */
-	int		__fpr_regs[32];	/* SH3E has 16, SH4 has 32 */
+	struct fpreg fpr;
 } __fpregset_t;
 
 typedef struct {
@@ -93,5 +126,4 @@
 #define	_UC_SETSTACK		0x10000
 #define	_UC_CLRSTACK		0x20000
 
-
 #endif /* !_SH3_MCONTEXT_H_ */
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/pcb.h src-sh4-fpu-lazy/./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-lazy/./sys/arch/sh3/include/pcb.h	2009-12-20 18:00:53.000000000 +0900
@@ -33,12 +33,16 @@
 #define	_SH3_PCB_H_
 
 #include <sh3/frame.h>
+#include <sh3/reg.h>
 
 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 */
+	struct fpreg pcb_fpu;		/* floating point context */
 };
 
 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-lazy/./sys/arch/sh3/include/proc.h
--- src.orig/./sys/arch/sh3/include/proc.h	2009-11-22 18:47:51.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/include/proc.h	2009-11-22 18:53:38.000000000 +0900
@@ -58,7 +58,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-lazy/./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-lazy/./sys/arch/sh3/include/psl.h	2009-12-20 19:18:14.000000000 +0900
@@ -45,18 +45,19 @@
 #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)
+#define	KERNELMODE(sr)	((sr) & PSL_MD)
 
 #ifdef _KERNEL
 #ifndef _LOCORE
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/ptrace.h src-sh4-fpu-lazy/./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-lazy/./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-lazy/./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-lazy/./sys/arch/sh3/include/reg.h	2009-12-20 19:38:17.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_fr[32];
+	int fpr_fpul;
+	int fpr_fpscr;
+};
+
 #endif /* !_SH3_REG_H_ */
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/setjmp.h src-sh4-fpu-lazy/./sys/arch/sh3/include/setjmp.h
--- src.orig/./sys/arch/sh3/include/setjmp.h	2006-01-05 09:50:23.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/include/setjmp.h	2009-12-22 15:21:49.000000000 +0900
@@ -4,7 +4,7 @@
  * machine/setjmp.h: machine dependent setjmp-related information.
  */
 
-#define	_JBLEN 14		/* size, in longs, of a jmp_buf */
+#define	_JBLEN		26	/* size, in longs, of a jmp_buf */
 
 #define _JB_REG_PR	0
 #define _JB_REG_R8	1
@@ -18,5 +18,22 @@
 
 #define _JB_HAS_MASK	9
 #define _JB_SIGMASK	10	/* occupies sizeof(sigset_t) = 4 slots */
+/*	_JB_SIGMASK2	11	   occupies sizeof(sigset_t): slot 2 */
+/*	_JB_SIGMASK3	12	   occupies sizeof(sigset_t): slot 3 */
+/*	_JB_SIGMASK4	13	   occupies sizeof(sigset_t): slot 4 */
 
 #define _JB_REG_SP	_JB_REG_R15
+
+#define _JB_REG_MACL	14
+#define _JB_REG_MACH	15
+
+#define _JB_REG_FR12	16
+#define _JB_REG_FR13	17
+#define _JB_REG_FR14	18
+#define _JB_REG_FR15	19
+#define _JB_REG_XR12	20
+#define _JB_REG_XR13	21
+#define _JB_REG_XR14	22
+#define _JB_REG_XR15	23
+#define _JB_REG_FPUL	24
+#define _JB_REG_FPSCR	25
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/include/stdarg.h src-sh4-fpu-lazy/./sys/arch/sh3/include/stdarg.h
--- src.orig/./sys/arch/sh3/include/stdarg.h	2006-05-22 07:39:04.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/include/stdarg.h	2009-12-22 18:20:43.000000000 +0900
@@ -40,19 +40,30 @@
 typedef _BSD_VA_LIST_	va_list;
 
 #ifdef __lint__
-#define __builtin_next_arg(t)		((t) ? 0 : 0)
+#define	__builtin_next_arg(t)		((t) ? 0 : 0)
 #define	__builtin_stdarg_start(a, l)	((a) = ((l) ? 0 : 0))
+#define	__builtin_va_start(a, l)	((a) = ((l) ? 0 : 0))
 #define	__builtin_va_arg(a, t)		((t)((a) ? 0 : 0))
-#define	__builtin_va_end		/* nothing */
+#define	__builtin_va_end(a)		((void)(a))
 #define	__builtin_va_copy(d, s)		((d) = (s))
 #endif
 
-#if __GNUC_PREREQ__(2, 96)
+#if __GNUC_PREREQ__(4, 4)
+
+#define	va_start(ap, last)	__builtin_va_start(ap, last)
+#define	va_end(ap)		__builtin_va_end(ap)
+#define	va_arg(ap, type)	__builtin_va_arg(ap, type)
+#define	__va_copy(dest, src)	__builtin_va_copy(dest, src)
+
+#elif __GNUC_PREREQ__(2, 96)
+
 #define	va_start(ap, last)	__builtin_stdarg_start((ap), (last))
 #define	va_arg			__builtin_va_arg
 #define	va_end			__builtin_va_end
 #define	__va_copy(dest, src)	__builtin_va_copy((dest), (src))
+
 #else
+
 #define	__va_size(type) \
 	(((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
 
@@ -66,7 +77,7 @@
 
 #define	__va_copy(dest, src)	((dest) = (src))
 
-#endif /* __GNUC_PREREQ__(2, 96) */
+#endif
 
 #if !defined(_ANSI_SOURCE) &&						\
     (defined(_ISOC99_SOURCE) || (__STDC_VERSION__ - 0) >= 199901L ||	\
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/core_machdep.c src-sh4-fpu-lazy/./sys/arch/sh3/sh3/core_machdep.c
--- src.orig/./sys/arch/sh3/sh3/core_machdep.c	2009-11-22 18:47:52.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/sh3/core_machdep.c	2009-12-22 15:48:36.000000000 +0900
@@ -101,6 +101,7 @@
 
 #include <sh3/locore.h>
 #include <sh3/cpu.h>
+#include <sh3/fpu.h>
 #include <sh3/reg.h>
 #include <sh3/mmu.h>
 #include <sh3/cache.h>
@@ -111,6 +112,7 @@
  */
 struct md_core {
 	struct reg intreg;
+	struct fpreg fpreg;
 };
 
 int
@@ -134,6 +136,13 @@
 	if (error)
 		return error;
 
+	/* Save floating point registers. */
+	if (CPU_HAS_FPU) {
+		error = process_read_fpregs(l, &md_core.fpreg);
+		if (error)
+			return error;
+	}
+
 	CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
 	cseg.c_addr = 0;
 	cseg.c_size = chdr->c_cpusize;
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/db_interface.c src-sh4-fpu-lazy/./sys/arch/sh3/sh3/db_interface.c
--- src.orig/./sys/arch/sh3/sh3/db_interface.c	2009-11-22 18:47:53.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/sh3/db_interface.c	2009-12-21 15:46:15.000000000 +0900
@@ -584,6 +584,8 @@
 	SF(sr);
 	SF(pr);
 	SF(gbr);
+	SF(macl);
+	SF(mach);
 	SF(r8);
 	SF(r9);
 	SF(r10);
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/exception.c src-sh4-fpu-lazy/./sys/arch/sh3/sh3/exception.c
--- src.orig/./sys/arch/sh3/sh3/exception.c	2009-11-22 18:47:53.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/sh3/exception.c	2009-12-22 15:50:57.000000000 +0900
@@ -100,6 +100,7 @@
 #include <uvm/uvm_extern.h>
 
 #include <sh3/cpu.h>
+#include <sh3/fpu.h>
 #include <sh3/mmu.h>
 #include <sh3/exception.h>
 #include <sh3/userret.h>
@@ -121,6 +122,20 @@
 	"illegal slot instruction exception",	/* 0x1a0 EXPEVT_SLOT_INST */
 	"--",					/* 0x1c0 (external interrupt) */
 	"user break point trap",		/* 0x1e0 EXPEVT_BREAK */
+	NULL, NULL, NULL, NULL,			/* 200-260 */
+	NULL, NULL, NULL, NULL,			/* 280-2e0 */
+	NULL, NULL, NULL, NULL,			/* 300-360 */
+	NULL, NULL, NULL, NULL,			/* 380-3e0 */
+	NULL, NULL, NULL, NULL,			/* 400-460 */
+	NULL, NULL, NULL, NULL,			/* 480-4e0 */
+	NULL, NULL, NULL, NULL,			/* 500-560 */
+	NULL, NULL, NULL, NULL,			/* 580-5e0 */
+	NULL, NULL, NULL, NULL,			/* 600-660 */
+	NULL, NULL, NULL, NULL,			/* 680-6e0 */
+	NULL, NULL, NULL, NULL,			/* 700-760 */
+	NULL, NULL, NULL, NULL,			/* 780-7e0 */
+	"FPU disabled",				/* 800 EXPEVT_FPU_DISABLE */
+	"slot FPU disabled"			/* 820 EXPEVT_FPU_SLOT_DISABLE*/
 };
 const int exp_types = __arraycount(exp_type);
 
@@ -218,6 +233,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-lazy/./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-lazy/./sys/arch/sh3/sh3/fpu.c	2009-12-22 15:41:27.000000000 +0900
@@ -0,0 +1,59 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sh3/fpu.h>
+
+void (*__sh_fpu_enable)(void);
+void (*__sh_fpu_save_lwp)(struct lwp *, bool);
+int (*__sh_fpu_exception)(struct lwp *, struct trapframe *, struct ksiginfo *);
+
+void
+sh_fpu_init(void)
+{
+
+	/*
+	 * Assign function hooks but only if both SH3 and SH4 are defined.
+	 * They are called directly otherwise.  See <sh3/fpu.h>.
+	 */
+	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");
+}
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/fpu_sh3.c src-sh4-fpu-lazy/./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-lazy/./sys/arch/sh3/sh3/fpu_sh3.c	2009-12-20 18:25:22.000000000 +0900
@@ -0,0 +1,68 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/siginfo.h>
+
+#include <sh3/frame.h>
+#include <sh3/fpu.h>
+
+/*
+ * 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-lazy/./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-lazy/./sys/arch/sh3/sh3/fpu_sh4.c	2009-12-22 18:26:55.000000000 +0900
@@ -0,0 +1,323 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
+ * 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
+#include <sh3/fpu.h>
+#include <sh3/reg.h>
+
+#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(struct fpreg *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_fr[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(struct fpreg *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_fr[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;
+
+	ci = curcpu();
+	l = ci->ci_fpulwp;
+
+	DPRINTF(("%s: start: lwp=%p, proc=%s\n", __func__, l,
+	    l ? (l->l_proc->p_comm ? l->l_proc->p_comm : "") : ""));
+
+	if (l == NULL) {
+		DPRINTF(("%s: ci->ci_fpulwp is NULL\n", __func__));
+		goto out;
+	}
+
+	if (save)
+		sh4_fpu_save_regs(&l->l_md.md_pcb->pcb_fpu);
+
+	ci->ci_fpulwp->l_md.md_regs->tf_ssr |= PSL_FDBIT;
+	ci->ci_fpulwp = NULL;
+	l->l_md.md_pcb->pcb_fpcpu = NULL;
+out:
+	DPRINTF(("%s: end: lwp=%p\n", __func__, l));
+}
+
+void
+sh4_fpu_enable(void)
+{
+	struct cpu_info *ci;
+	struct lwp *l;
+	int s;
+
+	s = _cpu_intr_suspend();
+
+	ci = curcpu();
+	l = curlwp;
+
+	DPRINTF(("%s: start: lwp=%p, proc=%s\n", __func__, l,
+	    l->l_proc->p_comm ? l->l_proc->p_comm: ""));
+
+	if (!(l->l_md.md_flags & MDL_USEDFPU)) {
+		DPRINTF(("%s: !MDL_USEDFPU\n", __func__));
+		memset(&l->l_md.md_pcb->pcb_fpu, 0,
+		    sizeof(l->l_md.md_pcb->pcb_fpu));
+		l->l_md.md_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;
+	else if (ci->ci_fpulwp != NULL)
+		sh4_fpu_save_cpu(true);
+	sh4_fpu_load_regs(&l->l_md.md_pcb->pcb_fpu);
+
+	l->l_md.md_pcb->pcb_fpcpu = ci;
+	ci->ci_fpulwp = l;
+out:
+	l->l_md.md_regs->tf_ssr &= ~PSL_FDBIT;
+
+	DPRINTF(("%s: end: lwp=%p\n", __func__, l));
+
+	_cpu_intr_resume(s);
+}
+
+void
+sh4_fpu_save_lwp(struct lwp *l, bool save)
+{
+	int s;
+
+	s = _cpu_intr_suspend();
+
+	DPRINTF(("%s: start: lwp=%p, proc=%s\n", __func__, l,
+	    l->l_proc->p_comm ? l->l_proc->p_comm: ""));
+
+	if (l->l_md.md_pcb->pcb_fpcpu != NULL) {
+		DPRINTF(("%s: do sh4_fpu_save_cpu(%d)\n", __func__, save));
+		sh4_fpu_save_cpu(save);
+	}
+
+	if (!save) {
+		/* Ensure we restart with a clean slate. */
+		l->l_md.md_flags &= ~MDL_USEDFPU;
+		DPRINTF(("%s: do clean\n", __func__));
+	}
+
+	DPRINTF(("%s: end: lwp=%p\n", __func__, l));
+
+	_cpu_intr_resume(s);
+}
+
+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 sr;
+	int fpscr;
+	int cause;
+	int i;
+
+	sr = get_sr();
+	set_sr(sr & ~PSL_FDBIT);
+	fpscr = get_fpscr();
+	set_sr(sr);
+
+	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;
+	}
+
+	DPRINTF(("%s: ksi_code = %d\n", __func__, ksi->ksi_code));
+
+	return 0;	/* trapsignal */
+}
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/locore_subr.S src-sh4-fpu-lazy/./sys/arch/sh3/sh3/locore_subr.S
--- src.orig/./sys/arch/sh3/sh3/locore_subr.S	2009-06-10 17:23:12.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/sh3/locore_subr.S	2009-12-21 15:32:34.000000000 +0900
@@ -66,6 +66,8 @@
 	mov.l	r10, @-pcb				; \
 	mov.l	r9, @-pcb				; \
 	mov.l	r8, @-pcb				; \
+	sts.l	mach, @-pcb				; \
+	sts.l	macl, @-pcb				; \
 	sts.l	pr, @-pcb				; \
 	stc.l	sr, @-pcb				; \
 	jump						; \
@@ -145,6 +147,8 @@
 	ldc.l	@r1+, gbr
 	ldc.l	@r1+, sr
 	lds.l	@r1+, pr
+	lds.l	@r1+, macl
+	lds.l	@r1+, mach
 	mov.l	@r1+, r8
 	mov.l	@r1+, r9
 	mov.l	@r1+, r10
@@ -792,18 +796,20 @@
 	 mov	#-1,	r0
 	mov.l	.L_fuswintr_curpcb, r1	/* set fault handler */
 	mov.l	@r1,	r2
+	add	#SF_SIZE, r2
 	mov.l	.L_fuswintr_onfault, r1
-	mov.l	r1,	@(PCB_ONFAULT,r2)
+	mov.l	r1,	@(PCB_ONFAULT - SF_SIZE, r2)
 	mov	#1,	r1		/* set faultbail */
-	mov.l	r1,	@(PCB_FAULTBAIL,r2)
+	mov.l	r1,	@(PCB_FAULTBAIL - SF_SIZE,r2)
 	mov.w	@r4,	r1		/* fetch the value */
 	extu.w	r1,	r0
 1:
 	mov.l	.L_fuswintr_curpcb, r1	/* clear fault handler and faultbail */
 	mov.l	@r1,	r2
+	add	#SF_SIZE, r2
 	mov	#0,	r1
-	mov.l	r1,	@(PCB_ONFAULT,r2)
-	mov.l	r1,	@(PCB_FAULTBAIL,r2)
+	mov.l	r1,	@(PCB_ONFAULT - SF_SIZE, r2)
+	mov.l	r1,	@(PCB_FAULTBAIL - SF_SIZE, r2)
 2:
 	rts
 	 nop
@@ -948,18 +954,20 @@
 	 mov	#-1,	r0
 	mov.l	.L_suswintr_curpcb, r1	/* set fault handler */
 	mov.l	@r1,	r2
+	add	#SF_SIZE, r2
 	mov.l	.L_suswintr_onfault, r1
-	mov.l	r1,	@(PCB_ONFAULT,r2)
+	mov.l	r1,	@(PCB_ONFAULT - SF_SIZE, r2)
 	mov	#1,	r1		/* set faultbail */
-	mov.l	r1,	@(PCB_FAULTBAIL,r2)
+	mov.l	r1,	@(PCB_FAULTBAIL - SF_SIZE, r2)
 	mov.w	r5,	@r4		/* store the value */
 	mov	#0,	r0
 1:
 	mov.l	.L_suswintr_curpcb, r1	/* clear fault handler and faultbail */
 	mov.l	@r1,	r2
+	add	#SF_SIZE, r2
 	mov	#0,	r1
-	mov.l	r1,	@(PCB_ONFAULT,r2)
-	mov.l	r1,	@(PCB_FAULTBAIL,r2)
+	mov.l	r1,	@(PCB_ONFAULT - SF_SIZE, r2)
+	mov.l	r1,	@(PCB_FAULTBAIL - SF_SIZE, r2)
 2:
 	rts
 	 nop
diff --exclude=CVS --exclude=obj.landisk --exclude=compile --exclude='makeBuild*.log' -uNr src.orig/./sys/arch/sh3/sh3/process_machdep.c src-sh4-fpu-lazy/./sys/arch/sh3/sh3/process_machdep.c
--- src.orig/./sys/arch/sh3/sh3/process_machdep.c	2009-11-22 18:47:53.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/sh3/process_machdep.c	2009-12-22 16:48:12.000000000 +0900
@@ -87,6 +87,7 @@
 #include <sys/vnode.h>
 #include <sys/ptrace.h>
 
+#include <sh3/fpu.h>
 #include <machine/psl.h>
 #include <machine/reg.h>
 
@@ -141,6 +142,27 @@
 	return (0);
 }
 
+int
+process_read_fpregs(struct lwp *l, struct fpreg *fpregs)
+{
+
+	if (CPU_HAS_FPU) {
+		struct pcb *pcb = l->l_md.md_pcb;
+		if ((l->l_md.md_flags & MDL_USEDFPU)) {
+			sh_fpu_save_lwp(l, true);
+		} else {
+			memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu));
+			pcb->pcb_fpu.fpr_fpscr = SH4_FPSCR_INIT;
+			l->l_md.md_flags |= MDL_USEDFPU;
+		}
+		*fpregs = pcb->pcb_fpu;
+	} else {
+		memset(fpregs, 0, sizeof(struct fpreg));
+	}
+
+	return (0);
+}
+
 #endif /* PTRACE || COREDUMP */
 
 
@@ -185,6 +207,21 @@
 	return (0);
 }
 
+int
+process_write_fpregs(struct lwp *l, const struct fpreg *fpregs)
+{
+
+	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;
+		}
+		l->l_md.md_pcb->pcb_fpu = *fpregs;
+	}
+
+	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-lazy/./sys/arch/sh3/sh3/sh3_machdep.c
--- src.orig/./sys/arch/sh3/sh3/sh3_machdep.c	2009-12-12 08:41:49.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/sh3/sh3_machdep.c	2009-12-22 18:16:37.000000000 +0900
@@ -100,6 +100,7 @@
 #include <sh3/cache.h>
 #include <sh3/clock.h>
 #include <sh3/exception.h>
+#include <sh3/fpu.h>
 #include <sh3/locore.h>
 #include <sh3/mmu.h>
 #include <sh3/intr.h>
@@ -157,6 +158,11 @@
 	/* MMU access ops. */
 	sh_mmu_init();
 
+#if defined(SH3) && defined(SH4)
+	/* FPU access ops. */
+	sh_fpu_init();
+#endif
+
 	/* Hardclock, RTC initialize. */
 	machine_clock_init();
 
@@ -212,7 +218,7 @@
 
 	/*
 	 * u-area map:
-	 * |pcb| .... | .................. |
+	 * | pcb | ... | .................. |
 	 * | PAGE_SIZE | USPACE - PAGE_SIZE |
          *        frame bot        stack bot
 	 * current frame ... r6_bank
@@ -412,6 +418,7 @@
 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_md.md_pcb;
 	__greg_t *gr = mcp->__gregs;
 	__greg_t ras_pc;
 
@@ -445,14 +452,24 @@
 
 	*flags |= _UC_CPU;
 
-	/* FPU context is currently not handled by the kernel. */
-	memset(&mcp->__fpregs, 0, sizeof (mcp->__fpregs));
+	if (CPU_HAS_FPU && (l->l_md.md_flags & MDL_USEDFPU) != 0) {
+		/*
+		 * 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);
+		mcp->__fpregs.fpr = pcb->pcb_fpu;
+		*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_md.md_pcb;
 	const __greg_t *gr = mcp->__gregs;
 	struct proc *p = l->l_proc;
 
@@ -486,12 +503,16 @@
 		tf->tf_r15    = gr[_REG_R15];
 	}
 
-#if 0
-	/* XXX: FPU context is currently not handled by the kernel. */
-	if (flags & _UC_FPU) {
-		/* TODO */;
+	/* Restore floating point register context, if any. */
+	if (CPU_HAS_FPU && (flags & _UC_FPU) != 0) {
+		/*
+		 * If we were using the FPU, forget that we were.
+		 */
+		if (pcb->pcb_fpcpu)
+			sh_fpu_save_lwp(l, false);
+		l->l_md.md_flags |= MDL_USEDFPU;
+		pcb->pcb_fpu = mcp->__fpregs.fpr;
 	}
-#endif
 
 	mutex_enter(p->p_lock);
 	if (flags & _UC_SETSTACK)
@@ -511,11 +532,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-lazy/./sys/arch/sh3/sh3/vm_machdep.c
--- src.orig/./sys/arch/sh3/sh3/vm_machdep.c	2009-12-10 23:06:32.000000000 +0900
+++ src-sh4-fpu-lazy/./sys/arch/sh3/sh3/vm_machdep.c	2009-12-22 18:18:13.000000000 +0900
@@ -101,6 +101,7 @@
 
 #include <sh3/locore.h>
 #include <sh3/cpu.h>
+#include <sh3/fpu.h>
 #include <sh3/reg.h>
 #include <sh3/mmu.h>
 #include <sh3/cache.h>
@@ -140,6 +141,17 @@
 	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 (CPU_HAS_FPU && l1->l_md.md_pcb->pcb_fpcpu != NULL)
+		sh_fpu_save_lwp(l1, true);
+
 	sh3_setup_uarea(l2);
 
 	l2->l_md.md_flags = l1->l_md.md_flags;
@@ -150,6 +162,10 @@
 	if (stack != NULL)
 		l2->l_md.md_regs->tf_r15 = (u_int)stack + stacksize;
 
+	/* Copy FPU context */
+	if (CPU_HAS_FPU)
+		l2->l_md.md_pcb->pcb_fpu = l1->l_md.md_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;
@@ -171,6 +187,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;
@@ -191,6 +209,7 @@
 	pcb = lwp_getpcb(l);
 	pcb->pcb_onfault = NULL;
 	pcb->pcb_faultbail = 0;
+	pcb->pcb_fpcpu = NULL;
 #ifdef SH3
 	/*
 	 * Accessing context store space must not cause exceptions.
@@ -291,18 +310,22 @@
 
 
 /*
- * 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 (CPU_HAS_FPU && l->l_md.md_pcb->pcb_fpcpu != NULL)
+		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)
