public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: caiyinyu <caiyinyu@loongson.cn>
To: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>,
	libc-alpha@sourceware.org
Cc: joseph_myers@mentor.com
Subject: Re: [PATCH v6 12/13] LoongArch: Hard Float Support
Date: Thu, 14 Jul 2022 21:00:33 +0800	[thread overview]
Message-ID: <fba9762d-2c7e-dce9-b350-ec426e81d4b0@loongson.cn> (raw)
In-Reply-To: <2d40591f-6431-a5a2-fc42-1445665f3231@linaro.org>

+#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


  reply	other threads:[~2022-07-14 13:00 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-08  6:52 [PATCH v6 00/13] GLIBC LoongArch PATCHES caiyinyu
2022-07-08  6:52 ` [PATCH v6 01/13] LoongArch: Update NEWS and README for the LoongArch port caiyinyu
2022-07-12 11:06   ` Adhemerval Zanella Netto
2022-07-08  6:52 ` [PATCH v6 02/13] LoongArch: Add LoongArch entries to config.h.in caiyinyu
2022-07-12 18:51   ` Adhemerval Zanella Netto
2022-07-08  6:52 ` [PATCH v6 03/13] LoongArch: Add relocations and ELF flags to elf.h and scripts/glibcelf.py caiyinyu
2022-07-12 19:27   ` Adhemerval Zanella Netto
2022-07-08  6:52 ` [PATCH v6 04/13] LoongArch: ABI Implementation caiyinyu
2022-07-12 20:39   ` Adhemerval Zanella Netto
2022-07-15  1:46     ` caiyinyu
2022-07-08  6:52 ` [PATCH v6 05/13] LoongArch: Thread-Local Storage Support caiyinyu
2022-07-13 13:10   ` Adhemerval Zanella Netto
2022-07-08  6:52 ` [PATCH v6 06/13] LoongArch: Generic <math.h> and soft-fp Routines caiyinyu
2022-07-13 13:25   ` Adhemerval Zanella Netto
2022-07-08  6:52 ` [PATCH v6 07/13] LoongArch: Atomic and Locking Routines caiyinyu
2022-07-13 13:53   ` Adhemerval Zanella Netto
2022-07-15  1:46     ` caiyinyu
2022-07-08  6:52 ` [PATCH v6 08/13] LoongArch: Linux Syscall Interface caiyinyu
2022-07-13 16:19   ` Adhemerval Zanella Netto
2023-09-13 11:05     ` caiyinyu
2022-07-08  6:52 ` [PATCH v6 09/13] LoongArch: Linux ABI caiyinyu
2022-07-13 16:35   ` Adhemerval Zanella Netto
2022-07-15  1:48     ` caiyinyu
2022-07-08  6:52 ` [PATCH v6 10/13] LoongArch: Add ABI Lists caiyinyu
2022-07-13 17:12   ` Adhemerval Zanella Netto
2022-07-08  6:52 ` [PATCH v6 11/13] LoongArch: Build Infastructure caiyinyu
2022-07-13  3:07   ` Xi Ruoyao
2022-07-13  3:43     ` WANG Xuerui
2022-07-13  7:51       ` caiyinyu
2022-07-13 17:48   ` Adhemerval Zanella Netto
2022-07-15  1:49     ` caiyinyu
2022-07-08  6:52 ` [PATCH v6 12/13] LoongArch: Hard Float Support caiyinyu
2022-07-13 19:22   ` Adhemerval Zanella Netto
2022-07-14 13:00     ` caiyinyu [this message]
2022-07-08  7:13 ` [PATCH v6 00/13] GLIBC LoongArch PATCHES Xi Ruoyao
2022-07-08  7:15   ` Xi Ruoyao
2022-07-13 19:55   ` Adhemerval Zanella Netto
2022-07-14 11:33     ` Xi Ruoyao
2022-07-14 12:11       ` Adhemerval Zanella Netto
2022-07-18 13:54 ` Carlos O'Donell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fba9762d-2c7e-dce9-b350-ec426e81d4b0@loongson.cn \
    --to=caiyinyu@loongson.cn \
    --cc=adhemerval.zanella@linaro.org \
    --cc=joseph_myers@mentor.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).