svn commit: r308130 - in head: . gnu/lib/libgcc gnu/usr.bin/binutils gnu/usr.bin/binutils/ld gnu/usr.bin/binutils/libbfd gnu/usr.bin/cc gnu/usr.bin/gdb gnu/usr.bin/gdb/libgdb lib/libc lib/libc/mips...

Ruslan Bukin br at FreeBSD.org
Mon Oct 31 15:34:02 UTC 2016


Author: br
Date: Mon Oct 31 15:33:58 2016
New Revision: 308130
URL: https://svnweb.freebsd.org/changeset/base/308130

Log:
  Add full softfloat and hardfloat support for MIPS.
  
  This adds new target architectures for hardfloat:
  mipselhf mipshf mips64elhf mips64hf.
  
  Tested in QEMU only.
  
  Sponsored by:	DARPA, AFRL
  Sponsored by:	HEIF5
  Differential Revision:	https://reviews.freebsd.org/D8376

Modified:
  head/Makefile
  head/Makefile.inc1
  head/gnu/lib/libgcc/Makefile
  head/gnu/usr.bin/binutils/Makefile.inc0
  head/gnu/usr.bin/binutils/ld/Makefile.mips
  head/gnu/usr.bin/binutils/libbfd/Makefile.mips
  head/gnu/usr.bin/cc/Makefile.inc
  head/gnu/usr.bin/cc/Makefile.tgt
  head/gnu/usr.bin/gdb/Makefile.inc
  head/gnu/usr.bin/gdb/libgdb/Makefile
  head/lib/libc/Makefile
  head/lib/libc/mips/Makefile.inc
  head/lib/libc/mips/Symbol.map
  head/lib/libc/mips/gen/Makefile.inc
  head/lib/libc/mips/gen/flt_rounds.c
  head/lib/msun/mips/Makefile.inc
  head/lib/msun/mips/Symbol.map
  head/lib/msun/mips/fenv.c
  head/lib/msun/mips/fenv.h
  head/share/man/man7/arch.7
  head/share/mk/bsd.cpu.mk
  head/share/mk/bsd.endian.mk
  head/share/mk/sys.mk
  head/sys/boot/Makefile.ficl
  head/sys/boot/common/Makefile.inc
  head/sys/boot/mips/uboot/Makefile
  head/sys/conf/kern.mk
  head/sys/mips/include/float.h
  head/sys/mips/mips/exception.S
  head/sys/mips/mips/locore.S
  head/sys/mips/mips/swtch.S
  head/sys/mips/mips/trap.c

Modified: head/Makefile
==============================================================================
--- head/Makefile	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/Makefile	Mon Oct 31 15:33:58 2016	(r308130)
@@ -239,7 +239,7 @@ _MAKE+=	MK_META_MODE=no
 _TARGET_ARCH=	${TARGET:S/pc98/i386/:S/arm64/aarch64/}
 .elif !defined(TARGET) && defined(TARGET_ARCH) && \
     ${TARGET_ARCH} != ${MACHINE_ARCH}
-_TARGET=		${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/powerpcspe/powerpc/:C/riscv64/riscv/}
+_TARGET=		${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/powerpcspe/powerpc/:C/riscv64/riscv/}
 .endif
 .if defined(TARGET) && !defined(_TARGET)
 _TARGET=${TARGET}
@@ -421,7 +421,7 @@ TARGETS?=amd64 arm arm64 i386 mips pc98 
 _UNIVERSE_TARGETS=	${TARGETS}
 TARGET_ARCHES_arm?=	arm armeb armv6
 TARGET_ARCHES_arm64?=	aarch64
-TARGET_ARCHES_mips?=	mipsel mips mips64el mips64 mipsn32
+TARGET_ARCHES_mips?=	mipsel mips mips64el mips64 mipsn32 mipselhf mipshf mips64elhf mips64hf
 TARGET_ARCHES_powerpc?=	powerpc powerpc64 powerpcspe
 TARGET_ARCHES_pc98?=	i386
 .for target in ${TARGETS}

Modified: head/Makefile.inc1
==============================================================================
--- head/Makefile.inc1	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/Makefile.inc1	Mon Oct 31 15:33:58 2016	(r308130)
@@ -356,6 +356,10 @@ KNOWN_ARCHES?=	aarch64/arm64 \
 		mipsn32el/mips \
 		mips64/mips \
 		mipsn32/mips \
+		mipshf/mips \
+		mipselhf/mips \
+		mips64elhf/mips \
+		mips64hf/mips \
 		powerpc \
 		powerpc64/powerpc \
 		powerpcspe/powerpc \

Modified: head/gnu/lib/libgcc/Makefile
==============================================================================
--- head/gnu/lib/libgcc/Makefile	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/gnu/lib/libgcc/Makefile	Mon Oct 31 15:33:58 2016	(r308130)
@@ -165,7 +165,7 @@ LIBADD+=	compiler_rt
 .if ${TARGET_CPUARCH} == mips
 LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c
 # ABIs other than o32 need this
-.if ${TARGET_ARCH} != "mips" && ${TARGET_ARCH} != "mipsel"
+.if ${TARGET_ARCH:Mmips64*} != "" || ${TARGET_ARCH:Mmipsn32*} != ""
 LIB2FUNCS_EXTRA+= floatdidf.c fixunsdfsi.c
 LIB2FUNCS_EXTRA+= floatdisf.c floatundidf.c
 LIB2FUNCS_EXTRA+= fixsfdi.c floatundisf.c

Modified: head/gnu/usr.bin/binutils/Makefile.inc0
==============================================================================
--- head/gnu/usr.bin/binutils/Makefile.inc0	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/gnu/usr.bin/binutils/Makefile.inc0	Mon Oct 31 15:33:58 2016	(r308130)
@@ -7,7 +7,7 @@
 VERSION=	"2.17.50 [FreeBSD] 2007-07-03"
 
 .if defined(TARGET_ARCH)
-TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
+TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
 .else
 TARGET_CPUARCH=${MACHINE_CPUARCH}
 .endif
@@ -17,7 +17,7 @@ TARGET_OS?=	freebsd
 BINUTILS_ARCH=${TARGET_ARCH:C/amd64/x86_64/}
 TARGET_TUPLE?=	${BINUTILS_ARCH}-${TARGET_VENDOR}-${TARGET_OS}
 .if ${TARGET_ARCH} == "armeb" || ${TARGET_ARCH} == "armv6eb" || \
-	(${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el} == "")
+	(${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el*} == "")
 TARGET_BIG_ENDIAN=t
 .endif
 

Modified: head/gnu/usr.bin/binutils/ld/Makefile.mips
==============================================================================
--- head/gnu/usr.bin/binutils/ld/Makefile.mips	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/gnu/usr.bin/binutils/ld/Makefile.mips	Mon Oct 31 15:33:58 2016	(r308130)
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.if ${TARGET_ARCH:Mmips*el} != ""
+.if ${TARGET_ARCH:Mmips*el*} != ""
 _EMULATION_ENDIAN=l
 .else
 _EMULATION_ENDIAN=b

Modified: head/gnu/usr.bin/binutils/libbfd/Makefile.mips
==============================================================================
--- head/gnu/usr.bin/binutils/libbfd/Makefile.mips	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/gnu/usr.bin/binutils/libbfd/Makefile.mips	Mon Oct 31 15:33:58 2016	(r308130)
@@ -1,6 +1,6 @@
 # $FreeBSD$
 
-.if ${TARGET_ARCH:Mmips*el} != ""
+.if ${TARGET_ARCH:Mmips*el*} != ""
 _EMULATION_ENDIAN=little
 .else
 _EMULATION_ENDIAN=big

Modified: head/gnu/usr.bin/cc/Makefile.inc
==============================================================================
--- head/gnu/usr.bin/cc/Makefile.inc	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/gnu/usr.bin/cc/Makefile.inc	Mon Oct 31 15:33:58 2016	(r308130)
@@ -39,7 +39,7 @@ CFLAGS += -DFREEBSD_ARCH_armv6
 .endif
 
 .if ${TARGET_CPUARCH} == "mips"
-.if ${TARGET_ARCH:Mmips*el} != ""
+.if ${TARGET_ARCH:Mmips*el*} != ""
 CFLAGS += -DTARGET_ENDIAN_DEFAULT=0
 .endif
 

Modified: head/gnu/usr.bin/cc/Makefile.tgt
==============================================================================
--- head/gnu/usr.bin/cc/Makefile.tgt	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/gnu/usr.bin/cc/Makefile.tgt	Mon Oct 31 15:33:58 2016	(r308130)
@@ -4,7 +4,7 @@
 # MACHINE_CPUARCH, but there's no easy way to export make functions...
 
 .if defined(TARGET_ARCH)
-TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
+TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
 .else
 TARGET_CPUARCH=${MACHINE_CPUARCH}
 .endif
@@ -15,7 +15,7 @@ GCC_CPU=${TARGET_CPUARCH:C/amd64/i386/:C
 TARGET_CPU_DEFAULT= TARGET_CPU_ultrasparc
 .endif
 .if ${TARGET_ARCH} == "armeb" || ${TARGET_ARCH} == "armv6eb" || \
-	(${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el} == "")
+	(${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el*} == "")
 TARGET_BIG_ENDIAN=t
 .endif
 .if ${TARGET_ARCH} == "powerpc64"

Modified: head/gnu/usr.bin/gdb/Makefile.inc
==============================================================================
--- head/gnu/usr.bin/gdb/Makefile.inc	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/gnu/usr.bin/gdb/Makefile.inc	Mon Oct 31 15:33:58 2016	(r308130)
@@ -23,7 +23,7 @@ OBJ_RL= ${OBJ_ROOT}/../lib/libreadline/r
 # MACHINE_CPUARCH, but there's no easy way to export make functions...
 
 .if defined(TARGET_ARCH)
-TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
+TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
 .else
 TARGET_CPUARCH=${MACHINE_CPUARCH}
 .endif

Modified: head/gnu/usr.bin/gdb/libgdb/Makefile
==============================================================================
--- head/gnu/usr.bin/gdb/libgdb/Makefile	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/gnu/usr.bin/gdb/libgdb/Makefile	Mon Oct 31 15:33:58 2016	(r308130)
@@ -4,7 +4,7 @@
 # MACHINE_CPUARCH, but there's no easy way to export make functions...
 
 .if defined(TARGET_ARCH)
-TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
+TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
 .else
 TARGET_CPUARCH=${MACHINE_CPUARCH}
 .endif

Modified: head/lib/libc/Makefile
==============================================================================
--- head/lib/libc/Makefile	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/libc/Makefile	Mon Oct 31 15:33:58 2016	(r308130)
@@ -111,7 +111,7 @@ NOASM=
 .include "${LIBC_SRCTOP}/xdr/Makefile.inc"
 .if (${LIBC_ARCH} == "arm" && \
 	(${MACHINE_ARCH:Marmv6*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \
-     ${LIBC_ARCH} == "mips"
+     (${LIBC_ARCH} == "mips" && ${MACHINE_ARCH:Mmips*hf} == "")
 .include "${LIBC_SRCTOP}/softfloat/Makefile.inc"
 .endif
 .if ${LIBC_ARCH} == "i386" || ${LIBC_ARCH} == "amd64"

Modified: head/lib/libc/mips/Makefile.inc
==============================================================================
--- head/lib/libc/mips/Makefile.inc	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/libc/mips/Makefile.inc	Mon Oct 31 15:33:58 2016	(r308130)
@@ -1,7 +1,9 @@
 #	$NetBSD: Makefile.inc,v 1.7 2005/09/17 11:49:39 tsutsui Exp $
 # $FreeBSD$
 
+.if ${MACHINE_ARCH:Mmips*hf} == ""
 CFLAGS+=-DSOFTFLOAT
+.endif
 
 MDSRCS+= machdep_ldisd.c
 SYM_MAPS+= ${LIBC_SRCTOP}/mips/Symbol.map

Modified: head/lib/libc/mips/Symbol.map
==============================================================================
--- head/lib/libc/mips/Symbol.map	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/libc/mips/Symbol.map	Mon Oct 31 15:33:58 2016	(r308130)
@@ -31,6 +31,10 @@ FBSD_1.0 {
 	sbrk;
 };
 
+FBSD_1.3 {
+	__flt_rounds;
+};
+
 FBSDprivate_1.0 {
 	/* PSEUDO syscalls */
 	__sys_getlogin;

Modified: head/lib/libc/mips/gen/Makefile.inc
==============================================================================
--- head/lib/libc/mips/gen/Makefile.inc	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/libc/mips/gen/Makefile.inc	Mon Oct 31 15:33:58 2016	(r308130)
@@ -1,7 +1,7 @@
 #	$NetBSD: Makefile.inc,v 1.27 2005/10/07 17:16:40 tsutsui Exp $
 # $FreeBSD$
 
-SRCS+=	infinity.c fabs.c ldexp.c
+SRCS+=	infinity.c fabs.c ldexp.c flt_rounds.c
 
 # SRCS+=	flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
 #	fpsetround.c fpsetsticky.c

Modified: head/lib/libc/mips/gen/flt_rounds.c
==============================================================================
--- head/lib/libc/mips/gen/flt_rounds.c	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/libc/mips/gen/flt_rounds.c	Mon Oct 31 15:33:58 2016	(r308130)
@@ -11,7 +11,14 @@ __FBSDID("$FreeBSD$");
 __RCSID("$NetBSD: flt_rounds.c,v 1.5 2005/12/24 23:10:08 perry Exp $");
 #endif /* LIBC_SCCS and not lint */
 
-#include <machine/float.h>
+#include <fenv.h>
+#include <float.h>
+
+#ifdef	SOFTFLOAT
+#include "softfloat-for-gcc.h"
+#include "milieu.h"
+#include "softfloat.h"
+#endif
 
 static const int map[] = {
 	1,	/* round to nearest */
@@ -23,8 +30,13 @@ static const int map[] = {
 int
 __flt_rounds()
 {
-	int x;
+	int mode;
+
+#ifdef SOFTFLOAT
+	mode = __softfloat_float_rounding_mode;
+#else
+	__asm __volatile("cfc1 %0,$31" : "=r" (mode));
+#endif
 
-	__asm("cfc1 %0,$31" : "=r" (x));
-	return map[x & 0x03];
+	return map[mode & 0x03];
 }

Modified: head/lib/msun/mips/Makefile.inc
==============================================================================
--- head/lib/msun/mips/Makefile.inc	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/msun/mips/Makefile.inc	Mon Oct 31 15:33:58 2016	(r308130)
@@ -1,4 +1,8 @@
 # $FreeBSD$
 
+.if ${MACHINE_ARCH:Mmips*hf} == ""
+CFLAGS+=-DSOFTFLOAT
+.endif
+
 LDBL_PREC = 53
 SYM_MAPS += ${.CURDIR}/mips/Symbol.map

Modified: head/lib/msun/mips/Symbol.map
==============================================================================
--- head/lib/msun/mips/Symbol.map	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/msun/mips/Symbol.map	Mon Oct 31 15:33:58 2016	(r308130)
@@ -5,9 +5,17 @@ FBSD_1.0 {
 };
 
 FBSD_1.3 {
+	feclearexcept;
+	fegetexceptflag;
 	fesetexceptflag;
 	feraiseexcept;
+	fetestexcept;
+	fegetround;
+	fesetround;
 	fegetenv;
 	feholdexcept;
 	feupdateenv;
+	feenableexcept;
+	fedisableexcept;
+	fegetexcept;
 };

Modified: head/lib/msun/mips/fenv.c
==============================================================================
--- head/lib/msun/mips/fenv.c	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/msun/mips/fenv.c	Mon Oct 31 15:33:58 2016	(r308130)
@@ -39,6 +39,17 @@
  */
 const fenv_t __fe_dfl_env = 0;
 
+#ifdef	SOFTFLOAT
+#define __set_env(env, flags, mask, rnd) env = ((flags)                 \
+                                                | (mask)<<_FPUSW_SHIFT  \
+                                                | (rnd) << 24)
+#define __env_flags(env)                ((env) & FE_ALL_EXCEPT)
+#define __env_mask(env)                 (((env) >> _FPUSW_SHIFT)        \
+                                                & FE_ALL_EXCEPT)
+#define __env_round(env)                (((env) >> 24) & _ROUND_MASK)
+#include "fenv-softfloat.h"
+#endif
+
 extern inline int feclearexcept(int __excepts);
 extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts);
 extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
@@ -50,3 +61,6 @@ extern inline int fegetenv(fenv_t *__env
 extern inline int feholdexcept(fenv_t *__envp);
 extern inline int fesetenv(const fenv_t *__envp);
 extern inline int feupdateenv(const fenv_t *__envp);
+extern inline int feenableexcept(int __mask);
+extern inline int fedisableexcept(int __mask);
+extern inline int fegetexcept(void);

Modified: head/lib/msun/mips/fenv.h
==============================================================================
--- head/lib/msun/mips/fenv.h	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/lib/msun/mips/fenv.h	Mon Oct 31 15:33:58 2016	(r308130)
@@ -39,11 +39,21 @@ typedef	__uint32_t	fenv_t;
 typedef	__uint32_t	fexcept_t;
 
 /* Exception flags */
+#ifdef SOFTFLOAT
+#define	_FPUSW_SHIFT	16
 #define	FE_INVALID	0x0001
 #define	FE_DIVBYZERO	0x0002
 #define	FE_OVERFLOW	0x0004
 #define	FE_UNDERFLOW	0x0008
 #define	FE_INEXACT	0x0010
+#else
+#define	_FCSR_CAUSE_SHIFT	10
+#define	FE_INVALID	0x0040
+#define	FE_DIVBYZERO	0x0020
+#define	FE_OVERFLOW	0x0010
+#define	FE_UNDERFLOW	0x0008
+#define	FE_INEXACT	0x0004
+#endif
 #define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | \
 			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
 
@@ -61,104 +71,135 @@ extern const fenv_t	__fe_dfl_env;
 #define	FE_DFL_ENV	(&__fe_dfl_env)
 
 /* We need to be able to map status flag positions to mask flag positions */
-#define _FPUSW_SHIFT	16
-#define	_ENABLE_MASK	(FE_ALL_EXCEPT << _FPUSW_SHIFT)
+#define	_ENABLE_SHIFT	5
+#define	_ENABLE_MASK	(FE_ALL_EXCEPT << _ENABLE_SHIFT)
 
-#ifdef	ARM_HARD_FLOAT
-#define	__rfs(__fpsr)	__asm __volatile("rfs %0" : "=r" (*(__fpsr)))
-#define	__wfs(__fpsr)	__asm __volatile("wfs %0" : : "r" (__fpsr))
-#else
-#define __rfs(__fpsr)
-#define __wfs(__fpsr)
+#ifndef	SOFTFLOAT
+#define	__cfc1(__fcsr)	__asm __volatile("cfc1 %0, $31" : "=r" (__fcsr))
+#define	__ctc1(__fcsr)	__asm __volatile("ctc1 %0, $31" :: "r" (__fcsr))
 #endif
 
+#ifdef SOFTFLOAT
+int feclearexcept(int __excepts);
+int fegetexceptflag(fexcept_t *__flagp, int __excepts);
+int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
+int feraiseexcept(int __excepts);
+int fetestexcept(int __excepts);
+int fegetround(void);
+int fesetround(int __round);
+int fegetenv(fenv_t *__envp);
+int feholdexcept(fenv_t *__envp);
+int fesetenv(const fenv_t *__envp);
+int feupdateenv(const fenv_t *__envp);
+#else
 __fenv_static inline int
 feclearexcept(int __excepts)
 {
-	fexcept_t __fpsr;
+	fexcept_t fcsr;
+
+	__excepts &= FE_ALL_EXCEPT;
+	__cfc1(fcsr);
+	fcsr &= ~(__excepts | (__excepts << _FCSR_CAUSE_SHIFT));
+	__ctc1(fcsr);
 
-	__rfs(&__fpsr);
-	__fpsr &= ~__excepts;
-	__wfs(__fpsr);
 	return (0);
 }
 
 __fenv_static inline int
 fegetexceptflag(fexcept_t *__flagp, int __excepts)
 {
-	fexcept_t __fpsr;
+	fexcept_t fcsr;
+
+	__excepts &= FE_ALL_EXCEPT;
+	__cfc1(fcsr);
+	*__flagp = fcsr & __excepts;
 
-	__rfs(&__fpsr);
-	*__flagp = __fpsr & __excepts;
 	return (0);
 }
 
 __fenv_static inline int
 fesetexceptflag(const fexcept_t *__flagp, int __excepts)
 {
-	fexcept_t __fpsr;
+	fexcept_t fcsr;
+
+	__excepts &= FE_ALL_EXCEPT;
+	__cfc1(fcsr);
+	fcsr &= ~__excepts;
+	fcsr |= *__flagp & __excepts;
+	__ctc1(fcsr);
 
-	__rfs(&__fpsr);
-	__fpsr &= ~__excepts;
-	__fpsr |= *__flagp & __excepts;
-	__wfs(__fpsr);
 	return (0);
 }
 
 __fenv_static inline int
 feraiseexcept(int __excepts)
 {
-	fexcept_t __ex = __excepts;
+	fexcept_t fcsr;
+
+	__excepts &= FE_ALL_EXCEPT;
+	__cfc1(fcsr);
+	fcsr |= __excepts | (__excepts << _FCSR_CAUSE_SHIFT);
+	__ctc1(fcsr);
 
-	fesetexceptflag(&__ex, __excepts);	/* XXX */
 	return (0);
 }
 
 __fenv_static inline int
 fetestexcept(int __excepts)
 {
-	fexcept_t __fpsr;
+	fexcept_t fcsr;
 
-	__rfs(&__fpsr);
-	return (__fpsr & __excepts);
+	__excepts &= FE_ALL_EXCEPT;
+	__cfc1(fcsr);
+
+	return (fcsr & __excepts);
 }
 
 __fenv_static inline int
 fegetround(void)
 {
+	fexcept_t fcsr;
+
+	__cfc1(fcsr);
 
-	/*
-	 * Apparently, the rounding mode is specified as part of the
-	 * instruction format on ARM, so the dynamic rounding mode is
-	 * indeterminate.  Some FPUs may differ.
-	 */
-	return (-1);
+	return (fcsr & _ROUND_MASK);
 }
 
 __fenv_static inline int
 fesetround(int __round)
 {
+	fexcept_t fcsr;
+
+	if (__round & ~_ROUND_MASK)
+		return (-1);
 
-	return (-1);
+	__cfc1(fcsr);
+	fcsr &= ~_ROUND_MASK;
+	fcsr |= __round;
+	__ctc1(fcsr);
+
+	return (0);
 }
 
 __fenv_static inline int
 fegetenv(fenv_t *__envp)
 {
 
-	__rfs(__envp);
+	__cfc1(*__envp);
+
 	return (0);
 }
 
 __fenv_static inline int
 feholdexcept(fenv_t *__envp)
 {
-	fenv_t __env;
+	fexcept_t fcsr;
+
+	__cfc1(fcsr);
+	*__envp = fcsr;
+	fcsr &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
+	__ctc1(fcsr);
 
-	__rfs(&__env);
-	*__envp = __env;
-	__env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
-	__wfs(__env);
 	return (0);
 }
 
@@ -166,56 +207,69 @@ __fenv_static inline int
 fesetenv(const fenv_t *__envp)
 {
 
-	__wfs(*__envp);
+	__ctc1(*__envp);
+
 	return (0);
 }
 
 __fenv_static inline int
 feupdateenv(const fenv_t *__envp)
 {
-	fexcept_t __fpsr;
+	fexcept_t fcsr;
+
+	__cfc1(fcsr);
+	fesetenv(__envp);
+	feraiseexcept(fcsr);
 
-	__rfs(&__fpsr);
-	__wfs(*__envp);
-	feraiseexcept(__fpsr & FE_ALL_EXCEPT);
 	return (0);
 }
+#endif /* !SOFTFLOAT */
 
 #if __BSD_VISIBLE
 
 /* We currently provide no external definitions of the functions below. */
 
+#ifdef SOFTFLOAT
+int feenableexcept(int __mask);
+int fedisableexcept(int __mask);
+int fegetexcept(void);
+#else
 static inline int
 feenableexcept(int __mask)
 {
-	fenv_t __old_fpsr, __new_fpsr;
+	fenv_t __old_fcsr, __new_fcsr;
+
+	__cfc1(__old_fcsr);
+	__new_fcsr = __old_fcsr | (__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT;
+	__ctc1(__new_fcsr);
 
-	__rfs(&__old_fpsr);
-	__new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
-	__wfs(__new_fpsr);
-	return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+	return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT);
 }
 
 static inline int
 fedisableexcept(int __mask)
 {
-	fenv_t __old_fpsr, __new_fpsr;
+	fenv_t __old_fcsr, __new_fcsr;
+
+	__cfc1(__old_fcsr);
+	__new_fcsr = __old_fcsr & ~((__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT);
+	__ctc1(__new_fcsr);
 
-	__rfs(&__old_fpsr);
-	__new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
-	__wfs(__new_fpsr);
-	return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+	return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT);
 }
 
 static inline int
 fegetexcept(void)
 {
-	fenv_t __fpsr;
+	fexcept_t fcsr;
 
-	__rfs(&__fpsr);
-	return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
+	__cfc1(fcsr);
+
+	return ((fcsr & _ENABLE_MASK) >> _ENABLE_SHIFT);
 }
 
+#endif /* !SOFTFLOAT */
+
 #endif /* __BSD_VISIBLE */
 
 __END_DECLS

Modified: head/share/man/man7/arch.7
==============================================================================
--- head/share/man/man7/arch.7	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/share/man/man7/arch.7	Mon Oct 31 15:33:58 2016	(r308130)
@@ -57,9 +57,13 @@ On all supported architectures,
 .It i386        Ta 4 Ta 12
 .It mips        Ta 4 Ta  8
 .It mipsel      Ta 4 Ta  8
+.It mipselhf    Ta 4 Ta  8
+.It mipshf      Ta 4 Ta  8
 .It mipsn32     Ta 4 Ta  8
 .It mips64      Ta 8 Ta  8
 .It mips64el    Ta 8 Ta  8
+.It mips64elhf  Ta 8 Ta  8
+.It mips64hf    Ta 8 Ta  8
 .It powerpc     Ta 4 Ta  8
 .It powerpc64   Ta 8 Ta  8
 .It riscv       Ta 8 Ta
@@ -76,9 +80,13 @@ On all supported architectures,
 .It i386        Ta little Ta   signed
 .It mips        Ta big    Ta   signed
 .It mipsel      Ta little Ta   signed
+.It mipselhf    Ta little Ta   signed
+.It mipshf      Ta big    Ta   signed
 .It mipsn32     Ta big    Ta   signed
 .It mips64      Ta big    Ta   signed
 .It mips64el    Ta little Ta   signed
+.It mips64elhf  Ta little Ta   signed
+.It mips64hf    Ta big    Ta   signed
 .It powerpc     Ta big    Ta unsigned
 .It powerpc64   Ta big    Ta unsigned
 .It riscv       Ta little Ta   signed
@@ -95,9 +103,13 @@ On all supported architectures,
 .It i386        Ta 4K, 2M (PAE), 4M
 .It mips        Ta 4K
 .It mipsel      Ta 4K
+.It mipselhf    Ta 4K
+.It mipshf      Ta 4K
 .It mipsn32     Ta 4K
 .It mips64      Ta 4K
 .It mips64el    Ta 4K
+.It mips64elhf  Ta 4K
+.It mips64hf    Ta 4K
 .It powerpc     Ta 4K
 .It powerpc64   Ta 4K
 .It riscv       Ta 4K
@@ -114,9 +126,13 @@ On all supported architectures,
 .It i386        Ta hard Ta hard, 80 bit
 .It mips        Ta soft Ta identical to double
 .It mipsel      Ta soft Ta identical to double
-.It mipsn32     Ta soft Ta  identical to double
+.It mipselhf    Ta hard Ta identical to double
+.It mipshf      Ta hard Ta identical to double
+.It mipsn32     Ta soft Ta identical to double
 .It mips64      Ta soft Ta identical to double
 .It mips64el    Ta soft Ta identical to double
+.It mips64elhf  Ta hard Ta identical to double
+.It mips64hf    Ta hard Ta identical to double
 .It powerpc     Ta hard Ta hard, double precision
 .It powerpc64   Ta hard Ta hard, double precision
 .It riscv       Ta
@@ -155,9 +171,13 @@ Architecture-specific macros:
 .It i386        Ta Dv __i386__
 .It mips        Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32
 .It mipsel      Ta Dv __mips__, Dv __mips_o32
+.It mipselhf    Ta Dv __mips__, Dv __mips_o32
+.It mipshf      Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32
 .It mipsn32     Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n32
 .It mips64      Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64
 .It mips64el    Ta Dv __mips__, Dv __mips_n64
+.It mips64elhf  Ta Dv __mips__, Dv __mips_n64
+.It mips64hf    Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64
 .It powerpc     Ta Dv __powerpc__
 .It powerpc64   Ta Dv __powerpc__, Dv __powerpc64__
 .It riscv       Ta Dv __riscv__, Dv __riscv64

Modified: head/share/mk/bsd.cpu.mk
==============================================================================
--- head/share/mk/bsd.cpu.mk	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/share/mk/bsd.cpu.mk	Mon Oct 31 15:33:58 2016	(r308130)
@@ -303,6 +303,9 @@ MACHINE_CPU = v9 ultrasparc ultrasparc3
 
 .if ${MACHINE_CPUARCH} == "mips"
 CFLAGS += -G0
+.if ${TARGET_ARCH:Mmips*hf}
+CFLAGS += -mhard-float
+.endif
 .endif
 
 ########## arm

Modified: head/share/mk/bsd.endian.mk
==============================================================================
--- head/share/mk/bsd.endian.mk	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/share/mk/bsd.endian.mk	Mon Oct 31 15:33:58 2016	(r308130)
@@ -5,7 +5,7 @@
     ${MACHINE_ARCH} == "i386" || \
     (${MACHINE} == "arm" && ${MACHINE_ARCH:Marm*eb*} == "") || \
     ${MACHINE_CPUARCH} == "riscv" || \
-    ${MACHINE_ARCH:Mmips*el} != ""
+    ${MACHINE_ARCH:Mmips*el*} != ""
 TARGET_ENDIANNESS= 1234
 .elif ${MACHINE_ARCH} == "powerpc" || \
     ${MACHINE_ARCH} == "powerpc64" || \

Modified: head/share/mk/sys.mk
==============================================================================
--- head/share/mk/sys.mk	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/share/mk/sys.mk	Mon Oct 31 15:33:58 2016	(r308130)
@@ -13,7 +13,7 @@ unix		?=	We run FreeBSD, not UNIX.
 # and/or endian.  This is called MACHINE_CPU in NetBSD, but that's used
 # for something different in FreeBSD.
 #
-MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc(64|spe)/powerpc/:C/riscv64/riscv/}
+MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc(64|spe)/powerpc/:C/riscv64/riscv/}
 .endif
 
 

Modified: head/sys/boot/Makefile.ficl
==============================================================================
--- head/sys/boot/Makefile.ficl	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/boot/Makefile.ficl	Mon Oct 31 15:33:58 2016	(r308130)
@@ -6,7 +6,7 @@ FICLDIR?=	${SRCTOP}/sys/boot/ficl
 
 .if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32)
 FICL_CPUARCH=	i386
-.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
+.elif ${MACHINE_ARCH:Mmips64*} != ""
 FICL_CPUARCH=	mips64
 .else
 FICL_CPUARCH=	${MACHINE_CPUARCH}

Modified: head/sys/boot/common/Makefile.inc
==============================================================================
--- head/sys/boot/common/Makefile.inc	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/boot/common/Makefile.inc	Mon Oct 31 15:33:58 2016	(r308130)
@@ -18,7 +18,7 @@ SRCS+=	load_elf32.c reloc_elf32.c
 SRCS+=	load_elf64.c reloc_elf64.c
 .elif ${MACHINE_CPUARCH} == "sparc64"
 SRCS+=	load_elf64.c reloc_elf64.c
-.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
+.elif ${MACHINE_ARCH:Mmips64*} != ""
 SRCS+= load_elf64.c reloc_elf64.c
 .elif ${MACHINE} == "mips"
 SRCS+=	load_elf32.c reloc_elf32.c

Modified: head/sys/boot/mips/uboot/Makefile
==============================================================================
--- head/sys/boot/mips/uboot/Makefile	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/boot/mips/uboot/Makefile	Mon Oct 31 15:33:58 2016	(r308130)
@@ -85,7 +85,7 @@ LIBFDT=		${.OBJDIR}/../../fdt/libfdt.a
 # Enable BootForth
 BOOT_FORTH=	yes
 CFLAGS+=	-DBOOT_FORTH -I${.CURDIR}/../../ficl
-.if ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
+.if ${MACHINE_ARCH:Mmips64*} != ""
 CFLAGS+=	-I${.CURDIR}/../../ficl/mips64
 .else
 CFLAGS+=	-I${.CURDIR}/../../ficl/mips

Modified: head/sys/conf/kern.mk
==============================================================================
--- head/sys/conf/kern.mk	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/conf/kern.mk	Mon Oct 31 15:33:58 2016	(r308130)
@@ -184,6 +184,9 @@ CFLAGS.gcc+=	-mcall-aixdesc
 .if ${MACHINE_CPUARCH} == "mips"
 CFLAGS+=	-msoft-float
 INLINE_LIMIT?=	8000
+.if ${TARGET_ARCH:Mmips*hf} != ""
+CFLAGS+= -DCPU_HAVEFPU
+.endif
 .endif
 
 #

Modified: head/sys/mips/include/float.h
==============================================================================
--- head/sys/mips/include/float.h	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/mips/include/float.h	Mon Oct 31 15:33:58 2016	(r308130)
@@ -42,11 +42,7 @@ extern int __flt_rounds(void);
 __END_DECLS
 
 #define	FLT_RADIX	2		/* b */
-#ifdef CPU_HAVEFPU
 #define	FLT_ROUNDS	__flt_rounds() /* FP addition rounds to nearest */
-#else
-#define	FLT_ROUNDS	(-1)
-#endif
 
 #if __ISO_C_VISIBLE >= 1999
 #define	FLT_EVAL_METHOD	0

Modified: head/sys/mips/mips/exception.S
==============================================================================
--- head/sys/mips/mips/exception.S	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/mips/mips/exception.S	Mon Oct 31 15:33:58 2016	(r308130)
@@ -1098,11 +1098,17 @@ END(MipsTLBMissException)
 NESTED(MipsFPTrap, CALLFRAME_SIZ, ra)
 	PTR_SUBU	sp, sp, CALLFRAME_SIZ
 	mfc0	t0, MIPS_COP_0_STATUS
+	HAZARD_DELAY
 	REG_S	ra, CALLFRAME_RA(sp)
 	.mask	0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
 
+#if defined(__mips_n64)
+	or	t1, t0, MIPS_SR_COP_1_BIT | MIPS_SR_FR
+#else
 	or	t1, t0, MIPS_SR_COP_1_BIT
+#endif
 	mtc0	t1, MIPS_COP_0_STATUS
+	HAZARD_DELAY
 	ITLBNOPFIX
 	cfc1	t1, MIPS_FPU_CSR		# stall til FP done
 	cfc1	t1, MIPS_FPU_CSR		# now get status

Modified: head/sys/mips/mips/locore.S
==============================================================================
--- head/sys/mips/mips/locore.S	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/mips/mips/locore.S	Mon Oct 31 15:33:58 2016	(r308130)
@@ -118,7 +118,7 @@ VECTOR(_locore, unknown)
 	 */
 	li	t1, MIPS_SR_COP_1_BIT
 #ifdef __mips_n64
-	or	t1, MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX
+	or	t1, MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS_SR_FR
 #endif
 #endif
 	/*

Modified: head/sys/mips/mips/swtch.S
==============================================================================
--- head/sys/mips/mips/swtch.S	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/mips/mips/swtch.S	Mon Oct 31 15:33:58 2016	(r308130)
@@ -415,8 +415,14 @@ LEAF(MipsSwitchFPState)
 	.set push
 	.set hardfloat
 	mfc0	t1, MIPS_COP_0_STATUS	# Save old SR
-	li	t0, MIPS_SR_COP_1_BIT	# enable the coprocessor
+	HAZARD_DELAY
+#if defined(__mips_n64)
+	or	t0, t1, MIPS_SR_COP_1_BIT | MIPS_SR_FR	# enable the coprocessor
+#else
+	or	t0, t1, MIPS_SR_COP_1_BIT 		# enable the coprocessor
+#endif
 	mtc0	t0, MIPS_COP_0_STATUS
+	HAZARD_DELAY
 	ITLBNOPFIX
 
 	beq	a0, zero, 1f		# skip save if NULL pointer
@@ -540,8 +546,14 @@ LEAF(MipsSaveCurFPState)
 	.set hardfloat
 	PTR_L	a0, TD_PCB(a0)			# get pointer to pcb for thread
 	mfc0	t1, MIPS_COP_0_STATUS		# Disable interrupts and
-	li	t0, MIPS_SR_COP_1_BIT		#  enable the coprocessor
+	HAZARD_DELAY
+#if defined(__mips_n64)
+	or	t0, t1, MIPS_SR_COP_1_BIT | MIPS_SR_FR		#  enable the coprocessor
+#else
+	or	t0, t1, MIPS_SR_COP_1_BIT 			#  enable the coprocessor
+#endif
 	mtc0	t0, MIPS_COP_0_STATUS
+	HAZARD_DELAY
 	ITLBNOPFIX
 	GET_CPU_PCPU(a1)
 	PTR_S	zero, PC_FPCURTHREAD(a1)	# indicate state has been saved

Modified: head/sys/mips/mips/trap.c
==============================================================================
--- head/sys/mips/mips/trap.c	Mon Oct 31 15:11:55 2016	(r308129)
+++ head/sys/mips/mips/trap.c	Mon Oct 31 15:33:58 2016	(r308130)
@@ -590,7 +590,8 @@ trap(struct trapframe *trapframe)
 			break;
 		}
 		if ((last_badvaddr == this_badvaddr) &&
-		    ((type & ~T_USER) != T_SYSCALL)) {
+		    ((type & ~T_USER) != T_SYSCALL) &&
+		    ((type & ~T_USER) != T_COP_UNUSABLE)) {
 			if (++count == 3) {
 				trap_frame_dump(trapframe);
 				panic("too many faults at %p\n", (void *)last_badvaddr);
@@ -980,7 +981,11 @@ dofault:
 			addr = trapframe->pc;
 			MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
 			PCPU_SET(fpcurthread, td);
+#if defined(__mips_n64)
+			td->td_frame->sr |= MIPS_SR_COP_1_BIT | MIPS_SR_FR;
+#else
 			td->td_frame->sr |= MIPS_SR_COP_1_BIT;
+#endif
 			td->td_md.md_flags |= MDTD_FPUSED;
 			goto out;
 #endif


More information about the svn-src-all mailing list