RISC-V: Generic <math.h> and soft-fp Routines

This patch contains the miscellaneous math routines and headers we have
implemented for RISC-V.  This includes things from <math.h> that aren't
completely ISA-generic, floating-point bit manipulation, and soft-fp
hooks.

2018-01-29  Palmer Dabbelt  <palmer@sifive.com>

        * sysdeps/riscv/bits/fenv.h: New file.
        * sysdeps/riscv/e_sqrtl.c: Likewise.
        * sysdeps/riscv/fpu_control.h: Likewise.
        * sysdeps/riscv/math-tests.h: Likewise.
        * sysdeps/riscv/nofpu/Implies: Likewise.
        * sysdeps/riscv/sfp-machine.h: Likewise.
        * sysdeps/riscv/tininess.h: Likewise.
This commit is contained in:
Palmer Dabbelt 2018-01-29 10:26:35 -08:00
parent 337126607f
commit 67236aeb6e
No known key found for this signature in database
GPG Key ID: EF4CA1502CCBAB41
8 changed files with 337 additions and 0 deletions

View File

@ -27,6 +27,13 @@
* sysdeps/riscv/nptl/tcb-offsets.sym: Likewise.
* sysdeps/riscv/nptl/tls.h: Likewise.
* sysdeps/riscv/stackinfo.h: Likewise.
* sysdeps/riscv/bits/fenv.h: New file.
* sysdeps/riscv/e_sqrtl.c: Likewise.
* sysdeps/riscv/fpu_control.h: Likewise.
* sysdeps/riscv/math-tests.h: Likewise.
* sysdeps/riscv/nofpu/Implies: Likewise.
* sysdeps/riscv/sfp-machine.h: Likewise.
* sysdeps/riscv/tininess.h: Likewise.
2018-01-29 Florian Weimer <fweimer@redhat.com>

74
sysdeps/riscv/bits/fenv.h Normal file
View File

@ -0,0 +1,74 @@
/* Floating point environment, RISC-V version.
Copyright (C) 1998-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _FENV_H
# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
#endif
enum
{
FE_INEXACT =
#define FE_INEXACT (0x01)
FE_INEXACT,
FE_UNDERFLOW =
#define FE_UNDERFLOW (0x02)
FE_UNDERFLOW,
FE_OVERFLOW =
#define FE_OVERFLOW (0x04)
FE_OVERFLOW,
FE_DIVBYZERO =
#define FE_DIVBYZERO (0x08)
FE_DIVBYZERO,
FE_INVALID =
#define FE_INVALID (0x10)
FE_INVALID
};
#define FE_ALL_EXCEPT \
(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
enum
{
FE_TONEAREST =
#define FE_TONEAREST (0x0)
FE_TONEAREST,
FE_TOWARDZERO =
#define FE_TOWARDZERO (0x1)
FE_TOWARDZERO,
FE_DOWNWARD =
#define FE_DOWNWARD (0x2)
FE_DOWNWARD,
FE_UPWARD =
#define FE_UPWARD (0x3)
FE_UPWARD
};
typedef unsigned int fexcept_t;
typedef unsigned int fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((__const fenv_t *) -1)
#if __GLIBC_USE (IEC_60559_BFP_EXT)
/* Type representing floating-point control modes. */
typedef unsigned int femode_t;
/* Default floating-point control modes. */
# define FE_DFL_MODE ((const femode_t *) -1L)
#endif

37
sysdeps/riscv/e_sqrtl.c Normal file
View File

@ -0,0 +1,37 @@
/* long double square root in software floating-point emulation.
Copyright (C) 1997-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <stdlib.h>
#include <soft-fp/soft-fp.h>
#include <soft-fp/quad.h>
long double
__ieee754_sqrtl (const long double a)
{
FP_DECL_EX;
FP_DECL_Q (A); FP_DECL_Q (C);
long double c;
FP_INIT_ROUNDMODE;
FP_UNPACK_Q (A, a);
FP_SQRT_Q (C, A);
FP_PACK_Q (c, C);
FP_HANDLE_EXCEPTIONS;
return c;
}
strong_alias (__ieee754_sqrtl, __sqrtl_finite)

View File

@ -0,0 +1,74 @@
/* FPU control word bits. RISC-V version.
Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _FPU_CONTROL_H
#define _FPU_CONTROL_H
#include <features.h>
#ifndef __riscv_flen
# define _FPU_RESERVED 0xffffffff
# define _FPU_DEFAULT 0x00000000
typedef unsigned int fpu_control_t;
# define _FPU_GETCW(cw) (cw) = 0
# define _FPU_SETCW(cw) do { } while (0)
extern fpu_control_t __fpu_control;
#else /* __riscv_flen */
# define _FPU_RESERVED 0
# define _FPU_DEFAULT 0
# define _FPU_IEEE _FPU_DEFAULT
/* Type of the control word. */
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
/* Macros for accessing the hardware control word. */
# define _FPU_GETCW(cw) __asm__ volatile ("frsr %0" : "=r" (cw))
# define _FPU_SETCW(cw) __asm__ volatile ("fssr %z0" : : "rJ" (cw))
/* Default control word set at startup. */
extern fpu_control_t __fpu_control;
# define _FCLASS(x) (__extension__ ({ int __res; \
if (sizeof (x) * 8 > __riscv_flen) __builtin_trap (); \
if (sizeof (x) == 4) asm ("fclass.s %0, %1" : "=r" (__res) : "f" (x)); \
else if (sizeof (x) == 8) asm ("fclass.d %0, %1" : "=r" (__res) : "f" (x)); \
else __builtin_trap (); \
__res; }))
# define _FCLASS_MINF (1 << 0)
# define _FCLASS_MNORM (1 << 1)
# define _FCLASS_MSUBNORM (1 << 2)
# define _FCLASS_MZERO (1 << 3)
# define _FCLASS_PZERO (1 << 4)
# define _FCLASS_PSUBNORM (1 << 5)
# define _FCLASS_PNORM (1 << 6)
# define _FCLASS_PINF (1 << 7)
# define _FCLASS_SNAN (1 << 8)
# define _FCLASS_QNAN (1 << 9)
# define _FCLASS_ZERO (_FCLASS_MZERO | _FCLASS_PZERO)
# define _FCLASS_SUBNORM (_FCLASS_MSUBNORM | _FCLASS_PSUBNORM)
# define _FCLASS_NORM (_FCLASS_MNORM | _FCLASS_PNORM)
# define _FCLASS_INF (_FCLASS_MINF | _FCLASS_PINF)
# define _FCLASS_NAN (_FCLASS_SNAN | _FCLASS_QNAN)
#endif /* __riscv_flen */
#endif /* fpu_control.h */

View File

@ -0,0 +1,42 @@
/* Configuration for math tests. RISC-V version
Copyright (C) 2014-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Copied from the aarch64 version
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* Trapping exceptions are not supported on RISC-V. */
#define EXCEPTION_ENABLE_SUPPORTED(EXCEPT) ((EXCEPT) == 0)
/* Despite not supporting trapping exceptions, we support setting
floating-point exception flags on hard-float targets. These are not
supported on soft-float targets. */
#ifndef __riscv_flen
# define EXCEPTION_TESTS_float 0
# define EXCEPTION_TESTS_double 0
# define EXCEPTION_TESTS_long_double 0
#endif
/* On soft-float targets we only support the "to nearest" rounding mode. */
#ifndef __riscv_flen
# define ROUNDING_TESTS_float(MODE) ((MODE) == FE_TONEAREST)
# define ROUNDING_TESTS_double(MODE) ((MODE) == FE_TONEAREST)
# define ROUNDING_TESTS_long_double(MODE) ((MODE) == FE_TONEAREST)
#endif
/* RISC-V floating-point instructions do not preserve NaN payloads. */
#define SNAN_TESTS_PRESERVE_PAYLOAD 0
#include_next <math-tests.h>

View File

@ -0,0 +1 @@
ieee754/soft-fp

101
sysdeps/riscv/sfp-machine.h Normal file
View File

@ -0,0 +1,101 @@
/* RISC-V softfloat definitions
Copyright (C) 2017-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#include <fenv.h>
#include <fpu_control.h>
#if __riscv_xlen == 32
# error "rv32i-based targets are not supported"
#else
# define _FP_W_TYPE_SIZE 64
# define _FP_W_TYPE unsigned long long
# define _FP_WS_TYPE signed long long
# define _FP_I_TYPE long long
# define _FP_MUL_MEAT_S(R, X, Y) \
_FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y)
# define _FP_MUL_MEAT_D(R, X, Y) \
_FP_MUL_MEAT_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
# define _FP_MUL_MEAT_Q(R, X, Y) \
_FP_MUL_MEAT_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
# define _FP_MUL_MEAT_DW_S(R, X, Y) \
_FP_MUL_MEAT_DW_1_imm (_FP_WFRACBITS_S, R, X, Y)
# define _FP_MUL_MEAT_DW_D(R, X, Y) \
_FP_MUL_MEAT_DW_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
# define _FP_MUL_MEAT_DW_Q(R, X, Y) \
_FP_MUL_MEAT_DW_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
# define _FP_DIV_MEAT_S(R, X, Y) _FP_DIV_MEAT_1_imm (S, R, X, Y, _FP_DIV_HELP_imm)
# define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_1_udiv_norm (D, R, X, Y)
# define _FP_DIV_MEAT_Q(R, X, Y) _FP_DIV_MEAT_2_udiv (Q, R, X, Y)
# define _FP_NANFRAC_S _FP_QNANBIT_S
# define _FP_NANFRAC_D _FP_QNANBIT_D
# define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
#endif
#define _FP_NANSIGN_S 0
#define _FP_NANSIGN_D 0
#define _FP_NANSIGN_Q 0
#define _FP_KEEPNANFRACP 0
#define _FP_QNANNEGATEDP 0
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
R##_s = _FP_NANSIGN_##fs; \
_FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
R##_c = FP_CLS_NAN; \
} while (0)
#define _FP_DECL_EX int _frm __attribute__ ((unused));
#define FP_ROUNDMODE _frm
#define FP_RND_NEAREST FE_TONEAREST
#define FP_RND_ZERO FE_TOWARDZERO
#define FP_RND_PINF FE_UPWARD
#define FP_RND_MINF FE_DOWNWARD
#define FP_EX_INVALID FE_INVALID
#define FP_EX_OVERFLOW FE_OVERFLOW
#define FP_EX_UNDERFLOW FE_UNDERFLOW
#define FP_EX_DIVZERO FE_DIVBYZERO
#define FP_EX_INEXACT FE_INEXACT
#define _FP_TININESS_AFTER_ROUNDING 1
#ifdef __riscv_flen
# define FP_INIT_ROUNDMODE \
do { \
__asm__ volatile ("frrm %0" : "=r" (_frm)); \
} while (0)
# define FP_HANDLE_EXCEPTIONS \
do { \
if (__builtin_expect (_fex, 0)) \
__asm__ volatile ("csrs fflags, %0" : : "rK" (_fex)); \
} while (0)
#else
# define FP_INIT_ROUNDMODE _frm = FP_RND_NEAREST
#endif

1
sysdeps/riscv/tininess.h Normal file
View File

@ -0,0 +1 @@
#define TININESS_AFTER_ROUNDING 1