LLVM 19.0.0git
Host.cpp
Go to the documentation of this file.
1//===-- Host.cpp - Implement OS Host Detection ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the operating system Host detection.
10//
11//===----------------------------------------------------------------------===//
12
15#include "llvm/ADT/StringMap.h"
16#include "llvm/ADT/StringRef.h"
18#include "llvm/Config/llvm-config.h"
23#include <string.h>
24
25// Include the platform-specific parts of this class.
26#ifdef LLVM_ON_UNIX
27#include "Unix/Host.inc"
28#include <sched.h>
29#endif
30#ifdef _WIN32
31#include "Windows/Host.inc"
32#endif
33#ifdef _MSC_VER
34#include <intrin.h>
35#endif
36#ifdef __MVS__
37#include "llvm/Support/BCD.h"
38#endif
39#if defined(__APPLE__)
40#include <mach/host_info.h>
41#include <mach/mach.h>
42#include <mach/mach_host.h>
43#include <mach/machine.h>
44#include <sys/param.h>
45#include <sys/sysctl.h>
46#endif
47#ifdef _AIX
48#include <sys/systemcfg.h>
49#endif
50#if defined(__sun__) && defined(__svr4__)
51#include <kstat.h>
52#endif
53
54#define DEBUG_TYPE "host-detection"
55
56//===----------------------------------------------------------------------===//
57//
58// Implementations of the CPU detection routines
59//
60//===----------------------------------------------------------------------===//
61
62using namespace llvm;
63
64static std::unique_ptr<llvm::MemoryBuffer>
68 if (std::error_code EC = Text.getError()) {
69 llvm::errs() << "Can't read "
70 << "/proc/cpuinfo: " << EC.message() << "\n";
71 return nullptr;
72 }
73 return std::move(*Text);
74}
75
77 // Access to the Processor Version Register (PVR) on PowerPC is privileged,
78 // and so we must use an operating-system interface to determine the current
79 // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
80 const char *generic = "generic";
81
82 // The cpu line is second (after the 'processor: 0' line), so if this
83 // buffer is too small then something has changed (or is wrong).
84 StringRef::const_iterator CPUInfoStart = ProcCpuinfoContent.begin();
85 StringRef::const_iterator CPUInfoEnd = ProcCpuinfoContent.end();
86
87 StringRef::const_iterator CIP = CPUInfoStart;
88
89 StringRef::const_iterator CPUStart = nullptr;
90 size_t CPULen = 0;
91
92 // We need to find the first line which starts with cpu, spaces, and a colon.
93 // After the colon, there may be some additional spaces and then the cpu type.
94 while (CIP < CPUInfoEnd && CPUStart == nullptr) {
95 if (CIP < CPUInfoEnd && *CIP == '\n')
96 ++CIP;
97
98 if (CIP < CPUInfoEnd && *CIP == 'c') {
99 ++CIP;
100 if (CIP < CPUInfoEnd && *CIP == 'p') {
101 ++CIP;
102 if (CIP < CPUInfoEnd && *CIP == 'u') {
103 ++CIP;
104 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
105 ++CIP;
106
107 if (CIP < CPUInfoEnd && *CIP == ':') {
108 ++CIP;
109 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
110 ++CIP;
111
112 if (CIP < CPUInfoEnd) {
113 CPUStart = CIP;
114 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
115 *CIP != ',' && *CIP != '\n'))
116 ++CIP;
117 CPULen = CIP - CPUStart;
118 }
119 }
120 }
121 }
122 }
123
124 if (CPUStart == nullptr)
125 while (CIP < CPUInfoEnd && *CIP != '\n')
126 ++CIP;
127 }
128
129 if (CPUStart == nullptr)
130 return generic;
131
132 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
133 .Case("604e", "604e")
134 .Case("604", "604")
135 .Case("7400", "7400")
136 .Case("7410", "7400")
137 .Case("7447", "7400")
138 .Case("7455", "7450")
139 .Case("G4", "g4")
140 .Case("POWER4", "970")
141 .Case("PPC970FX", "970")
142 .Case("PPC970MP", "970")
143 .Case("G5", "g5")
144 .Case("POWER5", "g5")
145 .Case("A2", "a2")
146 .Case("POWER6", "pwr6")
147 .Case("POWER7", "pwr7")
148 .Case("POWER8", "pwr8")
149 .Case("POWER8E", "pwr8")
150 .Case("POWER8NVL", "pwr8")
151 .Case("POWER9", "pwr9")
152 .Case("POWER10", "pwr10")
153 // FIXME: If we get a simulator or machine with the capabilities of
154 // mcpu=future, we should revisit this and add the name reported by the
155 // simulator/machine.
156 .Default(generic);
157}
158
160 // The cpuid register on arm is not accessible from user space. On Linux,
161 // it is exposed through the /proc/cpuinfo file.
162
163 // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line
164 // in all cases.
166 ProcCpuinfoContent.split(Lines, "\n");
167
168 // Look for the CPU implementer line.
169 StringRef Implementer;
170 StringRef Hardware;
171 StringRef Part;
172 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
173 if (Lines[I].starts_with("CPU implementer"))
174 Implementer = Lines[I].substr(15).ltrim("\t :");
175 if (Lines[I].starts_with("Hardware"))
176 Hardware = Lines[I].substr(8).ltrim("\t :");
177 if (Lines[I].starts_with("CPU part"))
178 Part = Lines[I].substr(8).ltrim("\t :");
179 }
180
181 if (Implementer == "0x41") { // ARM Ltd.
182 // MSM8992/8994 may give cpu part for the core that the kernel is running on,
183 // which is undeterministic and wrong. Always return cortex-a53 for these SoC.
184 if (Hardware.ends_with("MSM8994") || Hardware.ends_with("MSM8996"))
185 return "cortex-a53";
186
187
188 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
189 // values correspond to the "Part number" in the CP15/c0 register. The
190 // contents are specified in the various processor manuals.
191 // This corresponds to the Main ID Register in Technical Reference Manuals.
192 // and is used in programs like sys-utils
193 return StringSwitch<const char *>(Part)
194 .Case("0x926", "arm926ej-s")
195 .Case("0xb02", "mpcore")
196 .Case("0xb36", "arm1136j-s")
197 .Case("0xb56", "arm1156t2-s")
198 .Case("0xb76", "arm1176jz-s")
199 .Case("0xc05", "cortex-a5")
200 .Case("0xc07", "cortex-a7")
201 .Case("0xc08", "cortex-a8")
202 .Case("0xc09", "cortex-a9")
203 .Case("0xc0f", "cortex-a15")
204 .Case("0xc0e", "cortex-a17")
205 .Case("0xc20", "cortex-m0")
206 .Case("0xc23", "cortex-m3")
207 .Case("0xc24", "cortex-m4")
208 .Case("0xc27", "cortex-m7")
209 .Case("0xd20", "cortex-m23")
210 .Case("0xd21", "cortex-m33")
211 .Case("0xd24", "cortex-m52")
212 .Case("0xd22", "cortex-m55")
213 .Case("0xd23", "cortex-m85")
214 .Case("0xc18", "cortex-r8")
215 .Case("0xd13", "cortex-r52")
216 .Case("0xd15", "cortex-r82")
217 .Case("0xd02", "cortex-a34")
218 .Case("0xd04", "cortex-a35")
219 .Case("0xd03", "cortex-a53")
220 .Case("0xd05", "cortex-a55")
221 .Case("0xd46", "cortex-a510")
222 .Case("0xd80", "cortex-a520")
223 .Case("0xd88", "cortex-a520ae")
224 .Case("0xd07", "cortex-a57")
225 .Case("0xd06", "cortex-a65")
226 .Case("0xd43", "cortex-a65ae")
227 .Case("0xd08", "cortex-a72")
228 .Case("0xd09", "cortex-a73")
229 .Case("0xd0a", "cortex-a75")
230 .Case("0xd0b", "cortex-a76")
231 .Case("0xd0e", "cortex-a76ae")
232 .Case("0xd0d", "cortex-a77")
233 .Case("0xd41", "cortex-a78")
234 .Case("0xd42", "cortex-a78ae")
235 .Case("0xd4b", "cortex-a78c")
236 .Case("0xd47", "cortex-a710")
237 .Case("0xd4d", "cortex-a715")
238 .Case("0xd81", "cortex-a720")
239 .Case("0xd89", "cortex-a720ae")
240 .Case("0xd44", "cortex-x1")
241 .Case("0xd4c", "cortex-x1c")
242 .Case("0xd48", "cortex-x2")
243 .Case("0xd4e", "cortex-x3")
244 .Case("0xd82", "cortex-x4")
245 .Case("0xd4a", "neoverse-e1")
246 .Case("0xd0c", "neoverse-n1")
247 .Case("0xd49", "neoverse-n2")
248 .Case("0xd8e", "neoverse-n3")
249 .Case("0xd40", "neoverse-v1")
250 .Case("0xd4f", "neoverse-v2")
251 .Case("0xd84", "neoverse-v3")
252 .Case("0xd83", "neoverse-v3ae")
253 .Default("generic");
254 }
255
256 if (Implementer == "0x42" || Implementer == "0x43") { // Broadcom | Cavium.
257 return StringSwitch<const char *>(Part)
258 .Case("0x516", "thunderx2t99")
259 .Case("0x0516", "thunderx2t99")
260 .Case("0xaf", "thunderx2t99")
261 .Case("0x0af", "thunderx2t99")
262 .Case("0xa1", "thunderxt88")
263 .Case("0x0a1", "thunderxt88")
264 .Default("generic");
265 }
266
267 if (Implementer == "0x46") { // Fujitsu Ltd.
268 return StringSwitch<const char *>(Part)
269 .Case("0x001", "a64fx")
270 .Default("generic");
271 }
272
273 if (Implementer == "0x4e") { // NVIDIA Corporation
274 return StringSwitch<const char *>(Part)
275 .Case("0x004", "carmel")
276 .Default("generic");
277 }
278
279 if (Implementer == "0x48") // HiSilicon Technologies, Inc.
280 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
281 // values correspond to the "Part number" in the CP15/c0 register. The
282 // contents are specified in the various processor manuals.
283 return StringSwitch<const char *>(Part)
284 .Case("0xd01", "tsv110")
285 .Default("generic");
286
287 if (Implementer == "0x51") // Qualcomm Technologies, Inc.
288 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
289 // values correspond to the "Part number" in the CP15/c0 register. The
290 // contents are specified in the various processor manuals.
291 return StringSwitch<const char *>(Part)
292 .Case("0x06f", "krait") // APQ8064
293 .Case("0x201", "kryo")
294 .Case("0x205", "kryo")
295 .Case("0x211", "kryo")
296 .Case("0x800", "cortex-a73") // Kryo 2xx Gold
297 .Case("0x801", "cortex-a73") // Kryo 2xx Silver
298 .Case("0x802", "cortex-a75") // Kryo 3xx Gold
299 .Case("0x803", "cortex-a75") // Kryo 3xx Silver
300 .Case("0x804", "cortex-a76") // Kryo 4xx Gold
301 .Case("0x805", "cortex-a76") // Kryo 4xx/5xx Silver
302 .Case("0xc00", "falkor")
303 .Case("0xc01", "saphira")
304 .Default("generic");
305 if (Implementer == "0x53") { // Samsung Electronics Co., Ltd.
306 // The Exynos chips have a convoluted ID scheme that doesn't seem to follow
307 // any predictive pattern across variants and parts.
308 unsigned Variant = 0, Part = 0;
309
310 // Look for the CPU variant line, whose value is a 1 digit hexadecimal
311 // number, corresponding to the Variant bits in the CP15/C0 register.
312 for (auto I : Lines)
313 if (I.consume_front("CPU variant"))
314 I.ltrim("\t :").getAsInteger(0, Variant);
315
316 // Look for the CPU part line, whose value is a 3 digit hexadecimal
317 // number, corresponding to the PartNum bits in the CP15/C0 register.
318 for (auto I : Lines)
319 if (I.consume_front("CPU part"))
320 I.ltrim("\t :").getAsInteger(0, Part);
321
322 unsigned Exynos = (Variant << 12) | Part;
323 switch (Exynos) {
324 default:
325 // Default by falling through to Exynos M3.
326 [[fallthrough]];
327 case 0x1002:
328 return "exynos-m3";
329 case 0x1003:
330 return "exynos-m4";
331 }
332 }
333
334 if (Implementer == "0x6d") { // Microsoft Corporation.
335 // The Microsoft Azure Cobalt 100 CPU is handled as a Neoverse N2.
336 return StringSwitch<const char *>(Part)
337 .Case("0xd49", "neoverse-n2")
338 .Default("generic");
339 }
340
341 if (Implementer == "0xc0") { // Ampere Computing
342 return StringSwitch<const char *>(Part)
343 .Case("0xac3", "ampere1")
344 .Case("0xac4", "ampere1a")
345 .Case("0xac5", "ampere1b")
346 .Default("generic");
347 }
348
349 return "generic";
350}
351
352namespace {
353StringRef getCPUNameFromS390Model(unsigned int Id, bool HaveVectorSupport) {
354 switch (Id) {
355 case 2064: // z900 not supported by LLVM
356 case 2066:
357 case 2084: // z990 not supported by LLVM
358 case 2086:
359 case 2094: // z9-109 not supported by LLVM
360 case 2096:
361 return "generic";
362 case 2097:
363 case 2098:
364 return "z10";
365 case 2817:
366 case 2818:
367 return "z196";
368 case 2827:
369 case 2828:
370 return "zEC12";
371 case 2964:
372 case 2965:
373 return HaveVectorSupport? "z13" : "zEC12";
374 case 3906:
375 case 3907:
376 return HaveVectorSupport? "z14" : "zEC12";
377 case 8561:
378 case 8562:
379 return HaveVectorSupport? "z15" : "zEC12";
380 case 3931:
381 case 3932:
382 default:
383 return HaveVectorSupport? "z16" : "zEC12";
384 }
385}
386} // end anonymous namespace
387
389 // STIDP is a privileged operation, so use /proc/cpuinfo instead.
390
391 // The "processor 0:" line comes after a fair amount of other information,
392 // including a cache breakdown, but this should be plenty.
394 ProcCpuinfoContent.split(Lines, "\n");
395
396 // Look for the CPU features.
397 SmallVector<StringRef, 32> CPUFeatures;
398 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
399 if (Lines[I].starts_with("features")) {
400 size_t Pos = Lines[I].find(':');
401 if (Pos != StringRef::npos) {
402 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
403 break;
404 }
405 }
406
407 // We need to check for the presence of vector support independently of
408 // the machine type, since we may only use the vector register set when
409 // supported by the kernel (and hypervisor).
410 bool HaveVectorSupport = false;
411 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
412 if (CPUFeatures[I] == "vx")
413 HaveVectorSupport = true;
414 }
415
416 // Now check the processor machine type.
417 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
418 if (Lines[I].starts_with("processor ")) {
419 size_t Pos = Lines[I].find("machine = ");
420 if (Pos != StringRef::npos) {
421 Pos += sizeof("machine = ") - 1;
422 unsigned int Id;
423 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id))
424 return getCPUNameFromS390Model(Id, HaveVectorSupport);
425 }
426 break;
427 }
428 }
429
430 return "generic";
431}
432
434 // There are 24 lines in /proc/cpuinfo
436 ProcCpuinfoContent.split(Lines, "\n");
437
438 // Look for uarch line to determine cpu name
439 StringRef UArch;
440 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
441 if (Lines[I].starts_with("uarch")) {
442 UArch = Lines[I].substr(5).ltrim("\t :");
443 break;
444 }
445 }
446
447 return StringSwitch<const char *>(UArch)
448 .Case("sifive,u74-mc", "sifive-u74")
449 .Case("sifive,bullet0", "sifive-u74")
450 .Default("generic");
451}
452
454#if !defined(__linux__) || !defined(__x86_64__)
455 return "generic";
456#else
457 uint8_t v3_insns[40] __attribute__ ((aligned (8))) =
458 /* BPF_MOV64_IMM(BPF_REG_0, 0) */
459 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
460 /* BPF_MOV64_IMM(BPF_REG_2, 1) */
461 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
462 /* BPF_JMP32_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
463 0xae, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
464 /* BPF_MOV64_IMM(BPF_REG_0, 1) */
465 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
466 /* BPF_EXIT_INSN() */
467 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
468
469 uint8_t v2_insns[40] __attribute__ ((aligned (8))) =
470 /* BPF_MOV64_IMM(BPF_REG_0, 0) */
471 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
472 /* BPF_MOV64_IMM(BPF_REG_2, 1) */
473 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
474 /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
475 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
476 /* BPF_MOV64_IMM(BPF_REG_0, 1) */
477 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
478 /* BPF_EXIT_INSN() */
479 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
480
481 struct bpf_prog_load_attr {
482 uint32_t prog_type;
483 uint32_t insn_cnt;
484 uint64_t insns;
485 uint64_t license;
486 uint32_t log_level;
487 uint32_t log_size;
488 uint64_t log_buf;
489 uint32_t kern_version;
490 uint32_t prog_flags;
491 } attr = {};
492 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
493 attr.insn_cnt = 5;
494 attr.insns = (uint64_t)v3_insns;
495 attr.license = (uint64_t)"DUMMY";
496
497 int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr,
498 sizeof(attr));
499 if (fd >= 0) {
500 close(fd);
501 return "v3";
502 }
503
504 /* Clear the whole attr in case its content changed by syscall. */
505 memset(&attr, 0, sizeof(attr));
506 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
507 attr.insn_cnt = 5;
508 attr.insns = (uint64_t)v2_insns;
509 attr.license = (uint64_t)"DUMMY";
510 fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr));
511 if (fd >= 0) {
512 close(fd);
513 return "v2";
514 }
515 return "v1";
516#endif
517}
518
519#if defined(__i386__) || defined(_M_IX86) || \
520 defined(__x86_64__) || defined(_M_X64)
521
522// The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
523// Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
524// support. Consequently, for i386, the presence of CPUID is checked first
525// via the corresponding eflags bit.
526// Removal of cpuid.h header motivated by PR30384
527// Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
528// or test-suite, but are used in external projects e.g. libstdcxx
529static bool isCpuIdSupported() {
530#if defined(__GNUC__) || defined(__clang__)
531#if defined(__i386__)
532 int __cpuid_supported;
533 __asm__(" pushfl\n"
534 " popl %%eax\n"
535 " movl %%eax,%%ecx\n"
536 " xorl $0x00200000,%%eax\n"
537 " pushl %%eax\n"
538 " popfl\n"
539 " pushfl\n"
540 " popl %%eax\n"
541 " movl $0,%0\n"
542 " cmpl %%eax,%%ecx\n"
543 " je 1f\n"
544 " movl $1,%0\n"
545 "1:"
546 : "=r"(__cpuid_supported)
547 :
548 : "eax", "ecx");
549 if (!__cpuid_supported)
550 return false;
551#endif
552 return true;
553#endif
554 return true;
555}
556
557/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
558/// the specified arguments. If we can't run cpuid on the host, return true.
559static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
560 unsigned *rECX, unsigned *rEDX) {
561#if defined(__GNUC__) || defined(__clang__)
562#if defined(__x86_64__)
563 // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
564 // FIXME: should we save this for Clang?
565 __asm__("movq\t%%rbx, %%rsi\n\t"
566 "cpuid\n\t"
567 "xchgq\t%%rbx, %%rsi\n\t"
568 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
569 : "a"(value));
570 return false;
571#elif defined(__i386__)
572 __asm__("movl\t%%ebx, %%esi\n\t"
573 "cpuid\n\t"
574 "xchgl\t%%ebx, %%esi\n\t"
575 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
576 : "a"(value));
577 return false;
578#else
579 return true;
580#endif
581#elif defined(_MSC_VER)
582 // The MSVC intrinsic is portable across x86 and x64.
583 int registers[4];
584 __cpuid(registers, value);
585 *rEAX = registers[0];
586 *rEBX = registers[1];
587 *rECX = registers[2];
588 *rEDX = registers[3];
589 return false;
590#else
591 return true;
592#endif
593}
594
595namespace llvm {
596namespace sys {
597namespace detail {
598namespace x86 {
599
600VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
601 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
602 if (MaxLeaf == nullptr)
603 MaxLeaf = &EAX;
604 else
605 *MaxLeaf = 0;
606
607 if (!isCpuIdSupported())
608 return VendorSignatures::UNKNOWN;
609
610 if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1)
611 return VendorSignatures::UNKNOWN;
612
613 // "Genu ineI ntel"
614 if (EBX == 0x756e6547 && EDX == 0x49656e69 && ECX == 0x6c65746e)
615 return VendorSignatures::GENUINE_INTEL;
616
617 // "Auth enti cAMD"
618 if (EBX == 0x68747541 && EDX == 0x69746e65 && ECX == 0x444d4163)
619 return VendorSignatures::AUTHENTIC_AMD;
620
621 return VendorSignatures::UNKNOWN;
622}
623
624} // namespace x86
625} // namespace detail
626} // namespace sys
627} // namespace llvm
628
629using namespace llvm::sys::detail::x86;
630
631/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
632/// the 4 values in the specified arguments. If we can't run cpuid on the host,
633/// return true.
634static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
635 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
636 unsigned *rEDX) {
637#if defined(__GNUC__) || defined(__clang__)
638#if defined(__x86_64__)
639 // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
640 // FIXME: should we save this for Clang?
641 __asm__("movq\t%%rbx, %%rsi\n\t"
642 "cpuid\n\t"
643 "xchgq\t%%rbx, %%rsi\n\t"
644 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
645 : "a"(value), "c"(subleaf));
646 return false;
647#elif defined(__i386__)
648 __asm__("movl\t%%ebx, %%esi\n\t"
649 "cpuid\n\t"
650 "xchgl\t%%ebx, %%esi\n\t"
651 : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
652 : "a"(value), "c"(subleaf));
653 return false;
654#else
655 return true;
656#endif
657#elif defined(_MSC_VER)
658 int registers[4];
659 __cpuidex(registers, value, subleaf);
660 *rEAX = registers[0];
661 *rEBX = registers[1];
662 *rECX = registers[2];
663 *rEDX = registers[3];
664 return false;
665#else
666 return true;
667#endif
668}
669
670// Read control register 0 (XCR0). Used to detect features such as AVX.
671static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
672#if defined(__GNUC__) || defined(__clang__)
673 // Check xgetbv; this uses a .byte sequence instead of the instruction
674 // directly because older assemblers do not include support for xgetbv and
675 // there is no easy way to conditionally compile based on the assembler used.
676 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
677 return false;
678#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
679 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
680 *rEAX = Result;
681 *rEDX = Result >> 32;
682 return false;
683#else
684 return true;
685#endif
686}
687
688static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
689 unsigned *Model) {
690 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
691 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
692 if (*Family == 6 || *Family == 0xf) {
693 if (*Family == 0xf)
694 // Examine extended family ID if family ID is F.
695 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
696 // Examine extended model ID if family ID is 6 or F.
697 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
698 }
699}
700
701static StringRef
702getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
703 const unsigned *Features,
704 unsigned *Type, unsigned *Subtype) {
705 auto testFeature = [&](unsigned F) {
706 return (Features[F / 32] & (1U << (F % 32))) != 0;
707 };
708
709 StringRef CPU;
710
711 switch (Family) {
712 case 3:
713 CPU = "i386";
714 break;
715 case 4:
716 CPU = "i486";
717 break;
718 case 5:
719 if (testFeature(X86::FEATURE_MMX)) {
720 CPU = "pentium-mmx";
721 break;
722 }
723 CPU = "pentium";
724 break;
725 case 6:
726 switch (Model) {
727 case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
728 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
729 // mobile processor, Intel Core 2 Extreme processor, Intel
730 // Pentium Dual-Core processor, Intel Xeon processor, model
731 // 0Fh. All processors are manufactured using the 65 nm process.
732 case 0x16: // Intel Celeron processor model 16h. All processors are
733 // manufactured using the 65 nm process
734 CPU = "core2";
735 *Type = X86::INTEL_CORE2;
736 break;
737 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
738 // 17h. All processors are manufactured using the 45 nm process.
739 //
740 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
741 case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
742 // the 45 nm process.
743 CPU = "penryn";
744 *Type = X86::INTEL_CORE2;
745 break;
746 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
747 // processors are manufactured using the 45 nm process.
748 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
749 // As found in a Summer 2010 model iMac.
750 case 0x1f:
751 case 0x2e: // Nehalem EX
752 CPU = "nehalem";
753 *Type = X86::INTEL_COREI7;
754 *Subtype = X86::INTEL_COREI7_NEHALEM;
755 break;
756 case 0x25: // Intel Core i7, laptop version.
757 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
758 // processors are manufactured using the 32 nm process.
759 case 0x2f: // Westmere EX
760 CPU = "westmere";
761 *Type = X86::INTEL_COREI7;
762 *Subtype = X86::INTEL_COREI7_WESTMERE;
763 break;
764 case 0x2a: // Intel Core i7 processor. All processors are manufactured
765 // using the 32 nm process.
766 case 0x2d:
767 CPU = "sandybridge";
768 *Type = X86::INTEL_COREI7;
769 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
770 break;
771 case 0x3a:
772 case 0x3e: // Ivy Bridge EP
773 CPU = "ivybridge";
774 *Type = X86::INTEL_COREI7;
775 *Subtype = X86::INTEL_COREI7_IVYBRIDGE;
776 break;
777
778 // Haswell:
779 case 0x3c:
780 case 0x3f:
781 case 0x45:
782 case 0x46:
783 CPU = "haswell";
784 *Type = X86::INTEL_COREI7;
785 *Subtype = X86::INTEL_COREI7_HASWELL;
786 break;
787
788 // Broadwell:
789 case 0x3d:
790 case 0x47:
791 case 0x4f:
792 case 0x56:
793 CPU = "broadwell";
794 *Type = X86::INTEL_COREI7;
795 *Subtype = X86::INTEL_COREI7_BROADWELL;
796 break;
797
798 // Skylake:
799 case 0x4e: // Skylake mobile
800 case 0x5e: // Skylake desktop
801 case 0x8e: // Kaby Lake mobile
802 case 0x9e: // Kaby Lake desktop
803 case 0xa5: // Comet Lake-H/S
804 case 0xa6: // Comet Lake-U
805 CPU = "skylake";
806 *Type = X86::INTEL_COREI7;
807 *Subtype = X86::INTEL_COREI7_SKYLAKE;
808 break;
809
810 // Rocketlake:
811 case 0xa7:
812 CPU = "rocketlake";
813 *Type = X86::INTEL_COREI7;
814 *Subtype = X86::INTEL_COREI7_ROCKETLAKE;
815 break;
816
817 // Skylake Xeon:
818 case 0x55:
819 *Type = X86::INTEL_COREI7;
820 if (testFeature(X86::FEATURE_AVX512BF16)) {
821 CPU = "cooperlake";
822 *Subtype = X86::INTEL_COREI7_COOPERLAKE;
823 } else if (testFeature(X86::FEATURE_AVX512VNNI)) {
824 CPU = "cascadelake";
825 *Subtype = X86::INTEL_COREI7_CASCADELAKE;
826 } else {
827 CPU = "skylake-avx512";
828 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
829 }
830 break;
831
832 // Cannonlake:
833 case 0x66:
834 CPU = "cannonlake";
835 *Type = X86::INTEL_COREI7;
836 *Subtype = X86::INTEL_COREI7_CANNONLAKE;
837 break;
838
839 // Icelake:
840 case 0x7d:
841 case 0x7e:
842 CPU = "icelake-client";
843 *Type = X86::INTEL_COREI7;
844 *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT;
845 break;
846
847 // Tigerlake:
848 case 0x8c:
849 case 0x8d:
850 CPU = "tigerlake";
851 *Type = X86::INTEL_COREI7;
852 *Subtype = X86::INTEL_COREI7_TIGERLAKE;
853 break;
854
855 // Alderlake:
856 case 0x97:
857 case 0x9a:
858 // Gracemont
859 case 0xbe:
860 // Raptorlake:
861 case 0xb7:
862 case 0xba:
863 case 0xbf:
864 // Meteorlake:
865 case 0xaa:
866 case 0xac:
867 CPU = "alderlake";
868 *Type = X86::INTEL_COREI7;
869 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
870 break;
871
872 // Arrowlake:
873 case 0xc5:
874 CPU = "arrowlake";
875 *Type = X86::INTEL_COREI7;
876 *Subtype = X86::INTEL_COREI7_ARROWLAKE;
877 break;
878
879 // Arrowlake S:
880 case 0xc6:
881 // Lunarlake:
882 case 0xbd:
883 CPU = "arrowlake-s";
884 *Type = X86::INTEL_COREI7;
885 *Subtype = X86::INTEL_COREI7_ARROWLAKE_S;
886 break;
887
888 // Pantherlake:
889 case 0xcc:
890 CPU = "pantherlake";
891 *Type = X86::INTEL_COREI7;
892 *Subtype = X86::INTEL_COREI7_PANTHERLAKE;
893 break;
894
895 // Graniterapids:
896 case 0xad:
897 CPU = "graniterapids";
898 *Type = X86::INTEL_COREI7;
899 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS;
900 break;
901
902 // Granite Rapids D:
903 case 0xae:
904 CPU = "graniterapids-d";
905 *Type = X86::INTEL_COREI7;
906 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS_D;
907 break;
908
909 // Icelake Xeon:
910 case 0x6a:
911 case 0x6c:
912 CPU = "icelake-server";
913 *Type = X86::INTEL_COREI7;
914 *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER;
915 break;
916
917 // Emerald Rapids:
918 case 0xcf:
919 // Sapphire Rapids:
920 case 0x8f:
921 CPU = "sapphirerapids";
922 *Type = X86::INTEL_COREI7;
923 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
924 break;
925
926 case 0x1c: // Most 45 nm Intel Atom processors
927 case 0x26: // 45 nm Atom Lincroft
928 case 0x27: // 32 nm Atom Medfield
929 case 0x35: // 32 nm Atom Midview
930 case 0x36: // 32 nm Atom Midview
931 CPU = "bonnell";
932 *Type = X86::INTEL_BONNELL;
933 break;
934
935 // Atom Silvermont codes from the Intel software optimization guide.
936 case 0x37:
937 case 0x4a:
938 case 0x4d:
939 case 0x5a:
940 case 0x5d:
941 case 0x4c: // really airmont
942 CPU = "silvermont";
943 *Type = X86::INTEL_SILVERMONT;
944 break;
945 // Goldmont:
946 case 0x5c: // Apollo Lake
947 case 0x5f: // Denverton
948 CPU = "goldmont";
949 *Type = X86::INTEL_GOLDMONT;
950 break;
951 case 0x7a:
952 CPU = "goldmont-plus";
953 *Type = X86::INTEL_GOLDMONT_PLUS;
954 break;
955 case 0x86:
956 case 0x8a: // Lakefield
957 case 0x96: // Elkhart Lake
958 case 0x9c: // Jasper Lake
959 CPU = "tremont";
960 *Type = X86::INTEL_TREMONT;
961 break;
962
963 // Sierraforest:
964 case 0xaf:
965 CPU = "sierraforest";
966 *Type = X86::INTEL_SIERRAFOREST;
967 break;
968
969 // Grandridge:
970 case 0xb6:
971 CPU = "grandridge";
972 *Type = X86::INTEL_GRANDRIDGE;
973 break;
974
975 // Clearwaterforest:
976 case 0xdd:
977 CPU = "clearwaterforest";
978 *Type = X86::INTEL_CLEARWATERFOREST;
979 break;
980
981 // Xeon Phi (Knights Landing + Knights Mill):
982 case 0x57:
983 CPU = "knl";
984 *Type = X86::INTEL_KNL;
985 break;
986 case 0x85:
987 CPU = "knm";
988 *Type = X86::INTEL_KNM;
989 break;
990
991 default: // Unknown family 6 CPU, try to guess.
992 // Don't both with Type/Subtype here, they aren't used by the caller.
993 // They're used above to keep the code in sync with compiler-rt.
994 // TODO detect tigerlake host from model
995 if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) {
996 CPU = "tigerlake";
997 } else if (testFeature(X86::FEATURE_AVX512VBMI2)) {
998 CPU = "icelake-client";
999 } else if (testFeature(X86::FEATURE_AVX512VBMI)) {
1000 CPU = "cannonlake";
1001 } else if (testFeature(X86::FEATURE_AVX512BF16)) {
1002 CPU = "cooperlake";
1003 } else if (testFeature(X86::FEATURE_AVX512VNNI)) {
1004 CPU = "cascadelake";
1005 } else if (testFeature(X86::FEATURE_AVX512VL)) {
1006 CPU = "skylake-avx512";
1007 } else if (testFeature(X86::FEATURE_AVX512ER)) {
1008 CPU = "knl";
1009 } else if (testFeature(X86::FEATURE_CLFLUSHOPT)) {
1010 if (testFeature(X86::FEATURE_SHA))
1011 CPU = "goldmont";
1012 else
1013 CPU = "skylake";
1014 } else if (testFeature(X86::FEATURE_ADX)) {
1015 CPU = "broadwell";
1016 } else if (testFeature(X86::FEATURE_AVX2)) {
1017 CPU = "haswell";
1018 } else if (testFeature(X86::FEATURE_AVX)) {
1019 CPU = "sandybridge";
1020 } else if (testFeature(X86::FEATURE_SSE4_2)) {
1021 if (testFeature(X86::FEATURE_MOVBE))
1022 CPU = "silvermont";
1023 else
1024 CPU = "nehalem";
1025 } else if (testFeature(X86::FEATURE_SSE4_1)) {
1026 CPU = "penryn";
1027 } else if (testFeature(X86::FEATURE_SSSE3)) {
1028 if (testFeature(X86::FEATURE_MOVBE))
1029 CPU = "bonnell";
1030 else
1031 CPU = "core2";
1032 } else if (testFeature(X86::FEATURE_64BIT)) {
1033 CPU = "core2";
1034 } else if (testFeature(X86::FEATURE_SSE3)) {
1035 CPU = "yonah";
1036 } else if (testFeature(X86::FEATURE_SSE2)) {
1037 CPU = "pentium-m";
1038 } else if (testFeature(X86::FEATURE_SSE)) {
1039 CPU = "pentium3";
1040 } else if (testFeature(X86::FEATURE_MMX)) {
1041 CPU = "pentium2";
1042 } else {
1043 CPU = "pentiumpro";
1044 }
1045 break;
1046 }
1047 break;
1048 case 15: {
1049 if (testFeature(X86::FEATURE_64BIT)) {
1050 CPU = "nocona";
1051 break;
1052 }
1053 if (testFeature(X86::FEATURE_SSE3)) {
1054 CPU = "prescott";
1055 break;
1056 }
1057 CPU = "pentium4";
1058 break;
1059 }
1060 default:
1061 break; // Unknown.
1062 }
1063
1064 return CPU;
1065}
1066
1067static StringRef
1068getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
1069 const unsigned *Features,
1070 unsigned *Type, unsigned *Subtype) {
1071 auto testFeature = [&](unsigned F) {
1072 return (Features[F / 32] & (1U << (F % 32))) != 0;
1073 };
1074
1075 StringRef CPU;
1076
1077 switch (Family) {
1078 case 4:
1079 CPU = "i486";
1080 break;
1081 case 5:
1082 CPU = "pentium";
1083 switch (Model) {
1084 case 6:
1085 case 7:
1086 CPU = "k6";
1087 break;
1088 case 8:
1089 CPU = "k6-2";
1090 break;
1091 case 9:
1092 case 13:
1093 CPU = "k6-3";
1094 break;
1095 case 10:
1096 CPU = "geode";
1097 break;
1098 }
1099 break;
1100 case 6:
1101 if (testFeature(X86::FEATURE_SSE)) {
1102 CPU = "athlon-xp";
1103 break;
1104 }
1105 CPU = "athlon";
1106 break;
1107 case 15:
1108 if (testFeature(X86::FEATURE_SSE3)) {
1109 CPU = "k8-sse3";
1110 break;
1111 }
1112 CPU = "k8";
1113 break;
1114 case 16:
1115 CPU = "amdfam10";
1116 *Type = X86::AMDFAM10H; // "amdfam10"
1117 switch (Model) {
1118 case 2:
1119 *Subtype = X86::AMDFAM10H_BARCELONA;
1120 break;
1121 case 4:
1122 *Subtype = X86::AMDFAM10H_SHANGHAI;
1123 break;
1124 case 8:
1125 *Subtype = X86::AMDFAM10H_ISTANBUL;
1126 break;
1127 }
1128 break;
1129 case 20:
1130 CPU = "btver1";
1131 *Type = X86::AMD_BTVER1;
1132 break;
1133 case 21:
1134 CPU = "bdver1";
1135 *Type = X86::AMDFAM15H;
1136 if (Model >= 0x60 && Model <= 0x7f) {
1137 CPU = "bdver4";
1138 *Subtype = X86::AMDFAM15H_BDVER4;
1139 break; // 60h-7Fh: Excavator
1140 }
1141 if (Model >= 0x30 && Model <= 0x3f) {
1142 CPU = "bdver3";
1143 *Subtype = X86::AMDFAM15H_BDVER3;
1144 break; // 30h-3Fh: Steamroller
1145 }
1146 if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) {
1147 CPU = "bdver2";
1148 *Subtype = X86::AMDFAM15H_BDVER2;
1149 break; // 02h, 10h-1Fh: Piledriver
1150 }
1151 if (Model <= 0x0f) {
1152 *Subtype = X86::AMDFAM15H_BDVER1;
1153 break; // 00h-0Fh: Bulldozer
1154 }
1155 break;
1156 case 22:
1157 CPU = "btver2";
1158 *Type = X86::AMD_BTVER2;
1159 break;
1160 case 23:
1161 CPU = "znver1";
1162 *Type = X86::AMDFAM17H;
1163 if ((Model >= 0x30 && Model <= 0x3f) || (Model == 0x47) ||
1164 (Model >= 0x60 && Model <= 0x67) || (Model >= 0x68 && Model <= 0x6f) ||
1165 (Model >= 0x70 && Model <= 0x7f) || (Model >= 0x84 && Model <= 0x87) ||
1166 (Model >= 0x90 && Model <= 0x97) || (Model >= 0x98 && Model <= 0x9f) ||
1167 (Model >= 0xa0 && Model <= 0xaf)) {
1168 // Family 17h Models 30h-3Fh (Starship) Zen 2
1169 // Family 17h Models 47h (Cardinal) Zen 2
1170 // Family 17h Models 60h-67h (Renoir) Zen 2
1171 // Family 17h Models 68h-6Fh (Lucienne) Zen 2
1172 // Family 17h Models 70h-7Fh (Matisse) Zen 2
1173 // Family 17h Models 84h-87h (ProjectX) Zen 2
1174 // Family 17h Models 90h-97h (VanGogh) Zen 2
1175 // Family 17h Models 98h-9Fh (Mero) Zen 2
1176 // Family 17h Models A0h-AFh (Mendocino) Zen 2
1177 CPU = "znver2";
1178 *Subtype = X86::AMDFAM17H_ZNVER2;
1179 break;
1180 }
1181 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x20 && Model <= 0x2f)) {
1182 // Family 17h Models 10h-1Fh (Raven1) Zen
1183 // Family 17h Models 10h-1Fh (Picasso) Zen+
1184 // Family 17h Models 20h-2Fh (Raven2 x86) Zen
1185 *Subtype = X86::AMDFAM17H_ZNVER1;
1186 break;
1187 }
1188 break;
1189 case 25:
1190 CPU = "znver3";
1191 *Type = X86::AMDFAM19H;
1192 if (Model <= 0x0f || (Model >= 0x20 && Model <= 0x2f) ||
1193 (Model >= 0x30 && Model <= 0x3f) || (Model >= 0x40 && Model <= 0x4f) ||
1194 (Model >= 0x50 && Model <= 0x5f)) {
1195 // Family 19h Models 00h-0Fh (Genesis, Chagall) Zen 3
1196 // Family 19h Models 20h-2Fh (Vermeer) Zen 3
1197 // Family 19h Models 30h-3Fh (Badami) Zen 3
1198 // Family 19h Models 40h-4Fh (Rembrandt) Zen 3+
1199 // Family 19h Models 50h-5Fh (Cezanne) Zen 3
1200 *Subtype = X86::AMDFAM19H_ZNVER3;
1201 break;
1202 }
1203 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x60 && Model <= 0x6f) ||
1204 (Model >= 0x70 && Model <= 0x77) || (Model >= 0x78 && Model <= 0x7f) ||
1205 (Model >= 0xa0 && Model <= 0xaf)) {
1206 // Family 19h Models 10h-1Fh (Stones; Storm Peak) Zen 4
1207 // Family 19h Models 60h-6Fh (Raphael) Zen 4
1208 // Family 19h Models 70h-77h (Phoenix, Hawkpoint1) Zen 4
1209 // Family 19h Models 78h-7Fh (Phoenix 2, Hawkpoint2) Zen 4
1210 // Family 19h Models A0h-AFh (Stones-Dense) Zen 4
1211 CPU = "znver4";
1212 *Subtype = X86::AMDFAM19H_ZNVER4;
1213 break; // "znver4"
1214 }
1215 break;
1216 default:
1217 break; // Unknown AMD CPU.
1218 }
1219
1220 return CPU;
1221}
1222
1223static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
1224 unsigned *Features) {
1225 unsigned EAX, EBX;
1226
1227 auto setFeature = [&](unsigned F) {
1228 Features[F / 32] |= 1U << (F % 32);
1229 };
1230
1231 if ((EDX >> 15) & 1)
1232 setFeature(X86::FEATURE_CMOV);
1233 if ((EDX >> 23) & 1)
1234 setFeature(X86::FEATURE_MMX);
1235 if ((EDX >> 25) & 1)
1236 setFeature(X86::FEATURE_SSE);
1237 if ((EDX >> 26) & 1)
1238 setFeature(X86::FEATURE_SSE2);
1239
1240 if ((ECX >> 0) & 1)
1241 setFeature(X86::FEATURE_SSE3);
1242 if ((ECX >> 1) & 1)
1243 setFeature(X86::FEATURE_PCLMUL);
1244 if ((ECX >> 9) & 1)
1245 setFeature(X86::FEATURE_SSSE3);
1246 if ((ECX >> 12) & 1)
1247 setFeature(X86::FEATURE_FMA);
1248 if ((ECX >> 19) & 1)
1249 setFeature(X86::FEATURE_SSE4_1);
1250 if ((ECX >> 20) & 1) {
1251 setFeature(X86::FEATURE_SSE4_2);
1252 setFeature(X86::FEATURE_CRC32);
1253 }
1254 if ((ECX >> 23) & 1)
1255 setFeature(X86::FEATURE_POPCNT);
1256 if ((ECX >> 25) & 1)
1257 setFeature(X86::FEATURE_AES);
1258
1259 if ((ECX >> 22) & 1)
1260 setFeature(X86::FEATURE_MOVBE);
1261
1262 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1263 // indicates that the AVX registers will be saved and restored on context
1264 // switch, then we have full AVX support.
1265 const unsigned AVXBits = (1 << 27) | (1 << 28);
1266 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
1267 ((EAX & 0x6) == 0x6);
1268#if defined(__APPLE__)
1269 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
1270 // save the AVX512 context if we use AVX512 instructions, even the bit is not
1271 // set right now.
1272 bool HasAVX512Save = true;
1273#else
1274 // AVX512 requires additional context to be saved by the OS.
1275 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
1276#endif
1277
1278 if (HasAVX)
1279 setFeature(X86::FEATURE_AVX);
1280
1281 bool HasLeaf7 =
1282 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1283
1284 if (HasLeaf7 && ((EBX >> 3) & 1))
1285 setFeature(X86::FEATURE_BMI);
1286 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
1287 setFeature(X86::FEATURE_AVX2);
1288 if (HasLeaf7 && ((EBX >> 8) & 1))
1289 setFeature(X86::FEATURE_BMI2);
1290 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
1291 setFeature(X86::FEATURE_AVX512F);
1292 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
1293 setFeature(X86::FEATURE_AVX512DQ);
1294 if (HasLeaf7 && ((EBX >> 19) & 1))
1295 setFeature(X86::FEATURE_ADX);
1296 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
1297 setFeature(X86::FEATURE_AVX512IFMA);
1298 if (HasLeaf7 && ((EBX >> 23) & 1))
1299 setFeature(X86::FEATURE_CLFLUSHOPT);
1300 if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
1301 setFeature(X86::FEATURE_AVX512PF);
1302 if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
1303 setFeature(X86::FEATURE_AVX512ER);
1304 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
1305 setFeature(X86::FEATURE_AVX512CD);
1306 if (HasLeaf7 && ((EBX >> 29) & 1))
1307 setFeature(X86::FEATURE_SHA);
1308 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
1309 setFeature(X86::FEATURE_AVX512BW);
1310 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
1311 setFeature(X86::FEATURE_AVX512VL);
1312
1313 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
1314 setFeature(X86::FEATURE_AVX512VBMI);
1315 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
1316 setFeature(X86::FEATURE_AVX512VBMI2);
1317 if (HasLeaf7 && ((ECX >> 8) & 1))
1318 setFeature(X86::FEATURE_GFNI);
1319 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
1320 setFeature(X86::FEATURE_VPCLMULQDQ);
1321 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
1322 setFeature(X86::FEATURE_AVX512VNNI);
1323 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
1324 setFeature(X86::FEATURE_AVX512BITALG);
1325 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
1326 setFeature(X86::FEATURE_AVX512VPOPCNTDQ);
1327
1328 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
1329 setFeature(X86::FEATURE_AVX5124VNNIW);
1330 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
1331 setFeature(X86::FEATURE_AVX5124FMAPS);
1332 if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
1333 setFeature(X86::FEATURE_AVX512VP2INTERSECT);
1334
1335 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1336 // return all 0s for invalid subleaves so check the limit.
1337 bool HasLeaf7Subleaf1 =
1338 HasLeaf7 && EAX >= 1 &&
1339 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1340 if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
1341 setFeature(X86::FEATURE_AVX512BF16);
1342
1343 unsigned MaxExtLevel;
1344 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1345
1346 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1347 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1348 if (HasExtLeaf1 && ((ECX >> 6) & 1))
1349 setFeature(X86::FEATURE_SSE4_A);
1350 if (HasExtLeaf1 && ((ECX >> 11) & 1))
1351 setFeature(X86::FEATURE_XOP);
1352 if (HasExtLeaf1 && ((ECX >> 16) & 1))
1353 setFeature(X86::FEATURE_FMA4);
1354
1355 if (HasExtLeaf1 && ((EDX >> 29) & 1))
1356 setFeature(X86::FEATURE_64BIT);
1357}
1358
1360 unsigned MaxLeaf = 0;
1361 const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
1362 if (Vendor == VendorSignatures::UNKNOWN)
1363 return "generic";
1364
1365 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1366 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
1367
1368 unsigned Family = 0, Model = 0;
1369 unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0};
1370 detectX86FamilyModel(EAX, &Family, &Model);
1371 getAvailableFeatures(ECX, EDX, MaxLeaf, Features);
1372
1373 // These aren't consumed in this file, but we try to keep some source code the
1374 // same or similar to compiler-rt.
1375 unsigned Type = 0;
1376 unsigned Subtype = 0;
1377
1378 StringRef CPU;
1379
1380 if (Vendor == VendorSignatures::GENUINE_INTEL) {
1381 CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
1382 &Subtype);
1383 } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
1384 CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
1385 &Subtype);
1386 }
1387
1388 if (!CPU.empty())
1389 return CPU;
1390
1391 return "generic";
1392}
1393
1394#elif defined(__APPLE__) && defined(__powerpc__)
1396 host_basic_info_data_t hostInfo;
1397 mach_msg_type_number_t infoCount;
1398
1399 infoCount = HOST_BASIC_INFO_COUNT;
1400 mach_port_t hostPort = mach_host_self();
1401 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1402 &infoCount);
1403 mach_port_deallocate(mach_task_self(), hostPort);
1404
1405 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
1406 return "generic";
1407
1408 switch (hostInfo.cpu_subtype) {
1410 return "601";
1412 return "602";
1414 return "603";
1416 return "603e";
1418 return "603ev";
1420 return "604";
1422 return "604e";
1424 return "620";
1426 return "750";
1428 return "7400";
1430 return "7450";
1432 return "970";
1433 default:;
1434 }
1435
1436 return "generic";
1437}
1438#elif defined(__linux__) && defined(__powerpc__)
1440 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1441 StringRef Content = P ? P->getBuffer() : "";
1442 return detail::getHostCPUNameForPowerPC(Content);
1443}
1444#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1446 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1447 StringRef Content = P ? P->getBuffer() : "";
1448 return detail::getHostCPUNameForARM(Content);
1449}
1450#elif defined(__linux__) && defined(__s390x__)
1452 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1453 StringRef Content = P ? P->getBuffer() : "";
1454 return detail::getHostCPUNameForS390x(Content);
1455}
1456#elif defined(__MVS__)
1458 // Get pointer to Communications Vector Table (CVT).
1459 // The pointer is located at offset 16 of the Prefixed Save Area (PSA).
1460 // It is stored as 31 bit pointer and will be zero-extended to 64 bit.
1461 int *StartToCVTOffset = reinterpret_cast<int *>(0x10);
1462 // Since its stored as a 31-bit pointer, get the 4 bytes from the start
1463 // of address.
1464 int ReadValue = *StartToCVTOffset;
1465 // Explicitly clear the high order bit.
1466 ReadValue = (ReadValue & 0x7FFFFFFF);
1467 char *CVT = reinterpret_cast<char *>(ReadValue);
1468 // The model number is located in the CVT prefix at offset -6 and stored as
1469 // signless packed decimal.
1470 uint16_t Id = *(uint16_t *)&CVT[-6];
1471 // Convert number to integer.
1472 Id = decodePackedBCD<uint16_t>(Id, false);
1473 // Check for vector support. It's stored in field CVTFLAG5 (offset 244),
1474 // bit CVTVEF (X'80'). The facilities list is part of the PSA but the vector
1475 // extension can only be used if bit CVTVEF is on.
1476 bool HaveVectorSupport = CVT[244] & 0x80;
1477 return getCPUNameFromS390Model(Id, HaveVectorSupport);
1478}
1479#elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__))
1480#define CPUFAMILY_ARM_SWIFT 0x1e2d6381
1481#define CPUFAMILY_ARM_CYCLONE 0x37a09642
1482#define CPUFAMILY_ARM_TYPHOON 0x2c91a47e
1483#define CPUFAMILY_ARM_TWISTER 0x92fb37c8
1484#define CPUFAMILY_ARM_HURRICANE 0x67ceee93
1485#define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6
1486#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f
1487#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2
1488#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3
1489#define CPUFAMILY_ARM_BLIZZARD_AVALANCHE 0xda33d83d
1490#define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea
1491
1493 uint32_t Family;
1494 size_t Length = sizeof(Family);
1495 sysctlbyname("hw.cpufamily", &Family, &Length, NULL, 0);
1496
1497 switch (Family) {
1498 case CPUFAMILY_ARM_SWIFT:
1499 return "swift";
1500 case CPUFAMILY_ARM_CYCLONE:
1501 return "apple-a7";
1502 case CPUFAMILY_ARM_TYPHOON:
1503 return "apple-a8";
1504 case CPUFAMILY_ARM_TWISTER:
1505 return "apple-a9";
1506 case CPUFAMILY_ARM_HURRICANE:
1507 return "apple-a10";
1508 case CPUFAMILY_ARM_MONSOON_MISTRAL:
1509 return "apple-a11";
1510 case CPUFAMILY_ARM_VORTEX_TEMPEST:
1511 return "apple-a12";
1512 case CPUFAMILY_ARM_LIGHTNING_THUNDER:
1513 return "apple-a13";
1514 case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
1515 return "apple-m1";
1516 case CPUFAMILY_ARM_BLIZZARD_AVALANCHE:
1517 return "apple-m2";
1518 case CPUFAMILY_ARM_EVEREST_SAWTOOTH:
1519 return "apple-m3";
1520 default:
1521 // Default to the newest CPU we know about.
1522 return "apple-m3";
1523 }
1524}
1525#elif defined(_AIX)
1527 switch (_system_configuration.implementation) {
1528 case POWER_4:
1529 if (_system_configuration.version == PV_4_3)
1530 return "970";
1531 return "pwr4";
1532 case POWER_5:
1533 if (_system_configuration.version == PV_5)
1534 return "pwr5";
1535 return "pwr5x";
1536 case POWER_6:
1537 if (_system_configuration.version == PV_6_Compat)
1538 return "pwr6";
1539 return "pwr6x";
1540 case POWER_7:
1541 return "pwr7";
1542 case POWER_8:
1543 return "pwr8";
1544 case POWER_9:
1545 return "pwr9";
1546// TODO: simplify this once the macro is available in all OS levels.
1547#ifdef POWER_10
1548 case POWER_10:
1549#else
1550 case 0x40000:
1551#endif
1552 return "pwr10";
1553 default:
1554 return "generic";
1555 }
1556}
1557#elif defined(__loongarch__)
1559 // Use processor id to detect cpu name.
1560 uint32_t processor_id;
1561 __asm__("cpucfg %[prid], $zero\n\t" : [prid] "=r"(processor_id));
1562 // Refer PRID_SERIES_MASK in linux kernel: arch/loongarch/include/asm/cpu.h.
1563 switch (processor_id & 0xf000) {
1564 case 0xc000: // Loongson 64bit, 4-issue
1565 return "la464";
1566 // TODO: Others.
1567 default:
1568 break;
1569 }
1570 return "generic";
1571}
1572#elif defined(__riscv)
1574#if defined(__linux__)
1575 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1576 StringRef Content = P ? P->getBuffer() : "";
1577 return detail::getHostCPUNameForRISCV(Content);
1578#else
1579#if __riscv_xlen == 64
1580 return "generic-rv64";
1581#elif __riscv_xlen == 32
1582 return "generic-rv32";
1583#else
1584#error "Unhandled value of __riscv_xlen"
1585#endif
1586#endif
1587}
1588#elif defined(__sparc__)
1589#if defined(__linux__)
1592 ProcCpuinfoContent.split(Lines, "\n");
1593
1594 // Look for cpu line to determine cpu name
1595 StringRef Cpu;
1596 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
1597 if (Lines[I].starts_with("cpu")) {
1598 Cpu = Lines[I].substr(5).ltrim("\t :");
1599 break;
1600 }
1601 }
1602
1603 return StringSwitch<const char *>(Cpu)
1604 .StartsWith("SuperSparc", "supersparc")
1605 .StartsWith("HyperSparc", "hypersparc")
1606 .StartsWith("SpitFire", "ultrasparc")
1607 .StartsWith("BlackBird", "ultrasparc")
1608 .StartsWith("Sabre", " ultrasparc")
1609 .StartsWith("Hummingbird", "ultrasparc")
1610 .StartsWith("Cheetah", "ultrasparc3")
1611 .StartsWith("Jalapeno", "ultrasparc3")
1612 .StartsWith("Jaguar", "ultrasparc3")
1613 .StartsWith("Panther", "ultrasparc3")
1614 .StartsWith("Serrano", "ultrasparc3")
1615 .StartsWith("UltraSparc T1", "niagara")
1616 .StartsWith("UltraSparc T2", "niagara2")
1617 .StartsWith("UltraSparc T3", "niagara3")
1618 .StartsWith("UltraSparc T4", "niagara4")
1619 .StartsWith("UltraSparc T5", "niagara4")
1620 .StartsWith("LEON", "leon3")
1621 // niagara7/m8 not supported by LLVM yet.
1622 .StartsWith("SPARC-M7", "niagara4" /* "niagara7" */)
1623 .StartsWith("SPARC-S7", "niagara4" /* "niagara7" */)
1624 .StartsWith("SPARC-M8", "niagara4" /* "m8" */)
1625 .Default("generic");
1626}
1627#endif
1628
1630#if defined(__linux__)
1631 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1632 StringRef Content = P ? P->getBuffer() : "";
1633 return detail::getHostCPUNameForSPARC(Content);
1634#elif defined(__sun__) && defined(__svr4__)
1635 char *buf = NULL;
1636 kstat_ctl_t *kc;
1637 kstat_t *ksp;
1638 kstat_named_t *brand = NULL;
1639
1640 kc = kstat_open();
1641 if (kc != NULL) {
1642 ksp = kstat_lookup(kc, const_cast<char *>("cpu_info"), -1, NULL);
1643 if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1 &&
1644 ksp->ks_type == KSTAT_TYPE_NAMED)
1645 brand =
1646 (kstat_named_t *)kstat_data_lookup(ksp, const_cast<char *>("brand"));
1647 if (brand != NULL && brand->data_type == KSTAT_DATA_STRING)
1648 buf = KSTAT_NAMED_STR_PTR(brand);
1649 }
1650 kstat_close(kc);
1651
1652 return StringSwitch<const char *>(buf)
1653 .Case("TMS390S10", "supersparc") // Texas Instruments microSPARC I
1654 .Case("TMS390Z50", "supersparc") // Texas Instruments SuperSPARC I
1655 .Case("TMS390Z55",
1656 "supersparc") // Texas Instruments SuperSPARC I with SuperCache
1657 .Case("MB86904", "supersparc") // Fujitsu microSPARC II
1658 .Case("MB86907", "supersparc") // Fujitsu TurboSPARC
1659 .Case("RT623", "hypersparc") // Ross hyperSPARC
1660 .Case("RT625", "hypersparc")
1661 .Case("RT626", "hypersparc")
1662 .Case("UltraSPARC-I", "ultrasparc")
1663 .Case("UltraSPARC-II", "ultrasparc")
1664 .Case("UltraSPARC-IIe", "ultrasparc")
1665 .Case("UltraSPARC-IIi", "ultrasparc")
1666 .Case("SPARC64-III", "ultrasparc")
1667 .Case("SPARC64-IV", "ultrasparc")
1668 .Case("UltraSPARC-III", "ultrasparc3")
1669 .Case("UltraSPARC-III+", "ultrasparc3")
1670 .Case("UltraSPARC-IIIi", "ultrasparc3")
1671 .Case("UltraSPARC-IIIi+", "ultrasparc3")
1672 .Case("UltraSPARC-IV", "ultrasparc3")
1673 .Case("UltraSPARC-IV+", "ultrasparc3")
1674 .Case("SPARC64-V", "ultrasparc3")
1675 .Case("SPARC64-VI", "ultrasparc3")
1676 .Case("SPARC64-VII", "ultrasparc3")
1677 .Case("UltraSPARC-T1", "niagara")
1678 .Case("UltraSPARC-T2", "niagara2")
1679 .Case("UltraSPARC-T2", "niagara2")
1680 .Case("UltraSPARC-T2+", "niagara2")
1681 .Case("SPARC-T3", "niagara3")
1682 .Case("SPARC-T4", "niagara4")
1683 .Case("SPARC-T5", "niagara4")
1684 // niagara7/m8 not supported by LLVM yet.
1685 .Case("SPARC-M7", "niagara4" /* "niagara7" */)
1686 .Case("SPARC-S7", "niagara4" /* "niagara7" */)
1687 .Case("SPARC-M8", "niagara4" /* "m8" */)
1688 .Default("generic");
1689#else
1690 return "generic";
1691#endif
1692}
1693#else
1694StringRef sys::getHostCPUName() { return "generic"; }
1695namespace llvm {
1696namespace sys {
1697namespace detail {
1698namespace x86 {
1699
1702}
1703
1704} // namespace x86
1705} // namespace detail
1706} // namespace sys
1707} // namespace llvm
1708#endif
1709
1710#if defined(__i386__) || defined(_M_IX86) || \
1711 defined(__x86_64__) || defined(_M_X64)
1713 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1714 unsigned MaxLevel;
1715
1716 if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1)
1717 return false;
1718
1719 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1720
1721 Features["cx8"] = (EDX >> 8) & 1;
1722 Features["cmov"] = (EDX >> 15) & 1;
1723 Features["mmx"] = (EDX >> 23) & 1;
1724 Features["fxsr"] = (EDX >> 24) & 1;
1725 Features["sse"] = (EDX >> 25) & 1;
1726 Features["sse2"] = (EDX >> 26) & 1;
1727
1728 Features["sse3"] = (ECX >> 0) & 1;
1729 Features["pclmul"] = (ECX >> 1) & 1;
1730 Features["ssse3"] = (ECX >> 9) & 1;
1731 Features["cx16"] = (ECX >> 13) & 1;
1732 Features["sse4.1"] = (ECX >> 19) & 1;
1733 Features["sse4.2"] = (ECX >> 20) & 1;
1734 Features["crc32"] = Features["sse4.2"];
1735 Features["movbe"] = (ECX >> 22) & 1;
1736 Features["popcnt"] = (ECX >> 23) & 1;
1737 Features["aes"] = (ECX >> 25) & 1;
1738 Features["rdrnd"] = (ECX >> 30) & 1;
1739
1740 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1741 // indicates that the AVX registers will be saved and restored on context
1742 // switch, then we have full AVX support.
1743 bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX);
1744 bool HasAVXSave = HasXSave && ((ECX >> 28) & 1) && ((EAX & 0x6) == 0x6);
1745#if defined(__APPLE__)
1746 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
1747 // save the AVX512 context if we use AVX512 instructions, even the bit is not
1748 // set right now.
1749 bool HasAVX512Save = true;
1750#else
1751 // AVX512 requires additional context to be saved by the OS.
1752 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
1753#endif
1754 // AMX requires additional context to be saved by the OS.
1755 const unsigned AMXBits = (1 << 17) | (1 << 18);
1756 bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits);
1757
1758 Features["avx"] = HasAVXSave;
1759 Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave;
1760 // Only enable XSAVE if OS has enabled support for saving YMM state.
1761 Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave;
1762 Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave;
1763
1764 unsigned MaxExtLevel;
1765 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1766
1767 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1768 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1769 Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1);
1770 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1771 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1772 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1773 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
1774 Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
1775 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1776 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
1777 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
1778
1779 Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1);
1780
1781 // Miscellaneous memory related features, detected by
1782 // using the 0x80000008 leaf of the CPUID instruction
1783 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
1784 !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
1785 Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1);
1786 Features["rdpru"] = HasExtLeaf8 && ((EBX >> 4) & 1);
1787 Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1);
1788
1789 bool HasLeaf7 =
1790 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1791
1792 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
1793 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
1794 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
1795 // AVX2 is only supported if we have the OS save support from AVX.
1796 Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave;
1797 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
1798 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
1799 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
1800 // AVX512 is only supported if the OS supports the context save for it.
1801 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
1802 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
1803 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
1804 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
1805 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
1806 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
1807 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
1808 Features["avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
1809 Features["avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
1810 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
1811 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
1812 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
1813 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
1814
1815 Features["prefetchwt1"] = HasLeaf7 && ((ECX >> 0) & 1);
1816 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
1817 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
1818 Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1);
1819 Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save;
1820 Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1);
1821 Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1);
1822 Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave;
1823 Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave;
1824 Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save;
1825 Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
1826 Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
1827 Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1);
1828 Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker
1829 Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1);
1830 Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
1831 Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
1832 Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1);
1833
1834 Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1);
1835 Features["avx512vp2intersect"] =
1836 HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save;
1837 Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1);
1838 Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1);
1839 // There are two CPUID leafs which information associated with the pconfig
1840 // instruction:
1841 // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
1842 // bit of EDX), while the EAX=0x1b leaf returns information on the
1843 // availability of specific pconfig leafs.
1844 // The target feature here only refers to the the first of these two.
1845 // Users might need to check for the availability of specific pconfig
1846 // leaves using cpuid, since that information is ignored while
1847 // detecting features using the "-march=native" flag.
1848 // For more info, see X86 ISA docs.
1849 Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1);
1850 Features["amx-bf16"] = HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave;
1851 Features["avx512fp16"] = HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save;
1852 Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave;
1853 Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave;
1854 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1855 // return all 0s for invalid subleaves so check the limit.
1856 bool HasLeaf7Subleaf1 =
1857 HasLeaf7 && EAX >= 1 &&
1858 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1859 Features["sha512"] = HasLeaf7Subleaf1 && ((EAX >> 0) & 1);
1860 Features["sm3"] = HasLeaf7Subleaf1 && ((EAX >> 1) & 1);
1861 Features["sm4"] = HasLeaf7Subleaf1 && ((EAX >> 2) & 1);
1862 Features["raoint"] = HasLeaf7Subleaf1 && ((EAX >> 3) & 1);
1863 Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
1864 Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save;
1865 Features["amx-fp16"] = HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave;
1866 Features["cmpccxadd"] = HasLeaf7Subleaf1 && ((EAX >> 7) & 1);
1867 Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
1868 Features["avxifma"] = HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave;
1869 Features["avxvnniint8"] = HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave;
1870 Features["avxneconvert"] = HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave;
1871 Features["amx-complex"] = HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave;
1872 Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave;
1873 Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1);
1874 Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1);
1875 Features["avx10.1-256"] = HasLeaf7Subleaf1 && ((EDX >> 19) & 1);
1876 bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1);
1877 Features["egpr"] = HasAPXF;
1878 Features["push2pop2"] = HasAPXF;
1879 Features["ppx"] = HasAPXF;
1880 Features["ndd"] = HasAPXF;
1881 Features["ccmp"] = HasAPXF;
1882 Features["cf"] = HasAPXF;
1883
1884 bool HasLeafD = MaxLevel >= 0xd &&
1885 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
1886
1887 // Only enable XSAVE if OS has enabled support for saving YMM state.
1888 Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave;
1889 Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave;
1890 Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave;
1891
1892 bool HasLeaf14 = MaxLevel >= 0x14 &&
1893 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
1894
1895 Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1);
1896
1897 bool HasLeaf19 =
1898 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
1899 Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1);
1900
1901 bool HasLeaf24 =
1902 MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX);
1903 Features["avx10.1-512"] =
1904 Features["avx10.1-256"] && HasLeaf24 && ((EBX >> 18) & 1);
1905
1906 return true;
1907}
1908#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1910 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1911 if (!P)
1912 return false;
1913
1915 P->getBuffer().split(Lines, "\n");
1916
1918
1919 // Look for the CPU features.
1920 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1921 if (Lines[I].starts_with("Features")) {
1922 Lines[I].split(CPUFeatures, ' ');
1923 break;
1924 }
1925
1926#if defined(__aarch64__)
1927 // Keep track of which crypto features we have seen
1928 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1929 uint32_t crypto = 0;
1930#endif
1931
1932 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
1933 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
1934#if defined(__aarch64__)
1935 .Case("asimd", "neon")
1936 .Case("fp", "fp-armv8")
1937 .Case("crc32", "crc")
1938 .Case("atomics", "lse")
1939 .Case("sve", "sve")
1940 .Case("sve2", "sve2")
1941#else
1942 .Case("half", "fp16")
1943 .Case("neon", "neon")
1944 .Case("vfpv3", "vfp3")
1945 .Case("vfpv3d16", "vfp3d16")
1946 .Case("vfpv4", "vfp4")
1947 .Case("idiva", "hwdiv-arm")
1948 .Case("idivt", "hwdiv")
1949#endif
1950 .Default("");
1951
1952#if defined(__aarch64__)
1953 // We need to check crypto separately since we need all of the crypto
1954 // extensions to enable the subtarget feature
1955 if (CPUFeatures[I] == "aes")
1956 crypto |= CAP_AES;
1957 else if (CPUFeatures[I] == "pmull")
1958 crypto |= CAP_PMULL;
1959 else if (CPUFeatures[I] == "sha1")
1960 crypto |= CAP_SHA1;
1961 else if (CPUFeatures[I] == "sha2")
1962 crypto |= CAP_SHA2;
1963#endif
1964
1965 if (LLVMFeatureStr != "")
1966 Features[LLVMFeatureStr] = true;
1967 }
1968
1969#if defined(__aarch64__)
1970 // If we have all crypto bits we can add the feature
1971 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
1972 Features["crypto"] = true;
1973#endif
1974
1975 return true;
1976}
1977#elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64))
1979 if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE))
1980 Features["neon"] = true;
1981 if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE))
1982 Features["crc"] = true;
1983 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE))
1984 Features["crypto"] = true;
1985
1986 return true;
1987}
1988#elif defined(__linux__) && defined(__loongarch__)
1989#include <sys/auxv.h>
1991 unsigned long hwcap = getauxval(AT_HWCAP);
1992 bool HasFPU = hwcap & (1UL << 3); // HWCAP_LOONGARCH_FPU
1993 uint32_t cpucfg2 = 0x2;
1994 __asm__("cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2] "+r"(cpucfg2));
1995
1996 Features["f"] = HasFPU && (cpucfg2 & (1U << 1)); // CPUCFG.2.FP_SP
1997 Features["d"] = HasFPU && (cpucfg2 & (1U << 2)); // CPUCFG.2.FP_DP
1998
1999 Features["lsx"] = hwcap & (1UL << 4); // HWCAP_LOONGARCH_LSX
2000 Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX
2001 Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ
2002
2003 return true;
2004}
2005#else
2006bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
2007#endif
2008
2009#if __APPLE__
2010/// \returns the \p triple, but with the Host's arch spliced in.
2011static Triple withHostArch(Triple T) {
2012#if defined(__arm__)
2013 T.setArch(Triple::arm);
2014 T.setArchName("arm");
2015#elif defined(__arm64e__)
2017 T.setArchName("arm64e");
2018#elif defined(__aarch64__)
2019 T.setArch(Triple::aarch64);
2020 T.setArchName("arm64");
2021#elif defined(__x86_64h__)
2022 T.setArch(Triple::x86_64);
2023 T.setArchName("x86_64h");
2024#elif defined(__x86_64__)
2025 T.setArch(Triple::x86_64);
2026 T.setArchName("x86_64");
2027#elif defined(__i386__)
2028 T.setArch(Triple::x86);
2029 T.setArchName("i386");
2030#elif defined(__powerpc__)
2031 T.setArch(Triple::ppc);
2032 T.setArchName("powerpc");
2033#else
2034# error "Unimplemented host arch fixup"
2035#endif
2036 return T;
2037}
2038#endif
2039
2041 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
2042 Triple PT(Triple::normalize(TargetTripleString));
2043
2044#if __APPLE__
2045 /// In Universal builds, LLVM_HOST_TRIPLE will have the wrong arch in one of
2046 /// the slices. This fixes that up.
2047 PT = withHostArch(PT);
2048#endif
2049
2050 if (sizeof(void *) == 8 && PT.isArch32Bit())
2051 PT = PT.get64BitArchVariant();
2052 if (sizeof(void *) == 4 && PT.isArch64Bit())
2053 PT = PT.get32BitArchVariant();
2054
2055 return PT.str();
2056}
2057
2059#if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
2060 std::string CPU = std::string(sys::getHostCPUName());
2061 if (CPU == "generic")
2062 CPU = "(unknown)";
2063 OS << " Default target: " << sys::getDefaultTargetTriple() << '\n'
2064 << " Host CPU: " << CPU << '\n';
2065#endif
2066}
This file defines the StringMap class.
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:203
Given that RA is a live value
T Content
static std::unique_ptr< llvm::MemoryBuffer > LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent()
Definition: Host.cpp:65
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
raw_pwrite_stream & OS
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
DEMANGLE_NAMESPACE_BEGIN bool starts_with(std::string_view self, char C) noexcept
Represents either an error or a value T.
Definition: ErrorOr.h:56
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileAsStream(const Twine &Filename)
Read all of the specified file into a MemoryBuffer as a stream (i.e.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:127
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
iterator begin() const
Definition: StringRef.h:111
iterator end() const
Definition: StringRef.h:113
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:269
static constexpr size_t npos
Definition: StringRef.h:52
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:83
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::Triple get32BitArchVariant() const
Form a triple with a 32-bit variant of the current architecture.
Definition: Triple.cpp:1568
std::string normalize() const
Return the normalized form of this triple's string.
Definition: Triple.h:365
llvm::Triple get64BitArchVariant() const
Form a triple with a 64-bit variant of the current architecture.
Definition: Triple.cpp:1649
const std::string & str() const
Definition: Triple.h:435
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1556
@ AArch64SubArch_arm64e
Definition: Triple.h:149
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1560
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
@ CPU_SUBTYPE_POWERPC_970
Definition: MachO.h:1663
@ CPU_SUBTYPE_POWERPC_604e
Definition: MachO.h:1658
@ CPU_SUBTYPE_POWERPC_603e
Definition: MachO.h:1655
@ CPU_SUBTYPE_POWERPC_7400
Definition: MachO.h:1661
@ CPU_SUBTYPE_POWERPC_604
Definition: MachO.h:1657
@ CPU_SUBTYPE_POWERPC_750
Definition: MachO.h:1660
@ CPU_SUBTYPE_POWERPC_601
Definition: MachO.h:1652
@ CPU_SUBTYPE_POWERPC_620
Definition: MachO.h:1659
@ CPU_SUBTYPE_POWERPC_603ev
Definition: MachO.h:1656
@ CPU_SUBTYPE_POWERPC_603
Definition: MachO.h:1654
@ CPU_SUBTYPE_POWERPC_7450
Definition: MachO.h:1662
@ CPU_SUBTYPE_POWERPC_602
Definition: MachO.h:1653
Helper functions to extract CPU details from CPUID on x86.
Definition: Host.h:72
VendorSignatures getVendorSignature(unsigned *MaxLeaf=nullptr)
Returns the host CPU's vendor.
Definition: Host.cpp:1700
StringRef getHostCPUNameForS390x(StringRef ProcCpuinfoContent)
Definition: Host.cpp:388
StringRef getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent)
Helper functions to extract HostCPUName from /proc/cpuinfo on linux.
Definition: Host.cpp:76
StringRef getHostCPUNameForBPF()
Definition: Host.cpp:453
StringRef getHostCPUNameForARM(StringRef ProcCpuinfoContent)
Definition: Host.cpp:159
StringRef getHostCPUNameForRISCV(StringRef ProcCpuinfoContent)
Definition: Host.cpp:433
StringRef getHostCPUNameForSPARC(StringRef ProcCpuinfoContent)
StringRef getHostCPUName()
getHostCPUName - Get the LLVM name for the host CPU.
Definition: Host.cpp:1694
void printDefaultTargetAndDetectedCPU(raw_ostream &OS)
This is a function compatible with cl::AddExtraVersionPrinter, which adds info about the current targ...
Definition: Host.cpp:2058
bool getHostCPUFeatures(StringMap< bool, MallocAllocator > &Features)
getHostCPUFeatures - Get the LLVM names for the host CPU features.
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Host.cpp:2040
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:456
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.