about summary refs log tree commit diff
path: root/sysdeps/x86/cpu-features.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-08-27 09:06:26 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-08-27 09:06:44 -0700
commit75dd0a8f3db2813196db08928b1b6bb200230695 (patch)
treea7e7c109a7929ab4f48d593c6ed88a71ed89e111 /sysdeps/x86/cpu-features.h
parentd226114b9bfce2ea729f9c7b736aa5d509b2a73c (diff)
downloadglibc-75dd0a8f3db2813196db08928b1b6bb200230695.tar.gz
glibc-75dd0a8f3db2813196db08928b1b6bb200230695.tar.xz
glibc-75dd0a8f3db2813196db08928b1b6bb200230695.zip
Detect and select i586/i686 implementation at run-time fedora/master
We detect i586 and i686 features at run-time by checking CX8 and CMOV
CPUID features bits.  We can use these information to select the best
implementation in ix86 multiarch.  HAS_I586/HAS_I686 is true if i586/i686
instructions are available on the processor.

Due to the reordering and the other nifty extensions in i686, it is not
really good to use heavily i586 optimized code on an i686.  It's better
to use i486 code if it isn't an i586.  USE_I586/USE_I686 is true if
i586/i686 implementation should be used for the processor.  USE_I586
is true only if i686 instructions aren't available.  If i686 instructions
are available, we always choose i686 or i486 implementation, in that order,
and we never choose i586 implementation for i686-class processors.

	* sysdeps/i386/init-arch.h: New file.
	* sysdeps/i386/i586/init-arch.h: Likewise.
	* sysdeps/i386/i686/init-arch.h: Likewise.
	* sysdeps/x86/cpu-features.c (init_cpu_features): Set bit_I586
	bit if CX8 is available.  Set bit_I686 bit if CMOV is available.
	* sysdeps/x86/cpu-features.h (bit_I586): New.
	(bit_I686): Likewise.
	(bit_CX8): Likewise.
	(bit_CMOV): Likewise.
	(index_CX8): Likewise.
	(index_CMOV): Likewise.
	(index_I586): Likewise.
	(index_I686): Likewise.
	(reg_CX8): Likewise.
	(reg_CMOV): Likewise.
	(HAS_I586): Defined as HAS_ARCH_FEATURE (I586) if i586 isn't
	available at compile-time.
	(HAS_I686): Defined as HAS_ARCH_FEATURE (I686) if i686 isn't
	available at compile-time.
	* sysdeps/x86/init-arch.h (USE_I586): New macro.
	(USE_I686): Likewise.
Diffstat (limited to 'sysdeps/x86/cpu-features.h')
-rw-r--r--sysdeps/x86/cpu-features.h20
1 files changed, 17 insertions, 3 deletions
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 6e706241ad..80edbee75c 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -31,10 +31,14 @@
 #define bit_AVX_Fast_Unaligned_Load	(1 << 11)
 #define bit_AVX512F_Usable		(1 << 12)
 #define bit_AVX512DQ_Usable		(1 << 13)
+#define bit_I586			(1 << 14)
+#define bit_I686			(1 << 15)
 
 /* CPUID Feature flags.  */
 
 /* COMMON_CPUID_INDEX_1.  */
+#define bit_CX8		(1 << 8)
+#define bit_CMOV	(1 << 15)
 #define bit_SSE2	(1 << 26)
 #define bit_SSSE3	(1 << 9)
 #define bit_SSE4_1	(1 << 19)
@@ -69,6 +73,8 @@
 # include <ifunc-defines.h>
 # include <rtld-global-offsets.h>
 
+# define index_CX8	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
+# define index_CMOV	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
 # define index_SSE2	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
 # define index_SSSE3	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET
 # define index_SSE4_1	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET
@@ -89,6 +95,8 @@
 # define index_AVX_Fast_Unaligned_Load	FEATURE_INDEX_1*FEATURE_SIZE
 # define index_AVX512F_Usable		FEATURE_INDEX_1*FEATURE_SIZE
 # define index_AVX512DQ_Usable		FEATURE_INDEX_1*FEATURE_SIZE
+# define index_I586			FEATURE_INDEX_1*FEATURE_SIZE
+# define index_I686			FEATURE_INDEX_1*FEATURE_SIZE
 
 # if defined (_LIBC) && !IS_IN (nonlib)
 #  ifdef __x86_64__
@@ -193,6 +201,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define HAS_ARCH_FEATURE(name) \
   ((__get_cpu_features ()->feature[index_##name] & (bit_##name)) != 0)
 
+# define index_CX8		COMMON_CPUID_INDEX_1
+# define index_CMOV		COMMON_CPUID_INDEX_1
 # define index_SSE2		COMMON_CPUID_INDEX_1
 # define index_SSSE3		COMMON_CPUID_INDEX_1
 # define index_SSE4_1		COMMON_CPUID_INDEX_1
@@ -207,6 +217,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define index_POPCOUNT		COMMON_CPUID_INDEX_1
 # define index_OSXSAVE		COMMON_CPUID_INDEX_1
 
+# define reg_CX8		edx
+# define reg_CMOV		edx
 # define reg_SSE2		edx
 # define reg_SSSE3		ecx
 # define reg_SSE4_1		ecx
@@ -234,6 +246,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define index_AVX_Fast_Unaligned_Load	FEATURE_INDEX_1
 # define index_AVX512F_Usable		FEATURE_INDEX_1
 # define index_AVX512DQ_Usable		FEATURE_INDEX_1
+# define index_I586			FEATURE_INDEX_1
+# define index_I686			FEATURE_INDEX_1
 
 #endif	/* !__ASSEMBLER__ */
 
@@ -242,7 +256,7 @@ extern const struct cpu_features *__get_cpu_features (void)
 #elif defined __i586__ || defined __pentium__
 # define HAS_CPUID 1
 # define HAS_I586 1
-# define HAS_I686 0
+# define HAS_I686 HAS_ARCH_FEATURE (I686)
 #elif (defined __i686__ || defined __pentiumpro__		\
        || defined __pentium4__ || defined __nocona__		\
        || defined __atom__ || defined __core2__			\
@@ -261,8 +275,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define HAS_I686 1
 #else
 # define HAS_CPUID 0
-# define HAS_I586 0
-# define HAS_I686 0
+# define HAS_I586 HAS_ARCH_FEATURE (I586)
+# define HAS_I686 HAS_ARCH_FEATURE (I686)
 #endif
 
 #endif  /* cpu_features_h */