Message ID | 20220708065255.2316410-13-caiyinyu@loongson.cn |
---|---|
State | New |
Headers | show |
Series | GLIBC LoongArch PATCHES | expand |
Looks good, some minor style comment below. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> On 08/07/22 03:52, caiyinyu wrote: > --- > sysdeps/loongarch/fpu/fclrexcpt.c | 46 + > sysdeps/loongarch/fpu/fedisblxcpt.c | 39 + > sysdeps/loongarch/fpu/feenablxcpt.c | 39 + > sysdeps/loongarch/fpu/fegetenv.c | 31 + > sysdeps/loongarch/fpu/fegetexcept.c | 32 + > sysdeps/loongarch/fpu/fegetmode.c | 27 + > sysdeps/loongarch/fpu/fegetround.c | 33 + > sysdeps/loongarch/fpu/feholdexcpt.c | 40 + > sysdeps/loongarch/fpu/fenv_libc.h | 30 + > sysdeps/loongarch/fpu/fesetenv.c | 42 + > sysdeps/loongarch/fpu/fesetexcept.c | 32 + > sysdeps/loongarch/fpu/fesetmode.c | 38 + > sysdeps/loongarch/fpu/fesetround.c | 44 + > sysdeps/loongarch/fpu/feupdateenv.c | 43 + > sysdeps/loongarch/fpu/fgetexcptflg.c | 38 + > sysdeps/loongarch/fpu/fraiseexcpt.c | 75 + > sysdeps/loongarch/fpu/fsetexcptflg.c | 41 + > sysdeps/loongarch/fpu/ftestexcept.c | 32 + > .../loongarch/fpu/math-use-builtins-sqrt.h | 4 + > sysdeps/loongarch/lp64/libm-test-ulps | 1412 +++++++++++++++++ > sysdeps/loongarch/lp64/libm-test-ulps-name | 1 + > sysdeps/loongarch/math_private.h | 248 +++ > 22 files changed, 2367 insertions(+) > create mode 100644 sysdeps/loongarch/fpu/fclrexcpt.c > create mode 100644 sysdeps/loongarch/fpu/fedisblxcpt.c > create mode 100644 sysdeps/loongarch/fpu/feenablxcpt.c > create mode 100644 sysdeps/loongarch/fpu/fegetenv.c > create mode 100644 sysdeps/loongarch/fpu/fegetexcept.c > create mode 100644 sysdeps/loongarch/fpu/fegetmode.c > create mode 100644 sysdeps/loongarch/fpu/fegetround.c > create mode 100644 sysdeps/loongarch/fpu/feholdexcpt.c > create mode 100644 sysdeps/loongarch/fpu/fenv_libc.h > create mode 100644 sysdeps/loongarch/fpu/fesetenv.c > create mode 100644 sysdeps/loongarch/fpu/fesetexcept.c > create mode 100644 sysdeps/loongarch/fpu/fesetmode.c > create mode 100644 sysdeps/loongarch/fpu/fesetround.c > create mode 100644 sysdeps/loongarch/fpu/feupdateenv.c > create mode 100644 sysdeps/loongarch/fpu/fgetexcptflg.c > create mode 100644 sysdeps/loongarch/fpu/fraiseexcpt.c > create mode 100644 sysdeps/loongarch/fpu/fsetexcptflg.c > create mode 100644 sysdeps/loongarch/fpu/ftestexcept.c > create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-sqrt.h > create mode 100644 sysdeps/loongarch/lp64/libm-test-ulps > create mode 100644 sysdeps/loongarch/lp64/libm-test-ulps-name > create mode 100644 sysdeps/loongarch/math_private.h > > diff --git a/sysdeps/loongarch/fpu/fclrexcpt.c b/sysdeps/loongarch/fpu/fclrexcpt.c > new file mode 100644 > index 0000000000..e9f33a1658 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fclrexcpt.c > @@ -0,0 +1,46 @@ > +/* Clear given exceptions in current floating-point environment. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fenv_libc.h> > +#include <fpu_control.h> > + > +int > +feclearexcept (int excepts) > +{ > + int cw; > + > + /* Mask out unsupported bits/exceptions. */ > + excepts &= FE_ALL_EXCEPT; > + > + /* Read the complete control word. */ > + _FPU_GETCW (cw); > + > + /* Clear exception flag bits and cause bits. If the cause bit is not > + cleared, the next CTC instruction (just below) will re-generate the > + exception. */ > + > + cw &= ~(excepts | (excepts << CAUSE_SHIFT)); > + > + /* Put the new data in effect. */ > + _FPU_SETCW (cw); > + > + /* Success. */ > + return 0; > +} > +libm_hidden_def (feclearexcept) > diff --git a/sysdeps/loongarch/fpu/fedisblxcpt.c b/sysdeps/loongarch/fpu/fedisblxcpt.c > new file mode 100644 > index 0000000000..add62946fd > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fedisblxcpt.c > @@ -0,0 +1,39 @@ > +/* Disable floating-point exceptions. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fenv_libc.h> > +#include <fpu_control.h> > + > +int > +fedisableexcept (int excepts) > +{ > + 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; > +} > diff --git a/sysdeps/loongarch/fpu/feenablxcpt.c b/sysdeps/loongarch/fpu/feenablxcpt.c > new file mode 100644 > index 0000000000..ed809341f6 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/feenablxcpt.c > @@ -0,0 +1,39 @@ > +/* Enable floating-point exceptions. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fenv_libc.h> > +#include <fpu_control.h> > + > +int > +feenableexcept (int excepts) > +{ > + 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; > +} > diff --git a/sysdeps/loongarch/fpu/fegetenv.c b/sysdeps/loongarch/fpu/fegetenv.c > new file mode 100644 > index 0000000000..5a2a3d34dc > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fegetenv.c > @@ -0,0 +1,31 @@ > +/* Store current floating-point environment. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +__fegetenv (fenv_t *envp) > +{ > + _FPU_GETCW (*envp); > + > + /* Success. */ > + return 0; > +} > +libm_hidden_def (__fegetenv) weak_alias (__fegetenv, fegetenv) > +libm_hidden_weak (fegetenv) > diff --git a/sysdeps/loongarch/fpu/fegetexcept.c b/sysdeps/loongarch/fpu/fegetexcept.c > new file mode 100644 > index 0000000000..ba1c1466f4 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fegetexcept.c > @@ -0,0 +1,32 @@ > +/* Get enabled floating-point exceptions. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fenv_libc.h> > +#include <fpu_control.h> > + > +int > +fegetexcept (void) > +{ > + unsigned int exc; > + > + /* Get the current control word. */ > + _FPU_GETCW (exc); > + > + return (exc & ENABLE_MASK) << ENABLE_SHIFT; > +} > diff --git a/sysdeps/loongarch/fpu/fegetmode.c b/sysdeps/loongarch/fpu/fegetmode.c > new file mode 100644 > index 0000000000..e3517e34f6 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fegetmode.c > @@ -0,0 +1,27 @@ > +/* Store current floating-point control modes. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +fegetmode (femode_t *modep) > +{ > + _FPU_GETCW (*modep); > + return 0; > +} > diff --git a/sysdeps/loongarch/fpu/fegetround.c b/sysdeps/loongarch/fpu/fegetround.c > new file mode 100644 > index 0000000000..ff6113eb04 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fegetround.c > @@ -0,0 +1,33 @@ > +/* Return current rounding direction. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +__fegetround (void) > +{ > + int cw; > + > + /* Get control word. */ > + _FPU_GETCW (cw); > + > + return cw & _FPU_RC_MASK; > +} > +libm_hidden_def (__fegetround) weak_alias (__fegetround, fegetround) > +libm_hidden_weak (fegetround) > diff --git a/sysdeps/loongarch/fpu/feholdexcpt.c b/sysdeps/loongarch/fpu/feholdexcpt.c > new file mode 100644 > index 0000000000..e4f9f6a23b > --- /dev/null > +++ b/sysdeps/loongarch/fpu/feholdexcpt.c > @@ -0,0 +1,40 @@ > +/* Store current floating-point environment and clear exceptions. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +__feholdexcept (fenv_t *envp) > +{ > + fpu_control_t cw; > + > + /* Save the current state. */ > + _FPU_GETCW (cw); > + envp->__fp_control_register = cw; > + > + /* Clear all exception enable bits and flags. */ > + cw &= ~(_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I > + | FE_ALL_EXCEPT); > + _FPU_SETCW (cw); > + > + return 0; > +} > + > +libm_hidden_def (__feholdexcept) weak_alias (__feholdexcept, feholdexcept) > +libm_hidden_weak (feholdexcept) > diff --git a/sysdeps/loongarch/fpu/fenv_libc.h b/sysdeps/loongarch/fpu/fenv_libc.h > new file mode 100644 > index 0000000000..8360ae0377 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fenv_libc.h > @@ -0,0 +1,30 @@ > +/* Internal libc stuff for floating point environment routines. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#ifndef _FENV_LIBC_H > +#define _FENV_LIBC_H 1 > + > +/* Mask for enabling exceptions and for the CAUSE bits. */ > +#define ENABLE_MASK 0x0000001FU > +#define CAUSE_MASK 0x1F000000U > + > +/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ > +#define ENABLE_SHIFT 16 > +#define CAUSE_SHIFT 8 > + > +#endif /* _FENV_LIBC_H */ > diff --git a/sysdeps/loongarch/fpu/fesetenv.c b/sysdeps/loongarch/fpu/fesetenv.c > new file mode 100644 > index 0000000000..c10bd11ef9 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fesetenv.c > @@ -0,0 +1,42 @@ > +/* Install given floating-point environment. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +__fesetenv (const fenv_t *envp) > +{ > + fpu_control_t cw; > + > + /* Read first current state to flush fpu pipeline. */ > + _FPU_GETCW (cw); > + > + if (envp == FE_DFL_ENV) > + _FPU_SETCW (_FPU_DEFAULT); > + else if (envp == FE_NOMASK_ENV) > + _FPU_SETCW (_FPU_IEEE); > + else > + _FPU_SETCW (envp->__fp_control_register); > + > + /* Success. */ > + return 0; > +} > + > +libm_hidden_def (__fesetenv) weak_alias (__fesetenv, fesetenv) > +libm_hidden_weak (fesetenv) > diff --git a/sysdeps/loongarch/fpu/fesetexcept.c b/sysdeps/loongarch/fpu/fesetexcept.c > new file mode 100644 > index 0000000000..ad76d52d9e > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fesetexcept.c > @@ -0,0 +1,32 @@ > +/* Set given exception flags. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +fesetexcept (int excepts) > +{ > + fpu_control_t temp; > + > + _FPU_GETCW (temp); > + temp |= excepts & FE_ALL_EXCEPT; > + _FPU_SETCW (temp); > + > + return 0; > +} > diff --git a/sysdeps/loongarch/fpu/fesetmode.c b/sysdeps/loongarch/fpu/fesetmode.c > new file mode 100644 > index 0000000000..fc52fc114b > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fesetmode.c > @@ -0,0 +1,38 @@ > +/* Install given floating-point control modes. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +#define FCSR_STATUS 0x1f1f0000 > + > +int > +fesetmode (const femode_t *modep) > +{ > + fpu_control_t cw; > + > + _FPU_GETCW (cw); > + cw &= FCSR_STATUS; > + if (modep == FE_DFL_MODE) > + cw |= _FPU_DEFAULT; > + else > + cw |= *modep & ~FCSR_STATUS; > + _FPU_SETCW (cw); > + > + return 0; > +} > diff --git a/sysdeps/loongarch/fpu/fesetround.c b/sysdeps/loongarch/fpu/fesetround.c > new file mode 100644 > index 0000000000..32acac5f96 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fesetround.c > @@ -0,0 +1,44 @@ > +/* Set current rounding direction. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +__fesetround (int round) > +{ > + fpu_control_t cw; > + > + if ((round & ~_FPU_RC_MASK) != 0) > + /* ROUND is no valid rounding mode. */ > + return 1; > + > + /* Get current state. */ > + _FPU_GETCW (cw); > + > + /* Set rounding bits. */ > + cw &= ~_FPU_RC_MASK; > + cw |= round; > + /* Set new state. */ > + _FPU_SETCW (cw); > + > + return 0; > +} > + > +libm_hidden_def (__fesetround) weak_alias (__fesetround, fesetround) > +libm_hidden_weak (fesetround) > diff --git a/sysdeps/loongarch/fpu/feupdateenv.c b/sysdeps/loongarch/fpu/feupdateenv.c > new file mode 100644 > index 0000000000..5ad862a61d > --- /dev/null > +++ b/sysdeps/loongarch/fpu/feupdateenv.c > @@ -0,0 +1,43 @@ > +/* Install given floating-point environment and raise exceptions. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +__feupdateenv (const fenv_t *envp) > +{ > + int temp; > + > + /* Save current exceptions. */ > + _FPU_GETCW (temp); > + temp &= FE_ALL_EXCEPT; > + > + /* Install new environment. */ > + __fesetenv (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; > +} > +libm_hidden_def (__feupdateenv) weak_alias (__feupdateenv, feupdateenv) > +libm_hidden_weak (feupdateenv) > diff --git a/sysdeps/loongarch/fpu/fgetexcptflg.c b/sysdeps/loongarch/fpu/fgetexcptflg.c > new file mode 100644 > index 0000000000..6130c632c9 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fgetexcptflg.c > @@ -0,0 +1,38 @@ > +/* Store current representation for exceptions. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +fegetexceptflag (fexcept_t *flagp, int excepts) > +{ > + fpu_control_t temp; > + > + /* Get the current exceptions. */ > + _FPU_GETCW (temp); > + > + /* We only save the relevant bits here. In particular, care has to be > + taken with the CAUSE bits, as an inadvertent restore later on could > + generate unexpected exceptions. */ > + > + *flagp = temp & excepts & FE_ALL_EXCEPT; > + > + /* Success. */ > + return 0; > +} > diff --git a/sysdeps/loongarch/fpu/fraiseexcpt.c b/sysdeps/loongarch/fpu/fraiseexcpt.c > new file mode 100644 > index 0000000000..135a848bb5 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fraiseexcpt.c > @@ -0,0 +1,75 @@ > +/* Raise given exceptions. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > +#include <float.h> > + > +int > +__feraiseexcept (int excepts) > +{ > + const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX, fp_min = FLT_MIN, > + fp_1e32 = 1.0e32f, fp_two = 2.0, fp_three = 3.0; I think the usual way to declar variable are one per line: const float fp_zero = 0.0f; And I think it would be better to use the expect suffix 'f' on all declarations. > + > + /* Raise exceptions represented by EXPECTS. But we must raise only > + one signal at a time. It is important that if the overflow/underflow > + exception and the inexact exception are given at the same time, > + the overflow/underflow exception follows the inexact exception. */ > + > + /* First: invalid exception. */ > + if (FE_INVALID & excepts) > + __asm__ __volatile__("fdiv.s $f0,%0,%0\n\t" > + : > + : "f"(fp_zero) > + : "$f0"); > + > + /* Next: division by zero. */ > + if (FE_DIVBYZERO & excepts) > + __asm__ __volatile__("fdiv.s $f0,%0,%1\n\t" > + : > + : "f"(fp_one), "f"(fp_zero) > + : "$f0"); > + > + /* Next: overflow. */ > + if (FE_OVERFLOW & excepts) > + /* There's no way to raise overflow without also raising inexact. */ > + __asm__ __volatile__("fadd.s $f0,%0,%1\n\t" > + : > + : "f"(fp_max), "f"(fp_1e32) > + : "$f0"); > + > + /* Next: underflow. */ > + if (FE_UNDERFLOW & excepts) > + __asm__ __volatile__("fdiv.s $f0,%0,%1\n\t" > + : > + : "f"(fp_min), "f"(fp_three) > + : "$f0"); > + > + /* Last: inexact. */ > + if (FE_INEXACT & excepts) > + __asm__ __volatile__("fdiv.s $f0, %0, %1\n\t" > + : > + : "f"(fp_two), "f"(fp_three) > + : "$f0"); > + > + /* Success. */ > + return 0; > +} > + > +libm_hidden_def (__feraiseexcept) weak_alias (__feraiseexcept, feraiseexcept) > +libm_hidden_weak (feraiseexcept) > diff --git a/sysdeps/loongarch/fpu/fsetexcptflg.c b/sysdeps/loongarch/fpu/fsetexcptflg.c > new file mode 100644 > index 0000000000..9c135a663d > --- /dev/null > +++ b/sysdeps/loongarch/fpu/fsetexcptflg.c > @@ -0,0 +1,41 @@ > +/* Set floating-point environment exception handling. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +fesetexceptflag (const fexcept_t *flagp, int excepts) > +{ > + fpu_control_t temp; > + > + /* Get the current exceptions. */ > + _FPU_GETCW (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 & ~excepts) | (*flagp & excepts); > + > + _FPU_SETCW (temp); > + > + /* Success. */ > + return 0; > +} > diff --git a/sysdeps/loongarch/fpu/ftestexcept.c b/sysdeps/loongarch/fpu/ftestexcept.c > new file mode 100644 > index 0000000000..b9563b7ae1 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/ftestexcept.c > @@ -0,0 +1,32 @@ > +/* Test exception in current environment. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <fenv.h> > +#include <fpu_control.h> > + > +int > +fetestexcept (int excepts) > +{ > + int cw; > + > + /* Get current control word. */ > + _FPU_GETCW (cw); > + > + return cw & excepts & FE_ALL_EXCEPT; > +} > +libm_hidden_def (fetestexcept) > diff --git a/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h b/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h > new file mode 100644 > index 0000000000..e94c915ba6 > --- /dev/null > +++ b/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h > @@ -0,0 +1,4 @@ > +#define USE_SQRT_BUILTIN 1 > +#define USE_SQRTF_BUILTIN 1 > +#define USE_SQRTL_BUILTIN 0 > +#define USE_SQRTF128_BUILTIN 0 > diff --git a/sysdeps/loongarch/lp64/libm-test-ulps b/sysdeps/loongarch/lp64/libm-test-ulps > new file mode 100644 > index 0000000000..c711531eec > --- /dev/null > +++ b/sysdeps/loongarch/lp64/libm-test-ulps > @@ -0,0 +1,1412 @@ > +# Begin of automatic generation > + > +# Maximal error of functions: > +Function: "acos": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "acos_downward": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "acos_towardzero": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "acos_upward": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "acosh": > +double: 2 > +float: 2 > +ldouble: 4 > + > +Function: "acosh_downward": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: "acosh_towardzero": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: "acosh_upward": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: "asin": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "asin_downward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "asin_towardzero": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "asin_upward": > +double: 2 > +float: 1 > +ldouble: 2 > + > +Function: "asinh": > +double: 2 > +float: 2 > +ldouble: 4 > + > +Function: "asinh_downward": > +double: 3 > +float: 3 > +ldouble: 4 > + > +Function: "asinh_towardzero": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: "asinh_upward": > +double: 3 > +float: 3 > +ldouble: 4 > + > +Function: "atan": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "atan2": > +float: 2 > +ldouble: 2 > + > +Function: "atan2_downward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: "atan2_towardzero": > +double: 1 > +float: 2 > +ldouble: 3 > + > +Function: "atan2_upward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: "atan_downward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: "atan_towardzero": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "atan_upward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: "atanh": > +double: 2 > +float: 2 > +ldouble: 4 > + > +Function: "atanh_downward": > +double: 3 > +float: 3 > +ldouble: 4 > + > +Function: "atanh_towardzero": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: "atanh_upward": > +double: 3 > +float: 3 > +ldouble: 4 > + > +Function: "cabs": > +double: 1 > +ldouble: 1 > + > +Function: "cabs_downward": > +double: 1 > +ldouble: 1 > + > +Function: "cabs_towardzero": > +double: 1 > +ldouble: 1 > + > +Function: "cabs_upward": > +double: 1 > +ldouble: 1 > + > +Function: Real part of "cacos": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "cacos": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "cacos_downward": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "cacos_downward": > +double: 5 > +float: 3 > +ldouble: 6 > + > +Function: Real part of "cacos_towardzero": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "cacos_towardzero": > +double: 4 > +float: 2 > +ldouble: 5 > + > +Function: Real part of "cacos_upward": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "cacos_upward": > +double: 5 > +float: 7 > +ldouble: 7 > + > +Function: Real part of "cacosh": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "cacosh": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "cacosh_downward": > +double: 4 > +float: 2 > +ldouble: 5 > + > +Function: Imaginary part of "cacosh_downward": > +double: 3 > +float: 3 > +ldouble: 4 > + > +Function: Real part of "cacosh_towardzero": > +double: 4 > +float: 2 > +ldouble: 5 > + > +Function: Imaginary part of "cacosh_towardzero": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "cacosh_upward": > +double: 4 > +float: 3 > +ldouble: 6 > + > +Function: Imaginary part of "cacosh_upward": > +double: 3 > +float: 2 > +ldouble: 4 > + > +Function: "carg": > +float: 1 > +ldouble: 2 > + > +Function: "carg_downward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: "carg_towardzero": > +double: 1 > +float: 2 > +ldouble: 3 > + > +Function: "carg_upward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "casin": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: Imaginary part of "casin": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "casin_downward": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "casin_downward": > +double: 5 > +float: 3 > +ldouble: 6 > + > +Function: Real part of "casin_towardzero": > +double: 3 > +float: 1 > +ldouble: 3 > + > +Function: Imaginary part of "casin_towardzero": > +double: 4 > +float: 2 > +ldouble: 5 > + > +Function: Real part of "casin_upward": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "casin_upward": > +double: 5 > +float: 7 > +ldouble: 7 > + > +Function: Real part of "casinh": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "casinh": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: Real part of "casinh_downward": > +double: 5 > +float: 3 > +ldouble: 6 > + > +Function: Imaginary part of "casinh_downward": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "casinh_towardzero": > +double: 4 > +float: 2 > +ldouble: 5 > + > +Function: Imaginary part of "casinh_towardzero": > +double: 3 > +float: 1 > +ldouble: 3 > + > +Function: Real part of "casinh_upward": > +double: 5 > +float: 7 > +ldouble: 7 > + > +Function: Imaginary part of "casinh_upward": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "catan": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Imaginary part of "catan": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Real part of "catan_downward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "catan_downward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "catan_towardzero": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "catan_towardzero": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "catan_upward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: Imaginary part of "catan_upward": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "catanh": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Imaginary part of "catanh": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Real part of "catanh_downward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "catanh_downward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "catanh_towardzero": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "catanh_towardzero": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "catanh_upward": > +double: 4 > +float: 4 > +ldouble: 4 > + > +Function: Imaginary part of "catanh_upward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "cbrt": > +double: 4 > +float: 1 > +ldouble: 1 > + > +Function: "cbrt_downward": > +double: 4 > +float: 1 > +ldouble: 1 > + > +Function: "cbrt_towardzero": > +double: 3 > +float: 1 > +ldouble: 1 > + > +Function: "cbrt_upward": > +double: 5 > +float: 1 > +ldouble: 1 > + > +Function: Real part of "ccos": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Imaginary part of "ccos": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Real part of "ccos_downward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: Imaginary part of "ccos_downward": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "ccos_towardzero": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "ccos_towardzero": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "ccos_upward": > +double: 1 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "ccos_upward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "ccosh": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Imaginary part of "ccosh": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Real part of "ccosh_downward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "ccosh_downward": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "ccosh_towardzero": > +double: 2 > +float: 3 > +ldouble: 2 > + > +Function: Imaginary part of "ccosh_towardzero": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "ccosh_upward": > +double: 1 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "ccosh_upward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "cexp": > +double: 2 > +float: 1 > +ldouble: 1 > + > +Function: Imaginary part of "cexp": > +double: 1 > +float: 2 > +ldouble: 1 > + > +Function: Real part of "cexp_downward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "cexp_downward": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "cexp_towardzero": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "cexp_towardzero": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "cexp_upward": > +double: 1 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "cexp_upward": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "clog": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Imaginary part of "clog": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Real part of "clog10": > +double: 3 > +float: 4 > +ldouble: 2 > + > +Function: Imaginary part of "clog10": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "clog10_downward": > +double: 5 > +float: 5 > +ldouble: 3 > + > +Function: Imaginary part of "clog10_downward": > +double: 2 > +float: 4 > +ldouble: 3 > + > +Function: Real part of "clog10_towardzero": > +double: 5 > +float: 6 > +ldouble: 4 > + > +Function: Imaginary part of "clog10_towardzero": > +double: 2 > +float: 4 > +ldouble: 3 > + > +Function: Real part of "clog10_upward": > +double: 6 > +float: 5 > +ldouble: 4 > + > +Function: Imaginary part of "clog10_upward": > +double: 2 > +float: 4 > +ldouble: 3 > + > +Function: Real part of "clog_downward": > +double: 4 > +float: 3 > +ldouble: 3 > + > +Function: Imaginary part of "clog_downward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "clog_towardzero": > +double: 4 > +float: 4 > +ldouble: 3 > + > +Function: Imaginary part of "clog_towardzero": > +double: 1 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "clog_upward": > +double: 4 > +float: 3 > +ldouble: 4 > + > +Function: Imaginary part of "clog_upward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: "cos": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "cos_downward": > +double: 1 > +float: 1 > +ldouble: 3 > + > +Function: "cos_towardzero": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "cos_upward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "cosh": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: "cosh_downward": > +double: 3 > +float: 1 > +ldouble: 3 > + > +Function: "cosh_towardzero": > +double: 3 > +float: 1 > +ldouble: 3 > + > +Function: "cosh_upward": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "cpow": > +double: 2 > +float: 5 > +ldouble: 4 > + > +Function: Imaginary part of "cpow": > +float: 2 > +ldouble: 1 > + > +Function: Real part of "cpow_downward": > +double: 5 > +float: 8 > +ldouble: 6 > + > +Function: Imaginary part of "cpow_downward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "cpow_towardzero": > +double: 5 > +float: 8 > +ldouble: 6 > + > +Function: Imaginary part of "cpow_towardzero": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "cpow_upward": > +double: 4 > +float: 1 > +ldouble: 3 > + > +Function: Imaginary part of "cpow_upward": > +double: 1 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "csin": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Imaginary part of "csin": > +ldouble: 1 > + > +Function: Real part of "csin_downward": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Imaginary part of "csin_downward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: Real part of "csin_towardzero": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Imaginary part of "csin_towardzero": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: Real part of "csin_upward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "csin_upward": > +double: 1 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "csinh": > +float: 1 > +ldouble: 1 > + > +Function: Imaginary part of "csinh": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: Real part of "csinh_downward": > +double: 2 > +float: 1 > +ldouble: 2 > + > +Function: Imaginary part of "csinh_downward": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "csinh_towardzero": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "csinh_towardzero": > +double: 3 > +float: 3 > +ldouble: 2 > + > +Function: Real part of "csinh_upward": > +double: 1 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "csinh_upward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "csqrt": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Imaginary part of "csqrt": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: Real part of "csqrt_downward": > +double: 5 > +float: 4 > +ldouble: 4 > + > +Function: Imaginary part of "csqrt_downward": > +double: 4 > +float: 3 > +ldouble: 3 > + > +Function: Real part of "csqrt_towardzero": > +double: 4 > +float: 3 > +ldouble: 3 > + > +Function: Imaginary part of "csqrt_towardzero": > +double: 4 > +float: 3 > +ldouble: 3 > + > +Function: Real part of "csqrt_upward": > +double: 5 > +float: 4 > +ldouble: 4 > + > +Function: Imaginary part of "csqrt_upward": > +double: 3 > +float: 3 > +ldouble: 3 > + > +Function: Real part of "ctan": > +double: 2 > +float: 1 > +ldouble: 3 > + > +Function: Imaginary part of "ctan": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "ctan_downward": > +double: 6 > +float: 5 > +ldouble: 4 > + > +Function: Imaginary part of "ctan_downward": > +double: 2 > +float: 2 > +ldouble: 5 > + > +Function: Real part of "ctan_towardzero": > +double: 5 > +float: 3 > +ldouble: 4 > + > +Function: Imaginary part of "ctan_towardzero": > +double: 2 > +float: 2 > +ldouble: 5 > + > +Function: Real part of "ctan_upward": > +double: 2 > +float: 4 > +ldouble: 5 > + > +Function: Imaginary part of "ctan_upward": > +double: 2 > +float: 2 > +ldouble: 5 > + > +Function: Real part of "ctanh": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: Imaginary part of "ctanh": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: Real part of "ctanh_downward": > +double: 4 > +float: 2 > +ldouble: 5 > + > +Function: Imaginary part of "ctanh_downward": > +double: 6 > +float: 5 > +ldouble: 4 > + > +Function: Real part of "ctanh_towardzero": > +double: 2 > +float: 2 > +ldouble: 5 > + > +Function: Imaginary part of "ctanh_towardzero": > +double: 5 > +float: 3 > +ldouble: 3 > + > +Function: Real part of "ctanh_upward": > +double: 2 > +float: 2 > +ldouble: 5 > + > +Function: Imaginary part of "ctanh_upward": > +double: 2 > +float: 3 > +ldouble: 5 > + > +Function: "erf": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "erf_downward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "erf_towardzero": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "erf_upward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "erfc": > +double: 5 > +float: 3 > +ldouble: 4 > + > +Function: "erfc_downward": > +double: 5 > +float: 6 > +ldouble: 5 > + > +Function: "erfc_towardzero": > +double: 3 > +float: 4 > +ldouble: 4 > + > +Function: "erfc_upward": > +double: 5 > +float: 6 > +ldouble: 5 > + > +Function: "exp": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "exp10": > +double: 2 > +ldouble: 2 > + > +Function: "exp10_downward": > +double: 3 > +float: 1 > +ldouble: 3 > + > +Function: "exp10_towardzero": > +double: 3 > +float: 1 > +ldouble: 3 > + > +Function: "exp10_upward": > +double: 2 > +float: 1 > +ldouble: 3 > + > +Function: "exp2": > +double: 1 > +ldouble: 1 > + > +Function: "exp2_downward": > +double: 1 > +ldouble: 1 > + > +Function: "exp2_towardzero": > +double: 1 > +ldouble: 1 > + > +Function: "exp2_upward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "exp_downward": > +double: 1 > +float: 1 > + > +Function: "exp_towardzero": > +double: 1 > +float: 1 > + > +Function: "exp_upward": > +double: 1 > +float: 1 > + > +Function: "expm1": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "expm1_downward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "expm1_towardzero": > +double: 1 > +float: 2 > +ldouble: 4 > + > +Function: "expm1_upward": > +double: 1 > +float: 1 > +ldouble: 3 > + > +Function: "gamma": > +double: 4 > +float: 7 > +ldouble: 5 > + > +Function: "gamma_downward": > +double: 5 > +float: 7 > +ldouble: 8 > + > +Function: "gamma_towardzero": > +double: 5 > +float: 6 > +ldouble: 5 > + > +Function: "gamma_upward": > +double: 5 > +float: 6 > +ldouble: 8 > + > +Function: "hypot": > +double: 1 > +ldouble: 1 > + > +Function: "hypot_downward": > +double: 1 > +ldouble: 1 > + > +Function: "hypot_towardzero": > +double: 1 > +ldouble: 1 > + > +Function: "hypot_upward": > +double: 1 > +ldouble: 1 > + > +Function: "j0": > +double: 3 > +float: 9 > +ldouble: 2 > + > +Function: "j0_downward": > +double: 6 > +float: 9 > +ldouble: 9 > + > +Function: "j0_towardzero": > +double: 7 > +float: 9 > +ldouble: 9 > + > +Function: "j0_upward": > +double: 9 > +float: 9 > +ldouble: 7 > + > +Function: "j1": > +double: 4 > +float: 9 > +ldouble: 4 > + > +Function: "j1_downward": > +double: 5 > +float: 8 > +ldouble: 4 > + > +Function: "j1_towardzero": > +double: 4 > +float: 8 > +ldouble: 4 > + > +Function: "j1_upward": > +double: 9 > +float: 9 > +ldouble: 3 > + > +Function: "jn": > +double: 4 > +float: 4 > +ldouble: 7 > + > +Function: "jn_downward": > +double: 5 > +float: 5 > +ldouble: 8 > + > +Function: "jn_towardzero": > +double: 5 > +float: 5 > +ldouble: 8 > + > +Function: "jn_upward": > +double: 5 > +float: 4 > +ldouble: 7 > + > +Function: "lgamma": > +double: 4 > +float: 7 > +ldouble: 5 > + > +Function: "lgamma_downward": > +double: 5 > +float: 7 > +ldouble: 8 > + > +Function: "lgamma_towardzero": > +double: 5 > +float: 6 > +ldouble: 5 > + > +Function: "lgamma_upward": > +double: 5 > +float: 6 > +ldouble: 8 > + > +Function: "log": > +double: 1 > +ldouble: 1 > + > +Function: "log10": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: "log10_downward": > +double: 2 > +float: 3 > +ldouble: 1 > + > +Function: "log10_towardzero": > +double: 2 > +float: 1 > +ldouble: 1 > + > +Function: "log10_upward": > +double: 2 > +float: 2 > +ldouble: 1 > + > +Function: "log1p": > +double: 1 > +float: 1 > +ldouble: 3 > + > +Function: "log1p_downward": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: "log1p_towardzero": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: "log1p_upward": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: "log2": > +double: 1 > +float: 1 > +ldouble: 3 > + > +Function: "log2_downward": > +double: 3 > +ldouble: 3 > + > +Function: "log2_towardzero": > +double: 2 > +ldouble: 1 > + > +Function: "log2_upward": > +double: 3 > +ldouble: 1 > + > +Function: "log_downward": > +ldouble: 1 > + > +Function: "log_towardzero": > +ldouble: 2 > + > +Function: "log_upward": > +double: 1 > +ldouble: 2 > + > +Function: "pow": > +double: 1 > +ldouble: 2 > + > +Function: "pow_downward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "pow_towardzero": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "pow_upward": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "sin": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "sin_downward": > +double: 1 > +float: 1 > +ldouble: 3 > + > +Function: "sin_towardzero": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "sin_upward": > +double: 1 > +float: 1 > +ldouble: 3 > + > +Function: "sincos": > +double: 1 > +ldouble: 1 > + > +Function: "sincos_downward": > +double: 1 > +float: 1 > +ldouble: 3 > + > +Function: "sincos_towardzero": > +double: 1 > +float: 1 > +ldouble: 2 > + > +Function: "sincos_upward": > +double: 1 > +float: 1 > +ldouble: 3 > + > +Function: "sinh": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: "sinh_downward": > +double: 3 > +float: 3 > +ldouble: 3 > + > +Function: "sinh_towardzero": > +double: 3 > +float: 2 > +ldouble: 3 > + > +Function: "sinh_upward": > +double: 3 > +float: 3 > +ldouble: 4 > + > +Function: "tan": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "tan_downward": > +double: 1 > +float: 2 > +ldouble: 1 > + > +Function: "tan_towardzero": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "tan_upward": > +double: 1 > +float: 1 > +ldouble: 1 > + > +Function: "tanh": > +double: 2 > +float: 2 > +ldouble: 2 > + > +Function: "tanh_downward": > +double: 3 > +float: 3 > +ldouble: 4 > + > +Function: "tanh_towardzero": > +double: 2 > +float: 2 > +ldouble: 3 > + > +Function: "tanh_upward": > +double: 3 > +float: 3 > +ldouble: 3 > + > +Function: "tgamma": > +double: 9 > +float: 8 > +ldouble: 4 > + > +Function: "tgamma_downward": > +double: 9 > +float: 7 > +ldouble: 5 > + > +Function: "tgamma_towardzero": > +double: 9 > +float: 7 > +ldouble: 5 > + > +Function: "tgamma_upward": > +double: 9 > +float: 8 > +ldouble: 4 > + > +Function: "y0": > +double: 3 > +float: 9 > +ldouble: 3 > + > +Function: "y0_downward": > +double: 3 > +float: 9 > +ldouble: 7 > + > +Function: "y0_towardzero": > +double: 4 > +float: 9 > +ldouble: 3 > + > +Function: "y0_upward": > +double: 3 > +float: 9 > +ldouble: 4 > + > +Function: "y1": > +double: 3 > +float: 9 > +ldouble: 5 > + > +Function: "y1_downward": > +double: 6 > +float: 9 > +ldouble: 5 > + > +Function: "y1_towardzero": > +double: 3 > +float: 9 > +ldouble: 2 > + > +Function: "y1_upward": > +double: 7 > +float: 9 > +ldouble: 5 > + > +Function: "yn": > +double: 3 > +float: 3 > +ldouble: 5 > + > +Function: "yn_downward": > +double: 3 > +float: 4 > +ldouble: 5 > + > +Function: "yn_towardzero": > +double: 3 > +float: 3 > +ldouble: 5 > + > +Function: "yn_upward": > +double: 4 > +float: 5 > +ldouble: 5 > + > +# end of automatic generation > diff --git a/sysdeps/loongarch/lp64/libm-test-ulps-name b/sysdeps/loongarch/lp64/libm-test-ulps-name > new file mode 100644 > index 0000000000..ce02281eab > --- /dev/null > +++ b/sysdeps/loongarch/lp64/libm-test-ulps-name > @@ -0,0 +1 @@ > +LoongArch 64-bit > diff --git a/sysdeps/loongarch/math_private.h b/sysdeps/loongarch/math_private.h > new file mode 100644 > index 0000000000..cdf26a78dd > --- /dev/null > +++ b/sysdeps/loongarch/math_private.h > @@ -0,0 +1,248 @@ > +/* Internal math stuff. > + Copyright (C) 2022 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 > + <https://www.gnu.org/licenses/>. */ > + > +#ifndef LOONGARCH_MATH_PRIVATE_H > +#define LOONGARCH_MATH_PRIVATE_H 1 > + > +/* Inline functions to speed up the math library implementation. The > + default versions of these routines are in generic/math_private.h > + and call fesetround, feholdexcept, etc. These routines use inlined > + code instead. */ > + > +#ifdef __loongarch_hard_float > + > +#include <fenv.h> > +#include <fenv_libc.h> > +#include <fpu_control.h> > + > +#define _FPU_MASK_ALL \ > + (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I \ > + | FE_ALL_EXCEPT) > + > +static __always_inline void > +libc_feholdexcept_loongarch (fenv_t *envp) > +{ > + fpu_control_t cw; > + > + /* Save the current state. */ > + _FPU_GETCW (cw); > + envp->__fp_control_register = cw; > + > + /* Clear all exception enable bits and flags. */ > + cw &= ~(_FPU_MASK_ALL); > + _FPU_SETCW (cw); > +} > +#define libc_feholdexcept libc_feholdexcept_loongarch > +#define libc_feholdexceptf libc_feholdexcept_loongarch > +#define libc_feholdexceptl libc_feholdexcept_loongarch > + > +static __always_inline void > +libc_fesetround_loongarch (int round) > +{ > + fpu_control_t cw; > + > + /* Get current state. */ > + _FPU_GETCW (cw); > + > + /* Set rounding bits. */ > + cw &= ~_FPU_RC_MASK; > + cw |= round; > + > + /* Set new state. */ > + _FPU_SETCW (cw); > +} > +#define libc_fesetround libc_fesetround_loongarch > +#define libc_fesetroundf libc_fesetround_loongarch > +#define libc_fesetroundl libc_fesetround_loongarch > + > +static __always_inline void > +libc_feholdexcept_setround_loongarch (fenv_t *envp, int round) > +{ > + fpu_control_t cw; > + > + /* Save the current state. */ > + _FPU_GETCW (cw); > + envp->__fp_control_register = cw; > + > + /* Clear all exception enable bits and flags. */ > + cw &= ~(_FPU_MASK_ALL); > + > + /* Set rounding bits. */ > + cw &= ~_FPU_RC_MASK; > + cw |= round; > + > + /* Set new state. */ > + _FPU_SETCW (cw); > +} > +#define libc_feholdexcept_setround libc_feholdexcept_setround_loongarch > +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_loongarch > +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_loongarch > + > +#define libc_feholdsetround libc_feholdexcept_setround_loongarch > +#define libc_feholdsetroundf libc_feholdexcept_setround_loongarch > +#define libc_feholdsetroundl libc_feholdexcept_setround_loongarch > + > +static __always_inline void > +libc_fesetenv_loongarch (fenv_t *envp) > +{ > + fpu_control_t cw __attribute__ ((unused)); > + > + /* Read current state to flush fpu pipeline. */ > + _FPU_GETCW (cw); > + > + _FPU_SETCW (envp->__fp_control_register); > +} > +#define libc_fesetenv libc_fesetenv_loongarch > +#define libc_fesetenvf libc_fesetenv_loongarch > +#define libc_fesetenvl libc_fesetenv_loongarch > + > +static __always_inline int > +libc_feupdateenv_test_loongarch (fenv_t *envp, int excepts) > +{ > + /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */ > + int cw, temp; > + > + /* Get current control word. */ > + _FPU_GETCW (cw); > + > + /* Set flag bits (which are accumulative), and *also* set the > + cause bits. The setting of the cause bits is what actually causes > + the hardware to generate the exception, if the corresponding enable > + bit is set as well. */ > + temp = cw & FE_ALL_EXCEPT; > + temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT); > + > + /* Set new state. */ > + _FPU_SETCW (temp); > + > + return cw & excepts & FE_ALL_EXCEPT; > +} > +#define libc_feupdateenv_test libc_feupdateenv_test_loongarch > +#define libc_feupdateenv_testf libc_feupdateenv_test_loongarch > +#define libc_feupdateenv_testl libc_feupdateenv_test_loongarch > + > +static __always_inline void > +libc_feupdateenv_loongarch (fenv_t *envp) > +{ > + libc_feupdateenv_test_loongarch (envp, 0); > +} > +#define libc_feupdateenv libc_feupdateenv_loongarch > +#define libc_feupdateenvf libc_feupdateenv_loongarch > +#define libc_feupdateenvl libc_feupdateenv_loongarch > + > +#define libc_feresetround libc_feupdateenv_loongarch > +#define libc_feresetroundf libc_feupdateenv_loongarch > +#define libc_feresetroundl libc_feupdateenv_loongarch > + > +static __always_inline int > +libc_fetestexcept_loongarch (int excepts) > +{ > + int cw; > + > + /* Get current control word. */ > + _FPU_GETCW (cw); > + > + return cw & excepts & FE_ALL_EXCEPT; > +} > +#define libc_fetestexcept libc_fetestexcept_loongarch > +#define libc_fetestexceptf libc_fetestexcept_loongarch > +#define libc_fetestexceptl libc_fetestexcept_loongarch > + > +/* Enable support for rounding mode context. */ > +#define HAVE_RM_CTX 1 > + > +static __always_inline void > +libc_feholdexcept_setround_loongarch_ctx (struct rm_ctx *ctx, int round) > +{ > + fpu_control_t old, new; > + > + /* Save the current state. */ > + _FPU_GETCW (old); > + ctx->env.__fp_control_register = old; > + > + /* Clear all exception enable bits and flags. */ > + new = old & ~(_FPU_MASK_ALL); > + > + /* Set rounding bits. */ > + new = (new & ~_FPU_RC_MASK) | round; > + > + if (__glibc_unlikely (new != old)) > + { > + _FPU_SETCW (new); > + ctx->updated_status = true; > + } > + else > + ctx->updated_status = false; > +} > +#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_loongarch_ctx > +#define libc_feholdexcept_setroundf_ctx \ > + libc_feholdexcept_setround_loongarch_ctx > +#define libc_feholdexcept_setroundl_ctx \ > + libc_feholdexcept_setround_loongarch_ctx > + > +static __always_inline void > +libc_fesetenv_loongarch_ctx (struct rm_ctx *ctx) > +{ > + libc_fesetenv_loongarch (&ctx->env); > +} > +#define libc_fesetenv_ctx libc_fesetenv_loongarch_ctx > +#define libc_fesetenvf_ctx libc_fesetenv_loongarch_ctx > +#define libc_fesetenvl_ctx libc_fesetenv_loongarch_ctx > + > +static __always_inline void > +libc_feupdateenv_loongarch_ctx (struct rm_ctx *ctx) > +{ > + if (__glibc_unlikely (ctx->updated_status)) > + libc_feupdateenv_test_loongarch (&ctx->env, 0); > +} > +#define libc_feupdateenv_ctx libc_feupdateenv_loongarch_ctx > +#define libc_feupdateenvf_ctx libc_feupdateenv_loongarch_ctx > +#define libc_feupdateenvl_ctx libc_feupdateenv_loongarch_ctx > +#define libc_feresetround_ctx libc_feupdateenv_loongarch_ctx > +#define libc_feresetroundf_ctx libc_feupdateenv_loongarch_ctx > +#define libc_feresetroundl_ctx libc_feupdateenv_loongarch_ctx > + > +static __always_inline void > +libc_feholdsetround_loongarch_ctx (struct rm_ctx *ctx, int round) > +{ > + fpu_control_t old, new; > + > + /* Save the current state. */ > + _FPU_GETCW (old); > + ctx->env.__fp_control_register = old; > + > + /* Set rounding bits. */ > + new = (old & ~_FPU_RC_MASK) | round; > + > + if (__glibc_unlikely (new != old)) > + { > + _FPU_SETCW (new); > + ctx->updated_status = true; > + } > + else > + ctx->updated_status = false; > +} > +#define libc_feholdsetround_ctx libc_feholdsetround_loongarch_ctx > +#define libc_feholdsetroundf_ctx libc_feholdsetround_loongarch_ctx > +#define libc_feholdsetroundl_ctx libc_feholdsetround_loongarch_ctx > + > +#endif > + > +#include_next <math_private.h> > + > +#endif
+#include <fenv.h> +#include <fpu_control.h> +#include <float.h> + +int +__feraiseexcept (int excepts) +{ + const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX, fp_min = FLT_MIN, + fp_1e32 = 1.0e32f, fp_two = 2.0, fp_three = 3.0; I think the usual way to declar variable are one per line: const float fp_zero = 0.0f; And I think it would be better to use the expect suffix 'f' on all declarations. Fixed. Thanks. >>>>>> diff --git a/sysdeps/loongarch/fpu/fraiseexcpt.c b/sysdeps/loongarch/fpu/fraiseexcpt.c index 135a848bb5..c1c612242f 100644 --- a/sysdeps/loongarch/fpu/fraiseexcpt.c +++ b/sysdeps/loongarch/fpu/fraiseexcpt.c @@ -23,8 +23,13 @@ int __feraiseexcept (int excepts) { - const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX, fp_min = FLT_MIN, - fp_1e32 = 1.0e32f, fp_two = 2.0, fp_three = 3.0; + const float fp_zero = 0.0f; + const float fp_one = 1.0f; + const float fp_max = FLT_MAX; + const float fp_min = FLT_MIN; + const float fp_1e32 = 1.0e32f; + const float fp_two = 2.0f; + const float fp_three = 3.0f; /* Raise exceptions represented by EXPECTS. But we must raise only one signal at a time. It is important that if the overflow/underflow <<<<<< 在 2022/7/14 上午3:22, Adhemerval Zanella Netto 写道: > Looks good, some minor style comment below. > > Reviewed-by: Adhemerval Zanella<adhemerval.zanella@linaro.org> > > On 08/07/22 03:52, caiyinyu wrote: >> --- >> sysdeps/loongarch/fpu/fclrexcpt.c | 46 + >> sysdeps/loongarch/fpu/fedisblxcpt.c | 39 + >> sysdeps/loongarch/fpu/feenablxcpt.c | 39 + >> sysdeps/loongarch/fpu/fegetenv.c | 31 + >> sysdeps/loongarch/fpu/fegetexcept.c | 32 + >> sysdeps/loongarch/fpu/fegetmode.c | 27 + >> sysdeps/loongarch/fpu/fegetround.c | 33 + >> sysdeps/loongarch/fpu/feholdexcpt.c | 40 + >> sysdeps/loongarch/fpu/fenv_libc.h | 30 + >> sysdeps/loongarch/fpu/fesetenv.c | 42 + >> sysdeps/loongarch/fpu/fesetexcept.c | 32 + >> sysdeps/loongarch/fpu/fesetmode.c | 38 + >> sysdeps/loongarch/fpu/fesetround.c | 44 + >> sysdeps/loongarch/fpu/feupdateenv.c | 43 + >> sysdeps/loongarch/fpu/fgetexcptflg.c | 38 + >> sysdeps/loongarch/fpu/fraiseexcpt.c | 75 + >> sysdeps/loongarch/fpu/fsetexcptflg.c | 41 + >> sysdeps/loongarch/fpu/ftestexcept.c | 32 + >> .../loongarch/fpu/math-use-builtins-sqrt.h | 4 + >> sysdeps/loongarch/lp64/libm-test-ulps | 1412 +++++++++++++++++ >> sysdeps/loongarch/lp64/libm-test-ulps-name | 1 + >> sysdeps/loongarch/math_private.h | 248 +++ >> 22 files changed, 2367 insertions(+) >> create mode 100644 sysdeps/loongarch/fpu/fclrexcpt.c >> create mode 100644 sysdeps/loongarch/fpu/fedisblxcpt.c >> create mode 100644 sysdeps/loongarch/fpu/feenablxcpt.c >> create mode 100644 sysdeps/loongarch/fpu/fegetenv.c >> create mode 100644 sysdeps/loongarch/fpu/fegetexcept.c >> create mode 100644 sysdeps/loongarch/fpu/fegetmode.c >> create mode 100644 sysdeps/loongarch/fpu/fegetround.c >> create mode 100644 sysdeps/loongarch/fpu/feholdexcpt.c >> create mode 100644 sysdeps/loongarch/fpu/fenv_libc.h >> create mode 100644 sysdeps/loongarch/fpu/fesetenv.c >> create mode 100644 sysdeps/loongarch/fpu/fesetexcept.c >> create mode 100644 sysdeps/loongarch/fpu/fesetmode.c >> create mode 100644 sysdeps/loongarch/fpu/fesetround.c >> create mode 100644 sysdeps/loongarch/fpu/feupdateenv.c >> create mode 100644 sysdeps/loongarch/fpu/fgetexcptflg.c >> create mode 100644 sysdeps/loongarch/fpu/fraiseexcpt.c >> create mode 100644 sysdeps/loongarch/fpu/fsetexcptflg.c >> create mode 100644 sysdeps/loongarch/fpu/ftestexcept.c >> create mode 100644 sysdeps/loongarch/fpu/math-use-builtins-sqrt.h >> create mode 100644 sysdeps/loongarch/lp64/libm-test-ulps >> create mode 100644 sysdeps/loongarch/lp64/libm-test-ulps-name >> create mode 100644 sysdeps/loongarch/math_private.h >> >> diff --git a/sysdeps/loongarch/fpu/fclrexcpt.c b/sysdeps/loongarch/fpu/fclrexcpt.c >> new file mode 100644 >> index 0000000000..e9f33a1658 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fclrexcpt.c >> @@ -0,0 +1,46 @@ >> +/* Clear given exceptions in current floating-point environment. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fenv_libc.h> >> +#include <fpu_control.h> >> + >> +int >> +feclearexcept (int excepts) >> +{ >> + int cw; >> + >> + /* Mask out unsupported bits/exceptions. */ >> + excepts &= FE_ALL_EXCEPT; >> + >> + /* Read the complete control word. */ >> + _FPU_GETCW (cw); >> + >> + /* Clear exception flag bits and cause bits. If the cause bit is not >> + cleared, the next CTC instruction (just below) will re-generate the >> + exception. */ >> + >> + cw &= ~(excepts | (excepts << CAUSE_SHIFT)); >> + >> + /* Put the new data in effect. */ >> + _FPU_SETCW (cw); >> + >> + /* Success. */ >> + return 0; >> +} >> +libm_hidden_def (feclearexcept) >> diff --git a/sysdeps/loongarch/fpu/fedisblxcpt.c b/sysdeps/loongarch/fpu/fedisblxcpt.c >> new file mode 100644 >> index 0000000000..add62946fd >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fedisblxcpt.c >> @@ -0,0 +1,39 @@ >> +/* Disable floating-point exceptions. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fenv_libc.h> >> +#include <fpu_control.h> >> + >> +int >> +fedisableexcept (int excepts) >> +{ >> + 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; >> +} >> diff --git a/sysdeps/loongarch/fpu/feenablxcpt.c b/sysdeps/loongarch/fpu/feenablxcpt.c >> new file mode 100644 >> index 0000000000..ed809341f6 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/feenablxcpt.c >> @@ -0,0 +1,39 @@ >> +/* Enable floating-point exceptions. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fenv_libc.h> >> +#include <fpu_control.h> >> + >> +int >> +feenableexcept (int excepts) >> +{ >> + 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; >> +} >> diff --git a/sysdeps/loongarch/fpu/fegetenv.c b/sysdeps/loongarch/fpu/fegetenv.c >> new file mode 100644 >> index 0000000000..5a2a3d34dc >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fegetenv.c >> @@ -0,0 +1,31 @@ >> +/* Store current floating-point environment. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +__fegetenv (fenv_t *envp) >> +{ >> + _FPU_GETCW (*envp); >> + >> + /* Success. */ >> + return 0; >> +} >> +libm_hidden_def (__fegetenv) weak_alias (__fegetenv, fegetenv) >> +libm_hidden_weak (fegetenv) >> diff --git a/sysdeps/loongarch/fpu/fegetexcept.c b/sysdeps/loongarch/fpu/fegetexcept.c >> new file mode 100644 >> index 0000000000..ba1c1466f4 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fegetexcept.c >> @@ -0,0 +1,32 @@ >> +/* Get enabled floating-point exceptions. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fenv_libc.h> >> +#include <fpu_control.h> >> + >> +int >> +fegetexcept (void) >> +{ >> + unsigned int exc; >> + >> + /* Get the current control word. */ >> + _FPU_GETCW (exc); >> + >> + return (exc & ENABLE_MASK) << ENABLE_SHIFT; >> +} >> diff --git a/sysdeps/loongarch/fpu/fegetmode.c b/sysdeps/loongarch/fpu/fegetmode.c >> new file mode 100644 >> index 0000000000..e3517e34f6 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fegetmode.c >> @@ -0,0 +1,27 @@ >> +/* Store current floating-point control modes. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +fegetmode (femode_t *modep) >> +{ >> + _FPU_GETCW (*modep); >> + return 0; >> +} >> diff --git a/sysdeps/loongarch/fpu/fegetround.c b/sysdeps/loongarch/fpu/fegetround.c >> new file mode 100644 >> index 0000000000..ff6113eb04 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fegetround.c >> @@ -0,0 +1,33 @@ >> +/* Return current rounding direction. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +__fegetround (void) >> +{ >> + int cw; >> + >> + /* Get control word. */ >> + _FPU_GETCW (cw); >> + >> + return cw & _FPU_RC_MASK; >> +} >> +libm_hidden_def (__fegetround) weak_alias (__fegetround, fegetround) >> +libm_hidden_weak (fegetround) >> diff --git a/sysdeps/loongarch/fpu/feholdexcpt.c b/sysdeps/loongarch/fpu/feholdexcpt.c >> new file mode 100644 >> index 0000000000..e4f9f6a23b >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/feholdexcpt.c >> @@ -0,0 +1,40 @@ >> +/* Store current floating-point environment and clear exceptions. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +__feholdexcept (fenv_t *envp) >> +{ >> + fpu_control_t cw; >> + >> + /* Save the current state. */ >> + _FPU_GETCW (cw); >> + envp->__fp_control_register = cw; >> + >> + /* Clear all exception enable bits and flags. */ >> + cw &= ~(_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I >> + | FE_ALL_EXCEPT); >> + _FPU_SETCW (cw); >> + >> + return 0; >> +} >> + >> +libm_hidden_def (__feholdexcept) weak_alias (__feholdexcept, feholdexcept) >> +libm_hidden_weak (feholdexcept) >> diff --git a/sysdeps/loongarch/fpu/fenv_libc.h b/sysdeps/loongarch/fpu/fenv_libc.h >> new file mode 100644 >> index 0000000000..8360ae0377 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fenv_libc.h >> @@ -0,0 +1,30 @@ >> +/* Internal libc stuff for floating point environment routines. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#ifndef _FENV_LIBC_H >> +#define _FENV_LIBC_H 1 >> + >> +/* Mask for enabling exceptions and for the CAUSE bits. */ >> +#define ENABLE_MASK 0x0000001FU >> +#define CAUSE_MASK 0x1F000000U >> + >> +/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ >> +#define ENABLE_SHIFT 16 >> +#define CAUSE_SHIFT 8 >> + >> +#endif /* _FENV_LIBC_H */ >> diff --git a/sysdeps/loongarch/fpu/fesetenv.c b/sysdeps/loongarch/fpu/fesetenv.c >> new file mode 100644 >> index 0000000000..c10bd11ef9 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fesetenv.c >> @@ -0,0 +1,42 @@ >> +/* Install given floating-point environment. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +__fesetenv (const fenv_t *envp) >> +{ >> + fpu_control_t cw; >> + >> + /* Read first current state to flush fpu pipeline. */ >> + _FPU_GETCW (cw); >> + >> + if (envp == FE_DFL_ENV) >> + _FPU_SETCW (_FPU_DEFAULT); >> + else if (envp == FE_NOMASK_ENV) >> + _FPU_SETCW (_FPU_IEEE); >> + else >> + _FPU_SETCW (envp->__fp_control_register); >> + >> + /* Success. */ >> + return 0; >> +} >> + >> +libm_hidden_def (__fesetenv) weak_alias (__fesetenv, fesetenv) >> +libm_hidden_weak (fesetenv) >> diff --git a/sysdeps/loongarch/fpu/fesetexcept.c b/sysdeps/loongarch/fpu/fesetexcept.c >> new file mode 100644 >> index 0000000000..ad76d52d9e >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fesetexcept.c >> @@ -0,0 +1,32 @@ >> +/* Set given exception flags. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +fesetexcept (int excepts) >> +{ >> + fpu_control_t temp; >> + >> + _FPU_GETCW (temp); >> + temp |= excepts & FE_ALL_EXCEPT; >> + _FPU_SETCW (temp); >> + >> + return 0; >> +} >> diff --git a/sysdeps/loongarch/fpu/fesetmode.c b/sysdeps/loongarch/fpu/fesetmode.c >> new file mode 100644 >> index 0000000000..fc52fc114b >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fesetmode.c >> @@ -0,0 +1,38 @@ >> +/* Install given floating-point control modes. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +#define FCSR_STATUS 0x1f1f0000 >> + >> +int >> +fesetmode (const femode_t *modep) >> +{ >> + fpu_control_t cw; >> + >> + _FPU_GETCW (cw); >> + cw &= FCSR_STATUS; >> + if (modep == FE_DFL_MODE) >> + cw |= _FPU_DEFAULT; >> + else >> + cw |= *modep & ~FCSR_STATUS; >> + _FPU_SETCW (cw); >> + >> + return 0; >> +} >> diff --git a/sysdeps/loongarch/fpu/fesetround.c b/sysdeps/loongarch/fpu/fesetround.c >> new file mode 100644 >> index 0000000000..32acac5f96 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fesetround.c >> @@ -0,0 +1,44 @@ >> +/* Set current rounding direction. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +__fesetround (int round) >> +{ >> + fpu_control_t cw; >> + >> + if ((round & ~_FPU_RC_MASK) != 0) >> + /* ROUND is no valid rounding mode. */ >> + return 1; >> + >> + /* Get current state. */ >> + _FPU_GETCW (cw); >> + >> + /* Set rounding bits. */ >> + cw &= ~_FPU_RC_MASK; >> + cw |= round; >> + /* Set new state. */ >> + _FPU_SETCW (cw); >> + >> + return 0; >> +} >> + >> +libm_hidden_def (__fesetround) weak_alias (__fesetround, fesetround) >> +libm_hidden_weak (fesetround) >> diff --git a/sysdeps/loongarch/fpu/feupdateenv.c b/sysdeps/loongarch/fpu/feupdateenv.c >> new file mode 100644 >> index 0000000000..5ad862a61d >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/feupdateenv.c >> @@ -0,0 +1,43 @@ >> +/* Install given floating-point environment and raise exceptions. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +__feupdateenv (const fenv_t *envp) >> +{ >> + int temp; >> + >> + /* Save current exceptions. */ >> + _FPU_GETCW (temp); >> + temp &= FE_ALL_EXCEPT; >> + >> + /* Install new environment. */ >> + __fesetenv (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; >> +} >> +libm_hidden_def (__feupdateenv) weak_alias (__feupdateenv, feupdateenv) >> +libm_hidden_weak (feupdateenv) >> diff --git a/sysdeps/loongarch/fpu/fgetexcptflg.c b/sysdeps/loongarch/fpu/fgetexcptflg.c >> new file mode 100644 >> index 0000000000..6130c632c9 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fgetexcptflg.c >> @@ -0,0 +1,38 @@ >> +/* Store current representation for exceptions. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +fegetexceptflag (fexcept_t *flagp, int excepts) >> +{ >> + fpu_control_t temp; >> + >> + /* Get the current exceptions. */ >> + _FPU_GETCW (temp); >> + >> + /* We only save the relevant bits here. In particular, care has to be >> + taken with the CAUSE bits, as an inadvertent restore later on could >> + generate unexpected exceptions. */ >> + >> + *flagp = temp & excepts & FE_ALL_EXCEPT; >> + >> + /* Success. */ >> + return 0; >> +} >> diff --git a/sysdeps/loongarch/fpu/fraiseexcpt.c b/sysdeps/loongarch/fpu/fraiseexcpt.c >> new file mode 100644 >> index 0000000000..135a848bb5 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fraiseexcpt.c >> @@ -0,0 +1,75 @@ >> +/* Raise given exceptions. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> +#include <float.h> >> + >> +int >> +__feraiseexcept (int excepts) >> +{ >> + const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX, fp_min = FLT_MIN, >> + fp_1e32 = 1.0e32f, fp_two = 2.0, fp_three = 3.0; > I think the usual way to declar variable are one per line: > > const float fp_zero = 0.0f; > > And I think it would be better to use the expect suffix 'f' on all declarations. > >> + >> + /* Raise exceptions represented by EXPECTS. But we must raise only >> + one signal at a time. It is important that if the overflow/underflow >> + exception and the inexact exception are given at the same time, >> + the overflow/underflow exception follows the inexact exception. */ >> + >> + /* First: invalid exception. */ >> + if (FE_INVALID & excepts) >> + __asm__ __volatile__("fdiv.s $f0,%0,%0\n\t" >> + : >> + : "f"(fp_zero) >> + : "$f0"); >> + >> + /* Next: division by zero. */ >> + if (FE_DIVBYZERO & excepts) >> + __asm__ __volatile__("fdiv.s $f0,%0,%1\n\t" >> + : >> + : "f"(fp_one), "f"(fp_zero) >> + : "$f0"); >> + >> + /* Next: overflow. */ >> + if (FE_OVERFLOW & excepts) >> + /* There's no way to raise overflow without also raising inexact. */ >> + __asm__ __volatile__("fadd.s $f0,%0,%1\n\t" >> + : >> + : "f"(fp_max), "f"(fp_1e32) >> + : "$f0"); >> + >> + /* Next: underflow. */ >> + if (FE_UNDERFLOW & excepts) >> + __asm__ __volatile__("fdiv.s $f0,%0,%1\n\t" >> + : >> + : "f"(fp_min), "f"(fp_three) >> + : "$f0"); >> + >> + /* Last: inexact. */ >> + if (FE_INEXACT & excepts) >> + __asm__ __volatile__("fdiv.s $f0, %0, %1\n\t" >> + : >> + : "f"(fp_two), "f"(fp_three) >> + : "$f0"); >> + >> + /* Success. */ >> + return 0; >> +} >> + >> +libm_hidden_def (__feraiseexcept) weak_alias (__feraiseexcept, feraiseexcept) >> +libm_hidden_weak (feraiseexcept) >> diff --git a/sysdeps/loongarch/fpu/fsetexcptflg.c b/sysdeps/loongarch/fpu/fsetexcptflg.c >> new file mode 100644 >> index 0000000000..9c135a663d >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/fsetexcptflg.c >> @@ -0,0 +1,41 @@ >> +/* Set floating-point environment exception handling. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +fesetexceptflag (const fexcept_t *flagp, int excepts) >> +{ >> + fpu_control_t temp; >> + >> + /* Get the current exceptions. */ >> + _FPU_GETCW (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 & ~excepts) | (*flagp & excepts); >> + >> + _FPU_SETCW (temp); >> + >> + /* Success. */ >> + return 0; >> +} >> diff --git a/sysdeps/loongarch/fpu/ftestexcept.c b/sysdeps/loongarch/fpu/ftestexcept.c >> new file mode 100644 >> index 0000000000..b9563b7ae1 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/ftestexcept.c >> @@ -0,0 +1,32 @@ >> +/* Test exception in current environment. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#include <fenv.h> >> +#include <fpu_control.h> >> + >> +int >> +fetestexcept (int excepts) >> +{ >> + int cw; >> + >> + /* Get current control word. */ >> + _FPU_GETCW (cw); >> + >> + return cw & excepts & FE_ALL_EXCEPT; >> +} >> +libm_hidden_def (fetestexcept) >> diff --git a/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h b/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h >> new file mode 100644 >> index 0000000000..e94c915ba6 >> --- /dev/null >> +++ b/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h >> @@ -0,0 +1,4 @@ >> +#define USE_SQRT_BUILTIN 1 >> +#define USE_SQRTF_BUILTIN 1 >> +#define USE_SQRTL_BUILTIN 0 >> +#define USE_SQRTF128_BUILTIN 0 >> diff --git a/sysdeps/loongarch/lp64/libm-test-ulps b/sysdeps/loongarch/lp64/libm-test-ulps >> new file mode 100644 >> index 0000000000..c711531eec >> --- /dev/null >> +++ b/sysdeps/loongarch/lp64/libm-test-ulps >> @@ -0,0 +1,1412 @@ >> +# Begin of automatic generation >> + >> +# Maximal error of functions: >> +Function: "acos": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "acos_downward": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "acos_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "acos_upward": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "acosh": >> +double: 2 >> +float: 2 >> +ldouble: 4 >> + >> +Function: "acosh_downward": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: "acosh_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "acosh_upward": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: "asin": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "asin_downward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "asin_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "asin_upward": >> +double: 2 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "asinh": >> +double: 2 >> +float: 2 >> +ldouble: 4 >> + >> +Function: "asinh_downward": >> +double: 3 >> +float: 3 >> +ldouble: 4 >> + >> +Function: "asinh_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "asinh_upward": >> +double: 3 >> +float: 3 >> +ldouble: 4 >> + >> +Function: "atan": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "atan2": >> +float: 2 >> +ldouble: 2 >> + >> +Function: "atan2_downward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "atan2_towardzero": >> +double: 1 >> +float: 2 >> +ldouble: 3 >> + >> +Function: "atan2_upward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "atan_downward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "atan_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "atan_upward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "atanh": >> +double: 2 >> +float: 2 >> +ldouble: 4 >> + >> +Function: "atanh_downward": >> +double: 3 >> +float: 3 >> +ldouble: 4 >> + >> +Function: "atanh_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "atanh_upward": >> +double: 3 >> +float: 3 >> +ldouble: 4 >> + >> +Function: "cabs": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "cabs_downward": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "cabs_towardzero": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "cabs_upward": >> +double: 1 >> +ldouble: 1 >> + >> +Function: Real part of "cacos": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "cacos": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "cacos_downward": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "cacos_downward": >> +double: 5 >> +float: 3 >> +ldouble: 6 >> + >> +Function: Real part of "cacos_towardzero": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "cacos_towardzero": >> +double: 4 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Real part of "cacos_upward": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "cacos_upward": >> +double: 5 >> +float: 7 >> +ldouble: 7 >> + >> +Function: Real part of "cacosh": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "cacosh": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "cacosh_downward": >> +double: 4 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Imaginary part of "cacosh_downward": >> +double: 3 >> +float: 3 >> +ldouble: 4 >> + >> +Function: Real part of "cacosh_towardzero": >> +double: 4 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Imaginary part of "cacosh_towardzero": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "cacosh_upward": >> +double: 4 >> +float: 3 >> +ldouble: 6 >> + >> +Function: Imaginary part of "cacosh_upward": >> +double: 3 >> +float: 2 >> +ldouble: 4 >> + >> +Function: "carg": >> +float: 1 >> +ldouble: 2 >> + >> +Function: "carg_downward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "carg_towardzero": >> +double: 1 >> +float: 2 >> +ldouble: 3 >> + >> +Function: "carg_upward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "casin": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: Imaginary part of "casin": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "casin_downward": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "casin_downward": >> +double: 5 >> +float: 3 >> +ldouble: 6 >> + >> +Function: Real part of "casin_towardzero": >> +double: 3 >> +float: 1 >> +ldouble: 3 >> + >> +Function: Imaginary part of "casin_towardzero": >> +double: 4 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Real part of "casin_upward": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "casin_upward": >> +double: 5 >> +float: 7 >> +ldouble: 7 >> + >> +Function: Real part of "casinh": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "casinh": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: Real part of "casinh_downward": >> +double: 5 >> +float: 3 >> +ldouble: 6 >> + >> +Function: Imaginary part of "casinh_downward": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "casinh_towardzero": >> +double: 4 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Imaginary part of "casinh_towardzero": >> +double: 3 >> +float: 1 >> +ldouble: 3 >> + >> +Function: Real part of "casinh_upward": >> +double: 5 >> +float: 7 >> +ldouble: 7 >> + >> +Function: Imaginary part of "casinh_upward": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "catan": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Imaginary part of "catan": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Real part of "catan_downward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "catan_downward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "catan_towardzero": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "catan_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "catan_upward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: Imaginary part of "catan_upward": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "catanh": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Imaginary part of "catanh": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Real part of "catanh_downward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "catanh_downward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "catanh_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "catanh_towardzero": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "catanh_upward": >> +double: 4 >> +float: 4 >> +ldouble: 4 >> + >> +Function: Imaginary part of "catanh_upward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "cbrt": >> +double: 4 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "cbrt_downward": >> +double: 4 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "cbrt_towardzero": >> +double: 3 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "cbrt_upward": >> +double: 5 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Real part of "ccos": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Imaginary part of "ccos": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Real part of "ccos_downward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: Imaginary part of "ccos_downward": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "ccos_towardzero": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "ccos_towardzero": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "ccos_upward": >> +double: 1 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "ccos_upward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "ccosh": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Imaginary part of "ccosh": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Real part of "ccosh_downward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "ccosh_downward": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "ccosh_towardzero": >> +double: 2 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Imaginary part of "ccosh_towardzero": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "ccosh_upward": >> +double: 1 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "ccosh_upward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "cexp": >> +double: 2 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Imaginary part of "cexp": >> +double: 1 >> +float: 2 >> +ldouble: 1 >> + >> +Function: Real part of "cexp_downward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "cexp_downward": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "cexp_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "cexp_towardzero": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "cexp_upward": >> +double: 1 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "cexp_upward": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "clog": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Imaginary part of "clog": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Real part of "clog10": >> +double: 3 >> +float: 4 >> +ldouble: 2 >> + >> +Function: Imaginary part of "clog10": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "clog10_downward": >> +double: 5 >> +float: 5 >> +ldouble: 3 >> + >> +Function: Imaginary part of "clog10_downward": >> +double: 2 >> +float: 4 >> +ldouble: 3 >> + >> +Function: Real part of "clog10_towardzero": >> +double: 5 >> +float: 6 >> +ldouble: 4 >> + >> +Function: Imaginary part of "clog10_towardzero": >> +double: 2 >> +float: 4 >> +ldouble: 3 >> + >> +Function: Real part of "clog10_upward": >> +double: 6 >> +float: 5 >> +ldouble: 4 >> + >> +Function: Imaginary part of "clog10_upward": >> +double: 2 >> +float: 4 >> +ldouble: 3 >> + >> +Function: Real part of "clog_downward": >> +double: 4 >> +float: 3 >> +ldouble: 3 >> + >> +Function: Imaginary part of "clog_downward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "clog_towardzero": >> +double: 4 >> +float: 4 >> +ldouble: 3 >> + >> +Function: Imaginary part of "clog_towardzero": >> +double: 1 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "clog_upward": >> +double: 4 >> +float: 3 >> +ldouble: 4 >> + >> +Function: Imaginary part of "clog_upward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "cos": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "cos_downward": >> +double: 1 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "cos_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "cos_upward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "cosh": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "cosh_downward": >> +double: 3 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "cosh_towardzero": >> +double: 3 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "cosh_upward": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "cpow": >> +double: 2 >> +float: 5 >> +ldouble: 4 >> + >> +Function: Imaginary part of "cpow": >> +float: 2 >> +ldouble: 1 >> + >> +Function: Real part of "cpow_downward": >> +double: 5 >> +float: 8 >> +ldouble: 6 >> + >> +Function: Imaginary part of "cpow_downward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "cpow_towardzero": >> +double: 5 >> +float: 8 >> +ldouble: 6 >> + >> +Function: Imaginary part of "cpow_towardzero": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "cpow_upward": >> +double: 4 >> +float: 1 >> +ldouble: 3 >> + >> +Function: Imaginary part of "cpow_upward": >> +double: 1 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "csin": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Imaginary part of "csin": >> +ldouble: 1 >> + >> +Function: Real part of "csin_downward": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Imaginary part of "csin_downward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: Real part of "csin_towardzero": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Imaginary part of "csin_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: Real part of "csin_upward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "csin_upward": >> +double: 1 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "csinh": >> +float: 1 >> +ldouble: 1 >> + >> +Function: Imaginary part of "csinh": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: Real part of "csinh_downward": >> +double: 2 >> +float: 1 >> +ldouble: 2 >> + >> +Function: Imaginary part of "csinh_downward": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "csinh_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "csinh_towardzero": >> +double: 3 >> +float: 3 >> +ldouble: 2 >> + >> +Function: Real part of "csinh_upward": >> +double: 1 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "csinh_upward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "csqrt": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Imaginary part of "csqrt": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: Real part of "csqrt_downward": >> +double: 5 >> +float: 4 >> +ldouble: 4 >> + >> +Function: Imaginary part of "csqrt_downward": >> +double: 4 >> +float: 3 >> +ldouble: 3 >> + >> +Function: Real part of "csqrt_towardzero": >> +double: 4 >> +float: 3 >> +ldouble: 3 >> + >> +Function: Imaginary part of "csqrt_towardzero": >> +double: 4 >> +float: 3 >> +ldouble: 3 >> + >> +Function: Real part of "csqrt_upward": >> +double: 5 >> +float: 4 >> +ldouble: 4 >> + >> +Function: Imaginary part of "csqrt_upward": >> +double: 3 >> +float: 3 >> +ldouble: 3 >> + >> +Function: Real part of "ctan": >> +double: 2 >> +float: 1 >> +ldouble: 3 >> + >> +Function: Imaginary part of "ctan": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "ctan_downward": >> +double: 6 >> +float: 5 >> +ldouble: 4 >> + >> +Function: Imaginary part of "ctan_downward": >> +double: 2 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Real part of "ctan_towardzero": >> +double: 5 >> +float: 3 >> +ldouble: 4 >> + >> +Function: Imaginary part of "ctan_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Real part of "ctan_upward": >> +double: 2 >> +float: 4 >> +ldouble: 5 >> + >> +Function: Imaginary part of "ctan_upward": >> +double: 2 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Real part of "ctanh": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Imaginary part of "ctanh": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: Real part of "ctanh_downward": >> +double: 4 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Imaginary part of "ctanh_downward": >> +double: 6 >> +float: 5 >> +ldouble: 4 >> + >> +Function: Real part of "ctanh_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Imaginary part of "ctanh_towardzero": >> +double: 5 >> +float: 3 >> +ldouble: 3 >> + >> +Function: Real part of "ctanh_upward": >> +double: 2 >> +float: 2 >> +ldouble: 5 >> + >> +Function: Imaginary part of "ctanh_upward": >> +double: 2 >> +float: 3 >> +ldouble: 5 >> + >> +Function: "erf": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "erf_downward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "erf_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "erf_upward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "erfc": >> +double: 5 >> +float: 3 >> +ldouble: 4 >> + >> +Function: "erfc_downward": >> +double: 5 >> +float: 6 >> +ldouble: 5 >> + >> +Function: "erfc_towardzero": >> +double: 3 >> +float: 4 >> +ldouble: 4 >> + >> +Function: "erfc_upward": >> +double: 5 >> +float: 6 >> +ldouble: 5 >> + >> +Function: "exp": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "exp10": >> +double: 2 >> +ldouble: 2 >> + >> +Function: "exp10_downward": >> +double: 3 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "exp10_towardzero": >> +double: 3 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "exp10_upward": >> +double: 2 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "exp2": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "exp2_downward": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "exp2_towardzero": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "exp2_upward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "exp_downward": >> +double: 1 >> +float: 1 >> + >> +Function: "exp_towardzero": >> +double: 1 >> +float: 1 >> + >> +Function: "exp_upward": >> +double: 1 >> +float: 1 >> + >> +Function: "expm1": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "expm1_downward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "expm1_towardzero": >> +double: 1 >> +float: 2 >> +ldouble: 4 >> + >> +Function: "expm1_upward": >> +double: 1 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "gamma": >> +double: 4 >> +float: 7 >> +ldouble: 5 >> + >> +Function: "gamma_downward": >> +double: 5 >> +float: 7 >> +ldouble: 8 >> + >> +Function: "gamma_towardzero": >> +double: 5 >> +float: 6 >> +ldouble: 5 >> + >> +Function: "gamma_upward": >> +double: 5 >> +float: 6 >> +ldouble: 8 >> + >> +Function: "hypot": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "hypot_downward": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "hypot_towardzero": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "hypot_upward": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "j0": >> +double: 3 >> +float: 9 >> +ldouble: 2 >> + >> +Function: "j0_downward": >> +double: 6 >> +float: 9 >> +ldouble: 9 >> + >> +Function: "j0_towardzero": >> +double: 7 >> +float: 9 >> +ldouble: 9 >> + >> +Function: "j0_upward": >> +double: 9 >> +float: 9 >> +ldouble: 7 >> + >> +Function: "j1": >> +double: 4 >> +float: 9 >> +ldouble: 4 >> + >> +Function: "j1_downward": >> +double: 5 >> +float: 8 >> +ldouble: 4 >> + >> +Function: "j1_towardzero": >> +double: 4 >> +float: 8 >> +ldouble: 4 >> + >> +Function: "j1_upward": >> +double: 9 >> +float: 9 >> +ldouble: 3 >> + >> +Function: "jn": >> +double: 4 >> +float: 4 >> +ldouble: 7 >> + >> +Function: "jn_downward": >> +double: 5 >> +float: 5 >> +ldouble: 8 >> + >> +Function: "jn_towardzero": >> +double: 5 >> +float: 5 >> +ldouble: 8 >> + >> +Function: "jn_upward": >> +double: 5 >> +float: 4 >> +ldouble: 7 >> + >> +Function: "lgamma": >> +double: 4 >> +float: 7 >> +ldouble: 5 >> + >> +Function: "lgamma_downward": >> +double: 5 >> +float: 7 >> +ldouble: 8 >> + >> +Function: "lgamma_towardzero": >> +double: 5 >> +float: 6 >> +ldouble: 5 >> + >> +Function: "lgamma_upward": >> +double: 5 >> +float: 6 >> +ldouble: 8 >> + >> +Function: "log": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "log10": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "log10_downward": >> +double: 2 >> +float: 3 >> +ldouble: 1 >> + >> +Function: "log10_towardzero": >> +double: 2 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "log10_upward": >> +double: 2 >> +float: 2 >> +ldouble: 1 >> + >> +Function: "log1p": >> +double: 1 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "log1p_downward": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: "log1p_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: "log1p_upward": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "log2": >> +double: 1 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "log2_downward": >> +double: 3 >> +ldouble: 3 >> + >> +Function: "log2_towardzero": >> +double: 2 >> +ldouble: 1 >> + >> +Function: "log2_upward": >> +double: 3 >> +ldouble: 1 >> + >> +Function: "log_downward": >> +ldouble: 1 >> + >> +Function: "log_towardzero": >> +ldouble: 2 >> + >> +Function: "log_upward": >> +double: 1 >> +ldouble: 2 >> + >> +Function: "pow": >> +double: 1 >> +ldouble: 2 >> + >> +Function: "pow_downward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "pow_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "pow_upward": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "sin": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "sin_downward": >> +double: 1 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "sin_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "sin_upward": >> +double: 1 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "sincos": >> +double: 1 >> +ldouble: 1 >> + >> +Function: "sincos_downward": >> +double: 1 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "sincos_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 2 >> + >> +Function: "sincos_upward": >> +double: 1 >> +float: 1 >> +ldouble: 3 >> + >> +Function: "sinh": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "sinh_downward": >> +double: 3 >> +float: 3 >> +ldouble: 3 >> + >> +Function: "sinh_towardzero": >> +double: 3 >> +float: 2 >> +ldouble: 3 >> + >> +Function: "sinh_upward": >> +double: 3 >> +float: 3 >> +ldouble: 4 >> + >> +Function: "tan": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "tan_downward": >> +double: 1 >> +float: 2 >> +ldouble: 1 >> + >> +Function: "tan_towardzero": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "tan_upward": >> +double: 1 >> +float: 1 >> +ldouble: 1 >> + >> +Function: "tanh": >> +double: 2 >> +float: 2 >> +ldouble: 2 >> + >> +Function: "tanh_downward": >> +double: 3 >> +float: 3 >> +ldouble: 4 >> + >> +Function: "tanh_towardzero": >> +double: 2 >> +float: 2 >> +ldouble: 3 >> + >> +Function: "tanh_upward": >> +double: 3 >> +float: 3 >> +ldouble: 3 >> + >> +Function: "tgamma": >> +double: 9 >> +float: 8 >> +ldouble: 4 >> + >> +Function: "tgamma_downward": >> +double: 9 >> +float: 7 >> +ldouble: 5 >> + >> +Function: "tgamma_towardzero": >> +double: 9 >> +float: 7 >> +ldouble: 5 >> + >> +Function: "tgamma_upward": >> +double: 9 >> +float: 8 >> +ldouble: 4 >> + >> +Function: "y0": >> +double: 3 >> +float: 9 >> +ldouble: 3 >> + >> +Function: "y0_downward": >> +double: 3 >> +float: 9 >> +ldouble: 7 >> + >> +Function: "y0_towardzero": >> +double: 4 >> +float: 9 >> +ldouble: 3 >> + >> +Function: "y0_upward": >> +double: 3 >> +float: 9 >> +ldouble: 4 >> + >> +Function: "y1": >> +double: 3 >> +float: 9 >> +ldouble: 5 >> + >> +Function: "y1_downward": >> +double: 6 >> +float: 9 >> +ldouble: 5 >> + >> +Function: "y1_towardzero": >> +double: 3 >> +float: 9 >> +ldouble: 2 >> + >> +Function: "y1_upward": >> +double: 7 >> +float: 9 >> +ldouble: 5 >> + >> +Function: "yn": >> +double: 3 >> +float: 3 >> +ldouble: 5 >> + >> +Function: "yn_downward": >> +double: 3 >> +float: 4 >> +ldouble: 5 >> + >> +Function: "yn_towardzero": >> +double: 3 >> +float: 3 >> +ldouble: 5 >> + >> +Function: "yn_upward": >> +double: 4 >> +float: 5 >> +ldouble: 5 >> + >> +# end of automatic generation >> diff --git a/sysdeps/loongarch/lp64/libm-test-ulps-name b/sysdeps/loongarch/lp64/libm-test-ulps-name >> new file mode 100644 >> index 0000000000..ce02281eab >> --- /dev/null >> +++ b/sysdeps/loongarch/lp64/libm-test-ulps-name >> @@ -0,0 +1 @@ >> +LoongArch 64-bit >> diff --git a/sysdeps/loongarch/math_private.h b/sysdeps/loongarch/math_private.h >> new file mode 100644 >> index 0000000000..cdf26a78dd >> --- /dev/null >> +++ b/sysdeps/loongarch/math_private.h >> @@ -0,0 +1,248 @@ >> +/* Internal math stuff. >> + Copyright (C) 2022 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 >> +<https://www.gnu.org/licenses/>. */ >> + >> +#ifndef LOONGARCH_MATH_PRIVATE_H >> +#define LOONGARCH_MATH_PRIVATE_H 1 >> + >> +/* Inline functions to speed up the math library implementation. The >> + default versions of these routines are in generic/math_private.h >> + and call fesetround, feholdexcept, etc. These routines use inlined >> + code instead. */ >> + >> +#ifdef __loongarch_hard_float >> + >> +#include <fenv.h> >> +#include <fenv_libc.h> >> +#include <fpu_control.h> >> + >> +#define _FPU_MASK_ALL \ >> + (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I \ >> + | FE_ALL_EXCEPT) >> + >> +static __always_inline void >> +libc_feholdexcept_loongarch (fenv_t *envp) >> +{ >> + fpu_control_t cw; >> + >> + /* Save the current state. */ >> + _FPU_GETCW (cw); >> + envp->__fp_control_register = cw; >> + >> + /* Clear all exception enable bits and flags. */ >> + cw &= ~(_FPU_MASK_ALL); >> + _FPU_SETCW (cw); >> +} >> +#define libc_feholdexcept libc_feholdexcept_loongarch >> +#define libc_feholdexceptf libc_feholdexcept_loongarch >> +#define libc_feholdexceptl libc_feholdexcept_loongarch >> + >> +static __always_inline void >> +libc_fesetround_loongarch (int round) >> +{ >> + fpu_control_t cw; >> + >> + /* Get current state. */ >> + _FPU_GETCW (cw); >> + >> + /* Set rounding bits. */ >> + cw &= ~_FPU_RC_MASK; >> + cw |= round; >> + >> + /* Set new state. */ >> + _FPU_SETCW (cw); >> +} >> +#define libc_fesetround libc_fesetround_loongarch >> +#define libc_fesetroundf libc_fesetround_loongarch >> +#define libc_fesetroundl libc_fesetround_loongarch >> + >> +static __always_inline void >> +libc_feholdexcept_setround_loongarch (fenv_t *envp, int round) >> +{ >> + fpu_control_t cw; >> + >> + /* Save the current state. */ >> + _FPU_GETCW (cw); >> + envp->__fp_control_register = cw; >> + >> + /* Clear all exception enable bits and flags. */ >> + cw &= ~(_FPU_MASK_ALL); >> + >> + /* Set rounding bits. */ >> + cw &= ~_FPU_RC_MASK; >> + cw |= round; >> + >> + /* Set new state. */ >> + _FPU_SETCW (cw); >> +} >> +#define libc_feholdexcept_setround libc_feholdexcept_setround_loongarch >> +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_loongarch >> +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_loongarch >> + >> +#define libc_feholdsetround libc_feholdexcept_setround_loongarch >> +#define libc_feholdsetroundf libc_feholdexcept_setround_loongarch >> +#define libc_feholdsetroundl libc_feholdexcept_setround_loongarch >> + >> +static __always_inline void >> +libc_fesetenv_loongarch (fenv_t *envp) >> +{ >> + fpu_control_t cw __attribute__ ((unused)); >> + >> + /* Read current state to flush fpu pipeline. */ >> + _FPU_GETCW (cw); >> + >> + _FPU_SETCW (envp->__fp_control_register); >> +} >> +#define libc_fesetenv libc_fesetenv_loongarch >> +#define libc_fesetenvf libc_fesetenv_loongarch >> +#define libc_fesetenvl libc_fesetenv_loongarch >> + >> +static __always_inline int >> +libc_feupdateenv_test_loongarch (fenv_t *envp, int excepts) >> +{ >> + /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */ >> + int cw, temp; >> + >> + /* Get current control word. */ >> + _FPU_GETCW (cw); >> + >> + /* Set flag bits (which are accumulative), and *also* set the >> + cause bits. The setting of the cause bits is what actually causes >> + the hardware to generate the exception, if the corresponding enable >> + bit is set as well. */ >> + temp = cw & FE_ALL_EXCEPT; >> + temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT); >> + >> + /* Set new state. */ >> + _FPU_SETCW (temp); >> + >> + return cw & excepts & FE_ALL_EXCEPT; >> +} >> +#define libc_feupdateenv_test libc_feupdateenv_test_loongarch >> +#define libc_feupdateenv_testf libc_feupdateenv_test_loongarch >> +#define libc_feupdateenv_testl libc_feupdateenv_test_loongarch >> + >> +static __always_inline void >> +libc_feupdateenv_loongarch (fenv_t *envp) >> +{ >> + libc_feupdateenv_test_loongarch (envp, 0); >> +} >> +#define libc_feupdateenv libc_feupdateenv_loongarch >> +#define libc_feupdateenvf libc_feupdateenv_loongarch >> +#define libc_feupdateenvl libc_feupdateenv_loongarch >> + >> +#define libc_feresetround libc_feupdateenv_loongarch >> +#define libc_feresetroundf libc_feupdateenv_loongarch >> +#define libc_feresetroundl libc_feupdateenv_loongarch >> + >> +static __always_inline int >> +libc_fetestexcept_loongarch (int excepts) >> +{ >> + int cw; >> + >> + /* Get current control word. */ >> + _FPU_GETCW (cw); >> + >> + return cw & excepts & FE_ALL_EXCEPT; >> +} >> +#define libc_fetestexcept libc_fetestexcept_loongarch >> +#define libc_fetestexceptf libc_fetestexcept_loongarch >> +#define libc_fetestexceptl libc_fetestexcept_loongarch >> + >> +/* Enable support for rounding mode context. */ >> +#define HAVE_RM_CTX 1 >> + >> +static __always_inline void >> +libc_feholdexcept_setround_loongarch_ctx (struct rm_ctx *ctx, int round) >> +{ >> + fpu_control_t old, new; >> + >> + /* Save the current state. */ >> + _FPU_GETCW (old); >> + ctx->env.__fp_control_register = old; >> + >> + /* Clear all exception enable bits and flags. */ >> + new = old & ~(_FPU_MASK_ALL); >> + >> + /* Set rounding bits. */ >> + new = (new & ~_FPU_RC_MASK) | round; >> + >> + if (__glibc_unlikely (new != old)) >> + { >> + _FPU_SETCW (new); >> + ctx->updated_status = true; >> + } >> + else >> + ctx->updated_status = false; >> +} >> +#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_loongarch_ctx >> +#define libc_feholdexcept_setroundf_ctx \ >> + libc_feholdexcept_setround_loongarch_ctx >> +#define libc_feholdexcept_setroundl_ctx \ >> + libc_feholdexcept_setround_loongarch_ctx >> + >> +static __always_inline void >> +libc_fesetenv_loongarch_ctx (struct rm_ctx *ctx) >> +{ >> + libc_fesetenv_loongarch (&ctx->env); >> +} >> +#define libc_fesetenv_ctx libc_fesetenv_loongarch_ctx >> +#define libc_fesetenvf_ctx libc_fesetenv_loongarch_ctx >> +#define libc_fesetenvl_ctx libc_fesetenv_loongarch_ctx >> + >> +static __always_inline void >> +libc_feupdateenv_loongarch_ctx (struct rm_ctx *ctx) >> +{ >> + if (__glibc_unlikely (ctx->updated_status)) >> + libc_feupdateenv_test_loongarch (&ctx->env, 0); >> +} >> +#define libc_feupdateenv_ctx libc_feupdateenv_loongarch_ctx >> +#define libc_feupdateenvf_ctx libc_feupdateenv_loongarch_ctx >> +#define libc_feupdateenvl_ctx libc_feupdateenv_loongarch_ctx >> +#define libc_feresetround_ctx libc_feupdateenv_loongarch_ctx >> +#define libc_feresetroundf_ctx libc_feupdateenv_loongarch_ctx >> +#define libc_feresetroundl_ctx libc_feupdateenv_loongarch_ctx >> + >> +static __always_inline void >> +libc_feholdsetround_loongarch_ctx (struct rm_ctx *ctx, int round) >> +{ >> + fpu_control_t old, new; >> + >> + /* Save the current state. */ >> + _FPU_GETCW (old); >> + ctx->env.__fp_control_register = old; >> + >> + /* Set rounding bits. */ >> + new = (old & ~_FPU_RC_MASK) | round; >> + >> + if (__glibc_unlikely (new != old)) >> + { >> + _FPU_SETCW (new); >> + ctx->updated_status = true; >> + } >> + else >> + ctx->updated_status = false; >> +} >> +#define libc_feholdsetround_ctx libc_feholdsetround_loongarch_ctx >> +#define libc_feholdsetroundf_ctx libc_feholdsetround_loongarch_ctx >> +#define libc_feholdsetroundl_ctx libc_feholdsetround_loongarch_ctx >> + >> +#endif >> + >> +#include_next <math_private.h> >> + >> +#endif
diff --git a/sysdeps/loongarch/fpu/fclrexcpt.c b/sysdeps/loongarch/fpu/fclrexcpt.c new file mode 100644 index 0000000000..e9f33a1658 --- /dev/null +++ b/sysdeps/loongarch/fpu/fclrexcpt.c @@ -0,0 +1,46 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fenv_libc.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ + int cw; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Read the complete control word. */ + _FPU_GETCW (cw); + + /* Clear exception flag bits and cause bits. If the cause bit is not + cleared, the next CTC instruction (just below) will re-generate the + exception. */ + + cw &= ~(excepts | (excepts << CAUSE_SHIFT)); + + /* Put the new data in effect. */ + _FPU_SETCW (cw); + + /* Success. */ + return 0; +} +libm_hidden_def (feclearexcept) diff --git a/sysdeps/loongarch/fpu/fedisblxcpt.c b/sysdeps/loongarch/fpu/fedisblxcpt.c new file mode 100644 index 0000000000..add62946fd --- /dev/null +++ b/sysdeps/loongarch/fpu/fedisblxcpt.c @@ -0,0 +1,39 @@ +/* Disable floating-point exceptions. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fenv_libc.h> +#include <fpu_control.h> + +int +fedisableexcept (int excepts) +{ + 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; +} diff --git a/sysdeps/loongarch/fpu/feenablxcpt.c b/sysdeps/loongarch/fpu/feenablxcpt.c new file mode 100644 index 0000000000..ed809341f6 --- /dev/null +++ b/sysdeps/loongarch/fpu/feenablxcpt.c @@ -0,0 +1,39 @@ +/* Enable floating-point exceptions. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fenv_libc.h> +#include <fpu_control.h> + +int +feenableexcept (int excepts) +{ + 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; +} diff --git a/sysdeps/loongarch/fpu/fegetenv.c b/sysdeps/loongarch/fpu/fegetenv.c new file mode 100644 index 0000000000..5a2a3d34dc --- /dev/null +++ b/sysdeps/loongarch/fpu/fegetenv.c @@ -0,0 +1,31 @@ +/* Store current floating-point environment. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +__fegetenv (fenv_t *envp) +{ + _FPU_GETCW (*envp); + + /* Success. */ + return 0; +} +libm_hidden_def (__fegetenv) weak_alias (__fegetenv, fegetenv) +libm_hidden_weak (fegetenv) diff --git a/sysdeps/loongarch/fpu/fegetexcept.c b/sysdeps/loongarch/fpu/fegetexcept.c new file mode 100644 index 0000000000..ba1c1466f4 --- /dev/null +++ b/sysdeps/loongarch/fpu/fegetexcept.c @@ -0,0 +1,32 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fenv_libc.h> +#include <fpu_control.h> + +int +fegetexcept (void) +{ + unsigned int exc; + + /* Get the current control word. */ + _FPU_GETCW (exc); + + return (exc & ENABLE_MASK) << ENABLE_SHIFT; +} diff --git a/sysdeps/loongarch/fpu/fegetmode.c b/sysdeps/loongarch/fpu/fegetmode.c new file mode 100644 index 0000000000..e3517e34f6 --- /dev/null +++ b/sysdeps/loongarch/fpu/fegetmode.c @@ -0,0 +1,27 @@ +/* Store current floating-point control modes. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ + _FPU_GETCW (*modep); + return 0; +} diff --git a/sysdeps/loongarch/fpu/fegetround.c b/sysdeps/loongarch/fpu/fegetround.c new file mode 100644 index 0000000000..ff6113eb04 --- /dev/null +++ b/sysdeps/loongarch/fpu/fegetround.c @@ -0,0 +1,33 @@ +/* Return current rounding direction. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +__fegetround (void) +{ + int cw; + + /* Get control word. */ + _FPU_GETCW (cw); + + return cw & _FPU_RC_MASK; +} +libm_hidden_def (__fegetround) weak_alias (__fegetround, fegetround) +libm_hidden_weak (fegetround) diff --git a/sysdeps/loongarch/fpu/feholdexcpt.c b/sysdeps/loongarch/fpu/feholdexcpt.c new file mode 100644 index 0000000000..e4f9f6a23b --- /dev/null +++ b/sysdeps/loongarch/fpu/feholdexcpt.c @@ -0,0 +1,40 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +__feholdexcept (fenv_t *envp) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I + | FE_ALL_EXCEPT); + _FPU_SETCW (cw); + + return 0; +} + +libm_hidden_def (__feholdexcept) weak_alias (__feholdexcept, feholdexcept) +libm_hidden_weak (feholdexcept) diff --git a/sysdeps/loongarch/fpu/fenv_libc.h b/sysdeps/loongarch/fpu/fenv_libc.h new file mode 100644 index 0000000000..8360ae0377 --- /dev/null +++ b/sysdeps/loongarch/fpu/fenv_libc.h @@ -0,0 +1,30 @@ +/* Internal libc stuff for floating point environment routines. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#ifndef _FENV_LIBC_H +#define _FENV_LIBC_H 1 + +/* Mask for enabling exceptions and for the CAUSE bits. */ +#define ENABLE_MASK 0x0000001FU +#define CAUSE_MASK 0x1F000000U + +/* Shift for FE_* flags to get up to the ENABLE bits and the CAUSE bits. */ +#define ENABLE_SHIFT 16 +#define CAUSE_SHIFT 8 + +#endif /* _FENV_LIBC_H */ diff --git a/sysdeps/loongarch/fpu/fesetenv.c b/sysdeps/loongarch/fpu/fesetenv.c new file mode 100644 index 0000000000..c10bd11ef9 --- /dev/null +++ b/sysdeps/loongarch/fpu/fesetenv.c @@ -0,0 +1,42 @@ +/* Install given floating-point environment. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +__fesetenv (const fenv_t *envp) +{ + fpu_control_t cw; + + /* Read first current state to flush fpu pipeline. */ + _FPU_GETCW (cw); + + if (envp == FE_DFL_ENV) + _FPU_SETCW (_FPU_DEFAULT); + else if (envp == FE_NOMASK_ENV) + _FPU_SETCW (_FPU_IEEE); + else + _FPU_SETCW (envp->__fp_control_register); + + /* Success. */ + return 0; +} + +libm_hidden_def (__fesetenv) weak_alias (__fesetenv, fesetenv) +libm_hidden_weak (fesetenv) diff --git a/sysdeps/loongarch/fpu/fesetexcept.c b/sysdeps/loongarch/fpu/fesetexcept.c new file mode 100644 index 0000000000..ad76d52d9e --- /dev/null +++ b/sysdeps/loongarch/fpu/fesetexcept.c @@ -0,0 +1,32 @@ +/* Set given exception flags. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fesetexcept (int excepts) +{ + fpu_control_t temp; + + _FPU_GETCW (temp); + temp |= excepts & FE_ALL_EXCEPT; + _FPU_SETCW (temp); + + return 0; +} diff --git a/sysdeps/loongarch/fpu/fesetmode.c b/sysdeps/loongarch/fpu/fesetmode.c new file mode 100644 index 0000000000..fc52fc114b --- /dev/null +++ b/sysdeps/loongarch/fpu/fesetmode.c @@ -0,0 +1,38 @@ +/* Install given floating-point control modes. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +#define FCSR_STATUS 0x1f1f0000 + +int +fesetmode (const femode_t *modep) +{ + fpu_control_t cw; + + _FPU_GETCW (cw); + cw &= FCSR_STATUS; + if (modep == FE_DFL_MODE) + cw |= _FPU_DEFAULT; + else + cw |= *modep & ~FCSR_STATUS; + _FPU_SETCW (cw); + + return 0; +} diff --git a/sysdeps/loongarch/fpu/fesetround.c b/sysdeps/loongarch/fpu/fesetround.c new file mode 100644 index 0000000000..32acac5f96 --- /dev/null +++ b/sysdeps/loongarch/fpu/fesetround.c @@ -0,0 +1,44 @@ +/* Set current rounding direction. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +__fesetround (int round) +{ + fpu_control_t cw; + + if ((round & ~_FPU_RC_MASK) != 0) + /* ROUND is no valid rounding mode. */ + return 1; + + /* Get current state. */ + _FPU_GETCW (cw); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + /* Set new state. */ + _FPU_SETCW (cw); + + return 0; +} + +libm_hidden_def (__fesetround) weak_alias (__fesetround, fesetround) +libm_hidden_weak (fesetround) diff --git a/sysdeps/loongarch/fpu/feupdateenv.c b/sysdeps/loongarch/fpu/feupdateenv.c new file mode 100644 index 0000000000..5ad862a61d --- /dev/null +++ b/sysdeps/loongarch/fpu/feupdateenv.c @@ -0,0 +1,43 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +__feupdateenv (const fenv_t *envp) +{ + int temp; + + /* Save current exceptions. */ + _FPU_GETCW (temp); + temp &= FE_ALL_EXCEPT; + + /* Install new environment. */ + __fesetenv (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; +} +libm_hidden_def (__feupdateenv) weak_alias (__feupdateenv, feupdateenv) +libm_hidden_weak (feupdateenv) diff --git a/sysdeps/loongarch/fpu/fgetexcptflg.c b/sysdeps/loongarch/fpu/fgetexcptflg.c new file mode 100644 index 0000000000..6130c632c9 --- /dev/null +++ b/sysdeps/loongarch/fpu/fgetexcptflg.c @@ -0,0 +1,38 @@ +/* Store current representation for exceptions. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETCW (temp); + + /* We only save the relevant bits here. In particular, care has to be + taken with the CAUSE bits, as an inadvertent restore later on could + generate unexpected exceptions. */ + + *flagp = temp & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} diff --git a/sysdeps/loongarch/fpu/fraiseexcpt.c b/sysdeps/loongarch/fpu/fraiseexcpt.c new file mode 100644 index 0000000000..135a848bb5 --- /dev/null +++ b/sysdeps/loongarch/fpu/fraiseexcpt.c @@ -0,0 +1,75 @@ +/* Raise given exceptions. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> +#include <float.h> + +int +__feraiseexcept (int excepts) +{ + const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX, fp_min = FLT_MIN, + fp_1e32 = 1.0e32f, fp_two = 2.0, fp_three = 3.0; + + /* Raise exceptions represented by EXPECTS. But we must raise only + one signal at a time. It is important that if the overflow/underflow + exception and the inexact exception are given at the same time, + the overflow/underflow exception follows the inexact exception. */ + + /* First: invalid exception. */ + if (FE_INVALID & excepts) + __asm__ __volatile__("fdiv.s $f0,%0,%0\n\t" + : + : "f"(fp_zero) + : "$f0"); + + /* Next: division by zero. */ + if (FE_DIVBYZERO & excepts) + __asm__ __volatile__("fdiv.s $f0,%0,%1\n\t" + : + : "f"(fp_one), "f"(fp_zero) + : "$f0"); + + /* Next: overflow. */ + if (FE_OVERFLOW & excepts) + /* There's no way to raise overflow without also raising inexact. */ + __asm__ __volatile__("fadd.s $f0,%0,%1\n\t" + : + : "f"(fp_max), "f"(fp_1e32) + : "$f0"); + + /* Next: underflow. */ + if (FE_UNDERFLOW & excepts) + __asm__ __volatile__("fdiv.s $f0,%0,%1\n\t" + : + : "f"(fp_min), "f"(fp_three) + : "$f0"); + + /* Last: inexact. */ + if (FE_INEXACT & excepts) + __asm__ __volatile__("fdiv.s $f0, %0, %1\n\t" + : + : "f"(fp_two), "f"(fp_three) + : "$f0"); + + /* Success. */ + return 0; +} + +libm_hidden_def (__feraiseexcept) weak_alias (__feraiseexcept, feraiseexcept) +libm_hidden_weak (feraiseexcept) diff --git a/sysdeps/loongarch/fpu/fsetexcptflg.c b/sysdeps/loongarch/fpu/fsetexcptflg.c new file mode 100644 index 0000000000..9c135a663d --- /dev/null +++ b/sysdeps/loongarch/fpu/fsetexcptflg.c @@ -0,0 +1,41 @@ +/* Set floating-point environment exception handling. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fpu_control_t temp; + + /* Get the current exceptions. */ + _FPU_GETCW (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 & ~excepts) | (*flagp & excepts); + + _FPU_SETCW (temp); + + /* Success. */ + return 0; +} diff --git a/sysdeps/loongarch/fpu/ftestexcept.c b/sysdeps/loongarch/fpu/ftestexcept.c new file mode 100644 index 0000000000..b9563b7ae1 --- /dev/null +++ b/sysdeps/loongarch/fpu/ftestexcept.c @@ -0,0 +1,32 @@ +/* Test exception in current environment. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fetestexcept (int excepts) +{ + int cw; + + /* Get current control word. */ + _FPU_GETCW (cw); + + return cw & excepts & FE_ALL_EXCEPT; +} +libm_hidden_def (fetestexcept) diff --git a/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h b/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h new file mode 100644 index 0000000000..e94c915ba6 --- /dev/null +++ b/sysdeps/loongarch/fpu/math-use-builtins-sqrt.h @@ -0,0 +1,4 @@ +#define USE_SQRT_BUILTIN 1 +#define USE_SQRTF_BUILTIN 1 +#define USE_SQRTL_BUILTIN 0 +#define USE_SQRTF128_BUILTIN 0 diff --git a/sysdeps/loongarch/lp64/libm-test-ulps b/sysdeps/loongarch/lp64/libm-test-ulps new file mode 100644 index 0000000000..c711531eec --- /dev/null +++ b/sysdeps/loongarch/lp64/libm-test-ulps @@ -0,0 +1,1412 @@ +# Begin of automatic generation + +# Maximal error of functions: +Function: "acos": +double: 1 +float: 1 +ldouble: 1 + +Function: "acos_downward": +double: 1 +float: 1 +ldouble: 1 + +Function: "acos_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "acos_upward": +double: 1 +float: 1 +ldouble: 1 + +Function: "acosh": +double: 2 +float: 2 +ldouble: 4 + +Function: "acosh_downward": +double: 2 +float: 2 +ldouble: 3 + +Function: "acosh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: "acosh_upward": +double: 2 +float: 2 +ldouble: 3 + +Function: "asin": +double: 1 +float: 1 +ldouble: 1 + +Function: "asin_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: "asin_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "asin_upward": +double: 2 +float: 1 +ldouble: 2 + +Function: "asinh": +double: 2 +float: 2 +ldouble: 4 + +Function: "asinh_downward": +double: 3 +float: 3 +ldouble: 4 + +Function: "asinh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: "asinh_upward": +double: 3 +float: 3 +ldouble: 4 + +Function: "atan": +double: 1 +float: 1 +ldouble: 1 + +Function: "atan2": +float: 2 +ldouble: 2 + +Function: "atan2_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: "atan2_towardzero": +double: 1 +float: 2 +ldouble: 3 + +Function: "atan2_upward": +double: 1 +float: 2 +ldouble: 2 + +Function: "atan_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: "atan_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "atan_upward": +double: 1 +float: 2 +ldouble: 2 + +Function: "atanh": +double: 2 +float: 2 +ldouble: 4 + +Function: "atanh_downward": +double: 3 +float: 3 +ldouble: 4 + +Function: "atanh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: "atanh_upward": +double: 3 +float: 3 +ldouble: 4 + +Function: "cabs": +double: 1 +ldouble: 1 + +Function: "cabs_downward": +double: 1 +ldouble: 1 + +Function: "cabs_towardzero": +double: 1 +ldouble: 1 + +Function: "cabs_upward": +double: 1 +ldouble: 1 + +Function: Real part of "cacos": +double: 1 +float: 2 +ldouble: 2 + +Function: Imaginary part of "cacos": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "cacos_downward": +double: 3 +float: 2 +ldouble: 3 + +Function: Imaginary part of "cacos_downward": +double: 5 +float: 3 +ldouble: 6 + +Function: Real part of "cacos_towardzero": +double: 3 +float: 2 +ldouble: 3 + +Function: Imaginary part of "cacos_towardzero": +double: 4 +float: 2 +ldouble: 5 + +Function: Real part of "cacos_upward": +double: 2 +float: 2 +ldouble: 3 + +Function: Imaginary part of "cacos_upward": +double: 5 +float: 7 +ldouble: 7 + +Function: Real part of "cacosh": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "cacosh": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "cacosh_downward": +double: 4 +float: 2 +ldouble: 5 + +Function: Imaginary part of "cacosh_downward": +double: 3 +float: 3 +ldouble: 4 + +Function: Real part of "cacosh_towardzero": +double: 4 +float: 2 +ldouble: 5 + +Function: Imaginary part of "cacosh_towardzero": +double: 3 +float: 2 +ldouble: 3 + +Function: Real part of "cacosh_upward": +double: 4 +float: 3 +ldouble: 6 + +Function: Imaginary part of "cacosh_upward": +double: 3 +float: 2 +ldouble: 4 + +Function: "carg": +float: 1 +ldouble: 2 + +Function: "carg_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: "carg_towardzero": +double: 1 +float: 2 +ldouble: 3 + +Function: "carg_upward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "casin": +double: 1 +float: 1 +ldouble: 2 + +Function: Imaginary part of "casin": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "casin_downward": +double: 3 +float: 2 +ldouble: 3 + +Function: Imaginary part of "casin_downward": +double: 5 +float: 3 +ldouble: 6 + +Function: Real part of "casin_towardzero": +double: 3 +float: 1 +ldouble: 3 + +Function: Imaginary part of "casin_towardzero": +double: 4 +float: 2 +ldouble: 5 + +Function: Real part of "casin_upward": +double: 3 +float: 2 +ldouble: 3 + +Function: Imaginary part of "casin_upward": +double: 5 +float: 7 +ldouble: 7 + +Function: Real part of "casinh": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "casinh": +double: 1 +float: 1 +ldouble: 2 + +Function: Real part of "casinh_downward": +double: 5 +float: 3 +ldouble: 6 + +Function: Imaginary part of "casinh_downward": +double: 3 +float: 2 +ldouble: 3 + +Function: Real part of "casinh_towardzero": +double: 4 +float: 2 +ldouble: 5 + +Function: Imaginary part of "casinh_towardzero": +double: 3 +float: 1 +ldouble: 3 + +Function: Real part of "casinh_upward": +double: 5 +float: 7 +ldouble: 7 + +Function: Imaginary part of "casinh_upward": +double: 3 +float: 2 +ldouble: 3 + +Function: Real part of "catan": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "catan": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "catan_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: Imaginary part of "catan_downward": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "catan_towardzero": +double: 1 +float: 2 +ldouble: 2 + +Function: Imaginary part of "catan_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "catan_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: Imaginary part of "catan_upward": +double: 2 +float: 2 +ldouble: 3 + +Function: Real part of "catanh": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "catanh": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "catanh_downward": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "catanh_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "catanh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "catanh_towardzero": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "catanh_upward": +double: 4 +float: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "cbrt": +double: 4 +float: 1 +ldouble: 1 + +Function: "cbrt_downward": +double: 4 +float: 1 +ldouble: 1 + +Function: "cbrt_towardzero": +double: 3 +float: 1 +ldouble: 1 + +Function: "cbrt_upward": +double: 5 +float: 1 +ldouble: 1 + +Function: Real part of "ccos": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "ccos": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "ccos_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: Imaginary part of "ccos_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "ccos_towardzero": +double: 1 +float: 2 +ldouble: 2 + +Function: Imaginary part of "ccos_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "ccos_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Imaginary part of "ccos_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "ccosh": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "ccosh": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "ccosh_downward": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "ccosh_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "ccosh_towardzero": +double: 2 +float: 3 +ldouble: 2 + +Function: Imaginary part of "ccosh_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "ccosh_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Imaginary part of "ccosh_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "cexp": +double: 2 +float: 1 +ldouble: 1 + +Function: Imaginary part of "cexp": +double: 1 +float: 2 +ldouble: 1 + +Function: Real part of "cexp_downward": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "cexp_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "cexp_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "cexp_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "cexp_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Imaginary part of "cexp_upward": +double: 3 +float: 2 +ldouble: 3 + +Function: Real part of "clog": +double: 3 +float: 3 +ldouble: 2 + +Function: Imaginary part of "clog": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "clog10": +double: 3 +float: 4 +ldouble: 2 + +Function: Imaginary part of "clog10": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "clog10_downward": +double: 5 +float: 5 +ldouble: 3 + +Function: Imaginary part of "clog10_downward": +double: 2 +float: 4 +ldouble: 3 + +Function: Real part of "clog10_towardzero": +double: 5 +float: 6 +ldouble: 4 + +Function: Imaginary part of "clog10_towardzero": +double: 2 +float: 4 +ldouble: 3 + +Function: Real part of "clog10_upward": +double: 6 +float: 5 +ldouble: 4 + +Function: Imaginary part of "clog10_upward": +double: 2 +float: 4 +ldouble: 3 + +Function: Real part of "clog_downward": +double: 4 +float: 3 +ldouble: 3 + +Function: Imaginary part of "clog_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "clog_towardzero": +double: 4 +float: 4 +ldouble: 3 + +Function: Imaginary part of "clog_towardzero": +double: 1 +float: 3 +ldouble: 2 + +Function: Real part of "clog_upward": +double: 4 +float: 3 +ldouble: 4 + +Function: Imaginary part of "clog_upward": +double: 1 +float: 2 +ldouble: 2 + +Function: "cos": +double: 1 +float: 1 +ldouble: 2 + +Function: "cos_downward": +double: 1 +float: 1 +ldouble: 3 + +Function: "cos_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "cos_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "cosh": +double: 2 +float: 2 +ldouble: 2 + +Function: "cosh_downward": +double: 3 +float: 1 +ldouble: 3 + +Function: "cosh_towardzero": +double: 3 +float: 1 +ldouble: 3 + +Function: "cosh_upward": +double: 2 +float: 2 +ldouble: 3 + +Function: Real part of "cpow": +double: 2 +float: 5 +ldouble: 4 + +Function: Imaginary part of "cpow": +float: 2 +ldouble: 1 + +Function: Real part of "cpow_downward": +double: 5 +float: 8 +ldouble: 6 + +Function: Imaginary part of "cpow_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "cpow_towardzero": +double: 5 +float: 8 +ldouble: 6 + +Function: Imaginary part of "cpow_towardzero": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "cpow_upward": +double: 4 +float: 1 +ldouble: 3 + +Function: Imaginary part of "cpow_upward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "csin": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "csin": +ldouble: 1 + +Function: Real part of "csin_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Imaginary part of "csin_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: Real part of "csin_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Imaginary part of "csin_towardzero": +double: 1 +float: 1 +ldouble: 2 + +Function: Real part of "csin_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "csin_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Real part of "csinh": +float: 1 +ldouble: 1 + +Function: Imaginary part of "csinh": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "csinh_downward": +double: 2 +float: 1 +ldouble: 2 + +Function: Imaginary part of "csinh_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "csinh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "csinh_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "csinh_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Imaginary part of "csinh_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "csqrt": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "csqrt": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "csqrt_downward": +double: 5 +float: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_downward": +double: 4 +float: 3 +ldouble: 3 + +Function: Real part of "csqrt_towardzero": +double: 4 +float: 3 +ldouble: 3 + +Function: Imaginary part of "csqrt_towardzero": +double: 4 +float: 3 +ldouble: 3 + +Function: Real part of "csqrt_upward": +double: 5 +float: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_upward": +double: 3 +float: 3 +ldouble: 3 + +Function: Real part of "ctan": +double: 2 +float: 1 +ldouble: 3 + +Function: Imaginary part of "ctan": +double: 2 +float: 2 +ldouble: 3 + +Function: Real part of "ctan_downward": +double: 6 +float: 5 +ldouble: 4 + +Function: Imaginary part of "ctan_downward": +double: 2 +float: 2 +ldouble: 5 + +Function: Real part of "ctan_towardzero": +double: 5 +float: 3 +ldouble: 4 + +Function: Imaginary part of "ctan_towardzero": +double: 2 +float: 2 +ldouble: 5 + +Function: Real part of "ctan_upward": +double: 2 +float: 4 +ldouble: 5 + +Function: Imaginary part of "ctan_upward": +double: 2 +float: 2 +ldouble: 5 + +Function: Real part of "ctanh": +double: 2 +float: 2 +ldouble: 3 + +Function: Imaginary part of "ctanh": +double: 2 +float: 2 +ldouble: 3 + +Function: Real part of "ctanh_downward": +double: 4 +float: 2 +ldouble: 5 + +Function: Imaginary part of "ctanh_downward": +double: 6 +float: 5 +ldouble: 4 + +Function: Real part of "ctanh_towardzero": +double: 2 +float: 2 +ldouble: 5 + +Function: Imaginary part of "ctanh_towardzero": +double: 5 +float: 3 +ldouble: 3 + +Function: Real part of "ctanh_upward": +double: 2 +float: 2 +ldouble: 5 + +Function: Imaginary part of "ctanh_upward": +double: 2 +float: 3 +ldouble: 5 + +Function: "erf": +double: 1 +float: 1 +ldouble: 1 + +Function: "erf_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: "erf_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "erf_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "erfc": +double: 5 +float: 3 +ldouble: 4 + +Function: "erfc_downward": +double: 5 +float: 6 +ldouble: 5 + +Function: "erfc_towardzero": +double: 3 +float: 4 +ldouble: 4 + +Function: "erfc_upward": +double: 5 +float: 6 +ldouble: 5 + +Function: "exp": +double: 1 +float: 1 +ldouble: 1 + +Function: "exp10": +double: 2 +ldouble: 2 + +Function: "exp10_downward": +double: 3 +float: 1 +ldouble: 3 + +Function: "exp10_towardzero": +double: 3 +float: 1 +ldouble: 3 + +Function: "exp10_upward": +double: 2 +float: 1 +ldouble: 3 + +Function: "exp2": +double: 1 +ldouble: 1 + +Function: "exp2_downward": +double: 1 +ldouble: 1 + +Function: "exp2_towardzero": +double: 1 +ldouble: 1 + +Function: "exp2_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "exp_downward": +double: 1 +float: 1 + +Function: "exp_towardzero": +double: 1 +float: 1 + +Function: "exp_upward": +double: 1 +float: 1 + +Function: "expm1": +double: 1 +float: 1 +ldouble: 2 + +Function: "expm1_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: "expm1_towardzero": +double: 1 +float: 2 +ldouble: 4 + +Function: "expm1_upward": +double: 1 +float: 1 +ldouble: 3 + +Function: "gamma": +double: 4 +float: 7 +ldouble: 5 + +Function: "gamma_downward": +double: 5 +float: 7 +ldouble: 8 + +Function: "gamma_towardzero": +double: 5 +float: 6 +ldouble: 5 + +Function: "gamma_upward": +double: 5 +float: 6 +ldouble: 8 + +Function: "hypot": +double: 1 +ldouble: 1 + +Function: "hypot_downward": +double: 1 +ldouble: 1 + +Function: "hypot_towardzero": +double: 1 +ldouble: 1 + +Function: "hypot_upward": +double: 1 +ldouble: 1 + +Function: "j0": +double: 3 +float: 9 +ldouble: 2 + +Function: "j0_downward": +double: 6 +float: 9 +ldouble: 9 + +Function: "j0_towardzero": +double: 7 +float: 9 +ldouble: 9 + +Function: "j0_upward": +double: 9 +float: 9 +ldouble: 7 + +Function: "j1": +double: 4 +float: 9 +ldouble: 4 + +Function: "j1_downward": +double: 5 +float: 8 +ldouble: 4 + +Function: "j1_towardzero": +double: 4 +float: 8 +ldouble: 4 + +Function: "j1_upward": +double: 9 +float: 9 +ldouble: 3 + +Function: "jn": +double: 4 +float: 4 +ldouble: 7 + +Function: "jn_downward": +double: 5 +float: 5 +ldouble: 8 + +Function: "jn_towardzero": +double: 5 +float: 5 +ldouble: 8 + +Function: "jn_upward": +double: 5 +float: 4 +ldouble: 7 + +Function: "lgamma": +double: 4 +float: 7 +ldouble: 5 + +Function: "lgamma_downward": +double: 5 +float: 7 +ldouble: 8 + +Function: "lgamma_towardzero": +double: 5 +float: 6 +ldouble: 5 + +Function: "lgamma_upward": +double: 5 +float: 6 +ldouble: 8 + +Function: "log": +double: 1 +ldouble: 1 + +Function: "log10": +double: 2 +float: 2 +ldouble: 2 + +Function: "log10_downward": +double: 2 +float: 3 +ldouble: 1 + +Function: "log10_towardzero": +double: 2 +float: 1 +ldouble: 1 + +Function: "log10_upward": +double: 2 +float: 2 +ldouble: 1 + +Function: "log1p": +double: 1 +float: 1 +ldouble: 3 + +Function: "log1p_downward": +double: 2 +float: 2 +ldouble: 3 + +Function: "log1p_towardzero": +double: 2 +float: 2 +ldouble: 3 + +Function: "log1p_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: "log2": +double: 1 +float: 1 +ldouble: 3 + +Function: "log2_downward": +double: 3 +ldouble: 3 + +Function: "log2_towardzero": +double: 2 +ldouble: 1 + +Function: "log2_upward": +double: 3 +ldouble: 1 + +Function: "log_downward": +ldouble: 1 + +Function: "log_towardzero": +ldouble: 2 + +Function: "log_upward": +double: 1 +ldouble: 2 + +Function: "pow": +double: 1 +ldouble: 2 + +Function: "pow_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: "pow_towardzero": +double: 1 +float: 1 +ldouble: 2 + +Function: "pow_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "sin": +double: 1 +float: 1 +ldouble: 2 + +Function: "sin_downward": +double: 1 +float: 1 +ldouble: 3 + +Function: "sin_towardzero": +double: 1 +float: 1 +ldouble: 2 + +Function: "sin_upward": +double: 1 +float: 1 +ldouble: 3 + +Function: "sincos": +double: 1 +ldouble: 1 + +Function: "sincos_downward": +double: 1 +float: 1 +ldouble: 3 + +Function: "sincos_towardzero": +double: 1 +float: 1 +ldouble: 2 + +Function: "sincos_upward": +double: 1 +float: 1 +ldouble: 3 + +Function: "sinh": +double: 2 +float: 2 +ldouble: 2 + +Function: "sinh_downward": +double: 3 +float: 3 +ldouble: 3 + +Function: "sinh_towardzero": +double: 3 +float: 2 +ldouble: 3 + +Function: "sinh_upward": +double: 3 +float: 3 +ldouble: 4 + +Function: "tan": +double: 1 +float: 1 +ldouble: 1 + +Function: "tan_downward": +double: 1 +float: 2 +ldouble: 1 + +Function: "tan_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "tan_upward": +double: 1 +float: 1 +ldouble: 1 + +Function: "tanh": +double: 2 +float: 2 +ldouble: 2 + +Function: "tanh_downward": +double: 3 +float: 3 +ldouble: 4 + +Function: "tanh_towardzero": +double: 2 +float: 2 +ldouble: 3 + +Function: "tanh_upward": +double: 3 +float: 3 +ldouble: 3 + +Function: "tgamma": +double: 9 +float: 8 +ldouble: 4 + +Function: "tgamma_downward": +double: 9 +float: 7 +ldouble: 5 + +Function: "tgamma_towardzero": +double: 9 +float: 7 +ldouble: 5 + +Function: "tgamma_upward": +double: 9 +float: 8 +ldouble: 4 + +Function: "y0": +double: 3 +float: 9 +ldouble: 3 + +Function: "y0_downward": +double: 3 +float: 9 +ldouble: 7 + +Function: "y0_towardzero": +double: 4 +float: 9 +ldouble: 3 + +Function: "y0_upward": +double: 3 +float: 9 +ldouble: 4 + +Function: "y1": +double: 3 +float: 9 +ldouble: 5 + +Function: "y1_downward": +double: 6 +float: 9 +ldouble: 5 + +Function: "y1_towardzero": +double: 3 +float: 9 +ldouble: 2 + +Function: "y1_upward": +double: 7 +float: 9 +ldouble: 5 + +Function: "yn": +double: 3 +float: 3 +ldouble: 5 + +Function: "yn_downward": +double: 3 +float: 4 +ldouble: 5 + +Function: "yn_towardzero": +double: 3 +float: 3 +ldouble: 5 + +Function: "yn_upward": +double: 4 +float: 5 +ldouble: 5 + +# end of automatic generation diff --git a/sysdeps/loongarch/lp64/libm-test-ulps-name b/sysdeps/loongarch/lp64/libm-test-ulps-name new file mode 100644 index 0000000000..ce02281eab --- /dev/null +++ b/sysdeps/loongarch/lp64/libm-test-ulps-name @@ -0,0 +1 @@ +LoongArch 64-bit diff --git a/sysdeps/loongarch/math_private.h b/sysdeps/loongarch/math_private.h new file mode 100644 index 0000000000..cdf26a78dd --- /dev/null +++ b/sysdeps/loongarch/math_private.h @@ -0,0 +1,248 @@ +/* Internal math stuff. + Copyright (C) 2022 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 + <https://www.gnu.org/licenses/>. */ + +#ifndef LOONGARCH_MATH_PRIVATE_H +#define LOONGARCH_MATH_PRIVATE_H 1 + +/* Inline functions to speed up the math library implementation. The + default versions of these routines are in generic/math_private.h + and call fesetround, feholdexcept, etc. These routines use inlined + code instead. */ + +#ifdef __loongarch_hard_float + +#include <fenv.h> +#include <fenv_libc.h> +#include <fpu_control.h> + +#define _FPU_MASK_ALL \ + (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I \ + | FE_ALL_EXCEPT) + +static __always_inline void +libc_feholdexcept_loongarch (fenv_t *envp) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_ALL); + _FPU_SETCW (cw); +} +#define libc_feholdexcept libc_feholdexcept_loongarch +#define libc_feholdexceptf libc_feholdexcept_loongarch +#define libc_feholdexceptl libc_feholdexcept_loongarch + +static __always_inline void +libc_fesetround_loongarch (int round) +{ + fpu_control_t cw; + + /* Get current state. */ + _FPU_GETCW (cw); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + + /* Set new state. */ + _FPU_SETCW (cw); +} +#define libc_fesetround libc_fesetround_loongarch +#define libc_fesetroundf libc_fesetround_loongarch +#define libc_fesetroundl libc_fesetround_loongarch + +static __always_inline void +libc_feholdexcept_setround_loongarch (fenv_t *envp, int round) +{ + fpu_control_t cw; + + /* Save the current state. */ + _FPU_GETCW (cw); + envp->__fp_control_register = cw; + + /* Clear all exception enable bits and flags. */ + cw &= ~(_FPU_MASK_ALL); + + /* Set rounding bits. */ + cw &= ~_FPU_RC_MASK; + cw |= round; + + /* Set new state. */ + _FPU_SETCW (cw); +} +#define libc_feholdexcept_setround libc_feholdexcept_setround_loongarch +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_loongarch +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_loongarch + +#define libc_feholdsetround libc_feholdexcept_setround_loongarch +#define libc_feholdsetroundf libc_feholdexcept_setround_loongarch +#define libc_feholdsetroundl libc_feholdexcept_setround_loongarch + +static __always_inline void +libc_fesetenv_loongarch (fenv_t *envp) +{ + fpu_control_t cw __attribute__ ((unused)); + + /* Read current state to flush fpu pipeline. */ + _FPU_GETCW (cw); + + _FPU_SETCW (envp->__fp_control_register); +} +#define libc_fesetenv libc_fesetenv_loongarch +#define libc_fesetenvf libc_fesetenv_loongarch +#define libc_fesetenvl libc_fesetenv_loongarch + +static __always_inline int +libc_feupdateenv_test_loongarch (fenv_t *envp, int excepts) +{ + /* int ret = fetestexcept (excepts); feupdateenv (envp); return ret; */ + int cw, temp; + + /* Get current control word. */ + _FPU_GETCW (cw); + + /* Set flag bits (which are accumulative), and *also* set the + cause bits. The setting of the cause bits is what actually causes + the hardware to generate the exception, if the corresponding enable + bit is set as well. */ + temp = cw & FE_ALL_EXCEPT; + temp |= envp->__fp_control_register | (temp << CAUSE_SHIFT); + + /* Set new state. */ + _FPU_SETCW (temp); + + return cw & excepts & FE_ALL_EXCEPT; +} +#define libc_feupdateenv_test libc_feupdateenv_test_loongarch +#define libc_feupdateenv_testf libc_feupdateenv_test_loongarch +#define libc_feupdateenv_testl libc_feupdateenv_test_loongarch + +static __always_inline void +libc_feupdateenv_loongarch (fenv_t *envp) +{ + libc_feupdateenv_test_loongarch (envp, 0); +} +#define libc_feupdateenv libc_feupdateenv_loongarch +#define libc_feupdateenvf libc_feupdateenv_loongarch +#define libc_feupdateenvl libc_feupdateenv_loongarch + +#define libc_feresetround libc_feupdateenv_loongarch +#define libc_feresetroundf libc_feupdateenv_loongarch +#define libc_feresetroundl libc_feupdateenv_loongarch + +static __always_inline int +libc_fetestexcept_loongarch (int excepts) +{ + int cw; + + /* Get current control word. */ + _FPU_GETCW (cw); + + return cw & excepts & FE_ALL_EXCEPT; +} +#define libc_fetestexcept libc_fetestexcept_loongarch +#define libc_fetestexceptf libc_fetestexcept_loongarch +#define libc_fetestexceptl libc_fetestexcept_loongarch + +/* Enable support for rounding mode context. */ +#define HAVE_RM_CTX 1 + +static __always_inline void +libc_feholdexcept_setround_loongarch_ctx (struct rm_ctx *ctx, int round) +{ + fpu_control_t old, new; + + /* Save the current state. */ + _FPU_GETCW (old); + ctx->env.__fp_control_register = old; + + /* Clear all exception enable bits and flags. */ + new = old & ~(_FPU_MASK_ALL); + + /* Set rounding bits. */ + new = (new & ~_FPU_RC_MASK) | round; + + if (__glibc_unlikely (new != old)) + { + _FPU_SETCW (new); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} +#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_loongarch_ctx +#define libc_feholdexcept_setroundf_ctx \ + libc_feholdexcept_setround_loongarch_ctx +#define libc_feholdexcept_setroundl_ctx \ + libc_feholdexcept_setround_loongarch_ctx + +static __always_inline void +libc_fesetenv_loongarch_ctx (struct rm_ctx *ctx) +{ + libc_fesetenv_loongarch (&ctx->env); +} +#define libc_fesetenv_ctx libc_fesetenv_loongarch_ctx +#define libc_fesetenvf_ctx libc_fesetenv_loongarch_ctx +#define libc_fesetenvl_ctx libc_fesetenv_loongarch_ctx + +static __always_inline void +libc_feupdateenv_loongarch_ctx (struct rm_ctx *ctx) +{ + if (__glibc_unlikely (ctx->updated_status)) + libc_feupdateenv_test_loongarch (&ctx->env, 0); +} +#define libc_feupdateenv_ctx libc_feupdateenv_loongarch_ctx +#define libc_feupdateenvf_ctx libc_feupdateenv_loongarch_ctx +#define libc_feupdateenvl_ctx libc_feupdateenv_loongarch_ctx +#define libc_feresetround_ctx libc_feupdateenv_loongarch_ctx +#define libc_feresetroundf_ctx libc_feupdateenv_loongarch_ctx +#define libc_feresetroundl_ctx libc_feupdateenv_loongarch_ctx + +static __always_inline void +libc_feholdsetround_loongarch_ctx (struct rm_ctx *ctx, int round) +{ + fpu_control_t old, new; + + /* Save the current state. */ + _FPU_GETCW (old); + ctx->env.__fp_control_register = old; + + /* Set rounding bits. */ + new = (old & ~_FPU_RC_MASK) | round; + + if (__glibc_unlikely (new != old)) + { + _FPU_SETCW (new); + ctx->updated_status = true; + } + else + ctx->updated_status = false; +} +#define libc_feholdsetround_ctx libc_feholdsetround_loongarch_ctx +#define libc_feholdsetroundf_ctx libc_feholdsetround_loongarch_ctx +#define libc_feholdsetroundl_ctx libc_feholdsetround_loongarch_ctx + +#endif + +#include_next <math_private.h> + +#endif