[PATCH] arm: Add ARM VFPv4 VFMA instruction support in fma/fmaf (BZ 15503)

Adhemerval Zanella adhemerval.zanella@linaro.org
Tue Sep 23 19:47:10 GMT 2025


It is enabled through math-use-builtins-fma.h if  glibc is built
for VPFv4 (__ARM_FEATURE_FMA predefined by GCC), or through IFUNC
(testing HWCAP_ARM_VFPv4) otherwise.

Checked on arm-linux-gnueabihf.
---
 sysdeps/arm/arm-ifunc.h                       |  3 +++
 sysdeps/arm/armv7/fpu/multiarch/Makefile      | 11 +++++++++++
 .../arm/armv7/fpu/multiarch/s_fma-generic.c   |  5 +++++
 sysdeps/arm/armv7/fpu/multiarch/s_fma-vpfv4.c |  5 +++++
 sysdeps/arm/armv7/fpu/multiarch/s_fma.c       | 19 +++++++++++++++++++
 .../arm/armv7/fpu/multiarch/s_fmaf-generic.c  |  5 +++++
 .../arm/armv7/fpu/multiarch/s_fmaf-vpfv4.c    |  5 +++++
 sysdeps/arm/armv7/fpu/multiarch/s_fmaf.c      | 12 ++++++++++++
 sysdeps/arm/be/armv7/fpu/multiarch/Implies    |  1 +
 sysdeps/arm/fpu/math-use-builtins-fma.h       | 11 +++++++++++
 sysdeps/arm/le/armv7/fpu/multiarch/Implies    |  1 +
 11 files changed, 78 insertions(+)
 create mode 100644 sysdeps/arm/armv7/fpu/multiarch/Makefile
 create mode 100644 sysdeps/arm/armv7/fpu/multiarch/s_fma-generic.c
 create mode 100644 sysdeps/arm/armv7/fpu/multiarch/s_fma-vpfv4.c
 create mode 100644 sysdeps/arm/armv7/fpu/multiarch/s_fma.c
 create mode 100644 sysdeps/arm/armv7/fpu/multiarch/s_fmaf-generic.c
 create mode 100644 sysdeps/arm/armv7/fpu/multiarch/s_fmaf-vpfv4.c
 create mode 100644 sysdeps/arm/armv7/fpu/multiarch/s_fmaf.c
 create mode 100644 sysdeps/arm/be/armv7/fpu/multiarch/Implies
 create mode 100644 sysdeps/arm/fpu/math-use-builtins-fma.h
 create mode 100644 sysdeps/arm/le/armv7/fpu/multiarch/Implies

diff --git a/sysdeps/arm/arm-ifunc.h b/sysdeps/arm/arm-ifunc.h
index 3986b35894..a7836e5316 100644
--- a/sysdeps/arm/arm-ifunc.h
+++ b/sysdeps/arm/arm-ifunc.h
@@ -24,6 +24,9 @@
 #define arm_libc_ifunc_redirected(redirected_name, name, expr)	\
   __ifunc (redirected_name, name, expr(hwcap), int hwcap, INIT_ARCH)
 
+#define arm_libm_ifunc(name, expr)				\
+  __ifunc (name, name, expr, int hwcap, libm_ifunc_init)
+
 #if defined SHARED
 # define arm_libc_ifunc_hidden_def(redirect_name, name) \
   __hidden_ver1 (name, __GI_##name, redirect_name) \
diff --git a/sysdeps/arm/armv7/fpu/multiarch/Makefile b/sysdeps/arm/armv7/fpu/multiarch/Makefile
new file mode 100644
index 0000000000..71749eced7
--- /dev/null
+++ b/sysdeps/arm/armv7/fpu/multiarch/Makefile
@@ -0,0 +1,11 @@
+ifeq ($(subdir),math)
+libm-sysdep_routines += \
+  s_fma-generic \
+  s_fma-vpfv4 \
+  s_fmaf-generic \
+  s_fmaf-vpfv4 \
+# libm-sysdep_routinesA
+
+CFLAGS-s_fma-vpfv4.c = -mfpu=vfpv4
+CFLAGS-s_fmaf-vpfv4.c = -mfpu=vfpv4
+endif
diff --git a/sysdeps/arm/armv7/fpu/multiarch/s_fma-generic.c b/sysdeps/arm/armv7/fpu/multiarch/s_fma-generic.c
new file mode 100644
index 0000000000..56b9969269
--- /dev/null
+++ b/sysdeps/arm/armv7/fpu/multiarch/s_fma-generic.c
@@ -0,0 +1,5 @@
+#include <libm-alias-double.h>
+#define __fma __fma_generic
+#undef libm_alias_double
+#define libm_alias_double(a, b)
+#include <sysdeps/ieee754/dbl-64/s_fma.c>
diff --git a/sysdeps/arm/armv7/fpu/multiarch/s_fma-vpfv4.c b/sysdeps/arm/armv7/fpu/multiarch/s_fma-vpfv4.c
new file mode 100644
index 0000000000..1ea835dfc9
--- /dev/null
+++ b/sysdeps/arm/armv7/fpu/multiarch/s_fma-vpfv4.c
@@ -0,0 +1,5 @@
+#include <libm-alias-double.h>
+#define __fma __fma_vpfv4
+#undef libm_alias_double
+#define libm_alias_double(a, b)
+#include <sysdeps/ieee754/dbl-64/s_fma.c>
diff --git a/sysdeps/arm/armv7/fpu/multiarch/s_fma.c b/sysdeps/arm/armv7/fpu/multiarch/s_fma.c
new file mode 100644
index 0000000000..e4682c53cc
--- /dev/null
+++ b/sysdeps/arm/armv7/fpu/multiarch/s_fma.c
@@ -0,0 +1,19 @@
+#define NO_MATH_REDIRECT
+#include <arm-ifunc.h>
+#define dfmal __hide_dfmal
+#define f32xfmaf64 __hide_f32xfmaf64
+#include <math.h>
+#undef dfmal
+#undef f32xfmaf64
+#undef fma
+#include <libm-alias-double.h>
+#include <math-narrow-alias.h>
+
+extern __typeof (fma) __fma_vpfv4 attribute_hidden;
+extern __typeof (fma) __fma_generic attribute_hidden;
+
+arm_libm_ifunc (__fma, hwcap & HWCAP_ARM_VFPv4
+		       ? __fma_vpfv4
+		       : __fma_generic);
+libm_alias_double (__fma, fma)
+libm_alias_double_narrow (__fma, fma)
diff --git a/sysdeps/arm/armv7/fpu/multiarch/s_fmaf-generic.c b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf-generic.c
new file mode 100644
index 0000000000..96d22a1e4a
--- /dev/null
+++ b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf-generic.c
@@ -0,0 +1,5 @@
+#include <libm-alias-float.h>
+#define __fmaf __fmaf_generic
+#undef libm_alias_float
+#define libm_alias_float(a, b)
+#include <sysdeps/ieee754/dbl-64/s_fmaf.c>
diff --git a/sysdeps/arm/armv7/fpu/multiarch/s_fmaf-vpfv4.c b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf-vpfv4.c
new file mode 100644
index 0000000000..264c257f76
--- /dev/null
+++ b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf-vpfv4.c
@@ -0,0 +1,5 @@
+#include <libm-alias-float.h>
+#define __fmaf __fmaf_vpfv4
+#undef libm_alias_float
+#define libm_alias_float(a, b)
+#include <sysdeps/ieee754/dbl-64/s_fmaf.c>
diff --git a/sysdeps/arm/armv7/fpu/multiarch/s_fmaf.c b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf.c
new file mode 100644
index 0000000000..9cb041b439
--- /dev/null
+++ b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf.c
@@ -0,0 +1,12 @@
+#define NO_MATH_REDIRECT
+#include <arm-ifunc.h>
+#include <math.h>
+#include <libm-alias-float.h>
+
+extern __typeof (fmaf) __fmaf_vpfv4 attribute_hidden;
+extern __typeof (fmaf) __fmaf_generic attribute_hidden;
+
+arm_libm_ifunc (__fmaf, hwcap & HWCAP_ARM_VFPv4
+			? __fmaf_vpfv4
+			: __fmaf_generic)
+libm_alias_float (__fma, fma)
diff --git a/sysdeps/arm/be/armv7/fpu/multiarch/Implies b/sysdeps/arm/be/armv7/fpu/multiarch/Implies
new file mode 100644
index 0000000000..5d8bf8d938
--- /dev/null
+++ b/sysdeps/arm/be/armv7/fpu/multiarch/Implies
@@ -0,0 +1 @@
+arm/armv7/fpu/multiarch
diff --git a/sysdeps/arm/fpu/math-use-builtins-fma.h b/sysdeps/arm/fpu/math-use-builtins-fma.h
new file mode 100644
index 0000000000..fed148bb41
--- /dev/null
+++ b/sysdeps/arm/fpu/math-use-builtins-fma.h
@@ -0,0 +1,11 @@
+#if defined __ARM_FEATURE_FMA && __ARM_FP & 0x4
+# define USE_FMA_BUILTIN 1
+#endif
+#if defined __ARM_FEATURE_FMA && __ARM_FP & 0x2
+# define USE_FMAF_BUILTIN 1
+#else
+# define USE_FMA_BUILTIN 0
+# define USE_FMAF_BUILTIN 0
+#endif
+#define USE_FMAL_BUILTIN 0
+#define USE_FMAF128_BUILTIN 0
diff --git a/sysdeps/arm/le/armv7/fpu/multiarch/Implies b/sysdeps/arm/le/armv7/fpu/multiarch/Implies
new file mode 100644
index 0000000000..5d8bf8d938
--- /dev/null
+++ b/sysdeps/arm/le/armv7/fpu/multiarch/Implies
@@ -0,0 +1 @@
+arm/armv7/fpu/multiarch
-- 
2.43.0



More information about the Libc-alpha mailing list