瀏覽代碼

Support for riscv64 architecture (#254)

Changes needed for riscv64 support have been added.
Code for openlibm_fenv_riscv.h, riscv_fpmath.h and fenv.c
was taken from https://github.com/freebsd/freebsd
xctan 4 年之前
父節點
當前提交
428e7af214
共有 8 個文件被更改,包括 391 次插入1 次删除
  1. 3 0
      Make.inc
  2. 1 1
      Makefile
  3. 2 0
      include/openlibm_fenv.h
  4. 261 0
      include/openlibm_fenv_riscv.h
  5. 1 0
      riscv64/Make.files
  6. 63 0
      riscv64/fenv.c
  7. 2 0
      src/fpmath.h
  8. 58 0
      src/riscv_fpmath.h

+ 3 - 0
Make.inc

@@ -81,6 +81,9 @@ endif
 ifeq ($(findstring mips,$(ARCH)),mips)
 override ARCH := mips
 endif
+ifeq ($(findstring riscv64,$(ARCH)),riscv64)
+override ARCH := riscv64
+endif
 
 # If CFLAGS does not contain a -O optimization flag, default to -O3
 ifeq ($(findstring -O,$(CFLAGS)),)

+ 1 - 1
Makefile

@@ -81,7 +81,7 @@ test/test-float: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT)
 	$(MAKE) -C test test-float
 
 clean:
-	rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o mips/*.o s390/*.o
+	rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o mips/*.o s390/*.o riscv64/*.o
 	rm -f libopenlibm.a libopenlibm.*$(SHLIB_EXT)*
 	$(MAKE) -C test clean
 

+ 2 - 0
include/openlibm_fenv.h

@@ -14,6 +14,8 @@
 #include <openlibm_fenv_mips.h>
 #elif defined(__s390__)
 #include <openlibm_fenv_s390.h>
+#elif defined(__riscv)
+#include <openlibm_fenv_riscv.h>
 #else
 #error "Unsupported platform"
 #endif

+ 261 - 0
include/openlibm_fenv_riscv.h

@@ -0,0 +1,261 @@
+/*-
+ * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by SRI International and the
+ * University of Cambridge Computer Laboratory under DARPA/AFRL contract
+ * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Portions of this software were developed by the University of Cambridge
+ * Computer Laboratory as part of the CTSRD Project, with support from the
+ * UK Higher Education Innovation Fund (HEIF).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/lib/msun/riscv/fenv.h 332792 2018-04-19 20:36:15Z brooks $
+ */
+
+#ifndef	_FENV_H_
+#define	_FENV_H_
+
+#include <stdint.h>
+#include "cdefs-compat.h"
+
+#ifndef	__fenv_static
+#define	__fenv_static	static
+#endif
+
+typedef	__uint64_t	fenv_t;
+typedef	__uint64_t	fexcept_t;
+
+/* Exception flags */
+#define	FE_INVALID	0x0010
+#define	FE_DIVBYZERO	0x0008
+#define	FE_OVERFLOW	0x0004
+#define	FE_UNDERFLOW	0x0002
+#define	FE_INEXACT	0x0001
+#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | \
+			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/*
+ * RISC-V Rounding modes
+ */
+#define	_ROUND_SHIFT	5
+#define	FE_TONEAREST	(0x00 << _ROUND_SHIFT)
+#define	FE_TOWARDZERO	(0x01 << _ROUND_SHIFT)
+#define	FE_DOWNWARD	(0x02 << _ROUND_SHIFT)
+#define	FE_UPWARD	(0x03 << _ROUND_SHIFT)
+#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
+			 FE_UPWARD | FE_TOWARDZERO)
+
+__BEGIN_DECLS
+
+/* Default floating-point environment */
+extern const fenv_t	__fe_dfl_env;
+#define	FE_DFL_ENV	(&__fe_dfl_env)
+
+#if !defined(__riscv_float_abi_soft) && !defined(__riscv_float_abi_double)
+#if defined(__riscv_float_abi_single)
+#error single precision floating point ABI not supported
+#else
+#error compiler did not set soft/hard float macros
+#endif
+#endif
+
+#ifndef __riscv_float_abi_soft
+#define	__rfs(__fcsr)	__asm __volatile("csrr %0, fcsr" : "=r" (__fcsr))
+#define	__wfs(__fcsr)	__asm __volatile("csrw fcsr, %0" :: "r" (__fcsr))
+#endif
+
+#ifdef __riscv_float_abi_soft
+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)
+{
+
+	__asm __volatile("csrc fflags, %0" :: "r"(__excepts));
+
+	return (0);
+}
+
+__fenv_static inline int
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+	fexcept_t __fcsr;
+
+	__rfs(__fcsr);
+	*__flagp = __fcsr & __excepts;
+
+	return (0);
+}
+
+__fenv_static inline int
+fesetexceptflag(const fexcept_t *__flagp, int __excepts)
+{
+	fexcept_t __fcsr;
+
+	__fcsr = *__flagp;
+	__asm __volatile("csrc fflags, %0" :: "r"(__excepts));
+	__asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts));
+
+	return (0);
+}
+
+__fenv_static inline int
+feraiseexcept(int __excepts)
+{
+
+	__asm __volatile("csrs fflags, %0" :: "r"(__excepts));
+
+	return (0);
+}
+
+__fenv_static inline int
+fetestexcept(int __excepts)
+{
+	fexcept_t __fcsr;
+
+	__rfs(__fcsr);
+
+	return (__fcsr & __excepts);
+}
+
+__fenv_static inline int
+fegetround(void)
+{
+	fexcept_t __fcsr;
+
+	__rfs(__fcsr);
+
+	return (__fcsr & _ROUND_MASK);
+}
+
+__fenv_static inline int
+fesetround(int __round)
+{
+	fexcept_t __fcsr;
+
+	if (__round & ~_ROUND_MASK)
+		return (-1);
+
+	__rfs(__fcsr);
+	__fcsr &= ~_ROUND_MASK;
+	__fcsr |= __round;
+	__wfs(__fcsr);
+
+	return (0);
+}
+
+__fenv_static inline int
+fegetenv(fenv_t *__envp)
+{
+
+	__rfs(*__envp);
+
+	return (0);
+}
+
+__fenv_static inline int
+feholdexcept(fenv_t *__envp)
+{
+
+	/* No exception traps. */
+
+	return (-1);
+}
+
+__fenv_static inline int
+fesetenv(const fenv_t *__envp)
+{
+
+	__wfs(*__envp);
+
+	return (0);
+}
+
+__fenv_static inline int
+feupdateenv(const fenv_t *__envp)
+{
+	fexcept_t __fcsr;
+
+	__rfs(__fcsr);
+	__wfs(*__envp);
+	feraiseexcept(__fcsr & FE_ALL_EXCEPT);
+
+	return (0);
+}
+#endif /* !__riscv_float_abi_soft */
+
+#if __BSD_VISIBLE
+
+/* We currently provide no external definitions of the functions below. */
+
+#ifdef __riscv_float_abi_soft
+int feenableexcept(int __mask);
+int fedisableexcept(int __mask);
+int fegetexcept(void);
+#else
+static inline int
+feenableexcept(int __mask)
+{
+
+	/* No exception traps. */
+
+	return (-1);
+}
+
+static inline int
+fedisableexcept(int __mask)
+{
+
+	/* No exception traps. */
+
+	return (0);
+}
+
+static inline int
+fegetexcept(void)
+{
+
+	/* No exception traps. */
+
+	return (0);
+}
+#endif /* !__riscv_float_abi_soft */
+
+#endif /* __BSD_VISIBLE */
+
+__END_DECLS
+
+#endif	/* !_FENV_H_ */

+ 1 - 0
riscv64/Make.files

@@ -0,0 +1 @@
+$(CUR_SRCS) = fenv.c

+ 63 - 0
riscv64/fenv.c

@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/lib/msun/riscv/fenv.c 332792 2018-04-19 20:36:15Z brooks $
+ */
+
+#define	__fenv_static
+#include "fenv.h"
+
+#ifdef __GNUC_GNU_INLINE__
+#error "This file must be compiled with C99 'inline' semantics"
+#endif
+
+/*
+ * Hopefully the system ID byte is immutable, so it's valid to use
+ * this as a default environment.
+ */
+const fenv_t __fe_dfl_env = 0;
+
+#ifdef __riscv_float_abi_soft
+#define __set_env(env, flags, mask, rnd) env = ((flags) | (rnd) << 5)
+#define __env_flags(env)                ((env) & FE_ALL_EXCEPT)
+#define __env_mask(env)                 (0) /* No exception traps. */
+#define __env_round(env)                (((env) >> 5) & _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);
+extern inline int feraiseexcept(int __excepts);
+extern inline int fetestexcept(int __excepts);
+extern inline int fegetround(void);
+extern inline int fesetround(int __round);
+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);

+ 2 - 0
src/fpmath.h

@@ -43,6 +43,8 @@
 #include "mips_fpmath.h"
 #elif defined(__s390__)
 #include "s390_fpmath.h"
+#elif defined(__riscv)
+#include "riscv_fpmath.h"
 #endif
 
 /* Definitions provided directly by GCC and Clang. */

+ 58 - 0
src/riscv_fpmath.h

@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: head/lib/libc/riscv/_fpmath.h 362788 2020-06-29 19:30:35Z mhorne $
+ */
+
+union IEEEl2bits {
+	long double	e;
+	struct {
+		unsigned long	manl	:64;
+		unsigned long	manh	:48;
+		unsigned int	exp	:15;
+		unsigned int	sign	:1;
+	} bits;
+	struct {
+		unsigned long	manl	:64;
+		unsigned long	manh	:48;
+		unsigned int	expsign	:16;
+	} xbits;
+};
+
+#define	LDBL_NBIT	0
+#define	LDBL_IMPLICIT_NBIT
+#define	mask_nbit_l(u)	((void)0)
+
+#define	LDBL_MANH_SIZE	48
+#define	LDBL_MANL_SIZE	64
+
+#define	LDBL_TO_ARRAY32(u, a) do {			\
+	(a)[0] = (uint32_t)(u).bits.manl;		\
+	(a)[1] = (uint32_t)((u).bits.manl >> 32);	\
+	(a)[2] = (uint32_t)(u).bits.manh;		\
+	(a)[3] = (uint32_t)((u).bits.manh >> 32);	\
+} while(0)
+