[PATCH v6 12/13] LoongArch: Hard Float Support
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Wed Jul 13 19:22:40 GMT 2022
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
More information about the Libc-alpha
mailing list