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:
parent
ad9f2cecd7
commit
5bca221511
4
Makefile
4
Makefile
@ -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}
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if ${TARGET_ARCH:Mmips*el} != ""
|
||||
.if ${TARGET_ARCH:Mmips*el*} != ""
|
||||
_EMULATION_ENDIAN=l
|
||||
.else
|
||||
_EMULATION_ENDIAN=b
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if ${TARGET_ARCH:Mmips*el} != ""
|
||||
.if ${TARGET_ARCH:Mmips*el*} != ""
|
||||
_EMULATION_ENDIAN=little
|
||||
.else
|
||||
_EMULATION_ENDIAN=big
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -31,6 +31,10 @@ FBSD_1.0 {
|
||||
sbrk;
|
||||
};
|
||||
|
||||
FBSD_1.3 {
|
||||
__flt_rounds;
|
||||
};
|
||||
|
||||
FBSDprivate_1.0 {
|
||||
/* PSEUDO syscalls */
|
||||
__sys_getlogin;
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -1,4 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if ${MACHINE_ARCH:Mmips*hf} == ""
|
||||
CFLAGS+=-DSOFTFLOAT
|
||||
.endif
|
||||
|
||||
LDBL_PREC = 53
|
||||
SYM_MAPS += ${.CURDIR}/mips/Symbol.map
|
||||
|
@ -5,9 +5,17 @@ FBSD_1.0 {
|
||||
};
|
||||
|
||||
FBSD_1.3 {
|
||||
feclearexcept;
|
||||
fegetexceptflag;
|
||||
fesetexceptflag;
|
||||
feraiseexcept;
|
||||
fetestexcept;
|
||||
fegetround;
|
||||
fesetround;
|
||||
fegetenv;
|
||||
feholdexcept;
|
||||
feupdateenv;
|
||||
feenableexcept;
|
||||
fedisableexcept;
|
||||
fegetexcept;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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" || \
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user