From owner-svn-src-head@freebsd.org Mon Oct 31 15:34:02 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B40ACC28B02; Mon, 31 Oct 2016 15:34:02 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5596E1DB1; Mon, 31 Oct 2016 15:34:02 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9VFY181053196; Mon, 31 Oct 2016 15:34:01 GMT (envelope-from br@FreeBSD.org) Received: (from br@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9VFXw2x053156; Mon, 31 Oct 2016 15:33:58 GMT (envelope-from br@FreeBSD.org) Message-Id: <201610311533.u9VFXw2x053156@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: br set sender to br@FreeBSD.org using -f From: Ruslan Bukin Date: Mon, 31 Oct 2016 15:33:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: 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... X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Oct 2016 15:34:02 -0000 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 +#include +#include + +#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