[PATCH] LoongArch: Optimize float environment functions

caiyinyu caiyinyu@loongson.cn
Tue Mar 10 07:32:54 GMT 2026


LGTM

在 2026/3/9 下午3:37, Deng Jianbo 写道:
> In LoongArch, fcsr1 is the alias of enables field in fcsr0, fscr3 is the
> alias of RM field in fscr0. This patch use fcsr1 and fcsr3 register to
> optimize fedisableexcept, feenableexcept, fegetexcept, fegetround,
> fesetround, get_rounding_mode functions, which could reduce the
> additional andi instruction.
> ---
>   sysdeps/loongarch/fpu/fedisblxcpt.c       |  8 ++++----
>   sysdeps/loongarch/fpu/feenablxcpt.c       |  8 ++++----
>   sysdeps/loongarch/fpu/fegetexcept.c       |  6 +++---
>   sysdeps/loongarch/fpu/fegetround.c        |  7 +++----
>   sysdeps/loongarch/fpu/fesetround.c        | 12 ++----------
>   sysdeps/loongarch/fpu/get-rounding-mode.h |  5 +++--
>   sysdeps/loongarch/fpu_control.h           |  6 ++++++
>   7 files changed, 25 insertions(+), 27 deletions(-)
>
> diff --git a/sysdeps/loongarch/fpu/fedisblxcpt.c b/sysdeps/loongarch/fpu/fedisblxcpt.c
> index 3ca2056ca3..3153eb3e94 100644
> --- a/sysdeps/loongarch/fpu/fedisblxcpt.c
> +++ b/sysdeps/loongarch/fpu/fedisblxcpt.c
> @@ -25,15 +25,15 @@ fedisableexcept (int excepts)
>   {
>     unsigned int new_exc, old_exc;
>   
> -  /* Get the current control word.  */
> -  _FPU_GETCW (new_exc);
> +  /* Get the current enables.  */
> +  _FPU_GET_ENABLES (new_exc);
>   
> -  old_exc = (new_exc & ENABLE_MASK) << ENABLE_SHIFT;
> +  old_exc = new_exc << ENABLE_SHIFT;
>   
>     excepts &= FE_ALL_EXCEPT;
>   
>     new_exc &= ~(excepts >> ENABLE_SHIFT);
> -  _FPU_SETCW (new_exc);
> +  _FPU_SET_ENABLES (new_exc);
>   
>     return old_exc;
>   }
> diff --git a/sysdeps/loongarch/fpu/feenablxcpt.c b/sysdeps/loongarch/fpu/feenablxcpt.c
> index 670fc239d8..6ce78f5bab 100644
> --- a/sysdeps/loongarch/fpu/feenablxcpt.c
> +++ b/sysdeps/loongarch/fpu/feenablxcpt.c
> @@ -25,15 +25,15 @@ feenableexcept (int excepts)
>   {
>     unsigned int new_exc, old_exc;
>   
> -  /* Get the current control word.  */
> -  _FPU_GETCW (new_exc);
> +  /* Get the current enables.  */
> +  _FPU_GET_ENABLES (new_exc);
>   
> -  old_exc = (new_exc & ENABLE_MASK) << ENABLE_SHIFT;
> +  old_exc = new_exc << ENABLE_SHIFT;
>   
>     excepts &= FE_ALL_EXCEPT;
>   
>     new_exc |= excepts >> ENABLE_SHIFT;
> -  _FPU_SETCW (new_exc);
> +  _FPU_SET_ENABLES (new_exc);
>   
>     return old_exc;
>   }
> diff --git a/sysdeps/loongarch/fpu/fegetexcept.c b/sysdeps/loongarch/fpu/fegetexcept.c
> index 872e6d7c69..eb98ee5707 100644
> --- a/sysdeps/loongarch/fpu/fegetexcept.c
> +++ b/sysdeps/loongarch/fpu/fegetexcept.c
> @@ -25,8 +25,8 @@ fegetexcept (void)
>   {
>     unsigned int exc;
>   
> -  /* Get the current control word.  */
> -  _FPU_GETCW (exc);
> +  /* Get the current enables.  */
> +  _FPU_GET_ENABLES (exc);
>   
> -  return (exc & ENABLE_MASK) << ENABLE_SHIFT;
> +  return exc << ENABLE_SHIFT;
>   }
> diff --git a/sysdeps/loongarch/fpu/fegetround.c b/sysdeps/loongarch/fpu/fegetround.c
> index 04f543209c..2380614097 100644
> --- a/sysdeps/loongarch/fpu/fegetround.c
> +++ b/sysdeps/loongarch/fpu/fegetround.c
> @@ -23,11 +23,10 @@ int
>   __fegetround (void)
>   {
>     int cw;
> +  /* Get RM control word.  */
> +  _FPU_GET_RM (cw);
>   
> -  /* Get control word.  */
> -  _FPU_GETCW (cw);
> -
> -  return cw & _FPU_RC_MASK;
> +  return cw;
>   }
>   libm_hidden_def (__fegetround) weak_alias (__fegetround, fegetround)
>   libm_hidden_weak (fegetround)
> diff --git a/sysdeps/loongarch/fpu/fesetround.c b/sysdeps/loongarch/fpu/fesetround.c
> index 8ffb18f4a3..9c4d1e6db6 100644
> --- a/sysdeps/loongarch/fpu/fesetround.c
> +++ b/sysdeps/loongarch/fpu/fesetround.c
> @@ -22,20 +22,12 @@
>   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);
> +  /* Set RM state.  */
> +  _FPU_SET_RM (round);
>   
>     return 0;
>   }
> diff --git a/sysdeps/loongarch/fpu/get-rounding-mode.h b/sysdeps/loongarch/fpu/get-rounding-mode.h
> index 5f1b2049d1..5cd4c3beab 100644
> --- a/sysdeps/loongarch/fpu/get-rounding-mode.h
> +++ b/sysdeps/loongarch/fpu/get-rounding-mode.h
> @@ -31,8 +31,9 @@ get_rounding_mode (void)
>   {
>     fpu_control_t fpcr;
>   
> -  _FPU_GETCW (fpcr);
> -  return fpcr & _FPU_RC_MASK;
> +  _FPU_GET_RM (fpcr);
> +
> +  return fpcr;
>   }
>   
>   #endif /* get-rounding-mode.h */
> diff --git a/sysdeps/loongarch/fpu_control.h b/sysdeps/loongarch/fpu_control.h
> index f066e53dc4..95976fa192 100644
> --- a/sysdeps/loongarch/fpu_control.h
> +++ b/sysdeps/loongarch/fpu_control.h
> @@ -94,6 +94,12 @@ extern void __loongarch_fpu_setcw (fpu_control_t) __THROW;
>   #define _FPU_GETCW(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr0" : "=r"(cw))
>   #define _FPU_SETCW(cw) __asm__ volatile ("movgr2fcsr $fcsr0,%0" : : "r"(cw))
>   
> +#define _FPU_GET_ENABLES(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr1" : "=r"(cw))
> +#define _FPU_SET_ENABLES(cw) __asm__ volatile ("movgr2fcsr $fcsr1,%0" : : "r"(cw))
> +
> +#define _FPU_GET_RM(cw) __asm__ volatile ("movfcsr2gr %0,$fcsr3" : "=r"(cw))
> +#define _FPU_SET_RM(cw) __asm__ volatile ("movgr2fcsr $fcsr3,%0" : : "r"(cw))
> +
>   /* Default control word set at startup.  */
>   extern fpu_control_t __fpu_control;
>   



More information about the Libc-alpha mailing list