Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/tools/qsimd.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | - | |||||||||||||
2 | - | |||||||||||||
3 | - | |||||||||||||
4 | - | |||||||||||||
5 | static int maxBasicCpuidSupported() | - | ||||||||||||
6 | { | - | ||||||||||||
7 | - | |||||||||||||
8 | qregisterint tmp1; | - | ||||||||||||
9 | int result; | - | ||||||||||||
10 | asm ("xchg " "%%rbx"", %1\n" | - | ||||||||||||
11 | "cpuid\n" | - | ||||||||||||
12 | "xchg " "%%rbx"", %1\n" | - | ||||||||||||
13 | : "=&a" (result), "=&r" (tmp1) | - | ||||||||||||
14 | : "0" (0) | - | ||||||||||||
15 | : "ecx", "edx"); | - | ||||||||||||
16 | return executed 1162 times by 97 tests: result;return result; Executed by:
executed 1162 times by 97 tests: return result; Executed by:
| 1162 | ||||||||||||
17 | } | - | ||||||||||||
18 | - | |||||||||||||
19 | static void cpuidFeatures01(uint &ecx, uint &edx) | - | ||||||||||||
20 | { | - | ||||||||||||
21 | - | |||||||||||||
22 | qregisterint tmp1; | - | ||||||||||||
23 | asm ("xchg " "%%rbx"", %2\n" | - | ||||||||||||
24 | "cpuid\n" | - | ||||||||||||
25 | "xchg " "%%rbx"", %2\n" | - | ||||||||||||
26 | : "=&c" (ecx), "=&d" (edx), "=&r" (tmp1) | - | ||||||||||||
27 | : "a" (1)); | - | ||||||||||||
28 | } executed 1162 times by 97 tests: end of block Executed by:
| 1162 | ||||||||||||
29 | - | |||||||||||||
30 | - | |||||||||||||
31 | - | |||||||||||||
32 | - | |||||||||||||
33 | - | |||||||||||||
34 | static void cpuidFeatures07_00(uint &ebx, uint &ecx) | - | ||||||||||||
35 | { | - | ||||||||||||
36 | - | |||||||||||||
37 | qregisteruint rbx; | - | ||||||||||||
38 | qregisteruint rcx = 0; | - | ||||||||||||
39 | asm ("xchg " "%%rbx"", %0\n" | - | ||||||||||||
40 | "cpuid\n" | - | ||||||||||||
41 | "xchg " "%%rbx"", %0\n" | - | ||||||||||||
42 | : "=&r" (rbx), "+&c" (rcx) | - | ||||||||||||
43 | : "a" (7) | - | ||||||||||||
44 | : "%edx"); | - | ||||||||||||
45 | ebx = rbx; | - | ||||||||||||
46 | ecx = rcx; | - | ||||||||||||
47 | } executed 1162 times by 97 tests: end of block Executed by:
| 1162 | ||||||||||||
48 | - | |||||||||||||
49 | - | |||||||||||||
50 | - | |||||||||||||
51 | - | |||||||||||||
52 | - | |||||||||||||
53 | static void xgetbv(uint in, uint &eax, uint &edx) | - | ||||||||||||
54 | { | - | ||||||||||||
55 | - | |||||||||||||
56 | asm (".byte 0x0F, 0x01, 0xD0" | - | ||||||||||||
57 | : "=a" (eax), "=d" (edx) | - | ||||||||||||
58 | : "c" (in)); | - | ||||||||||||
59 | - | |||||||||||||
60 | - | |||||||||||||
61 | - | |||||||||||||
62 | - | |||||||||||||
63 | - | |||||||||||||
64 | } never executed: end of block | 0 | ||||||||||||
65 | - | |||||||||||||
66 | static quint64 detectProcessorFeatures() | - | ||||||||||||
67 | { | - | ||||||||||||
68 | - | |||||||||||||
69 | enum XCR0Flags { | - | ||||||||||||
70 | X87 = 1 << 0, | - | ||||||||||||
71 | XMM0_15 = 1 << 1, | - | ||||||||||||
72 | YMM0_15Hi128 = 1 << 2, | - | ||||||||||||
73 | BNDRegs = 1 << 3, | - | ||||||||||||
74 | BNDCSR = 1 << 4, | - | ||||||||||||
75 | OpMask = 1 << 5, | - | ||||||||||||
76 | ZMM0_15Hi256 = 1 << 6, | - | ||||||||||||
77 | ZMM16_31 = 1 << 7, | - | ||||||||||||
78 | - | |||||||||||||
79 | SSEState = XMM0_15, | - | ||||||||||||
80 | AVXState = XMM0_15 | YMM0_15Hi128, | - | ||||||||||||
81 | AVX512State = AVXState | OpMask | ZMM0_15Hi256 | ZMM16_31 | - | ||||||||||||
82 | }; | - | ||||||||||||
83 | static const quint64 AllAVX512 = (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512F) | (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512CD) | | - | ||||||||||||
84 | (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512ER) | (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512PF) | | - | ||||||||||||
85 | (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512BW) | (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512DQ) | | - | ||||||||||||
86 | (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512VL) | | - | ||||||||||||
87 | (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512IFMA) | (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512VBMI); | - | ||||||||||||
88 | static const quint64 AllAVX2 = (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX2) | AllAVX512; | - | ||||||||||||
89 | static const quint64 AllAVX = (static_cast<unsigned long long>(1ULL) << CpuFeatureAVX) | AllAVX2; | - | ||||||||||||
90 | - | |||||||||||||
91 | quint64 features = 0; | - | ||||||||||||
92 | int cpuidLevel = maxBasicCpuidSupported(); | - | ||||||||||||
93 | - | |||||||||||||
94 | - | |||||||||||||
95 | - | |||||||||||||
96 | - | |||||||||||||
97 | ((!(cpuidLevel >= 1)) ? qt_assert("cpuidLevel >= 1",__FILE__,326) : qt_noop()); | - | ||||||||||||
98 | - | |||||||||||||
99 | - | |||||||||||||
100 | uint cpuid01ECX = 0, cpuid01EDX = 0; | - | ||||||||||||
101 | cpuidFeatures01(cpuid01ECX, cpuid01EDX); | - | ||||||||||||
102 | - | |||||||||||||
103 | - | |||||||||||||
104 | - | |||||||||||||
105 | features = cpuid01ECX; | - | ||||||||||||
106 | features |= static_cast<unsigned long long>(1ULL) << CpuFeatureSSE2; | - | ||||||||||||
107 | - | |||||||||||||
108 | - | |||||||||||||
109 | uint xgetbvA = 0, xgetbvD = 0; | - | ||||||||||||
110 | if (cpuid01ECX & (1u << 27)
| 0-1162 | ||||||||||||
111 | - | |||||||||||||
112 | xgetbv(0, xgetbvA, xgetbvD); | - | ||||||||||||
113 | } never executed: end of block | 0 | ||||||||||||
114 | - | |||||||||||||
115 | uint cpuid0700EBX = 0; | - | ||||||||||||
116 | uint cpuid0700ECX = 0; | - | ||||||||||||
117 | if (cpuidLevel >= 7
| 0-1162 | ||||||||||||
118 | cpuidFeatures07_00(cpuid0700EBX, cpuid0700ECX); | - | ||||||||||||
119 | - | |||||||||||||
120 | - | |||||||||||||
121 | features |= quint64(cpuid0700EBX) << 32; | - | ||||||||||||
122 | } executed 1162 times by 97 tests: end of block Executed by:
| 1162 | ||||||||||||
123 | - | |||||||||||||
124 | if ((
| 0-1162 | ||||||||||||
125 | - | |||||||||||||
126 | features &= ~AllAVX; | - | ||||||||||||
127 | } executed 1162 times by 97 tests: else if ((end of block Executed by:
| 0-1162 | ||||||||||||
128 | - | |||||||||||||
129 | features &= ~AllAVX512; | - | ||||||||||||
130 | } never executed: else {end of block | 0 | ||||||||||||
131 | - | |||||||||||||
132 | if (cpuid0700ECX & (1u << 1)
| 0 | ||||||||||||
133 | features |= static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512VBMI; never executed: features |= static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512VBMI; | 0 | ||||||||||||
134 | else | - | ||||||||||||
135 | features &= ~(static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512VBMI); never executed: features &= ~(static_cast<unsigned long long>(1ULL) << CpuFeatureAVX512VBMI); | 0 | ||||||||||||
136 | } | - | ||||||||||||
137 | - | |||||||||||||
138 | return executed 1162 times by 97 tests: features;return features; Executed by:
executed 1162 times by 97 tests: return features; Executed by:
| 1162 | ||||||||||||
139 | } | - | ||||||||||||
140 | static const char features_string[] = | - | ||||||||||||
141 | " sse3\0" | - | ||||||||||||
142 | " sse2\0" | - | ||||||||||||
143 | " avx512vbmi\0" | - | ||||||||||||
144 | " ssse3\0" | - | ||||||||||||
145 | " fma\0" | - | ||||||||||||
146 | " cmpxchg16b\0" | - | ||||||||||||
147 | " sse4.1\0" | - | ||||||||||||
148 | " sse4.2\0" | - | ||||||||||||
149 | " movbe\0" | - | ||||||||||||
150 | " popcnt\0" | - | ||||||||||||
151 | " aes\0" | - | ||||||||||||
152 | " avx\0" | - | ||||||||||||
153 | " f16c\0" | - | ||||||||||||
154 | " rdrand\0" | - | ||||||||||||
155 | " bmi\0" | - | ||||||||||||
156 | " hle\0" | - | ||||||||||||
157 | " avx2\0" | - | ||||||||||||
158 | " bmi2\0" | - | ||||||||||||
159 | " rtm\0" | - | ||||||||||||
160 | " avx512f\0" | - | ||||||||||||
161 | " avx512dq\0" | - | ||||||||||||
162 | " rdseed\0" | - | ||||||||||||
163 | " avx512ifma\0" | - | ||||||||||||
164 | " avx512pf\0" | - | ||||||||||||
165 | " avx512er\0" | - | ||||||||||||
166 | " avx512cd\0" | - | ||||||||||||
167 | " sha\0" | - | ||||||||||||
168 | " avx512bw\0" | - | ||||||||||||
169 | " avx512vl\0" | - | ||||||||||||
170 | "\0"; | - | ||||||||||||
171 | - | |||||||||||||
172 | static const quint8 features_indices[] = { | - | ||||||||||||
173 | 0, 6, 12, 5, 5, 5, 5, 5, | - | ||||||||||||
174 | 5, 24, 5, 5, 31, 36, 5, 5, | - | ||||||||||||
175 | 5, 5, 5, 48, 56, 5, 64, 71, | - | ||||||||||||
176 | 5, 79, 5, 5, 84, 89, 95, 5, | - | ||||||||||||
177 | 5, 5, 5, 103, 108, 113, 5, 5, | - | ||||||||||||
178 | 119, 5, 5, 125, 5, 5, 5, 5, | - | ||||||||||||
179 | 130, 139, 149, 5, 5, 157, 5, 5, | - | ||||||||||||
180 | 5, 5, 169, 179, 189, 199, 204, 214 | - | ||||||||||||
181 | }; | - | ||||||||||||
182 | - | |||||||||||||
183 | - | |||||||||||||
184 | - | |||||||||||||
185 | - | |||||||||||||
186 | - | |||||||||||||
187 | - | |||||||||||||
188 | static const int features_count = (sizeof features_indices) / (sizeof features_indices[0]); | - | ||||||||||||
189 | - | |||||||||||||
190 | - | |||||||||||||
191 | static const quint64 minFeature = qCompilerCpuFeatures; | - | ||||||||||||
192 | - | |||||||||||||
193 | - | |||||||||||||
194 | __attribute__((visibility("default"))) QBasicAtomicInteger<quint64> qt_cpu_features[1] = { { 0 } }; | - | ||||||||||||
195 | - | |||||||||||||
196 | - | |||||||||||||
197 | - | |||||||||||||
198 | - | |||||||||||||
199 | void qDetectCpuFeatures() | - | ||||||||||||
200 | { | - | ||||||||||||
201 | quint64 f = detectProcessorFeatures(); | - | ||||||||||||
202 | QByteArray disable = qgetenv("QT_NO_CPU_FEATURE"); | - | ||||||||||||
203 | if (!disable.isEmpty()
| 0-1162 | ||||||||||||
204 | disable.prepend(' '); | - | ||||||||||||
205 | for (int i = 0; i < features_count
| 0 | ||||||||||||
206 | if (disable.contains(features_string + features_indices[i])
| 0 | ||||||||||||
207 | f &= ~(static_cast<unsigned long long>(1ULL) << i); never executed: f &= ~(static_cast<unsigned long long>(1ULL) << i); | 0 | ||||||||||||
208 | } never executed: end of block | 0 | ||||||||||||
209 | } never executed: end of block | 0 | ||||||||||||
210 | - | |||||||||||||
211 | - | |||||||||||||
212 | bool runningOnValgrind = __extension__ ({unsigned int _qzz_res; { volatile unsigned long long int _zzq_args[6]; volatile unsigned long long int _zzq_result; _zzq_args[0] = (unsigned long long int)(VG_USERREQ__RUNNING_ON_VALGRIND); _zzq_args[1] = (unsigned long long int)(0); _zzq_args[2] = (unsigned long long int)(0); _zzq_args[3] = (unsigned long long int)(0); _zzq_args[4] = (unsigned long long int)(0); _zzq_args[5] = (unsigned long long int)(0); __asm__ volatile("rolq $3, %%rdi ; rolq $13, %%rdi\n\t" "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" "xchgq %%rbx,%%rbx" : "=d" (_zzq_result) : "a" (&_zzq_args[0]), "0" (0) : "cc", "memory" ); _qzz_res = _zzq_result; (void)_qzz_res; }; _qzz_res; }); | - | ||||||||||||
213 | - | |||||||||||||
214 | - | |||||||||||||
215 | - | |||||||||||||
216 | if (__builtin_expect(!!(!runningOnValgrind && minFeature != 0 && (f & minFeature) != minFeature), false)
| 0-1162 | ||||||||||||
217 | quint64 missing = minFeature & ~f; | - | ||||||||||||
218 | fprintf(stderr, "Incompatible processor. This Qt build requires the following features:\n "); | - | ||||||||||||
219 | for (int i = 0; i < features_count
| 0 | ||||||||||||
220 | if (missing & (static_cast<unsigned long long>(1ULL) << i)
| 0 | ||||||||||||
221 | fprintf(stderr, "%s", features_string + features_indices[i]); never executed: fprintf(stderr, "%s", features_string + features_indices[i]); | 0 | ||||||||||||
222 | } never executed: end of block | 0 | ||||||||||||
223 | fprintf(stderr, "\n"); | - | ||||||||||||
224 | fflush(stderr); | - | ||||||||||||
225 | QMessageLogger(__FILE__, 732, __PRETTY_FUNCTION__).fatal("Aborted. Incompatible processor: missing feature 0x%llx -%s.", missing, | - | ||||||||||||
226 | features_string + features_indices[qCountTrailingZeroBits(missing)]); | - | ||||||||||||
227 | } never executed: end of block | 0 | ||||||||||||
228 | - | |||||||||||||
229 | qt_cpu_features[0].store(f | quint32(QSimdInitialized)); | - | ||||||||||||
230 | - | |||||||||||||
231 | - | |||||||||||||
232 | - | |||||||||||||
233 | } executed 1162 times by 97 tests: end of block Executed by:
| 1162 | ||||||||||||
234 | - | |||||||||||||
235 | void qDumpCPUFeatures() | - | ||||||||||||
236 | { | - | ||||||||||||
237 | quint64 features = qCpuFeatures() & ~quint64(QSimdInitialized); | - | ||||||||||||
238 | printf("Processor features: "); | - | ||||||||||||
239 | for (int i = 0; i < features_count
| 0 | ||||||||||||
240 | if (features & (static_cast<unsigned long long>(1ULL) << i)
| 0 | ||||||||||||
241 | printf("%s%s", features_string + features_indices[i], never executed: printf("%s%s", features_string + features_indices[i], minFeature & (static_cast<unsigned long long>(1ULL) << i) ? "[required]" : ""); | 0 | ||||||||||||
242 | minFeature & (static_cast<unsigned long long>(1ULL) << i) ? "[required]" : ""); never executed: printf("%s%s", features_string + features_indices[i], minFeature & (static_cast<unsigned long long>(1ULL) << i) ? "[required]" : ""); | 0 | ||||||||||||
243 | } never executed: end of block | 0 | ||||||||||||
244 | puts(""); | - | ||||||||||||
245 | } never executed: end of block | 0 | ||||||||||||
246 | - | |||||||||||||
247 | - | |||||||||||||
Switch to Source code | Preprocessed file |