[RFC PATCH 4/5] riscv: libmvec: add RVV logf

Yao Zihong zihong.plct@isrc.iscas.ac.cn
Sun Feb 8 22:04:39 GMT 2026


From: Zihong Yao <zihong.plct@isrc.iscas.ac.cn>

Add the RVV single-precision logf implementation and register it
as a libmvec vector entry point.

Export the logf symbols, hook the function into the build/bench
lists, and add ABI test for logf.

Signed-off-by: Zihong Yao <zihong.plct@isrc.iscas.ac.cn>
---
 sysdeps/riscv/rvd/Makeconfig                  |   2 +
 sysdeps/riscv/rvd/Versions                    |  11 ++
 sysdeps/riscv/rvd/test-float-libmvec-logf.c   |  21 +++
 sysdeps/riscv/rvd/v_f_logf.c                  |  22 +++
 sysdeps/riscv/rvd/v_f_logf_skeleton.c         | 138 ++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/libmvec.abilist |  11 ++
 6 files changed, 205 insertions(+)
 create mode 100644 sysdeps/riscv/rvd/test-float-libmvec-logf.c
 create mode 100644 sysdeps/riscv/rvd/v_f_logf.c
 create mode 100644 sysdeps/riscv/rvd/v_f_logf_skeleton.c

diff --git a/sysdeps/riscv/rvd/Makeconfig b/sysdeps/riscv/rvd/Makeconfig
index 3c1fac4316..aaaa5f2f43 100644
--- a/sysdeps/riscv/rvd/Makeconfig
+++ b/sysdeps/riscv/rvd/Makeconfig
@@ -21,6 +21,7 @@
 postclean-generated += libmvec.mk
 
 libmvec-float-funcs-bare = \
+	logf       \
 
 libmvec-float-funcs-with-data = \
 
@@ -71,6 +72,7 @@ libmvec-double-bench-funcs = \
   log        \
 
 libmvec-float-bench-funcs = \
+  logf        \
 
 bench-libmvec-double = \
   $(addprefix double-, $(libmvec-double-bench-funcs)) \
diff --git a/sysdeps/riscv/rvd/Versions b/sysdeps/riscv/rvd/Versions
index 9d43e652a9..4edf5350a7 100644
--- a/sysdeps/riscv/rvd/Versions
+++ b/sysdeps/riscv/rvd/Versions
@@ -11,5 +11,16 @@ libmvec {
     _ZGVr8N8v_log;
     _ZGVr8N16v_log;
     _ZGVr8N32v_log;
+    _ZGVr1N4v_logf;
+    _ZGVr1N8v_logf;
+    _ZGVr2N4v_logf;
+    _ZGVr2N8v_logf;
+    _ZGVr2N16v_logf;
+    _ZGVr4N8v_logf;
+    _ZGVr4N16v_logf;
+    _ZGVr4N32v_logf;
+    _ZGVr8N16v_logf;
+    _ZGVr8N32v_logf;
+    _ZGVr8N64v_logf;
   }
 }
diff --git a/sysdeps/riscv/rvd/test-float-libmvec-logf.c b/sysdeps/riscv/rvd/test-float-libmvec-logf.c
new file mode 100644
index 0000000000..a0b5bf2eb1
--- /dev/null
+++ b/sysdeps/riscv/rvd/test-float-libmvec-logf.c
@@ -0,0 +1,21 @@
+/* Vector ABI test for RISC-V libmvec logf.
+   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/>.  */
+
+#define LIBMVEC_TYPE float
+#define LIBMVEC_FUNC logf
+#include "test-vector-abi-arg1.h"
diff --git a/sysdeps/riscv/rvd/v_f_logf.c b/sysdeps/riscv/rvd/v_f_logf.c
new file mode 100644
index 0000000000..39a1135e8d
--- /dev/null
+++ b/sysdeps/riscv/rvd/v_f_logf.c
@@ -0,0 +1,22 @@
+/* Single-precision vector log function.
+   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/>.  */
+
+#define LIBMVEC_TYPE float
+#define LIBMVEC_FUNC logf
+#define LIBMVEC_IMPL "v_f_logf_skeleton.c"
+#include "v_math_importer.h"
diff --git a/sysdeps/riscv/rvd/v_f_logf_skeleton.c b/sysdeps/riscv/rvd/v_f_logf_skeleton.c
new file mode 100644
index 0000000000..8540e146fa
--- /dev/null
+++ b/sysdeps/riscv/rvd/v_f_logf_skeleton.c
@@ -0,0 +1,138 @@
+/* Single-precision vector log function.
+   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/>.  */
+
+#include <vecmath_config.h>
+#include <v_math.h>
+
+#ifndef RVV_LIBMVEC_IMPL_NAME
+# error "RVV_LIBMVEC_IMPL_NAME must be defined for RVV libmvec skeleton"
+#endif
+#ifndef V_MATH_FUNC
+# error "V_MATH_FUNC must be defined for RVV libmvec skeleton"
+#endif
+
+#ifndef V_F_LOGF_VFREC7_OPT_SKELETON_ONCE
+#define V_F_LOGF_VFREC7_OPT_SKELETON_ONCE
+
+#define LOGF_LN2_HI_OPT 0.69314718246459960938f
+#define LOGF_LN2_LO_OPT -1.904654323148236017e-09f
+
+#define LOGF_C0_OPT 0.3027294874e+0f
+#define LOGF_C1_OPT 0.3996108174e+0f
+#define LOGF_C2_OPT 0.6666694880e+0f
+
+#endif
+
+static VFLOAT
+RVV_LIBMVEC_IMPL_NAME (V_MATH_FUNC, LMUL) (VFLOAT x, size_t vlen)
+{
+  VFLOAT vx, vy, vy_special;
+  VBOOL special_args;
+  VINT n_adjust;
+
+  SET_ROUNDTONEAREST;
+  vx = x;
+
+  /* Handle special cases */
+  VUINT vclass = __riscv_vfclass(vx, vlen);
+  IDENTIFY(vclass, 0x3BF, special_args, vlen);
+  UINT nb_special_args = __riscv_vcpop(special_args, vlen);
+  n_adjust = VMVI_VX(0, vlen);
+  vy_special = VFMV_VF(0.0f, vlen);
+
+  if (nb_special_args > 0)
+  {
+    VBOOL id_mask;
+    IDENTIFY(vclass, class_negative, id_mask, vlen);
+    vx = VFMERGE_VFM(vx, fp_sNaN, id_mask, vlen);
+    IDENTIFY(vclass, class_posZero, id_mask, vlen);
+    vx = VFMERGE_VFM(vx, fp_negZero, id_mask, vlen);
+    IDENTIFY(vclass, 0x39F, special_args, vlen);
+    vy_special = VFREC7_M(special_args, vx, vlen);
+    vy_special = VFADD_VV_M(special_args, vy_special, vx, vlen);
+    vx = VFMERGE_VFM(vx, fp_posOne, special_args, vlen);
+    IDENTIFY(vclass, class_posDenorm, id_mask, vlen);
+    n_adjust = VMERGE_VXM_I(n_adjust, 64, id_mask, vlen);
+    VFLOAT vx_normalized = VFMUL_VF_M(id_mask, vx, 0x1.0p64f, vlen);
+    vx = VMERGE_VVM_F(vx, vx_normalized, id_mask, vlen);
+  }
+
+  /* Range reduction: multiply by 4/3 */
+  VFLOAT vx_adj = __riscv_vfmul(vx, 0x1.555556p0f, vlen);
+  VUINT ix_adj = F_AS_U(vx_adj);
+  
+  /* Extract exponent e - keep as integer, don't convert to float yet! */
+  VINT e = U_AS_I(__riscv_vsrl(ix_adj, MAN_LEN, vlen));
+  e = __riscv_vand(e, 0xff, vlen);
+  e = __riscv_vsub(e, EXP_BIAS, vlen);
+  
+  /* Compute m = vx * 2^(-e) */
+  VINT neg_e = __riscv_vneg(e, vlen);
+  VFLOAT m = I_AS_F(__riscv_vadd(F_AS_I(vx), __riscv_vsll(neg_e, MAN_LEN, vlen), vlen));
+  e = __riscv_vsub(e, n_adjust, vlen);
+
+  /* Float-float division: x = (m-1)/(m+1) as (x_hi, x_lo) */
+  VFLOAT num = __riscv_vfsub(m, 1.0f, vlen);
+  VFLOAT den = __riscv_vfadd(m, 1.0f, vlen);
+
+  VFLOAT r = __riscv_vfrec7(den, vlen);
+  VFLOAT two = VFMV_VF(2.0f, vlen);
+  r = __riscv_vfmul(__riscv_vfnmsac(two, den, r, vlen), r, vlen);
+  two = VFMV_VF(2.0f, vlen);
+  r = __riscv_vfmul(__riscv_vfnmsac(two, den, r, vlen), r, vlen);
+  
+  VFLOAT x_hi = __riscv_vfmul(num, r, vlen);
+  VFLOAT residual = __riscv_vfnmsac(num, x_hi, den, vlen);
+  VFLOAT x_lo = __riscv_vfmul(residual, r, vlen);
+
+  /* x2 = x_hi*x_hi
+     poly = C2 + x2*(C1 + x2*C0)
+     poly_tail = x2 * x_hi * poly
+  */
+  VFLOAT x2 = __riscv_vfmul(x_hi, x_hi, vlen);
+  
+  VFLOAT poly = VFMV_VF(LOGF_C0_OPT, vlen);
+  poly = __riscv_vfmacc(VFMV_VF(LOGF_C1_OPT, vlen), poly, x2, vlen);
+  poly = __riscv_vfmacc(VFMV_VF(LOGF_C2_OPT, vlen), poly, x2, vlen);
+  
+  VFLOAT poly_tail = __riscv_vfmul(__riscv_vfmul(x2, x_hi, vlen), poly, vlen);
+
+  VFLOAT ef = __riscv_vfcvt_f(e, vlen);
+
+  VFLOAT s_hi = __riscv_vfmul(ef, LOGF_LN2_HI_OPT, vlen);
+  VFLOAT s_lo = __riscv_vfmul(ef, LOGF_LN2_LO_OPT, vlen);
+
+  /* Compact dfadd: s + 2*x + poly_tail
+     sum_hi = s_hi + 2*x_hi
+     sum_lo = (s_hi - sum_hi) + 2*x_hi + s_lo + 2*x_lo + poly_tail
+  */
+  VFLOAT sum_hi = __riscv_vfadd(s_hi, __riscv_vfadd(x_hi, x_hi, vlen), vlen);
+  VFLOAT err = __riscv_vfsub(s_hi, sum_hi, vlen);
+  VFLOAT sum_lo = __riscv_vfadd(err, __riscv_vfadd(x_hi, x_hi, vlen), vlen);
+  sum_lo = __riscv_vfadd(sum_lo, s_lo, vlen);
+  sum_lo = __riscv_vfadd(sum_lo, __riscv_vfadd(x_lo, x_lo, vlen), vlen);
+  sum_lo = __riscv_vfadd(sum_lo, poly_tail, vlen);
+  vy = __riscv_vfadd(sum_hi, sum_lo, vlen);
+
+  vy = VMERGE_VVM_F(vy, vy_special, special_args, vlen);
+
+  RESTORE_FRM;
+  return vy;
+}
+
+#undef LMUL
diff --git a/sysdeps/unix/sysv/linux/riscv/libmvec.abilist b/sysdeps/unix/sysv/linux/riscv/libmvec.abilist
index 2592c2dc6f..4daf4f2495 100644
--- a/sysdeps/unix/sysv/linux/riscv/libmvec.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/libmvec.abilist
@@ -9,3 +9,14 @@ GLIBC_2.43 _ZGVr4N16v_log F
 GLIBC_2.43 _ZGVr8N8v_log F
 GLIBC_2.43 _ZGVr8N16v_log F
 GLIBC_2.43 _ZGVr8N32v_log F
+GLIBC_2.43 _ZGVr1N4v_logf F
+GLIBC_2.43 _ZGVr1N8v_logf F
+GLIBC_2.43 _ZGVr2N4v_logf F
+GLIBC_2.43 _ZGVr2N8v_logf F
+GLIBC_2.43 _ZGVr2N16v_logf F
+GLIBC_2.43 _ZGVr4N8v_logf F
+GLIBC_2.43 _ZGVr4N16v_logf F
+GLIBC_2.43 _ZGVr4N32v_logf F
+GLIBC_2.43 _ZGVr8N16v_logf F
+GLIBC_2.43 _ZGVr8N32v_logf F
+GLIBC_2.43 _ZGVr8N64v_logf F
-- 
2.47.3



More information about the Libc-alpha mailing list