From: Adhemerval Zanella Date: Tue, 23 Sep 2025 19:47:10 +0000 (+0000) Subject: arm: Add ARM VFPv4 VFMA instruction support in fma/fmaf (BZ 15503) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c8cdb10a1659b64ae04edacf9368dc9778e06a8;p=thirdparty%2Fglibc.git arm: Add ARM VFPv4 VFMA instruction support in fma/fmaf (BZ 15503) 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 --- diff --git a/sysdeps/arm/arm-ifunc.h b/sysdeps/arm/arm-ifunc.h index 3986b358946..a7836e5316d 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 00000000000..71749eced72 --- /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 00000000000..56b9969269c --- /dev/null +++ b/sysdeps/arm/armv7/fpu/multiarch/s_fma-generic.c @@ -0,0 +1,5 @@ +#include +#define __fma __fma_generic +#undef libm_alias_double +#define libm_alias_double(a, b) +#include 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 00000000000..1ea835dfc9c --- /dev/null +++ b/sysdeps/arm/armv7/fpu/multiarch/s_fma-vpfv4.c @@ -0,0 +1,5 @@ +#include +#define __fma __fma_vpfv4 +#undef libm_alias_double +#define libm_alias_double(a, b) +#include 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 00000000000..e4682c53cc5 --- /dev/null +++ b/sysdeps/arm/armv7/fpu/multiarch/s_fma.c @@ -0,0 +1,19 @@ +#define NO_MATH_REDIRECT +#include +#define dfmal __hide_dfmal +#define f32xfmaf64 __hide_f32xfmaf64 +#include +#undef dfmal +#undef f32xfmaf64 +#undef fma +#include +#include + +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 00000000000..96d22a1e4aa --- /dev/null +++ b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf-generic.c @@ -0,0 +1,5 @@ +#include +#define __fmaf __fmaf_generic +#undef libm_alias_float +#define libm_alias_float(a, b) +#include 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 00000000000..264c257f76d --- /dev/null +++ b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf-vpfv4.c @@ -0,0 +1,5 @@ +#include +#define __fmaf __fmaf_vpfv4 +#undef libm_alias_float +#define libm_alias_float(a, b) +#include 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 00000000000..9cb041b439f --- /dev/null +++ b/sysdeps/arm/armv7/fpu/multiarch/s_fmaf.c @@ -0,0 +1,12 @@ +#define NO_MATH_REDIRECT +#include +#include +#include + +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 00000000000..5d8bf8d9388 --- /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 00000000000..fed148bb413 --- /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 00000000000..5d8bf8d9388 --- /dev/null +++ b/sysdeps/arm/le/armv7/fpu/multiarch/Implies @@ -0,0 +1 @@ +arm/armv7/fpu/multiarch