[PATCH] LoongArch: Optimize float environment functions
Deng Jianbo
dengjianbo@loongson.cn
Mon Mar 9 07:37:49 GMT 2026
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;
--
2.20.1
More information about the Libc-alpha
mailing list