diff options
Diffstat (limited to 'sysdeps/s390/multiarch/ifunc-resolve.h')
-rw-r--r-- | sysdeps/s390/multiarch/ifunc-resolve.h | 77 |
1 files changed, 35 insertions, 42 deletions
diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h index 26e097ad6e..768829b39b 100644 --- a/sysdeps/s390/multiarch/ifunc-resolve.h +++ b/sysdeps/s390/multiarch/ifunc-resolve.h @@ -40,53 +40,46 @@ ".machine pop" "\n" \ : "=QS" (STFLE_BITS), "+d" (reg0) \ : : "cc"); +#define s390_libc_ifunc_init() \ + unsigned long long stfle_bits = 0ULL; \ + if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE) \ + && (dl_hwcap & HWCAP_S390_ZARCH) \ + && (dl_hwcap & HWCAP_S390_HIGH_GPRS))) \ + { \ + S390_STORE_STFLE (stfle_bits); \ + } -#define s390_libc_ifunc(FUNC) \ - __asm__ (".globl " #FUNC "\n\t" \ - ".type " #FUNC ",@gnu_indirect_function\n\t" \ - ".set " #FUNC ",__resolve_" #FUNC "\n\t"); \ - \ +#define s390_libc_ifunc(TYPE_FUNC, RESOLVERFUNC, FUNC) \ /* Make the declarations of the optimized functions hidden in order to prevent GOT slots being generated for them. */ \ - extern void *__##FUNC##_z196 attribute_hidden; \ - extern void *__##FUNC##_z10 attribute_hidden; \ - extern void *__##FUNC##_default attribute_hidden; \ - \ - void *__resolve_##FUNC (unsigned long int dl_hwcap) \ - { \ - if ((dl_hwcap & HWCAP_S390_STFLE) \ - && (dl_hwcap & HWCAP_S390_ZARCH) \ - && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) \ - { \ - unsigned long long stfle_bits; \ - S390_STORE_STFLE (stfle_bits); \ - \ - if (S390_IS_Z196 (stfle_bits)) \ - return &__##FUNC##_z196; \ - else if (S390_IS_Z10 (stfle_bits)) \ - return &__##FUNC##_z10; \ - else \ - return &__##FUNC##_default; \ - } \ - else \ - return &__##FUNC##_default; \ - } + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z196 attribute_hidden; \ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z10 attribute_hidden; \ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_default attribute_hidden; \ + __ifunc (TYPE_FUNC, FUNC, \ + __glibc_likely (S390_IS_Z196 (stfle_bits)) \ + ? RESOLVERFUNC##_z196 \ + : __glibc_likely (S390_IS_Z10 (stfle_bits)) \ + ? RESOLVERFUNC##_z10 \ + : RESOLVERFUNC##_default, \ + unsigned long int dl_hwcap, s390_libc_ifunc_init); #define s390_vx_libc_ifunc(FUNC) \ - s390_vx_libc_ifunc2(FUNC, FUNC) + s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC) -#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \ +#define s390_vx_libc_ifunc_redirected(TYPE_FUNC, FUNC) \ + s390_vx_libc_ifunc2_redirected(TYPE_FUNC, FUNC, FUNC) + +#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \ + s390_vx_libc_ifunc2_redirected(FUNC, RESOLVERFUNC, FUNC) + +#define s390_vx_libc_ifunc_init() +#define s390_vx_libc_ifunc2_redirected(TYPE_FUNC, RESOLVERFUNC, FUNC) \ /* Make the declarations of the optimized functions hidden in order to prevent GOT slots being generated for them. */ \ - extern __typeof (FUNC) RESOLVERFUNC##_vx attribute_hidden; \ - extern __typeof (FUNC) RESOLVERFUNC##_c attribute_hidden; \ - extern void *__resolve_##RESOLVERFUNC (unsigned long int) __asm__ (#FUNC); \ - \ - void *__resolve_##RESOLVERFUNC (unsigned long int dl_hwcap) \ - { \ - if (dl_hwcap & HWCAP_S390_VX) \ - return &RESOLVERFUNC##_vx; \ - else \ - return &RESOLVERFUNC##_c; \ - } \ - __asm__ (".type " #FUNC ", %gnu_indirect_function"); + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden; \ + extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden; \ + __ifunc (TYPE_FUNC, FUNC, \ + (dl_hwcap & HWCAP_S390_VX) \ + ? RESOLVERFUNC##_vx \ + : RESOLVERFUNC##_c, \ + unsigned long int dl_hwcap, s390_vx_libc_ifunc_init); |