[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