[PATCH 4/5] riscv: Use Zfa for floating-point rounding functions
Julian Zhu <[email protected]> Thu, 6 Aug 2026 18:25:30 +0800
| 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