blob: b1d5b44ebd0010dee7461c64d6209fe36ac0f693 [file] [log] [blame]
Simon Pilgrima271c542017-05-03 15:42:29 +00001//===-- 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/SmallSet.h"
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/StringSwitch.h"
19#include "llvm/ADT/Triple.h"
20#include "llvm/Config/config.h"
21#include "llvm/Support/Debug.h"
22#include "llvm/Support/FileSystem.h"
23#include "llvm/Support/MemoryBuffer.h"
24#include "llvm/Support/raw_ostream.h"
25#include <assert.h>
26#include <string.h>
27
28// Include the platform-specific parts of this class.
29#ifdef LLVM_ON_UNIX
30#include "Unix/Host.inc"
31#endif
32#ifdef LLVM_ON_WIN32
33#include "Windows/Host.inc"
34#endif
35#ifdef _MSC_VER
36#include <intrin.h>
37#endif
38#if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
39#include <mach/host_info.h>
40#include <mach/mach.h>
41#include <mach/mach_host.h>
42#include <mach/machine.h>
43#endif
44
45#define DEBUG_TYPE "host-detection"
46
47//===----------------------------------------------------------------------===//
48//
49// Implementations of the CPU detection routines
50//
51//===----------------------------------------------------------------------===//
52
53using namespace llvm;
54
55static std::unique_ptr<llvm::MemoryBuffer>
56 LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent() {
57 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
58 llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
59 if (std::error_code EC = Text.getError()) {
60 llvm::errs() << "Can't read "
61 << "/proc/cpuinfo: " << EC.message() << "\n";
62 return nullptr;
63 }
64 return std::move(*Text);
65}
66
67StringRef sys::detail::getHostCPUNameForPowerPC(
68 const 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 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 while (CIP < CPUInfoEnd && CPUStart == 0) {
87 if (CIP < CPUInfoEnd && *CIP == '\n')
88 ++CIP;
89
90 if (CIP < CPUInfoEnd && *CIP == 'c') {
91 ++CIP;
92 if (CIP < CPUInfoEnd && *CIP == 'p') {
93 ++CIP;
94 if (CIP < CPUInfoEnd && *CIP == 'u') {
95 ++CIP;
96 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
97 ++CIP;
98
99 if (CIP < CPUInfoEnd && *CIP == ':') {
100 ++CIP;
101 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
102 ++CIP;
103
104 if (CIP < CPUInfoEnd) {
105 CPUStart = CIP;
106 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
107 *CIP != ',' && *CIP != '\n'))
108 ++CIP;
109 CPULen = CIP - CPUStart;
110 }
111 }
112 }
113 }
114 }
115
116 if (CPUStart == 0)
117 while (CIP < CPUInfoEnd && *CIP != '\n')
118 ++CIP;
119 }
120
121 if (CPUStart == 0)
122 return generic;
123
124 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
125 .Case("604e", "604e")
126 .Case("604", "604")
127 .Case("7400", "7400")
128 .Case("7410", "7400")
129 .Case("7447", "7400")
130 .Case("7455", "7450")
131 .Case("G4", "g4")
132 .Case("POWER4", "970")
133 .Case("PPC970FX", "970")
134 .Case("PPC970MP", "970")
135 .Case("G5", "g5")
136 .Case("POWER5", "g5")
137 .Case("A2", "a2")
138 .Case("POWER6", "pwr6")
139 .Case("POWER7", "pwr7")
140 .Case("POWER8", "pwr8")
141 .Case("POWER8E", "pwr8")
142 .Case("POWER8NVL", "pwr8")
143 .Case("POWER9", "pwr9")
144 .Default(generic);
145}
146
147StringRef sys::detail::getHostCPUNameForARM(
148 const StringRef &ProcCpuinfoContent) {
149 // The cpuid register on arm is not accessible from user space. On Linux,
150 // it is exposed through the /proc/cpuinfo file.
151
152 // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line
153 // in all cases.
154 SmallVector<StringRef, 32> Lines;
155 ProcCpuinfoContent.split(Lines, "\n");
156
157 // Look for the CPU implementer line.
158 StringRef Implementer;
159 StringRef Hardware;
160 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
161 if (Lines[I].startswith("CPU implementer"))
162 Implementer = Lines[I].substr(15).ltrim("\t :");
163 if (Lines[I].startswith("Hardware"))
164 Hardware = Lines[I].substr(8).ltrim("\t :");
165 }
166
167 if (Implementer == "0x41") { // ARM Ltd.
168 // MSM8992/8994 may give cpu part for the core that the kernel is running on,
169 // which is undeterministic and wrong. Always return cortex-a53 for these SoC.
170 if (Hardware.endswith("MSM8994") || Hardware.endswith("MSM8996"))
171 return "cortex-a53";
172
173
174 // Look for the CPU part line.
175 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
176 if (Lines[I].startswith("CPU part"))
177 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
178 // values correspond to the "Part number" in the CP15/c0 register. The
179 // contents are specified in the various processor manuals.
180 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
181 .Case("0x926", "arm926ej-s")
182 .Case("0xb02", "mpcore")
183 .Case("0xb36", "arm1136j-s")
184 .Case("0xb56", "arm1156t2-s")
185 .Case("0xb76", "arm1176jz-s")
186 .Case("0xc08", "cortex-a8")
187 .Case("0xc09", "cortex-a9")
188 .Case("0xc0f", "cortex-a15")
189 .Case("0xc20", "cortex-m0")
190 .Case("0xc23", "cortex-m3")
191 .Case("0xc24", "cortex-m4")
192 .Case("0xd04", "cortex-a35")
193 .Case("0xd03", "cortex-a53")
194 .Case("0xd07", "cortex-a57")
195 .Case("0xd08", "cortex-a72")
196 .Case("0xd09", "cortex-a73")
197 .Default("generic");
198 }
199
200 if (Implementer == "0x51") // Qualcomm Technologies, Inc.
201 // Look for the CPU part line.
202 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
203 if (Lines[I].startswith("CPU part"))
204 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
205 // values correspond to the "Part number" in the CP15/c0 register. The
206 // contents are specified in the various processor manuals.
207 return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
208 .Case("0x06f", "krait") // APQ8064
209 .Case("0x201", "kryo")
210 .Case("0x205", "kryo")
Eli Friedmanbde9fc72017-09-13 21:48:00 +0000211 .Case("0x211", "kryo")
212 .Case("0x800", "cortex-a73")
213 .Case("0x801", "cortex-a73")
Balaram Makama1e7ecc72017-09-22 17:46:36 +0000214 .Case("0xc00", "falkor")
Chad Rosier71070852017-09-25 14:05:00 +0000215 .Case("0xc01", "saphira")
Simon Pilgrima271c542017-05-03 15:42:29 +0000216 .Default("generic");
217
218 return "generic";
219}
220
221StringRef sys::detail::getHostCPUNameForS390x(
222 const StringRef &ProcCpuinfoContent) {
223 // STIDP is a privileged operation, so use /proc/cpuinfo instead.
224
225 // The "processor 0:" line comes after a fair amount of other information,
226 // including a cache breakdown, but this should be plenty.
227 SmallVector<StringRef, 32> Lines;
228 ProcCpuinfoContent.split(Lines, "\n");
229
230 // Look for the CPU features.
231 SmallVector<StringRef, 32> CPUFeatures;
232 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
233 if (Lines[I].startswith("features")) {
234 size_t Pos = Lines[I].find(":");
235 if (Pos != StringRef::npos) {
236 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
237 break;
238 }
239 }
240
241 // We need to check for the presence of vector support independently of
242 // the machine type, since we may only use the vector register set when
243 // supported by the kernel (and hypervisor).
244 bool HaveVectorSupport = false;
245 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
246 if (CPUFeatures[I] == "vx")
247 HaveVectorSupport = true;
248 }
249
250 // Now check the processor machine type.
251 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
252 if (Lines[I].startswith("processor ")) {
253 size_t Pos = Lines[I].find("machine = ");
254 if (Pos != StringRef::npos) {
255 Pos += sizeof("machine = ") - 1;
256 unsigned int Id;
257 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
Ulrich Weigand2b3482f2017-07-17 17:41:11 +0000258 if (Id >= 3906 && HaveVectorSupport)
259 return "z14";
Simon Pilgrima271c542017-05-03 15:42:29 +0000260 if (Id >= 2964 && HaveVectorSupport)
261 return "z13";
262 if (Id >= 2827)
263 return "zEC12";
264 if (Id >= 2817)
265 return "z196";
266 }
267 }
268 break;
269 }
270 }
271
272 return "generic";
273}
274
Yonghong Songdc1dbf62017-08-23 04:25:57 +0000275StringRef sys::detail::getHostCPUNameForBPF() {
276#if !defined(__linux__) || !defined(__x86_64__)
277 return "generic";
278#else
279 uint8_t insns[40] __attribute__ ((aligned (8))) =
280 /* BPF_MOV64_IMM(BPF_REG_0, 0) */
281 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
282 /* BPF_MOV64_IMM(BPF_REG_2, 1) */
283 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
284 /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
285 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
286 /* BPF_MOV64_IMM(BPF_REG_0, 1) */
287 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
288 /* BPF_EXIT_INSN() */
289 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
290
291 struct bpf_prog_load_attr {
292 uint32_t prog_type;
293 uint32_t insn_cnt;
294 uint64_t insns;
295 uint64_t license;
296 uint32_t log_level;
297 uint32_t log_size;
298 uint64_t log_buf;
299 uint32_t kern_version;
300 uint32_t prog_flags;
301 } attr = {};
302 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
303 attr.insn_cnt = 5;
304 attr.insns = (uint64_t)insns;
305 attr.license = (uint64_t)"DUMMY";
306
307 int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr));
Yonghong Songc6d25712017-08-23 16:24:31 +0000308 if (fd >= 0) {
309 close(fd);
310 return "v2";
311 }
312 return "v1";
Yonghong Songdc1dbf62017-08-23 04:25:57 +0000313#endif
314}
315
Simon Pilgrima271c542017-05-03 15:42:29 +0000316#if defined(__i386__) || defined(_M_IX86) || \
317 defined(__x86_64__) || defined(_M_X64)
318
319enum VendorSignatures {
320 SIG_INTEL = 0x756e6547 /* Genu */,
321 SIG_AMD = 0x68747541 /* Auth */
322};
323
324enum ProcessorVendors {
325 VENDOR_INTEL = 1,
326 VENDOR_AMD,
327 VENDOR_OTHER,
328 VENDOR_MAX
329};
330
331enum ProcessorTypes {
Craig Topperf3af64e2017-07-12 06:49:57 +0000332 INTEL_BONNELL = 1,
Simon Pilgrima271c542017-05-03 15:42:29 +0000333 INTEL_CORE2,
334 INTEL_COREI7,
335 AMDFAM10H,
336 AMDFAM15H,
Craig Topperf3af64e2017-07-12 06:49:57 +0000337 INTEL_SILVERMONT,
338 INTEL_KNL,
339 AMD_BTVER1,
340 AMD_BTVER2,
341 AMDFAM17H,
Craig Topper5d692912017-10-13 18:10:17 +0000342 INTEL_KNM,
Craig Topperf3af64e2017-07-12 06:49:57 +0000343 // Entries below this are not in libgcc/compiler-rt.
Simon Pilgrima271c542017-05-03 15:42:29 +0000344 INTEL_i386,
345 INTEL_i486,
346 INTEL_PENTIUM,
347 INTEL_PENTIUM_PRO,
348 INTEL_PENTIUM_II,
349 INTEL_PENTIUM_III,
350 INTEL_PENTIUM_IV,
351 INTEL_PENTIUM_M,
352 INTEL_CORE_DUO,
Simon Pilgrima271c542017-05-03 15:42:29 +0000353 INTEL_X86_64,
354 INTEL_NOCONA,
355 INTEL_PRESCOTT,
356 AMD_i486,
357 AMDPENTIUM,
358 AMDATHLON,
Craig Topperf3af64e2017-07-12 06:49:57 +0000359 INTEL_GOLDMONT,
Simon Pilgrima271c542017-05-03 15:42:29 +0000360 CPU_TYPE_MAX
361};
362
363enum ProcessorSubtypes {
364 INTEL_COREI7_NEHALEM = 1,
365 INTEL_COREI7_WESTMERE,
366 INTEL_COREI7_SANDYBRIDGE,
367 AMDFAM10H_BARCELONA,
368 AMDFAM10H_SHANGHAI,
369 AMDFAM10H_ISTANBUL,
370 AMDFAM15H_BDVER1,
371 AMDFAM15H_BDVER2,
Craig Topperf3af64e2017-07-12 06:49:57 +0000372 AMDFAM15H_BDVER3,
373 AMDFAM15H_BDVER4,
374 AMDFAM17H_ZNVER1,
Simon Pilgrima271c542017-05-03 15:42:29 +0000375 INTEL_COREI7_IVYBRIDGE,
376 INTEL_COREI7_HASWELL,
377 INTEL_COREI7_BROADWELL,
378 INTEL_COREI7_SKYLAKE,
379 INTEL_COREI7_SKYLAKE_AVX512,
Craig Topperf3af64e2017-07-12 06:49:57 +0000380 // Entries below this are not in libgcc/compiler-rt.
381 INTEL_PENTIUM_MMX,
382 INTEL_CORE2_65,
383 INTEL_CORE2_45,
Simon Pilgrima271c542017-05-03 15:42:29 +0000384 AMDPENTIUM_K6,
385 AMDPENTIUM_K62,
386 AMDPENTIUM_K63,
387 AMDPENTIUM_GEODE,
Craig Topperf3de5eb2017-07-13 06:34:10 +0000388 AMDATHLON_CLASSIC,
Simon Pilgrima271c542017-05-03 15:42:29 +0000389 AMDATHLON_XP,
Craig Topperf3de5eb2017-07-13 06:34:10 +0000390 AMDATHLON_K8,
Simon Pilgrima271c542017-05-03 15:42:29 +0000391 AMDATHLON_K8SSE3,
Simon Pilgrima271c542017-05-03 15:42:29 +0000392 CPU_SUBTYPE_MAX
393};
394
395enum ProcessorFeatures {
396 FEATURE_CMOV = 0,
397 FEATURE_MMX,
398 FEATURE_POPCNT,
399 FEATURE_SSE,
400 FEATURE_SSE2,
401 FEATURE_SSE3,
402 FEATURE_SSSE3,
403 FEATURE_SSE4_1,
404 FEATURE_SSE4_2,
405 FEATURE_AVX,
406 FEATURE_AVX2,
Craig Topper3a5d0822017-07-12 06:49:58 +0000407 FEATURE_SSE4_A,
408 FEATURE_FMA4,
409 FEATURE_XOP,
410 FEATURE_FMA,
411 FEATURE_AVX512F,
412 FEATURE_BMI,
413 FEATURE_BMI2,
414 FEATURE_AES,
415 FEATURE_PCLMUL,
416 FEATURE_AVX512VL,
417 FEATURE_AVX512BW,
418 FEATURE_AVX512DQ,
419 FEATURE_AVX512CD,
420 FEATURE_AVX512ER,
421 FEATURE_AVX512PF,
422 FEATURE_AVX512VBMI,
423 FEATURE_AVX512IFMA,
424 FEATURE_AVX5124VNNIW,
425 FEATURE_AVX5124FMAPS,
426 FEATURE_AVX512VPOPCNTDQ,
427 // Only one bit free left in the first 32 features.
428 FEATURE_MOVBE = 32,
Simon Pilgrima271c542017-05-03 15:42:29 +0000429 FEATURE_ADX,
Craig Topper4eda7562017-07-27 03:26:52 +0000430 FEATURE_EM64T,
431 FEATURE_CLFLUSHOPT,
432 FEATURE_SHA,
Simon Pilgrima271c542017-05-03 15:42:29 +0000433};
434
435// The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
436// Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
437// support. Consequently, for i386, the presence of CPUID is checked first
438// via the corresponding eflags bit.
439// Removal of cpuid.h header motivated by PR30384
440// Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
441// or test-suite, but are used in external projects e.g. libstdcxx
442static bool isCpuIdSupported() {
443#if defined(__GNUC__) || defined(__clang__)
444#if defined(__i386__)
445 int __cpuid_supported;
446 __asm__(" pushfl\n"
447 " popl %%eax\n"
448 " movl %%eax,%%ecx\n"
449 " xorl $0x00200000,%%eax\n"
450 " pushl %%eax\n"
451 " popfl\n"
452 " pushfl\n"
453 " popl %%eax\n"
454 " movl $0,%0\n"
455 " cmpl %%eax,%%ecx\n"
456 " je 1f\n"
457 " movl $1,%0\n"
458 "1:"
459 : "=r"(__cpuid_supported)
460 :
461 : "eax", "ecx");
462 if (!__cpuid_supported)
463 return false;
464#endif
465 return true;
466#endif
467 return true;
468}
469
470/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
471/// the specified arguments. If we can't run cpuid on the host, return true.
472static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
473 unsigned *rECX, unsigned *rEDX) {
Simon Pilgrima271c542017-05-03 15:42:29 +0000474#if defined(__GNUC__) || defined(__clang__)
475#if defined(__x86_64__)
476 // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
477 // FIXME: should we save this for Clang?
478 __asm__("movq\t%%rbx, %%rsi\n\t"
479 "cpuid\n\t"
480 "xchgq\t%%rbx, %%rsi\n\t"
481 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
482 : "a"(value));
Craig Topper1efd10a2017-07-10 06:04:11 +0000483 return false;
Simon Pilgrima271c542017-05-03 15:42:29 +0000484#elif defined(__i386__)
485 __asm__("movl\t%%ebx, %%esi\n\t"
486 "cpuid\n\t"
487 "xchgl\t%%ebx, %%esi\n\t"
488 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
489 : "a"(value));
Craig Topper1efd10a2017-07-10 06:04:11 +0000490 return false;
Simon Pilgrima271c542017-05-03 15:42:29 +0000491#else
Craig Topper1efd10a2017-07-10 06:04:11 +0000492 return true;
Simon Pilgrima271c542017-05-03 15:42:29 +0000493#endif
494#elif defined(_MSC_VER)
495 // The MSVC intrinsic is portable across x86 and x64.
496 int registers[4];
497 __cpuid(registers, value);
498 *rEAX = registers[0];
499 *rEBX = registers[1];
500 *rECX = registers[2];
501 *rEDX = registers[3];
Simon Pilgrima271c542017-05-03 15:42:29 +0000502 return false;
503#else
504 return true;
505#endif
506}
507
508/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
509/// the 4 values in the specified arguments. If we can't run cpuid on the host,
510/// return true.
511static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
512 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
513 unsigned *rEDX) {
Simon Pilgrima271c542017-05-03 15:42:29 +0000514#if defined(__GNUC__) || defined(__clang__)
Craig Topper828cf302017-07-17 05:16:16 +0000515#if defined(__x86_64__)
Craig Topperada983a2017-07-10 06:09:22 +0000516 // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
Simon Pilgrima271c542017-05-03 15:42:29 +0000517 // FIXME: should we save this for Clang?
518 __asm__("movq\t%%rbx, %%rsi\n\t"
519 "cpuid\n\t"
520 "xchgq\t%%rbx, %%rsi\n\t"
521 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
522 : "a"(value), "c"(subleaf));
Craig Topper1efd10a2017-07-10 06:04:11 +0000523 return false;
Craig Topper828cf302017-07-17 05:16:16 +0000524#elif defined(__i386__)
525 __asm__("movl\t%%ebx, %%esi\n\t"
526 "cpuid\n\t"
527 "xchgl\t%%ebx, %%esi\n\t"
528 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
529 : "a"(value), "c"(subleaf));
530 return false;
531#else
532 return true;
533#endif
Simon Pilgrima271c542017-05-03 15:42:29 +0000534#elif defined(_MSC_VER)
535 int registers[4];
536 __cpuidex(registers, value, subleaf);
537 *rEAX = registers[0];
538 *rEBX = registers[1];
539 *rECX = registers[2];
540 *rEDX = registers[3];
Craig Topper1efd10a2017-07-10 06:04:11 +0000541 return false;
542#else
543 return true;
Simon Pilgrima271c542017-05-03 15:42:29 +0000544#endif
Simon Pilgrima271c542017-05-03 15:42:29 +0000545}
546
Craig Topperf3af64e2017-07-12 06:49:57 +0000547// Read control register 0 (XCR0). Used to detect features such as AVX.
Simon Pilgrima271c542017-05-03 15:42:29 +0000548static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
549#if defined(__GNUC__) || defined(__clang__)
550 // Check xgetbv; this uses a .byte sequence instead of the instruction
551 // directly because older assemblers do not include support for xgetbv and
552 // there is no easy way to conditionally compile based on the assembler used.
553 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
554 return false;
555#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
556 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
557 *rEAX = Result;
558 *rEDX = Result >> 32;
559 return false;
560#else
561 return true;
562#endif
563}
564
565static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
566 unsigned *Model) {
567 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
568 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
569 if (*Family == 6 || *Family == 0xf) {
570 if (*Family == 0xf)
571 // Examine extended family ID if family ID is F.
572 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
573 // Examine extended model ID if family ID is 6 or F.
574 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
575 }
576}
577
578static void
Craig Topperc6bbe4b2017-07-08 05:16:14 +0000579getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
580 unsigned Brand_id, unsigned Features,
Craig Topper3a5d0822017-07-12 06:49:58 +0000581 unsigned Features2, unsigned *Type,
582 unsigned *Subtype) {
Simon Pilgrima271c542017-05-03 15:42:29 +0000583 if (Brand_id != 0)
584 return;
585 switch (Family) {
586 case 3:
587 *Type = INTEL_i386;
588 break;
589 case 4:
590 switch (Model) {
591 case 0: // Intel486 DX processors
592 case 1: // Intel486 DX processors
593 case 2: // Intel486 SX processors
594 case 3: // Intel487 processors, IntelDX2 OverDrive processors,
595 // IntelDX2 processors
596 case 4: // Intel486 SL processor
597 case 5: // IntelSX2 processors
598 case 7: // Write-Back Enhanced IntelDX2 processors
599 case 8: // IntelDX4 OverDrive processors, IntelDX4 processors
600 default:
601 *Type = INTEL_i486;
602 break;
603 }
604 break;
605 case 5:
606 switch (Model) {
607 case 1: // Pentium OverDrive processor for Pentium processor (60, 66),
608 // Pentium processors (60, 66)
609 case 2: // Pentium OverDrive processor for Pentium processor (75, 90,
610 // 100, 120, 133), Pentium processors (75, 90, 100, 120, 133,
611 // 150, 166, 200)
612 case 3: // Pentium OverDrive processors for Intel486 processor-based
613 // systems
614 *Type = INTEL_PENTIUM;
615 break;
616 case 4: // Pentium OverDrive processor with MMX technology for Pentium
617 // processor (75, 90, 100, 120, 133), Pentium processor with
618 // MMX technology (166, 200)
619 *Type = INTEL_PENTIUM;
620 *Subtype = INTEL_PENTIUM_MMX;
621 break;
622 default:
623 *Type = INTEL_PENTIUM;
624 break;
625 }
626 break;
627 case 6:
628 switch (Model) {
629 case 0x01: // Pentium Pro processor
630 *Type = INTEL_PENTIUM_PRO;
631 break;
632 case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
633 // model 03
634 case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
635 // model 05, and Intel Celeron processor, model 05
636 case 0x06: // Celeron processor, model 06
637 *Type = INTEL_PENTIUM_II;
638 break;
639 case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
640 // processor, model 07
641 case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
642 // model 08, and Celeron processor, model 08
643 case 0x0a: // Pentium III Xeon processor, model 0Ah
644 case 0x0b: // Pentium III processor, model 0Bh
645 *Type = INTEL_PENTIUM_III;
646 break;
647 case 0x09: // Intel Pentium M processor, Intel Celeron M processor model 09.
648 case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
649 // 0Dh. All processors are manufactured using the 90 nm process.
650 case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
651 // Integrated Processor with Intel QuickAssist Technology
652 *Type = INTEL_PENTIUM_M;
653 break;
654 case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
655 // 0Eh. All processors are manufactured using the 65 nm process.
656 *Type = INTEL_CORE_DUO;
657 break; // yonah
658 case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
659 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
660 // mobile processor, Intel Core 2 Extreme processor, Intel
661 // Pentium Dual-Core processor, Intel Xeon processor, model
662 // 0Fh. All processors are manufactured using the 65 nm process.
663 case 0x16: // Intel Celeron processor model 16h. All processors are
664 // manufactured using the 65 nm process
665 *Type = INTEL_CORE2; // "core2"
666 *Subtype = INTEL_CORE2_65;
667 break;
668 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
669 // 17h. All processors are manufactured using the 45 nm process.
670 //
671 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
672 case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
673 // the 45 nm process.
674 *Type = INTEL_CORE2; // "penryn"
675 *Subtype = INTEL_CORE2_45;
676 break;
677 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
678 // processors are manufactured using the 45 nm process.
679 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
680 // As found in a Summer 2010 model iMac.
681 case 0x1f:
682 case 0x2e: // Nehalem EX
683 *Type = INTEL_COREI7; // "nehalem"
684 *Subtype = INTEL_COREI7_NEHALEM;
685 break;
686 case 0x25: // Intel Core i7, laptop version.
687 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
688 // processors are manufactured using the 32 nm process.
689 case 0x2f: // Westmere EX
690 *Type = INTEL_COREI7; // "westmere"
691 *Subtype = INTEL_COREI7_WESTMERE;
692 break;
693 case 0x2a: // Intel Core i7 processor. All processors are manufactured
694 // using the 32 nm process.
695 case 0x2d:
696 *Type = INTEL_COREI7; //"sandybridge"
697 *Subtype = INTEL_COREI7_SANDYBRIDGE;
698 break;
699 case 0x3a:
700 case 0x3e: // Ivy Bridge EP
701 *Type = INTEL_COREI7; // "ivybridge"
702 *Subtype = INTEL_COREI7_IVYBRIDGE;
703 break;
704
705 // Haswell:
706 case 0x3c:
707 case 0x3f:
708 case 0x45:
709 case 0x46:
710 *Type = INTEL_COREI7; // "haswell"
711 *Subtype = INTEL_COREI7_HASWELL;
712 break;
713
714 // Broadwell:
715 case 0x3d:
716 case 0x47:
717 case 0x4f:
718 case 0x56:
719 *Type = INTEL_COREI7; // "broadwell"
720 *Subtype = INTEL_COREI7_BROADWELL;
721 break;
722
723 // Skylake:
724 case 0x4e: // Skylake mobile
725 case 0x5e: // Skylake desktop
726 case 0x8e: // Kaby Lake mobile
727 case 0x9e: // Kaby Lake desktop
728 *Type = INTEL_COREI7; // "skylake"
729 *Subtype = INTEL_COREI7_SKYLAKE;
730 break;
731
732 // Skylake Xeon:
733 case 0x55:
734 *Type = INTEL_COREI7;
Craig Topper52cec382017-07-09 07:26:14 +0000735 *Subtype = INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512"
Simon Pilgrima271c542017-05-03 15:42:29 +0000736 break;
737
738 case 0x1c: // Most 45 nm Intel Atom processors
739 case 0x26: // 45 nm Atom Lincroft
740 case 0x27: // 32 nm Atom Medfield
741 case 0x35: // 32 nm Atom Midview
742 case 0x36: // 32 nm Atom Midview
Craig Topperf3af64e2017-07-12 06:49:57 +0000743 *Type = INTEL_BONNELL;
Simon Pilgrima271c542017-05-03 15:42:29 +0000744 break; // "bonnell"
745
746 // Atom Silvermont codes from the Intel software optimization guide.
747 case 0x37:
748 case 0x4a:
749 case 0x4d:
750 case 0x5a:
751 case 0x5d:
752 case 0x4c: // really airmont
Craig Topperf3af64e2017-07-12 06:49:57 +0000753 *Type = INTEL_SILVERMONT;
Simon Pilgrima271c542017-05-03 15:42:29 +0000754 break; // "silvermont"
Michael Zuckerman4bcb9c32017-06-29 10:00:33 +0000755 // Goldmont:
756 case 0x5c:
757 case 0x5f:
Craig Topperf3af64e2017-07-12 06:49:57 +0000758 *Type = INTEL_GOLDMONT;
Michael Zuckerman4bcb9c32017-06-29 10:00:33 +0000759 break; // "goldmont"
Simon Pilgrima271c542017-05-03 15:42:29 +0000760 case 0x57:
Craig Topperf3af64e2017-07-12 06:49:57 +0000761 *Type = INTEL_KNL; // knl
Simon Pilgrima271c542017-05-03 15:42:29 +0000762 break;
Craig Topper5d692912017-10-13 18:10:17 +0000763 case 0x85:
764 *Type = INTEL_KNM; // knm
765 break;
Simon Pilgrima271c542017-05-03 15:42:29 +0000766
767 default: // Unknown family 6 CPU, try to guess.
Craig Topper3a5d0822017-07-12 06:49:58 +0000768 if (Features & (1 << FEATURE_AVX512F)) {
Craig Topper4eda7562017-07-27 03:26:52 +0000769 if (Features & (1 << FEATURE_AVX512VL)) {
770 *Type = INTEL_COREI7;
771 *Subtype = INTEL_COREI7_SKYLAKE_AVX512;
772 } else {
773 *Type = INTEL_KNL; // knl
774 }
775 break;
776 }
777 if (Features2 & (1 << (FEATURE_CLFLUSHOPT - 32))) {
778 if (Features2 & (1 << (FEATURE_SHA - 32))) {
779 *Type = INTEL_GOLDMONT;
780 } else {
781 *Type = INTEL_COREI7;
782 *Subtype = INTEL_COREI7_SKYLAKE;
783 }
Simon Pilgrima271c542017-05-03 15:42:29 +0000784 break;
785 }
Craig Topper3a5d0822017-07-12 06:49:58 +0000786 if (Features2 & (1 << (FEATURE_ADX - 32))) {
Simon Pilgrima271c542017-05-03 15:42:29 +0000787 *Type = INTEL_COREI7;
788 *Subtype = INTEL_COREI7_BROADWELL;
789 break;
790 }
791 if (Features & (1 << FEATURE_AVX2)) {
792 *Type = INTEL_COREI7;
793 *Subtype = INTEL_COREI7_HASWELL;
794 break;
795 }
796 if (Features & (1 << FEATURE_AVX)) {
797 *Type = INTEL_COREI7;
798 *Subtype = INTEL_COREI7_SANDYBRIDGE;
799 break;
800 }
801 if (Features & (1 << FEATURE_SSE4_2)) {
Craig Topper3a5d0822017-07-12 06:49:58 +0000802 if (Features2 & (1 << (FEATURE_MOVBE - 32))) {
Craig Topperf3af64e2017-07-12 06:49:57 +0000803 *Type = INTEL_SILVERMONT;
Simon Pilgrima271c542017-05-03 15:42:29 +0000804 } else {
805 *Type = INTEL_COREI7;
806 *Subtype = INTEL_COREI7_NEHALEM;
807 }
808 break;
809 }
810 if (Features & (1 << FEATURE_SSE4_1)) {
811 *Type = INTEL_CORE2; // "penryn"
812 *Subtype = INTEL_CORE2_45;
813 break;
814 }
815 if (Features & (1 << FEATURE_SSSE3)) {
Craig Topper3a5d0822017-07-12 06:49:58 +0000816 if (Features2 & (1 << (FEATURE_MOVBE - 32))) {
Craig Topperf3af64e2017-07-12 06:49:57 +0000817 *Type = INTEL_BONNELL; // "bonnell"
Simon Pilgrima271c542017-05-03 15:42:29 +0000818 } else {
819 *Type = INTEL_CORE2; // "core2"
820 *Subtype = INTEL_CORE2_65;
821 }
822 break;
823 }
Craig Topper3a5d0822017-07-12 06:49:58 +0000824 if (Features2 & (1 << (FEATURE_EM64T - 32))) {
Simon Pilgrima271c542017-05-03 15:42:29 +0000825 *Type = INTEL_X86_64;
826 break; // x86-64
827 }
828 if (Features & (1 << FEATURE_SSE2)) {
829 *Type = INTEL_PENTIUM_M;
830 break;
831 }
832 if (Features & (1 << FEATURE_SSE)) {
833 *Type = INTEL_PENTIUM_III;
834 break;
835 }
836 if (Features & (1 << FEATURE_MMX)) {
837 *Type = INTEL_PENTIUM_II;
838 break;
839 }
840 *Type = INTEL_PENTIUM_PRO;
841 break;
842 }
843 break;
844 case 15: {
845 switch (Model) {
846 case 0: // Pentium 4 processor, Intel Xeon processor. All processors are
847 // model 00h and manufactured using the 0.18 micron process.
848 case 1: // Pentium 4 processor, Intel Xeon processor, Intel Xeon
849 // processor MP, and Intel Celeron processor. All processors are
850 // model 01h and manufactured using the 0.18 micron process.
851 case 2: // Pentium 4 processor, Mobile Intel Pentium 4 processor - M,
852 // Intel Xeon processor, Intel Xeon processor MP, Intel Celeron
853 // processor, and Mobile Intel Celeron processor. All processors
854 // are model 02h and manufactured using the 0.13 micron process.
Craig Topper3a5d0822017-07-12 06:49:58 +0000855 *Type = ((Features2 & (1 << (FEATURE_EM64T - 32))) ? INTEL_X86_64
856 : INTEL_PENTIUM_IV);
Simon Pilgrima271c542017-05-03 15:42:29 +0000857 break;
858
859 case 3: // Pentium 4 processor, Intel Xeon processor, Intel Celeron D
860 // processor. All processors are model 03h and manufactured using
861 // the 90 nm process.
862 case 4: // Pentium 4 processor, Pentium 4 processor Extreme Edition,
863 // Pentium D processor, Intel Xeon processor, Intel Xeon
864 // processor MP, Intel Celeron D processor. All processors are
865 // model 04h and manufactured using the 90 nm process.
866 case 6: // Pentium 4 processor, Pentium D processor, Pentium processor
867 // Extreme Edition, Intel Xeon processor, Intel Xeon processor
868 // MP, Intel Celeron D processor. All processors are model 06h
869 // and manufactured using the 65 nm process.
Craig Topper3a5d0822017-07-12 06:49:58 +0000870 *Type = ((Features2 & (1 << (FEATURE_EM64T - 32))) ? INTEL_NOCONA
871 : INTEL_PRESCOTT);
Simon Pilgrima271c542017-05-03 15:42:29 +0000872 break;
873
874 default:
Craig Topper3a5d0822017-07-12 06:49:58 +0000875 *Type = ((Features2 & (1 << (FEATURE_EM64T - 32))) ? INTEL_X86_64
876 : INTEL_PENTIUM_IV);
Simon Pilgrima271c542017-05-03 15:42:29 +0000877 break;
878 }
879 break;
880 }
881 default:
882 break; /*"generic"*/
883 }
884}
885
Craig Topper2ace1532017-07-08 06:44:34 +0000886static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
887 unsigned Features, unsigned *Type,
Simon Pilgrima271c542017-05-03 15:42:29 +0000888 unsigned *Subtype) {
889 // FIXME: this poorly matches the generated SubtargetFeatureKV table. There
890 // appears to be no way to generate the wide variety of AMD-specific targets
891 // from the information returned from CPUID.
892 switch (Family) {
893 case 4:
894 *Type = AMD_i486;
895 break;
896 case 5:
897 *Type = AMDPENTIUM;
898 switch (Model) {
899 case 6:
900 case 7:
901 *Subtype = AMDPENTIUM_K6;
902 break; // "k6"
903 case 8:
904 *Subtype = AMDPENTIUM_K62;
905 break; // "k6-2"
906 case 9:
907 case 13:
908 *Subtype = AMDPENTIUM_K63;
909 break; // "k6-3"
910 case 10:
911 *Subtype = AMDPENTIUM_GEODE;
912 break; // "geode"
913 }
914 break;
915 case 6:
916 *Type = AMDATHLON;
Craig Topperf3de5eb2017-07-13 06:34:10 +0000917 if (Features & (1 << FEATURE_SSE)) {
Simon Pilgrima271c542017-05-03 15:42:29 +0000918 *Subtype = AMDATHLON_XP;
919 break; // "athlon-xp"
920 }
Craig Topperf3de5eb2017-07-13 06:34:10 +0000921 *Subtype = AMDATHLON_CLASSIC;
922 break; // "athlon"
Simon Pilgrima271c542017-05-03 15:42:29 +0000923 case 15:
924 *Type = AMDATHLON;
925 if (Features & (1 << FEATURE_SSE3)) {
926 *Subtype = AMDATHLON_K8SSE3;
927 break; // "k8-sse3"
928 }
Craig Topperf3de5eb2017-07-13 06:34:10 +0000929 *Subtype = AMDATHLON_K8;
930 break; // "k8"
Simon Pilgrima271c542017-05-03 15:42:29 +0000931 case 16:
932 *Type = AMDFAM10H; // "amdfam10"
933 switch (Model) {
934 case 2:
935 *Subtype = AMDFAM10H_BARCELONA;
936 break;
937 case 4:
938 *Subtype = AMDFAM10H_SHANGHAI;
939 break;
940 case 8:
941 *Subtype = AMDFAM10H_ISTANBUL;
942 break;
943 }
944 break;
945 case 20:
Craig Topperf3af64e2017-07-12 06:49:57 +0000946 *Type = AMD_BTVER1;
Simon Pilgrima271c542017-05-03 15:42:29 +0000947 break; // "btver1";
948 case 21:
949 *Type = AMDFAM15H;
Craig Topper1f9d3c02017-07-08 06:44:35 +0000950 if (Model >= 0x60 && Model <= 0x7f) {
Simon Pilgrima271c542017-05-03 15:42:29 +0000951 *Subtype = AMDFAM15H_BDVER4;
Craig Topper3db11702017-07-12 06:49:56 +0000952 break; // "bdver4"; 60h-7Fh: Excavator
Simon Pilgrima271c542017-05-03 15:42:29 +0000953 }
954 if (Model >= 0x30 && Model <= 0x3f) {
955 *Subtype = AMDFAM15H_BDVER3;
956 break; // "bdver3"; 30h-3Fh: Steamroller
957 }
958 if (Model >= 0x10 && Model <= 0x1f) {
959 *Subtype = AMDFAM15H_BDVER2;
960 break; // "bdver2"; 10h-1Fh: Piledriver
961 }
962 if (Model <= 0x0f) {
963 *Subtype = AMDFAM15H_BDVER1;
964 break; // "bdver1"; 00h-0Fh: Bulldozer
965 }
966 break;
967 case 22:
Craig Topperf3af64e2017-07-12 06:49:57 +0000968 *Type = AMD_BTVER2;
Simon Pilgrima271c542017-05-03 15:42:29 +0000969 break; // "btver2"
970 case 23:
971 *Type = AMDFAM17H;
Craig Topperffe672d2017-07-08 06:44:36 +0000972 *Subtype = AMDFAM17H_ZNVER1;
Simon Pilgrima271c542017-05-03 15:42:29 +0000973 break;
974 default:
975 break; // "generic"
976 }
977}
978
Craig Topper3a5d0822017-07-12 06:49:58 +0000979static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
980 unsigned *FeaturesOut,
981 unsigned *Features2Out) {
Simon Pilgrima271c542017-05-03 15:42:29 +0000982 unsigned Features = 0;
Craig Topper3a5d0822017-07-12 06:49:58 +0000983 unsigned Features2 = 0;
Craig Topperc6bbe4b2017-07-08 05:16:14 +0000984 unsigned EAX, EBX;
Craig Topper3a5d0822017-07-12 06:49:58 +0000985
986 if ((EDX >> 15) & 1)
987 Features |= 1 << FEATURE_CMOV;
988 if ((EDX >> 23) & 1)
989 Features |= 1 << FEATURE_MMX;
990 if ((EDX >> 25) & 1)
991 Features |= 1 << FEATURE_SSE;
992 if ((EDX >> 26) & 1)
993 Features |= 1 << FEATURE_SSE2;
994
995 if ((ECX >> 0) & 1)
996 Features |= 1 << FEATURE_SSE3;
997 if ((ECX >> 1) & 1)
998 Features |= 1 << FEATURE_PCLMUL;
999 if ((ECX >> 9) & 1)
1000 Features |= 1 << FEATURE_SSSE3;
1001 if ((ECX >> 12) & 1)
1002 Features |= 1 << FEATURE_FMA;
1003 if ((ECX >> 19) & 1)
1004 Features |= 1 << FEATURE_SSE4_1;
1005 if ((ECX >> 20) & 1)
1006 Features |= 1 << FEATURE_SSE4_2;
1007 if ((ECX >> 23) & 1)
1008 Features |= 1 << FEATURE_POPCNT;
1009 if ((ECX >> 25) & 1)
1010 Features |= 1 << FEATURE_AES;
1011
1012 if ((ECX >> 22) & 1)
1013 Features2 |= 1 << (FEATURE_MOVBE - 32);
Simon Pilgrima271c542017-05-03 15:42:29 +00001014
1015 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1016 // indicates that the AVX registers will be saved and restored on context
1017 // switch, then we have full AVX support.
1018 const unsigned AVXBits = (1 << 27) | (1 << 28);
1019 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
1020 ((EAX & 0x6) == 0x6);
1021 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
Craig Topper3a5d0822017-07-12 06:49:58 +00001022
1023 if (HasAVX)
1024 Features |= 1 << FEATURE_AVX;
1025
Simon Pilgrima271c542017-05-03 15:42:29 +00001026 bool HasLeaf7 =
1027 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
Craig Topper3a5d0822017-07-12 06:49:58 +00001028
1029 if (HasLeaf7 && ((EBX >> 3) & 1))
1030 Features |= 1 << FEATURE_BMI;
1031 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
1032 Features |= 1 << FEATURE_AVX2;
1033 if (HasLeaf7 && ((EBX >> 9) & 1))
1034 Features |= 1 << FEATURE_BMI2;
1035 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
1036 Features |= 1 << FEATURE_AVX512F;
1037 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
1038 Features |= 1 << FEATURE_AVX512DQ;
1039 if (HasLeaf7 && ((EBX >> 19) & 1))
1040 Features2 |= 1 << (FEATURE_ADX - 32);
1041 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
1042 Features |= 1 << FEATURE_AVX512IFMA;
Craig Topper4eda7562017-07-27 03:26:52 +00001043 if (HasLeaf7 && ((EBX >> 23) & 1))
1044 Features2 |= 1 << (FEATURE_CLFLUSHOPT - 32);
Craig Topper3a5d0822017-07-12 06:49:58 +00001045 if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
1046 Features |= 1 << FEATURE_AVX512PF;
1047 if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
1048 Features |= 1 << FEATURE_AVX512ER;
1049 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
1050 Features |= 1 << FEATURE_AVX512CD;
Craig Topper4eda7562017-07-27 03:26:52 +00001051 if (HasLeaf7 && ((EBX >> 29) & 1))
1052 Features2 |= 1 << (FEATURE_SHA - 32);
Craig Topper3a5d0822017-07-12 06:49:58 +00001053 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
1054 Features |= 1 << FEATURE_AVX512BW;
1055 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
1056 Features |= 1 << FEATURE_AVX512VL;
1057
1058 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
1059 Features |= 1 << FEATURE_AVX512VBMI;
1060 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
1061 Features |= 1 << FEATURE_AVX512VPOPCNTDQ;
1062
1063 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
1064 Features |= 1 << FEATURE_AVX5124VNNIW;
1065 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
1066 Features |= 1 << FEATURE_AVX5124FMAPS;
Simon Pilgrima271c542017-05-03 15:42:29 +00001067
Craig Topperbb8c7992017-07-08 05:16:13 +00001068 unsigned MaxExtLevel;
1069 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1070
1071 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1072 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
Craig Topper3a5d0822017-07-12 06:49:58 +00001073 if (HasExtLeaf1 && ((ECX >> 6) & 1))
1074 Features |= 1 << FEATURE_SSE4_A;
1075 if (HasExtLeaf1 && ((ECX >> 11) & 1))
1076 Features |= 1 << FEATURE_XOP;
1077 if (HasExtLeaf1 && ((ECX >> 16) & 1))
1078 Features |= 1 << FEATURE_FMA4;
Craig Topperbb8c7992017-07-08 05:16:13 +00001079
Craig Topper3a5d0822017-07-12 06:49:58 +00001080 if (HasExtLeaf1 && ((EDX >> 29) & 1))
1081 Features2 |= 1 << (FEATURE_EM64T - 32);
1082
1083 *FeaturesOut = Features;
1084 *Features2Out = Features2;
Simon Pilgrima271c542017-05-03 15:42:29 +00001085}
1086
1087StringRef sys::getHostCPUName() {
1088 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1089 unsigned MaxLeaf, Vendor;
1090
1091#if defined(__GNUC__) || defined(__clang__)
1092 //FIXME: include cpuid.h from clang or copy __get_cpuid_max here
1093 // and simplify it to not invoke __cpuid (like cpu_model.c in
1094 // compiler-rt/lib/builtins/cpu_model.c?
1095 // Opting for the second option.
1096 if(!isCpuIdSupported())
1097 return "generic";
1098#endif
Craig Topperbb8c7992017-07-08 05:16:13 +00001099 if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1)
Simon Pilgrima271c542017-05-03 15:42:29 +00001100 return "generic";
Craig Topperbb8c7992017-07-08 05:16:13 +00001101 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
Simon Pilgrima271c542017-05-03 15:42:29 +00001102
1103 unsigned Brand_id = EBX & 0xff;
1104 unsigned Family = 0, Model = 0;
Craig Topper3a5d0822017-07-12 06:49:58 +00001105 unsigned Features = 0, Features2 = 0;
Simon Pilgrima271c542017-05-03 15:42:29 +00001106 detectX86FamilyModel(EAX, &Family, &Model);
Craig Topper3a5d0822017-07-12 06:49:58 +00001107 getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2);
Simon Pilgrima271c542017-05-03 15:42:29 +00001108
1109 unsigned Type;
1110 unsigned Subtype;
1111
1112 if (Vendor == SIG_INTEL) {
Craig Topper3a5d0822017-07-12 06:49:58 +00001113 getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features,
1114 Features2, &Type, &Subtype);
Simon Pilgrima271c542017-05-03 15:42:29 +00001115 switch (Type) {
1116 case INTEL_i386:
1117 return "i386";
1118 case INTEL_i486:
1119 return "i486";
1120 case INTEL_PENTIUM:
1121 if (Subtype == INTEL_PENTIUM_MMX)
1122 return "pentium-mmx";
1123 return "pentium";
1124 case INTEL_PENTIUM_PRO:
1125 return "pentiumpro";
1126 case INTEL_PENTIUM_II:
1127 return "pentium2";
1128 case INTEL_PENTIUM_III:
1129 return "pentium3";
1130 case INTEL_PENTIUM_IV:
1131 return "pentium4";
1132 case INTEL_PENTIUM_M:
1133 return "pentium-m";
1134 case INTEL_CORE_DUO:
1135 return "yonah";
1136 case INTEL_CORE2:
1137 switch (Subtype) {
1138 case INTEL_CORE2_65:
1139 return "core2";
1140 case INTEL_CORE2_45:
1141 return "penryn";
1142 default:
Craig Topper3db11702017-07-12 06:49:56 +00001143 llvm_unreachable("Unexpected subtype!");
Simon Pilgrima271c542017-05-03 15:42:29 +00001144 }
1145 case INTEL_COREI7:
1146 switch (Subtype) {
1147 case INTEL_COREI7_NEHALEM:
1148 return "nehalem";
1149 case INTEL_COREI7_WESTMERE:
1150 return "westmere";
1151 case INTEL_COREI7_SANDYBRIDGE:
1152 return "sandybridge";
1153 case INTEL_COREI7_IVYBRIDGE:
1154 return "ivybridge";
1155 case INTEL_COREI7_HASWELL:
1156 return "haswell";
1157 case INTEL_COREI7_BROADWELL:
1158 return "broadwell";
1159 case INTEL_COREI7_SKYLAKE:
1160 return "skylake";
1161 case INTEL_COREI7_SKYLAKE_AVX512:
1162 return "skylake-avx512";
1163 default:
Craig Topper3db11702017-07-12 06:49:56 +00001164 llvm_unreachable("Unexpected subtype!");
Simon Pilgrima271c542017-05-03 15:42:29 +00001165 }
Craig Topperf3af64e2017-07-12 06:49:57 +00001166 case INTEL_BONNELL:
1167 return "bonnell";
1168 case INTEL_SILVERMONT:
1169 return "silvermont";
1170 case INTEL_GOLDMONT:
1171 return "goldmont";
1172 case INTEL_KNL:
1173 return "knl";
Craig Topper5d692912017-10-13 18:10:17 +00001174 case INTEL_KNM:
1175 return "knm";
Simon Pilgrima271c542017-05-03 15:42:29 +00001176 case INTEL_X86_64:
1177 return "x86-64";
1178 case INTEL_NOCONA:
1179 return "nocona";
1180 case INTEL_PRESCOTT:
1181 return "prescott";
1182 default:
Craig Topper3db11702017-07-12 06:49:56 +00001183 break;
Simon Pilgrima271c542017-05-03 15:42:29 +00001184 }
1185 } else if (Vendor == SIG_AMD) {
1186 getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
1187 switch (Type) {
1188 case AMD_i486:
1189 return "i486";
1190 case AMDPENTIUM:
1191 switch (Subtype) {
1192 case AMDPENTIUM_K6:
1193 return "k6";
1194 case AMDPENTIUM_K62:
1195 return "k6-2";
1196 case AMDPENTIUM_K63:
1197 return "k6-3";
1198 case AMDPENTIUM_GEODE:
1199 return "geode";
1200 default:
1201 return "pentium";
1202 }
1203 case AMDATHLON:
1204 switch (Subtype) {
Craig Topperf3de5eb2017-07-13 06:34:10 +00001205 case AMDATHLON_CLASSIC:
1206 return "athlon";
Simon Pilgrima271c542017-05-03 15:42:29 +00001207 case AMDATHLON_XP:
1208 return "athlon-xp";
Craig Topperf3de5eb2017-07-13 06:34:10 +00001209 case AMDATHLON_K8:
1210 return "k8";
Simon Pilgrima271c542017-05-03 15:42:29 +00001211 case AMDATHLON_K8SSE3:
1212 return "k8-sse3";
Simon Pilgrima271c542017-05-03 15:42:29 +00001213 default:
Craig Topper3db11702017-07-12 06:49:56 +00001214 llvm_unreachable("Unexpected subtype!");
Simon Pilgrima271c542017-05-03 15:42:29 +00001215 }
1216 case AMDFAM10H:
Simon Pilgrima271c542017-05-03 15:42:29 +00001217 return "amdfam10";
Craig Topperf3af64e2017-07-12 06:49:57 +00001218 case AMD_BTVER1:
Simon Pilgrima271c542017-05-03 15:42:29 +00001219 return "btver1";
1220 case AMDFAM15H:
1221 switch (Subtype) {
Craig Topper3db11702017-07-12 06:49:56 +00001222 default: // There are gaps in the subtype detection.
Simon Pilgrima271c542017-05-03 15:42:29 +00001223 case AMDFAM15H_BDVER1:
1224 return "bdver1";
1225 case AMDFAM15H_BDVER2:
1226 return "bdver2";
1227 case AMDFAM15H_BDVER3:
1228 return "bdver3";
1229 case AMDFAM15H_BDVER4:
1230 return "bdver4";
Simon Pilgrima271c542017-05-03 15:42:29 +00001231 }
Craig Topperf3af64e2017-07-12 06:49:57 +00001232 case AMD_BTVER2:
Craig Topper3db11702017-07-12 06:49:56 +00001233 return "btver2";
Simon Pilgrima271c542017-05-03 15:42:29 +00001234 case AMDFAM17H:
Craig Topper3db11702017-07-12 06:49:56 +00001235 return "znver1";
Simon Pilgrima271c542017-05-03 15:42:29 +00001236 default:
Craig Topper3db11702017-07-12 06:49:56 +00001237 break;
Simon Pilgrima271c542017-05-03 15:42:29 +00001238 }
1239 }
1240 return "generic";
1241}
1242
1243#elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
1244StringRef sys::getHostCPUName() {
1245 host_basic_info_data_t hostInfo;
1246 mach_msg_type_number_t infoCount;
1247
1248 infoCount = HOST_BASIC_INFO_COUNT;
1249 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
1250 &infoCount);
1251
1252 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
1253 return "generic";
1254
1255 switch (hostInfo.cpu_subtype) {
1256 case CPU_SUBTYPE_POWERPC_601:
1257 return "601";
1258 case CPU_SUBTYPE_POWERPC_602:
1259 return "602";
1260 case CPU_SUBTYPE_POWERPC_603:
1261 return "603";
1262 case CPU_SUBTYPE_POWERPC_603e:
1263 return "603e";
1264 case CPU_SUBTYPE_POWERPC_603ev:
1265 return "603ev";
1266 case CPU_SUBTYPE_POWERPC_604:
1267 return "604";
1268 case CPU_SUBTYPE_POWERPC_604e:
1269 return "604e";
1270 case CPU_SUBTYPE_POWERPC_620:
1271 return "620";
1272 case CPU_SUBTYPE_POWERPC_750:
1273 return "750";
1274 case CPU_SUBTYPE_POWERPC_7400:
1275 return "7400";
1276 case CPU_SUBTYPE_POWERPC_7450:
1277 return "7450";
1278 case CPU_SUBTYPE_POWERPC_970:
1279 return "970";
1280 default:;
1281 }
1282
1283 return "generic";
1284}
1285#elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
1286StringRef sys::getHostCPUName() {
1287 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1288 const StringRef& Content = P ? P->getBuffer() : "";
1289 return detail::getHostCPUNameForPowerPC(Content);
1290}
1291#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1292StringRef sys::getHostCPUName() {
1293 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1294 const StringRef& Content = P ? P->getBuffer() : "";
1295 return detail::getHostCPUNameForARM(Content);
1296}
1297#elif defined(__linux__) && defined(__s390x__)
1298StringRef sys::getHostCPUName() {
1299 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1300 const StringRef& Content = P ? P->getBuffer() : "";
1301 return detail::getHostCPUNameForS390x(Content);
1302}
1303#else
1304StringRef sys::getHostCPUName() { return "generic"; }
1305#endif
1306
1307#if defined(__linux__) && defined(__x86_64__)
1308// On Linux, the number of physical cores can be computed from /proc/cpuinfo,
1309// using the number of unique physical/core id pairs. The following
1310// implementation reads the /proc/cpuinfo format on an x86_64 system.
1311static int computeHostNumPhysicalCores() {
1312 // Read /proc/cpuinfo as a stream (until EOF reached). It cannot be
1313 // mmapped because it appears to have 0 size.
1314 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
1315 llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
1316 if (std::error_code EC = Text.getError()) {
1317 llvm::errs() << "Can't read "
1318 << "/proc/cpuinfo: " << EC.message() << "\n";
1319 return -1;
1320 }
1321 SmallVector<StringRef, 8> strs;
1322 (*Text)->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
1323 /*KeepEmpty=*/false);
1324 int CurPhysicalId = -1;
1325 int CurCoreId = -1;
1326 SmallSet<std::pair<int, int>, 32> UniqueItems;
1327 for (auto &Line : strs) {
1328 Line = Line.trim();
1329 if (!Line.startswith("physical id") && !Line.startswith("core id"))
1330 continue;
1331 std::pair<StringRef, StringRef> Data = Line.split(':');
1332 auto Name = Data.first.trim();
1333 auto Val = Data.second.trim();
1334 if (Name == "physical id") {
1335 assert(CurPhysicalId == -1 &&
1336 "Expected a core id before seeing another physical id");
1337 Val.getAsInteger(10, CurPhysicalId);
1338 }
1339 if (Name == "core id") {
1340 assert(CurCoreId == -1 &&
1341 "Expected a physical id before seeing another core id");
1342 Val.getAsInteger(10, CurCoreId);
1343 }
1344 if (CurPhysicalId != -1 && CurCoreId != -1) {
1345 UniqueItems.insert(std::make_pair(CurPhysicalId, CurCoreId));
1346 CurPhysicalId = -1;
1347 CurCoreId = -1;
1348 }
1349 }
1350 return UniqueItems.size();
1351}
1352#elif defined(__APPLE__) && defined(__x86_64__)
1353#include <sys/param.h>
1354#include <sys/sysctl.h>
1355
1356// Gets the number of *physical cores* on the machine.
1357static int computeHostNumPhysicalCores() {
1358 uint32_t count;
1359 size_t len = sizeof(count);
1360 sysctlbyname("hw.physicalcpu", &count, &len, NULL, 0);
1361 if (count < 1) {
1362 int nm[2];
1363 nm[0] = CTL_HW;
1364 nm[1] = HW_AVAILCPU;
1365 sysctl(nm, 2, &count, &len, NULL, 0);
1366 if (count < 1)
1367 return -1;
1368 }
1369 return count;
1370}
1371#else
1372// On other systems, return -1 to indicate unknown.
1373static int computeHostNumPhysicalCores() { return -1; }
1374#endif
1375
1376int sys::getHostNumPhysicalCores() {
1377 static int NumCores = computeHostNumPhysicalCores();
1378 return NumCores;
1379}
1380
1381#if defined(__i386__) || defined(_M_IX86) || \
1382 defined(__x86_64__) || defined(_M_X64)
1383bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
1384 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1385 unsigned MaxLevel;
1386 union {
1387 unsigned u[3];
1388 char c[12];
1389 } text;
1390
1391 if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
1392 MaxLevel < 1)
1393 return false;
1394
1395 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1396
1397 Features["cmov"] = (EDX >> 15) & 1;
1398 Features["mmx"] = (EDX >> 23) & 1;
1399 Features["sse"] = (EDX >> 25) & 1;
1400 Features["sse2"] = (EDX >> 26) & 1;
1401 Features["sse3"] = (ECX >> 0) & 1;
1402 Features["ssse3"] = (ECX >> 9) & 1;
1403 Features["sse4.1"] = (ECX >> 19) & 1;
1404 Features["sse4.2"] = (ECX >> 20) & 1;
1405
1406 Features["pclmul"] = (ECX >> 1) & 1;
1407 Features["cx16"] = (ECX >> 13) & 1;
1408 Features["movbe"] = (ECX >> 22) & 1;
1409 Features["popcnt"] = (ECX >> 23) & 1;
1410 Features["aes"] = (ECX >> 25) & 1;
1411 Features["rdrnd"] = (ECX >> 30) & 1;
1412
1413 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1414 // indicates that the AVX registers will be saved and restored on context
1415 // switch, then we have full AVX support.
1416 bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
1417 !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
1418 Features["avx"] = HasAVXSave;
1419 Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
1420 Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;
1421
1422 // Only enable XSAVE if OS has enabled support for saving YMM state.
1423 Features["xsave"] = HasAVXSave && (ECX >> 26) & 1;
1424
1425 // AVX512 requires additional context to be saved by the OS.
1426 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
1427
1428 unsigned MaxExtLevel;
1429 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1430
1431 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1432 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1433 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1434 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1435 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1436 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
Simon Pilgrim99b925b2017-05-03 15:51:39 +00001437 Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
Simon Pilgrima271c542017-05-03 15:42:29 +00001438 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1439 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
1440 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
1441
1442 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
1443 !getX86CpuIDAndInfoEx(0x80000008,0x0, &EAX, &EBX, &ECX, &EDX);
1444 Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1);
1445
1446 bool HasLeaf7 =
1447 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1448
1449 // AVX2 is only supported if we have the OS save support from AVX.
1450 Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
1451
1452 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
1453 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
1454 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
1455 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
1456 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
1457 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
1458 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
1459 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
1460 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
1461 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
1462
1463 // AVX512 is only supported if the OS supports the context save for it.
1464 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
1465 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
1466 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
1467 Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
1468 Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
1469 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
1470 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
1471 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
1472
1473 Features["prefetchwt1"] = HasLeaf7 && (ECX & 1);
1474 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
Yonghong Songdc1dbf62017-08-23 04:25:57 +00001475 Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
Simon Pilgrima271c542017-05-03 15:42:29 +00001476 // Enable protection keys
1477 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
1478
1479 bool HasLeafD = MaxLevel >= 0xd &&
1480 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
1481
1482 // Only enable XSAVE if OS has enabled support for saving YMM state.
1483 Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
1484 Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
1485 Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);
1486
1487 return true;
1488}
1489#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1490bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
1491 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1492 if (!P)
1493 return false;
1494
1495 SmallVector<StringRef, 32> Lines;
1496 P->getBuffer().split(Lines, "\n");
1497
1498 SmallVector<StringRef, 32> CPUFeatures;
1499
1500 // Look for the CPU features.
1501 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1502 if (Lines[I].startswith("Features")) {
1503 Lines[I].split(CPUFeatures, ' ');
1504 break;
1505 }
1506
1507#if defined(__aarch64__)
1508 // Keep track of which crypto features we have seen
1509 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1510 uint32_t crypto = 0;
1511#endif
1512
1513 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
1514 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
1515#if defined(__aarch64__)
1516 .Case("asimd", "neon")
1517 .Case("fp", "fp-armv8")
1518 .Case("crc32", "crc")
1519#else
1520 .Case("half", "fp16")
1521 .Case("neon", "neon")
1522 .Case("vfpv3", "vfp3")
1523 .Case("vfpv3d16", "d16")
1524 .Case("vfpv4", "vfp4")
1525 .Case("idiva", "hwdiv-arm")
1526 .Case("idivt", "hwdiv")
1527#endif
1528 .Default("");
1529
1530#if defined(__aarch64__)
1531 // We need to check crypto separately since we need all of the crypto
1532 // extensions to enable the subtarget feature
1533 if (CPUFeatures[I] == "aes")
1534 crypto |= CAP_AES;
1535 else if (CPUFeatures[I] == "pmull")
1536 crypto |= CAP_PMULL;
1537 else if (CPUFeatures[I] == "sha1")
1538 crypto |= CAP_SHA1;
1539 else if (CPUFeatures[I] == "sha2")
1540 crypto |= CAP_SHA2;
1541#endif
1542
1543 if (LLVMFeatureStr != "")
1544 Features[LLVMFeatureStr] = true;
1545 }
1546
1547#if defined(__aarch64__)
1548 // If we have all crypto bits we can add the feature
1549 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
1550 Features["crypto"] = true;
1551#endif
1552
1553 return true;
1554}
1555#else
1556bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
1557#endif
1558
1559std::string sys::getProcessTriple() {
Alex Lorenz3803df32017-07-07 09:53:47 +00001560 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
1561 Triple PT(Triple::normalize(TargetTripleString));
Simon Pilgrima271c542017-05-03 15:42:29 +00001562
1563 if (sizeof(void *) == 8 && PT.isArch32Bit())
1564 PT = PT.get64BitArchVariant();
1565 if (sizeof(void *) == 4 && PT.isArch64Bit())
1566 PT = PT.get32BitArchVariant();
1567
1568 return PT.str();
1569}