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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to