[v7,05/13] LoongArch: Generic <math.h> and soft-fp Routines

Message ID 20220719012056.1461897-6-caiyinyu@loongson.cn
State Committed
Headers
Series [v7,01/13] LoongArch: Add LoongArch entries to config.h.in |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

caiyinyu July 19, 2022, 1:20 a.m. UTC
  ---
 sysdeps/loongarch/bits/fenv.h   |  90 ++++++++++++++++++++++++++++
 sysdeps/loongarch/e_sqrtl.c     |  39 ++++++++++++
 sysdeps/loongarch/fpu_control.h |  90 ++++++++++++++++++++++++++++
 sysdeps/loongarch/sfp-machine.h | 102 ++++++++++++++++++++++++++++++++
 sysdeps/loongarch/tininess.h    |   1 +
 5 files changed, 322 insertions(+)
 create mode 100644 sysdeps/loongarch/bits/fenv.h
 create mode 100644 sysdeps/loongarch/e_sqrtl.c
 create mode 100644 sysdeps/loongarch/fpu_control.h
 create mode 100644 sysdeps/loongarch/sfp-machine.h
 create mode 100644 sysdeps/loongarch/tininess.h
  

Comments

Adhemerval Zanella Netto July 20, 2022, 1:04 p.m. UTC | #1
LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

On 18/07/22 22:20, caiyinyu wrote:
> ---
>  sysdeps/loongarch/bits/fenv.h   |  90 ++++++++++++++++++++++++++++
>  sysdeps/loongarch/e_sqrtl.c     |  39 ++++++++++++
>  sysdeps/loongarch/fpu_control.h |  90 ++++++++++++++++++++++++++++
>  sysdeps/loongarch/sfp-machine.h | 102 ++++++++++++++++++++++++++++++++
>  sysdeps/loongarch/tininess.h    |   1 +
>  5 files changed, 322 insertions(+)
>  create mode 100644 sysdeps/loongarch/bits/fenv.h
>  create mode 100644 sysdeps/loongarch/e_sqrtl.c
>  create mode 100644 sysdeps/loongarch/fpu_control.h
>  create mode 100644 sysdeps/loongarch/sfp-machine.h
>  create mode 100644 sysdeps/loongarch/tininess.h
> 
> diff --git a/sysdeps/loongarch/bits/fenv.h b/sysdeps/loongarch/bits/fenv.h
> new file mode 100644
> index 0000000000..7e223b402b
> --- /dev/null
> +++ b/sysdeps/loongarch/bits/fenv.h
> @@ -0,0 +1,90 @@
> +/* 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/>.  */
> +
> +#ifndef _FENV_H
> +#error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
> +#endif
> +
> +/* Define bits representing the exception.  We use the bit positions
> +   of the appropriate bits in the FPU control word.  */
> +enum
> +{
> +  FE_INEXACT =
> +#define FE_INEXACT 0x010000
> +    FE_INEXACT,
> +  FE_UNDERFLOW =
> +#define FE_UNDERFLOW 0x020000
> +    FE_UNDERFLOW,
> +  FE_OVERFLOW =
> +#define FE_OVERFLOW 0x040000
> +    FE_OVERFLOW,
> +  FE_DIVBYZERO =
> +#define FE_DIVBYZERO 0x080000
> +    FE_DIVBYZERO,
> +  FE_INVALID =
> +#define FE_INVALID 0x100000
> +    FE_INVALID,
> +};
> +
> +#define FE_ALL_EXCEPT \
> +  (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
> +
> +/* The LoongArch FPU supports all of the four defined rounding modes.  We
> +   use again the bit positions in the FPU control word as the values
> +   for the appropriate macros.  */
> +enum
> +{
> +  FE_TONEAREST =
> +#define FE_TONEAREST 0x000
> +    FE_TONEAREST,
> +  FE_TOWARDZERO =
> +#define FE_TOWARDZERO 0x100
> +    FE_TOWARDZERO,
> +  FE_UPWARD =
> +#define FE_UPWARD 0x200
> +    FE_UPWARD,
> +  FE_DOWNWARD =
> +#define FE_DOWNWARD 0x300
> +    FE_DOWNWARD
> +};
> +
> +/* Type representing exception flags.  */
> +typedef unsigned int fexcept_t;
> +
> +/* Type representing floating-point environment.  This function corresponds
> +   to the layout of the block written by the `fstenv'.  */
> +typedef struct
> +{
> +  unsigned int __fp_control_register;
> +} fenv_t;
> +
> +/* If the default argument is used we use this value.  */
> +#define FE_DFL_ENV ((const fenv_t *) -1)
> +
> +#ifdef __USE_GNU
> +/* Floating-point environment where none of the exception is masked.  */
> +#define FE_NOMASK_ENV ((const fenv_t *) -257)
> +#endif
> +
> +#if __GLIBC_USE (IEC_60559_BFP_EXT_C2X)
> +/* Type representing floating-point control modes.  */
> +typedef unsigned int femode_t;
> +
> +/* Default floating-point control modes.  */
> +#define FE_DFL_MODE ((const femode_t *) -1L)
> +#endif

Ok.

> diff --git a/sysdeps/loongarch/e_sqrtl.c b/sysdeps/loongarch/e_sqrtl.c
> new file mode 100644
> index 0000000000..020c8911e6
> --- /dev/null
> +++ b/sysdeps/loongarch/e_sqrtl.c
> @@ -0,0 +1,39 @@
> +/* long double square root in software floating-point emulation.
> +   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 <stdlib.h>
> +#include <soft-fp/soft-fp.h>
> +#include <soft-fp/quad.h>
> +#include <libm-alias-finite.h>
> +
> +long double
> +__ieee754_sqrtl (const long double a)
> +{
> +  FP_DECL_EX;
> +  FP_DECL_Q (A);
> +  FP_DECL_Q (C);
> +  long double c;
> +
> +  FP_INIT_ROUNDMODE;
> +  FP_UNPACK_Q (A, a);
> +  FP_SQRT_Q (C, A);
> +  FP_PACK_Q (c, C);
> +  FP_HANDLE_EXCEPTIONS;
> +  return c;
> +}
> +libm_alias_finite (__ieee754_sqrtl, __sqrtl)

Ok.

> diff --git a/sysdeps/loongarch/fpu_control.h b/sysdeps/loongarch/fpu_control.h
> new file mode 100644
> index 0000000000..d34936c62b
> --- /dev/null
> +++ b/sysdeps/loongarch/fpu_control.h
> @@ -0,0 +1,90 @@
> +/* FPU control word bits.
> +   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 _FPU_CONTROL_H
> +#define _FPU_CONTROL_H
> +
> +/* LoongArch FPU floating point control register bits.
> + *
> + * 31-29  -> reserved (read as 0, can not changed by software)
> + * 28     -> cause bit for invalid exception
> + * 27     -> cause bit for division by zero exception
> + * 26     -> cause bit for overflow exception
> + * 25     -> cause bit for underflow exception
> + * 24     -> cause bit for inexact exception
> + * 23-21  -> reserved (read as 0, can not changed by software)
> + * 20     -> flag invalid exception
> + * 19     -> flag division by zero exception
> + * 18     -> flag overflow exception
> + * 17     -> flag underflow exception
> + * 16     -> flag inexact exception
> + *  9-8   -> rounding control
> + *  7-5   -> reserved (read as 0, can not changed by software)
> + *  4     -> enable exception for invalid exception
> + *  3     -> enable exception for division by zero exception
> + *  2     -> enable exception for overflow exception
> + *  1     -> enable exception for underflow exception
> + *  0     -> enable exception for inexact exception
> + *
> + *
> + * Rounding Control:
> + * 00 - rounding ties to even (RNE)
> + * 01 - rounding toward zero (RZ)
> + * 10 - rounding (up) toward plus infinity (RP)
> + * 11 - rounding (down) toward minus infinity (RM)
> + */
> +
> +#include <features.h>
> +
> +/* Masks for interrupts.  */
> +#define _FPU_MASK_V 0x10 /* Invalid operation */
> +#define _FPU_MASK_Z 0x08 /* Division by zero  */
> +#define _FPU_MASK_O 0x04 /* Overflow */
> +#define _FPU_MASK_U 0x02 /* Underflow */
> +#define _FPU_MASK_I 0x01 /* Inexact operation */
> +
> +/* Flush denormalized numbers to zero.  */
> +#define _FPU_FLUSH_TZ 0x1000000
> +
> +/* Rounding control.  */
> +#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED */
> +#define _FPU_RC_ZERO 0x100
> +#define _FPU_RC_UP 0x200
> +#define _FPU_RC_DOWN 0x300
> +/* Mask for rounding control.  */
> +#define _FPU_RC_MASK 0x300
> +
> +#define _FPU_RESERVED 0x0
> +
> +#define _FPU_DEFAULT 0x0
> +#define _FPU_IEEE 0x1F
> +
> +/* Type of the control word.  */
> +typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
> +
> +/* Macros for accessing the hardware control word.  */
> +extern fpu_control_t __loongarch_fpu_getcw (void) __THROW;
> +extern void __loongarch_fpu_setcw (fpu_control_t) __THROW;
> +#define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$r0" : "=r"(cw))
> +#define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $r0,%0" : : "r"(cw))
> +
> +/* Default control word set at startup.  */
> +extern fpu_control_t __fpu_control;
> +
> +#endif /* fpu_control.h */
> +

Ok.

> diff --git a/sysdeps/loongarch/sfp-machine.h b/sysdeps/loongarch/sfp-machine.h
> new file mode 100644
> index 0000000000..5b92ac4ba2
> --- /dev/null
> +++ b/sysdeps/loongarch/sfp-machine.h
> @@ -0,0 +1,102 @@
> +/* LoongArch softfloat definitions
> +   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 _FP_W_TYPE_SIZE 64
> +#define _FP_W_TYPE unsigned long long
> +#define _FP_WS_TYPE signed long long
> +#define _FP_I_TYPE long long
> +
> +#define _FP_MUL_MEAT_S(R, X, Y) _FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y)
> +#define _FP_MUL_MEAT_D(R, X, Y) \
> +  _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
> +#define _FP_MUL_MEAT_Q(R, X, Y) \
> +  _FP_MUL_MEAT_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
> +
> +#define _FP_MUL_MEAT_DW_S(R, X, Y) \
> +  _FP_MUL_MEAT_DW_1_imm (_FP_WFRACBITS_S, R, X, Y)
> +#define _FP_MUL_MEAT_DW_D(R, X, Y) \
> +  _FP_MUL_MEAT_DW_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
> +#define _FP_MUL_MEAT_DW_Q(R, X, Y) \
> +  _FP_MUL_MEAT_DW_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
> +
> +#define _FP_DIV_MEAT_S(R, X, Y) \
> +  _FP_DIV_MEAT_1_imm (S, R, X, Y, _FP_DIV_HELP_imm)
> +#define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_1_udiv_norm (D, R, X, Y)
> +#define _FP_DIV_MEAT_Q(R, X, Y) _FP_DIV_MEAT_2_udiv (Q, R, X, Y)
> +
> +#define _FP_NANFRAC_S _FP_QNANBIT_S
> +#define _FP_NANFRAC_D _FP_QNANBIT_D
> +#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
> +
> +#define _FP_NANSIGN_S 0
> +#define _FP_NANSIGN_D 0
> +#define _FP_NANSIGN_Q 0
> +
> +#define _FP_KEEPNANFRACP 1
> +#define _FP_QNANNEGATEDP 0
> +
> +/* NaN payloads should be preserved for NAN2008.  */
> +#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
> +  do \
> +    { \
> +      R##_s = X##_s; \
> +      _FP_FRAC_COPY_##wc (R, X); \
> +      R##_c = FP_CLS_NAN; \
> +    } \
> +  while (0)
> +
> +#define _FP_DECL_EX fpu_control_t _fcw
> +
> +#define FP_ROUNDMODE (_fcw & 0x300)
> +
> +#define FP_RND_NEAREST FE_TONEAREST
> +#define FP_RND_ZERO FE_TOWARDZERO
> +#define FP_RND_PINF FE_UPWARD
> +#define FP_RND_MINF FE_DOWNWARD
> +
> +#define FP_EX_INVALID FE_INVALID
> +#define FP_EX_OVERFLOW FE_OVERFLOW
> +#define FP_EX_UNDERFLOW FE_UNDERFLOW
> +#define FP_EX_DIVZERO FE_DIVBYZERO
> +#define FP_EX_INEXACT FE_INEXACT
> +
> +#define _FP_TININESS_AFTER_ROUNDING 1
> +
> +#ifdef __loongarch_hard_float
> +#define FP_INIT_ROUNDMODE \
> +  do \
> +    { \
> +      _FPU_GETCW (_fcw); \
> +    } \
> +  while (0)
> +
> +#define FP_HANDLE_EXCEPTIONS \
> +  do \
> +    { \
> +      if (__glibc_unlikely (_fex)) \
> +	_FPU_SETCW (_fcw | _fex | (_fex << 8)); \
> +    } \
> +  while (0)
> +#define FP_TRAPPING_EXCEPTIONS ((_fcw << 16) & 0x1f0000)
> +#else
> +#define FP_INIT_ROUNDMODE _fcw = FP_RND_NEAREST
> +#endif
> diff --git a/sysdeps/loongarch/tininess.h b/sysdeps/loongarch/tininess.h
> new file mode 100644
> index 0000000000..90956c35f7
> --- /dev/null
> +++ b/sysdeps/loongarch/tininess.h
> @@ -0,0 +1 @@
> +#define TININESS_AFTER_ROUNDING 1

Ok.
  

Patch

diff --git a/sysdeps/loongarch/bits/fenv.h b/sysdeps/loongarch/bits/fenv.h
new file mode 100644
index 0000000000..7e223b402b
--- /dev/null
+++ b/sysdeps/loongarch/bits/fenv.h
@@ -0,0 +1,90 @@ 
+/* 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/>.  */
+
+#ifndef _FENV_H
+#error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+/* Define bits representing the exception.  We use the bit positions
+   of the appropriate bits in the FPU control word.  */
+enum
+{
+  FE_INEXACT =
+#define FE_INEXACT 0x010000
+    FE_INEXACT,
+  FE_UNDERFLOW =
+#define FE_UNDERFLOW 0x020000
+    FE_UNDERFLOW,
+  FE_OVERFLOW =
+#define FE_OVERFLOW 0x040000
+    FE_OVERFLOW,
+  FE_DIVBYZERO =
+#define FE_DIVBYZERO 0x080000
+    FE_DIVBYZERO,
+  FE_INVALID =
+#define FE_INVALID 0x100000
+    FE_INVALID,
+};
+
+#define FE_ALL_EXCEPT \
+  (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* The LoongArch FPU supports all of the four defined rounding modes.  We
+   use again the bit positions in the FPU control word as the values
+   for the appropriate macros.  */
+enum
+{
+  FE_TONEAREST =
+#define FE_TONEAREST 0x000
+    FE_TONEAREST,
+  FE_TOWARDZERO =
+#define FE_TOWARDZERO 0x100
+    FE_TOWARDZERO,
+  FE_UPWARD =
+#define FE_UPWARD 0x200
+    FE_UPWARD,
+  FE_DOWNWARD =
+#define FE_DOWNWARD 0x300
+    FE_DOWNWARD
+};
+
+/* Type representing exception flags.  */
+typedef unsigned int fexcept_t;
+
+/* Type representing floating-point environment.  This function corresponds
+   to the layout of the block written by the `fstenv'.  */
+typedef struct
+{
+  unsigned int __fp_control_register;
+} fenv_t;
+
+/* If the default argument is used we use this value.  */
+#define FE_DFL_ENV ((const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exception is masked.  */
+#define FE_NOMASK_ENV ((const fenv_t *) -257)
+#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT_C2X)
+/* Type representing floating-point control modes.  */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes.  */
+#define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/loongarch/e_sqrtl.c b/sysdeps/loongarch/e_sqrtl.c
new file mode 100644
index 0000000000..020c8911e6
--- /dev/null
+++ b/sysdeps/loongarch/e_sqrtl.c
@@ -0,0 +1,39 @@ 
+/* long double square root in software floating-point emulation.
+   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 <stdlib.h>
+#include <soft-fp/soft-fp.h>
+#include <soft-fp/quad.h>
+#include <libm-alias-finite.h>
+
+long double
+__ieee754_sqrtl (const long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q (A);
+  FP_DECL_Q (C);
+  long double c;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q (A, a);
+  FP_SQRT_Q (C, A);
+  FP_PACK_Q (c, C);
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
+libm_alias_finite (__ieee754_sqrtl, __sqrtl)
diff --git a/sysdeps/loongarch/fpu_control.h b/sysdeps/loongarch/fpu_control.h
new file mode 100644
index 0000000000..d34936c62b
--- /dev/null
+++ b/sysdeps/loongarch/fpu_control.h
@@ -0,0 +1,90 @@ 
+/* FPU control word bits.
+   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 _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+/* LoongArch FPU floating point control register bits.
+ *
+ * 31-29  -> reserved (read as 0, can not changed by software)
+ * 28     -> cause bit for invalid exception
+ * 27     -> cause bit for division by zero exception
+ * 26     -> cause bit for overflow exception
+ * 25     -> cause bit for underflow exception
+ * 24     -> cause bit for inexact exception
+ * 23-21  -> reserved (read as 0, can not changed by software)
+ * 20     -> flag invalid exception
+ * 19     -> flag division by zero exception
+ * 18     -> flag overflow exception
+ * 17     -> flag underflow exception
+ * 16     -> flag inexact exception
+ *  9-8   -> rounding control
+ *  7-5   -> reserved (read as 0, can not changed by software)
+ *  4     -> enable exception for invalid exception
+ *  3     -> enable exception for division by zero exception
+ *  2     -> enable exception for overflow exception
+ *  1     -> enable exception for underflow exception
+ *  0     -> enable exception for inexact exception
+ *
+ *
+ * Rounding Control:
+ * 00 - rounding ties to even (RNE)
+ * 01 - rounding toward zero (RZ)
+ * 10 - rounding (up) toward plus infinity (RP)
+ * 11 - rounding (down) toward minus infinity (RM)
+ */
+
+#include <features.h>
+
+/* Masks for interrupts.  */
+#define _FPU_MASK_V 0x10 /* Invalid operation */
+#define _FPU_MASK_Z 0x08 /* Division by zero  */
+#define _FPU_MASK_O 0x04 /* Overflow */
+#define _FPU_MASK_U 0x02 /* Underflow */
+#define _FPU_MASK_I 0x01 /* Inexact operation */
+
+/* Flush denormalized numbers to zero.  */
+#define _FPU_FLUSH_TZ 0x1000000
+
+/* Rounding control.  */
+#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED */
+#define _FPU_RC_ZERO 0x100
+#define _FPU_RC_UP 0x200
+#define _FPU_RC_DOWN 0x300
+/* Mask for rounding control.  */
+#define _FPU_RC_MASK 0x300
+
+#define _FPU_RESERVED 0x0
+
+#define _FPU_DEFAULT 0x0
+#define _FPU_IEEE 0x1F
+
+/* Type of the control word.  */
+typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
+
+/* Macros for accessing the hardware control word.  */
+extern fpu_control_t __loongarch_fpu_getcw (void) __THROW;
+extern void __loongarch_fpu_setcw (fpu_control_t) __THROW;
+#define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$r0" : "=r"(cw))
+#define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $r0,%0" : : "r"(cw))
+
+/* Default control word set at startup.  */
+extern fpu_control_t __fpu_control;
+
+#endif /* fpu_control.h */
+
diff --git a/sysdeps/loongarch/sfp-machine.h b/sysdeps/loongarch/sfp-machine.h
new file mode 100644
index 0000000000..5b92ac4ba2
--- /dev/null
+++ b/sysdeps/loongarch/sfp-machine.h
@@ -0,0 +1,102 @@ 
+/* LoongArch softfloat definitions
+   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 _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long long
+#define _FP_WS_TYPE signed long long
+#define _FP_I_TYPE long long
+
+#define _FP_MUL_MEAT_S(R, X, Y) _FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y)
+#define _FP_MUL_MEAT_D(R, X, Y) \
+  _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
+#define _FP_MUL_MEAT_Q(R, X, Y) \
+  _FP_MUL_MEAT_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
+
+#define _FP_MUL_MEAT_DW_S(R, X, Y) \
+  _FP_MUL_MEAT_DW_1_imm (_FP_WFRACBITS_S, R, X, Y)
+#define _FP_MUL_MEAT_DW_D(R, X, Y) \
+  _FP_MUL_MEAT_DW_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
+#define _FP_MUL_MEAT_DW_Q(R, X, Y) \
+  _FP_MUL_MEAT_DW_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R, X, Y) \
+  _FP_DIV_MEAT_1_imm (S, R, X, Y, _FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_1_udiv_norm (D, R, X, Y)
+#define _FP_DIV_MEAT_Q(R, X, Y) _FP_DIV_MEAT_2_udiv (Q, R, X, Y)
+
+#define _FP_NANFRAC_S _FP_QNANBIT_S
+#define _FP_NANFRAC_D _FP_QNANBIT_D
+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
+
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+#define _FP_QNANNEGATEDP 0
+
+/* NaN payloads should be preserved for NAN2008.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+  do \
+    { \
+      R##_s = X##_s; \
+      _FP_FRAC_COPY_##wc (R, X); \
+      R##_c = FP_CLS_NAN; \
+    } \
+  while (0)
+
+#define _FP_DECL_EX fpu_control_t _fcw
+
+#define FP_ROUNDMODE (_fcw & 0x300)
+
+#define FP_RND_NEAREST FE_TONEAREST
+#define FP_RND_ZERO FE_TOWARDZERO
+#define FP_RND_PINF FE_UPWARD
+#define FP_RND_MINF FE_DOWNWARD
+
+#define FP_EX_INVALID FE_INVALID
+#define FP_EX_OVERFLOW FE_OVERFLOW
+#define FP_EX_UNDERFLOW FE_UNDERFLOW
+#define FP_EX_DIVZERO FE_DIVBYZERO
+#define FP_EX_INEXACT FE_INEXACT
+
+#define _FP_TININESS_AFTER_ROUNDING 1
+
+#ifdef __loongarch_hard_float
+#define FP_INIT_ROUNDMODE \
+  do \
+    { \
+      _FPU_GETCW (_fcw); \
+    } \
+  while (0)
+
+#define FP_HANDLE_EXCEPTIONS \
+  do \
+    { \
+      if (__glibc_unlikely (_fex)) \
+	_FPU_SETCW (_fcw | _fex | (_fex << 8)); \
+    } \
+  while (0)
+#define FP_TRAPPING_EXCEPTIONS ((_fcw << 16) & 0x1f0000)
+#else
+#define FP_INIT_ROUNDMODE _fcw = FP_RND_NEAREST
+#endif
diff --git a/sysdeps/loongarch/tininess.h b/sysdeps/loongarch/tininess.h
new file mode 100644
index 0000000000..90956c35f7
--- /dev/null
+++ b/sysdeps/loongarch/tininess.h
@@ -0,0 +1 @@ 
+#define TININESS_AFTER_ROUNDING 1