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
+2 -2
View File
@@ -239,7 +239,7 @@ _MAKE+= MK_META_MODE=no
_TARGET_ARCH= ${TARGET:S/pc98/i386/:S/arm64/aarch64/} _TARGET_ARCH= ${TARGET:S/pc98/i386/:S/arm64/aarch64/}
.elif !defined(TARGET) && defined(TARGET_ARCH) && \ .elif !defined(TARGET) && defined(TARGET_ARCH) && \
${TARGET_ARCH} != ${MACHINE_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 .endif
.if defined(TARGET) && !defined(_TARGET) .if defined(TARGET) && !defined(_TARGET)
_TARGET=${TARGET} _TARGET=${TARGET}
@@ -421,7 +421,7 @@ TARGETS?=amd64 arm arm64 i386 mips pc98 powerpc sparc64
_UNIVERSE_TARGETS= ${TARGETS} _UNIVERSE_TARGETS= ${TARGETS}
TARGET_ARCHES_arm?= arm armeb armv6 TARGET_ARCHES_arm?= arm armeb armv6
TARGET_ARCHES_arm64?= aarch64 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_powerpc?= powerpc powerpc64 powerpcspe
TARGET_ARCHES_pc98?= i386 TARGET_ARCHES_pc98?= i386
.for target in ${TARGETS} .for target in ${TARGETS}
+4
View File
@@ -356,6 +356,10 @@ KNOWN_ARCHES?= aarch64/arm64 \
mipsn32el/mips \ mipsn32el/mips \
mips64/mips \ mips64/mips \
mipsn32/mips \ mipsn32/mips \
mipshf/mips \
mipselhf/mips \
mips64elhf/mips \
mips64hf/mips \
powerpc \ powerpc \
powerpc64/powerpc \ powerpc64/powerpc \
powerpcspe/powerpc \ powerpcspe/powerpc \
+1 -1
View File
@@ -165,7 +165,7 @@ LIBADD+= compiler_rt
.if ${TARGET_CPUARCH} == mips .if ${TARGET_CPUARCH} == mips
LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c
# ABIs other than o32 need this # 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+= floatdidf.c fixunsdfsi.c
LIB2FUNCS_EXTRA+= floatdisf.c floatundidf.c LIB2FUNCS_EXTRA+= floatdisf.c floatundidf.c
LIB2FUNCS_EXTRA+= fixsfdi.c floatundisf.c LIB2FUNCS_EXTRA+= fixsfdi.c floatundisf.c
+2 -2
View File
@@ -7,7 +7,7 @@
VERSION= "2.17.50 [FreeBSD] 2007-07-03" VERSION= "2.17.50 [FreeBSD] 2007-07-03"
.if defined(TARGET_ARCH) .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 .else
TARGET_CPUARCH=${MACHINE_CPUARCH} TARGET_CPUARCH=${MACHINE_CPUARCH}
.endif .endif
@@ -17,7 +17,7 @@ TARGET_OS?= freebsd
BINUTILS_ARCH=${TARGET_ARCH:C/amd64/x86_64/} BINUTILS_ARCH=${TARGET_ARCH:C/amd64/x86_64/}
TARGET_TUPLE?= ${BINUTILS_ARCH}-${TARGET_VENDOR}-${TARGET_OS} TARGET_TUPLE?= ${BINUTILS_ARCH}-${TARGET_VENDOR}-${TARGET_OS}
.if ${TARGET_ARCH} == "armeb" || ${TARGET_ARCH} == "armv6eb" || \ .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 TARGET_BIG_ENDIAN=t
.endif .endif
+1 -1
View File
@@ -1,6 +1,6 @@
# $FreeBSD$ # $FreeBSD$
.if ${TARGET_ARCH:Mmips*el} != "" .if ${TARGET_ARCH:Mmips*el*} != ""
_EMULATION_ENDIAN=l _EMULATION_ENDIAN=l
.else .else
_EMULATION_ENDIAN=b _EMULATION_ENDIAN=b
+1 -1
View File
@@ -1,6 +1,6 @@
# $FreeBSD$ # $FreeBSD$
.if ${TARGET_ARCH:Mmips*el} != "" .if ${TARGET_ARCH:Mmips*el*} != ""
_EMULATION_ENDIAN=little _EMULATION_ENDIAN=little
.else .else
_EMULATION_ENDIAN=big _EMULATION_ENDIAN=big
+1 -1
View File
@@ -39,7 +39,7 @@ CFLAGS += -DFREEBSD_ARCH_armv6
.endif .endif
.if ${TARGET_CPUARCH} == "mips" .if ${TARGET_CPUARCH} == "mips"
.if ${TARGET_ARCH:Mmips*el} != "" .if ${TARGET_ARCH:Mmips*el*} != ""
CFLAGS += -DTARGET_ENDIAN_DEFAULT=0 CFLAGS += -DTARGET_ENDIAN_DEFAULT=0
.endif .endif
+2 -2
View File
@@ -4,7 +4,7 @@
# MACHINE_CPUARCH, but there's no easy way to export make functions... # MACHINE_CPUARCH, but there's no easy way to export make functions...
.if defined(TARGET_ARCH) .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 .else
TARGET_CPUARCH=${MACHINE_CPUARCH} TARGET_CPUARCH=${MACHINE_CPUARCH}
.endif .endif
@@ -15,7 +15,7 @@ GCC_CPU=${TARGET_CPUARCH:C/amd64/i386/:C/powerpc/rs6000/:C/sparc64/sparc/}
TARGET_CPU_DEFAULT= TARGET_CPU_ultrasparc TARGET_CPU_DEFAULT= TARGET_CPU_ultrasparc
.endif .endif
.if ${TARGET_ARCH} == "armeb" || ${TARGET_ARCH} == "armv6eb" || \ .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 TARGET_BIG_ENDIAN=t
.endif .endif
.if ${TARGET_ARCH} == "powerpc64" .if ${TARGET_ARCH} == "powerpc64"
+1 -1
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... # MACHINE_CPUARCH, but there's no easy way to export make functions...
.if defined(TARGET_ARCH) .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 .else
TARGET_CPUARCH=${MACHINE_CPUARCH} TARGET_CPUARCH=${MACHINE_CPUARCH}
.endif .endif
+1 -1
View File
@@ -4,7 +4,7 @@
# MACHINE_CPUARCH, but there's no easy way to export make functions... # MACHINE_CPUARCH, but there's no easy way to export make functions...
.if defined(TARGET_ARCH) .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 .else
TARGET_CPUARCH=${MACHINE_CPUARCH} TARGET_CPUARCH=${MACHINE_CPUARCH}
.endif .endif
+1 -1
View File
@@ -111,7 +111,7 @@ NOASM=
.include "${LIBC_SRCTOP}/xdr/Makefile.inc" .include "${LIBC_SRCTOP}/xdr/Makefile.inc"
.if (${LIBC_ARCH} == "arm" && \ .if (${LIBC_ARCH} == "arm" && \
(${MACHINE_ARCH:Marmv6*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \ (${MACHINE_ARCH:Marmv6*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \
${LIBC_ARCH} == "mips" (${LIBC_ARCH} == "mips" && ${MACHINE_ARCH:Mmips*hf} == "")
.include "${LIBC_SRCTOP}/softfloat/Makefile.inc" .include "${LIBC_SRCTOP}/softfloat/Makefile.inc"
.endif .endif
.if ${LIBC_ARCH} == "i386" || ${LIBC_ARCH} == "amd64" .if ${LIBC_ARCH} == "i386" || ${LIBC_ARCH} == "amd64"
+2
View File
@@ -1,7 +1,9 @@
# $NetBSD: Makefile.inc,v 1.7 2005/09/17 11:49:39 tsutsui Exp $ # $NetBSD: Makefile.inc,v 1.7 2005/09/17 11:49:39 tsutsui Exp $
# $FreeBSD$ # $FreeBSD$
.if ${MACHINE_ARCH:Mmips*hf} == ""
CFLAGS+=-DSOFTFLOAT CFLAGS+=-DSOFTFLOAT
.endif
MDSRCS+= machdep_ldisd.c MDSRCS+= machdep_ldisd.c
SYM_MAPS+= ${LIBC_SRCTOP}/mips/Symbol.map SYM_MAPS+= ${LIBC_SRCTOP}/mips/Symbol.map
+4
View File
@@ -31,6 +31,10 @@ FBSD_1.0 {
sbrk; sbrk;
}; };
FBSD_1.3 {
__flt_rounds;
};
FBSDprivate_1.0 { FBSDprivate_1.0 {
/* PSEUDO syscalls */ /* PSEUDO syscalls */
__sys_getlogin; __sys_getlogin;
+1 -1
View File
@@ -1,7 +1,7 @@
# $NetBSD: Makefile.inc,v 1.27 2005/10/07 17:16:40 tsutsui Exp $ # $NetBSD: Makefile.inc,v 1.27 2005/10/07 17:16:40 tsutsui Exp $
# $FreeBSD$ # $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 \ # SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
# fpsetround.c fpsetsticky.c # fpsetround.c fpsetsticky.c
+16 -4
View File
@@ -11,7 +11,14 @@ __FBSDID("$FreeBSD$");
__RCSID("$NetBSD: flt_rounds.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); __RCSID("$NetBSD: flt_rounds.c,v 1.5 2005/12/24 23:10:08 perry Exp $");
#endif /* LIBC_SCCS and not lint */ #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[] = { static const int map[] = {
1, /* round to nearest */ 1, /* round to nearest */
@@ -23,8 +30,13 @@ static const int map[] = {
int int
__flt_rounds() __flt_rounds()
{ {
int x; int mode;
__asm("cfc1 %0,$31" : "=r" (x)); #ifdef SOFTFLOAT
return map[x & 0x03]; mode = __softfloat_float_rounding_mode;
#else
__asm __volatile("cfc1 %0,$31" : "=r" (mode));
#endif
return map[mode & 0x03];
} }
+4
View File
@@ -1,4 +1,8 @@
# $FreeBSD$ # $FreeBSD$
.if ${MACHINE_ARCH:Mmips*hf} == ""
CFLAGS+=-DSOFTFLOAT
.endif
LDBL_PREC = 53 LDBL_PREC = 53
SYM_MAPS += ${.CURDIR}/mips/Symbol.map SYM_MAPS += ${.CURDIR}/mips/Symbol.map
+8
View File
@@ -5,9 +5,17 @@ FBSD_1.0 {
}; };
FBSD_1.3 { FBSD_1.3 {
feclearexcept;
fegetexceptflag;
fesetexceptflag; fesetexceptflag;
feraiseexcept; feraiseexcept;
fetestexcept;
fegetround;
fesetround;
fegetenv; fegetenv;
feholdexcept; feholdexcept;
feupdateenv; feupdateenv;
feenableexcept;
fedisableexcept;
fegetexcept;
}; };
+14
View File
@@ -39,6 +39,17 @@
*/ */
const fenv_t __fe_dfl_env = 0; 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 feclearexcept(int __excepts);
extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts);
extern inline int fesetexceptflag(const 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 feholdexcept(fenv_t *__envp);
extern inline int fesetenv(const fenv_t *__envp); extern inline int fesetenv(const fenv_t *__envp);
extern inline int feupdateenv(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);
+109 -55
View File
@@ -39,11 +39,21 @@ typedef __uint32_t fenv_t;
typedef __uint32_t fexcept_t; typedef __uint32_t fexcept_t;
/* Exception flags */ /* Exception flags */
#ifdef SOFTFLOAT
#define _FPUSW_SHIFT 16
#define FE_INVALID 0x0001 #define FE_INVALID 0x0001
#define FE_DIVBYZERO 0x0002 #define FE_DIVBYZERO 0x0002
#define FE_OVERFLOW 0x0004 #define FE_OVERFLOW 0x0004
#define FE_UNDERFLOW 0x0008 #define FE_UNDERFLOW 0x0008
#define FE_INEXACT 0x0010 #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 | \ #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \
FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
@@ -61,104 +71,135 @@ extern const fenv_t __fe_dfl_env;
#define FE_DFL_ENV (&__fe_dfl_env) #define FE_DFL_ENV (&__fe_dfl_env)
/* We need to be able to map status flag positions to mask flag positions */ /* We need to be able to map status flag positions to mask flag positions */
#define _FPUSW_SHIFT 16 #define _ENABLE_SHIFT 5
#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) #define _ENABLE_MASK (FE_ALL_EXCEPT << _ENABLE_SHIFT)
#ifdef ARM_HARD_FLOAT #ifndef SOFTFLOAT
#define __rfs(__fpsr) __asm __volatile("rfs %0" : "=r" (*(__fpsr))) #define __cfc1(__fcsr) __asm __volatile("cfc1 %0, $31" : "=r" (__fcsr))
#define __wfs(__fpsr) __asm __volatile("wfs %0" : : "r" (__fpsr)) #define __ctc1(__fcsr) __asm __volatile("ctc1 %0, $31" :: "r" (__fcsr))
#else
#define __rfs(__fpsr)
#define __wfs(__fpsr)
#endif #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 __fenv_static inline int
feclearexcept(int __excepts) 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); return (0);
} }
__fenv_static inline int __fenv_static inline int
fegetexceptflag(fexcept_t *__flagp, int __excepts) 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); return (0);
} }
__fenv_static inline int __fenv_static inline int
fesetexceptflag(const fexcept_t *__flagp, int __excepts) 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); return (0);
} }
__fenv_static inline int __fenv_static inline int
feraiseexcept(int __excepts) 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); return (0);
} }
__fenv_static inline int __fenv_static inline int
fetestexcept(int __excepts) fetestexcept(int __excepts)
{ {
fexcept_t __fpsr; fexcept_t fcsr;
__rfs(&__fpsr); __excepts &= FE_ALL_EXCEPT;
return (__fpsr & __excepts); __cfc1(fcsr);
return (fcsr & __excepts);
} }
__fenv_static inline int __fenv_static inline int
fegetround(void) 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 return (fcsr & _ROUND_MASK);
* indeterminate. Some FPUs may differ.
*/
return (-1);
} }
__fenv_static inline int __fenv_static inline int
fesetround(int __round) 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 __fenv_static inline int
fegetenv(fenv_t *__envp) fegetenv(fenv_t *__envp)
{ {
__rfs(__envp); __cfc1(*__envp);
return (0); return (0);
} }
__fenv_static inline int __fenv_static inline int
feholdexcept(fenv_t *__envp) 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); return (0);
} }
@@ -166,56 +207,69 @@ __fenv_static inline int
fesetenv(const fenv_t *__envp) fesetenv(const fenv_t *__envp)
{ {
__wfs(*__envp); __ctc1(*__envp);
return (0); return (0);
} }
__fenv_static inline int __fenv_static inline int
feupdateenv(const fenv_t *__envp) 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); return (0);
} }
#endif /* !SOFTFLOAT */
#if __BSD_VISIBLE #if __BSD_VISIBLE
/* We currently provide no external definitions of the functions below. */ /* 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 static inline int
feenableexcept(int __mask) feenableexcept(int __mask)
{ {
fenv_t __old_fpsr, __new_fpsr; fenv_t __old_fcsr, __new_fcsr;
__rfs(&__old_fpsr); __cfc1(__old_fcsr);
__new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; __new_fcsr = __old_fcsr | (__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT;
__wfs(__new_fpsr); __ctc1(__new_fcsr);
return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT);
} }
static inline int static inline int
fedisableexcept(int __mask) fedisableexcept(int __mask)
{ {
fenv_t __old_fpsr, __new_fpsr; fenv_t __old_fcsr, __new_fcsr;
__rfs(&__old_fpsr); __cfc1(__old_fcsr);
__new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); __new_fcsr = __old_fcsr & ~((__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT);
__wfs(__new_fpsr); __ctc1(__new_fcsr);
return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT);
} }
static inline int static inline int
fegetexcept(void) fegetexcept(void)
{ {
fenv_t __fpsr; fexcept_t fcsr;
__rfs(&__fpsr); __cfc1(fcsr);
return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
return ((fcsr & _ENABLE_MASK) >> _ENABLE_SHIFT);
} }
#endif /* !SOFTFLOAT */
#endif /* __BSD_VISIBLE */ #endif /* __BSD_VISIBLE */
__END_DECLS __END_DECLS
+20
View File
@@ -57,9 +57,13 @@ On all supported architectures,
.It i386 Ta 4 Ta 12 .It i386 Ta 4 Ta 12
.It mips Ta 4 Ta 8 .It mips Ta 4 Ta 8
.It mipsel 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 mipsn32 Ta 4 Ta 8
.It mips64 Ta 8 Ta 8 .It mips64 Ta 8 Ta 8
.It mips64el 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 powerpc Ta 4 Ta 8
.It powerpc64 Ta 8 Ta 8 .It powerpc64 Ta 8 Ta 8
.It riscv Ta 8 Ta .It riscv Ta 8 Ta
@@ -76,9 +80,13 @@ On all supported architectures,
.It i386 Ta little Ta signed .It i386 Ta little Ta signed
.It mips Ta big Ta signed .It mips Ta big Ta signed
.It mipsel Ta little 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 mipsn32 Ta big Ta signed
.It mips64 Ta big Ta signed .It mips64 Ta big Ta signed
.It mips64el Ta little 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 powerpc Ta big Ta unsigned
.It powerpc64 Ta big Ta unsigned .It powerpc64 Ta big Ta unsigned
.It riscv Ta little Ta signed .It riscv Ta little Ta signed
@@ -95,9 +103,13 @@ On all supported architectures,
.It i386 Ta 4K, 2M (PAE), 4M .It i386 Ta 4K, 2M (PAE), 4M
.It mips Ta 4K .It mips Ta 4K
.It mipsel Ta 4K .It mipsel Ta 4K
.It mipselhf Ta 4K
.It mipshf Ta 4K
.It mipsn32 Ta 4K .It mipsn32 Ta 4K
.It mips64 Ta 4K .It mips64 Ta 4K
.It mips64el Ta 4K .It mips64el Ta 4K
.It mips64elhf Ta 4K
.It mips64hf Ta 4K
.It powerpc Ta 4K .It powerpc Ta 4K
.It powerpc64 Ta 4K .It powerpc64 Ta 4K
.It riscv Ta 4K .It riscv Ta 4K
@@ -114,9 +126,13 @@ On all supported architectures,
.It i386 Ta hard Ta hard, 80 bit .It i386 Ta hard Ta hard, 80 bit
.It mips Ta soft Ta identical to double .It mips Ta soft Ta identical to double
.It mipsel Ta soft Ta identical to double .It mipsel 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 mipsn32 Ta soft Ta identical to double
.It mips64 Ta soft Ta identical to double .It mips64 Ta soft Ta identical to double
.It mips64el 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 powerpc Ta hard Ta hard, double precision
.It powerpc64 Ta hard Ta hard, double precision .It powerpc64 Ta hard Ta hard, double precision
.It riscv Ta .It riscv Ta
@@ -155,9 +171,13 @@ Architecture-specific macros:
.It i386 Ta Dv __i386__ .It i386 Ta Dv __i386__
.It mips Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32 .It mips Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32
.It mipsel Ta Dv __mips__, 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 mipsn32 Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n32
.It mips64 Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64 .It mips64 Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64
.It mips64el Ta Dv __mips__, 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 powerpc Ta Dv __powerpc__
.It powerpc64 Ta Dv __powerpc__, Dv __powerpc64__ .It powerpc64 Ta Dv __powerpc__, Dv __powerpc64__
.It riscv Ta Dv __riscv__, Dv __riscv64 .It riscv Ta Dv __riscv__, Dv __riscv64
+3
View File
@@ -303,6 +303,9 @@ MACHINE_CPU = v9 ultrasparc ultrasparc3
.if ${MACHINE_CPUARCH} == "mips" .if ${MACHINE_CPUARCH} == "mips"
CFLAGS += -G0 CFLAGS += -G0
.if ${TARGET_ARCH:Mmips*hf}
CFLAGS += -mhard-float
.endif
.endif .endif
########## arm ########## arm
+1 -1
View File
@@ -5,7 +5,7 @@
${MACHINE_ARCH} == "i386" || \ ${MACHINE_ARCH} == "i386" || \
(${MACHINE} == "arm" && ${MACHINE_ARCH:Marm*eb*} == "") || \ (${MACHINE} == "arm" && ${MACHINE_ARCH:Marm*eb*} == "") || \
${MACHINE_CPUARCH} == "riscv" || \ ${MACHINE_CPUARCH} == "riscv" || \
${MACHINE_ARCH:Mmips*el} != "" ${MACHINE_ARCH:Mmips*el*} != ""
TARGET_ENDIANNESS= 1234 TARGET_ENDIANNESS= 1234
.elif ${MACHINE_ARCH} == "powerpc" || \ .elif ${MACHINE_ARCH} == "powerpc" || \
${MACHINE_ARCH} == "powerpc64" || \ ${MACHINE_ARCH} == "powerpc64" || \
+1 -1
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 # and/or endian. This is called MACHINE_CPU in NetBSD, but that's used
# for something different in FreeBSD. # 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 .endif
+1 -1
View File
@@ -6,7 +6,7 @@ FICLDIR?= ${SRCTOP}/sys/boot/ficl
.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) .if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32)
FICL_CPUARCH= i386 FICL_CPUARCH= i386
.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" .elif ${MACHINE_ARCH:Mmips64*} != ""
FICL_CPUARCH= mips64 FICL_CPUARCH= mips64
.else .else
FICL_CPUARCH= ${MACHINE_CPUARCH} FICL_CPUARCH= ${MACHINE_CPUARCH}
+1 -1
View File
@@ -18,7 +18,7 @@ SRCS+= load_elf32.c reloc_elf32.c
SRCS+= load_elf64.c reloc_elf64.c SRCS+= load_elf64.c reloc_elf64.c
.elif ${MACHINE_CPUARCH} == "sparc64" .elif ${MACHINE_CPUARCH} == "sparc64"
SRCS+= load_elf64.c reloc_elf64.c 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 SRCS+= load_elf64.c reloc_elf64.c
.elif ${MACHINE} == "mips" .elif ${MACHINE} == "mips"
SRCS+= load_elf32.c reloc_elf32.c SRCS+= load_elf32.c reloc_elf32.c
+1 -1
View File
@@ -85,7 +85,7 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
# Enable BootForth # Enable BootForth
BOOT_FORTH= yes BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl
.if ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" .if ${MACHINE_ARCH:Mmips64*} != ""
CFLAGS+= -I${.CURDIR}/../../ficl/mips64 CFLAGS+= -I${.CURDIR}/../../ficl/mips64
.else .else
CFLAGS+= -I${.CURDIR}/../../ficl/mips CFLAGS+= -I${.CURDIR}/../../ficl/mips
+3
View File
@@ -184,6 +184,9 @@ CFLAGS.gcc+= -mcall-aixdesc
.if ${MACHINE_CPUARCH} == "mips" .if ${MACHINE_CPUARCH} == "mips"
CFLAGS+= -msoft-float CFLAGS+= -msoft-float
INLINE_LIMIT?= 8000 INLINE_LIMIT?= 8000
.if ${TARGET_ARCH:Mmips*hf} != ""
CFLAGS+= -DCPU_HAVEFPU
.endif
.endif .endif
# #
-4
View File
@@ -42,11 +42,7 @@ extern int __flt_rounds(void);
__END_DECLS __END_DECLS
#define FLT_RADIX 2 /* b */ #define FLT_RADIX 2 /* b */
#ifdef CPU_HAVEFPU
#define FLT_ROUNDS __flt_rounds() /* FP addition rounds to nearest */ #define FLT_ROUNDS __flt_rounds() /* FP addition rounds to nearest */
#else
#define FLT_ROUNDS (-1)
#endif
#if __ISO_C_VISIBLE >= 1999 #if __ISO_C_VISIBLE >= 1999
#define FLT_EVAL_METHOD 0 #define FLT_EVAL_METHOD 0
+6
View File
@@ -1098,11 +1098,17 @@ END(MipsTLBMissException)
NESTED(MipsFPTrap, CALLFRAME_SIZ, ra) NESTED(MipsFPTrap, CALLFRAME_SIZ, ra)
PTR_SUBU sp, sp, CALLFRAME_SIZ PTR_SUBU sp, sp, CALLFRAME_SIZ
mfc0 t0, MIPS_COP_0_STATUS mfc0 t0, MIPS_COP_0_STATUS
HAZARD_DELAY
REG_S ra, CALLFRAME_RA(sp) REG_S ra, CALLFRAME_RA(sp)
.mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) .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 or t1, t0, MIPS_SR_COP_1_BIT
#endif
mtc0 t1, MIPS_COP_0_STATUS mtc0 t1, MIPS_COP_0_STATUS
HAZARD_DELAY
ITLBNOPFIX ITLBNOPFIX
cfc1 t1, MIPS_FPU_CSR # stall til FP done cfc1 t1, MIPS_FPU_CSR # stall til FP done
cfc1 t1, MIPS_FPU_CSR # now get status cfc1 t1, MIPS_FPU_CSR # now get status
+1 -1
View File
@@ -118,7 +118,7 @@ VECTOR(_locore, unknown)
*/ */
li t1, MIPS_SR_COP_1_BIT li t1, MIPS_SR_COP_1_BIT
#ifdef __mips_n64 #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
#endif #endif
/* /*
+14 -2
View File
@@ -415,8 +415,14 @@ LEAF(MipsSwitchFPState)
.set push .set push
.set hardfloat .set hardfloat
mfc0 t1, MIPS_COP_0_STATUS # Save old SR 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 mtc0 t0, MIPS_COP_0_STATUS
HAZARD_DELAY
ITLBNOPFIX ITLBNOPFIX
beq a0, zero, 1f # skip save if NULL pointer beq a0, zero, 1f # skip save if NULL pointer
@@ -540,8 +546,14 @@ LEAF(MipsSaveCurFPState)
.set hardfloat .set hardfloat
PTR_L a0, TD_PCB(a0) # get pointer to pcb for thread PTR_L a0, TD_PCB(a0) # get pointer to pcb for thread
mfc0 t1, MIPS_COP_0_STATUS # Disable interrupts and 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 mtc0 t0, MIPS_COP_0_STATUS
HAZARD_DELAY
ITLBNOPFIX ITLBNOPFIX
GET_CPU_PCPU(a1) GET_CPU_PCPU(a1)
PTR_S zero, PC_FPCURTHREAD(a1) # indicate state has been saved PTR_S zero, PC_FPCURTHREAD(a1) # indicate state has been saved
+6 -1
View File
@@ -590,7 +590,8 @@ trap(struct trapframe *trapframe)
break; break;
} }
if ((last_badvaddr == this_badvaddr) && if ((last_badvaddr == this_badvaddr) &&
((type & ~T_USER) != T_SYSCALL)) { ((type & ~T_USER) != T_SYSCALL) &&
((type & ~T_USER) != T_COP_UNUSABLE)) {
if (++count == 3) { if (++count == 3) {
trap_frame_dump(trapframe); trap_frame_dump(trapframe);
panic("too many faults at %p\n", (void *)last_badvaddr); panic("too many faults at %p\n", (void *)last_badvaddr);
@@ -980,7 +981,11 @@ trap(struct trapframe *trapframe)
addr = trapframe->pc; addr = trapframe->pc;
MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame); MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
PCPU_SET(fpcurthread, td); 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; td->td_frame->sr |= MIPS_SR_COP_1_BIT;
#endif
td->td_md.md_flags |= MDTD_FPUSED; td->td_md.md_flags |= MDTD_FPUSED;
goto out; goto out;
#endif #endif