From patchwork Sun Apr 8 07:02:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?5q+b5pmX?= X-Patchwork-Id: 26646 Received: (qmail 122029 invoked by alias); 8 Apr 2018 07:03:48 -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 121914 invoked by uid 89); 8 Apr 2018 07:03:47 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, UNPARSEABLE_RELAY autolearn=ham version=3.3.2 spammy=Install, Reserved X-HELO: mail139-36.mail.alibaba.com X-Alimail-AntiSpam: AC=CONTINUE; BC=0.07444093|-1; CH=green; FP=0|0|0|0|0|-1|-1|-1; HT=e01l07447; MF=han_mao@c-sky.com; NM=1; PH=DS; RN=4; RT=4; SR=0; TI=SMTPD_---.Bc2QaKQ_1523171013; From: Mao Han To: libc-alpha@sourceware.org Cc: Mao Han , c-sky_gcc_upstream@c-sky.com, gnu-csky@mentor.com Subject: [RFC PATCH V2 04/10] C-SKY: Hard Float Support Date: Sun, 8 Apr 2018 15:02:27 +0800 Message-Id: In-Reply-To: References: In-Reply-To: References: This patch contains hardware floating-point support for C-SKY. * sysdeps/csky/fpu/fclrexcpt.c: New file * sysdeps/csky/fpu/fedisblxcpt.c: New file * sysdeps/csky/fpu/feenablxcpt.c: New file * sysdeps/csky/fpu/fegetenv.c: New file * sysdeps/csky/fpu/fegetexcept.c: New file * sysdeps/csky/fpu/fegetmode.c: New file * sysdeps/csky/fpu/fegetround.c: New file * sysdeps/csky/fpu/feholdexcpt.c: New file * sysdeps/csky/fpu/fenv_libc.h: New file * sysdeps/csky/fpu/fesetenv.c: New file * sysdeps/csky/fpu/fesetexcept.c: New file * sysdeps/csky/fpu/fesetmode.c: New file * sysdeps/csky/fpu/fesetround.c: New file * sysdeps/csky/fpu/feupdateenv.c: New file * sysdeps/csky/fpu/fgetexcptflg.c: New file * sysdeps/csky/fpu/fraiseexcpt.c: New file * sysdeps/csky/fpu/fsetexcptflg.c: New file * sysdeps/csky/fpu/ftestexcept.c: New file * sysdeps/csky/fpu_control.h: New file --- sysdeps/csky/fpu/fclrexcpt.c | 47 +++++++++++++ sysdeps/csky/fpu/fedisblxcpt.c | 46 ++++++++++++ sysdeps/csky/fpu/feenablxcpt.c | 45 ++++++++++++ sysdeps/csky/fpu/fegetenv.c | 42 +++++++++++ sysdeps/csky/fpu/fegetexcept.c | 37 ++++++++++ sysdeps/csky/fpu/fegetmode.c | 29 ++++++++ sysdeps/csky/fpu/fegetround.c | 39 +++++++++++ sysdeps/csky/fpu/feholdexcpt.c | 39 +++++++++++ sysdeps/csky/fpu/fenv_libc.h | 29 ++++++++ sysdeps/csky/fpu/fesetenv.c | 64 +++++++++++++++++ sysdeps/csky/fpu/fesetexcept.c | 37 ++++++++++ sysdeps/csky/fpu/fesetmode.c | 37 ++++++++++ sysdeps/csky/fpu/fesetround.c | 41 +++++++++++ sysdeps/csky/fpu/feupdateenv.c | 51 ++++++++++++++ sysdeps/csky/fpu/fgetexcptflg.c | 37 ++++++++++ sysdeps/csky/fpu/fraiseexcpt.c | 131 +++++++++++++++++++++++++++++++++++ sysdeps/csky/fpu/fsetexcptflg.c | 48 +++++++++++++ sysdeps/csky/fpu/ftestexcept.c | 35 ++++++++++ sysdeps/csky/fpu_control.h | 150 ++++++++++++++++++++++++++++++++++++++++ 19 files changed, 984 insertions(+) create mode 100644 sysdeps/csky/fpu/fclrexcpt.c create mode 100644 sysdeps/csky/fpu/fedisblxcpt.c create mode 100644 sysdeps/csky/fpu/feenablxcpt.c create mode 100644 sysdeps/csky/fpu/fegetenv.c create mode 100644 sysdeps/csky/fpu/fegetexcept.c create mode 100644 sysdeps/csky/fpu/fegetmode.c create mode 100644 sysdeps/csky/fpu/fegetround.c create mode 100644 sysdeps/csky/fpu/feholdexcpt.c create mode 100644 sysdeps/csky/fpu/fenv_libc.h create mode 100644 sysdeps/csky/fpu/fesetenv.c create mode 100644 sysdeps/csky/fpu/fesetexcept.c create mode 100644 sysdeps/csky/fpu/fesetmode.c create mode 100644 sysdeps/csky/fpu/fesetround.c create mode 100644 sysdeps/csky/fpu/feupdateenv.c create mode 100644 sysdeps/csky/fpu/fgetexcptflg.c create mode 100644 sysdeps/csky/fpu/fraiseexcpt.c create mode 100644 sysdeps/csky/fpu/fsetexcptflg.c create mode 100644 sysdeps/csky/fpu/ftestexcept.c create mode 100644 sysdeps/csky/fpu_control.h diff --git a/sysdeps/csky/fpu/fclrexcpt.c b/sysdeps/csky/fpu/fclrexcpt.c new file mode 100644 index 0000000..3599e49 --- /dev/null +++ b/sysdeps/csky/fpu/fclrexcpt.c @@ -0,0 +1,47 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 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 + +int +feclearexcept (int excepts) +{ +#ifdef __csky_hard_float__ + int fpsr; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Read the complete control word. */ + _FPU_GETFPSR (fpsr); + + /* Clear the relevant bits. */ + fpsr &= ~(excepts | (excepts << CAUSE_SHIFT)); + + /* Put the new data in effect. */ + _FPU_SETFPSR (fpsr); + + return 0; +#else + /* Unsupported, so fail unless nothing needs to be done. */ + return (excepts != 0); +#endif /* __csky_hard_float__ */ +} +libm_hidden_def (feclearexcept) diff --git a/sysdeps/csky/fpu/fedisblxcpt.c b/sysdeps/csky/fpu/fedisblxcpt.c new file mode 100644 index 0000000..6a70c0e --- /dev/null +++ b/sysdeps/csky/fpu/fedisblxcpt.c @@ -0,0 +1,46 @@ +/* Disable floating-point exceptions. + Copyright (C) 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 + +int +fedisableexcept (int excepts) +{ +#ifdef __csky_hard_float__ + unsigned int new_exc, old_exc; + + /* Get the current control word. */ + _FPU_GETCW (new_exc); + + old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT; + + /* Get the except disable mask. */ + excepts &= FE_ALL_EXCEPT; + new_exc &= ~(excepts << ENABLE_SHIFT); + + /* Put the new data in effect. */ + _FPU_SETCW (new_exc); + + return old_exc; +#else + /* Unsupported, so return -1 for failure. */ + return -1; +#endif /* __csky_hard_float__ */ +} diff --git a/sysdeps/csky/fpu/feenablxcpt.c b/sysdeps/csky/fpu/feenablxcpt.c new file mode 100644 index 0000000..21c1e77 --- /dev/null +++ b/sysdeps/csky/fpu/feenablxcpt.c @@ -0,0 +1,45 @@ +/* Enable floating-point exceptions. + Copyright (C) 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 + +int +feenableexcept (int excepts) +{ +#ifdef __csky_hard_float__ + unsigned int new_exc, old_exc; + + /* Get the current control word. */ + _FPU_GETCW (new_exc); + + old_exc = (new_exc & ENABLE_MASK) >> ENABLE_SHIFT; + + excepts &= FE_ALL_EXCEPT; + + new_exc |= excepts << ENABLE_SHIFT; + + _FPU_SETCW (new_exc); + + return old_exc; +#else + /* Unsupported, so return -1 for failure. */ + return -1; +#endif /* __csky_hard_float__ */ +} diff --git a/sysdeps/csky/fpu/fegetenv.c b/sysdeps/csky/fpu/fegetenv.c new file mode 100644 index 0000000..19c3a74 --- /dev/null +++ b/sysdeps/csky/fpu/fegetenv.c @@ -0,0 +1,42 @@ +/* Store current floating-point environment. + Copyright (C) 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 + +int +__fegetenv (fenv_t *envp) +{ +#ifdef __csky_hard_float__ + unsigned int fpcr; + unsigned int fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + envp->__fpcr = fpcr; + envp->__fpsr = fpsr; + + return 0; +#else + /* Unsupported, so return 1 for failure. */ + return 1; +#endif /* __csky_hard_float__ */ +} +libm_hidden_def (__fegetenv) +weak_alias (__fegetenv, fegetenv) +libm_hidden_weak (fegetenv) diff --git a/sysdeps/csky/fpu/fegetexcept.c b/sysdeps/csky/fpu/fegetexcept.c new file mode 100644 index 0000000..784f4f7 --- /dev/null +++ b/sysdeps/csky/fpu/fegetexcept.c @@ -0,0 +1,37 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 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 + +int +fegetexcept (void) +{ +#ifdef __csky_hard_float__ + unsigned int exc; + + /* Get the current control word. */ + _FPU_GETCW (exc); + + return (exc & ENABLE_MASK) >> ENABLE_SHIFT; +#else + /* Unsupported. Return all exceptions disabled. */ + return 0; +#endif /* __csky_hard_float__ */ +} diff --git a/sysdeps/csky/fpu/fegetmode.c b/sysdeps/csky/fpu/fegetmode.c new file mode 100644 index 0000000..f3115b1 --- /dev/null +++ b/sysdeps/csky/fpu/fegetmode.c @@ -0,0 +1,29 @@ +/* Store current floating-point control modes. + Copyright (C) 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 + +int +fegetmode (femode_t *modep) +{ +#ifdef __csky_hard_float__ + _FPU_GETCW (*modep); +#endif /* __csky_hard_float__ */ + return 0; +} diff --git a/sysdeps/csky/fpu/fegetround.c b/sysdeps/csky/fpu/fegetround.c new file mode 100644 index 0000000..6e0fcec --- /dev/null +++ b/sysdeps/csky/fpu/fegetround.c @@ -0,0 +1,39 @@ +/* Return current rounding direction. + Copyright (C) 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 + +int +__fegetround (void) +{ +#ifdef __csky_hard_float__ + unsigned int cw; + + /* Get control word. */ + _FPU_GETCW (cw); + + return cw & FE_ROUND_MASK; +#else + /* The current soft-float implementation only handles TONEAREST. */ + return FE_TONEAREST; +#endif /* __csky_hard_float__ */ +} +libm_hidden_def (__fegetround) +weak_alias (__fegetround, fegetround) +libm_hidden_weak (fegetround) diff --git a/sysdeps/csky/fpu/feholdexcpt.c b/sysdeps/csky/fpu/feholdexcpt.c new file mode 100644 index 0000000..6c466d0 --- /dev/null +++ b/sysdeps/csky/fpu/feholdexcpt.c @@ -0,0 +1,39 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 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 +#include + +#include + +int +__feholdexcept (fenv_t *envp) +{ +#ifdef __csky_hard_float__ + libc_feholdexcept_vfp (envp); + return 0; +#else + /* Unsupported, so fail. */ + return 1; +#endif /* __csky_hard_float__ */ +} +libm_hidden_def (__feholdexcept) +weak_alias (__feholdexcept, feholdexcept) +libm_hidden_weak (feholdexcept) diff --git a/sysdeps/csky/fpu/fenv_libc.h b/sysdeps/csky/fpu/fenv_libc.h new file mode 100644 index 0000000..2dacb2c --- /dev/null +++ b/sysdeps/csky/fpu/fenv_libc.h @@ -0,0 +1,29 @@ +/* Copyright (C) 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_LIBC_H +#define _FENV_LIBC_H 1 + +/* Mask for enabling exceptions and for the CAUSE bits. */ +#define ENABLE_MASK 0x0003FU +#define CAUSE_MASK 0x3F000U + +/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ +#define ENABLE_SHIFT 0 +#define CAUSE_SHIFT 8 + +#endif /* _FENV_LIBC_H */ diff --git a/sysdeps/csky/fpu/fesetenv.c b/sysdeps/csky/fpu/fesetenv.c new file mode 100644 index 0000000..0ac50a7 --- /dev/null +++ b/sysdeps/csky/fpu/fesetenv.c @@ -0,0 +1,64 @@ +/* Install given floating-point environment. + Copyright (C) 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 + +int +__fesetenv (const fenv_t *envp) +{ +#ifdef __csky_hard_float__ + unsigned int fpcr; + unsigned int fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + + fpcr &= _FPU_RESERVED; + fpsr &= _FPU_FPSR_RESERVED; + + if (envp == FE_DFL_ENV) + { + fpcr |= _FPU_DEFAULT; + fpsr |= _FPU_FPSR_DEFAULT; + } + else if (envp == FE_NOMASK_ENV) + { + fpcr |= _FPU_FPCR_IEEE; + fpsr |= _FPU_FPSR_IEEE; + } + else + { + fpcr |= envp->__fpcr & ~_FPU_RESERVED; + fpsr |= envp->__fpsr & ~_FPU_FPSR_RESERVED; + } + + _FPU_SETFPSR (fpsr); + + _FPU_SETCW (fpcr); + + /* Success. */ + return 0; +#else + /* Unsupported, so fail. */ + return 1; +#endif /* __csky_hard_float__ */ +} +libm_hidden_def (__fesetenv) +weak_alias (__fesetenv, fesetenv) +libm_hidden_weak (fesetenv) diff --git a/sysdeps/csky/fpu/fesetexcept.c b/sysdeps/csky/fpu/fesetexcept.c new file mode 100644 index 0000000..e0a90f6 --- /dev/null +++ b/sysdeps/csky/fpu/fesetexcept.c @@ -0,0 +1,37 @@ +/* Set given exception flags. + Copyright (C) 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 + +int +fesetexcept (int excepts) +{ +#ifdef __csky_hard_float__ + fpu_control_t fpsr, new_fpsr; + _FPU_GETFPSR (fpsr); + new_fpsr = fpsr | ((excepts & FE_ALL_EXCEPT) << CAUSE_SHIFT); + if (new_fpsr != fpsr) + _FPU_SETFPSR (new_fpsr); +#else + return (excepts != 0); +#endif /* __csky_hard_float__ */ + + return 0; +} diff --git a/sysdeps/csky/fpu/fesetmode.c b/sysdeps/csky/fpu/fesetmode.c new file mode 100644 index 0000000..9e259d0 --- /dev/null +++ b/sysdeps/csky/fpu/fesetmode.c @@ -0,0 +1,37 @@ +/* Install given floating-point control modes. + Copyright (C) 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 + +int +fesetmode (const femode_t *modep) +{ +#ifdef __csky_hard_float__ + if (modep == FE_DFL_MODE) + mode = _FPU_DEFAULT; + else + mode = *modep; + _FPU_SETCW (mode); + + return 0; +#else + /* Nothing to do. */ + return 0; +#endif /* __csky_hard_float__ */ +} diff --git a/sysdeps/csky/fpu/fesetround.c b/sysdeps/csky/fpu/fesetround.c new file mode 100644 index 0000000..8aba20e --- /dev/null +++ b/sysdeps/csky/fpu/fesetround.c @@ -0,0 +1,41 @@ +/* Set current rounding direction. + Copyright (C) 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 + +#include +int +__fesetround (int round) +{ +#ifdef __csky_hard_float__ + libc_fesetround_vfp (round); + return 0; +#else + if (round == FE_TONEAREST) + /* This is the only supported rounding mode for soft-fp. */ + return 0; + + /* Unsupported, so fail. */ + return 1; +#endif /* __csky_hard_float__ */ +} +libm_hidden_def (__fesetround) +weak_alias (__fesetround, fesetround) +libm_hidden_weak (fesetround) diff --git a/sysdeps/csky/fpu/feupdateenv.c b/sysdeps/csky/fpu/feupdateenv.c new file mode 100644 index 0000000..8972291 --- /dev/null +++ b/sysdeps/csky/fpu/feupdateenv.c @@ -0,0 +1,51 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 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 +#include +#include + +int +__feupdateenv (const fenv_t *envp) +{ +#ifdef __csky_hard_float__ + int temp; + + /* Save current exceptions. */ + _FPU_GETFPSR(temp); + temp = (temp >> CAUSE_SHIFT) & FE_ALL_EXCEPT; + /* Install new environment. */ + libc_fesetenv_vfp (envp); + + /* Raise the safed exception. Incidently for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + feraiseexcept (temp); + + /* Success. */ + return 0; +#else + /* Unsupported, so fail. */ + return 1; +#endif /* __csky_hard_float__ */ +} +libm_hidden_def (__feupdateenv) +weak_alias (__feupdateenv, feupdateenv) +libm_hidden_weak (feupdateenv) diff --git a/sysdeps/csky/fpu/fgetexcptflg.c b/sysdeps/csky/fpu/fgetexcptflg.c new file mode 100644 index 0000000..73d0ce8 --- /dev/null +++ b/sysdeps/csky/fpu/fgetexcptflg.c @@ -0,0 +1,37 @@ +/* Store current representation for exceptions. + Copyright (C) 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 +#include +#include + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ +#ifdef __csky_hard_float__ + *flagp = libc_fetestexcept_vfp (excepts); + + /* Success. */ + return 0; +#else + /* Unsupported, so fail. */ + return 1; +#endif /* __csky_hard_float__ */ +} diff --git a/sysdeps/csky/fpu/fraiseexcpt.c b/sysdeps/csky/fpu/fraiseexcpt.c new file mode 100644 index 0000000..7456407 --- /dev/null +++ b/sysdeps/csky/fpu/fraiseexcpt.c @@ -0,0 +1,131 @@ +/* Raise given exceptions. + Copyright (C) 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 +#include +#include + +int +__feraiseexcept (int excepts) +{ +#ifdef __csky_hard_float__ + /* Raise exceptions represented by EXCEPTS. But we must raise only one + signal at a time. It is important that if the overflow/underflow + exception and the divide by zero exception are given at the same + time, the overflow/underflow exception follows the divide by zero + exception. */ + +# ifdef __csky_fpuv2__ + /* First: invalid exception. */ + if (FE_INVALID & excepts) + { + /* One example of a invalid operation is 0 * Infinity. */ + float x = HUGE_VALF, y = 0.0f; + __asm__ __volatile__ ("fmuls %0, %0, %1" : "+v" (x) : "v" (y)); + } + + /* Next: division by zero. */ + if (FE_DIVBYZERO & excepts) + { + float x = 1.0f, y = 0.0f; + __asm__ __volatile__ ("fdivs %0, %0, %1" : "+v" (x) : "v" (y)); + } + + /* Next: overflow. */ + if (FE_OVERFLOW & excepts) + { + float x = FLT_MAX; + __asm__ __volatile__ ("fmuls %0, %0, %0" : "+v" (x)); + } + /* Next: underflow. */ + if (FE_UNDERFLOW & excepts) + { + float x = -FLT_MIN; + + __asm__ __volatile__ ("fmuls %0, %0, %0" : "+v" (x)); + } + + /* Last: inexact. */ + if (FE_INEXACT & excepts) + { + float x = 1.0f, y = 3.0f; + __asm__ __volatile__ ("fdivs %0, %0, %1" : "+v" (x) : "v" (y)); + } + + if (FE_DENORMAL & excepts) + { + double x = 4.9406564584124654e-324; + __asm__ __volatile__ ("fstod %0, %0" : "+v" (x)); + } +# else /* __csky_fpuv2__ */ + int tmp = 0; + /* First: invalid exception. */ + if (FE_INVALID & excepts) + { + /* One example of a invalid operation is 0 * Infinity. */ + float x = HUGE_VALF, y = 0.0f; + __asm__ __volatile__ ("fmuls %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } + + /* Next: division by zero. */ + if (FE_DIVBYZERO & excepts) + { + float x = 1.0f, y = 0.0f; + __asm__ __volatile__ ("fdivs %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } + + /* Next: overflow. */ + if (FE_OVERFLOW & excepts) + { + float x = FLT_MAX, y = FLT_MAX; + __asm__ __volatile__ ("fmuls %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } + + /* Next: underflow. */ + if (FE_UNDERFLOW & excepts) + { + float x = -FLT_MIN, y = -FLT_MIN; + + __asm__ __volatile__ ("fmuls %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } + + /* Last: inexact. */ + if (FE_INEXACT & excepts) + { + float x = 1.0f, y = 3.0f; + __asm__ __volatile__ ("fdivs %0, %0, %2, %1" + : "+f" (x), "+r"(tmp) : "f" (y)); + } +# endif /* __csky_fpuv2__ */ + + /* Success. */ + return 0; +#else /* __csky_hard_float__ */ + /* Unsupported, so fail unless nothing needs to be done. */ + return (excepts != 0); +#endif +} +libm_hidden_def (__feraiseexcept) +weak_alias (__feraiseexcept, feraiseexcept) +libm_hidden_weak (feraiseexcept) diff --git a/sysdeps/csky/fpu/fsetexcptflg.c b/sysdeps/csky/fpu/fsetexcptflg.c new file mode 100644 index 0000000..79ddc50 --- /dev/null +++ b/sysdeps/csky/fpu/fsetexcptflg.c @@ -0,0 +1,48 @@ +/* Set floating-point environment exception handling. + Copyright (C) 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 + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ +#ifdef __csky_hard_float__ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETFPSR (temp); + + /* Make sure the flags we want restored are legal. */ + excepts &= FE_ALL_EXCEPT; + + /* Now clear the bits called for, and copy them in from flagp. Note that + we ignore all non-flag bits from *flagp, so they don't matter. */ + temp = ((temp >> CAUSE_SHIFT) & ~excepts) | (*flagp & excepts); + temp = temp << CAUSE_SHIFT; + + _FPU_SETFPSR (temp); + + /* Success. */ + return 0; +#else + /* Unsupported, so fail unless nothing needs to be done. */ + return (excepts != 0); +#endif +} diff --git a/sysdeps/csky/fpu/ftestexcept.c b/sysdeps/csky/fpu/ftestexcept.c new file mode 100644 index 0000000..23f7f0b --- /dev/null +++ b/sysdeps/csky/fpu/ftestexcept.c @@ -0,0 +1,35 @@ +/* Test exception in current environment. + Copyright (C) 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 +#include +#include + +int +fetestexcept (int excepts) +{ +#ifdef __csky_hard_float__ + return libc_fetestexcept_vfp (excepts); +#else + /* Unsupported, return 0. */ + return 0; +#endif +} +libm_hidden_def (fetestexcept) diff --git a/sysdeps/csky/fpu_control.h b/sysdeps/csky/fpu_control.h new file mode 100644 index 0000000..2238bd1 --- /dev/null +++ b/sysdeps/csky/fpu_control.h @@ -0,0 +1,150 @@ +/* FPU control word bits. C-SKY version. + Copyright (C) 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 + +/* + * CSKY FPU floating point control register bits. + * + * 31-28 -> reserved (read as 0, write with 0) + * 27 -> 0: flush denormalized results to zero + * 1: flush denormalized results to signed minimal normal number. + * 26 -> reserved (read as 0, write with 0) + * 25-24 -> rounding control + * 23-6 -> reserved (read as 0, write with 0) + * 5 -> enable exception for input denormalized exception + * 4 -> enable exception for inexact exception + * 3 -> enable exception for underflow exception + * 2 -> enable exception for overflow exception + * 1 -> enable exception for division by zero exception + * 0 -> enable exception for invalid operation exception + * + * Rounding Control: + * 00 - rounding to nearest (RN) + * 01 - rounding toward zero (RZ) + * 10 - rounding (up) toward plus infinity (RP) + * 11 - rounding (down)toward minus infinity (RM) + * + * CSKY FPU floating point exception status register bits. + * + * 15 -> accumulate bit for any exception + * 14 -> reserved (read as 0, write with 0) + * 13 -> cause bit for input denormalized exception + * 12 -> cause bit for inexact exception + * 11 -> cause bit for underflow exception + * 10 -> cause bit for overflow exception + * 9 -> cause bit for division by zero exception + * 8 -> cause bit for invalid operation exception + * 7 -> flag bit for any exception + * 6 -> reserved (read as 0, write with 0) + * 5 -> flag exception for input denormalized exception + * 4 -> flag exception for inexact exception + * 3 -> flag exception for underflow exception + * 2 -> flag exception for overflow exception + * 1 -> flag exception for division by zero exception + * 0 -> flag exception for invalid operation exception + */ + +#include + +#ifdef __csky_soft_float__ + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +# define _FPU_GETCW(cw) (cw) = 0 +# define _FPU_SETCW(cw) (void) (cw) +# define _FPU_GETFPSR(cw) (cw) = 0 +# define _FPU_SETFPSR(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else /* !__csky_soft_float__ */ + +/* masking of interrupts */ +# define _FPU_MASK_IDE (1 << 5) /* input denormalized exception */ +# define _FPU_MASK_IXE (1 << 4) /* inexact exception */ +# define _FPU_MASK_UFE (1 << 3) /* underflow exception */ +# define _FPU_MASK_OFE (1 << 2) /* overflow exception */ +# define _FPU_MASK_DZE (1 << 1) /* division by zero exception */ +# define _FPU_MASK_IOE (1 << 0) /* invalid operation exception */ + +# define _FPU_MASK_FEA (1 << 15) /* case for any exception */ +# define _FPU_MASK_FEC (1 << 7) /* flag for any exception */ + +/* flush denormalized numbers to zero */ +# define _FPU_FLUSH_TZ 0x8000000 + +/* rounding control */ +# define _FPU_RC_NEAREST (0x0 << 24) /* RECOMMENDED */ +# define _FPU_RC_ZERO (0x1 << 24) +# define _FPU_RC_UP (0x2 << 24) +# define _FPU_RC_DOWN (0x3 << 24) + +# define _FPU_RESERVED 0xf4ffffc0 /* Reserved bits in cw */ +# define _FPU_FPSR_RESERVED 0x3fff0000 + +/* The fdlibm code requires strict IEEE double precision arithmetic, + and no interrupts for exceptions, rounding to nearest. */ + +# define _FPU_DEFAULT 0x00000000 +# define _FPU_FPSR_DEFAULT 0x00000000 + +/* IEEE: same as above, but exceptions */ +# define _FPU_FPCR_IEEE 0x0000001F +# define _FPU_FPSR_IEEE 0x00000000 + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +# if (__CSKY__ == 2) +# define _FPU_GETCW(cw) __asm__ volatile ("mfcr %0, cr<1, 2>" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("mtcr %0, cr<1, 2>" : : "r" (cw)) +# define _FPU_GETFPSR(cw) __asm__ volatile ("mfcr %0, cr<2, 2>" : "=r" (cw)) +# define _FPU_SETFPSR(cw) __asm__ volatile ("mtcr %0, cr<2, 2>" : : "r" (cw)) +# else /* __CSKY__ != 2 */ +# define _FPU_GETCW(cw) __asm__ volatile ("1: cprcr %0, cpcr2 \n" \ + " btsti %0, 31 \n" \ + " bt 1b \n" \ + " cprcr %0, cpcr1\n" : "=b" (cw)) + +# define _FPU_SETCW(cw) __asm__ volatile ("1: cprcr r7, cpcr2 \n" \ + " btsti r7, 31 \n" \ + " bt 1b \n" \ + " cpwcr %0, cpcr1 \n" \ + : : "b" (cw) : "r7") + +# define _FPU_GETFPSR(cw) __asm__ volatile ("1: cprcr %0, cpcr2 \n" \ + " btsti %0, 31 \n" \ + " bt 1b \n" \ + " cprcr %0, cpcr4\n" : "=b" (cw)) + +# define _FPU_SETFPSR(cw) __asm__ volatile ("1: cprcr r7, cpcr2 \n" \ + " btsti r7, 31 \n" \ + " bt 1b \n" \ + " cpwcr %0, cpcr4 \n" \ + : : "b" (cw) : "r7") +# endif /* __CSKY__ != 2 */ + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* !__csky_soft_float__ */ + +#endif /* fpu_control.h */