]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
arm: Add ARM VFPv4 VFMA instruction support in fma/fmaf (BZ 15503)
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 23 Sep 2025 19:47:10 +0000 (19:47 +0000)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 3 Oct 2025 18:19:54 +0000 (15:19 -0300)
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.

Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
sysdeps/arm/arm-ifunc.h
sysdeps/arm/armv7/fpu/multiarch/Makefile [new file with mode: 0644]
sysdeps/arm/armv7/fpu/multiarch/s_fma-generic.c [new file with mode: 0644]
sysdeps/arm/armv7/fpu/multiarch/s_fma-vpfv4.c [new file with mode: 0644]
sysdeps/arm/armv7/fpu/multiarch/s_fma.c [new file with mode: 0644]
sysdeps/arm/armv7/fpu/multiarch/s_fmaf-generic.c [new file with mode: 0644]
sysdeps/arm/armv7/fpu/multiarch/s_fmaf-vpfv4.c [new file with mode: 0644]
sysdeps/arm/armv7/fpu/multiarch/s_fmaf.c [new file with mode: 0644]
sysdeps/arm/be/armv7/fpu/multiarch/Implies [new file with mode: 0644]
sysdeps/arm/fpu/math-use-builtins-fma.h [new file with mode: 0644]
sysdeps/arm/le/armv7/fpu/multiarch/Implies [new file with mode: 0644]

index 3986b358946b7cd8b4fe6b1aa7ce011ff53bb55b..a7836e5316d2ead3b3d83066a8ffd91def5e1536 100644 (file)
@@ -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 (file)
index 0000000..71749ec
--- /dev/null
@@ -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 (file)
index 0000000..56b9969
--- /dev/null
@@ -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 (file)
index 0000000..1ea835d
--- /dev/null
@@ -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 (file)
index 0000000..e4682c5
--- /dev/null
@@ -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 (file)
index 0000000..96d22a1
--- /dev/null
@@ -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 (file)
index 0000000..264c257
--- /dev/null
@@ -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 (file)
index 0000000..9cb041b
--- /dev/null
@@ -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 (file)
index 0000000..5d8bf8d
--- /dev/null
@@ -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 (file)
index 0000000..fed148b
--- /dev/null
@@ -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 (file)
index 0000000..5d8bf8d
--- /dev/null
@@ -0,0 +1 @@
+arm/armv7/fpu/multiarch