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
This commit is contained in:
Ruslan Bukin 2016-10-31 15:33:58 +00:00
parent ad9f2cecd7
commit 5bca221511
32 changed files with 235 additions and 88 deletions

View File

@ -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 powerpc sparc64
_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}

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.if ${TARGET_ARCH:Mmips*el} != ""
.if ${TARGET_ARCH:Mmips*el*} != ""
_EMULATION_ENDIAN=l
.else
_EMULATION_ENDIAN=b

View File

@ -1,6 +1,6 @@
# $FreeBSD$
.if ${TARGET_ARCH:Mmips*el} != ""
.if ${TARGET_ARCH:Mmips*el*} != ""
_EMULATION_ENDIAN=little
.else
_EMULATION_ENDIAN=big

View File

@ -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

View File

@ -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/powerpc/rs6000/:C/sparc64/sparc/}
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"

View File

@ -23,7 +23,7 @@ OBJ_RL= ${OBJ_ROOT}/../lib/libreadline/readline
# 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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -31,6 +31,10 @@ FBSD_1.0 {
sbrk;
};
FBSD_1.3 {
__flt_rounds;
};
FBSDprivate_1.0 {
/* PSEUDO syscalls */
__sys_getlogin;

View File

@ -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

View File

@ -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;
__asm("cfc1 %0,$31" : "=r" (x));
return map[x & 0x03];
#ifdef SOFTFLOAT
mode = __softfloat_float_rounding_mode;
#else
__asm __volatile("cfc1 %0,$31" : "=r" (mode));
#endif
return map[mode & 0x03];
}

View File

@ -1,4 +1,8 @@
# $FreeBSD$
.if ${MACHINE_ARCH:Mmips*hf} == ""
CFLAGS+=-DSOFTFLOAT
.endif
LDBL_PREC = 53
SYM_MAPS += ${.CURDIR}/mips/Symbol.map

View File

@ -5,9 +5,17 @@ FBSD_1.0 {
};
FBSD_1.3 {
feclearexcept;
fegetexceptflag;
fesetexceptflag;
feraiseexcept;
fetestexcept;
fegetround;
fesetround;
fegetenv;
feholdexcept;
feupdateenv;
feenableexcept;
fedisableexcept;
fegetexcept;
};

View File

@ -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 *__envp);
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);

View File

@ -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;
/*
* 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);
__cfc1(fcsr);
return (fcsr & _ROUND_MASK);
}
__fenv_static inline int
fesetround(int __round)
{
fexcept_t fcsr;
return (-1);
if (__round & ~_ROUND_MASK)
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;
__rfs(&__old_fpsr);
__new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
__wfs(__new_fpsr);
return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
__cfc1(__old_fcsr);
__new_fcsr = __old_fcsr | (__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT;
__ctc1(__new_fcsr);
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;
__rfs(&__old_fpsr);
__new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
__wfs(__new_fpsr);
return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
__cfc1(__old_fcsr);
__new_fcsr = __old_fcsr & ~((__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT);
__ctc1(__new_fcsr);
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

View File

@ -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

View File

@ -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

View File

@ -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" || \

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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
#

View File

@ -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

View File

@ -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

View File

@ -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
/*

View File

@ -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

View File

@ -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 @@ trap(struct trapframe *trapframe)
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