Index: Makefile =================================================================== --- Makefile +++ Makefile @@ -239,7 +239,7 @@ _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 @@ _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} Index: Makefile.inc1 =================================================================== --- Makefile.inc1 +++ Makefile.inc1 @@ -356,6 +356,10 @@ mipsn32el/mips \ mips64/mips \ mipsn32/mips \ + mipshf/mips \ + mipselhf/mips \ + mips64elhf/mips \ + mips64hf/mips \ powerpc \ powerpc64/powerpc \ powerpcspe/powerpc \ Index: gnu/lib/libgcc/Makefile =================================================================== --- gnu/lib/libgcc/Makefile +++ gnu/lib/libgcc/Makefile @@ -165,7 +165,7 @@ .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 Index: gnu/usr.bin/binutils/Makefile.inc0 =================================================================== --- gnu/usr.bin/binutils/Makefile.inc0 +++ gnu/usr.bin/binutils/Makefile.inc0 @@ -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 @@ 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 Index: gnu/usr.bin/binutils/ld/Makefile.mips =================================================================== --- gnu/usr.bin/binutils/ld/Makefile.mips +++ gnu/usr.bin/binutils/ld/Makefile.mips @@ -1,6 +1,6 @@ # $FreeBSD$ -.if ${TARGET_ARCH:Mmips*el} != "" +.if ${TARGET_ARCH:Mmips*el*} != "" _EMULATION_ENDIAN=l .else _EMULATION_ENDIAN=b Index: gnu/usr.bin/binutils/libbfd/Makefile.mips =================================================================== --- gnu/usr.bin/binutils/libbfd/Makefile.mips +++ gnu/usr.bin/binutils/libbfd/Makefile.mips @@ -1,6 +1,6 @@ # $FreeBSD$ -.if ${TARGET_ARCH:Mmips*el} != "" +.if ${TARGET_ARCH:Mmips*el*} != "" _EMULATION_ENDIAN=little .else _EMULATION_ENDIAN=big Index: gnu/usr.bin/cc/Makefile.inc =================================================================== --- gnu/usr.bin/cc/Makefile.inc +++ gnu/usr.bin/cc/Makefile.inc @@ -39,7 +39,7 @@ .endif .if ${TARGET_CPUARCH} == "mips" -.if ${TARGET_ARCH:Mmips*el} != "" +.if ${TARGET_ARCH:Mmips*el*} != "" CFLAGS += -DTARGET_ENDIAN_DEFAULT=0 .endif Index: gnu/usr.bin/cc/Makefile.tgt =================================================================== --- gnu/usr.bin/cc/Makefile.tgt +++ gnu/usr.bin/cc/Makefile.tgt @@ -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 @@ 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" Index: gnu/usr.bin/gdb/Makefile.inc =================================================================== --- gnu/usr.bin/gdb/Makefile.inc +++ gnu/usr.bin/gdb/Makefile.inc @@ -23,7 +23,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 Index: gnu/usr.bin/gdb/libgdb/Makefile =================================================================== --- gnu/usr.bin/gdb/libgdb/Makefile +++ gnu/usr.bin/gdb/libgdb/Makefile @@ -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 Index: lib/libc/Makefile =================================================================== --- lib/libc/Makefile +++ lib/libc/Makefile @@ -111,7 +111,7 @@ .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" Index: lib/libc/mips/Makefile.inc =================================================================== --- lib/libc/mips/Makefile.inc +++ lib/libc/mips/Makefile.inc @@ -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 Index: lib/libc/mips/Symbol.map =================================================================== --- lib/libc/mips/Symbol.map +++ lib/libc/mips/Symbol.map @@ -31,6 +31,10 @@ sbrk; }; +FBSD_1.3 { + __flt_rounds; +}; + FBSDprivate_1.0 { /* PSEUDO syscalls */ __sys_getlogin; Index: lib/libc/mips/gen/Makefile.inc =================================================================== --- lib/libc/mips/gen/Makefile.inc +++ lib/libc/mips/gen/Makefile.inc @@ -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 Index: lib/libc/mips/gen/flt_rounds.c =================================================================== --- lib/libc/mips/gen/flt_rounds.c +++ lib/libc/mips/gen/flt_rounds.c @@ -11,7 +11,14 @@ __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 @@ 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]; } Index: lib/msun/mips/Makefile.inc =================================================================== --- lib/msun/mips/Makefile.inc +++ lib/msun/mips/Makefile.inc @@ -1,4 +1,8 @@ # $FreeBSD$ +.if ${MACHINE_ARCH:Mmips*hf} == "" +CFLAGS+=-DSOFTFLOAT +.endif + LDBL_PREC = 53 SYM_MAPS += ${.CURDIR}/mips/Symbol.map Index: lib/msun/mips/Symbol.map =================================================================== --- lib/msun/mips/Symbol.map +++ lib/msun/mips/Symbol.map @@ -5,9 +5,17 @@ }; FBSD_1.3 { + feclearexcept; + fegetexceptflag; fesetexceptflag; feraiseexcept; + fetestexcept; + fegetround; + fesetround; fegetenv; feholdexcept; feupdateenv; + feenableexcept; + fedisableexcept; + fegetexcept; }; Index: lib/msun/mips/fenv.h =================================================================== --- lib/msun/mips/fenv.h +++ lib/msun/mips/fenv.h @@ -39,11 +39,21 @@ 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 @@ #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 @@ 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 Index: lib/msun/mips/fenv.c =================================================================== --- lib/msun/mips/fenv.c +++ lib/msun/mips/fenv.c @@ -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 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); Index: share/man/man7/arch.7 =================================================================== --- share/man/man7/arch.7 +++ share/man/man7/arch.7 @@ -60,6 +60,10 @@ .It mipsn32 Ta 4 Ta 8 .It mips64 Ta 8 Ta 8 .It mips64el Ta 8 Ta 8 +.It mipshf Ta 4 Ta 8 +.It mipselhf Ta 4 Ta 8 +.It mips64hf Ta 8 Ta 8 +.It mips64elhf Ta 8 Ta 8 .It powerpc Ta 4 Ta 8 .It powerpc64 Ta 8 Ta 8 .It riscv Ta 8 Ta @@ -79,6 +83,10 @@ .It mipsn32 Ta big Ta signed .It mips64 Ta big Ta signed .It mips64el Ta little Ta signed +.It mipshf Ta big Ta signed +.It mipselhf Ta little Ta signed +.It mips64hf Ta big Ta signed +.It mips64elhf Ta little Ta signed .It powerpc Ta big Ta unsigned .It powerpc64 Ta big Ta unsigned .It riscv Ta little Ta signed @@ -98,6 +106,10 @@ .It mipsn32 Ta 4K .It mips64 Ta 4K .It mips64el Ta 4K +.It mipshf Ta 4K +.It mipselhf Ta 4K +.It mips64hf Ta 4K +.It mips64elhf Ta 4K .It powerpc Ta 4K .It powerpc64 Ta 4K .It riscv Ta 4K @@ -114,9 +126,13 @@ .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 mipsn32 Ta soft Ta identical to double .It mips64 Ta soft Ta identical to double .It mips64el Ta soft Ta identical to double +.It mipshf Ta hard Ta identical to double +.It mipselhf Ta hard Ta identical to double +.It mips64hf Ta hard Ta identical to double +.It mips64elhf 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 @@ -158,6 +174,10 @@ .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 mipshf Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32 +.It mipselhf Ta Dv __mips__, Dv __mips_o32 +.It mips64hf Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64 +.It mips64elhf Ta Dv __mips__, Dv __mips_n64 .It powerpc Ta Dv __powerpc__ .It powerpc64 Ta Dv __powerpc__, Dv __powerpc64__ .It riscv Ta Dv __riscv__, Dv __riscv64 Index: share/mk/bsd.cpu.mk =================================================================== --- share/mk/bsd.cpu.mk +++ share/mk/bsd.cpu.mk @@ -303,6 +303,9 @@ .if ${MACHINE_CPUARCH} == "mips" CFLAGS += -G0 +.if ${TARGET_ARCH:Mmips*hf} +CFLAGS += -mhard-float +.endif .endif ########## arm Index: share/mk/bsd.endian.mk =================================================================== --- share/mk/bsd.endian.mk +++ share/mk/bsd.endian.mk @@ -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" || \ Index: share/mk/sys.mk =================================================================== --- share/mk/sys.mk +++ share/mk/sys.mk @@ -13,7 +13,7 @@ # 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 Index: sys/boot/Makefile.ficl =================================================================== --- sys/boot/Makefile.ficl +++ sys/boot/Makefile.ficl @@ -6,7 +6,7 @@ .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} Index: sys/boot/common/Makefile.inc =================================================================== --- sys/boot/common/Makefile.inc +++ sys/boot/common/Makefile.inc @@ -18,7 +18,7 @@ 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 Index: sys/boot/mips/uboot/Makefile =================================================================== --- sys/boot/mips/uboot/Makefile +++ sys/boot/mips/uboot/Makefile @@ -85,7 +85,7 @@ # 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 Index: sys/conf/kern.mk =================================================================== --- sys/conf/kern.mk +++ sys/conf/kern.mk @@ -184,6 +184,9 @@ .if ${MACHINE_CPUARCH} == "mips" CFLAGS+= -msoft-float INLINE_LIMIT?= 8000 +.if ${TARGET_ARCH:Mmips*hf} != "" +CFLAGS+= -DCPU_HAVEFPU +.endif .endif # Index: sys/mips/include/float.h =================================================================== --- sys/mips/include/float.h +++ sys/mips/include/float.h @@ -42,11 +42,7 @@ __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 Index: sys/mips/mips/exception.S =================================================================== --- sys/mips/mips/exception.S +++ sys/mips/mips/exception.S @@ -1098,11 +1098,17 @@ 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 Index: sys/mips/mips/locore.S =================================================================== --- sys/mips/mips/locore.S +++ sys/mips/mips/locore.S @@ -118,7 +118,7 @@ */ 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 /* Index: sys/mips/mips/swtch.S =================================================================== --- sys/mips/mips/swtch.S +++ sys/mips/mips/swtch.S @@ -415,8 +415,14 @@ .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 @@ .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 Index: sys/mips/mips/trap.c =================================================================== --- sys/mips/mips/trap.c +++ sys/mips/mips/trap.c @@ -590,7 +590,8 @@ 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 @@ 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 @@ -1028,7 +1033,7 @@ case T_FPE + T_USER: if (!emulate_fp) { - i = SIGILL; + i = SIGFPE; addr = trapframe->pc; break; }