Line data Source code
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/Support/TargetParser.h"
16 : #include "llvm/ADT/SmallSet.h"
17 : #include "llvm/ADT/SmallVector.h"
18 : #include "llvm/ADT/StringRef.h"
19 : #include "llvm/ADT/StringSwitch.h"
20 : #include "llvm/ADT/Triple.h"
21 : #include "llvm/Config/llvm-config.h"
22 : #include "llvm/Support/Debug.h"
23 : #include "llvm/Support/FileSystem.h"
24 : #include "llvm/Support/MemoryBuffer.h"
25 : #include "llvm/Support/raw_ostream.h"
26 : #include <assert.h>
27 : #include <string.h>
28 :
29 : // Include the platform-specific parts of this class.
30 : #ifdef LLVM_ON_UNIX
31 : #include "Unix/Host.inc"
32 : #endif
33 : #ifdef _WIN32
34 : #include "Windows/Host.inc"
35 : #endif
36 : #ifdef _MSC_VER
37 : #include <intrin.h>
38 : #endif
39 : #if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
40 : #include <mach/host_info.h>
41 : #include <mach/mach.h>
42 : #include <mach/mach_host.h>
43 : #include <mach/machine.h>
44 : #endif
45 :
46 : #define DEBUG_TYPE "host-detection"
47 :
48 : //===----------------------------------------------------------------------===//
49 : //
50 : // Implementations of the CPU detection routines
51 : //
52 : //===----------------------------------------------------------------------===//
53 :
54 : using namespace llvm;
55 :
56 : static std::unique_ptr<llvm::MemoryBuffer>
57 : LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent() {
58 : llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
59 : llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
60 : if (std::error_code EC = Text.getError()) {
61 : llvm::errs() << "Can't read "
62 : << "/proc/cpuinfo: " << EC.message() << "\n";
63 : return nullptr;
64 : }
65 : return std::move(*Text);
66 : }
67 :
68 0 : StringRef sys::detail::getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent) {
69 : // Access to the Processor Version Register (PVR) on PowerPC is privileged,
70 : // and so we must use an operating-system interface to determine the current
71 : // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
72 : const char *generic = "generic";
73 :
74 : // The cpu line is second (after the 'processor: 0' line), so if this
75 : // buffer is too small then something has changed (or is wrong).
76 : StringRef::const_iterator CPUInfoStart = ProcCpuinfoContent.begin();
77 0 : StringRef::const_iterator CPUInfoEnd = ProcCpuinfoContent.end();
78 :
79 : StringRef::const_iterator CIP = CPUInfoStart;
80 :
81 : StringRef::const_iterator CPUStart = 0;
82 : size_t CPULen = 0;
83 :
84 : // We need to find the first line which starts with cpu, spaces, and a colon.
85 : // After the colon, there may be some additional spaces and then the cpu type.
86 0 : while (CIP < CPUInfoEnd && CPUStart == 0) {
87 0 : if (CIP < CPUInfoEnd && *CIP == '\n')
88 0 : ++CIP;
89 :
90 0 : if (CIP < CPUInfoEnd && *CIP == 'c') {
91 0 : ++CIP;
92 0 : if (CIP < CPUInfoEnd && *CIP == 'p') {
93 0 : ++CIP;
94 0 : if (CIP < CPUInfoEnd && *CIP == 'u') {
95 0 : ++CIP;
96 0 : while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
97 0 : ++CIP;
98 :
99 0 : if (CIP < CPUInfoEnd && *CIP == ':') {
100 0 : ++CIP;
101 0 : while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
102 0 : ++CIP;
103 :
104 0 : if (CIP < CPUInfoEnd) {
105 : CPUStart = CIP;
106 0 : while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
107 0 : *CIP != ',' && *CIP != '\n'))
108 0 : ++CIP;
109 0 : CPULen = CIP - CPUStart;
110 : }
111 : }
112 : }
113 : }
114 : }
115 :
116 0 : if (CPUStart == 0)
117 0 : while (CIP < CPUInfoEnd && *CIP != '\n')
118 0 : ++CIP;
119 : }
120 :
121 0 : if (CPUStart == 0)
122 0 : return generic;
123 :
124 0 : return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
125 0 : .Case("604e", "604e")
126 0 : .Case("604", "604")
127 0 : .Case("7400", "7400")
128 0 : .Case("7410", "7400")
129 0 : .Case("7447", "7400")
130 0 : .Case("7455", "7450")
131 0 : .Case("G4", "g4")
132 0 : .Case("POWER4", "970")
133 0 : .Case("PPC970FX", "970")
134 0 : .Case("PPC970MP", "970")
135 0 : .Case("G5", "g5")
136 0 : .Case("POWER5", "g5")
137 0 : .Case("A2", "a2")
138 0 : .Case("POWER6", "pwr6")
139 0 : .Case("POWER7", "pwr7")
140 0 : .Case("POWER8", "pwr8")
141 0 : .Case("POWER8E", "pwr8")
142 0 : .Case("POWER8NVL", "pwr8")
143 0 : .Case("POWER9", "pwr9")
144 0 : .Default(generic);
145 : }
146 :
147 25 : StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) {
148 : // The cpuid register on arm is not accessible from user space. On Linux,
149 : // it is exposed through the /proc/cpuinfo file.
150 :
151 : // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line
152 : // in all cases.
153 : SmallVector<StringRef, 32> Lines;
154 25 : ProcCpuinfoContent.split(Lines, "\n");
155 :
156 : // Look for the CPU implementer line.
157 : StringRef Implementer;
158 : StringRef Hardware;
159 229 : for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
160 204 : if (Lines[I].startswith("CPU implementer"))
161 78 : Implementer = Lines[I].substr(15).ltrim("\t :");
162 : if (Lines[I].startswith("Hardware"))
163 4 : Hardware = Lines[I].substr(8).ltrim("\t :");
164 : }
165 :
166 : if (Implementer == "0x41") { // ARM Ltd.
167 : // MSM8992/8994 may give cpu part for the core that the kernel is running on,
168 : // which is undeterministic and wrong. Always return cortex-a53 for these SoC.
169 : if (Hardware.endswith("MSM8994") || Hardware.endswith("MSM8996"))
170 0 : return "cortex-a53";
171 :
172 :
173 : // Look for the CPU part line.
174 26 : for (unsigned I = 0, E = Lines.size(); I != E; ++I)
175 26 : if (Lines[I].startswith("CPU part"))
176 : // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
177 : // values correspond to the "Part number" in the CP15/c0 register. The
178 : // contents are specified in the various processor manuals.
179 8 : return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
180 : .Case("0x926", "arm926ej-s")
181 : .Case("0xb02", "mpcore")
182 : .Case("0xb36", "arm1136j-s")
183 : .Case("0xb56", "arm1156t2-s")
184 : .Case("0xb76", "arm1176jz-s")
185 : .Case("0xc08", "cortex-a8")
186 : .Case("0xc09", "cortex-a9")
187 : .Case("0xc0f", "cortex-a15")
188 : .Case("0xc20", "cortex-m0")
189 : .Case("0xc23", "cortex-m3")
190 : .Case("0xc24", "cortex-m4")
191 : .Case("0xd04", "cortex-a35")
192 : .Case("0xd03", "cortex-a53")
193 : .Case("0xd07", "cortex-a57")
194 : .Case("0xd08", "cortex-a72")
195 : .Case("0xd09", "cortex-a73")
196 4 : .Default("generic");
197 : }
198 :
199 : if (Implementer == "0x42" || Implementer == "0x43") { // Broadcom | Cavium.
200 80 : for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
201 80 : if (Lines[I].startswith("CPU part")) {
202 20 : return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
203 : .Case("0x516", "thunderx2t99")
204 : .Case("0x0516", "thunderx2t99")
205 : .Case("0xaf", "thunderx2t99")
206 : .Case("0x0af", "thunderx2t99")
207 : .Case("0xa1", "thunderxt88")
208 : .Case("0x0a1", "thunderxt88")
209 10 : .Default("generic");
210 : }
211 : }
212 : }
213 :
214 : if (Implementer == "0x51") // Qualcomm Technologies, Inc.
215 : // Look for the CPU part line.
216 12 : for (unsigned I = 0, E = Lines.size(); I != E; ++I)
217 12 : if (Lines[I].startswith("CPU part"))
218 : // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
219 : // values correspond to the "Part number" in the CP15/c0 register. The
220 : // contents are specified in the various processor manuals.
221 12 : return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
222 : .Case("0x06f", "krait") // APQ8064
223 : .Case("0x201", "kryo")
224 : .Case("0x205", "kryo")
225 : .Case("0x211", "kryo")
226 : .Case("0x800", "cortex-a73")
227 : .Case("0x801", "cortex-a73")
228 : .Case("0xc00", "falkor")
229 : .Case("0xc01", "saphira")
230 6 : .Default("generic");
231 :
232 : if (Implementer == "0x53") { // Samsung Electronics Co., Ltd.
233 : // The Exynos chips have a convoluted ID scheme that doesn't seem to follow
234 : // any predictive pattern across variants and parts.
235 3 : unsigned Variant = 0, Part = 0;
236 :
237 : // Look for the CPU variant line, whose value is a 1 digit hexadecimal
238 : // number, corresponding to the Variant bits in the CP15/C0 register.
239 45 : for (auto I : Lines)
240 : if (I.consume_front("CPU variant"))
241 6 : I.ltrim("\t :").getAsInteger(0, Variant);
242 :
243 : // Look for the CPU part line, whose value is a 3 digit hexadecimal
244 : // number, corresponding to the PartNum bits in the CP15/C0 register.
245 45 : for (auto I : Lines)
246 : if (I.consume_front("CPU part"))
247 6 : I.ltrim("\t :").getAsInteger(0, Part);
248 :
249 3 : unsigned Exynos = (Variant << 12) | Part;
250 3 : switch (Exynos) {
251 : default:
252 : // Default by falling through to Exynos M1.
253 : LLVM_FALLTHROUGH;
254 :
255 : case 0x1001:
256 2 : return "exynos-m1";
257 :
258 : case 0x4001:
259 1 : return "exynos-m2";
260 : }
261 : }
262 :
263 2 : return "generic";
264 : }
265 :
266 0 : StringRef sys::detail::getHostCPUNameForS390x(StringRef ProcCpuinfoContent) {
267 : // STIDP is a privileged operation, so use /proc/cpuinfo instead.
268 :
269 : // The "processor 0:" line comes after a fair amount of other information,
270 : // including a cache breakdown, but this should be plenty.
271 : SmallVector<StringRef, 32> Lines;
272 0 : ProcCpuinfoContent.split(Lines, "\n");
273 :
274 : // Look for the CPU features.
275 : SmallVector<StringRef, 32> CPUFeatures;
276 0 : for (unsigned I = 0, E = Lines.size(); I != E; ++I)
277 0 : if (Lines[I].startswith("features")) {
278 0 : size_t Pos = Lines[I].find(":");
279 0 : if (Pos != StringRef::npos) {
280 0 : Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
281 0 : break;
282 : }
283 : }
284 :
285 : // We need to check for the presence of vector support independently of
286 : // the machine type, since we may only use the vector register set when
287 : // supported by the kernel (and hypervisor).
288 : bool HaveVectorSupport = false;
289 0 : for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
290 0 : if (CPUFeatures[I] == "vx")
291 : HaveVectorSupport = true;
292 : }
293 :
294 : // Now check the processor machine type.
295 0 : for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
296 0 : if (Lines[I].startswith("processor ")) {
297 0 : size_t Pos = Lines[I].find("machine = ");
298 0 : if (Pos != StringRef::npos) {
299 0 : Pos += sizeof("machine = ") - 1;
300 : unsigned int Id;
301 0 : if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
302 0 : if (Id >= 3906 && HaveVectorSupport)
303 0 : return "z14";
304 0 : if (Id >= 2964 && HaveVectorSupport)
305 0 : return "z13";
306 0 : if (Id >= 2827)
307 0 : return "zEC12";
308 0 : if (Id >= 2817)
309 0 : return "z196";
310 : }
311 : }
312 : break;
313 : }
314 : }
315 :
316 0 : return "generic";
317 : }
318 :
319 0 : StringRef sys::detail::getHostCPUNameForBPF() {
320 : #if !defined(__linux__) || !defined(__x86_64__)
321 : return "generic";
322 : #else
323 0 : uint8_t insns[40] __attribute__ ((aligned (8))) =
324 : /* BPF_MOV64_IMM(BPF_REG_0, 0) */
325 : { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
326 : /* BPF_MOV64_IMM(BPF_REG_2, 1) */
327 : 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
328 : /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
329 : 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
330 : /* BPF_MOV64_IMM(BPF_REG_0, 1) */
331 : 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
332 : /* BPF_EXIT_INSN() */
333 : 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
334 :
335 : struct bpf_prog_load_attr {
336 : uint32_t prog_type;
337 : uint32_t insn_cnt;
338 : uint64_t insns;
339 : uint64_t license;
340 : uint32_t log_level;
341 : uint32_t log_size;
342 : uint64_t log_buf;
343 : uint32_t kern_version;
344 : uint32_t prog_flags;
345 0 : } attr = {};
346 0 : attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
347 0 : attr.insn_cnt = 5;
348 0 : attr.insns = (uint64_t)insns;
349 0 : attr.license = (uint64_t)"DUMMY";
350 :
351 0 : int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr));
352 0 : if (fd >= 0) {
353 0 : close(fd);
354 0 : return "v2";
355 : }
356 0 : return "v1";
357 : #endif
358 : }
359 :
360 : #if defined(__i386__) || defined(_M_IX86) || \
361 : defined(__x86_64__) || defined(_M_X64)
362 :
363 : enum VendorSignatures {
364 : SIG_INTEL = 0x756e6547 /* Genu */,
365 : SIG_AMD = 0x68747541 /* Auth */
366 : };
367 :
368 : // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
369 : // Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
370 : // support. Consequently, for i386, the presence of CPUID is checked first
371 : // via the corresponding eflags bit.
372 : // Removal of cpuid.h header motivated by PR30384
373 : // Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
374 : // or test-suite, but are used in external projects e.g. libstdcxx
375 : static bool isCpuIdSupported() {
376 : #if defined(__GNUC__) || defined(__clang__)
377 : #if defined(__i386__)
378 : int __cpuid_supported;
379 : __asm__(" pushfl\n"
380 : " popl %%eax\n"
381 : " movl %%eax,%%ecx\n"
382 : " xorl $0x00200000,%%eax\n"
383 : " pushl %%eax\n"
384 : " popfl\n"
385 : " pushfl\n"
386 : " popl %%eax\n"
387 : " movl $0,%0\n"
388 : " cmpl %%eax,%%ecx\n"
389 : " je 1f\n"
390 : " movl $1,%0\n"
391 : "1:"
392 : : "=r"(__cpuid_supported)
393 : :
394 : : "eax", "ecx");
395 : if (!__cpuid_supported)
396 : return false;
397 : #endif
398 : return true;
399 : #endif
400 : return true;
401 : }
402 :
403 : /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
404 : /// the specified arguments. If we can't run cpuid on the host, return true.
405 : static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
406 : unsigned *rECX, unsigned *rEDX) {
407 : #if defined(__GNUC__) || defined(__clang__)
408 : #if defined(__x86_64__)
409 : // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
410 : // FIXME: should we save this for Clang?
411 : __asm__("movq\t%%rbx, %%rsi\n\t"
412 : "cpuid\n\t"
413 : "xchgq\t%%rbx, %%rsi\n\t"
414 : : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
415 156 : : "a"(value));
416 : return false;
417 : #elif defined(__i386__)
418 : __asm__("movl\t%%ebx, %%esi\n\t"
419 : "cpuid\n\t"
420 : "xchgl\t%%ebx, %%esi\n\t"
421 : : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
422 : : "a"(value));
423 : return false;
424 : #else
425 : return true;
426 : #endif
427 : #elif defined(_MSC_VER)
428 : // The MSVC intrinsic is portable across x86 and x64.
429 : int registers[4];
430 : __cpuid(registers, value);
431 : *rEAX = registers[0];
432 : *rEBX = registers[1];
433 : *rECX = registers[2];
434 : *rEDX = registers[3];
435 : return false;
436 : #else
437 : return true;
438 : #endif
439 : }
440 :
441 : /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
442 : /// the 4 values in the specified arguments. If we can't run cpuid on the host,
443 : /// return true.
444 : static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
445 : unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
446 : unsigned *rEDX) {
447 : #if defined(__GNUC__) || defined(__clang__)
448 : #if defined(__x86_64__)
449 : // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
450 : // FIXME: should we save this for Clang?
451 : __asm__("movq\t%%rbx, %%rsi\n\t"
452 : "cpuid\n\t"
453 : "xchgq\t%%rbx, %%rsi\n\t"
454 : : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
455 39 : : "a"(value), "c"(subleaf));
456 : return false;
457 : #elif defined(__i386__)
458 : __asm__("movl\t%%ebx, %%esi\n\t"
459 : "cpuid\n\t"
460 : "xchgl\t%%ebx, %%esi\n\t"
461 : : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
462 : : "a"(value), "c"(subleaf));
463 : return false;
464 : #else
465 : return true;
466 : #endif
467 : #elif defined(_MSC_VER)
468 : int registers[4];
469 : __cpuidex(registers, value, subleaf);
470 : *rEAX = registers[0];
471 : *rEBX = registers[1];
472 : *rECX = registers[2];
473 : *rEDX = registers[3];
474 : return false;
475 : #else
476 : return true;
477 : #endif
478 : }
479 :
480 : // Read control register 0 (XCR0). Used to detect features such as AVX.
481 : static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
482 : #if defined(__GNUC__) || defined(__clang__)
483 : // Check xgetbv; this uses a .byte sequence instead of the instruction
484 : // directly because older assemblers do not include support for xgetbv and
485 : // there is no easy way to conditionally compile based on the assembler used.
486 0 : __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
487 : return false;
488 : #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
489 : unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
490 : *rEAX = Result;
491 : *rEDX = Result >> 32;
492 : return false;
493 : #else
494 : return true;
495 : #endif
496 : }
497 :
498 39 : static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
499 : unsigned *Model) {
500 39 : *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
501 39 : *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
502 39 : if (*Family == 6 || *Family == 0xf) {
503 39 : if (*Family == 0xf)
504 : // Examine extended family ID if family ID is F.
505 0 : *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
506 : // Examine extended model ID if family ID is 6 or F.
507 39 : *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
508 : }
509 39 : }
510 :
511 : static void
512 39 : getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
513 : unsigned Brand_id, unsigned Features,
514 : unsigned Features2, unsigned *Type,
515 : unsigned *Subtype) {
516 39 : if (Brand_id != 0)
517 : return;
518 39 : switch (Family) {
519 0 : case 3:
520 0 : *Type = X86::INTEL_i386;
521 0 : break;
522 0 : case 4:
523 0 : *Type = X86::INTEL_i486;
524 0 : break;
525 0 : case 5:
526 0 : if (Features & (1 << X86::FEATURE_MMX)) {
527 0 : *Type = X86::INTEL_PENTIUM_MMX;
528 0 : break;
529 : }
530 0 : *Type = X86::INTEL_PENTIUM;
531 0 : break;
532 39 : case 6:
533 : switch (Model) {
534 0 : case 0x01: // Pentium Pro processor
535 0 : *Type = X86::INTEL_PENTIUM_PRO;
536 0 : break;
537 0 : case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
538 : // model 03
539 : case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
540 : // model 05, and Intel Celeron processor, model 05
541 : case 0x06: // Celeron processor, model 06
542 0 : *Type = X86::INTEL_PENTIUM_II;
543 0 : break;
544 0 : case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
545 : // processor, model 07
546 : case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
547 : // model 08, and Celeron processor, model 08
548 : case 0x0a: // Pentium III Xeon processor, model 0Ah
549 : case 0x0b: // Pentium III processor, model 0Bh
550 0 : *Type = X86::INTEL_PENTIUM_III;
551 0 : break;
552 0 : case 0x09: // Intel Pentium M processor, Intel Celeron M processor model 09.
553 : case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
554 : // 0Dh. All processors are manufactured using the 90 nm process.
555 : case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
556 : // Integrated Processor with Intel QuickAssist Technology
557 0 : *Type = X86::INTEL_PENTIUM_M;
558 0 : break;
559 0 : case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
560 : // 0Eh. All processors are manufactured using the 65 nm process.
561 0 : *Type = X86::INTEL_CORE_DUO;
562 0 : break; // yonah
563 39 : case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
564 : // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
565 : // mobile processor, Intel Core 2 Extreme processor, Intel
566 : // Pentium Dual-Core processor, Intel Xeon processor, model
567 : // 0Fh. All processors are manufactured using the 65 nm process.
568 : case 0x16: // Intel Celeron processor model 16h. All processors are
569 : // manufactured using the 65 nm process
570 39 : *Type = X86::INTEL_CORE2; // "core2"
571 39 : *Subtype = X86::INTEL_CORE2_65;
572 39 : break;
573 0 : case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
574 : // 17h. All processors are manufactured using the 45 nm process.
575 : //
576 : // 45nm: Penryn , Wolfdale, Yorkfield (XE)
577 : case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
578 : // the 45 nm process.
579 0 : *Type = X86::INTEL_CORE2; // "penryn"
580 0 : *Subtype = X86::INTEL_CORE2_45;
581 0 : break;
582 0 : case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
583 : // processors are manufactured using the 45 nm process.
584 : case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
585 : // As found in a Summer 2010 model iMac.
586 : case 0x1f:
587 : case 0x2e: // Nehalem EX
588 0 : *Type = X86::INTEL_COREI7; // "nehalem"
589 0 : *Subtype = X86::INTEL_COREI7_NEHALEM;
590 0 : break;
591 0 : case 0x25: // Intel Core i7, laptop version.
592 : case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
593 : // processors are manufactured using the 32 nm process.
594 : case 0x2f: // Westmere EX
595 0 : *Type = X86::INTEL_COREI7; // "westmere"
596 0 : *Subtype = X86::INTEL_COREI7_WESTMERE;
597 0 : break;
598 0 : case 0x2a: // Intel Core i7 processor. All processors are manufactured
599 : // using the 32 nm process.
600 : case 0x2d:
601 0 : *Type = X86::INTEL_COREI7; //"sandybridge"
602 0 : *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
603 0 : break;
604 0 : case 0x3a:
605 : case 0x3e: // Ivy Bridge EP
606 0 : *Type = X86::INTEL_COREI7; // "ivybridge"
607 0 : *Subtype = X86::INTEL_COREI7_IVYBRIDGE;
608 0 : break;
609 :
610 : // Haswell:
611 0 : case 0x3c:
612 : case 0x3f:
613 : case 0x45:
614 : case 0x46:
615 0 : *Type = X86::INTEL_COREI7; // "haswell"
616 0 : *Subtype = X86::INTEL_COREI7_HASWELL;
617 0 : break;
618 :
619 : // Broadwell:
620 0 : case 0x3d:
621 : case 0x47:
622 : case 0x4f:
623 : case 0x56:
624 0 : *Type = X86::INTEL_COREI7; // "broadwell"
625 0 : *Subtype = X86::INTEL_COREI7_BROADWELL;
626 0 : break;
627 :
628 : // Skylake:
629 0 : case 0x4e: // Skylake mobile
630 : case 0x5e: // Skylake desktop
631 : case 0x8e: // Kaby Lake mobile
632 : case 0x9e: // Kaby Lake desktop
633 0 : *Type = X86::INTEL_COREI7; // "skylake"
634 0 : *Subtype = X86::INTEL_COREI7_SKYLAKE;
635 0 : break;
636 :
637 : // Skylake Xeon:
638 0 : case 0x55:
639 0 : *Type = X86::INTEL_COREI7;
640 0 : *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512"
641 0 : break;
642 :
643 : // Cannonlake:
644 0 : case 0x66:
645 0 : *Type = X86::INTEL_COREI7;
646 0 : *Subtype = X86::INTEL_COREI7_CANNONLAKE; // "cannonlake"
647 0 : break;
648 :
649 0 : case 0x1c: // Most 45 nm Intel Atom processors
650 : case 0x26: // 45 nm Atom Lincroft
651 : case 0x27: // 32 nm Atom Medfield
652 : case 0x35: // 32 nm Atom Midview
653 : case 0x36: // 32 nm Atom Midview
654 0 : *Type = X86::INTEL_BONNELL;
655 0 : break; // "bonnell"
656 :
657 : // Atom Silvermont codes from the Intel software optimization guide.
658 0 : case 0x37:
659 : case 0x4a:
660 : case 0x4d:
661 : case 0x5a:
662 : case 0x5d:
663 : case 0x4c: // really airmont
664 0 : *Type = X86::INTEL_SILVERMONT;
665 0 : break; // "silvermont"
666 : // Goldmont:
667 0 : case 0x5c: // Apollo Lake
668 : case 0x5f: // Denverton
669 0 : *Type = X86::INTEL_GOLDMONT;
670 0 : break; // "goldmont"
671 0 : case 0x7a:
672 0 : *Type = X86::INTEL_GOLDMONT_PLUS;
673 0 : break;
674 0 : case 0x57:
675 0 : *Type = X86::INTEL_KNL; // knl
676 0 : break;
677 0 : case 0x85:
678 0 : *Type = X86::INTEL_KNM; // knm
679 0 : break;
680 :
681 0 : default: // Unknown family 6 CPU, try to guess.
682 0 : if (Features & (1 << X86::FEATURE_AVX512VBMI)) {
683 0 : *Type = X86::INTEL_COREI7;
684 0 : *Subtype = X86::INTEL_COREI7_CANNONLAKE;
685 0 : break;
686 : }
687 :
688 0 : if (Features & (1 << X86::FEATURE_AVX512VL)) {
689 0 : *Type = X86::INTEL_COREI7;
690 0 : *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
691 0 : break;
692 : }
693 :
694 0 : if (Features & (1 << X86::FEATURE_AVX512ER)) {
695 0 : *Type = X86::INTEL_KNL; // knl
696 0 : break;
697 : }
698 :
699 0 : if (Features2 & (1 << (X86::FEATURE_CLFLUSHOPT - 32))) {
700 0 : if (Features2 & (1 << (X86::FEATURE_SHA - 32))) {
701 0 : *Type = X86::INTEL_GOLDMONT;
702 : } else {
703 0 : *Type = X86::INTEL_COREI7;
704 0 : *Subtype = X86::INTEL_COREI7_SKYLAKE;
705 : }
706 : break;
707 : }
708 0 : if (Features2 & (1 << (X86::FEATURE_ADX - 32))) {
709 0 : *Type = X86::INTEL_COREI7;
710 0 : *Subtype = X86::INTEL_COREI7_BROADWELL;
711 0 : break;
712 : }
713 0 : if (Features & (1 << X86::FEATURE_AVX2)) {
714 0 : *Type = X86::INTEL_COREI7;
715 0 : *Subtype = X86::INTEL_COREI7_HASWELL;
716 0 : break;
717 : }
718 0 : if (Features & (1 << X86::FEATURE_AVX)) {
719 0 : *Type = X86::INTEL_COREI7;
720 0 : *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
721 0 : break;
722 : }
723 0 : if (Features & (1 << X86::FEATURE_SSE4_2)) {
724 0 : if (Features2 & (1 << (X86::FEATURE_MOVBE - 32))) {
725 0 : *Type = X86::INTEL_SILVERMONT;
726 : } else {
727 0 : *Type = X86::INTEL_COREI7;
728 0 : *Subtype = X86::INTEL_COREI7_NEHALEM;
729 : }
730 : break;
731 : }
732 0 : if (Features & (1 << X86::FEATURE_SSE4_1)) {
733 0 : *Type = X86::INTEL_CORE2; // "penryn"
734 0 : *Subtype = X86::INTEL_CORE2_45;
735 0 : break;
736 : }
737 0 : if (Features & (1 << X86::FEATURE_SSSE3)) {
738 0 : if (Features2 & (1 << (X86::FEATURE_MOVBE - 32))) {
739 0 : *Type = X86::INTEL_BONNELL; // "bonnell"
740 : } else {
741 0 : *Type = X86::INTEL_CORE2; // "core2"
742 0 : *Subtype = X86::INTEL_CORE2_65;
743 : }
744 : break;
745 : }
746 0 : if (Features2 & (1 << (X86::FEATURE_EM64T - 32))) {
747 0 : *Type = X86::INTEL_CORE2; // "core2"
748 0 : *Subtype = X86::INTEL_CORE2_65;
749 0 : break;
750 : }
751 0 : if (Features & (1 << X86::FEATURE_SSE3)) {
752 0 : *Type = X86::INTEL_CORE_DUO;
753 0 : break;
754 : }
755 0 : if (Features & (1 << X86::FEATURE_SSE2)) {
756 0 : *Type = X86::INTEL_PENTIUM_M;
757 0 : break;
758 : }
759 0 : if (Features & (1 << X86::FEATURE_SSE)) {
760 0 : *Type = X86::INTEL_PENTIUM_III;
761 0 : break;
762 : }
763 0 : if (Features & (1 << X86::FEATURE_MMX)) {
764 0 : *Type = X86::INTEL_PENTIUM_II;
765 0 : break;
766 : }
767 0 : *Type = X86::INTEL_PENTIUM_PRO;
768 0 : break;
769 : }
770 : break;
771 0 : case 15: {
772 0 : if (Features2 & (1 << (X86::FEATURE_EM64T - 32))) {
773 0 : *Type = X86::INTEL_NOCONA;
774 0 : break;
775 : }
776 0 : if (Features & (1 << X86::FEATURE_SSE3)) {
777 0 : *Type = X86::INTEL_PRESCOTT;
778 0 : break;
779 : }
780 0 : *Type = X86::INTEL_PENTIUM_IV;
781 0 : break;
782 : }
783 : default:
784 : break; /*"generic"*/
785 : }
786 : }
787 :
788 0 : static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
789 : unsigned Features, unsigned *Type,
790 : unsigned *Subtype) {
791 : // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
792 : // appears to be no way to generate the wide variety of AMD-specific targets
793 : // from the information returned from CPUID.
794 0 : switch (Family) {
795 0 : case 4:
796 0 : *Type = X86::AMD_i486;
797 0 : break;
798 0 : case 5:
799 0 : *Type = X86::AMDPENTIUM;
800 : switch (Model) {
801 0 : case 6:
802 : case 7:
803 0 : *Subtype = X86::AMDPENTIUM_K6;
804 0 : break; // "k6"
805 0 : case 8:
806 0 : *Subtype = X86::AMDPENTIUM_K62;
807 0 : break; // "k6-2"
808 0 : case 9:
809 : case 13:
810 0 : *Subtype = X86::AMDPENTIUM_K63;
811 0 : break; // "k6-3"
812 0 : case 10:
813 0 : *Subtype = X86::AMDPENTIUM_GEODE;
814 0 : break; // "geode"
815 : }
816 : break;
817 0 : case 6:
818 0 : if (Features & (1 << X86::FEATURE_SSE)) {
819 0 : *Type = X86::AMD_ATHLON_XP;
820 0 : break; // "athlon-xp"
821 : }
822 0 : *Type = X86::AMD_ATHLON;
823 0 : break; // "athlon"
824 0 : case 15:
825 0 : if (Features & (1 << X86::FEATURE_SSE3)) {
826 0 : *Type = X86::AMD_K8SSE3;
827 0 : break; // "k8-sse3"
828 : }
829 0 : *Type = X86::AMD_K8;
830 0 : break; // "k8"
831 0 : case 16:
832 0 : *Type = X86::AMDFAM10H; // "amdfam10"
833 : switch (Model) {
834 0 : case 2:
835 0 : *Subtype = X86::AMDFAM10H_BARCELONA;
836 0 : break;
837 0 : case 4:
838 0 : *Subtype = X86::AMDFAM10H_SHANGHAI;
839 0 : break;
840 0 : case 8:
841 0 : *Subtype = X86::AMDFAM10H_ISTANBUL;
842 0 : break;
843 : }
844 : break;
845 0 : case 20:
846 0 : *Type = X86::AMD_BTVER1;
847 0 : break; // "btver1";
848 0 : case 21:
849 0 : *Type = X86::AMDFAM15H;
850 0 : if (Model >= 0x60 && Model <= 0x7f) {
851 0 : *Subtype = X86::AMDFAM15H_BDVER4;
852 0 : break; // "bdver4"; 60h-7Fh: Excavator
853 : }
854 0 : if (Model >= 0x30 && Model <= 0x3f) {
855 0 : *Subtype = X86::AMDFAM15H_BDVER3;
856 0 : break; // "bdver3"; 30h-3Fh: Steamroller
857 : }
858 0 : if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) {
859 0 : *Subtype = X86::AMDFAM15H_BDVER2;
860 0 : break; // "bdver2"; 02h, 10h-1Fh: Piledriver
861 : }
862 0 : if (Model <= 0x0f) {
863 0 : *Subtype = X86::AMDFAM15H_BDVER1;
864 0 : break; // "bdver1"; 00h-0Fh: Bulldozer
865 : }
866 : break;
867 0 : case 22:
868 0 : *Type = X86::AMD_BTVER2;
869 0 : break; // "btver2"
870 0 : case 23:
871 0 : *Type = X86::AMDFAM17H;
872 0 : *Subtype = X86::AMDFAM17H_ZNVER1;
873 0 : break;
874 : default:
875 : break; // "generic"
876 : }
877 0 : }
878 :
879 39 : static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
880 : unsigned *FeaturesOut,
881 : unsigned *Features2Out) {
882 : unsigned Features = 0;
883 : unsigned Features2 = 0;
884 : unsigned EAX, EBX;
885 :
886 39 : if ((EDX >> 15) & 1)
887 : Features |= 1 << X86::FEATURE_CMOV;
888 39 : if ((EDX >> 23) & 1)
889 39 : Features |= 1 << X86::FEATURE_MMX;
890 39 : if ((EDX >> 25) & 1)
891 39 : Features |= 1 << X86::FEATURE_SSE;
892 39 : if ((EDX >> 26) & 1)
893 39 : Features |= 1 << X86::FEATURE_SSE2;
894 :
895 39 : if ((ECX >> 0) & 1)
896 39 : Features |= 1 << X86::FEATURE_SSE3;
897 39 : if ((ECX >> 1) & 1)
898 0 : Features |= 1 << X86::FEATURE_PCLMUL;
899 39 : if ((ECX >> 9) & 1)
900 39 : Features |= 1 << X86::FEATURE_SSSE3;
901 39 : if ((ECX >> 12) & 1)
902 0 : Features |= 1 << X86::FEATURE_FMA;
903 39 : if ((ECX >> 19) & 1)
904 0 : Features |= 1 << X86::FEATURE_SSE4_1;
905 39 : if ((ECX >> 20) & 1)
906 0 : Features |= 1 << X86::FEATURE_SSE4_2;
907 39 : if ((ECX >> 23) & 1)
908 0 : Features |= 1 << X86::FEATURE_POPCNT;
909 39 : if ((ECX >> 25) & 1)
910 0 : Features |= 1 << X86::FEATURE_AES;
911 :
912 39 : if ((ECX >> 22) & 1)
913 : Features2 |= 1 << (X86::FEATURE_MOVBE - 32);
914 :
915 : // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
916 : // indicates that the AVX registers will be saved and restored on context
917 : // switch, then we have full AVX support.
918 : const unsigned AVXBits = (1 << 27) | (1 << 28);
919 39 : bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
920 0 : ((EAX & 0x6) == 0x6);
921 39 : bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
922 :
923 39 : if (HasAVX)
924 0 : Features |= 1 << X86::FEATURE_AVX;
925 :
926 : bool HasLeaf7 =
927 39 : MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
928 :
929 39 : if (HasLeaf7 && ((EBX >> 3) & 1))
930 0 : Features |= 1 << X86::FEATURE_BMI;
931 39 : if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
932 0 : Features |= 1 << X86::FEATURE_AVX2;
933 39 : if (HasLeaf7 && ((EBX >> 9) & 1))
934 0 : Features |= 1 << X86::FEATURE_BMI2;
935 39 : if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
936 0 : Features |= 1 << X86::FEATURE_AVX512F;
937 39 : if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
938 0 : Features |= 1 << X86::FEATURE_AVX512DQ;
939 39 : if (HasLeaf7 && ((EBX >> 19) & 1))
940 0 : Features2 |= 1 << (X86::FEATURE_ADX - 32);
941 39 : if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
942 0 : Features |= 1 << X86::FEATURE_AVX512IFMA;
943 39 : if (HasLeaf7 && ((EBX >> 23) & 1))
944 0 : Features2 |= 1 << (X86::FEATURE_CLFLUSHOPT - 32);
945 39 : if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
946 0 : Features |= 1 << X86::FEATURE_AVX512PF;
947 39 : if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
948 0 : Features |= 1 << X86::FEATURE_AVX512ER;
949 39 : if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
950 0 : Features |= 1 << X86::FEATURE_AVX512CD;
951 39 : if (HasLeaf7 && ((EBX >> 29) & 1))
952 0 : Features2 |= 1 << (X86::FEATURE_SHA - 32);
953 39 : if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
954 0 : Features |= 1 << X86::FEATURE_AVX512BW;
955 39 : if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
956 0 : Features |= 1 << X86::FEATURE_AVX512VL;
957 :
958 39 : if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
959 0 : Features |= 1 << X86::FEATURE_AVX512VBMI;
960 39 : if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
961 0 : Features |= 1 << X86::FEATURE_AVX512VPOPCNTDQ;
962 :
963 39 : if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
964 0 : Features |= 1 << X86::FEATURE_AVX5124VNNIW;
965 39 : if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
966 0 : Features |= 1 << X86::FEATURE_AVX5124FMAPS;
967 :
968 : unsigned MaxExtLevel;
969 : getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
970 :
971 39 : bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
972 : !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
973 39 : if (HasExtLeaf1 && ((ECX >> 6) & 1))
974 0 : Features |= 1 << X86::FEATURE_SSE4_A;
975 39 : if (HasExtLeaf1 && ((ECX >> 11) & 1))
976 0 : Features |= 1 << X86::FEATURE_XOP;
977 39 : if (HasExtLeaf1 && ((ECX >> 16) & 1))
978 0 : Features |= 1 << X86::FEATURE_FMA4;
979 :
980 39 : if (HasExtLeaf1 && ((EDX >> 29) & 1))
981 39 : Features2 |= 1 << (X86::FEATURE_EM64T - 32);
982 :
983 39 : *FeaturesOut = Features;
984 39 : *Features2Out = Features2;
985 39 : }
986 :
987 39 : StringRef sys::getHostCPUName() {
988 : unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
989 : unsigned MaxLeaf, Vendor;
990 :
991 : #if defined(__GNUC__) || defined(__clang__)
992 : //FIXME: include cpuid.h from clang or copy __get_cpuid_max here
993 : // and simplify it to not invoke __cpuid (like cpu_model.c in
994 : // compiler-rt/lib/builtins/cpu_model.c?
995 : // Opting for the second option.
996 : if(!isCpuIdSupported())
997 : return "generic";
998 : #endif
999 39 : if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1)
1000 0 : return "generic";
1001 : getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
1002 :
1003 39 : unsigned Brand_id = EBX & 0xff;
1004 39 : unsigned Family = 0, Model = 0;
1005 39 : unsigned Features = 0, Features2 = 0;
1006 39 : detectX86FamilyModel(EAX, &Family, &Model);
1007 39 : getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2);
1008 :
1009 39 : unsigned Type = 0;
1010 39 : unsigned Subtype = 0;
1011 :
1012 39 : if (Vendor == SIG_INTEL) {
1013 39 : getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features,
1014 : Features2, &Type, &Subtype);
1015 0 : } else if (Vendor == SIG_AMD) {
1016 0 : getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
1017 : }
1018 :
1019 : // Check subtypes first since those are more specific.
1020 : #define X86_CPU_SUBTYPE(ARCHNAME, ENUM) \
1021 : if (Subtype == X86::ENUM) \
1022 : return ARCHNAME;
1023 : #include "llvm/Support/X86TargetParser.def"
1024 :
1025 : // Now check types.
1026 : #define X86_CPU_TYPE(ARCHNAME, ENUM) \
1027 : if (Type == X86::ENUM) \
1028 : return ARCHNAME;
1029 : #include "llvm/Support/X86TargetParser.def"
1030 :
1031 0 : return "generic";
1032 : }
1033 :
1034 : #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
1035 : StringRef sys::getHostCPUName() {
1036 : host_basic_info_data_t hostInfo;
1037 : mach_msg_type_number_t infoCount;
1038 :
1039 : infoCount = HOST_BASIC_INFO_COUNT;
1040 : mach_port_t hostPort = mach_host_self();
1041 : host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1042 : &infoCount);
1043 : mach_port_deallocate(mach_task_self(), hostPort);
1044 :
1045 : if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
1046 : return "generic";
1047 :
1048 : switch (hostInfo.cpu_subtype) {
1049 : case CPU_SUBTYPE_POWERPC_601:
1050 : return "601";
1051 : case CPU_SUBTYPE_POWERPC_602:
1052 : return "602";
1053 : case CPU_SUBTYPE_POWERPC_603:
1054 : return "603";
1055 : case CPU_SUBTYPE_POWERPC_603e:
1056 : return "603e";
1057 : case CPU_SUBTYPE_POWERPC_603ev:
1058 : return "603ev";
1059 : case CPU_SUBTYPE_POWERPC_604:
1060 : return "604";
1061 : case CPU_SUBTYPE_POWERPC_604e:
1062 : return "604e";
1063 : case CPU_SUBTYPE_POWERPC_620:
1064 : return "620";
1065 : case CPU_SUBTYPE_POWERPC_750:
1066 : return "750";
1067 : case CPU_SUBTYPE_POWERPC_7400:
1068 : return "7400";
1069 : case CPU_SUBTYPE_POWERPC_7450:
1070 : return "7450";
1071 : case CPU_SUBTYPE_POWERPC_970:
1072 : return "970";
1073 : default:;
1074 : }
1075 :
1076 : return "generic";
1077 : }
1078 : #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
1079 : StringRef sys::getHostCPUName() {
1080 : std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1081 : StringRef Content = P ? P->getBuffer() : "";
1082 : return detail::getHostCPUNameForPowerPC(Content);
1083 : }
1084 : #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1085 : StringRef sys::getHostCPUName() {
1086 : std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1087 : StringRef Content = P ? P->getBuffer() : "";
1088 : return detail::getHostCPUNameForARM(Content);
1089 : }
1090 : #elif defined(__linux__) && defined(__s390x__)
1091 : StringRef sys::getHostCPUName() {
1092 : std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1093 : StringRef Content = P ? P->getBuffer() : "";
1094 : return detail::getHostCPUNameForS390x(Content);
1095 : }
1096 : #else
1097 : StringRef sys::getHostCPUName() { return "generic"; }
1098 : #endif
1099 :
1100 : #if defined(__linux__) && defined(__x86_64__)
1101 : // On Linux, the number of physical cores can be computed from /proc/cpuinfo,
1102 : // using the number of unique physical/core id pairs. The following
1103 : // implementation reads the /proc/cpuinfo format on an x86_64 system.
1104 113936 : static int computeHostNumPhysicalCores() {
1105 : // Read /proc/cpuinfo as a stream (until EOF reached). It cannot be
1106 : // mmapped because it appears to have 0 size.
1107 : llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
1108 113936 : llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
1109 113936 : if (std::error_code EC = Text.getError()) {
1110 0 : llvm::errs() << "Can't read "
1111 0 : << "/proc/cpuinfo: " << EC.message() << "\n";
1112 : return -1;
1113 : }
1114 : SmallVector<StringRef, 8> strs;
1115 227872 : (*Text)->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
1116 : /*KeepEmpty=*/false);
1117 : int CurPhysicalId = -1;
1118 : int CurCoreId = -1;
1119 113936 : SmallSet<std::pair<int, int>, 32> UniqueItems;
1120 23812624 : for (auto &Line : strs) {
1121 23698688 : Line = Line.trim();
1122 : if (!Line.startswith("physical id") && !Line.startswith("core id"))
1123 21875712 : continue;
1124 1822976 : std::pair<StringRef, StringRef> Data = Line.split(':');
1125 1822976 : auto Name = Data.first.trim();
1126 1822976 : auto Val = Data.second.trim();
1127 : if (Name == "physical id") {
1128 : assert(CurPhysicalId == -1 &&
1129 : "Expected a core id before seeing another physical id");
1130 911488 : Val.getAsInteger(10, CurPhysicalId);
1131 : }
1132 : if (Name == "core id") {
1133 : assert(CurCoreId == -1 &&
1134 : "Expected a physical id before seeing another core id");
1135 911488 : Val.getAsInteger(10, CurCoreId);
1136 : }
1137 1822976 : if (CurPhysicalId != -1 && CurCoreId != -1) {
1138 911488 : UniqueItems.insert(std::make_pair(CurPhysicalId, CurCoreId));
1139 : CurPhysicalId = -1;
1140 : CurCoreId = -1;
1141 : }
1142 : }
1143 113936 : return UniqueItems.size();
1144 : }
1145 : #elif defined(__APPLE__) && defined(__x86_64__)
1146 : #include <sys/param.h>
1147 : #include <sys/sysctl.h>
1148 :
1149 : // Gets the number of *physical cores* on the machine.
1150 : static int computeHostNumPhysicalCores() {
1151 : uint32_t count;
1152 : size_t len = sizeof(count);
1153 : sysctlbyname("hw.physicalcpu", &count, &len, NULL, 0);
1154 : if (count < 1) {
1155 : int nm[2];
1156 : nm[0] = CTL_HW;
1157 : nm[1] = HW_AVAILCPU;
1158 : sysctl(nm, 2, &count, &len, NULL, 0);
1159 : if (count < 1)
1160 : return -1;
1161 : }
1162 : return count;
1163 : }
1164 : #else
1165 : // On other systems, return -1 to indicate unknown.
1166 : static int computeHostNumPhysicalCores() { return -1; }
1167 : #endif
1168 :
1169 114484 : int sys::getHostNumPhysicalCores() {
1170 114484 : static int NumCores = computeHostNumPhysicalCores();
1171 114484 : return NumCores;
1172 : }
1173 :
1174 : #if defined(__i386__) || defined(_M_IX86) || \
1175 : defined(__x86_64__) || defined(_M_X64)
1176 0 : bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
1177 : unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1178 : unsigned MaxLevel;
1179 : union {
1180 : unsigned u[3];
1181 : char c[12];
1182 : } text;
1183 :
1184 0 : if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
1185 : MaxLevel < 1)
1186 : return false;
1187 :
1188 : getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1189 :
1190 0 : Features["cmov"] = (EDX >> 15) & 1;
1191 0 : Features["mmx"] = (EDX >> 23) & 1;
1192 0 : Features["sse"] = (EDX >> 25) & 1;
1193 0 : Features["sse2"] = (EDX >> 26) & 1;
1194 :
1195 0 : Features["sse3"] = (ECX >> 0) & 1;
1196 0 : Features["pclmul"] = (ECX >> 1) & 1;
1197 0 : Features["ssse3"] = (ECX >> 9) & 1;
1198 0 : Features["cx16"] = (ECX >> 13) & 1;
1199 0 : Features["sse4.1"] = (ECX >> 19) & 1;
1200 0 : Features["sse4.2"] = (ECX >> 20) & 1;
1201 0 : Features["movbe"] = (ECX >> 22) & 1;
1202 0 : Features["popcnt"] = (ECX >> 23) & 1;
1203 0 : Features["aes"] = (ECX >> 25) & 1;
1204 0 : Features["rdrnd"] = (ECX >> 30) & 1;
1205 :
1206 : // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1207 : // indicates that the AVX registers will be saved and restored on context
1208 : // switch, then we have full AVX support.
1209 0 : bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
1210 0 : !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
1211 : // AVX512 requires additional context to be saved by the OS.
1212 0 : bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
1213 :
1214 0 : Features["avx"] = HasAVXSave;
1215 0 : Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave;
1216 : // Only enable XSAVE if OS has enabled support for saving YMM state.
1217 0 : Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave;
1218 0 : Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave;
1219 :
1220 : unsigned MaxExtLevel;
1221 : getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1222 :
1223 0 : bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1224 : !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1225 0 : Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1);
1226 0 : Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1227 0 : Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1228 0 : Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1229 0 : Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
1230 0 : Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
1231 0 : Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1232 0 : Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
1233 0 : Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
1234 :
1235 0 : Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1);
1236 :
1237 : // Miscellaneous memory related features, detected by
1238 : // using the 0x80000008 leaf of the CPUID instruction
1239 0 : bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
1240 : !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
1241 0 : Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1);
1242 0 : Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1);
1243 :
1244 : bool HasLeaf7 =
1245 0 : MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1246 :
1247 0 : Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
1248 0 : Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
1249 0 : Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
1250 : // AVX2 is only supported if we have the OS save support from AVX.
1251 0 : Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave;
1252 0 : Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
1253 0 : Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
1254 0 : Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
1255 : // AVX512 is only supported if the OS supports the context save for it.
1256 0 : Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
1257 0 : Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
1258 0 : Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
1259 0 : Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
1260 0 : Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
1261 0 : Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
1262 0 : Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
1263 0 : Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
1264 0 : Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
1265 0 : Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
1266 0 : Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
1267 0 : Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
1268 0 : Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
1269 :
1270 0 : Features["prefetchwt1"] = HasLeaf7 && ((ECX >> 0) & 1);
1271 0 : Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
1272 0 : Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
1273 0 : Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1);
1274 0 : Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save;
1275 0 : Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1);
1276 0 : Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1);
1277 0 : Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave;
1278 0 : Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave;
1279 0 : Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save;
1280 0 : Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
1281 0 : Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
1282 0 : Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1);
1283 0 : Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1);
1284 0 : Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
1285 0 : Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
1286 :
1287 : // There are two CPUID leafs which information associated with the pconfig
1288 : // instruction:
1289 : // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
1290 : // bit of EDX), while the EAX=0x1b leaf returns information on the
1291 : // availability of specific pconfig leafs.
1292 : // The target feature here only refers to the the first of these two.
1293 : // Users might need to check for the availability of specific pconfig
1294 : // leaves using cpuid, since that information is ignored while
1295 : // detecting features using the "-march=native" flag.
1296 : // For more info, see X86 ISA docs.
1297 0 : Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1);
1298 :
1299 0 : bool HasLeafD = MaxLevel >= 0xd &&
1300 : !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
1301 :
1302 : // Only enable XSAVE if OS has enabled support for saving YMM state.
1303 0 : Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave;
1304 0 : Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave;
1305 0 : Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave;
1306 :
1307 0 : bool HasLeaf14 = MaxLevel >= 0x14 &&
1308 : !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
1309 :
1310 0 : Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1);
1311 :
1312 0 : return true;
1313 : }
1314 : #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1315 : bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
1316 : std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1317 : if (!P)
1318 : return false;
1319 :
1320 : SmallVector<StringRef, 32> Lines;
1321 : P->getBuffer().split(Lines, "\n");
1322 :
1323 : SmallVector<StringRef, 32> CPUFeatures;
1324 :
1325 : // Look for the CPU features.
1326 : for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1327 : if (Lines[I].startswith("Features")) {
1328 : Lines[I].split(CPUFeatures, ' ');
1329 : break;
1330 : }
1331 :
1332 : #if defined(__aarch64__)
1333 : // Keep track of which crypto features we have seen
1334 : enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1335 : uint32_t crypto = 0;
1336 : #endif
1337 :
1338 : for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
1339 : StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
1340 : #if defined(__aarch64__)
1341 : .Case("asimd", "neon")
1342 : .Case("fp", "fp-armv8")
1343 : .Case("crc32", "crc")
1344 : #else
1345 : .Case("half", "fp16")
1346 : .Case("neon", "neon")
1347 : .Case("vfpv3", "vfp3")
1348 : .Case("vfpv3d16", "d16")
1349 : .Case("vfpv4", "vfp4")
1350 : .Case("idiva", "hwdiv-arm")
1351 : .Case("idivt", "hwdiv")
1352 : #endif
1353 : .Default("");
1354 :
1355 : #if defined(__aarch64__)
1356 : // We need to check crypto separately since we need all of the crypto
1357 : // extensions to enable the subtarget feature
1358 : if (CPUFeatures[I] == "aes")
1359 : crypto |= CAP_AES;
1360 : else if (CPUFeatures[I] == "pmull")
1361 : crypto |= CAP_PMULL;
1362 : else if (CPUFeatures[I] == "sha1")
1363 : crypto |= CAP_SHA1;
1364 : else if (CPUFeatures[I] == "sha2")
1365 : crypto |= CAP_SHA2;
1366 : #endif
1367 :
1368 : if (LLVMFeatureStr != "")
1369 : Features[LLVMFeatureStr] = true;
1370 : }
1371 :
1372 : #if defined(__aarch64__)
1373 : // If we have all crypto bits we can add the feature
1374 : if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
1375 : Features["crypto"] = true;
1376 : #endif
1377 :
1378 : return true;
1379 : }
1380 : #else
1381 : bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
1382 : #endif
1383 :
1384 141247 : std::string sys::getProcessTriple() {
1385 282494 : std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
1386 141247 : Triple PT(Triple::normalize(TargetTripleString));
1387 :
1388 141247 : if (sizeof(void *) == 8 && PT.isArch32Bit())
1389 0 : PT = PT.get64BitArchVariant();
1390 : if (sizeof(void *) == 4 && PT.isArch64Bit())
1391 : PT = PT.get32BitArchVariant();
1392 :
1393 141247 : return PT.str();
1394 : }
|