Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108392565
D8529.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
52 KB
Referenced Files
None
Subscribers
None
D8529.diff
View Options
Index: head/Makefile
===================================================================
--- head/Makefile
+++ head/Makefile
@@ -239,7 +239,7 @@
_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}
Index: head/Makefile.inc1
===================================================================
--- head/Makefile.inc1
+++ head/Makefile.inc1
@@ -364,6 +364,7 @@
powerpc64/powerpc \
powerpcspe/powerpc \
riscv64/riscv \
+ riscv64sf/riscv \
sparc64
.if ${TARGET} == ${TARGET_ARCH}
Index: head/gnu/usr.bin/cc/Makefile.tgt
===================================================================
--- head/gnu/usr.bin/cc/Makefile.tgt
+++ head/gnu/usr.bin/cc/Makefile.tgt
@@ -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
Index: head/lib/libc/Makefile
===================================================================
--- head/lib/libc/Makefile
+++ head/lib/libc/Makefile
@@ -111,7 +111,8 @@
.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"
Index: head/lib/libc/riscv/Makefile.inc
===================================================================
--- head/lib/libc/riscv/Makefile.inc
+++ head/lib/libc/riscv/Makefile.inc
@@ -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
Index: head/lib/libc/riscv/Symbol.map
===================================================================
--- head/lib/libc/riscv/Symbol.map
+++ head/lib/libc/riscv/Symbol.map
@@ -35,4 +35,22 @@
_set_tp;
_end;
__makecontext;
+
+ /* softfloat */
+ __addsf3;
+ __adddf3;
+ __subsf3;
+ __subdf3;
+ __mulsf3;
+ __muldf3;
+ __divsf3;
+ __divdf3;
+ __floatsisf;
+ __floatsidf;
+ __fixsfsi;
+ __fixdfsi;
+ __fixunssfsi;
+ __fixunsdfsi;
+ __extendsfdf2;
+ __truncdfsf2;
};
Index: head/lib/libc/riscv/gen/_setjmp.S
===================================================================
--- head/lib/libc/riscv/gen/_setjmp.S
+++ head/lib/libc/riscv/gen/_setjmp.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -61,25 +61,22 @@
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 @@
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
Index: head/lib/libc/riscv/gen/flt_rounds.c
===================================================================
--- head/lib/libc/riscv/gen/flt_rounds.c
+++ head/lib/libc/riscv/gen/flt_rounds.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -40,23 +40,24 @@
#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:
Index: head/lib/libc/riscv/gen/setjmp.S
===================================================================
--- head/lib/libc/riscv/gen/setjmp.S
+++ head/lib/libc/riscv/gen/setjmp.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -75,21 +75,20 @@
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 @@
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
Index: head/lib/libc/riscv/softfloat/milieu.h
===================================================================
--- head/lib/libc/riscv/softfloat/milieu.h
+++ head/lib/libc/riscv/softfloat/milieu.h
@@ -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
+};
Index: head/lib/libc/riscv/softfloat/riscv-gcc.h
===================================================================
--- head/lib/libc/riscv/softfloat/riscv-gcc.h
+++ head/lib/libc/riscv/softfloat/riscv-gcc.h
@@ -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
Index: head/lib/libc/riscv/softfloat/softfloat.h
===================================================================
--- head/lib/libc/riscv/softfloat/softfloat.h
+++ head/lib/libc/riscv/softfloat/softfloat.h
@@ -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
+
Index: head/lib/libc/softfloat/Makefile.inc
===================================================================
--- head/lib/libc/softfloat/Makefile.inc
+++ head/lib/libc/softfloat/Makefile.inc
@@ -12,8 +12,11 @@
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 \
Index: head/lib/libcompiler_rt/Makefile.inc
===================================================================
--- head/lib/libcompiler_rt/Makefile.inc
+++ head/lib/libcompiler_rt/Makefile.inc
@@ -125,7 +125,7 @@
#
# 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+= 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
Index: head/lib/msun/riscv/Makefile.inc
===================================================================
--- head/lib/msun/riscv/Makefile.inc
+++ head/lib/msun/riscv/Makefile.inc
@@ -1,3 +1,8 @@
# $FreeBSD$
+.if ${MACHINE_ARCH:Mriscv*sf} != ""
+CFLAGS+=-DSOFTFLOAT
+.endif
+
LDBL_PREC = 113
+SYM_MAPS += ${.CURDIR}/riscv/Symbol.map
Index: head/lib/msun/riscv/Symbol.map
===================================================================
--- head/lib/msun/riscv/Symbol.map
+++ head/lib/msun/riscv/Symbol.map
@@ -0,0 +1,21 @@
+/*
+ * $FreeBSD$
+ */
+FBSD_1.0 {
+};
+
+FBSD_1.3 {
+ feclearexcept;
+ fegetexceptflag;
+ fesetexceptflag;
+ feraiseexcept;
+ fetestexcept;
+ fegetround;
+ fesetround;
+ fegetenv;
+ feholdexcept;
+ feupdateenv;
+ feenableexcept;
+ fedisableexcept;
+ fegetexcept;
+};
Index: head/lib/msun/riscv/fenv.h
===================================================================
--- head/lib/msun/riscv/fenv.h
+++ head/lib/msun/riscv/fenv.h
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -59,11 +59,11 @@
/*
* 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 @@
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);
}
__fenv_static inline int
fegetenv(fenv_t *__envp)
{
- __rfs(__envp);
+ __rfs(*__envp);
+
return (0);
}
__fenv_static inline int
feholdexcept(fenv_t *__envp)
{
- fenv_t __env;
- __rfs(&__env);
- *__envp = __env;
- __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
- __wfs(__env);
- return (0);
+ /* No exception traps. */
+
+ return (-1);
}
__fenv_static inline int
@@ -170,56 +191,59 @@
{
__wfs(*__envp);
+
return (0);
}
__fenv_static inline int
feupdateenv(const fenv_t *__envp)
{
- fexcept_t __fpsr;
+ fexcept_t __fcsr;
- __rfs(&__fpsr);
+ __rfs(__fcsr);
__wfs(*__envp);
- feraiseexcept(__fpsr & FE_ALL_EXCEPT);
+ feraiseexcept(__fcsr & 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;
- fenv_t __new_fpsr;
- __rfs(&__old_fpsr);
- __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
- __wfs(__new_fpsr);
- return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+ /* No exception traps. */
+
+ return (-1);
}
static inline int
fedisableexcept(int __mask)
{
- fenv_t __old_fpsr;
- fenv_t __new_fpsr;
- __rfs(&__old_fpsr);
- __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
- __wfs(__new_fpsr);
- return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+ /* No exception traps. */
+
+ return (0);
}
static inline int
fegetexcept(void)
{
- fenv_t __fpsr;
- __rfs(&__fpsr);
- return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
+ /* No exception traps. */
+
+ return (0);
}
+#endif /* !SOFTFLOAT */
#endif /* __BSD_VISIBLE */
Index: head/lib/msun/riscv/fenv.c
===================================================================
--- head/lib/msun/riscv/fenv.c
+++ head/lib/msun/riscv/fenv.c
@@ -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 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);
Index: head/share/mk/bsd.cpu.mk
===================================================================
--- head/share/mk/bsd.cpu.mk
+++ head/share/mk/bsd.cpu.mk
@@ -155,8 +155,6 @@
# sb1, xlp, xlr
_CPUCFLAGS = -march=${CPUTYPE:S/^mips//}
. endif
-. elif ${MACHINE_CPUARCH} == "riscv"
-_CPUCFLAGS = -mno-float -march="IMAFD"
. elif ${MACHINE_ARCH} == "sparc64"
. if ${CPUTYPE} == "v9"
_CPUCFLAGS = -mcpu=v9
@@ -350,9 +348,11 @@
.endif
.if ${MACHINE_CPUARCH} == "riscv"
+.if ${TARGET_ARCH:Mriscv*sf}
CFLAGS += -mno-float
ACFLAGS += -mno-float
.endif
+.endif
# NB: COPTFLAGS is handled in /usr/src/sys/conf/kern.pre.mk
Index: head/share/mk/local.meta.sys.mk
===================================================================
--- head/share/mk/local.meta.sys.mk
+++ head/share/mk/local.meta.sys.mk
@@ -48,7 +48,7 @@
TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipsn32el
TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe
TARGET_ARCHES_pc98?= i386
-TARGET_ARCHES_riscv?= riscv64
+TARGET_ARCHES_riscv?= riscv64 riscv64sf
# some corner cases
BOOT_MACHINE_DIR.amd64 = boot/i386
Index: head/share/mk/src.opts.mk
===================================================================
--- head/share/mk/src.opts.mk
+++ head/share/mk/src.opts.mk
@@ -236,16 +236,16 @@
__DEFAULT_NO_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_FULL CLANG_IS_CC
.endif
# In-tree binutils/gcc are older versions without modern architecture support.
-.if ${__T} == "aarch64" || ${__T} == "riscv64"
+.if ${__T} == "aarch64" || ${__T:Mriscv*} != ""
BROKEN_OPTIONS+=BINUTILS BINUTILS_BOOTSTRAP GCC GCC_BOOTSTRAP GDB
.endif
-.if ${__T} == "riscv64"
+.if ${__T:Mriscv*} != ""
BROKEN_OPTIONS+=PROFILE # "sorry, unimplemented: profiler support for RISC-V"
BROKEN_OPTIONS+=TESTS # "undefined reference to `_Unwind_Resume'"
BROKEN_OPTIONS+=CXX # "libcxxrt.so: undefined reference to `_Unwind_Resume_or_Rethrow'"
.endif
.if ${__T} == "aarch64" || ${__T} == "amd64" || ${__T} == "i386" || \
- ${__T} == "riscv64"
+ ${__T:Mriscv*} != ""
__DEFAULT_YES_OPTIONS+=LLVM_LIBUNWIND
.else
__DEFAULT_NO_OPTIONS+=LLVM_LIBUNWIND
Index: head/share/mk/sys.mk
===================================================================
--- head/share/mk/sys.mk
+++ head/share/mk/sys.mk
@@ -13,7 +13,7 @@
# 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)?(hf)?/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(sf)?/riscv/}
.endif
Index: head/sys/conf/options.riscv
===================================================================
--- head/sys/conf/options.riscv
+++ head/sys/conf/options.riscv
@@ -1,4 +1,4 @@
# $FreeBSD$
RISCV opt_global.h
-VFP opt_global.h
+FPE opt_global.h
Index: head/sys/modules/dtrace/dtrace/Makefile
===================================================================
--- head/sys/modules/dtrace/dtrace/Makefile
+++ head/sys/modules/dtrace/dtrace/Makefile
@@ -60,7 +60,11 @@
.if ${MACHINE_CPUARCH} == "riscv"
assym.o: assym.s
+.if ${TARGET_ARCH:Mriscv*sf}
${AS} -mfloat-abi=soft -o assym.o assym.s
+.else
+ ${AS} -mfloat-abi=double -o assym.o assym.s
+.endif
.endif
.include <bsd.kmod.mk>
Index: head/sys/riscv/conf/GENERIC
===================================================================
--- head/sys/riscv/conf/GENERIC
+++ head/sys/riscv/conf/GENERIC
@@ -69,7 +69,7 @@
options MAC # TrustedBSD MAC Framework
options KDTRACE_FRAME # Ensure frames are compiled in
options KDTRACE_HOOKS # Kernel DTrace hooks
-# options VFP # Floating-point support
+options FPE # Floating-point extension support
options RACCT # Resource accounting framework
options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default
options RCTL # Resource limits
Index: head/sys/riscv/include/fpe.h
===================================================================
--- head/sys/riscv/include/fpe.h
+++ head/sys/riscv/include/fpe.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was 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.
+ *
+ * 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$
+ */
+
+#ifndef _MACHINE_FPE_H_
+#define _MACHINE_FPE_H_
+
+void fpe_state_save(struct thread *td);
+
+#endif /* !_MACHINE_FPE_H_ */
Index: head/sys/riscv/include/pcb.h
===================================================================
--- head/sys/riscv/include/pcb.h
+++ head/sys/riscv/include/pcb.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -42,16 +42,21 @@
struct trapframe;
struct pcb {
- uint64_t pcb_ra;
- uint64_t pcb_sp;
- uint64_t pcb_gp;
- uint64_t pcb_tp;
- uint64_t pcb_t[7];
- uint64_t pcb_s[12];
- uint64_t pcb_a[8];
- uint64_t pcb_sepc;
+ uint64_t pcb_ra; /* Return address */
+ uint64_t pcb_sp; /* Stack pointer */
+ uint64_t pcb_gp; /* Global pointer */
+ uint64_t pcb_tp; /* Thread pointer */
+ uint64_t pcb_t[7]; /* Temporary registers */
+ uint64_t pcb_s[12]; /* Saved registers */
+ uint64_t pcb_a[8]; /* Argument registers */
+ uint64_t pcb_x[32][2]; /* Floating point registers */
+ uint64_t pcb_fcsr; /* Floating point control reg */
+ uint64_t pcb_fpflags; /* Floating point flags */
+#define PCB_FP_STARTED 0x1
+#define PCB_FP_USERMASK 0x1
+ uint64_t pcb_sepc; /* Supervisor exception pc */
vm_offset_t pcb_l1addr; /* L1 page tables base address */
- vm_offset_t pcb_onfault;
+ vm_offset_t pcb_onfault; /* Copyinout fault handler */
};
#ifdef _KERNEL
Index: head/sys/riscv/include/reg.h
===================================================================
--- head/sys/riscv/include/reg.h
+++ head/sys/riscv/include/reg.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -50,7 +50,8 @@
};
struct fpreg {
- int dummy;
+ uint64_t fp_x[32][2]; /* Floating point registers */
+ uint64_t fp_fcsr; /* Floating point control reg */
};
struct dbreg {
Index: head/sys/riscv/include/riscvreg.h
===================================================================
--- head/sys/riscv/include/riscvreg.h
+++ head/sys/riscv/include/riscvreg.h
@@ -60,10 +60,14 @@
#define SSTATUS_SPIE_SHIFT 5
#define SSTATUS_SPP (1 << 8)
#define SSTATUS_SPP_SHIFT 8
-#define SSTATUS_FS_MASK 0x3
#define SSTATUS_FS_SHIFT 13
-#define SSTATUS_XS_MASK 0x3
+#define SSTATUS_FS_OFF (0x0 << SSTATUS_FS_SHIFT)
+#define SSTATUS_FS_INITIAL (0x1 << SSTATUS_FS_SHIFT)
+#define SSTATUS_FS_CLEAN (0x2 << SSTATUS_FS_SHIFT)
+#define SSTATUS_FS_DIRTY (0x3 << SSTATUS_FS_SHIFT)
+#define SSTATUS_FS_MASK (0x3 << SSTATUS_FS_SHIFT)
#define SSTATUS_XS_SHIFT 15
+#define SSTATUS_XS_MASK (0x3 << SSTATUS_XS_SHIFT)
#define SSTATUS_PUM (1 << 18)
#define SSTATUS32_SD (1 << 63)
#define SSTATUS64_SD (1 << 31)
Index: head/sys/riscv/riscv/genassym.c
===================================================================
--- head/sys/riscv/riscv/genassym.c
+++ head/sys/riscv/riscv/genassym.c
@@ -72,6 +72,8 @@
ASSYM(PCB_T, offsetof(struct pcb, pcb_t));
ASSYM(PCB_S, offsetof(struct pcb, pcb_s));
ASSYM(PCB_A, offsetof(struct pcb, pcb_a));
+ASSYM(PCB_X, offsetof(struct pcb, pcb_x));
+ASSYM(PCB_FCSR, offsetof(struct pcb, pcb_fcsr));
ASSYM(SF_UC, offsetof(struct sigframe, sf_uc));
Index: head/sys/riscv/riscv/machdep.c
===================================================================
--- head/sys/riscv/riscv/machdep.c
+++ head/sys/riscv/riscv/machdep.c
@@ -84,8 +84,8 @@
#include <machine/asm.h>
-#ifdef VFP
-#include <machine/vfp.h>
+#ifdef FPE
+#include <machine/fpe.h>
#endif
#ifdef FDT
@@ -203,17 +203,39 @@
int
fill_fpregs(struct thread *td, struct fpreg *regs)
{
+#ifdef FPE
+ struct pcb *pcb;
+
+ pcb = td->td_pcb;
+
+ if ((pcb->pcb_fpflags & PCB_FP_STARTED) != 0) {
+ /*
+ * If we have just been running FPE instructions we will
+ * need to save the state to memcpy it below.
+ */
+ fpe_state_save(td);
+
+ memcpy(regs->fp_x, pcb->pcb_x, sizeof(regs->fp_x));
+ regs->fp_fcsr = pcb->pcb_fcsr;
+ } else
+#endif
+ memset(regs->fp_x, 0, sizeof(regs->fp_x));
- /* TODO */
- bzero(regs, sizeof(*regs));
return (0);
}
int
set_fpregs(struct thread *td, struct fpreg *regs)
{
+#ifdef FPE
+ struct pcb *pcb;
+
+ pcb = td->td_pcb;
+
+ memcpy(pcb->pcb_x, regs->fp_x, sizeof(regs->fp_x));
+ pcb->pcb_fcsr = regs->fp_fcsr;
+#endif
- /* TODO */
return (0);
}
@@ -259,8 +281,10 @@
exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
struct trapframe *tf;
+ struct pcb *pcb;
tf = td->td_frame;
+ pcb = td->td_pcb;
memset(tf, 0, sizeof(struct trapframe));
@@ -273,6 +297,8 @@
tf->tf_sp = STACKALIGN(stack);
tf->tf_ra = imgp->entry_addr;
tf->tf_sepc = imgp->entry_addr;
+
+ pcb->pcb_fpflags &= ~PCB_FP_STARTED;
}
/* Sanity check these are the same size, they will be memcpy'd to and fro */
@@ -337,13 +363,54 @@
static void
get_fpcontext(struct thread *td, mcontext_t *mcp)
{
- /* TODO */
+#ifdef FPE
+ struct pcb *curpcb;
+
+ critical_enter();
+
+ curpcb = curthread->td_pcb;
+
+ KASSERT(td->td_pcb == curpcb, ("Invalid fpe pcb"));
+
+ if ((curpcb->pcb_fpflags & PCB_FP_STARTED) != 0) {
+ /*
+ * If we have just been running FPE instructions we will
+ * need to save the state to memcpy it below.
+ */
+ fpe_state_save(td);
+
+ KASSERT((curpcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0,
+ ("Non-userspace FPE flags set in get_fpcontext"));
+ memcpy(mcp->mc_fpregs.fp_x, curpcb->pcb_x,
+ sizeof(mcp->mc_fpregs));
+ mcp->mc_fpregs.fp_fcsr = curpcb->pcb_fcsr;
+ mcp->mc_fpregs.fp_flags = curpcb->pcb_fpflags;
+ mcp->mc_flags |= _MC_FP_VALID;
+ }
+
+ critical_exit();
+#endif
}
static void
set_fpcontext(struct thread *td, mcontext_t *mcp)
{
- /* TODO */
+#ifdef FPE
+ struct pcb *curpcb;
+
+ critical_enter();
+
+ if ((mcp->mc_flags & _MC_FP_VALID) != 0) {
+ curpcb = curthread->td_pcb;
+ /* FPE usage is enabled, override registers. */
+ memcpy(curpcb->pcb_x, mcp->mc_fpregs.fp_x,
+ sizeof(mcp->mc_fpregs));
+ curpcb->pcb_fcsr = mcp->mc_fpregs.fp_fcsr;
+ curpcb->pcb_fpflags = mcp->mc_fpregs.fp_flags & PCB_FP_USERMASK;
+ }
+
+ critical_exit();
+#endif
}
void
@@ -572,6 +639,7 @@
proc_linkup0(&proc0, &thread0);
thread0.td_kstack = kstack;
thread0.td_pcb = (struct pcb *)(thread0.td_kstack) - 1;
+ thread0.td_pcb->pcb_fpflags = 0;
thread0.td_frame = &proc0_tf;
pcpup->pc_curpcb = thread0.td_pcb;
}
Index: head/sys/riscv/riscv/mp_machdep.c
===================================================================
--- head/sys/riscv/riscv/mp_machdep.c
+++ head/sys/riscv/riscv/mp_machdep.c
@@ -62,9 +62,6 @@
#include <machine/intr.h>
#include <machine/smp.h>
#include <machine/sbi.h>
-#ifdef VFP
-#include <machine/vfp.h>
-#endif
#ifdef FDT
#include <dev/ofw/openfirm.h>
@@ -242,10 +239,6 @@
/* Start per-CPU event timers. */
cpu_initclocks_ap();
-#ifdef VFP
- /* TODO: init FPU */
-#endif
-
/* Enable interrupts */
intr_enable();
Index: head/sys/riscv/riscv/swtch.S
===================================================================
--- head/sys/riscv/riscv/swtch.S
+++ head/sys/riscv/riscv/swtch.S
@@ -42,6 +42,117 @@
__FBSDID("$FreeBSD$");
+#ifdef FPE
+.macro __fpe_state_save p
+ /*
+ * Enable FPE usage in supervisor mode,
+ * so we can access registers.
+ */
+ li t0, SSTATUS_FS_INITIAL
+ csrs sstatus, t0
+
+ /* Store registers */
+ frcsr t0
+ sd t0, (PCB_FCSR)(\p)
+ fsd f0, (PCB_X + 0 * 16)(\p)
+ fsd f1, (PCB_X + 1 * 16)(\p)
+ fsd f2, (PCB_X + 2 * 16)(\p)
+ fsd f3, (PCB_X + 3 * 16)(\p)
+ fsd f4, (PCB_X + 4 * 16)(\p)
+ fsd f5, (PCB_X + 5 * 16)(\p)
+ fsd f6, (PCB_X + 6 * 16)(\p)
+ fsd f7, (PCB_X + 7 * 16)(\p)
+ fsd f8, (PCB_X + 8 * 16)(\p)
+ fsd f9, (PCB_X + 9 * 16)(\p)
+ fsd f10, (PCB_X + 10 * 16)(\p)
+ fsd f11, (PCB_X + 11 * 16)(\p)
+ fsd f12, (PCB_X + 12 * 16)(\p)
+ fsd f13, (PCB_X + 13 * 16)(\p)
+ fsd f14, (PCB_X + 14 * 16)(\p)
+ fsd f15, (PCB_X + 15 * 16)(\p)
+ fsd f16, (PCB_X + 16 * 16)(\p)
+ fsd f17, (PCB_X + 17 * 16)(\p)
+ fsd f18, (PCB_X + 18 * 16)(\p)
+ fsd f19, (PCB_X + 19 * 16)(\p)
+ fsd f20, (PCB_X + 20 * 16)(\p)
+ fsd f21, (PCB_X + 21 * 16)(\p)
+ fsd f22, (PCB_X + 22 * 16)(\p)
+ fsd f23, (PCB_X + 23 * 16)(\p)
+ fsd f24, (PCB_X + 24 * 16)(\p)
+ fsd f25, (PCB_X + 25 * 16)(\p)
+ fsd f26, (PCB_X + 26 * 16)(\p)
+ fsd f27, (PCB_X + 27 * 16)(\p)
+ fsd f28, (PCB_X + 28 * 16)(\p)
+ fsd f29, (PCB_X + 29 * 16)(\p)
+ fsd f30, (PCB_X + 30 * 16)(\p)
+ fsd f31, (PCB_X + 31 * 16)(\p)
+
+ /* Disable FPE usage in supervisor mode. */
+ li t0, SSTATUS_FS_MASK
+ csrc sstatus, t0
+.endm
+
+.macro __fpe_state_load p
+ /*
+ * Enable FPE usage in supervisor mode,
+ * so we can access registers.
+ */
+ li t0, SSTATUS_FS_INITIAL
+ csrs sstatus, t0
+
+ /* Restore registers */
+ ld t0, (PCB_FCSR)(\p)
+ fscsr t0
+ fld f0, (PCB_X + 0 * 16)(\p)
+ fld f1, (PCB_X + 1 * 16)(\p)
+ fld f2, (PCB_X + 2 * 16)(\p)
+ fld f3, (PCB_X + 3 * 16)(\p)
+ fld f4, (PCB_X + 4 * 16)(\p)
+ fld f5, (PCB_X + 5 * 16)(\p)
+ fld f6, (PCB_X + 6 * 16)(\p)
+ fld f7, (PCB_X + 7 * 16)(\p)
+ fld f8, (PCB_X + 8 * 16)(\p)
+ fld f9, (PCB_X + 9 * 16)(\p)
+ fld f10, (PCB_X + 10 * 16)(\p)
+ fld f11, (PCB_X + 11 * 16)(\p)
+ fld f12, (PCB_X + 12 * 16)(\p)
+ fld f13, (PCB_X + 13 * 16)(\p)
+ fld f14, (PCB_X + 14 * 16)(\p)
+ fld f15, (PCB_X + 15 * 16)(\p)
+ fld f16, (PCB_X + 16 * 16)(\p)
+ fld f17, (PCB_X + 17 * 16)(\p)
+ fld f18, (PCB_X + 18 * 16)(\p)
+ fld f19, (PCB_X + 19 * 16)(\p)
+ fld f20, (PCB_X + 20 * 16)(\p)
+ fld f21, (PCB_X + 21 * 16)(\p)
+ fld f22, (PCB_X + 22 * 16)(\p)
+ fld f23, (PCB_X + 23 * 16)(\p)
+ fld f24, (PCB_X + 24 * 16)(\p)
+ fld f25, (PCB_X + 25 * 16)(\p)
+ fld f26, (PCB_X + 26 * 16)(\p)
+ fld f27, (PCB_X + 27 * 16)(\p)
+ fld f28, (PCB_X + 28 * 16)(\p)
+ fld f29, (PCB_X + 29 * 16)(\p)
+ fld f30, (PCB_X + 30 * 16)(\p)
+ fld f31, (PCB_X + 31 * 16)(\p)
+
+ /* Disable FPE usage in supervisor mode. */
+ li t0, SSTATUS_FS_MASK
+ csrc sstatus, t0
+.endm
+
+/*
+ * void
+ * fpe_state_save(struct thread *td)
+ */
+ENTRY(fpe_state_save)
+ /* Get pointer to PCB */
+ ld a0, TD_PCB(a0)
+ __fpe_state_save a0
+ ret
+END(fpe_state_save)
+#endif /* FPE */
+
/*
* void cpu_throw(struct thread *old, struct thread *new)
*/
@@ -81,8 +192,20 @@
ld s10, (PCB_S + 10 * 8)(x13)
ld s11, (PCB_S + 11 * 8)(x13)
- ret
+#ifdef FPE
+ /* Is FPE enabled for new thread? */
+ ld t0, TD_FRAME(a1)
+ ld t1, (TF_SSTATUS)(t0)
+ li t2, SSTATUS_FS_MASK
+ and t3, t1, t2
+ beqz t3, 1f /* No, skip. */
+
+ /* Restore registers. */
+ __fpe_state_load x13
+1:
+#endif
+ ret
.Lcpu_throw_panic_str:
.asciz "cpu_throw: %p\0"
END(cpu_throw)
@@ -123,6 +246,29 @@
sd s10, (PCB_S + 10 * 8)(x13)
sd s11, (PCB_S + 11 * 8)(x13)
+#ifdef FPE
+ /*
+ * Is FPE enabled and is it in dirty state
+ * for the old thread?
+ */
+ ld t0, TD_FRAME(a0)
+ ld t1, (TF_SSTATUS)(t0)
+ li t2, SSTATUS_FS_MASK
+ and t3, t1, t2
+ li t2, SSTATUS_FS_DIRTY
+ bne t3, t2, 1f /* No, skip. */
+
+ /* Yes, mark FPE state clean and save registers. */
+ li t2, ~SSTATUS_FS_MASK
+ and t3, t1, t2
+ li t2, SSTATUS_FS_CLEAN
+ or t3, t3, t2
+ sd t3, (TF_SSTATUS)(t0)
+
+ __fpe_state_save x13
+1:
+#endif
+
/*
* Restore the saved context.
*/
@@ -171,6 +317,20 @@
ld s9, (PCB_S + 9 * 8)(x13)
ld s10, (PCB_S + 10 * 8)(x13)
ld s11, (PCB_S + 11 * 8)(x13)
+
+#ifdef FPE
+ /* Is FPE enabled for new thread? */
+ ld t0, TD_FRAME(a1)
+ ld t1, (TF_SSTATUS)(t0)
+ li t2, SSTATUS_FS_MASK
+ and t3, t1, t2
+ beqz t3, 1f /* No, skip. */
+
+ /* Restore registers. */
+ __fpe_state_load x13
+1:
+#endif
+
ret
.Lcpu_switch_panic_str:
.asciz "cpu_switch: %p\0"
@@ -269,9 +429,8 @@
sd s10, (PCB_S + 10 * 8)(a0)
sd s11, (PCB_S + 11 * 8)(a0)
- /* Store the VFP registers */
-#ifdef VFP
- /* TODO */
+#ifdef FPE
+ __fpe_state_save a0
#endif
ret
END(savectx)
Index: head/sys/riscv/riscv/trap.c
===================================================================
--- head/sys/riscv/riscv/trap.c
+++ head/sys/riscv/riscv/trap.c
@@ -328,9 +328,11 @@
uint64_t exception;
struct thread *td;
uint64_t sstatus;
+ struct pcb *pcb;
td = curthread;
td->td_frame = frame;
+ pcb = td->td_pcb;
/* Ensure we came from usermode, interrupts disabled */
__asm __volatile("csrr %0, sstatus" : "=&r" (sstatus));
@@ -358,6 +360,17 @@
svc_handler(frame);
break;
case EXCP_ILLEGAL_INSTRUCTION:
+#ifdef FPE
+ if ((pcb->pcb_fpflags & PCB_FP_STARTED) == 0) {
+ /*
+ * May be a FPE trap. Enable FPE usage
+ * for this thread and try again.
+ */
+ frame->tf_sstatus |= SSTATUS_FS_INITIAL;
+ pcb->pcb_fpflags |= PCB_FP_STARTED;
+ break;
+ }
+#endif
call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)frame->tf_sepc);
userret(td, frame);
break;
Index: head/sys/riscv/riscv/vm_machdep.c
===================================================================
--- head/sys/riscv/riscv/vm_machdep.c
+++ head/sys/riscv/riscv/vm_machdep.c
@@ -87,8 +87,8 @@
/* Arguments for child */
tf->tf_a[0] = 0;
tf->tf_a[1] = 0;
- tf->tf_sstatus = (SSTATUS_SPIE);
- tf->tf_sstatus |= (MSTATUS_PRV_U << MSTATUS_SPP_SHIFT);
+ tf->tf_sstatus |= (SSTATUS_SPIE); /* Enable interrupts. */
+ tf->tf_sstatus &= ~(SSTATUS_SPP); /* User mode. */
td2->td_frame = tf;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 25, 10:21 AM (16 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16137723
Default Alt Text
D8529.diff (52 KB)
Attached To
Mode
D8529: Full softfloat and hardfloat support for RISC-V
Attached
Detach File
Event Timeline
Log In to Comment