File: | lib/Support/Host.cpp |
Location: | line 880, column 18 |
Description: | The left operand of '==' is a garbage value |
1 | //===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // This file implements the operating system Host concept. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "llvm/Support/Host.h" | |||
15 | #include "llvm/ADT/SmallVector.h" | |||
16 | #include "llvm/ADT/StringRef.h" | |||
17 | #include "llvm/ADT/StringSwitch.h" | |||
18 | #include "llvm/ADT/Triple.h" | |||
19 | #include "llvm/Config/config.h" | |||
20 | #include "llvm/Support/Debug.h" | |||
21 | #include "llvm/Support/FileSystem.h" | |||
22 | #include "llvm/Support/raw_ostream.h" | |||
23 | #include <string.h> | |||
24 | #include <assert.h> | |||
25 | ||||
26 | // Include the platform-specific parts of this class. | |||
27 | #ifdef LLVM_ON_UNIX1 | |||
28 | #include "Unix/Host.inc" | |||
29 | #endif | |||
30 | #ifdef LLVM_ON_WIN32 | |||
31 | #include "Windows/Host.inc" | |||
32 | #endif | |||
33 | #ifdef _MSC_VER | |||
34 | #include <intrin.h> | |||
35 | #endif | |||
36 | #if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) | |||
37 | #include <mach/host_info.h> | |||
38 | #include <mach/mach.h> | |||
39 | #include <mach/mach_host.h> | |||
40 | #include <mach/machine.h> | |||
41 | #endif | |||
42 | ||||
43 | #define DEBUG_TYPE"host-detection" "host-detection" | |||
44 | ||||
45 | //===----------------------------------------------------------------------===// | |||
46 | // | |||
47 | // Implementations of the CPU detection routines | |||
48 | // | |||
49 | //===----------------------------------------------------------------------===// | |||
50 | ||||
51 | using namespace llvm; | |||
52 | ||||
53 | #if defined(__linux__1) | |||
54 | static ssize_t LLVM_ATTRIBUTE_UNUSED__attribute__((__unused__)) readCpuInfo(void *Buf, size_t Size) { | |||
55 | // Note: We cannot mmap /proc/cpuinfo here and then process the resulting | |||
56 | // memory buffer because the 'file' has 0 size (it can be read from only | |||
57 | // as a stream). | |||
58 | ||||
59 | int FD; | |||
60 | std::error_code EC = sys::fs::openFileForRead("/proc/cpuinfo", FD); | |||
61 | if (EC) { | |||
62 | DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << EC.message() << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("host-detection")) { dbgs() << "Unable to open /proc/cpuinfo: " << EC.message() << "\n"; } } while (false); | |||
63 | return -1; | |||
64 | } | |||
65 | int Ret = read(FD, Buf, Size); | |||
66 | int CloseStatus = close(FD); | |||
67 | if (CloseStatus) | |||
68 | return -1; | |||
69 | return Ret; | |||
70 | } | |||
71 | #endif | |||
72 | ||||
73 | #if defined(__i386__) || defined(_M_IX86) || \ | |||
74 | defined(__x86_64__1) || defined(_M_X64) | |||
75 | ||||
76 | #if defined(__GNUC__4) || defined(__clang__1) | |||
77 | #include <cpuid.h> | |||
78 | #endif | |||
79 | ||||
80 | enum VendorSignatures { | |||
81 | SIG_INTEL = 0x756e6547 /* Genu */, | |||
82 | SIG_AMD = 0x68747541 /* Auth */ | |||
83 | }; | |||
84 | ||||
85 | enum ProcessorVendors { | |||
86 | VENDOR_INTEL = 1, | |||
87 | VENDOR_AMD, | |||
88 | VENDOR_OTHER, | |||
89 | VENDOR_MAX | |||
90 | }; | |||
91 | ||||
92 | enum ProcessorTypes { | |||
93 | INTEL_ATOM = 1, | |||
94 | INTEL_CORE2, | |||
95 | INTEL_COREI7, | |||
96 | AMDFAM10H, | |||
97 | AMDFAM15H, | |||
98 | INTEL_i386, | |||
99 | INTEL_i486, | |||
100 | INTEL_PENTIUM, | |||
101 | INTEL_PENTIUM_PRO, | |||
102 | INTEL_PENTIUM_II, | |||
103 | INTEL_PENTIUM_III, | |||
104 | INTEL_PENTIUM_IV, | |||
105 | INTEL_PENTIUM_M, | |||
106 | INTEL_CORE_DUO, | |||
107 | INTEL_XEONPHI, | |||
108 | INTEL_X86_64, | |||
109 | INTEL_NOCONA, | |||
110 | INTEL_PRESCOTT, | |||
111 | AMD_i486, | |||
112 | AMDPENTIUM, | |||
113 | AMDATHLON, | |||
114 | AMDFAM14H, | |||
115 | AMDFAM16H, | |||
116 | CPU_TYPE_MAX | |||
117 | }; | |||
118 | ||||
119 | enum ProcessorSubtypes { | |||
120 | INTEL_COREI7_NEHALEM = 1, | |||
121 | INTEL_COREI7_WESTMERE, | |||
122 | INTEL_COREI7_SANDYBRIDGE, | |||
123 | AMDFAM10H_BARCELONA, | |||
124 | AMDFAM10H_SHANGHAI, | |||
125 | AMDFAM10H_ISTANBUL, | |||
126 | AMDFAM15H_BDVER1, | |||
127 | AMDFAM15H_BDVER2, | |||
128 | INTEL_PENTIUM_MMX, | |||
129 | INTEL_CORE2_65, | |||
130 | INTEL_CORE2_45, | |||
131 | INTEL_COREI7_IVYBRIDGE, | |||
132 | INTEL_COREI7_HASWELL, | |||
133 | INTEL_COREI7_BROADWELL, | |||
134 | INTEL_COREI7_SKYLAKE, | |||
135 | INTEL_COREI7_SKYLAKE_AVX512, | |||
136 | INTEL_ATOM_BONNELL, | |||
137 | INTEL_ATOM_SILVERMONT, | |||
138 | INTEL_KNIGHTS_LANDING, | |||
139 | AMDPENTIUM_K6, | |||
140 | AMDPENTIUM_K62, | |||
141 | AMDPENTIUM_K63, | |||
142 | AMDPENTIUM_GEODE, | |||
143 | AMDATHLON_TBIRD, | |||
144 | AMDATHLON_MP, | |||
145 | AMDATHLON_XP, | |||
146 | AMDATHLON_K8SSE3, | |||
147 | AMDATHLON_OPTERON, | |||
148 | AMDATHLON_FX, | |||
149 | AMDATHLON_64, | |||
150 | AMD_BTVER1, | |||
151 | AMD_BTVER2, | |||
152 | AMDFAM15H_BDVER3, | |||
153 | AMDFAM15H_BDVER4, | |||
154 | CPU_SUBTYPE_MAX | |||
155 | }; | |||
156 | ||||
157 | enum ProcessorFeatures { | |||
158 | FEATURE_CMOV = 0, | |||
159 | FEATURE_MMX, | |||
160 | FEATURE_POPCNT, | |||
161 | FEATURE_SSE, | |||
162 | FEATURE_SSE2, | |||
163 | FEATURE_SSE3, | |||
164 | FEATURE_SSSE3, | |||
165 | FEATURE_SSE4_1, | |||
166 | FEATURE_SSE4_2, | |||
167 | FEATURE_AVX, | |||
168 | FEATURE_AVX2, | |||
169 | FEATURE_AVX512, | |||
170 | FEATURE_AVX512SAVE, | |||
171 | FEATURE_MOVBE, | |||
172 | FEATURE_ADX, | |||
173 | FEATURE_EM64T | |||
174 | }; | |||
175 | ||||
176 | /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in | |||
177 | /// the specified arguments. If we can't run cpuid on the host, return true. | |||
178 | static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX, | |||
179 | unsigned *rECX, unsigned *rEDX) { | |||
180 | #if defined(__GNUC__4) || defined(__clang__1) || defined(_MSC_VER) | |||
181 | #if defined(__GNUC__4) || defined(__clang__1) | |||
182 | #if defined(__x86_64__1) | |||
183 | // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually. | |||
184 | // FIXME: should we save this for Clang? | |||
185 | __asm__("movq\t%%rbx, %%rsi\n\t" | |||
186 | "cpuid\n\t" | |||
187 | "xchgq\t%%rbx, %%rsi\n\t" | |||
188 | : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) | |||
189 | : "a"(value)); | |||
190 | #elif defined(__i386__) | |||
191 | __asm__("movl\t%%ebx, %%esi\n\t" | |||
192 | "cpuid\n\t" | |||
193 | "xchgl\t%%ebx, %%esi\n\t" | |||
194 | : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) | |||
195 | : "a"(value)); | |||
196 | #else | |||
197 | assert(0 && "This method is defined only for x86.")((0 && "This method is defined only for x86.") ? static_cast <void> (0) : __assert_fail ("0 && \"This method is defined only for x86.\"" , "/tmp/buildd/llvm-toolchain-snapshot-4.0~svn283027/lib/Support/Host.cpp" , 197, __PRETTY_FUNCTION__)); | |||
198 | #endif | |||
199 | #elif defined(_MSC_VER) | |||
200 | // The MSVC intrinsic is portable across x86 and x64. | |||
201 | int registers[4]; | |||
202 | __cpuid(registers, value); | |||
203 | *rEAX = registers[0]; | |||
204 | *rEBX = registers[1]; | |||
205 | *rECX = registers[2]; | |||
206 | *rEDX = registers[3]; | |||
207 | #endif | |||
208 | return false; | |||
209 | #else | |||
210 | return true; | |||
211 | #endif | |||
212 | } | |||
213 | ||||
214 | /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return | |||
215 | /// the 4 values in the specified arguments. If we can't run cpuid on the host, | |||
216 | /// return true. | |||
217 | static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf, | |||
218 | unsigned *rEAX, unsigned *rEBX, unsigned *rECX, | |||
219 | unsigned *rEDX) { | |||
220 | #if defined(__GNUC__4) || defined(__clang__1) || defined(_MSC_VER) | |||
221 | #if defined(__x86_64__1) || defined(_M_X64) | |||
222 | #if defined(__GNUC__4) || defined(__clang__1) | |||
223 | // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually. | |||
224 | // FIXME: should we save this for Clang? | |||
225 | __asm__("movq\t%%rbx, %%rsi\n\t" | |||
226 | "cpuid\n\t" | |||
227 | "xchgq\t%%rbx, %%rsi\n\t" | |||
228 | : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) | |||
229 | : "a"(value), "c"(subleaf)); | |||
230 | #elif defined(_MSC_VER) | |||
231 | int registers[4]; | |||
232 | __cpuidex(registers, value, subleaf); | |||
233 | *rEAX = registers[0]; | |||
234 | *rEBX = registers[1]; | |||
235 | *rECX = registers[2]; | |||
236 | *rEDX = registers[3]; | |||
237 | #endif | |||
238 | #elif defined(__i386__) || defined(_M_IX86) | |||
239 | #if defined(__GNUC__4) || defined(__clang__1) | |||
240 | __asm__("movl\t%%ebx, %%esi\n\t" | |||
241 | "cpuid\n\t" | |||
242 | "xchgl\t%%ebx, %%esi\n\t" | |||
243 | : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) | |||
244 | : "a"(value), "c"(subleaf)); | |||
245 | #elif defined(_MSC_VER) | |||
246 | __asm { | |||
247 | mov eax,value | |||
248 | mov ecx,subleaf | |||
249 | cpuid | |||
250 | mov esi,rEAX | |||
251 | mov dword ptr [esi],eax | |||
252 | mov esi,rEBX | |||
253 | mov dword ptr [esi],ebx | |||
254 | mov esi,rECX | |||
255 | mov dword ptr [esi],ecx | |||
256 | mov esi,rEDX | |||
257 | mov dword ptr [esi],edx | |||
258 | } | |||
259 | #endif | |||
260 | #else | |||
261 | assert(0 && "This method is defined only for x86.")((0 && "This method is defined only for x86.") ? static_cast <void> (0) : __assert_fail ("0 && \"This method is defined only for x86.\"" , "/tmp/buildd/llvm-toolchain-snapshot-4.0~svn283027/lib/Support/Host.cpp" , 261, __PRETTY_FUNCTION__)); | |||
262 | #endif | |||
263 | return false; | |||
264 | #else | |||
265 | return true; | |||
266 | #endif | |||
267 | } | |||
268 | ||||
269 | static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) { | |||
270 | #if defined(__GNUC__4) || defined(__clang__1) | |||
271 | // Check xgetbv; this uses a .byte sequence instead of the instruction | |||
272 | // directly because older assemblers do not include support for xgetbv and | |||
273 | // there is no easy way to conditionally compile based on the assembler used. | |||
274 | __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0)); | |||
275 | return false; | |||
276 | #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) | |||
277 | unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); | |||
278 | *rEAX = Result; | |||
279 | *rEDX = Result >> 32; | |||
280 | return false; | |||
281 | #else | |||
282 | return true; | |||
283 | #endif | |||
284 | } | |||
285 | ||||
286 | static void detectX86FamilyModel(unsigned EAX, unsigned *Family, | |||
287 | unsigned *Model) { | |||
288 | *Family = (EAX >> 8) & 0xf; // Bits 8 - 11 | |||
289 | *Model = (EAX >> 4) & 0xf; // Bits 4 - 7 | |||
290 | if (*Family == 6 || *Family == 0xf) { | |||
291 | if (*Family == 0xf) | |||
292 | // Examine extended family ID if family ID is F. | |||
293 | *Family += (EAX >> 20) & 0xff; // Bits 20 - 27 | |||
294 | // Examine extended model ID if family ID is 6 or F. | |||
295 | *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 | |||
296 | } | |||
297 | } | |||
298 | ||||
299 | static void | |||
300 | getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model, | |||
301 | unsigned int Brand_id, unsigned int Features, | |||
302 | unsigned *Type, unsigned *Subtype) { | |||
303 | if (Brand_id != 0) | |||
304 | return; | |||
305 | switch (Family) { | |||
306 | case 3: | |||
307 | *Type = INTEL_i386; | |||
308 | break; | |||
309 | case 4: | |||
310 | switch (Model) { | |||
311 | case 0: // Intel486 DX processors | |||
312 | case 1: // Intel486 DX processors | |||
313 | case 2: // Intel486 SX processors | |||
314 | case 3: // Intel487 processors, IntelDX2 OverDrive processors, | |||
315 | // IntelDX2 processors | |||
316 | case 4: // Intel486 SL processor | |||
317 | case 5: // IntelSX2 processors | |||
318 | case 7: // Write-Back Enhanced IntelDX2 processors | |||
319 | case 8: // IntelDX4 OverDrive processors, IntelDX4 processors | |||
320 | default: | |||
321 | *Type = INTEL_i486; | |||
322 | break; | |||
323 | } | |||
324 | break; | |||
325 | case 5: | |||
326 | switch (Model) { | |||
327 | case 1: // Pentium OverDrive processor for Pentium processor (60, 66), | |||
328 | // Pentium processors (60, 66) | |||
329 | case 2: // Pentium OverDrive processor for Pentium processor (75, 90, | |||
330 | // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133, | |||
331 | // 150, 166, 200) | |||
332 | case 3: // Pentium OverDrive processors for Intel486 processor-based | |||
333 | // systems | |||
334 | *Type = INTEL_PENTIUM; | |||
335 | break; | |||
336 | case 4: // Pentium OverDrive processor with MMX technology for Pentium | |||
337 | // processor (75, 90, 100, 120, 133), Pentium processor with | |||
338 | // MMX technology (166, 200) | |||
339 | *Type = INTEL_PENTIUM; | |||
340 | *Subtype = INTEL_PENTIUM_MMX; | |||
341 | break; | |||
342 | default: | |||
343 | *Type = INTEL_PENTIUM; | |||
344 | break; | |||
345 | } | |||
346 | break; | |||
347 | case 6: | |||
348 | switch (Model) { | |||
349 | case 0x01: // Pentium Pro processor | |||
350 | *Type = INTEL_PENTIUM_PRO; | |||
351 | break; | |||
352 | case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor, | |||
353 | // model 03 | |||
354 | case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor, | |||
355 | // model 05, and Intel Celeron processor, model 05 | |||
356 | case 0x06: // Celeron processor, model 06 | |||
357 | *Type = INTEL_PENTIUM_II; | |||
358 | break; | |||
359 | case 0x07: // Pentium III processor, model 07, and Pentium III Xeon | |||
360 | // processor, model 07 | |||
361 | case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor, | |||
362 | // model 08, and Celeron processor, model 08 | |||
363 | case 0x0a: // Pentium III Xeon processor, model 0Ah | |||
364 | case 0x0b: // Pentium III processor, model 0Bh | |||
365 | *Type = INTEL_PENTIUM_III; | |||
366 | break; | |||
367 | case 0x09: // Intel Pentium M processor, Intel Celeron M processor model 09. | |||
368 | case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model | |||
369 | // 0Dh. All processors are manufactured using the 90 nm process. | |||
370 | case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579 | |||
371 | // Integrated Processor with Intel QuickAssist Technology | |||
372 | *Type = INTEL_PENTIUM_M; | |||
373 | break; | |||
374 | case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model | |||
375 | // 0Eh. All processors are manufactured using the 65 nm process. | |||
376 | *Type = INTEL_CORE_DUO; | |||
377 | break; // yonah | |||
378 | case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile | |||
379 | // processor, Intel Core 2 Quad processor, Intel Core 2 Quad | |||
380 | // mobile processor, Intel Core 2 Extreme processor, Intel | |||
381 | // Pentium Dual-Core processor, Intel Xeon processor, model | |||
382 | // 0Fh. All processors are manufactured using the 65 nm process. | |||
383 | case 0x16: // Intel Celeron processor model 16h. All processors are | |||
384 | // manufactured using the 65 nm process | |||
385 | *Type = INTEL_CORE2; // "core2" | |||
386 | *Subtype = INTEL_CORE2_65; | |||
387 | break; | |||
388 | case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model | |||
389 | // 17h. All processors are manufactured using the 45 nm process. | |||
390 | // | |||
391 | // 45nm: Penryn , Wolfdale, Yorkfield (XE) | |||
392 | case 0x1d: // Intel Xeon processor MP. All processors are manufactured using | |||
393 | // the 45 nm process. | |||
394 | *Type = INTEL_CORE2; // "penryn" | |||
395 | *Subtype = INTEL_CORE2_45; | |||
396 | break; | |||
397 | case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All | |||
398 | // processors are manufactured using the 45 nm process. | |||
399 | case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. | |||
400 | // As found in a Summer 2010 model iMac. | |||
401 | case 0x1f: | |||
402 | case 0x2e: // Nehalem EX | |||
403 | *Type = INTEL_COREI7; // "nehalem" | |||
404 | *Subtype = INTEL_COREI7_NEHALEM; | |||
405 | break; | |||
406 | case 0x25: // Intel Core i7, laptop version. | |||
407 | case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All | |||
408 | // processors are manufactured using the 32 nm process. | |||
409 | case 0x2f: // Westmere EX | |||
410 | *Type = INTEL_COREI7; // "westmere" | |||
411 | *Subtype = INTEL_COREI7_WESTMERE; | |||
412 | break; | |||
413 | case 0x2a: // Intel Core i7 processor. All processors are manufactured | |||
414 | // using the 32 nm process. | |||
415 | case 0x2d: | |||
416 | *Type = INTEL_COREI7; //"sandybridge" | |||
417 | *Subtype = INTEL_COREI7_SANDYBRIDGE; | |||
418 | break; | |||
419 | case 0x3a: | |||
420 | case 0x3e: // Ivy Bridge EP | |||
421 | *Type = INTEL_COREI7; // "ivybridge" | |||
422 | *Subtype = INTEL_COREI7_IVYBRIDGE; | |||
423 | break; | |||
424 | ||||
425 | // Haswell: | |||
426 | case 0x3c: | |||
427 | case 0x3f: | |||
428 | case 0x45: | |||
429 | case 0x46: | |||
430 | *Type = INTEL_COREI7; // "haswell" | |||
431 | *Subtype = INTEL_COREI7_HASWELL; | |||
432 | break; | |||
433 | ||||
434 | // Broadwell: | |||
435 | case 0x3d: | |||
436 | case 0x47: | |||
437 | case 0x4f: | |||
438 | case 0x56: | |||
439 | *Type = INTEL_COREI7; // "broadwell" | |||
440 | *Subtype = INTEL_COREI7_BROADWELL; | |||
441 | break; | |||
442 | ||||
443 | // Skylake: | |||
444 | case 0x4e: | |||
445 | *Type = INTEL_COREI7; // "skylake-avx512" | |||
446 | *Subtype = INTEL_COREI7_SKYLAKE_AVX512; | |||
447 | break; | |||
448 | case 0x5e: | |||
449 | *Type = INTEL_COREI7; // "skylake" | |||
450 | *Subtype = INTEL_COREI7_SKYLAKE; | |||
451 | break; | |||
452 | ||||
453 | case 0x1c: // Most 45 nm Intel Atom processors | |||
454 | case 0x26: // 45 nm Atom Lincroft | |||
455 | case 0x27: // 32 nm Atom Medfield | |||
456 | case 0x35: // 32 nm Atom Midview | |||
457 | case 0x36: // 32 nm Atom Midview | |||
458 | *Type = INTEL_ATOM; | |||
459 | *Subtype = INTEL_ATOM_BONNELL; | |||
460 | break; // "bonnell" | |||
461 | ||||
462 | // Atom Silvermont codes from the Intel software optimization guide. | |||
463 | case 0x37: | |||
464 | case 0x4a: | |||
465 | case 0x4d: | |||
466 | case 0x5a: | |||
467 | case 0x5d: | |||
468 | case 0x4c: // really airmont | |||
469 | *Type = INTEL_ATOM; | |||
470 | *Subtype = INTEL_ATOM_SILVERMONT; | |||
471 | break; // "silvermont" | |||
472 | ||||
473 | case 0x57: | |||
474 | *Type = INTEL_XEONPHI; // knl | |||
475 | *Subtype = INTEL_KNIGHTS_LANDING; | |||
476 | break; | |||
477 | ||||
478 | default: // Unknown family 6 CPU, try to guess. | |||
479 | if (Features & (1 << FEATURE_AVX512)) { | |||
480 | *Type = INTEL_XEONPHI; // knl | |||
481 | *Subtype = INTEL_KNIGHTS_LANDING; | |||
482 | break; | |||
483 | } | |||
484 | if (Features & (1 << FEATURE_ADX)) { | |||
485 | *Type = INTEL_COREI7; | |||
486 | *Subtype = INTEL_COREI7_BROADWELL; | |||
487 | break; | |||
488 | } | |||
489 | if (Features & (1 << FEATURE_AVX2)) { | |||
490 | *Type = INTEL_COREI7; | |||
491 | *Subtype = INTEL_COREI7_HASWELL; | |||
492 | break; | |||
493 | } | |||
494 | if (Features & (1 << FEATURE_AVX)) { | |||
495 | *Type = INTEL_COREI7; | |||
496 | *Subtype = INTEL_COREI7_SANDYBRIDGE; | |||
497 | break; | |||
498 | } | |||
499 | if (Features & (1 << FEATURE_SSE4_2)) { | |||
500 | if (Features & (1 << FEATURE_MOVBE)) { | |||
501 | *Type = INTEL_ATOM; | |||
502 | *Subtype = INTEL_ATOM_SILVERMONT; | |||
503 | } else { | |||
504 | *Type = INTEL_COREI7; | |||
505 | *Subtype = INTEL_COREI7_NEHALEM; | |||
506 | } | |||
507 | break; | |||
508 | } | |||
509 | if (Features & (1 << FEATURE_SSE4_1)) { | |||
510 | *Type = INTEL_CORE2; // "penryn" | |||
511 | *Subtype = INTEL_CORE2_45; | |||
512 | break; | |||
513 | } | |||
514 | if (Features & (1 << FEATURE_SSSE3)) { | |||
515 | if (Features & (1 << FEATURE_MOVBE)) { | |||
516 | *Type = INTEL_ATOM; | |||
517 | *Subtype = INTEL_ATOM_BONNELL; // "bonnell" | |||
518 | } else { | |||
519 | *Type = INTEL_CORE2; // "core2" | |||
520 | *Subtype = INTEL_CORE2_65; | |||
521 | } | |||
522 | break; | |||
523 | } | |||
524 | if (Features & (1 << FEATURE_EM64T)) { | |||
525 | *Type = INTEL_X86_64; | |||
526 | break; // x86-64 | |||
527 | } | |||
528 | if (Features & (1 << FEATURE_SSE2)) { | |||
529 | *Type = INTEL_PENTIUM_M; | |||
530 | break; | |||
531 | } | |||
532 | if (Features & (1 << FEATURE_SSE)) { | |||
533 | *Type = INTEL_PENTIUM_III; | |||
534 | break; | |||
535 | } | |||
536 | if (Features & (1 << FEATURE_MMX)) { | |||
537 | *Type = INTEL_PENTIUM_II; | |||
538 | break; | |||
539 | } | |||
540 | *Type = INTEL_PENTIUM_PRO; | |||
541 | break; | |||
542 | } | |||
543 | break; | |||
544 | case 15: { | |||
545 | switch (Model) { | |||
546 | case 0: // Pentium 4 processor, Intel Xeon processor. All processors are | |||
547 | // model 00h and manufactured using the 0.18 micron process. | |||
548 | case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon | |||
549 | // processor MP, and Intel Celeron processor. All processors are | |||
550 | // model 01h and manufactured using the 0.18 micron process. | |||
551 | case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M, | |||
552 | // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron | |||
553 | // processor, and Mobile Intel Celeron processor. All processors | |||
554 | // are model 02h and manufactured using the 0.13 micron process. | |||
555 | *Type = | |||
556 | ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV); | |||
557 | break; | |||
558 | ||||
559 | case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D | |||
560 | // processor. All processors are model 03h and manufactured using | |||
561 | // the 90 nm process. | |||
562 | case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition, | |||
563 | // Pentium D processor, Intel Xeon processor, Intel Xeon | |||
564 | // processor MP, Intel Celeron D processor. All processors are | |||
565 | // model 04h and manufactured using the 90 nm process. | |||
566 | case 6: // Pentium 4 processor, Pentium D processor, Pentium processor | |||
567 | // Extreme Edition, Intel Xeon processor, Intel Xeon processor | |||
568 | // MP, Intel Celeron D processor. All processors are model 06h | |||
569 | // and manufactured using the 65 nm process. | |||
570 | *Type = | |||
571 | ((Features & (1 << FEATURE_EM64T)) ? INTEL_NOCONA : INTEL_PRESCOTT); | |||
572 | break; | |||
573 | ||||
574 | default: | |||
575 | *Type = | |||
576 | ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV); | |||
577 | break; | |||
578 | } | |||
579 | break; | |||
580 | } | |||
581 | default: | |||
582 | break; /*"generic"*/ | |||
583 | } | |||
584 | } | |||
585 | ||||
586 | static void getAMDProcessorTypeAndSubtype(unsigned int Family, | |||
587 | unsigned int Model, | |||
588 | unsigned int Features, | |||
589 | unsigned *Type, | |||
590 | unsigned *Subtype) { | |||
591 | // FIXME: this poorly matches the generated SubtargetFeatureKV table. There | |||
592 | // appears to be no way to generate the wide variety of AMD-specific targets | |||
593 | // from the information returned from CPUID. | |||
594 | switch (Family) { | |||
595 | case 4: | |||
596 | *Type = AMD_i486; | |||
597 | break; | |||
598 | case 5: | |||
599 | *Type = AMDPENTIUM; | |||
600 | switch (Model) { | |||
601 | case 6: | |||
602 | case 7: | |||
603 | *Subtype = AMDPENTIUM_K6; | |||
604 | break; // "k6" | |||
605 | case 8: | |||
606 | *Subtype = AMDPENTIUM_K62; | |||
607 | break; // "k6-2" | |||
608 | case 9: | |||
609 | case 13: | |||
610 | *Subtype = AMDPENTIUM_K63; | |||
611 | break; // "k6-3" | |||
612 | case 10: | |||
613 | *Subtype = AMDPENTIUM_GEODE; | |||
614 | break; // "geode" | |||
615 | } | |||
616 | break; | |||
617 | case 6: | |||
618 | *Type = AMDATHLON; | |||
619 | switch (Model) { | |||
620 | case 4: | |||
621 | *Subtype = AMDATHLON_TBIRD; | |||
622 | break; // "athlon-tbird" | |||
623 | case 6: | |||
624 | case 7: | |||
625 | case 8: | |||
626 | *Subtype = AMDATHLON_MP; | |||
627 | break; // "athlon-mp" | |||
628 | case 10: | |||
629 | *Subtype = AMDATHLON_XP; | |||
630 | break; // "athlon-xp" | |||
631 | } | |||
632 | break; | |||
633 | case 15: | |||
634 | *Type = AMDATHLON; | |||
635 | if (Features & (1 << FEATURE_SSE3)) { | |||
636 | *Subtype = AMDATHLON_K8SSE3; | |||
637 | break; // "k8-sse3" | |||
638 | } | |||
639 | switch (Model) { | |||
640 | case 1: | |||
641 | *Subtype = AMDATHLON_OPTERON; | |||
642 | break; // "opteron" | |||
643 | case 5: | |||
644 | *Subtype = AMDATHLON_FX; | |||
645 | break; // "athlon-fx"; also opteron | |||
646 | default: | |||
647 | *Subtype = AMDATHLON_64; | |||
648 | break; // "athlon64" | |||
649 | } | |||
650 | break; | |||
651 | case 16: | |||
652 | *Type = AMDFAM10H; // "amdfam10" | |||
653 | switch (Model) { | |||
654 | case 2: | |||
655 | *Subtype = AMDFAM10H_BARCELONA; | |||
656 | break; | |||
657 | case 4: | |||
658 | *Subtype = AMDFAM10H_SHANGHAI; | |||
659 | break; | |||
660 | case 8: | |||
661 | *Subtype = AMDFAM10H_ISTANBUL; | |||
662 | break; | |||
663 | } | |||
664 | break; | |||
665 | case 20: | |||
666 | *Type = AMDFAM14H; | |||
667 | *Subtype = AMD_BTVER1; | |||
668 | break; // "btver1"; | |||
669 | case 21: | |||
670 | *Type = AMDFAM15H; | |||
671 | if (!(Features & | |||
672 | (1 << FEATURE_AVX))) { // If no AVX support, provide a sane fallback. | |||
673 | *Subtype = AMD_BTVER1; | |||
674 | break; // "btver1" | |||
675 | } | |||
676 | if (Model >= 0x50 && Model <= 0x6f) { | |||
677 | *Subtype = AMDFAM15H_BDVER4; | |||
678 | break; // "bdver4"; 50h-6Fh: Excavator | |||
679 | } | |||
680 | if (Model >= 0x30 && Model <= 0x3f) { | |||
681 | *Subtype = AMDFAM15H_BDVER3; | |||
682 | break; // "bdver3"; 30h-3Fh: Steamroller | |||
683 | } | |||
684 | if (Model >= 0x10 && Model <= 0x1f) { | |||
685 | *Subtype = AMDFAM15H_BDVER2; | |||
686 | break; // "bdver2"; 10h-1Fh: Piledriver | |||
687 | } | |||
688 | if (Model <= 0x0f) { | |||
689 | *Subtype = AMDFAM15H_BDVER1; | |||
690 | break; // "bdver1"; 00h-0Fh: Bulldozer | |||
691 | } | |||
692 | break; | |||
693 | case 22: | |||
694 | *Type = AMDFAM16H; | |||
695 | if (!(Features & | |||
696 | (1 << FEATURE_AVX))) { // If no AVX support provide a sane fallback. | |||
697 | *Subtype = AMD_BTVER1; | |||
698 | break; // "btver1"; | |||
699 | } | |||
700 | *Subtype = AMD_BTVER2; | |||
701 | break; // "btver2" | |||
702 | default: | |||
703 | break; // "generic" | |||
704 | } | |||
705 | } | |||
706 | ||||
707 | static unsigned getAvailableFeatures(unsigned int ECX, unsigned int EDX, | |||
708 | unsigned MaxLeaf) { | |||
709 | unsigned Features = 0; | |||
710 | unsigned int EAX, EBX; | |||
711 | Features |= (((EDX >> 23) & 1) << FEATURE_MMX); | |||
712 | Features |= (((EDX >> 25) & 1) << FEATURE_SSE); | |||
713 | Features |= (((EDX >> 26) & 1) << FEATURE_SSE2); | |||
714 | Features |= (((ECX >> 0) & 1) << FEATURE_SSE3); | |||
715 | Features |= (((ECX >> 9) & 1) << FEATURE_SSSE3); | |||
716 | Features |= (((ECX >> 19) & 1) << FEATURE_SSE4_1); | |||
717 | Features |= (((ECX >> 20) & 1) << FEATURE_SSE4_2); | |||
718 | Features |= (((ECX >> 22) & 1) << FEATURE_MOVBE); | |||
719 | ||||
720 | // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV | |||
721 | // indicates that the AVX registers will be saved and restored on context | |||
722 | // switch, then we have full AVX support. | |||
723 | const unsigned AVXBits = (1 << 27) | (1 << 28); | |||
724 | bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) && | |||
725 | ((EAX & 0x6) == 0x6); | |||
726 | bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0); | |||
727 | bool HasLeaf7 = | |||
728 | MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); | |||
729 | bool HasADX = HasLeaf7 && ((EBX >> 19) & 1); | |||
730 | bool HasAVX2 = HasAVX && HasLeaf7 && (EBX & 0x20); | |||
731 | bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((EBX >> 16) & 1); | |||
732 | Features |= (HasAVX << FEATURE_AVX); | |||
733 | Features |= (HasAVX2 << FEATURE_AVX2); | |||
734 | Features |= (HasAVX512 << FEATURE_AVX512); | |||
735 | Features |= (HasAVX512Save << FEATURE_AVX512SAVE); | |||
736 | Features |= (HasADX << FEATURE_ADX); | |||
737 | ||||
738 | getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); | |||
739 | Features |= (((EDX >> 29) & 0x1) << FEATURE_EM64T); | |||
740 | return Features; | |||
741 | } | |||
742 | ||||
743 | StringRef sys::getHostCPUName() { | |||
744 | unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; | |||
745 | unsigned MaxLeaf, Vendor; | |||
746 | ||||
747 | #if defined(__GNUC__4) || defined(__clang__1) | |||
748 | //FIXME: include cpuid.h from clang or copy __get_cpuid_max here | |||
749 | // and simplify it to not invoke __cpuid (like cpu_model.c in | |||
750 | // compiler-rt/lib/builtins/cpu_model.c? | |||
751 | if(!__get_cpuid_max(0, &Vendor)) | |||
| ||||
752 | return "generic"; | |||
753 | #endif | |||
754 | if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX)) | |||
755 | return "generic"; | |||
756 | if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX)) | |||
757 | return "generic"; | |||
758 | ||||
759 | unsigned Brand_id = EBX & 0xff; | |||
760 | unsigned Family = 0, Model = 0; | |||
761 | unsigned Features = 0; | |||
762 | detectX86FamilyModel(EAX, &Family, &Model); | |||
763 | Features = getAvailableFeatures(ECX, EDX, MaxLeaf); | |||
764 | ||||
765 | unsigned Type; | |||
766 | unsigned Subtype; | |||
767 | ||||
768 | if (Vendor == SIG_INTEL) { | |||
769 | getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features, &Type, | |||
770 | &Subtype); | |||
771 | switch (Type) { | |||
772 | case INTEL_i386: | |||
773 | return "i386"; | |||
774 | case INTEL_i486: | |||
775 | return "i486"; | |||
776 | case INTEL_PENTIUM: | |||
777 | if (Subtype == INTEL_PENTIUM_MMX) | |||
778 | return "pentium-mmx"; | |||
779 | return "pentium"; | |||
780 | case INTEL_PENTIUM_PRO: | |||
781 | return "pentiumpro"; | |||
782 | case INTEL_PENTIUM_II: | |||
783 | return "pentium2"; | |||
784 | case INTEL_PENTIUM_III: | |||
785 | return "pentium3"; | |||
786 | case INTEL_PENTIUM_IV: | |||
787 | return "pentium4"; | |||
788 | case INTEL_PENTIUM_M: | |||
789 | return "pentium-m"; | |||
790 | case INTEL_CORE_DUO: | |||
791 | return "yonah"; | |||
792 | case INTEL_CORE2: | |||
793 | switch (Subtype) { | |||
794 | case INTEL_CORE2_65: | |||
795 | return "core2"; | |||
796 | case INTEL_CORE2_45: | |||
797 | return "penryn"; | |||
798 | default: | |||
799 | return "core2"; | |||
800 | } | |||
801 | case INTEL_COREI7: | |||
802 | switch (Subtype) { | |||
803 | case INTEL_COREI7_NEHALEM: | |||
804 | return "nehalem"; | |||
805 | case INTEL_COREI7_WESTMERE: | |||
806 | return "westmere"; | |||
807 | case INTEL_COREI7_SANDYBRIDGE: | |||
808 | return "sandybridge"; | |||
809 | case INTEL_COREI7_IVYBRIDGE: | |||
810 | return "ivybridge"; | |||
811 | case INTEL_COREI7_HASWELL: | |||
812 | return "haswell"; | |||
813 | case INTEL_COREI7_BROADWELL: | |||
814 | return "broadwell"; | |||
815 | case INTEL_COREI7_SKYLAKE: | |||
816 | return "skylake"; | |||
817 | case INTEL_COREI7_SKYLAKE_AVX512: | |||
818 | return "skylake-avx512"; | |||
819 | default: | |||
820 | return "corei7"; | |||
821 | } | |||
822 | case INTEL_ATOM: | |||
823 | switch (Subtype) { | |||
824 | case INTEL_ATOM_BONNELL: | |||
825 | return "bonnell"; | |||
826 | case INTEL_ATOM_SILVERMONT: | |||
827 | return "silvermont"; | |||
828 | default: | |||
829 | return "atom"; | |||
830 | } | |||
831 | case INTEL_XEONPHI: | |||
832 | return "knl"; /*update for more variants added*/ | |||
833 | case INTEL_X86_64: | |||
834 | return "x86-64"; | |||
835 | case INTEL_NOCONA: | |||
836 | return "nocona"; | |||
837 | case INTEL_PRESCOTT: | |||
838 | return "prescott"; | |||
839 | default: | |||
840 | return "generic"; | |||
841 | } | |||
842 | } else if (Vendor == SIG_AMD) { | |||
843 | getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype); | |||
844 | switch (Type) { | |||
845 | case AMD_i486: | |||
846 | return "i486"; | |||
847 | case AMDPENTIUM: | |||
848 | switch (Subtype) { | |||
849 | case AMDPENTIUM_K6: | |||
850 | return "k6"; | |||
851 | case AMDPENTIUM_K62: | |||
852 | return "k6-2"; | |||
853 | case AMDPENTIUM_K63: | |||
854 | return "k6-3"; | |||
855 | case AMDPENTIUM_GEODE: | |||
856 | return "geode"; | |||
857 | default: | |||
858 | return "pentium"; | |||
859 | } | |||
860 | case AMDATHLON: | |||
861 | switch (Subtype) { | |||
862 | case AMDATHLON_TBIRD: | |||
863 | return "athlon-tbird"; | |||
864 | case AMDATHLON_MP: | |||
865 | return "athlon-mp"; | |||
866 | case AMDATHLON_XP: | |||
867 | return "athlon-xp"; | |||
868 | case AMDATHLON_K8SSE3: | |||
869 | return "k8-sse3"; | |||
870 | case AMDATHLON_OPTERON: | |||
871 | return "opteron"; | |||
872 | case AMDATHLON_FX: | |||
873 | return "athlon-fx"; | |||
874 | case AMDATHLON_64: | |||
875 | return "athlon64"; | |||
876 | default: | |||
877 | return "athlon"; | |||
878 | } | |||
879 | case AMDFAM10H: | |||
880 | if(Subtype == AMDFAM10H_BARCELONA) | |||
| ||||
881 | return "barcelona"; | |||
882 | return "amdfam10"; | |||
883 | case AMDFAM14H: | |||
884 | return "btver1"; | |||
885 | case AMDFAM15H: | |||
886 | switch (Subtype) { | |||
887 | case AMDFAM15H_BDVER1: | |||
888 | return "bdver1"; | |||
889 | case AMDFAM15H_BDVER2: | |||
890 | return "bdver2"; | |||
891 | case AMDFAM15H_BDVER3: | |||
892 | return "bdver3"; | |||
893 | case AMDFAM15H_BDVER4: | |||
894 | return "bdver4"; | |||
895 | case AMD_BTVER1: | |||
896 | return "btver1"; | |||
897 | default: | |||
898 | return "amdfam15"; | |||
899 | } | |||
900 | case AMDFAM16H: | |||
901 | switch (Subtype) { | |||
902 | case AMD_BTVER1: | |||
903 | return "btver1"; | |||
904 | case AMD_BTVER2: | |||
905 | return "btver2"; | |||
906 | default: | |||
907 | return "amdfam16"; | |||
908 | } | |||
909 | default: | |||
910 | return "generic"; | |||
911 | } | |||
912 | } | |||
913 | return "generic"; | |||
914 | } | |||
915 | ||||
916 | #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) | |||
917 | StringRef sys::getHostCPUName() { | |||
918 | host_basic_info_data_t hostInfo; | |||
919 | mach_msg_type_number_t infoCount; | |||
920 | ||||
921 | infoCount = HOST_BASIC_INFO_COUNT; | |||
922 | host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, | |||
923 | &infoCount); | |||
924 | ||||
925 | if (hostInfo.cpu_type != CPU_TYPE_POWERPC) | |||
926 | return "generic"; | |||
927 | ||||
928 | switch (hostInfo.cpu_subtype) { | |||
929 | case CPU_SUBTYPE_POWERPC_601: | |||
930 | return "601"; | |||
931 | case CPU_SUBTYPE_POWERPC_602: | |||
932 | return "602"; | |||
933 | case CPU_SUBTYPE_POWERPC_603: | |||
934 | return "603"; | |||
935 | case CPU_SUBTYPE_POWERPC_603e: | |||
936 | return "603e"; | |||
937 | case CPU_SUBTYPE_POWERPC_603ev: | |||
938 | return "603ev"; | |||
939 | case CPU_SUBTYPE_POWERPC_604: | |||
940 | return "604"; | |||
941 | case CPU_SUBTYPE_POWERPC_604e: | |||
942 | return "604e"; | |||
943 | case CPU_SUBTYPE_POWERPC_620: | |||
944 | return "620"; | |||
945 | case CPU_SUBTYPE_POWERPC_750: | |||
946 | return "750"; | |||
947 | case CPU_SUBTYPE_POWERPC_7400: | |||
948 | return "7400"; | |||
949 | case CPU_SUBTYPE_POWERPC_7450: | |||
950 | return "7450"; | |||
951 | case CPU_SUBTYPE_POWERPC_970: | |||
952 | return "970"; | |||
953 | default:; | |||
954 | } | |||
955 | ||||
956 | return "generic"; | |||
957 | } | |||
958 | #elif defined(__linux__1) && (defined(__ppc__) || defined(__powerpc__)) | |||
959 | StringRef sys::getHostCPUName() { | |||
960 | // Access to the Processor Version Register (PVR) on PowerPC is privileged, | |||
961 | // and so we must use an operating-system interface to determine the current | |||
962 | // processor type. On Linux, this is exposed through the /proc/cpuinfo file. | |||
963 | const char *generic = "generic"; | |||
964 | ||||
965 | // The cpu line is second (after the 'processor: 0' line), so if this | |||
966 | // buffer is too small then something has changed (or is wrong). | |||
967 | char buffer[1024]; | |||
968 | ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer)); | |||
969 | if (CPUInfoSize == -1) | |||
970 | return generic; | |||
971 | ||||
972 | const char *CPUInfoStart = buffer; | |||
973 | const char *CPUInfoEnd = buffer + CPUInfoSize; | |||
974 | ||||
975 | const char *CIP = CPUInfoStart; | |||
976 | ||||
977 | const char *CPUStart = 0; | |||
978 | size_t CPULen = 0; | |||
979 | ||||
980 | // We need to find the first line which starts with cpu, spaces, and a colon. | |||
981 | // After the colon, there may be some additional spaces and then the cpu type. | |||
982 | while (CIP < CPUInfoEnd && CPUStart == 0) { | |||
983 | if (CIP < CPUInfoEnd && *CIP == '\n') | |||
984 | ++CIP; | |||
985 | ||||
986 | if (CIP < CPUInfoEnd && *CIP == 'c') { | |||
987 | ++CIP; | |||
988 | if (CIP < CPUInfoEnd && *CIP == 'p') { | |||
989 | ++CIP; | |||
990 | if (CIP < CPUInfoEnd && *CIP == 'u') { | |||
991 | ++CIP; | |||
992 | while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) | |||
993 | ++CIP; | |||
994 | ||||
995 | if (CIP < CPUInfoEnd && *CIP == ':') { | |||
996 | ++CIP; | |||
997 | while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) | |||
998 | ++CIP; | |||
999 | ||||
1000 | if (CIP < CPUInfoEnd) { | |||
1001 | CPUStart = CIP; | |||
1002 | while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' && | |||
1003 | *CIP != ',' && *CIP != '\n')) | |||
1004 | ++CIP; | |||
1005 | CPULen = CIP - CPUStart; | |||
1006 | } | |||
1007 | } | |||
1008 | } | |||
1009 | } | |||
1010 | } | |||
1011 | ||||
1012 | if (CPUStart == 0) | |||
1013 | while (CIP < CPUInfoEnd && *CIP != '\n') | |||
1014 | ++CIP; | |||
1015 | } | |||
1016 | ||||
1017 | if (CPUStart == 0) | |||
1018 | return generic; | |||
1019 | ||||
1020 | return StringSwitch<const char *>(StringRef(CPUStart, CPULen)) | |||
1021 | .Case("604e", "604e") | |||
1022 | .Case("604", "604") | |||
1023 | .Case("7400", "7400") | |||
1024 | .Case("7410", "7400") | |||
1025 | .Case("7447", "7400") | |||
1026 | .Case("7455", "7450") | |||
1027 | .Case("G4", "g4") | |||
1028 | .Case("POWER4", "970") | |||
1029 | .Case("PPC970FX", "970") | |||
1030 | .Case("PPC970MP", "970") | |||
1031 | .Case("G5", "g5") | |||
1032 | .Case("POWER5", "g5") | |||
1033 | .Case("A2", "a2") | |||
1034 | .Case("POWER6", "pwr6") | |||
1035 | .Case("POWER7", "pwr7") | |||
1036 | .Case("POWER8", "pwr8") | |||
1037 | .Case("POWER8E", "pwr8") | |||
1038 | .Case("POWER9", "pwr9") | |||
1039 | .Default(generic); | |||
1040 | } | |||
1041 | #elif defined(__linux__1) && defined(__arm__) | |||
1042 | StringRef sys::getHostCPUName() { | |||
1043 | // The cpuid register on arm is not accessible from user space. On Linux, | |||
1044 | // it is exposed through the /proc/cpuinfo file. | |||
1045 | ||||
1046 | // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line | |||
1047 | // in all cases. | |||
1048 | char buffer[1024]; | |||
1049 | ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer)); | |||
1050 | if (CPUInfoSize == -1) | |||
1051 | return "generic"; | |||
1052 | ||||
1053 | StringRef Str(buffer, CPUInfoSize); | |||
1054 | ||||
1055 | SmallVector<StringRef, 32> Lines; | |||
1056 | Str.split(Lines, "\n"); | |||
1057 | ||||
1058 | // Look for the CPU implementer line. | |||
1059 | StringRef Implementer; | |||
1060 | for (unsigned I = 0, E = Lines.size(); I != E; ++I) | |||
1061 | if (Lines[I].startswith("CPU implementer")) | |||
1062 | Implementer = Lines[I].substr(15).ltrim("\t :"); | |||
1063 | ||||
1064 | if (Implementer == "0x41") // ARM Ltd. | |||
1065 | // Look for the CPU part line. | |||
1066 | for (unsigned I = 0, E = Lines.size(); I != E; ++I) | |||
1067 | if (Lines[I].startswith("CPU part")) | |||
1068 | // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The | |||
1069 | // values correspond to the "Part number" in the CP15/c0 register. The | |||
1070 | // contents are specified in the various processor manuals. | |||
1071 | return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :")) | |||
1072 | .Case("0x926", "arm926ej-s") | |||
1073 | .Case("0xb02", "mpcore") | |||
1074 | .Case("0xb36", "arm1136j-s") | |||
1075 | .Case("0xb56", "arm1156t2-s") | |||
1076 | .Case("0xb76", "arm1176jz-s") | |||
1077 | .Case("0xc08", "cortex-a8") | |||
1078 | .Case("0xc09", "cortex-a9") | |||
1079 | .Case("0xc0f", "cortex-a15") | |||
1080 | .Case("0xc20", "cortex-m0") | |||
1081 | .Case("0xc23", "cortex-m3") | |||
1082 | .Case("0xc24", "cortex-m4") | |||
1083 | .Default("generic"); | |||
1084 | ||||
1085 | if (Implementer == "0x51") // Qualcomm Technologies, Inc. | |||
1086 | // Look for the CPU part line. | |||
1087 | for (unsigned I = 0, E = Lines.size(); I != E; ++I) | |||
1088 | if (Lines[I].startswith("CPU part")) | |||
1089 | // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The | |||
1090 | // values correspond to the "Part number" in the CP15/c0 register. The | |||
1091 | // contents are specified in the various processor manuals. | |||
1092 | return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :")) | |||
1093 | .Case("0x06f", "krait") // APQ8064 | |||
1094 | .Default("generic"); | |||
1095 | ||||
1096 | return "generic"; | |||
1097 | } | |||
1098 | #elif defined(__linux__1) && defined(__s390x__) | |||
1099 | StringRef sys::getHostCPUName() { | |||
1100 | // STIDP is a privileged operation, so use /proc/cpuinfo instead. | |||
1101 | ||||
1102 | // The "processor 0:" line comes after a fair amount of other information, | |||
1103 | // including a cache breakdown, but this should be plenty. | |||
1104 | char buffer[2048]; | |||
1105 | ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer)); | |||
1106 | if (CPUInfoSize == -1) | |||
1107 | return "generic"; | |||
1108 | ||||
1109 | StringRef Str(buffer, CPUInfoSize); | |||
1110 | SmallVector<StringRef, 32> Lines; | |||
1111 | Str.split(Lines, "\n"); | |||
1112 | ||||
1113 | // Look for the CPU features. | |||
1114 | SmallVector<StringRef, 32> CPUFeatures; | |||
1115 | for (unsigned I = 0, E = Lines.size(); I != E; ++I) | |||
1116 | if (Lines[I].startswith("features")) { | |||
1117 | size_t Pos = Lines[I].find(":"); | |||
1118 | if (Pos != StringRef::npos) { | |||
1119 | Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' '); | |||
1120 | break; | |||
1121 | } | |||
1122 | } | |||
1123 | ||||
1124 | // We need to check for the presence of vector support independently of | |||
1125 | // the machine type, since we may only use the vector register set when | |||
1126 | // supported by the kernel (and hypervisor). | |||
1127 | bool HaveVectorSupport = false; | |||
1128 | for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { | |||
1129 | if (CPUFeatures[I] == "vx") | |||
1130 | HaveVectorSupport = true; | |||
1131 | } | |||
1132 | ||||
1133 | // Now check the processor machine type. | |||
1134 | for (unsigned I = 0, E = Lines.size(); I != E; ++I) { | |||
1135 | if (Lines[I].startswith("processor ")) { | |||
1136 | size_t Pos = Lines[I].find("machine = "); | |||
1137 | if (Pos != StringRef::npos) { | |||
1138 | Pos += sizeof("machine = ") - 1; | |||
1139 | unsigned int Id; | |||
1140 | if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) { | |||
1141 | if (Id >= 2964 && HaveVectorSupport) | |||
1142 | return "z13"; | |||
1143 | if (Id >= 2827) | |||
1144 | return "zEC12"; | |||
1145 | if (Id >= 2817) | |||
1146 | return "z196"; | |||
1147 | } | |||
1148 | } | |||
1149 | break; | |||
1150 | } | |||
1151 | } | |||
1152 | ||||
1153 | return "generic"; | |||
1154 | } | |||
1155 | #else | |||
1156 | StringRef sys::getHostCPUName() { return "generic"; } | |||
1157 | #endif | |||
1158 | ||||
1159 | #if defined(__i386__) || defined(_M_IX86) || \ | |||
1160 | defined(__x86_64__1) || defined(_M_X64) | |||
1161 | bool sys::getHostCPUFeatures(StringMap<bool> &Features) { | |||
1162 | unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; | |||
1163 | unsigned MaxLevel; | |||
1164 | union { | |||
1165 | unsigned u[3]; | |||
1166 | char c[12]; | |||
1167 | } text; | |||
1168 | ||||
1169 | if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) || | |||
1170 | MaxLevel < 1) | |||
1171 | return false; | |||
1172 | ||||
1173 | getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX); | |||
1174 | ||||
1175 | Features["cmov"] = (EDX >> 15) & 1; | |||
1176 | Features["mmx"] = (EDX >> 23) & 1; | |||
1177 | Features["sse"] = (EDX >> 25) & 1; | |||
1178 | Features["sse2"] = (EDX >> 26) & 1; | |||
1179 | Features["sse3"] = (ECX >> 0) & 1; | |||
1180 | Features["ssse3"] = (ECX >> 9) & 1; | |||
1181 | Features["sse4.1"] = (ECX >> 19) & 1; | |||
1182 | Features["sse4.2"] = (ECX >> 20) & 1; | |||
1183 | ||||
1184 | Features["pclmul"] = (ECX >> 1) & 1; | |||
1185 | Features["cx16"] = (ECX >> 13) & 1; | |||
1186 | Features["movbe"] = (ECX >> 22) & 1; | |||
1187 | Features["popcnt"] = (ECX >> 23) & 1; | |||
1188 | Features["aes"] = (ECX >> 25) & 1; | |||
1189 | Features["rdrnd"] = (ECX >> 30) & 1; | |||
1190 | ||||
1191 | // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV | |||
1192 | // indicates that the AVX registers will be saved and restored on context | |||
1193 | // switch, then we have full AVX support. | |||
1194 | bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) && | |||
1195 | !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6); | |||
1196 | Features["avx"] = HasAVXSave; | |||
1197 | Features["fma"] = HasAVXSave && (ECX >> 12) & 1; | |||
1198 | Features["f16c"] = HasAVXSave && (ECX >> 29) & 1; | |||
1199 | ||||
1200 | // Only enable XSAVE if OS has enabled support for saving YMM state. | |||
1201 | Features["xsave"] = HasAVXSave && (ECX >> 26) & 1; | |||
1202 | ||||
1203 | // AVX512 requires additional context to be saved by the OS. | |||
1204 | bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0); | |||
1205 | ||||
1206 | unsigned MaxExtLevel; | |||
1207 | getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); | |||
1208 | ||||
1209 | bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && | |||
1210 | !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); | |||
1211 | Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1); | |||
1212 | Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1); | |||
1213 | Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1); | |||
1214 | Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave; | |||
1215 | Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave; | |||
1216 | Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1); | |||
1217 | Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1); | |||
1218 | ||||
1219 | bool HasLeaf7 = | |||
1220 | MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); | |||
1221 | ||||
1222 | // AVX2 is only supported if we have the OS save support from AVX. | |||
1223 | Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1); | |||
1224 | ||||
1225 | Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1); | |||
1226 | Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1); | |||
1227 | Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1); | |||
1228 | Features["hle"] = HasLeaf7 && ((EBX >> 4) & 1); | |||
1229 | Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1); | |||
1230 | Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1); | |||
1231 | Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1); | |||
1232 | Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1); | |||
1233 | Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1); | |||
1234 | Features["smap"] = HasLeaf7 && ((EBX >> 20) & 1); | |||
1235 | Features["pcommit"] = HasLeaf7 && ((EBX >> 22) & 1); | |||
1236 | Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1); | |||
1237 | Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1); | |||
1238 | Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1); | |||
1239 | ||||
1240 | // AVX512 is only supported if the OS supports the context save for it. | |||
1241 | Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save; | |||
1242 | Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save; | |||
1243 | Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save; | |||
1244 | Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save; | |||
1245 | Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save; | |||
1246 | Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save; | |||
1247 | Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save; | |||
1248 | Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save; | |||
1249 | ||||
1250 | Features["prefetchwt1"] = HasLeaf7 && (ECX & 1); | |||
1251 | Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save; | |||
1252 | // Enable protection keys | |||
1253 | Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1); | |||
1254 | ||||
1255 | bool HasLeafD = MaxLevel >= 0xd && | |||
1256 | !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX); | |||
1257 | ||||
1258 | // Only enable XSAVE if OS has enabled support for saving YMM state. | |||
1259 | Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1); | |||
1260 | Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1); | |||
1261 | Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1); | |||
1262 | ||||
1263 | return true; | |||
1264 | } | |||
1265 | #elif defined(__linux__1) && (defined(__arm__) || defined(__aarch64__)) | |||
1266 | bool sys::getHostCPUFeatures(StringMap<bool> &Features) { | |||
1267 | // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line | |||
1268 | // in all cases. | |||
1269 | char buffer[1024]; | |||
1270 | ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer)); | |||
1271 | if (CPUInfoSize == -1) | |||
1272 | return false; | |||
1273 | ||||
1274 | StringRef Str(buffer, CPUInfoSize); | |||
1275 | ||||
1276 | SmallVector<StringRef, 32> Lines; | |||
1277 | Str.split(Lines, "\n"); | |||
1278 | ||||
1279 | SmallVector<StringRef, 32> CPUFeatures; | |||
1280 | ||||
1281 | // Look for the CPU features. | |||
1282 | for (unsigned I = 0, E = Lines.size(); I != E; ++I) | |||
1283 | if (Lines[I].startswith("Features")) { | |||
1284 | Lines[I].split(CPUFeatures, ' '); | |||
1285 | break; | |||
1286 | } | |||
1287 | ||||
1288 | #if defined(__aarch64__) | |||
1289 | // Keep track of which crypto features we have seen | |||
1290 | enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 }; | |||
1291 | uint32_t crypto = 0; | |||
1292 | #endif | |||
1293 | ||||
1294 | for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { | |||
1295 | StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I]) | |||
1296 | #if defined(__aarch64__) | |||
1297 | .Case("asimd", "neon") | |||
1298 | .Case("fp", "fp-armv8") | |||
1299 | .Case("crc32", "crc") | |||
1300 | #else | |||
1301 | .Case("half", "fp16") | |||
1302 | .Case("neon", "neon") | |||
1303 | .Case("vfpv3", "vfp3") | |||
1304 | .Case("vfpv3d16", "d16") | |||
1305 | .Case("vfpv4", "vfp4") | |||
1306 | .Case("idiva", "hwdiv-arm") | |||
1307 | .Case("idivt", "hwdiv") | |||
1308 | #endif | |||
1309 | .Default(""); | |||
1310 | ||||
1311 | #if defined(__aarch64__) | |||
1312 | // We need to check crypto separately since we need all of the crypto | |||
1313 | // extensions to enable the subtarget feature | |||
1314 | if (CPUFeatures[I] == "aes") | |||
1315 | crypto |= CAP_AES; | |||
1316 | else if (CPUFeatures[I] == "pmull") | |||
1317 | crypto |= CAP_PMULL; | |||
1318 | else if (CPUFeatures[I] == "sha1") | |||
1319 | crypto |= CAP_SHA1; | |||
1320 | else if (CPUFeatures[I] == "sha2") | |||
1321 | crypto |= CAP_SHA2; | |||
1322 | #endif | |||
1323 | ||||
1324 | if (LLVMFeatureStr != "") | |||
1325 | Features[LLVMFeatureStr] = true; | |||
1326 | } | |||
1327 | ||||
1328 | #if defined(__aarch64__) | |||
1329 | // If we have all crypto bits we can add the feature | |||
1330 | if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2)) | |||
1331 | Features["crypto"] = true; | |||
1332 | #endif | |||
1333 | ||||
1334 | return true; | |||
1335 | } | |||
1336 | #else | |||
1337 | bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; } | |||
1338 | #endif | |||
1339 | ||||
1340 | std::string sys::getProcessTriple() { | |||
1341 | Triple PT(Triple::normalize(LLVM_HOST_TRIPLE"x86_64-pc-linux-gnu")); | |||
1342 | ||||
1343 | if (sizeof(void *) == 8 && PT.isArch32Bit()) | |||
1344 | PT = PT.get64BitArchVariant(); | |||
1345 | if (sizeof(void *) == 4 && PT.isArch64Bit()) | |||
1346 | PT = PT.get32BitArchVariant(); | |||
1347 | ||||
1348 | return PT.str(); | |||
1349 | } |