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