svn commit: r308731 - in head: . gnu/usr.bin/cc lib/libc lib/libc/riscv lib/libc/riscv/gen lib/libc/riscv/softfloat lib/libc/softfloat lib/libcompiler_rt lib/msun/riscv share/mk sys/conf sys/module...

Ruslan Bukin br at FreeBSD.org
Wed Nov 16 15:21:35 UTC 2016


Author: br
Date: Wed Nov 16 15:21:32 2016
New Revision: 308731
URL: https://svnweb.freebsd.org/changeset/base/308731

Log:
  Add full softfloat and hardfloat support for RISC-V.
  
  Hardfloat is now default (use riscv64sf as TARGET_ARCH
  for softfloat).
  
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D8529

Added:
  head/lib/libc/riscv/softfloat/
  head/lib/libc/riscv/softfloat/milieu.h   (contents, props changed)
  head/lib/libc/riscv/softfloat/riscv-gcc.h   (contents, props changed)
  head/lib/libc/riscv/softfloat/softfloat.h   (contents, props changed)
  head/lib/msun/riscv/Symbol.map   (contents, props changed)
  head/sys/riscv/include/fpe.h   (contents, props changed)
Modified:
  head/Makefile
  head/Makefile.inc1
  head/gnu/usr.bin/cc/Makefile.tgt
  head/lib/libc/Makefile
  head/lib/libc/riscv/Makefile.inc
  head/lib/libc/riscv/Symbol.map
  head/lib/libc/riscv/gen/_setjmp.S
  head/lib/libc/riscv/gen/flt_rounds.c
  head/lib/libc/riscv/gen/setjmp.S
  head/lib/libc/softfloat/Makefile.inc
  head/lib/libcompiler_rt/Makefile.inc
  head/lib/msun/riscv/Makefile.inc
  head/lib/msun/riscv/fenv.c
  head/lib/msun/riscv/fenv.h
  head/share/mk/bsd.cpu.mk
  head/share/mk/local.meta.sys.mk
  head/share/mk/src.opts.mk
  head/share/mk/sys.mk
  head/sys/conf/options.riscv
  head/sys/modules/dtrace/dtrace/Makefile
  head/sys/riscv/conf/GENERIC
  head/sys/riscv/include/pcb.h
  head/sys/riscv/include/reg.h
  head/sys/riscv/include/riscvreg.h
  head/sys/riscv/riscv/genassym.c
  head/sys/riscv/riscv/machdep.c
  head/sys/riscv/riscv/mp_machdep.c
  head/sys/riscv/riscv/swtch.S
  head/sys/riscv/riscv/trap.c
  head/sys/riscv/riscv/vm_machdep.c

Modified: head/Makefile
==============================================================================
--- head/Makefile	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/Makefile	Wed Nov 16 15:21:32 2016	(r308731)
@@ -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)?(hf)?/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(sf)?/riscv/}
 .endif
 .if defined(TARGET) && !defined(_TARGET)
 _TARGET=${TARGET}

Modified: head/Makefile.inc1
==============================================================================
--- head/Makefile.inc1	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/Makefile.inc1	Wed Nov 16 15:21:32 2016	(r308731)
@@ -364,6 +364,7 @@ KNOWN_ARCHES?=	aarch64/arm64 \
 		powerpc64/powerpc \
 		powerpcspe/powerpc \
 		riscv64/riscv \
+		riscv64sf/riscv \
 		sparc64
 
 .if ${TARGET} == ${TARGET_ARCH}

Modified: head/gnu/usr.bin/cc/Makefile.tgt
==============================================================================
--- head/gnu/usr.bin/cc/Makefile.tgt	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/gnu/usr.bin/cc/Makefile.tgt	Wed Nov 16 15:21:32 2016	(r308731)
@@ -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)?(hf)?/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/:C/riscv64(sf)?/riscv64/}
 .else
 TARGET_CPUARCH=${MACHINE_CPUARCH}
 .endif

Modified: head/lib/libc/Makefile
==============================================================================
--- head/lib/libc/Makefile	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/libc/Makefile	Wed Nov 16 15:21:32 2016	(r308731)
@@ -111,7 +111,8 @@ NOASM=
 .include "${LIBC_SRCTOP}/xdr/Makefile.inc"
 .if (${LIBC_ARCH} == "arm" && \
 	(${MACHINE_ARCH:Marmv6*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \
-     (${LIBC_ARCH} == "mips" && ${MACHINE_ARCH:Mmips*hf} == "")
+    (${LIBC_ARCH} == "mips" && ${MACHINE_ARCH:Mmips*hf} == "") || \
+    (${LIBC_ARCH} == "riscv" && ${MACHINE_ARCH:Mriscv*sf} != "")
 .include "${LIBC_SRCTOP}/softfloat/Makefile.inc"
 .endif
 .if ${LIBC_ARCH} == "i386" || ${LIBC_ARCH} == "amd64"

Modified: head/lib/libc/riscv/Makefile.inc
==============================================================================
--- head/lib/libc/riscv/Makefile.inc	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/libc/riscv/Makefile.inc	Wed Nov 16 15:21:32 2016	(r308731)
@@ -3,6 +3,10 @@
 # Machine dependent definitions for the RISC-V architecture.
 #
 
+.if ${MACHINE_ARCH:Mriscv*sf} != ""
+CFLAGS+=-DSOFTFLOAT
+.endif
+
 # Long double is quad precision
 GDTOASRCS+=strtorQ.c
 MDSRCS+=machdep_ldisQ.c

Modified: head/lib/libc/riscv/Symbol.map
==============================================================================
--- head/lib/libc/riscv/Symbol.map	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/libc/riscv/Symbol.map	Wed Nov 16 15:21:32 2016	(r308731)
@@ -35,4 +35,22 @@ FBSDprivate_1.0 {
 	_set_tp;
 	_end;
 	__makecontext;
+
+	/* softfloat */
+	__addsf3;
+	__adddf3;
+	__subsf3;
+	__subdf3;
+	__mulsf3;
+	__muldf3;
+	__divsf3;
+	__divdf3;
+	__floatsisf;
+	__floatsidf;
+	__fixsfsi;
+	__fixdfsi;
+	__fixunssfsi;
+	__fixunsdfsi;
+	__extendsfdf2;
+	__truncdfsf2;
 };

Modified: head/lib/libc/riscv/gen/_setjmp.S
==============================================================================
--- head/lib/libc/riscv/gen/_setjmp.S	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/libc/riscv/gen/_setjmp.S	Wed Nov 16 15:21:32 2016	(r308731)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -61,25 +61,22 @@ ENTRY(_setjmp)
 	sd	ra, (12 * 8)(a0)
 	addi	a0, a0, (13 * 8)
 
-#ifndef _STANDALONE
-#if 0
-	/* RISCVTODO */
-	/* Store the vfp registers */
-	fsq	fs0, (0 * 16)(a0)
-	fsq	fs1, (1 * 16)(a0)
-	fsq	fs2, (2 * 16)(a0)
-	fsq	fs3, (3 * 16)(a0)
-	fsq	fs4, (4 * 16)(a0)
-	fsq	fs5, (5 * 16)(a0)
-	fsq	fs6, (6 * 16)(a0)
-	fsq	fs7, (7 * 16)(a0)
-	fsq	fs8, (8 * 16)(a0)
-	fsq	fs9, (9 * 16)(a0)
-	fsq	fs10, (10 * 16)(a0)
-	fsq	fs11, (11 * 16)(a0)
+#if !defined(_STANDALONE) && !defined(SOFTFLOAT)
+	/* Store the fpe registers */
+	fsd	fs0, (0 * 16)(a0)
+	fsd	fs1, (1 * 16)(a0)
+	fsd	fs2, (2 * 16)(a0)
+	fsd	fs3, (3 * 16)(a0)
+	fsd	fs4, (4 * 16)(a0)
+	fsd	fs5, (5 * 16)(a0)
+	fsd	fs6, (6 * 16)(a0)
+	fsd	fs7, (7 * 16)(a0)
+	fsd	fs8, (8 * 16)(a0)
+	fsd	fs9, (9 * 16)(a0)
+	fsd	fs10, (10 * 16)(a0)
+	fsd	fs11, (11 * 16)(a0)
 	addi	a0, a0, (12 * 16)
 #endif
-#endif
 
 	/* Return value */
 	li	a0, 0
@@ -117,25 +114,22 @@ ENTRY(_longjmp)
 	ld	ra, (12 * 8)(a0)
 	addi	a0, a0, (13 * 8)
 
-#ifndef _STANDALONE
-#if 0
-	/* RISCVTODO */
-	/* Restore the vfp registers */
-	flq	fs0, (0 * 16)(a0)
-	flq	fs1, (1 * 16)(a0)
-	flq	fs2, (2 * 16)(a0)
-	flq	fs3, (3 * 16)(a0)
-	flq	fs4, (4 * 16)(a0)
-	flq	fs5, (5 * 16)(a0)
-	flq	fs6, (6 * 16)(a0)
-	flq	fs7, (7 * 16)(a0)
-	flq	fs8, (8 * 16)(a0)
-	flq	fs9, (9 * 16)(a0)
-	flq	fs10, (10 * 16)(a0)
-	flq	fs11, (11 * 16)(a0)
+#if !defined(_STANDALONE) && !defined(SOFTFLOAT)
+	/* Restore the fpe registers */
+	fld	fs0, (0 * 16)(a0)
+	fld	fs1, (1 * 16)(a0)
+	fld	fs2, (2 * 16)(a0)
+	fld	fs3, (3 * 16)(a0)
+	fld	fs4, (4 * 16)(a0)
+	fld	fs5, (5 * 16)(a0)
+	fld	fs6, (6 * 16)(a0)
+	fld	fs7, (7 * 16)(a0)
+	fld	fs8, (8 * 16)(a0)
+	fld	fs9, (9 * 16)(a0)
+	fld	fs10, (10 * 16)(a0)
+	fld	fs11, (11 * 16)(a0)
 	addi	a0, a0, (12 * 16)
 #endif
-#endif
 
 	/* Load the return value */
 	mv	a0, a1

Modified: head/lib/libc/riscv/gen/flt_rounds.c
==============================================================================
--- head/lib/libc/riscv/gen/flt_rounds.c	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/libc/riscv/gen/flt_rounds.c	Wed Nov 16 15:21:32 2016	(r308731)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -40,23 +40,24 @@ __FBSDID("$FreeBSD$");
 #include <fenv.h>
 #include <float.h>
 
+#ifdef	SOFTFLOAT
+#include "softfloat-for-gcc.h"
+#include "milieu.h"
+#include "softfloat.h"
+#endif
+
 int
 __flt_rounds(void)
 {
-#if 0
-	uint64_t fcsr;
-#endif
-	int mode;
+	uint64_t mode;
 
-#if 0
-	__asm __volatile("csrr    %0, fcsr" : "=r" (fcsr));
-	mode = (fcsr & _ROUND_MASK);
+#ifdef SOFTFLOAT
+	mode = __softfloat_float_rounding_mode;
+#else
+	__asm __volatile("csrr %0, fcsr" : "=r" (mode));
 #endif
 
-	/* RISCVTODO */
-	mode = FE_TOWARDZERO; /* softfloat rounding mode */
-
-	switch (mode) {
+	switch (mode & _ROUND_MASK) {
 	case FE_TOWARDZERO:
 		return (0);
 	case FE_TONEAREST:

Modified: head/lib/libc/riscv/gen/setjmp.S
==============================================================================
--- head/lib/libc/riscv/gen/setjmp.S	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/libc/riscv/gen/setjmp.S	Wed Nov 16 15:21:32 2016	(r308731)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -75,21 +75,20 @@ ENTRY(setjmp)
 	sd	ra, (12 * 8)(a0)
 	addi	a0, a0, (13 * 8)
 
-#if 0
-	/* RISCVTODO */
-	/* Store the vfp registers */
-	fsq	fs0, (0 * 16)(a0)
-	fsq	fs1, (1 * 16)(a0)
-	fsq	fs2, (2 * 16)(a0)
-	fsq	fs3, (3 * 16)(a0)
-	fsq	fs4, (4 * 16)(a0)
-	fsq	fs5, (5 * 16)(a0)
-	fsq	fs6, (6 * 16)(a0)
-	fsq	fs7, (7 * 16)(a0)
-	fsq	fs8, (8 * 16)(a0)
-	fsq	fs9, (9 * 16)(a0)
-	fsq	fs10, (10 * 16)(a0)
-	fsq	fs11, (11 * 16)(a0)
+#ifndef SOFTFLOAT
+	/* Store the fpe registers */
+	fsd	fs0, (0 * 16)(a0)
+	fsd	fs1, (1 * 16)(a0)
+	fsd	fs2, (2 * 16)(a0)
+	fsd	fs3, (3 * 16)(a0)
+	fsd	fs4, (4 * 16)(a0)
+	fsd	fs5, (5 * 16)(a0)
+	fsd	fs6, (6 * 16)(a0)
+	fsd	fs7, (7 * 16)(a0)
+	fsd	fs8, (8 * 16)(a0)
+	fsd	fs9, (9 * 16)(a0)
+	fsd	fs10, (10 * 16)(a0)
+	fsd	fs11, (11 * 16)(a0)
 	addi	a0, a0, (12 * 16)
 #endif
 
@@ -145,21 +144,20 @@ ENTRY(longjmp)
 	ld	ra, (12 * 8)(a0)
 	addi	a0, a0, (13 * 8)
 
-#if 0
-	/* RISCVTODO */
-	/* Restore the vfp registers */
-	flq	fs0, (0 * 16)(a0)
-	flq	fs1, (1 * 16)(a0)
-	flq	fs2, (2 * 16)(a0)
-	flq	fs3, (3 * 16)(a0)
-	flq	fs4, (4 * 16)(a0)
-	flq	fs5, (5 * 16)(a0)
-	flq	fs6, (6 * 16)(a0)
-	flq	fs7, (7 * 16)(a0)
-	flq	fs8, (8 * 16)(a0)
-	flq	fs9, (9 * 16)(a0)
-	flq	fs10, (10 * 16)(a0)
-	flq	fs11, (11 * 16)(a0)
+#ifndef SOFTFLOAT
+	/* Restore the fpe registers */
+	fld	fs0, (0 * 16)(a0)
+	fld	fs1, (1 * 16)(a0)
+	fld	fs2, (2 * 16)(a0)
+	fld	fs3, (3 * 16)(a0)
+	fld	fs4, (4 * 16)(a0)
+	fld	fs5, (5 * 16)(a0)
+	fld	fs6, (6 * 16)(a0)
+	fld	fs7, (7 * 16)(a0)
+	fld	fs8, (8 * 16)(a0)
+	fld	fs9, (9 * 16)(a0)
+	fld	fs10, (10 * 16)(a0)
+	fld	fs11, (11 * 16)(a0)
 	addi	a0, a0, (12 * 16)
 #endif
 

Added: head/lib/libc/riscv/softfloat/milieu.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/riscv/softfloat/milieu.h	Wed Nov 16 15:21:32 2016	(r308731)
@@ -0,0 +1,48 @@
+/* $FreeBSD$ */
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2a.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/SoftFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Include common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+#include "riscv-gcc.h"
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+    FALSE = 0,
+    TRUE  = 1
+};

Added: head/lib/libc/riscv/softfloat/riscv-gcc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/riscv/softfloat/riscv-gcc.h	Wed Nov 16 15:21:32 2016	(r308731)
@@ -0,0 +1,86 @@
+/* $NetBSD: arm-gcc.h,v 1.2 2001/02/21 18:09:25 bjh21 Exp $ */
+/* $FreeBSD$ */
+
+/*
+-------------------------------------------------------------------------------
+One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
+-------------------------------------------------------------------------------
+*/
+#define LITTLEENDIAN
+
+/*
+-------------------------------------------------------------------------------
+The macro `BITS64' can be defined to indicate that 64-bit integer types are
+supported by the compiler.
+-------------------------------------------------------------------------------
+*/
+#define BITS64
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines the most convenient type that holds
+integers of at least as many bits as specified.  For example, `uint8' should
+be the most convenient type that can hold unsigned integers of as many as
+8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most
+implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
+to the same as `int'.
+-------------------------------------------------------------------------------
+*/
+typedef int flag;
+typedef int uint8;
+typedef int int8;
+typedef int uint16;
+typedef int int16;
+typedef unsigned int uint32;
+typedef signed int int32;
+#ifdef BITS64
+typedef unsigned long long int uint64;
+typedef signed long long int int64;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines a type that holds integers
+of _exactly_ the number of bits specified.  For instance, for most
+implementation of C, `bits16' and `sbits16' should be `typedef'ed to
+`unsigned short int' and `signed short int' (or `short int'), respectively.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned char bits8;
+typedef signed char sbits8;
+typedef unsigned short int bits16;
+typedef signed short int sbits16;
+typedef unsigned int bits32;
+typedef signed int sbits32;
+#ifdef BITS64
+typedef unsigned long long int bits64;
+typedef signed long long int sbits64;
+#endif
+
+#ifdef BITS64
+/*
+-------------------------------------------------------------------------------
+The `LIT64' macro takes as its argument a textual integer literal and
+if necessary ``marks'' the literal as having a 64-bit integer type.
+For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
+appended with the letters `LL' standing for `long long', which is `gcc's
+name for the 64-bit integer type.  Some compilers may allow `LIT64' to be
+defined as the identity macro:  `#define LIT64( a ) a'.
+-------------------------------------------------------------------------------
+*/
+#define LIT64( a ) a##LL
+#endif
+
+/*
+-------------------------------------------------------------------------------
+The macro `INLINE' can be used before functions that should be inlined.  If
+a compiler does not support explicit inlining, this macro should be defined
+to be `static'.
+-------------------------------------------------------------------------------
+*/
+#define INLINE static __inline
+
+#if defined(SOFTFLOAT_FOR_GCC)
+#define FLOAT64_DEMANGLE(a)	(a)
+#define FLOAT64_MANGLE(a)	(a)
+#endif

Added: head/lib/libc/riscv/softfloat/softfloat.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/riscv/softfloat/softfloat.h	Wed Nov 16 15:21:32 2016	(r308731)
@@ -0,0 +1,315 @@
+/*	$NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $	*/
+/* $FreeBSD$ */
+
+/* This is a derivative work. */
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2a.
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/SoftFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+The macro `FLOATX80' must be defined to enable the extended double-precision
+floating-point format `floatx80'.  If this macro is not defined, the
+`floatx80' type will not be defined, and none of the functions that either
+input or output the `floatx80' type will be defined.  The same applies to
+the `FLOAT128' macro and the quadruple-precision format `float128'.
+-------------------------------------------------------------------------------
+*/
+/* #define FLOATX80 */
+/* #define FLOAT128 */
+
+#include <fenv.h>
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point types.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned int float32;
+typedef unsigned long long float64;
+#ifdef FLOATX80
+typedef struct {
+    unsigned short high;
+    unsigned long long low;
+} floatx80;
+#endif
+#ifdef FLOAT128
+typedef struct {
+    unsigned long long high, low;
+} float128;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point underflow tininess-detection mode.
+-------------------------------------------------------------------------------
+*/
+#ifndef SOFTFLOAT_FOR_GCC
+extern int float_detect_tininess;
+#endif
+enum {
+    float_tininess_after_rounding  = 0,
+    float_tininess_before_rounding = 1
+};
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point rounding mode.
+-------------------------------------------------------------------------------
+*/
+extern int float_rounding_mode;
+enum {
+    float_round_nearest_even = FE_TONEAREST,
+    float_round_to_zero      = FE_TOWARDZERO,
+    float_round_down         = FE_DOWNWARD,
+    float_round_up           = FE_UPWARD
+};
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point exception flags.
+-------------------------------------------------------------------------------
+*/
+extern int float_exception_flags;
+extern int float_exception_mask;
+enum {
+    float_flag_inexact   = FE_INEXACT,
+    float_flag_underflow = FE_UNDERFLOW,
+    float_flag_overflow  = FE_OVERFLOW,
+    float_flag_divbyzero = FE_DIVBYZERO,
+    float_flag_invalid   = FE_INVALID
+};
+
+/*
+-------------------------------------------------------------------------------
+Routine to raise any or all of the software IEC/IEEE floating-point
+exception flags.
+-------------------------------------------------------------------------------
+*/
+void float_raise( int );
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE integer-to-floating-point conversion routines.
+-------------------------------------------------------------------------------
+*/
+float32 int32_to_float32( int );
+float64 int32_to_float64( int );
+#ifdef FLOATX80
+floatx80 int32_to_floatx80( int );
+#endif
+#ifdef FLOAT128
+float128 int32_to_float128( int );
+#endif
+#ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */
+float32 int64_to_float32( long long );
+float64 int64_to_float64( long long );
+#ifdef FLOATX80
+floatx80 int64_to_floatx80( long long );
+#endif
+#ifdef FLOAT128
+float128 int64_to_float128( long long );
+#endif
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE single-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+int float32_to_int32( float32 );
+int float32_to_int32_round_to_zero( float32 );
+#if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS)
+unsigned int float32_to_uint32_round_to_zero( float32 );
+#endif
+#ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */
+long long float32_to_int64( float32 );
+long long float32_to_int64_round_to_zero( float32 );
+#endif
+float64 float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 float32_to_float128( float32 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE single-precision operations.
+-------------------------------------------------------------------------------
+*/
+float32 float32_round_to_int( float32 );
+float32 float32_add( float32, float32 );
+float32 float32_sub( float32, float32 );
+float32 float32_mul( float32, float32 );
+float32 float32_div( float32, float32 );
+float32 float32_rem( float32, float32 );
+float32 float32_sqrt( float32 );
+int float32_eq( float32, float32 );
+int float32_le( float32, float32 );
+int float32_lt( float32, float32 );
+int float32_eq_signaling( float32, float32 );
+int float32_le_quiet( float32, float32 );
+int float32_lt_quiet( float32, float32 );
+#ifndef SOFTFLOAT_FOR_GCC
+int float32_is_signaling_nan( float32 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE double-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+int float64_to_int32( float64 );
+int float64_to_int32_round_to_zero( float64 );
+#if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS)
+unsigned int float64_to_uint32_round_to_zero( float64 );
+#endif
+#ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */
+long long float64_to_int64( float64 );
+long long float64_to_int64_round_to_zero( float64 );
+#endif
+float32 float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 float64_to_float128( float64 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE double-precision operations.
+-------------------------------------------------------------------------------
+*/
+float64 float64_round_to_int( float64 );
+float64 float64_add( float64, float64 );
+float64 float64_sub( float64, float64 );
+float64 float64_mul( float64, float64 );
+float64 float64_div( float64, float64 );
+float64 float64_rem( float64, float64 );
+float64 float64_sqrt( float64 );
+int float64_eq( float64, float64 );
+int float64_le( float64, float64 );
+int float64_lt( float64, float64 );
+int float64_eq_signaling( float64, float64 );
+int float64_le_quiet( float64, float64 );
+int float64_lt_quiet( float64, float64 );
+#ifndef SOFTFLOAT_FOR_GCC
+int float64_is_signaling_nan( float64 );
+#endif
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+int floatx80_to_int32( floatx80 );
+int floatx80_to_int32_round_to_zero( floatx80 );
+long long floatx80_to_int64( floatx80 );
+long long floatx80_to_int64_round_to_zero( floatx80 );
+float32 floatx80_to_float32( floatx80 );
+float64 floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 floatx80_to_float128( floatx80 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision rounding precision.  Valid
+values are 32, 64, and 80.
+-------------------------------------------------------------------------------
+*/
+extern int floatx80_rounding_precision;
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision operations.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_round_to_int( floatx80 );
+floatx80 floatx80_add( floatx80, floatx80 );
+floatx80 floatx80_sub( floatx80, floatx80 );
+floatx80 floatx80_mul( floatx80, floatx80 );
+floatx80 floatx80_div( floatx80, floatx80 );
+floatx80 floatx80_rem( floatx80, floatx80 );
+floatx80 floatx80_sqrt( floatx80 );
+int floatx80_eq( floatx80, floatx80 );
+int floatx80_le( floatx80, floatx80 );
+int floatx80_lt( floatx80, floatx80 );
+int floatx80_eq_signaling( floatx80, floatx80 );
+int floatx80_le_quiet( floatx80, floatx80 );
+int floatx80_lt_quiet( floatx80, floatx80 );
+int floatx80_is_signaling_nan( floatx80 );
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE quadruple-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+int float128_to_int32( float128 );
+int float128_to_int32_round_to_zero( float128 );
+long long float128_to_int64( float128 );
+long long float128_to_int64_round_to_zero( float128 );
+float32 float128_to_float32( float128 );
+float64 float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 float128_to_floatx80( float128 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE quadruple-precision operations.
+-------------------------------------------------------------------------------
+*/
+float128 float128_round_to_int( float128 );
+float128 float128_add( float128, float128 );
+float128 float128_sub( float128, float128 );
+float128 float128_mul( float128, float128 );
+float128 float128_div( float128, float128 );
+float128 float128_rem( float128, float128 );
+float128 float128_sqrt( float128 );
+int float128_eq( float128, float128 );
+int float128_le( float128, float128 );
+int float128_lt( float128, float128 );
+int float128_eq_signaling( float128, float128 );
+int float128_le_quiet( float128, float128 );
+int float128_lt_quiet( float128, float128 );
+int float128_is_signaling_nan( float128 );
+
+#endif
+

Modified: head/lib/libc/softfloat/Makefile.inc
==============================================================================
--- head/lib/libc/softfloat/Makefile.inc	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/libc/softfloat/Makefile.inc	Wed Nov 16 15:21:32 2016	(r308731)
@@ -12,8 +12,11 @@ CFLAGS+=	-DSOFTFLOAT_FOR_GCC
 
 SRCS+=		softfloat.c
 
+# Deprecated FPU control interface
+.if ${LIBC_ARCH} != "riscv"
 SRCS+=		fpgetround.c fpsetround.c fpgetmask.c fpsetmask.c \
 		fpgetsticky.c
+.endif
 
 SRCS+=		eqsf2.c nesf2.c gtsf2.c gesf2.c ltsf2.c lesf2.c negsf2.c \
 		eqdf2.c nedf2.c gtdf2.c gedf2.c ltdf2.c ledf2.c negdf2.c \

Modified: head/lib/libcompiler_rt/Makefile.inc
==============================================================================
--- head/lib/libcompiler_rt/Makefile.inc	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/libcompiler_rt/Makefile.inc	Wed Nov 16 15:21:32 2016	(r308731)
@@ -125,7 +125,7 @@ SRCF+=		umodti3
 
 #
 # 128-bit quad precision long double support,
-# only used on arm64 and riscv.
+# only used on some architectures.
 #
 .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "riscv"
 SRCF+=		addtf3
@@ -146,8 +146,9 @@ SRCF+=		trunctfdf2
 SRCF+=		trunctfsf2
 .endif
 
-# These are already shipped by libc.a on arm and mips
-.if ${MACHINE_CPUARCH} != "arm" && ${MACHINE_CPUARCH} != "mips"
+# These are already shipped by libc.a on some architectures.
+.if ${MACHINE_CPUARCH} != "arm" && ${MACHINE_CPUARCH} != "mips" && \
+    ${MACHINE_CPUARCH} != "riscv"
 SRCF+=		adddf3
 SRCF+=		addsf3
 SRCF+=		divdf3

Modified: head/lib/msun/riscv/Makefile.inc
==============================================================================
--- head/lib/msun/riscv/Makefile.inc	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/msun/riscv/Makefile.inc	Wed Nov 16 15:21:32 2016	(r308731)
@@ -1,3 +1,8 @@
 # $FreeBSD$
 
+.if ${MACHINE_ARCH:Mriscv*sf} != ""
+CFLAGS+=-DSOFTFLOAT
+.endif
+
 LDBL_PREC = 113
+SYM_MAPS += ${.CURDIR}/riscv/Symbol.map

Added: head/lib/msun/riscv/Symbol.map
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/msun/riscv/Symbol.map	Wed Nov 16 15:21:32 2016	(r308731)
@@ -0,0 +1,21 @@
+/*
+ * $FreeBSD$
+ */
+FBSD_1.0 {
+};
+
+FBSD_1.3 {
+	feclearexcept;
+	fegetexceptflag;
+	fesetexceptflag;
+	feraiseexcept;
+	fetestexcept;
+	fegetround;
+	fesetround;
+	fegetenv;
+	feholdexcept;
+	feupdateenv;
+	feenableexcept;
+	fedisableexcept;
+	fegetexcept;
+};

Modified: head/lib/msun/riscv/fenv.c
==============================================================================
--- head/lib/msun/riscv/fenv.c	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/msun/riscv/fenv.c	Wed Nov 16 15:21:32 2016	(r308731)
@@ -39,6 +39,14 @@
  */
 const fenv_t __fe_dfl_env = 0;
 
+#ifdef SOFTFLOAT
+#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);
@@ -50,3 +58,6 @@ extern inline int fegetenv(fenv_t *__env
 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);

Modified: head/lib/msun/riscv/fenv.h
==============================================================================
--- head/lib/msun/riscv/fenv.h	Wed Nov 16 14:39:03 2016	(r308730)
+++ head/lib/msun/riscv/fenv.h	Wed Nov 16 15:21:32 2016	(r308731)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2004-2005 David Schultz <das at FreeBSD.ORG>
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -59,11 +59,11 @@ typedef	__uint64_t	fexcept_t;
 /*
  * RISC-V Rounding modes
  */
-#define	FE_TONEAREST	(0x00 << 5)
-#define	FE_TOWARDZERO	(0x01 << 5)
-#define	FE_DOWNWARD	(0x02 << 5)
-#define	FE_UPWARD	(0x03 << 5)
 #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)
 
@@ -73,96 +73,117 @@ __BEGIN_DECLS
 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	0
-#define	_ENABLE_MASK	(FE_ALL_EXCEPT << _FPUSW_SHIFT)
-
-#define	__rfs(__fpsr)	__asm __volatile("csrr %0, fcsr" : "=r" (*(__fpsr)))
-#define	__wfs(__fpsr)	__asm __volatile("csrw fcsr, %0" :: "r" (__fpsr))
+#ifndef SOFTFLOAT
+#define	__rfs(__fcsr)	__asm __volatile("csrr %0, fcsr" : "=r" (__fcsr))
+#define	__wfs(__fcsr)	__asm __volatile("csrw fcsr, %0" :: "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;
 
-	__rfs(&__fpsr);
-	__fpsr &= ~__excepts;
-	__wfs(__fpsr);
+	__asm __volatile("csrc fflags, %0" :: "r"(__excepts));
+
 	return (0);
 }
 
 __fenv_static inline int
 fegetexceptflag(fexcept_t *__flagp, int __excepts)
 {
-	fexcept_t __fpsr;
+	fexcept_t __fcsr;
+
+	__rfs(__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;
+
+	__fcsr = *__flagp;
+	__asm __volatile("csrc fflags, %0" :: "r"(__excepts));
+	__asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts));
 
-	__rfs(&__fpsr);
-	__fpsr &= ~__excepts;
-	__fpsr |= *__flagp & __excepts;
-	__wfs(__fpsr);
 	return (0);
 }
 
 __fenv_static inline int
 feraiseexcept(int __excepts)
 {
-	fexcept_t __ex = __excepts;
 
-	fesetexceptflag(&__ex, __excepts);	/* XXX */
+	__asm __volatile("csrs fflags, %0" :: "r"(__excepts));
+
 	return (0);
 }
 
 __fenv_static inline int
 fetestexcept(int __excepts)
 {
-	fexcept_t __fpsr;
+	fexcept_t __fcsr;
+
+	__rfs(__fcsr);
 
-	__rfs(&__fpsr);
-	return (__fpsr & __excepts);
+	return (__fcsr & __excepts);
 }
 
 __fenv_static inline int
 fegetround(void)
 {
+	fexcept_t __fcsr;
 
-	return (-1);
+	__rfs(__fcsr);
+
+	return (__fcsr & _ROUND_MASK);
 }
 
 __fenv_static inline int
 fesetround(int __round)
 {
+	fexcept_t __fcsr;
 
-	return (-1);
+	if (__round & ~_ROUND_MASK)
+		return (-1);
+
+	__rfs(__fcsr);
+	__fcsr &= ~_ROUND_MASK;
+	__fcsr |= __round;
+	__wfs(__fcsr);
+
+	return (0);
 }

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list