diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-01-12 14:41:10 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-01-21 10:22:26 -0800 |
commit | 7a5ab88e218d2091e876a9779a4acae426afb85c (patch) | |
tree | cdecfb845b1d9e4aacc7b302ed341c0d42085c7e /sysdeps/x86/tst-ifunc-isa.h | |
parent | 46c1c765d14c77c6c36df1b51dae6674a4eef06b (diff) | |
download | glibc-7a5ab88e218d2091e876a9779a4acae426afb85c.tar.gz glibc-7a5ab88e218d2091e876a9779a4acae426afb85c.tar.xz glibc-7a5ab88e218d2091e876a9779a4acae426afb85c.zip |
x86: Check ifunc resolver with CPU_FEATURE_USABLE [BZ #27072]
Check ifunc resolver with CPU_FEATURE_USABLE and tunables in dynamic and static executables to verify that CPUID features are initialized early in static PIE. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'sysdeps/x86/tst-ifunc-isa.h')
-rw-r--r-- | sysdeps/x86/tst-ifunc-isa.h | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/sysdeps/x86/tst-ifunc-isa.h b/sysdeps/x86/tst-ifunc-isa.h new file mode 100644 index 0000000000..60aa1cea6a --- /dev/null +++ b/sysdeps/x86/tst-ifunc-isa.h @@ -0,0 +1,104 @@ +/* IFUNC resolver with CPU_FEATURE_USABLE. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <sys/platform/x86.h> + +enum isa +{ + none, + sse2, + sse4_2, + avx, + avx2, + avx512f +}; + +enum isa +get_isa (void) +{ + if (CPU_FEATURE_USABLE (AVX512F)) + return avx512f; + if (CPU_FEATURE_USABLE (AVX2)) + return avx2; + if (CPU_FEATURE_USABLE (AVX)) + return avx; + if (CPU_FEATURE_USABLE (SSE4_2)) + return sse4_2; + if (CPU_FEATURE_USABLE (SSE2)) + return sse2; + return none; +} + +static int +isa_sse2 (void) +{ + return sse2; +} + +static int +isa_sse4_2 (void) +{ + return sse4_2; +} + +static int +isa_avx (void) +{ + return avx; +} + +static int +isa_avx2 (void) +{ + return avx2; +} + +static int +isa_avx512f (void) +{ + return avx512f; +} + +static int +isa_none (void) +{ + return none; +} + +int foo (void) __attribute__ ((ifunc ("foo_ifunc"))); + +void * +foo_ifunc (void) +{ + switch (get_isa ()) + { + case avx512f: + return isa_avx512f; + case avx2: + return isa_avx2; + case avx: + return isa_avx; + case sse4_2: + return isa_sse4_2; + case sse2: + return isa_sse2; + default: + break; + } + return isa_none; +} |