From patchwork Sat Jan 13 10:38:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 25377 Received: (qmail 99246 invoked by alias); 13 Jan 2018 10:38:59 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 99015 invoked by uid 89); 13 Jan 2018 10:38:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=miscellaneous X-HELO: mail-pf0-f172.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=RWRr3es/aCHaDBtfK/LmrnyM471eHD3Fx8hhvEF2zes=; b=fZtA46qrMt6eqw5OQ/kDYZFF6KNoVVl54BvYvjv0OZGASp5u1mnYP71FVkvujKhiFE evIQvQIKeZm2bbDDa+IzJMTB+bkrqSDZkPxPKQCD9/RSJVNHMwX4PZMMISSK1oy8y2lD wE1IC6MJOa57Qi3KVB4ivbaU7yNJ7OrjESQrQpNY7TiIjxO12rsiLY6/qMIZsPXlnbw9 t8GxdMjBhtPYLNsAC8mffADSmGu1tiLwyrcuytLXRMF21e8Jw8HVdlEbMX+FiCZ2Y4Jt hpNQInSOfiOVbMWQaIxh1Pk6tArFObg7PfyIbjoW9lrZVT/LcOgl94Z7M+Qq+MnkmAxT KSjw== X-Gm-Message-State: AKGB3mL8LU7V8bEoCisLSQf7qPopMWjQEGE4MqZ7NqsFB4SbRknp5Gie qoQsWg+Qpd1cpf3hi9t6Cj1lOA== X-Google-Smtp-Source: ACJfBosyT6beUU+FkhxpdJuOMvtmDQtPiS0XfiRqNdRFo9IMwVivrrak4uDOnjdV42ng9gmXy+y+XA== X-Received: by 10.99.51.77 with SMTP id z74mr22942862pgz.324.1515839932809; Sat, 13 Jan 2018 02:38:52 -0800 (PST) Subject: [PATCH v4 08/17] RISC-V: Generic and soft-fp Routines Date: Sat, 13 Jan 2018 02:38:07 -0800 Message-Id: <20180113103816.4861-9-palmer@dabbelt.com> In-Reply-To: <20180113103816.4861-1-palmer@dabbelt.com> References: <20180113103816.4861-1-palmer@dabbelt.com> Cc: patches@groups.riscv.org, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org This patch contains the miscellaneous math routines and headers we have implemented for RISC-V. This includes things from that aren't completely ISA-generic, floating-point bit manipulation, and soft-fp hooks. FIXME: add ieee745/soft-fp via a riscv/soft-fp directory. --- sysdeps/riscv/bits/fenv.h | 74 ++++++++++++++++++++++++ sysdeps/riscv/fpu_control.h | 74 ++++++++++++++++++++++++ sysdeps/riscv/math-tests.h | 30 ++++++++++ sysdeps/riscv/soft-fp/Makefile | 3 + sysdeps/riscv/soft-fp/e_sqrtl.c | 37 ++++++++++++ sysdeps/riscv/soft-fp/sfp-machine.h | 112 ++++++++++++++++++++++++++++++++++++ sysdeps/riscv/tininess.h | 1 + 7 files changed, 331 insertions(+) create mode 100644 sysdeps/riscv/bits/fenv.h create mode 100644 sysdeps/riscv/fpu_control.h create mode 100644 sysdeps/riscv/math-tests.h create mode 100644 sysdeps/riscv/soft-fp/Makefile create mode 100644 sysdeps/riscv/soft-fp/e_sqrtl.c create mode 100644 sysdeps/riscv/soft-fp/sfp-machine.h create mode 100644 sysdeps/riscv/tininess.h diff --git a/sysdeps/riscv/bits/fenv.h b/sysdeps/riscv/bits/fenv.h new file mode 100644 index 000000000000..e23b7e253d93 --- /dev/null +++ b/sysdeps/riscv/bits/fenv.h @@ -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 + . */ + +#ifndef _FENV_H +# error "Never use directly; include 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 diff --git a/sysdeps/riscv/fpu_control.h b/sysdeps/riscv/fpu_control.h new file mode 100644 index 000000000000..c050d279b246 --- /dev/null +++ b/sysdeps/riscv/fpu_control.h @@ -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 + . */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +#include + +#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 */ diff --git a/sysdeps/riscv/math-tests.h b/sysdeps/riscv/math-tests.h new file mode 100644 index 000000000000..e7f3c44209a5 --- /dev/null +++ b/sysdeps/riscv/math-tests.h @@ -0,0 +1,30 @@ +/* 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 + . */ + +/* Trapping exceptions are not supported on RISC-V. */ +#define EXCEPTION_ENABLE_SUPPORTED(EXCEPT) ((EXCEPT) == 0) + +#define EXCEPTION_TESTS_float 0 +#define EXCEPTION_TESTS_double 0 +#define EXCEPTION_TESTS_long_double 0 + +/* RISC-V floating-point instructions do not preserve NaN payloads. */ +#define SNAN_TESTS_PRESERVE_PAYLOAD 0 + +#include_next diff --git a/sysdeps/riscv/soft-fp/Makefile b/sysdeps/riscv/soft-fp/Makefile new file mode 100644 index 000000000000..ada13e8b70e5 --- /dev/null +++ b/sysdeps/riscv/soft-fp/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),math) +CPPFLAGS += -I../soft-fp +endif diff --git a/sysdeps/riscv/soft-fp/e_sqrtl.c b/sysdeps/riscv/soft-fp/e_sqrtl.c new file mode 100644 index 000000000000..9e4209452107 --- /dev/null +++ b/sysdeps/riscv/soft-fp/e_sqrtl.c @@ -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 + . */ + +#include +#include +#include + +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) diff --git a/sysdeps/riscv/soft-fp/sfp-machine.h b/sysdeps/riscv/soft-fp/sfp-machine.h new file mode 100644 index 000000000000..b86a9cfa66f4 --- /dev/null +++ b/sysdeps/riscv/soft-fp/sfp-machine.h @@ -0,0 +1,112 @@ +/* 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 + . */ + +#include +#include + +#if __riscv_xlen == 32 + +# define _FP_W_TYPE_SIZE 32 +# define _FP_W_TYPE unsigned long +# define _FP_WS_TYPE signed long +# define _FP_I_TYPE long + +# define _FP_MUL_MEAT_S(R, X, Y) \ + _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_S, R, X, Y, umul_ppmm) +# define _FP_MUL_MEAT_D(R, X, Y) \ + _FP_MUL_MEAT_2_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm) +# define _FP_MUL_MEAT_Q(R, X, Y) \ + _FP_MUL_MEAT_4_wide (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm) + +# define _FP_DIV_MEAT_S(R, X, Y) _FP_DIV_MEAT_1_udiv_norm (S, R, X, Y) +# define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_2_udiv (D, R, X, Y) +# define _FP_DIV_MEAT_Q(R, X, Y) _FP_DIV_MEAT_4_udiv (Q, R, X, Y) + +# define _FP_NANFRAC_S _FP_QNANBIT_S +# define _FP_NANFRAC_D _FP_QNANBIT_D, 0 +# define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 + +#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_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 diff --git a/sysdeps/riscv/tininess.h b/sysdeps/riscv/tininess.h new file mode 100644 index 000000000000..1db37790f881 --- /dev/null +++ b/sysdeps/riscv/tininess.h @@ -0,0 +1 @@ +#define TININESS_AFTER_ROUNDING 1