From patchwork Thu Jan 25 04:36:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 865736 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89486-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="rxNbJe0D"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zRq644LRWz9t3F for ; Thu, 25 Jan 2018 15:38:04 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; q=dns; s=default; b=diiypWiym5E4SH5v/Q2rl513bOTHzsj Gui1mmj4Rq6aKsjdgOXp6vFJLPI161B5gJkVz0s8zG8tgLo+hnfuJkqa7771I7uR sXKoLOS19irwi4chm9makOtVc0eFvzB3PlPXN9lGtELtSkbSNVothydTSV1tdebq i4HWB8A2Na60= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:date:message-id:in-reply-to:references :cc:from:to; s=default; bh=+jPoEI9lp3uAagwM8xOaDEG0liU=; b=rxNbJ e0DgByDPJ+M6mLB+djKvmeBvCCsNwqcOclrCoF1olE8q3R59VWGu46AS/s282UK+ ZXy/eXikyp68WVNr8IwA0qF1f76AU2tnk9/nkclLPGxAntNLcoMnWmDIACoTY/Oo 71Gfam3BzC01WLF4gAfRbu8EFLBoVpXFJxhwvc= Received: (qmail 20699 invoked by alias); 25 Jan 2018 04:36:54 -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 20612 invoked by uid 89); 25 Jan 2018 04:36:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.1 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= X-HELO: mail-pf0-f181.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=ZOCTpAmmPWwBPwIi9Fe8Y7KFAEUZdC/3ZYT2/434LuQ=; b=L4/+jByzuu+TVrSwU9HiOu4DhvNX0L7ZoNiBOOsM4fXz7e0MqQrFiU3RXwXOB1x56G V0jjGB8atNsO4SwXIvmaW22gVH09HdVx16gkUX9GtxBeoMGeGMkOluzUsw87+X7aUa3i WA5l45Nw+u90Bdotv/tZE7JosLutPFsfYBv/FcwiHMvpdIGmjLMLA/EdOTsN9xnzk9gP 7to03n9oogSb4JjDoOk74uK8FSwrAYBEW6xP5bOwW8yxWw/3y22e32asU3LyWPxuzTHe i0/ccq0beFeDrTe6lunR0ZCKGlrO83yRMgvb0LoK2yySvJBjZfhRh7EDaM7mkNSeIlgA gi3w== X-Gm-Message-State: AKwxytelwLWAwDjZUxa69cgEj7fftI6TyoquuFqK96QVu4u3dfJF2XfK E/0yyOv+errSJYNYgFqXF23Z4A== X-Google-Smtp-Source: AH8x226YeJy8GAAhAeYGABmO5KCcjS1fPBIi4rkp6wkvJKDB5EUqmN/xlay3g791N/K24ktUx/VhiQ== X-Received: by 10.98.201.69 with SMTP id k66mr14937216pfg.105.1516855007545; Wed, 24 Jan 2018 20:36:47 -0800 (PST) Subject: [PATCH 08/17] RISC-V: Generic and soft-fp Routines Date: Wed, 24 Jan 2018 20:36:12 -0800 Message-Id: <20180125043621.19972-9-palmer@dabbelt.com> In-Reply-To: <20180125043621.19972-1-palmer@dabbelt.com> References: <20180125043621.19972-1-palmer@dabbelt.com> Cc: Andrew Waterman , Darius Rad , dj@redhat.com, patches@groups.riscv.org, Palmer Dabbelt From: Palmer Dabbelt To: libc-alpha@sourceware.org, joseph@codesourcery.com 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/e_sqrtl.c | 37 +++++++++++++++ sysdeps/riscv/fpu_control.h | 74 +++++++++++++++++++++++++++++ sysdeps/riscv/math-tests.h | 38 +++++++++++++++ sysdeps/riscv/nofpu/Implies | 1 + sysdeps/riscv/sfp-machine.h | 112 ++++++++++++++++++++++++++++++++++++++++++++ sysdeps/riscv/tininess.h | 1 + 7 files changed, 337 insertions(+) create mode 100644 sysdeps/riscv/bits/fenv.h create mode 100644 sysdeps/riscv/e_sqrtl.c create mode 100644 sysdeps/riscv/fpu_control.h create mode 100644 sysdeps/riscv/math-tests.h create mode 100644 sysdeps/riscv/nofpu/Implies create mode 100644 sysdeps/riscv/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/e_sqrtl.c b/sysdeps/riscv/e_sqrtl.c new file mode 100644 index 000000000000..55a875d9fbb3 --- /dev/null +++ b/sysdeps/riscv/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/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..b2dcc08032f6 --- /dev/null +++ b/sysdeps/riscv/math-tests.h @@ -0,0 +1,38 @@ +/* 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) + +/* Despite not supporting trapping exceptions, we support setting + floating-point exception flags on hard-float targets. These are not + supported on soft-float targets. */ +#if __riscv_flen == 0 +#define EXCEPTION_TESTS_float 0 +#define EXCEPTION_TESTS_double 0 +#endif + +/* We don't support the Q extension yet, so long double is always soft float + * and therefor doesn't support exceptions. */ +#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/nofpu/Implies b/sysdeps/riscv/nofpu/Implies new file mode 100644 index 000000000000..abcbadb25f22 --- /dev/null +++ b/sysdeps/riscv/nofpu/Implies @@ -0,0 +1 @@ +ieee754/soft-fp diff --git a/sysdeps/riscv/sfp-machine.h b/sysdeps/riscv/sfp-machine.h new file mode 100644 index 000000000000..b86a9cfa66f4 --- /dev/null +++ b/sysdeps/riscv/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