[PATCH v2 3/4] riscv: Add Zfa for the rounding functions

Julian Zhu <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
Use compiler builtins for the float and double ceil, floor, nearbyint,
rint, round, roundeven and trunc implementations when Zfa is enabled.

Signed-off-by: Julian Zhu <[email protected]>
---
 sysdeps/riscv/rv64/rvd/s_ceil.c      | 6 ++++++
 sysdeps/riscv/rv64/rvd/s_floor.c     | 6 ++++++
 sysdeps/riscv/rv64/rvd/s_nearbyint.c | 7 +++++++
 sysdeps/riscv/rv64/rvd/s_rint.c      | 7 +++++++
 sysdeps/riscv/rv64/rvd/s_round.c     | 7 +++++++
 sysdeps/riscv/rv64/rvd/s_roundeven.c | 7 +++++++
 sysdeps/riscv/rv64/rvd/s_trunc.c     | 6 ++++++
 sysdeps/riscv/rvf/s_ceilf.c          | 6 ++++++
 sysdeps/riscv/rvf/s_floorf.c         | 6 ++++++
 sysdeps/riscv/rvf/s_nearbyintf.c     | 7 +++++++
 sysdeps/riscv/rvf/s_rintf.c          | 7 +++++++
 sysdeps/riscv/rvf/s_roundevenf.c     | 7 +++++++
 sysdeps/riscv/rvf/s_roundf.c         | 7 +++++++
 sysdeps/riscv/rvf/s_truncf.c         | 6 ++++++
 14 files changed, 92 insertions(+)

diff --git a/sysdeps/riscv/rv64/rvd/s_ceil.c b/sysdeps/riscv/rv64/rvd/s_ceil.c
index 01519aeee7..7f62a72de1 100644
--- a/sysdeps/riscv/rv64/rvd/s_ceil.c
+++ b/sysdeps/riscv/rv64/rvd/s_ceil.c
@@ -25,6 +25,11 @@
 double
 __ceil (double x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.d rounds to an integer with a static rounding mode
+     (rup for ceil) without raising the inexact exception.  */
+  return __builtin_ceil (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   double mag = fabs (x);
@@ -48,6 +53,7 @@ __ceil (double x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_double (__ceil, ceil)
diff --git a/sysdeps/riscv/rv64/rvd/s_floor.c b/sysdeps/riscv/rv64/rvd/s_floor.c
index bce3e403c6..1e9a4fc65a 100644
--- a/sysdeps/riscv/rv64/rvd/s_floor.c
+++ b/sysdeps/riscv/rv64/rvd/s_floor.c
@@ -25,6 +25,11 @@
 double
 __floor (double x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.d rounds to an integer with a static rounding mode
+     (rdn for floor) without raising the inexact exception.  */
+  return __builtin_floor (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   double mag = fabs (x);
@@ -48,6 +53,7 @@ __floor (double x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_double (__floor, floor)
diff --git a/sysdeps/riscv/rv64/rvd/s_nearbyint.c b/sysdeps/riscv/rv64/rvd/s_nearbyint.c
index 79502f8109..6c5fa9f01d 100644
--- a/sysdeps/riscv/rv64/rvd/s_nearbyint.c
+++ b/sysdeps/riscv/rv64/rvd/s_nearbyint.c
@@ -24,6 +24,12 @@
 double
 __nearbyint (double x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.d rounds to an integer in the current rounding mode
+     without raising the inexact exception, matching nearbyint, and
+     handles NaN and out-of-range inputs in one instruction.  */
+  return __builtin_nearbyint (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   double mag = fabs (x);
@@ -47,6 +53,7 @@ __nearbyint (double x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_double (__nearbyint, nearbyint)
diff --git a/sysdeps/riscv/rv64/rvd/s_rint.c b/sysdeps/riscv/rv64/rvd/s_rint.c
index e5b5e42ed2..df338e98ae 100644
--- a/sysdeps/riscv/rv64/rvd/s_rint.c
+++ b/sysdeps/riscv/rv64/rvd/s_rint.c
@@ -25,6 +25,12 @@
 double
 __rint (double x)
 {
+#ifdef __riscv_zfa
+  /* Zfa froundnx.d rounds to an integer in the current rounding mode,
+     raises the inexact exception for non-integer values, and handles
+     NaN and out-of-range inputs, implementing rint in one instruction.  */
+  return __builtin_rint (x);
+#else
   bool nan;
   double mag;
 
@@ -48,6 +54,7 @@ __rint (double x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_double (__rint, rint)
diff --git a/sysdeps/riscv/rv64/rvd/s_round.c b/sysdeps/riscv/rv64/rvd/s_round.c
index 8c3df99271..541261d205 100644
--- a/sysdeps/riscv/rv64/rvd/s_round.c
+++ b/sysdeps/riscv/rv64/rvd/s_round.c
@@ -25,6 +25,12 @@
 double
 __round (double x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.d rounds to an integer with a static rounding mode
+     (rmm, round half away from zero, for round) without raising the
+     inexact exception.  */
+  return __builtin_round (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   double mag = fabs (x);
@@ -48,6 +54,7 @@ __round (double x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_double (__round, round)
diff --git a/sysdeps/riscv/rv64/rvd/s_roundeven.c b/sysdeps/riscv/rv64/rvd/s_roundeven.c
index ed00098a94..d905a91326 100644
--- a/sysdeps/riscv/rv64/rvd/s_roundeven.c
+++ b/sysdeps/riscv/rv64/rvd/s_roundeven.c
@@ -25,6 +25,12 @@
 double
 __roundeven (double x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.d rounds to an integer with a static rounding mode
+     (rne, round half to even, for roundeven) without raising the
+     inexact exception.  */
+  return __builtin_roundeven (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   double mag = fabs (x);
@@ -48,6 +54,7 @@ __roundeven (double x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_double (__roundeven, roundeven)
diff --git a/sysdeps/riscv/rv64/rvd/s_trunc.c b/sysdeps/riscv/rv64/rvd/s_trunc.c
index 33f690eed3..581a51497c 100644
--- a/sysdeps/riscv/rv64/rvd/s_trunc.c
+++ b/sysdeps/riscv/rv64/rvd/s_trunc.c
@@ -25,6 +25,11 @@
 double
 __trunc (double x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.d rounds to an integer with a static rounding mode
+     (rtz for trunc) without raising the inexact exception.  */
+  return __builtin_trunc (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   double mag = fabs (x);
@@ -48,6 +53,7 @@ __trunc (double x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_double (__trunc, trunc)
diff --git a/sysdeps/riscv/rvf/s_ceilf.c b/sysdeps/riscv/rvf/s_ceilf.c
index 8dfbda85cc..2923d6e32d 100644
--- a/sysdeps/riscv/rvf/s_ceilf.c
+++ b/sysdeps/riscv/rvf/s_ceilf.c
@@ -25,6 +25,11 @@
 float
 __ceilf (float x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.s rounds to an integer with a static rounding mode
+     (rup for ceil) without raising the inexact exception.  */
+  return __builtin_ceilf (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   float mag = fabsf (x);
@@ -48,6 +53,7 @@ __ceilf (float x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_float (__ceil, ceil)
diff --git a/sysdeps/riscv/rvf/s_floorf.c b/sysdeps/riscv/rvf/s_floorf.c
index 7ecce22ec8..c9de4158d1 100644
--- a/sysdeps/riscv/rvf/s_floorf.c
+++ b/sysdeps/riscv/rvf/s_floorf.c
@@ -25,6 +25,11 @@
 float
 __floorf (float x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.s rounds to an integer with a static rounding mode
+     (rdn for floor) without raising the inexact exception.  */
+  return __builtin_floorf (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   float mag = fabsf (x);
@@ -48,6 +53,7 @@ __floorf (float x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_float (__floor, floor)
diff --git a/sysdeps/riscv/rvf/s_nearbyintf.c b/sysdeps/riscv/rvf/s_nearbyintf.c
index b4bed924da..715f64361a 100644
--- a/sysdeps/riscv/rvf/s_nearbyintf.c
+++ b/sysdeps/riscv/rvf/s_nearbyintf.c
@@ -24,6 +24,12 @@
 float
 __nearbyintf (float x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.s rounds to an integer in the current rounding mode
+     without raising the inexact exception, matching nearbyintf, and
+     handles NaN and out-of-range inputs in one instruction.  */
+  return __builtin_nearbyintf (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   float mag = fabsf (x);
@@ -47,6 +53,7 @@ __nearbyintf (float x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_float (__nearbyint, nearbyint)
diff --git a/sysdeps/riscv/rvf/s_rintf.c b/sysdeps/riscv/rvf/s_rintf.c
index 01ce204494..9c2fb1c330 100644
--- a/sysdeps/riscv/rvf/s_rintf.c
+++ b/sysdeps/riscv/rvf/s_rintf.c
@@ -25,6 +25,12 @@
 float
 __rintf (float x)
 {
+#ifdef __riscv_zfa
+  /* Zfa froundnx.s rounds to an integer in the current rounding mode,
+     raises the inexact exception for non-integer values, and handles
+     NaN and out-of-range inputs, implementing rintf in one instruction.  */
+  return __builtin_rintf (x);
+#else
   bool nan;
   float mag;
 
@@ -48,6 +54,7 @@ __rintf (float x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_float (__rint, rint)
diff --git a/sysdeps/riscv/rvf/s_roundevenf.c b/sysdeps/riscv/rvf/s_roundevenf.c
index 5fe395b461..315f8bf046 100644
--- a/sysdeps/riscv/rvf/s_roundevenf.c
+++ b/sysdeps/riscv/rvf/s_roundevenf.c
@@ -25,6 +25,12 @@
 float
 __roundevenf (float x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.s rounds to an integer with a static rounding mode
+     (rne, round half to even, for roundeven) without raising the
+     inexact exception.  */
+  return __builtin_roundevenf (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   float mag = fabsf (x);
@@ -48,6 +54,7 @@ __roundevenf (float x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_float (__roundeven, roundeven)
diff --git a/sysdeps/riscv/rvf/s_roundf.c b/sysdeps/riscv/rvf/s_roundf.c
index 8291ccff74..9872c6c320 100644
--- a/sysdeps/riscv/rvf/s_roundf.c
+++ b/sysdeps/riscv/rvf/s_roundf.c
@@ -25,6 +25,12 @@
 float
 __roundf (float x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.s rounds to an integer with a static rounding mode
+     (rmm, round half away from zero, for round) without raising the
+     inexact exception.  */
+  return __builtin_roundf (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   float mag = fabsf (x);
@@ -48,6 +54,7 @@ __roundf (float x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_float (__round, round)
diff --git a/sysdeps/riscv/rvf/s_truncf.c b/sysdeps/riscv/rvf/s_truncf.c
index aa1f40112f..d325c1ccf3 100644
--- a/sysdeps/riscv/rvf/s_truncf.c
+++ b/sysdeps/riscv/rvf/s_truncf.c
@@ -25,6 +25,11 @@
 float
 __truncf (float x)
 {
+#ifdef __riscv_zfa
+  /* Zfa fround.s rounds to an integer with a static rounding mode
+     (rtz for trunc) without raising the inexact exception.  */
+  return __builtin_truncf (x);
+#else
   int flags = riscv_getflags ();
   bool nan = isnan (x);
   float mag = fabsf (x);
@@ -48,6 +53,7 @@ __truncf (float x)
     }
 
   return x;
+#endif
 }
 
 libm_alias_float (__trunc, trunc)
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.