[PATCH v2 2/4] riscv: Add Zfa implementations for fmaximum and fminimum

Julian Zhu <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
Use the Zfa fmaxm and fminm instructions for the NaN-propagating C23
maximum and minimum operations in float and double precision, which they
implement directly: one instruction and no branch, against the eight
instructions and a branch the generic implementation needs even with Zfa
in -march.

Signed-off-by: Julian Zhu <[email protected]>
---
 sysdeps/riscv/rvd/s_fmaximum.c  | 44 +++++++++++++++++++++++++++++++++
 sysdeps/riscv/rvd/s_fminimum.c  | 42 +++++++++++++++++++++++++++++++
 sysdeps/riscv/rvf/s_fmaximumf.c | 42 +++++++++++++++++++++++++++++++
 sysdeps/riscv/rvf/s_fminimumf.c | 42 +++++++++++++++++++++++++++++++
 4 files changed, 170 insertions(+)
 create mode 100644 sysdeps/riscv/rvd/s_fmaximum.c
 create mode 100644 sysdeps/riscv/rvd/s_fminimum.c
 create mode 100644 sysdeps/riscv/rvf/s_fmaximumf.c
 create mode 100644 sysdeps/riscv/rvf/s_fminimumf.c

diff --git a/sysdeps/riscv/rvd/s_fmaximum.c b/sysdeps/riscv/rvd/s_fmaximum.c
new file mode 100644
index 0000000000..39b0f4658f
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_fmaximum.c
@@ -0,0 +1,44 @@
+/* fmaximum().  RISC-V version.
+   Copyright (C) 2026 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/>.  */
+
+/* fmaximum is the IEEE 754-2019 maximum operation: like fmaximum_num but
+   NaN-propagating, so a NaN operand yields a quiet NaN result, and a
+   signaling NaN also raises the invalid exception.  Zfa's fmaxm.d
+   implements it in a single instruction; without Zfa no instruction
+   implements it, so use the generic implementation.  */
+
+#ifdef __riscv_zfa
+
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__fmaximum (double x, double y)
+{
+  double res;
+  asm ("fmaxm.d %0, %1, %2" : "=f" (res) : "f" (x), "f" (y));
+  return res;
+}
+libm_alias_double (__fmaximum, fmaximum)
+
+#else
+
+# include <math-type-macros-double.h>
+# include <s_fmaximum_template.c>
+
+#endif
diff --git a/sysdeps/riscv/rvd/s_fminimum.c b/sysdeps/riscv/rvd/s_fminimum.c
new file mode 100644
index 0000000000..7726269a55
--- /dev/null
+++ b/sysdeps/riscv/rvd/s_fminimum.c
@@ -0,0 +1,42 @@
+/* fminimum().  RISC-V version.
+   Copyright (C) 2026 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/>.  */
+
+/* See s_fmaximum.c for a description of the semantics and of why the
+   fast path is gated on Zfa; fminm.d implements minimum for double
+   precision.  */
+
+#ifdef __riscv_zfa
+
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__fminimum (double x, double y)
+{
+  double res;
+  asm ("fminm.d %0, %1, %2" : "=f" (res) : "f" (x), "f" (y));
+  return res;
+}
+libm_alias_double (__fminimum, fminimum)
+
+#else
+
+# include <math-type-macros-double.h>
+# include <s_fminimum_template.c>
+
+#endif
diff --git a/sysdeps/riscv/rvf/s_fmaximumf.c b/sysdeps/riscv/rvf/s_fmaximumf.c
new file mode 100644
index 0000000000..4b30a5457f
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_fmaximumf.c
@@ -0,0 +1,42 @@
+/* fmaximumf().  RISC-V version.
+   Copyright (C) 2026 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/>.  */
+
+/* See s_fmaximum.c for a description of the semantics and of why the
+   fast path is gated on Zfa; fmaxm.s implements maximum for single
+   precision.  */
+
+#ifdef __riscv_zfa
+
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__fmaximumf (float x, float y)
+{
+  float res;
+  asm ("fmaxm.s %0, %1, %2" : "=f" (res) : "f" (x), "f" (y));
+  return res;
+}
+libm_alias_float (__fmaximum, fmaximum)
+
+#else
+
+# include <math-type-macros-float.h>
+# include <s_fmaximum_template.c>
+
+#endif
diff --git a/sysdeps/riscv/rvf/s_fminimumf.c b/sysdeps/riscv/rvf/s_fminimumf.c
new file mode 100644
index 0000000000..3faba4b91f
--- /dev/null
+++ b/sysdeps/riscv/rvf/s_fminimumf.c
@@ -0,0 +1,42 @@
+/* fminimumf().  RISC-V version.
+   Copyright (C) 2026 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/>.  */
+
+/* See s_fmaximum.c for a description of the semantics and of why the
+   fast path is gated on Zfa; fminm.s implements minimum for single
+   precision.  */
+
+#ifdef __riscv_zfa
+
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__fminimumf (float x, float y)
+{
+  float res;
+  asm ("fminm.s %0, %1, %2" : "=f" (res) : "f" (x), "f" (y));
+  return res;
+}
+libm_alias_float (__fminimum, fminimum)
+
+#else
+
+# include <math-type-macros-float.h>
+# include <s_fminimum_template.c>
+
+#endif
-- 
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.