]>
Commit | Line | Data |
---|---|---|
425ce2ed | 1 | /* This file is part of the GNU C Library. |
568035b7 | 2 | Copyright (C) 2008-2013 Free Software Foundation, Inc. |
425ce2ed UD |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Lesser General Public | |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
8 | ||
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Lesser General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 PE |
15 | License along with the GNU C Library; if not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
425ce2ed | 17 | |
ff02d528 L |
18 | #define bit_Fast_Rep_String (1 << 0) |
19 | #define bit_Fast_Copy_Backward (1 << 1) | |
20 | #define bit_Slow_BSF (1 << 2) | |
21 | #define bit_Prefer_SSE_for_memop (1 << 3) | |
0b1cbaae | 22 | #define bit_Fast_Unaligned_Load (1 << 4) |
99710781 | 23 | #define bit_Prefer_PMINUB_for_stringop (1 << 5) |
1a0994f5 | 24 | #define bit_AVX_Usable (1 << 6) |
05699367 L |
25 | #define bit_FMA_Usable (1 << 7) |
26 | #define bit_FMA4_Usable (1 << 8) | |
3af48cbd | 27 | |
1a0994f5 | 28 | /* CPUID Feature flags. */ |
e0016b11 UD |
29 | #define bit_SSE2 (1 << 26) |
30 | #define bit_SSSE3 (1 << 9) | |
31 | #define bit_SSE4_1 (1 << 19) | |
32 | #define bit_SSE4_2 (1 << 20) | |
afc5ed09 | 33 | #define bit_OSXSAVE (1 << 27) |
e0016b11 UD |
34 | #define bit_AVX (1 << 28) |
35 | #define bit_POPCOUNT (1 << 23) | |
36 | #define bit_FMA (1 << 12) | |
37 | #define bit_FMA4 (1 << 16) | |
38 | ||
1a0994f5 CD |
39 | /* XCR0 Feature flags. */ |
40 | #define bit_XMM_state (1 << 1) | |
41 | #define bit_YMM_state (2 << 1) | |
42 | ||
51ddd2c0 L |
43 | #ifdef __ASSEMBLER__ |
44 | ||
bbbdd778 | 45 | # include <ifunc-defines.h> |
51ddd2c0 | 46 | |
bbbdd778 UD |
47 | # define index_SSE2 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET |
48 | # define index_SSSE3 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET | |
49 | # define index_SSE4_1 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET | |
50 | # define index_SSE4_2 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET | |
d9a4d2ab | 51 | # define index_AVX COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET |
51ddd2c0 | 52 | |
6fb8cbcb L |
53 | # define index_Fast_Rep_String FEATURE_INDEX_1*FEATURE_SIZE |
54 | # define index_Fast_Copy_Backward FEATURE_INDEX_1*FEATURE_SIZE | |
e73015f2 | 55 | # define index_Slow_BSF FEATURE_INDEX_1*FEATURE_SIZE |
ff02d528 | 56 | # define index_Prefer_SSE_for_memop FEATURE_INDEX_1*FEATURE_SIZE |
0b1cbaae | 57 | # define index_Fast_Unaligned_Load FEATURE_INDEX_1*FEATURE_SIZE |
99710781 | 58 | # define index_Prefer_PMINUB_for_stringop FEATURE_INDEX_1*FEATURE_SIZE |
1a0994f5 | 59 | # define index_AVX_Usable FEATURE_INDEX_1*FEATURE_SIZE |
05699367 | 60 | # define index_FMA_Usable FEATURE_INDEX_1*FEATURE_SIZE |
1a0994f5 | 61 | # define index_FMA4_Usable FEATURE_INDEX_1*FEATURE_SIZE |
3af48cbd | 62 | |
51ddd2c0 L |
63 | #else /* __ASSEMBLER__ */ |
64 | ||
bbbdd778 | 65 | # include <sys/param.h> |
425ce2ed UD |
66 | |
67 | enum | |
68 | { | |
963cb6fc | 69 | COMMON_CPUID_INDEX_1 = 0, |
ed72b654 | 70 | COMMON_CPUID_INDEX_80000001, /* for AMD */ |
425ce2ed | 71 | /* Keep the following line at the end. */ |
963cb6fc | 72 | COMMON_CPUID_INDEX_MAX |
425ce2ed UD |
73 | }; |
74 | ||
3af48cbd L |
75 | enum |
76 | { | |
77 | FEATURE_INDEX_1 = 0, | |
78 | /* Keep the following line at the end. */ | |
79 | FEATURE_INDEX_MAX | |
80 | }; | |
81 | ||
425ce2ed UD |
82 | extern struct cpu_features |
83 | { | |
22f4f44b | 84 | enum cpu_features_kind |
425ce2ed UD |
85 | { |
86 | arch_kind_unknown = 0, | |
87 | arch_kind_intel, | |
88 | arch_kind_amd, | |
89 | arch_kind_other | |
90 | } kind; | |
91 | int max_cpuid; | |
3ab2d57a | 92 | struct cpuid_registers |
425ce2ed UD |
93 | { |
94 | unsigned int eax; | |
95 | unsigned int ebx; | |
96 | unsigned int ecx; | |
97 | unsigned int edx; | |
963cb6fc | 98 | } cpuid[COMMON_CPUID_INDEX_MAX]; |
01812913 L |
99 | unsigned int family; |
100 | unsigned int model; | |
3af48cbd | 101 | unsigned int feature[FEATURE_INDEX_MAX]; |
425ce2ed UD |
102 | } __cpu_features attribute_hidden; |
103 | ||
104 | ||
105 | extern void __init_cpu_features (void) attribute_hidden; | |
08cf777f | 106 | # define INIT_ARCH() \ |
425ce2ed UD |
107 | do \ |
108 | if (__cpu_features.kind == arch_kind_unknown) \ | |
109 | __init_cpu_features (); \ | |
110 | while (0) | |
111 | ||
9a1d2d45 UD |
112 | /* Used from outside libc.so to get access to the CPU features structure. */ |
113 | extern const struct cpu_features *__get_cpu_features (void) | |
114 | __attribute__ ((const)); | |
115 | ||
bbbdd778 UD |
116 | # ifndef NOT_IN_libc |
117 | # define __get_cpu_features() (&__cpu_features) | |
118 | # endif | |
6f6f1215 | 119 | |
bbbdd778 | 120 | # define HAS_CPU_FEATURE(idx, reg, bit) \ |
e0016b11 | 121 | ((__get_cpu_features ()->cpuid[idx].reg & (bit)) != 0) |
9a1d2d45 | 122 | |
9d6982d5 | 123 | /* Following are the feature tests used throughout libc. */ |
9a1d2d45 | 124 | |
1a0994f5 CD |
125 | /* CPUID_* evaluates to true if the feature flag is enabled. |
126 | We always use &__cpu_features because the HAS_CPUID_* macros | |
127 | are called only within __init_cpu_features, where we can't | |
128 | call __get_cpu_features without infinite recursion. */ | |
129 | # define HAS_CPUID_FLAG(idx, reg, bit) \ | |
130 | (((&__cpu_features)->cpuid[idx].reg & (bit)) != 0) | |
131 | ||
132 | # define CPUID_OSXSAVE \ | |
133 | HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_OSXSAVE) | |
134 | # define CPUID_AVX \ | |
135 | HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_AVX) | |
05699367 L |
136 | # define CPUID_FMA \ |
137 | HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_FMA) | |
1a0994f5 CD |
138 | # define CPUID_FMA4 \ |
139 | HAS_CPUID_FLAG (COMMON_CPUID_INDEX_80000001, ecx, bit_FMA4) | |
140 | ||
141 | /* HAS_* evaluates to true if we may use the feature at runtime. */ | |
e0016b11 UD |
142 | # define HAS_SSE2 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, edx, bit_SSE2) |
143 | # define HAS_POPCOUNT HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_POPCOUNT) | |
144 | # define HAS_SSSE3 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSSE3) | |
145 | # define HAS_SSE4_1 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSE4_1) | |
146 | # define HAS_SSE4_2 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSE4_2) | |
51ddd2c0 | 147 | |
6fb8cbcb L |
148 | # define index_Fast_Rep_String FEATURE_INDEX_1 |
149 | # define index_Fast_Copy_Backward FEATURE_INDEX_1 | |
e73015f2 | 150 | # define index_Slow_BSF FEATURE_INDEX_1 |
ff02d528 | 151 | # define index_Prefer_SSE_for_memop FEATURE_INDEX_1 |
0b1cbaae | 152 | # define index_Fast_Unaligned_Load FEATURE_INDEX_1 |
1a0994f5 | 153 | # define index_AVX_Usable FEATURE_INDEX_1 |
05699367 | 154 | # define index_FMA_Usable FEATURE_INDEX_1 |
1a0994f5 | 155 | # define index_FMA4_Usable FEATURE_INDEX_1 |
6fb8cbcb | 156 | |
08cf777f UD |
157 | # define HAS_ARCH_FEATURE(name) \ |
158 | ((__get_cpu_features ()->feature[index_##name] & (bit_##name)) != 0) | |
6fb8cbcb | 159 | |
1a0994f5 CD |
160 | # define HAS_FAST_REP_STRING HAS_ARCH_FEATURE (Fast_Rep_String) |
161 | # define HAS_FAST_COPY_BACKWARD HAS_ARCH_FEATURE (Fast_Copy_Backward) | |
162 | # define HAS_SLOW_BSF HAS_ARCH_FEATURE (Slow_BSF) | |
163 | # define HAS_PREFER_SSE_FOR_MEMOP HAS_ARCH_FEATURE (Prefer_SSE_for_memop) | |
164 | # define HAS_FAST_UNALIGNED_LOAD HAS_ARCH_FEATURE (Fast_Unaligned_Load) | |
165 | # define HAS_AVX HAS_ARCH_FEATURE (AVX_Usable) | |
05699367 | 166 | # define HAS_FMA HAS_ARCH_FEATURE (FMA_Usable) |
1a0994f5 | 167 | # define HAS_FMA4 HAS_ARCH_FEATURE (FMA4_Usable) |
0b1cbaae | 168 | |
51ddd2c0 | 169 | #endif /* __ASSEMBLER__ */ |