LLVM 20.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 default:
428 return HaveVectorSupport? "z16" : "zEC12";
429 }
430}
431} // end anonymous namespace
432
434 // STIDP is a privileged operation, so use /proc/cpuinfo instead.
435
436 // The "processor 0:" line comes after a fair amount of other information,
437 // including a cache breakdown, but this should be plenty.
439 ProcCpuinfoContent.split(Lines, "\n");
440
441 // Look for the CPU features.
442 SmallVector<StringRef, 32> CPUFeatures;
443 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
444 if (Lines[I].starts_with("features")) {
445 size_t Pos = Lines[I].find(':');
446 if (Pos != StringRef::npos) {
447 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
448 break;
449 }
450 }
451
452 // We need to check for the presence of vector support independently of
453 // the machine type, since we may only use the vector register set when
454 // supported by the kernel (and hypervisor).
455 bool HaveVectorSupport = false;
456 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
457 if (CPUFeatures[I] == "vx")
458 HaveVectorSupport = true;
459 }
460
461 // Now check the processor machine type.
462 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
463 if (Lines[I].starts_with("processor ")) {
464 size_t Pos = Lines[I].find("machine = ");
465 if (Pos != StringRef::npos) {
466 Pos += sizeof("machine = ") - 1;
467 unsigned int Id;
468 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id))
469 return getCPUNameFromS390Model(Id, HaveVectorSupport);
470 }
471 break;
472 }
473 }
474
475 return "generic";
476}
477
479 // There are 24 lines in /proc/cpuinfo
481 ProcCpuinfoContent.split(Lines, "\n");
482
483 // Look for uarch line to determine cpu name
484 StringRef UArch;
485 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
486 if (Lines[I].starts_with("uarch")) {
487 UArch = Lines[I].substr(5).ltrim("\t :");
488 break;
489 }
490 }
491
492 return StringSwitch<const char *>(UArch)
493 .Case("sifive,u74-mc", "sifive-u74")
494 .Case("sifive,bullet0", "sifive-u74")
495 .Default("");
496}
497
499#if !defined(__linux__) || !defined(__x86_64__)
500 return "generic";
501#else
502 uint8_t v3_insns[40] __attribute__ ((aligned (8))) =
503 /* BPF_MOV64_IMM(BPF_REG_0, 0) */
504 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
505 /* BPF_MOV64_IMM(BPF_REG_2, 1) */
506 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
507 /* BPF_JMP32_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
508 0xae, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
509 /* BPF_MOV64_IMM(BPF_REG_0, 1) */
510 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
511 /* BPF_EXIT_INSN() */
512 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
513
514 uint8_t v2_insns[40] __attribute__ ((aligned (8))) =
515 /* BPF_MOV64_IMM(BPF_REG_0, 0) */
516 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
517 /* BPF_MOV64_IMM(BPF_REG_2, 1) */
518 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
519 /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
520 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
521 /* BPF_MOV64_IMM(BPF_REG_0, 1) */
522 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
523 /* BPF_EXIT_INSN() */
524 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
525
526 struct bpf_prog_load_attr {
527 uint32_t prog_type;
528 uint32_t insn_cnt;
529 uint64_t insns;
530 uint64_t license;
531 uint32_t log_level;
532 uint32_t log_size;
533 uint64_t log_buf;
534 uint32_t kern_version;
535 uint32_t prog_flags;
536 } attr = {};
537 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
538 attr.insn_cnt = 5;
539 attr.insns = (uint64_t)v3_insns;
540 attr.license = (uint64_t)"DUMMY";
541
542 int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr,
543 sizeof(attr));
544 if (fd >= 0) {
545 close(fd);
546 return "v3";
547 }
548
549 /* Clear the whole attr in case its content changed by syscall. */
550 memset(&attr, 0, sizeof(attr));
551 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
552 attr.insn_cnt = 5;
553 attr.insns = (uint64_t)v2_insns;
554 attr.license = (uint64_t)"DUMMY";
555 fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr));
556 if (fd >= 0) {
557 close(fd);
558 return "v2";
559 }
560 return "v1";
561#endif
562}
563
564#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
565 defined(_M_X64)
566
567/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
568/// the specified arguments. If we can't run cpuid on the host, return true.
569static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
570 unsigned *rECX, unsigned *rEDX) {
571#if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
572 return !__get_cpuid(value, rEAX, rEBX, rECX, rEDX);
573#elif defined(_MSC_VER)
574 // The MSVC intrinsic is portable across x86 and x64.
575 int registers[4];
576 __cpuid(registers, value);
577 *rEAX = registers[0];
578 *rEBX = registers[1];
579 *rECX = registers[2];
580 *rEDX = registers[3];
581 return false;
582#else
583 return true;
584#endif
585}
586
587namespace llvm {
588namespace sys {
589namespace detail {
590namespace x86 {
591
592VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
593 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
594 if (MaxLeaf == nullptr)
595 MaxLeaf = &EAX;
596 else
597 *MaxLeaf = 0;
598
599 if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1)
600 return VendorSignatures::UNKNOWN;
601
602 // "Genu ineI ntel"
603 if (EBX == 0x756e6547 && EDX == 0x49656e69 && ECX == 0x6c65746e)
604 return VendorSignatures::GENUINE_INTEL;
605
606 // "Auth enti cAMD"
607 if (EBX == 0x68747541 && EDX == 0x69746e65 && ECX == 0x444d4163)
608 return VendorSignatures::AUTHENTIC_AMD;
609
610 return VendorSignatures::UNKNOWN;
611}
612
613} // namespace x86
614} // namespace detail
615} // namespace sys
616} // namespace llvm
617
618using namespace llvm::sys::detail::x86;
619
620/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
621/// the 4 values in the specified arguments. If we can't run cpuid on the host,
622/// return true.
623static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
624 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
625 unsigned *rEDX) {
626 // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
627 // are such that __cpuidex is defined within cpuid.h for both, we can remove
628 // the __get_cpuid_count function and share the MSVC implementation between
629 // all three.
630#if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
631 return !__get_cpuid_count(value, subleaf, rEAX, rEBX, rECX, rEDX);
632#elif defined(_MSC_VER)
633 int registers[4];
634 __cpuidex(registers, value, subleaf);
635 *rEAX = registers[0];
636 *rEBX = registers[1];
637 *rECX = registers[2];
638 *rEDX = registers[3];
639 return false;
640#else
641 return true;
642#endif
643}
644
645// Read control register 0 (XCR0). Used to detect features such as AVX.
646static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
647 // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
648 // are such that _xgetbv is supported by both, we can unify the implementation
649 // with MSVC and remove all inline assembly.
650#if defined(__GNUC__) || defined(__clang__)
651 // Check xgetbv; this uses a .byte sequence instead of the instruction
652 // directly because older assemblers do not include support for xgetbv and
653 // there is no easy way to conditionally compile based on the assembler used.
654 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
655 return false;
656#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
657 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
658 *rEAX = Result;
659 *rEDX = Result >> 32;
660 return false;
661#else
662 return true;
663#endif
664}
665
666static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
667 unsigned *Model) {
668 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
669 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
670 if (*Family == 6 || *Family == 0xf) {
671 if (*Family == 0xf)
672 // Examine extended family ID if family ID is F.
673 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
674 // Examine extended model ID if family ID is 6 or F.
675 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
676 }
677}
678
679#define testFeature(F) (Features[F / 32] & (1 << (F % 32))) != 0
680
681static StringRef getIntelProcessorTypeAndSubtype(unsigned Family,
682 unsigned Model,
683 const unsigned *Features,
684 unsigned *Type,
685 unsigned *Subtype) {
686 StringRef CPU;
687
688 switch (Family) {
689 case 3:
690 CPU = "i386";
691 break;
692 case 4:
693 CPU = "i486";
694 break;
695 case 5:
696 if (testFeature(X86::FEATURE_MMX)) {
697 CPU = "pentium-mmx";
698 break;
699 }
700 CPU = "pentium";
701 break;
702 case 6:
703 switch (Model) {
704 case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
705 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
706 // mobile processor, Intel Core 2 Extreme processor, Intel
707 // Pentium Dual-Core processor, Intel Xeon processor, model
708 // 0Fh. All processors are manufactured using the 65 nm process.
709 case 0x16: // Intel Celeron processor model 16h. All processors are
710 // manufactured using the 65 nm process
711 CPU = "core2";
712 *Type = X86::INTEL_CORE2;
713 break;
714 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
715 // 17h. All processors are manufactured using the 45 nm process.
716 //
717 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
718 case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
719 // the 45 nm process.
720 CPU = "penryn";
721 *Type = X86::INTEL_CORE2;
722 break;
723 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
724 // processors are manufactured using the 45 nm process.
725 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
726 // As found in a Summer 2010 model iMac.
727 case 0x1f:
728 case 0x2e: // Nehalem EX
729 CPU = "nehalem";
730 *Type = X86::INTEL_COREI7;
731 *Subtype = X86::INTEL_COREI7_NEHALEM;
732 break;
733 case 0x25: // Intel Core i7, laptop version.
734 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
735 // processors are manufactured using the 32 nm process.
736 case 0x2f: // Westmere EX
737 CPU = "westmere";
738 *Type = X86::INTEL_COREI7;
739 *Subtype = X86::INTEL_COREI7_WESTMERE;
740 break;
741 case 0x2a: // Intel Core i7 processor. All processors are manufactured
742 // using the 32 nm process.
743 case 0x2d:
744 CPU = "sandybridge";
745 *Type = X86::INTEL_COREI7;
746 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
747 break;
748 case 0x3a:
749 case 0x3e: // Ivy Bridge EP
750 CPU = "ivybridge";
751 *Type = X86::INTEL_COREI7;
752 *Subtype = X86::INTEL_COREI7_IVYBRIDGE;
753 break;
754
755 // Haswell:
756 case 0x3c:
757 case 0x3f:
758 case 0x45:
759 case 0x46:
760 CPU = "haswell";
761 *Type = X86::INTEL_COREI7;
762 *Subtype = X86::INTEL_COREI7_HASWELL;
763 break;
764
765 // Broadwell:
766 case 0x3d:
767 case 0x47:
768 case 0x4f:
769 case 0x56:
770 CPU = "broadwell";
771 *Type = X86::INTEL_COREI7;
772 *Subtype = X86::INTEL_COREI7_BROADWELL;
773 break;
774
775 // Skylake:
776 case 0x4e: // Skylake mobile
777 case 0x5e: // Skylake desktop
778 case 0x8e: // Kaby Lake mobile
779 case 0x9e: // Kaby Lake desktop
780 case 0xa5: // Comet Lake-H/S
781 case 0xa6: // Comet Lake-U
782 CPU = "skylake";
783 *Type = X86::INTEL_COREI7;
784 *Subtype = X86::INTEL_COREI7_SKYLAKE;
785 break;
786
787 // Rocketlake:
788 case 0xa7:
789 CPU = "rocketlake";
790 *Type = X86::INTEL_COREI7;
791 *Subtype = X86::INTEL_COREI7_ROCKETLAKE;
792 break;
793
794 // Skylake Xeon:
795 case 0x55:
796 *Type = X86::INTEL_COREI7;
797 if (testFeature(X86::FEATURE_AVX512BF16)) {
798 CPU = "cooperlake";
799 *Subtype = X86::INTEL_COREI7_COOPERLAKE;
800 } else if (testFeature(X86::FEATURE_AVX512VNNI)) {
801 CPU = "cascadelake";
802 *Subtype = X86::INTEL_COREI7_CASCADELAKE;
803 } else {
804 CPU = "skylake-avx512";
805 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
806 }
807 break;
808
809 // Cannonlake:
810 case 0x66:
811 CPU = "cannonlake";
812 *Type = X86::INTEL_COREI7;
813 *Subtype = X86::INTEL_COREI7_CANNONLAKE;
814 break;
815
816 // Icelake:
817 case 0x7d:
818 case 0x7e:
819 CPU = "icelake-client";
820 *Type = X86::INTEL_COREI7;
821 *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT;
822 break;
823
824 // Tigerlake:
825 case 0x8c:
826 case 0x8d:
827 CPU = "tigerlake";
828 *Type = X86::INTEL_COREI7;
829 *Subtype = X86::INTEL_COREI7_TIGERLAKE;
830 break;
831
832 // Alderlake:
833 case 0x97:
834 case 0x9a:
835 CPU = "alderlake";
836 *Type = X86::INTEL_COREI7;
837 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
838 break;
839
840 // Gracemont
841 case 0xbe:
842 CPU = "gracemont";
843 *Type = X86::INTEL_COREI7;
844 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
845 break;
846
847 // Raptorlake:
848 case 0xb7:
849 case 0xba:
850 case 0xbf:
851 CPU = "raptorlake";
852 *Type = X86::INTEL_COREI7;
853 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
854 break;
855
856 // Meteorlake:
857 case 0xaa:
858 case 0xac:
859 CPU = "meteorlake";
860 *Type = X86::INTEL_COREI7;
861 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
862 break;
863
864 // Arrowlake:
865 case 0xc5:
866 // Arrowlake U:
867 case 0xb5:
868 CPU = "arrowlake";
869 *Type = X86::INTEL_COREI7;
870 *Subtype = X86::INTEL_COREI7_ARROWLAKE;
871 break;
872
873 // Arrowlake S:
874 case 0xc6:
875 CPU = "arrowlake-s";
876 *Type = X86::INTEL_COREI7;
877 *Subtype = X86::INTEL_COREI7_ARROWLAKE_S;
878 break;
879
880 // Lunarlake:
881 case 0xbd:
882 CPU = "lunarlake";
883 *Type = X86::INTEL_COREI7;
884 *Subtype = X86::INTEL_COREI7_ARROWLAKE_S;
885 break;
886
887 // Pantherlake:
888 case 0xcc:
889 CPU = "pantherlake";
890 *Type = X86::INTEL_COREI7;
891 *Subtype = X86::INTEL_COREI7_PANTHERLAKE;
892 break;
893
894 // Graniterapids:
895 case 0xad:
896 CPU = "graniterapids";
897 *Type = X86::INTEL_COREI7;
898 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS;
899 break;
900
901 // Granite Rapids D:
902 case 0xae:
903 CPU = "graniterapids-d";
904 *Type = X86::INTEL_COREI7;
905 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS_D;
906 break;
907
908 // Icelake Xeon:
909 case 0x6a:
910 case 0x6c:
911 CPU = "icelake-server";
912 *Type = X86::INTEL_COREI7;
913 *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER;
914 break;
915
916 // Emerald Rapids:
917 case 0xcf:
918 CPU = "emeraldrapids";
919 *Type = X86::INTEL_COREI7;
920 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
921 break;
922
923 // Sapphire Rapids:
924 case 0x8f:
925 CPU = "sapphirerapids";
926 *Type = X86::INTEL_COREI7;
927 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
928 break;
929
930 case 0x1c: // Most 45 nm Intel Atom processors
931 case 0x26: // 45 nm Atom Lincroft
932 case 0x27: // 32 nm Atom Medfield
933 case 0x35: // 32 nm Atom Midview
934 case 0x36: // 32 nm Atom Midview
935 CPU = "bonnell";
936 *Type = X86::INTEL_BONNELL;
937 break;
938
939 // Atom Silvermont codes from the Intel software optimization guide.
940 case 0x37:
941 case 0x4a:
942 case 0x4d:
943 case 0x5a:
944 case 0x5d:
945 case 0x4c: // really airmont
946 CPU = "silvermont";
947 *Type = X86::INTEL_SILVERMONT;
948 break;
949 // Goldmont:
950 case 0x5c: // Apollo Lake
951 case 0x5f: // Denverton
952 CPU = "goldmont";
953 *Type = X86::INTEL_GOLDMONT;
954 break;
955 case 0x7a:
956 CPU = "goldmont-plus";
957 *Type = X86::INTEL_GOLDMONT_PLUS;
958 break;
959 case 0x86:
960 case 0x8a: // Lakefield
961 case 0x96: // Elkhart Lake
962 case 0x9c: // Jasper Lake
963 CPU = "tremont";
964 *Type = X86::INTEL_TREMONT;
965 break;
966
967 // Sierraforest:
968 case 0xaf:
969 CPU = "sierraforest";
970 *Type = X86::INTEL_SIERRAFOREST;
971 break;
972
973 // Grandridge:
974 case 0xb6:
975 CPU = "grandridge";
976 *Type = X86::INTEL_GRANDRIDGE;
977 break;
978
979 // Clearwaterforest:
980 case 0xdd:
981 CPU = "clearwaterforest";
982 *Type = X86::INTEL_CLEARWATERFOREST;
983 break;
984
985 // Xeon Phi (Knights Landing + Knights Mill):
986 case 0x57:
987 CPU = "knl";
988 *Type = X86::INTEL_KNL;
989 break;
990 case 0x85:
991 CPU = "knm";
992 *Type = X86::INTEL_KNM;
993 break;
994
995 default: // Unknown family 6 CPU, try to guess.
996 // Don't both with Type/Subtype here, they aren't used by the caller.
997 // They're used above to keep the code in sync with compiler-rt.
998 // TODO detect tigerlake host from model
999 if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) {
1000 CPU = "tigerlake";
1001 } else if (testFeature(X86::FEATURE_AVX512VBMI2)) {
1002 CPU = "icelake-client";
1003 } else if (testFeature(X86::FEATURE_AVX512VBMI)) {
1004 CPU = "cannonlake";
1005 } else if (testFeature(X86::FEATURE_AVX512BF16)) {
1006 CPU = "cooperlake";
1007 } else if (testFeature(X86::FEATURE_AVX512VNNI)) {
1008 CPU = "cascadelake";
1009 } else if (testFeature(X86::FEATURE_AVX512VL)) {
1010 CPU = "skylake-avx512";
1011 } else if (testFeature(X86::FEATURE_CLFLUSHOPT)) {
1012 if (testFeature(X86::FEATURE_SHA))
1013 CPU = "goldmont";
1014 else
1015 CPU = "skylake";
1016 } else if (testFeature(X86::FEATURE_ADX)) {
1017 CPU = "broadwell";
1018 } else if (testFeature(X86::FEATURE_AVX2)) {
1019 CPU = "haswell";
1020 } else if (testFeature(X86::FEATURE_AVX)) {
1021 CPU = "sandybridge";
1022 } else if (testFeature(X86::FEATURE_SSE4_2)) {
1023 if (testFeature(X86::FEATURE_MOVBE))
1024 CPU = "silvermont";
1025 else
1026 CPU = "nehalem";
1027 } else if (testFeature(X86::FEATURE_SSE4_1)) {
1028 CPU = "penryn";
1029 } else if (testFeature(X86::FEATURE_SSSE3)) {
1030 if (testFeature(X86::FEATURE_MOVBE))
1031 CPU = "bonnell";
1032 else
1033 CPU = "core2";
1034 } else if (testFeature(X86::FEATURE_64BIT)) {
1035 CPU = "core2";
1036 } else if (testFeature(X86::FEATURE_SSE3)) {
1037 CPU = "yonah";
1038 } else if (testFeature(X86::FEATURE_SSE2)) {
1039 CPU = "pentium-m";
1040 } else if (testFeature(X86::FEATURE_SSE)) {
1041 CPU = "pentium3";
1042 } else if (testFeature(X86::FEATURE_MMX)) {
1043 CPU = "pentium2";
1044 } else {
1045 CPU = "pentiumpro";
1046 }
1047 break;
1048 }
1049 break;
1050 case 15: {
1051 if (testFeature(X86::FEATURE_64BIT)) {
1052 CPU = "nocona";
1053 break;
1054 }
1055 if (testFeature(X86::FEATURE_SSE3)) {
1056 CPU = "prescott";
1057 break;
1058 }
1059 CPU = "pentium4";
1060 break;
1061 }
1062 case 19:
1063 switch (Model) {
1064 // Diamond Rapids:
1065 case 0x01:
1066 CPU = "diamondrapids";
1067 *Type = X86::INTEL_COREI7;
1068 *Subtype = X86::INTEL_COREI7_DIAMONDRAPIDS;
1069 break;
1070
1071 default: // Unknown family 19 CPU.
1072 break;
1073 }
1074 break;
1075 default:
1076 break; // Unknown.
1077 }
1078
1079 return CPU;
1080}
1081
1082static const char *getAMDProcessorTypeAndSubtype(unsigned Family,
1083 unsigned Model,
1084 const unsigned *Features,
1085 unsigned *Type,
1086 unsigned *Subtype) {
1087 const char *CPU = 0;
1088
1089 switch (Family) {
1090 case 4:
1091 CPU = "i486";
1092 break;
1093 case 5:
1094 CPU = "pentium";
1095 switch (Model) {
1096 case 6:
1097 case 7:
1098 CPU = "k6";
1099 break;
1100 case 8:
1101 CPU = "k6-2";
1102 break;
1103 case 9:
1104 case 13:
1105 CPU = "k6-3";
1106 break;
1107 case 10:
1108 CPU = "geode";
1109 break;
1110 }
1111 break;
1112 case 6:
1113 if (testFeature(X86::FEATURE_SSE)) {
1114 CPU = "athlon-xp";
1115 break;
1116 }
1117 CPU = "athlon";
1118 break;
1119 case 15:
1120 if (testFeature(X86::FEATURE_SSE3)) {
1121 CPU = "k8-sse3";
1122 break;
1123 }
1124 CPU = "k8";
1125 break;
1126 case 16:
1127 case 18:
1128 CPU = "amdfam10";
1129 *Type = X86::AMDFAM10H; // "amdfam10"
1130 switch (Model) {
1131 case 2:
1132 *Subtype = X86::AMDFAM10H_BARCELONA;
1133 break;
1134 case 4:
1135 *Subtype = X86::AMDFAM10H_SHANGHAI;
1136 break;
1137 case 8:
1138 *Subtype = X86::AMDFAM10H_ISTANBUL;
1139 break;
1140 }
1141 break;
1142 case 20:
1143 CPU = "btver1";
1144 *Type = X86::AMD_BTVER1;
1145 break;
1146 case 21:
1147 CPU = "bdver1";
1148 *Type = X86::AMDFAM15H;
1149 if (Model >= 0x60 && Model <= 0x7f) {
1150 CPU = "bdver4";
1151 *Subtype = X86::AMDFAM15H_BDVER4;
1152 break; // 60h-7Fh: Excavator
1153 }
1154 if (Model >= 0x30 && Model <= 0x3f) {
1155 CPU = "bdver3";
1156 *Subtype = X86::AMDFAM15H_BDVER3;
1157 break; // 30h-3Fh: Steamroller
1158 }
1159 if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) {
1160 CPU = "bdver2";
1161 *Subtype = X86::AMDFAM15H_BDVER2;
1162 break; // 02h, 10h-1Fh: Piledriver
1163 }
1164 if (Model <= 0x0f) {
1165 *Subtype = X86::AMDFAM15H_BDVER1;
1166 break; // 00h-0Fh: Bulldozer
1167 }
1168 break;
1169 case 22:
1170 CPU = "btver2";
1171 *Type = X86::AMD_BTVER2;
1172 break;
1173 case 23:
1174 CPU = "znver1";
1175 *Type = X86::AMDFAM17H;
1176 if ((Model >= 0x30 && Model <= 0x3f) || (Model == 0x47) ||
1177 (Model >= 0x60 && Model <= 0x67) || (Model >= 0x68 && Model <= 0x6f) ||
1178 (Model >= 0x70 && Model <= 0x7f) || (Model >= 0x84 && Model <= 0x87) ||
1179 (Model >= 0x90 && Model <= 0x97) || (Model >= 0x98 && Model <= 0x9f) ||
1180 (Model >= 0xa0 && Model <= 0xaf)) {
1181 // Family 17h Models 30h-3Fh (Starship) Zen 2
1182 // Family 17h Models 47h (Cardinal) Zen 2
1183 // Family 17h Models 60h-67h (Renoir) Zen 2
1184 // Family 17h Models 68h-6Fh (Lucienne) Zen 2
1185 // Family 17h Models 70h-7Fh (Matisse) Zen 2
1186 // Family 17h Models 84h-87h (ProjectX) Zen 2
1187 // Family 17h Models 90h-97h (VanGogh) Zen 2
1188 // Family 17h Models 98h-9Fh (Mero) Zen 2
1189 // Family 17h Models A0h-AFh (Mendocino) Zen 2
1190 CPU = "znver2";
1191 *Subtype = X86::AMDFAM17H_ZNVER2;
1192 break;
1193 }
1194 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x20 && Model <= 0x2f)) {
1195 // Family 17h Models 10h-1Fh (Raven1) Zen
1196 // Family 17h Models 10h-1Fh (Picasso) Zen+
1197 // Family 17h Models 20h-2Fh (Raven2 x86) Zen
1198 *Subtype = X86::AMDFAM17H_ZNVER1;
1199 break;
1200 }
1201 break;
1202 case 25:
1203 CPU = "znver3";
1204 *Type = X86::AMDFAM19H;
1205 if (Model <= 0x0f || (Model >= 0x20 && Model <= 0x2f) ||
1206 (Model >= 0x30 && Model <= 0x3f) || (Model >= 0x40 && Model <= 0x4f) ||
1207 (Model >= 0x50 && Model <= 0x5f)) {
1208 // Family 19h Models 00h-0Fh (Genesis, Chagall) Zen 3
1209 // Family 19h Models 20h-2Fh (Vermeer) Zen 3
1210 // Family 19h Models 30h-3Fh (Badami) Zen 3
1211 // Family 19h Models 40h-4Fh (Rembrandt) Zen 3+
1212 // Family 19h Models 50h-5Fh (Cezanne) Zen 3
1213 *Subtype = X86::AMDFAM19H_ZNVER3;
1214 break;
1215 }
1216 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x60 && Model <= 0x6f) ||
1217 (Model >= 0x70 && Model <= 0x77) || (Model >= 0x78 && Model <= 0x7f) ||
1218 (Model >= 0xa0 && Model <= 0xaf)) {
1219 // Family 19h Models 10h-1Fh (Stones; Storm Peak) Zen 4
1220 // Family 19h Models 60h-6Fh (Raphael) Zen 4
1221 // Family 19h Models 70h-77h (Phoenix, Hawkpoint1) Zen 4
1222 // Family 19h Models 78h-7Fh (Phoenix 2, Hawkpoint2) Zen 4
1223 // Family 19h Models A0h-AFh (Stones-Dense) Zen 4
1224 CPU = "znver4";
1225 *Subtype = X86::AMDFAM19H_ZNVER4;
1226 break; // "znver4"
1227 }
1228 break; // family 19h
1229 case 26:
1230 CPU = "znver5";
1231 *Type = X86::AMDFAM1AH;
1232 if (Model <= 0x77) {
1233 // Models 00h-0Fh (Breithorn).
1234 // Models 10h-1Fh (Breithorn-Dense).
1235 // Models 20h-2Fh (Strix 1).
1236 // Models 30h-37h (Strix 2).
1237 // Models 38h-3Fh (Strix 3).
1238 // Models 40h-4Fh (Granite Ridge).
1239 // Models 50h-5Fh (Weisshorn).
1240 // Models 60h-6Fh (Krackan1).
1241 // Models 70h-77h (Sarlak).
1242 CPU = "znver5";
1243 *Subtype = X86::AMDFAM1AH_ZNVER5;
1244 break; // "znver5"
1245 }
1246 break;
1247
1248 default:
1249 break; // Unknown AMD CPU.
1250 }
1251
1252 return CPU;
1253}
1254
1255#undef testFeature
1256
1257static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
1258 unsigned *Features) {
1259 unsigned EAX, EBX;
1260
1261 auto setFeature = [&](unsigned F) {
1262 Features[F / 32] |= 1U << (F % 32);
1263 };
1264
1265 if ((EDX >> 15) & 1)
1266 setFeature(X86::FEATURE_CMOV);
1267 if ((EDX >> 23) & 1)
1268 setFeature(X86::FEATURE_MMX);
1269 if ((EDX >> 25) & 1)
1270 setFeature(X86::FEATURE_SSE);
1271 if ((EDX >> 26) & 1)
1272 setFeature(X86::FEATURE_SSE2);
1273
1274 if ((ECX >> 0) & 1)
1275 setFeature(X86::FEATURE_SSE3);
1276 if ((ECX >> 1) & 1)
1277 setFeature(X86::FEATURE_PCLMUL);
1278 if ((ECX >> 9) & 1)
1279 setFeature(X86::FEATURE_SSSE3);
1280 if ((ECX >> 12) & 1)
1281 setFeature(X86::FEATURE_FMA);
1282 if ((ECX >> 19) & 1)
1283 setFeature(X86::FEATURE_SSE4_1);
1284 if ((ECX >> 20) & 1) {
1285 setFeature(X86::FEATURE_SSE4_2);
1286 setFeature(X86::FEATURE_CRC32);
1287 }
1288 if ((ECX >> 23) & 1)
1289 setFeature(X86::FEATURE_POPCNT);
1290 if ((ECX >> 25) & 1)
1291 setFeature(X86::FEATURE_AES);
1292
1293 if ((ECX >> 22) & 1)
1294 setFeature(X86::FEATURE_MOVBE);
1295
1296 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1297 // indicates that the AVX registers will be saved and restored on context
1298 // switch, then we have full AVX support.
1299 const unsigned AVXBits = (1 << 27) | (1 << 28);
1300 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
1301 ((EAX & 0x6) == 0x6);
1302#if defined(__APPLE__)
1303 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
1304 // save the AVX512 context if we use AVX512 instructions, even the bit is not
1305 // set right now.
1306 bool HasAVX512Save = true;
1307#else
1308 // AVX512 requires additional context to be saved by the OS.
1309 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
1310#endif
1311
1312 if (HasAVX)
1313 setFeature(X86::FEATURE_AVX);
1314
1315 bool HasLeaf7 =
1316 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1317
1318 if (HasLeaf7 && ((EBX >> 3) & 1))
1319 setFeature(X86::FEATURE_BMI);
1320 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
1321 setFeature(X86::FEATURE_AVX2);
1322 if (HasLeaf7 && ((EBX >> 8) & 1))
1323 setFeature(X86::FEATURE_BMI2);
1324 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) {
1325 setFeature(X86::FEATURE_AVX512F);
1326 setFeature(X86::FEATURE_EVEX512);
1327 }
1328 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
1329 setFeature(X86::FEATURE_AVX512DQ);
1330 if (HasLeaf7 && ((EBX >> 19) & 1))
1331 setFeature(X86::FEATURE_ADX);
1332 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
1333 setFeature(X86::FEATURE_AVX512IFMA);
1334 if (HasLeaf7 && ((EBX >> 23) & 1))
1335 setFeature(X86::FEATURE_CLFLUSHOPT);
1336 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
1337 setFeature(X86::FEATURE_AVX512CD);
1338 if (HasLeaf7 && ((EBX >> 29) & 1))
1339 setFeature(X86::FEATURE_SHA);
1340 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
1341 setFeature(X86::FEATURE_AVX512BW);
1342 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
1343 setFeature(X86::FEATURE_AVX512VL);
1344
1345 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
1346 setFeature(X86::FEATURE_AVX512VBMI);
1347 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
1348 setFeature(X86::FEATURE_AVX512VBMI2);
1349 if (HasLeaf7 && ((ECX >> 8) & 1))
1350 setFeature(X86::FEATURE_GFNI);
1351 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
1352 setFeature(X86::FEATURE_VPCLMULQDQ);
1353 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
1354 setFeature(X86::FEATURE_AVX512VNNI);
1355 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
1356 setFeature(X86::FEATURE_AVX512BITALG);
1357 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
1358 setFeature(X86::FEATURE_AVX512VPOPCNTDQ);
1359
1360 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
1361 setFeature(X86::FEATURE_AVX5124VNNIW);
1362 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
1363 setFeature(X86::FEATURE_AVX5124FMAPS);
1364 if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
1365 setFeature(X86::FEATURE_AVX512VP2INTERSECT);
1366
1367 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1368 // return all 0s for invalid subleaves so check the limit.
1369 bool HasLeaf7Subleaf1 =
1370 HasLeaf7 && EAX >= 1 &&
1371 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1372 if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
1373 setFeature(X86::FEATURE_AVX512BF16);
1374
1375 unsigned MaxExtLevel;
1376 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1377
1378 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1379 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1380 if (HasExtLeaf1 && ((ECX >> 6) & 1))
1381 setFeature(X86::FEATURE_SSE4_A);
1382 if (HasExtLeaf1 && ((ECX >> 11) & 1))
1383 setFeature(X86::FEATURE_XOP);
1384 if (HasExtLeaf1 && ((ECX >> 16) & 1))
1385 setFeature(X86::FEATURE_FMA4);
1386
1387 if (HasExtLeaf1 && ((EDX >> 29) & 1))
1388 setFeature(X86::FEATURE_64BIT);
1389}
1390
1392 unsigned MaxLeaf = 0;
1393 const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
1394 if (Vendor == VendorSignatures::UNKNOWN)
1395 return "generic";
1396
1397 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1398 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
1399
1400 unsigned Family = 0, Model = 0;
1401 unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0};
1402 detectX86FamilyModel(EAX, &Family, &Model);
1403 getAvailableFeatures(ECX, EDX, MaxLeaf, Features);
1404
1405 // These aren't consumed in this file, but we try to keep some source code the
1406 // same or similar to compiler-rt.
1407 unsigned Type = 0;
1408 unsigned Subtype = 0;
1409
1410 StringRef CPU;
1411
1412 if (Vendor == VendorSignatures::GENUINE_INTEL) {
1413 CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
1414 &Subtype);
1415 } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
1416 CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
1417 &Subtype);
1418 }
1419
1420 if (!CPU.empty())
1421 return CPU;
1422
1423 return "generic";
1424}
1425
1426#elif defined(__APPLE__) && defined(__powerpc__)
1428 host_basic_info_data_t hostInfo;
1429 mach_msg_type_number_t infoCount;
1430
1431 infoCount = HOST_BASIC_INFO_COUNT;
1432 mach_port_t hostPort = mach_host_self();
1433 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1434 &infoCount);
1435 mach_port_deallocate(mach_task_self(), hostPort);
1436
1437 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
1438 return "generic";
1439
1440 switch (hostInfo.cpu_subtype) {
1442 return "601";
1444 return "602";
1446 return "603";
1448 return "603e";
1450 return "603ev";
1452 return "604";
1454 return "604e";
1456 return "620";
1458 return "750";
1460 return "7400";
1462 return "7450";
1464 return "970";
1465 default:;
1466 }
1467
1468 return "generic";
1469}
1470#elif defined(__linux__) && defined(__powerpc__)
1472 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1473 StringRef Content = P ? P->getBuffer() : "";
1474 return detail::getHostCPUNameForPowerPC(Content);
1475}
1476#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1478 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1479 StringRef Content = P ? P->getBuffer() : "";
1480 return detail::getHostCPUNameForARM(Content);
1481}
1482#elif defined(__linux__) && defined(__s390x__)
1484 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1485 StringRef Content = P ? P->getBuffer() : "";
1486 return detail::getHostCPUNameForS390x(Content);
1487}
1488#elif defined(__MVS__)
1490 // Get pointer to Communications Vector Table (CVT).
1491 // The pointer is located at offset 16 of the Prefixed Save Area (PSA).
1492 // It is stored as 31 bit pointer and will be zero-extended to 64 bit.
1493 int *StartToCVTOffset = reinterpret_cast<int *>(0x10);
1494 // Since its stored as a 31-bit pointer, get the 4 bytes from the start
1495 // of address.
1496 int ReadValue = *StartToCVTOffset;
1497 // Explicitly clear the high order bit.
1498 ReadValue = (ReadValue & 0x7FFFFFFF);
1499 char *CVT = reinterpret_cast<char *>(ReadValue);
1500 // The model number is located in the CVT prefix at offset -6 and stored as
1501 // signless packed decimal.
1502 uint16_t Id = *(uint16_t *)&CVT[-6];
1503 // Convert number to integer.
1504 Id = decodePackedBCD<uint16_t>(Id, false);
1505 // Check for vector support. It's stored in field CVTFLAG5 (offset 244),
1506 // bit CVTVEF (X'80'). The facilities list is part of the PSA but the vector
1507 // extension can only be used if bit CVTVEF is on.
1508 bool HaveVectorSupport = CVT[244] & 0x80;
1509 return getCPUNameFromS390Model(Id, HaveVectorSupport);
1510}
1511#elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__))
1512#define CPUFAMILY_ARM_SWIFT 0x1e2d6381
1513#define CPUFAMILY_ARM_CYCLONE 0x37a09642
1514#define CPUFAMILY_ARM_TYPHOON 0x2c91a47e
1515#define CPUFAMILY_ARM_TWISTER 0x92fb37c8
1516#define CPUFAMILY_ARM_HURRICANE 0x67ceee93
1517#define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6
1518#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f
1519#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2
1520#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3
1521#define CPUFAMILY_ARM_BLIZZARD_AVALANCHE 0xda33d83d
1522#define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea
1523
1525 uint32_t Family;
1526 size_t Length = sizeof(Family);
1527 sysctlbyname("hw.cpufamily", &Family, &Length, NULL, 0);
1528
1529 switch (Family) {
1530 case CPUFAMILY_ARM_SWIFT:
1531 return "swift";
1532 case CPUFAMILY_ARM_CYCLONE:
1533 return "apple-a7";
1534 case CPUFAMILY_ARM_TYPHOON:
1535 return "apple-a8";
1536 case CPUFAMILY_ARM_TWISTER:
1537 return "apple-a9";
1538 case CPUFAMILY_ARM_HURRICANE:
1539 return "apple-a10";
1540 case CPUFAMILY_ARM_MONSOON_MISTRAL:
1541 return "apple-a11";
1542 case CPUFAMILY_ARM_VORTEX_TEMPEST:
1543 return "apple-a12";
1544 case CPUFAMILY_ARM_LIGHTNING_THUNDER:
1545 return "apple-a13";
1546 case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
1547 return "apple-m1";
1548 case CPUFAMILY_ARM_BLIZZARD_AVALANCHE:
1549 return "apple-m2";
1550 case CPUFAMILY_ARM_EVEREST_SAWTOOTH:
1551 return "apple-m3";
1552 default:
1553 // Default to the newest CPU we know about.
1554 return "apple-m3";
1555 }
1556}
1557#elif defined(_AIX)
1559 switch (_system_configuration.implementation) {
1560 case POWER_4:
1561 if (_system_configuration.version == PV_4_3)
1562 return "970";
1563 return "pwr4";
1564 case POWER_5:
1565 if (_system_configuration.version == PV_5)
1566 return "pwr5";
1567 return "pwr5x";
1568 case POWER_6:
1569 if (_system_configuration.version == PV_6_Compat)
1570 return "pwr6";
1571 return "pwr6x";
1572 case POWER_7:
1573 return "pwr7";
1574 case POWER_8:
1575 return "pwr8";
1576 case POWER_9:
1577 return "pwr9";
1578// TODO: simplify this once the macro is available in all OS levels.
1579#ifdef POWER_10
1580 case POWER_10:
1581#else
1582 case 0x40000:
1583#endif
1584 return "pwr10";
1585#ifdef POWER_11
1586 case POWER_11:
1587#else
1588 case 0x80000:
1589#endif
1590 return "pwr11";
1591 default:
1592 return "generic";
1593 }
1594}
1595#elif defined(__loongarch__)
1597 // Use processor id to detect cpu name.
1598 uint32_t processor_id;
1599 __asm__("cpucfg %[prid], $zero\n\t" : [prid] "=r"(processor_id));
1600 // Refer PRID_SERIES_MASK in linux kernel: arch/loongarch/include/asm/cpu.h.
1601 switch (processor_id & 0xf000) {
1602 case 0xc000: // Loongson 64bit, 4-issue
1603 return "la464";
1604 case 0xd000: // Loongson 64bit, 6-issue
1605 return "la664";
1606 // TODO: Others.
1607 default:
1608 break;
1609 }
1610 return "generic";
1611}
1612#elif defined(__riscv)
1614#if defined(__linux__)
1615 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1616 StringRef Content = P ? P->getBuffer() : "";
1617 StringRef Name = detail::getHostCPUNameForRISCV(Content);
1618 if (!Name.empty())
1619 return Name;
1620#endif
1621#if __riscv_xlen == 64
1622 return "generic-rv64";
1623#elif __riscv_xlen == 32
1624 return "generic-rv32";
1625#else
1626#error "Unhandled value of __riscv_xlen"
1627#endif
1628}
1629#elif defined(__sparc__)
1630#if defined(__linux__)
1633 ProcCpuinfoContent.split(Lines, "\n");
1634
1635 // Look for cpu line to determine cpu name
1636 StringRef Cpu;
1637 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
1638 if (Lines[I].starts_with("cpu")) {
1639 Cpu = Lines[I].substr(5).ltrim("\t :");
1640 break;
1641 }
1642 }
1643
1644 return StringSwitch<const char *>(Cpu)
1645 .StartsWith("SuperSparc", "supersparc")
1646 .StartsWith("HyperSparc", "hypersparc")
1647 .StartsWith("SpitFire", "ultrasparc")
1648 .StartsWith("BlackBird", "ultrasparc")
1649 .StartsWith("Sabre", " ultrasparc")
1650 .StartsWith("Hummingbird", "ultrasparc")
1651 .StartsWith("Cheetah", "ultrasparc3")
1652 .StartsWith("Jalapeno", "ultrasparc3")
1653 .StartsWith("Jaguar", "ultrasparc3")
1654 .StartsWith("Panther", "ultrasparc3")
1655 .StartsWith("Serrano", "ultrasparc3")
1656 .StartsWith("UltraSparc T1", "niagara")
1657 .StartsWith("UltraSparc T2", "niagara2")
1658 .StartsWith("UltraSparc T3", "niagara3")
1659 .StartsWith("UltraSparc T4", "niagara4")
1660 .StartsWith("UltraSparc T5", "niagara4")
1661 .StartsWith("LEON", "leon3")
1662 // niagara7/m8 not supported by LLVM yet.
1663 .StartsWith("SPARC-M7", "niagara4" /* "niagara7" */)
1664 .StartsWith("SPARC-S7", "niagara4" /* "niagara7" */)
1665 .StartsWith("SPARC-M8", "niagara4" /* "m8" */)
1666 .Default("generic");
1667}
1668#endif
1669
1671#if defined(__linux__)
1672 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1673 StringRef Content = P ? P->getBuffer() : "";
1674 return detail::getHostCPUNameForSPARC(Content);
1675#elif defined(__sun__) && defined(__svr4__)
1676 char *buf = NULL;
1677 kstat_ctl_t *kc;
1678 kstat_t *ksp;
1679 kstat_named_t *brand = NULL;
1680
1681 kc = kstat_open();
1682 if (kc != NULL) {
1683 ksp = kstat_lookup(kc, const_cast<char *>("cpu_info"), -1, NULL);
1684 if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1 &&
1685 ksp->ks_type == KSTAT_TYPE_NAMED)
1686 brand =
1687 (kstat_named_t *)kstat_data_lookup(ksp, const_cast<char *>("brand"));
1688 if (brand != NULL && brand->data_type == KSTAT_DATA_STRING)
1689 buf = KSTAT_NAMED_STR_PTR(brand);
1690 }
1691 kstat_close(kc);
1692
1693 return StringSwitch<const char *>(buf)
1694 .Case("TMS390S10", "supersparc") // Texas Instruments microSPARC I
1695 .Case("TMS390Z50", "supersparc") // Texas Instruments SuperSPARC I
1696 .Case("TMS390Z55",
1697 "supersparc") // Texas Instruments SuperSPARC I with SuperCache
1698 .Case("MB86904", "supersparc") // Fujitsu microSPARC II
1699 .Case("MB86907", "supersparc") // Fujitsu TurboSPARC
1700 .Case("RT623", "hypersparc") // Ross hyperSPARC
1701 .Case("RT625", "hypersparc")
1702 .Case("RT626", "hypersparc")
1703 .Case("UltraSPARC-I", "ultrasparc")
1704 .Case("UltraSPARC-II", "ultrasparc")
1705 .Case("UltraSPARC-IIe", "ultrasparc")
1706 .Case("UltraSPARC-IIi", "ultrasparc")
1707 .Case("SPARC64-III", "ultrasparc")
1708 .Case("SPARC64-IV", "ultrasparc")
1709 .Case("UltraSPARC-III", "ultrasparc3")
1710 .Case("UltraSPARC-III+", "ultrasparc3")
1711 .Case("UltraSPARC-IIIi", "ultrasparc3")
1712 .Case("UltraSPARC-IIIi+", "ultrasparc3")
1713 .Case("UltraSPARC-IV", "ultrasparc3")
1714 .Case("UltraSPARC-IV+", "ultrasparc3")
1715 .Case("SPARC64-V", "ultrasparc3")
1716 .Case("SPARC64-VI", "ultrasparc3")
1717 .Case("SPARC64-VII", "ultrasparc3")
1718 .Case("UltraSPARC-T1", "niagara")
1719 .Case("UltraSPARC-T2", "niagara2")
1720 .Case("UltraSPARC-T2", "niagara2")
1721 .Case("UltraSPARC-T2+", "niagara2")
1722 .Case("SPARC-T3", "niagara3")
1723 .Case("SPARC-T4", "niagara4")
1724 .Case("SPARC-T5", "niagara4")
1725 // niagara7/m8 not supported by LLVM yet.
1726 .Case("SPARC-M7", "niagara4" /* "niagara7" */)
1727 .Case("SPARC-S7", "niagara4" /* "niagara7" */)
1728 .Case("SPARC-M8", "niagara4" /* "m8" */)
1729 .Default("generic");
1730#else
1731 return "generic";
1732#endif
1733}
1734#else
1735StringRef sys::getHostCPUName() { return "generic"; }
1736namespace llvm {
1737namespace sys {
1738namespace detail {
1739namespace x86 {
1740
1743}
1744
1745} // namespace x86
1746} // namespace detail
1747} // namespace sys
1748} // namespace llvm
1749#endif
1750
1751#if defined(__i386__) || defined(_M_IX86) || \
1752 defined(__x86_64__) || defined(_M_X64)
1754 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1755 unsigned MaxLevel;
1756 StringMap<bool> Features;
1757
1758 if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1)
1759 return Features;
1760
1761 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1762
1763 Features["cx8"] = (EDX >> 8) & 1;
1764 Features["cmov"] = (EDX >> 15) & 1;
1765 Features["mmx"] = (EDX >> 23) & 1;
1766 Features["fxsr"] = (EDX >> 24) & 1;
1767 Features["sse"] = (EDX >> 25) & 1;
1768 Features["sse2"] = (EDX >> 26) & 1;
1769
1770 Features["sse3"] = (ECX >> 0) & 1;
1771 Features["pclmul"] = (ECX >> 1) & 1;
1772 Features["ssse3"] = (ECX >> 9) & 1;
1773 Features["cx16"] = (ECX >> 13) & 1;
1774 Features["sse4.1"] = (ECX >> 19) & 1;
1775 Features["sse4.2"] = (ECX >> 20) & 1;
1776 Features["crc32"] = Features["sse4.2"];
1777 Features["movbe"] = (ECX >> 22) & 1;
1778 Features["popcnt"] = (ECX >> 23) & 1;
1779 Features["aes"] = (ECX >> 25) & 1;
1780 Features["rdrnd"] = (ECX >> 30) & 1;
1781
1782 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1783 // indicates that the AVX registers will be saved and restored on context
1784 // switch, then we have full AVX support.
1785 bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX);
1786 bool HasAVXSave = HasXSave && ((ECX >> 28) & 1) && ((EAX & 0x6) == 0x6);
1787#if defined(__APPLE__)
1788 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
1789 // save the AVX512 context if we use AVX512 instructions, even the bit is not
1790 // set right now.
1791 bool HasAVX512Save = true;
1792#else
1793 // AVX512 requires additional context to be saved by the OS.
1794 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
1795#endif
1796 // AMX requires additional context to be saved by the OS.
1797 const unsigned AMXBits = (1 << 17) | (1 << 18);
1798 bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits);
1799
1800 Features["avx"] = HasAVXSave;
1801 Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave;
1802 // Only enable XSAVE if OS has enabled support for saving YMM state.
1803 Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave;
1804 Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave;
1805
1806 unsigned MaxExtLevel;
1807 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1808
1809 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1810 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1811 Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1);
1812 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1813 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1814 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1815 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
1816 Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
1817 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1818 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
1819 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
1820
1821 Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1);
1822
1823 // Miscellaneous memory related features, detected by
1824 // using the 0x80000008 leaf of the CPUID instruction
1825 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
1826 !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
1827 Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1);
1828 Features["rdpru"] = HasExtLeaf8 && ((EBX >> 4) & 1);
1829 Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1);
1830
1831 bool HasLeaf7 =
1832 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1833
1834 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
1835 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
1836 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
1837 // AVX2 is only supported if we have the OS save support from AVX.
1838 Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave;
1839 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
1840 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
1841 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
1842 // AVX512 is only supported if the OS supports the context save for it.
1843 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
1844 if (Features["avx512f"])
1845 Features["evex512"] = true;
1846 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
1847 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
1848 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
1849 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
1850 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
1851 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
1852 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
1853 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
1854 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
1855 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
1856
1857 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
1858 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
1859 Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1);
1860 Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save;
1861 Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1);
1862 Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1);
1863 Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave;
1864 Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave;
1865 Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save;
1866 Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
1867 Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
1868 Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1);
1869 Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker
1870 Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1);
1871 Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
1872 Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
1873 Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1);
1874
1875 Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1);
1876 Features["avx512vp2intersect"] =
1877 HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save;
1878 Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1);
1879 Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1);
1880 // There are two CPUID leafs which information associated with the pconfig
1881 // instruction:
1882 // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
1883 // bit of EDX), while the EAX=0x1b leaf returns information on the
1884 // availability of specific pconfig leafs.
1885 // The target feature here only refers to the the first of these two.
1886 // Users might need to check for the availability of specific pconfig
1887 // leaves using cpuid, since that information is ignored while
1888 // detecting features using the "-march=native" flag.
1889 // For more info, see X86 ISA docs.
1890 Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1);
1891 Features["amx-bf16"] = HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave;
1892 Features["avx512fp16"] = HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save;
1893 Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave;
1894 Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave;
1895 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1896 // return all 0s for invalid subleaves so check the limit.
1897 bool HasLeaf7Subleaf1 =
1898 HasLeaf7 && EAX >= 1 &&
1899 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1900 Features["sha512"] = HasLeaf7Subleaf1 && ((EAX >> 0) & 1);
1901 Features["sm3"] = HasLeaf7Subleaf1 && ((EAX >> 1) & 1);
1902 Features["sm4"] = HasLeaf7Subleaf1 && ((EAX >> 2) & 1);
1903 Features["raoint"] = HasLeaf7Subleaf1 && ((EAX >> 3) & 1);
1904 Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
1905 Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save;
1906 Features["amx-fp16"] = HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave;
1907 Features["cmpccxadd"] = HasLeaf7Subleaf1 && ((EAX >> 7) & 1);
1908 Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
1909 Features["avxifma"] = HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave;
1910 Features["movrs"] = HasLeaf7Subleaf1 && ((EAX >> 31) & 1);
1911 Features["avxvnniint8"] = HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave;
1912 Features["avxneconvert"] = HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave;
1913 Features["amx-complex"] = HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave;
1914 Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave;
1915 Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1);
1916 Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1);
1917 bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1);
1918 bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1);
1919 Features["egpr"] = HasAPXF;
1920 Features["push2pop2"] = HasAPXF;
1921 Features["ppx"] = HasAPXF;
1922 Features["ndd"] = HasAPXF;
1923 Features["ccmp"] = HasAPXF;
1924 Features["nf"] = HasAPXF;
1925 Features["cf"] = HasAPXF;
1926 Features["zu"] = HasAPXF;
1927
1928 bool HasLeafD = MaxLevel >= 0xd &&
1929 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
1930
1931 // Only enable XSAVE if OS has enabled support for saving YMM state.
1932 Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave;
1933 Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave;
1934 Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave;
1935
1936 bool HasLeaf14 = MaxLevel >= 0x14 &&
1937 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
1938
1939 Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1);
1940
1941 bool HasLeaf19 =
1942 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
1943 Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1);
1944
1945 bool HasLeaf1E = MaxLevel >= 0x1e &&
1946 !getX86CpuIDAndInfoEx(0x1e, 0x1, &EAX, &EBX, &ECX, &EDX);
1947 Features["amx-fp8"] = HasLeaf1E && ((EAX >> 4) & 1) && HasAMXSave;
1948 Features["amx-transpose"] = HasLeaf1E && ((EAX >> 5) & 1) && HasAMXSave;
1949 Features["amx-tf32"] = HasLeaf1E && ((EAX >> 6) & 1) && HasAMXSave;
1950 Features["amx-avx512"] = HasLeaf1E && ((EAX >> 7) & 1) && HasAMXSave;
1951 Features["amx-movrs"] = HasLeaf1E && ((EAX >> 8) & 1) && HasAMXSave;
1952
1953 bool HasLeaf24 =
1954 MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX);
1955
1956 int AVX10Ver = HasLeaf24 && (EBX & 0xff);
1957 int Has512Len = HasLeaf24 && ((EBX >> 18) & 1);
1958 Features["avx10.1-256"] = HasAVX10 && AVX10Ver >= 1;
1959 Features["avx10.1-512"] = HasAVX10 && AVX10Ver >= 1 && Has512Len;
1960 Features["avx10.2-256"] = HasAVX10 && AVX10Ver >= 2;
1961 Features["avx10.2-512"] = HasAVX10 && AVX10Ver >= 2 && Has512Len;
1962
1963 return Features;
1964}
1965#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1967 StringMap<bool> Features;
1968 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1969 if (!P)
1970 return Features;
1971
1973 P->getBuffer().split(Lines, "\n");
1974
1975 SmallVector<StringRef, 32> CPUFeatures;
1976
1977 // Look for the CPU features.
1978 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
1979 if (Lines[I].starts_with("Features")) {
1980 Lines[I].split(CPUFeatures, ' ');
1981 break;
1982 }
1983
1984#if defined(__aarch64__)
1985 // All of these are "crypto" features, but we must sift out actual features
1986 // as the former meaning of "crypto" as a single feature is no more.
1987 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1988 uint32_t crypto = 0;
1989#endif
1990
1991 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
1992 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
1993#if defined(__aarch64__)
1994 .Case("asimd", "neon")
1995 .Case("fp", "fp-armv8")
1996 .Case("crc32", "crc")
1997 .Case("atomics", "lse")
1998 .Case("sve", "sve")
1999 .Case("sve2", "sve2")
2000#else
2001 .Case("half", "fp16")
2002 .Case("neon", "neon")
2003 .Case("vfpv3", "vfp3")
2004 .Case("vfpv3d16", "vfp3d16")
2005 .Case("vfpv4", "vfp4")
2006 .Case("idiva", "hwdiv-arm")
2007 .Case("idivt", "hwdiv")
2008#endif
2009 .Default("");
2010
2011#if defined(__aarch64__)
2012 // We need to check crypto separately since we need all of the crypto
2013 // extensions to enable the subtarget feature
2014 if (CPUFeatures[I] == "aes")
2015 crypto |= CAP_AES;
2016 else if (CPUFeatures[I] == "pmull")
2017 crypto |= CAP_PMULL;
2018 else if (CPUFeatures[I] == "sha1")
2019 crypto |= CAP_SHA1;
2020 else if (CPUFeatures[I] == "sha2")
2021 crypto |= CAP_SHA2;
2022#endif
2023
2024 if (LLVMFeatureStr != "")
2025 Features[LLVMFeatureStr] = true;
2026 }
2027
2028#if defined(__aarch64__)
2029 // LLVM has decided some AArch64 CPUs have all the instructions they _may_
2030 // have, as opposed to all the instructions they _must_ have, so allow runtime
2031 // information to correct us on that.
2032 uint32_t Aes = CAP_AES | CAP_PMULL;
2033 uint32_t Sha2 = CAP_SHA1 | CAP_SHA2;
2034 Features["aes"] = (crypto & Aes) == Aes;
2035 Features["sha2"] = (crypto & Sha2) == Sha2;
2036#endif
2037
2038 return Features;
2039}
2040#elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64))
2042 StringMap<bool> Features;
2043
2044 // If we're asking the OS at runtime, believe what the OS says
2045 Features["neon"] =
2046 IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE);
2047 Features["crc"] =
2048 IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
2049
2050 // Avoid inferring "crypto" means more than the traditional AES + SHA2
2051 bool TradCrypto =
2052 IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE);
2053 Features["aes"] = TradCrypto;
2054 Features["sha2"] = TradCrypto;
2055
2056 return Features;
2057}
2058#elif defined(__linux__) && defined(__loongarch__)
2059#include <sys/auxv.h>
2061 unsigned long hwcap = getauxval(AT_HWCAP);
2062 bool HasFPU = hwcap & (1UL << 3); // HWCAP_LOONGARCH_FPU
2063 uint32_t cpucfg2 = 0x2, cpucfg3 = 0x3;
2064 __asm__("cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2] "+r"(cpucfg2));
2065 __asm__("cpucfg %[cpucfg3], %[cpucfg3]\n\t" : [cpucfg3] "+r"(cpucfg3));
2066
2067 StringMap<bool> Features;
2068
2069 Features["f"] = HasFPU && (cpucfg2 & (1U << 1)); // CPUCFG.2.FP_SP
2070 Features["d"] = HasFPU && (cpucfg2 & (1U << 2)); // CPUCFG.2.FP_DP
2071
2072 Features["lsx"] = hwcap & (1UL << 4); // HWCAP_LOONGARCH_LSX
2073 Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX
2074 Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ
2075
2076 Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE
2077 Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32
2078 Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH
2079 Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS
2080
2081 Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA
2082
2083 // TODO: Need to complete.
2084 // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL
2085 // Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ
2086 return Features;
2087}
2088#elif defined(__linux__) && defined(__riscv)
2089// struct riscv_hwprobe
2090struct RISCVHwProbe {
2091 int64_t Key;
2093};
2095 RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
2096 {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0},
2097 {/*RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF=*/9, 0}};
2098 int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
2099 /*pair_count=*/std::size(Query), /*cpu_count=*/0,
2100 /*cpus=*/0, /*flags=*/0);
2101 if (Ret != 0)
2102 return {};
2103
2104 StringMap<bool> Features;
2105 uint64_t BaseMask = Query[0].Value;
2106 // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set.
2107 if (BaseMask & 1) {
2108 Features["i"] = true;
2109 Features["m"] = true;
2110 Features["a"] = true;
2111 }
2112
2113 uint64_t ExtMask = Query[1].Value;
2114 Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
2115 Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
2116 Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C
2117 Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V
2118 Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA
2119 Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB
2120 Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS
2121 Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ
2122 Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC
2123 Features["zbkb"] = ExtMask & (1 << 8); // RISCV_HWPROBE_EXT_ZBKB
2124 Features["zbkc"] = ExtMask & (1 << 9); // RISCV_HWPROBE_EXT_ZBKC
2125 Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX
2126 Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND
2127 Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE
2128 Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH
2129 Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED
2130 Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH
2131 Features["zkt"] = ExtMask & (1 << 16); // RISCV_HWPROBE_EXT_ZKT
2132 Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB
2133 Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC
2134 Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB
2135 Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG
2136 Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED
2137 Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA
2138 Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB
2139 Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED
2140 Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH
2141 Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT
2142 Features["zfh"] = ExtMask & (1 << 27); // RISCV_HWPROBE_EXT_ZFH
2143 Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN
2144 Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL
2145 Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH
2146 Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
2147 Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA
2148 Features["ztso"] = ExtMask & (1ULL << 33); // RISCV_HWPROBE_EXT_ZTSO
2149 Features["zacas"] = ExtMask & (1ULL << 34); // RISCV_HWPROBE_EXT_ZACAS
2150 Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
2151 Features["zihintpause"] =
2152 ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
2153 Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X
2154 Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F
2155 Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X
2156 Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F
2157 Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D
2158 Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP
2159 Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA
2160 Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB
2161 Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD
2162 Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF
2163 Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP
2164 Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS
2165
2166 // Check whether the processor supports fast misaligned scalar memory access.
2167 // NOTE: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF is only available on
2168 // Linux 6.11 or later. If it is not recognized, the key field will be cleared
2169 // to -1.
2170 if (Query[2].Key != -1 &&
2171 Query[2].Value == /*RISCV_HWPROBE_MISALIGNED_SCALAR_FAST=*/3)
2172 Features["unaligned-scalar-mem"] = true;
2173
2174 return Features;
2175}
2176#else
2178#endif
2179
2180#if __APPLE__
2181/// \returns the \p triple, but with the Host's arch spliced in.
2182static Triple withHostArch(Triple T) {
2183#if defined(__arm__)
2184 T.setArch(Triple::arm);
2185 T.setArchName("arm");
2186#elif defined(__arm64e__)
2188 T.setArchName("arm64e");
2189#elif defined(__aarch64__)
2190 T.setArch(Triple::aarch64);
2191 T.setArchName("arm64");
2192#elif defined(__x86_64h__)
2193 T.setArch(Triple::x86_64);
2194 T.setArchName("x86_64h");
2195#elif defined(__x86_64__)
2196 T.setArch(Triple::x86_64);
2197 T.setArchName("x86_64");
2198#elif defined(__i386__)
2199 T.setArch(Triple::x86);
2200 T.setArchName("i386");
2201#elif defined(__powerpc__)
2202 T.setArch(Triple::ppc);
2203 T.setArchName("powerpc");
2204#else
2205# error "Unimplemented host arch fixup"
2206#endif
2207 return T;
2208}
2209#endif
2210
2212 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
2213 Triple PT(Triple::normalize(TargetTripleString));
2214
2215#if __APPLE__
2216 /// In Universal builds, LLVM_HOST_TRIPLE will have the wrong arch in one of
2217 /// the slices. This fixes that up.
2218 PT = withHostArch(PT);
2219#endif
2220
2221 if (sizeof(void *) == 8 && PT.isArch32Bit())
2222 PT = PT.get64BitArchVariant();
2223 if (sizeof(void *) == 4 && PT.isArch64Bit())
2224 PT = PT.get32BitArchVariant();
2225
2226 return PT.str();
2227}
2228
2230#if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
2231 std::string CPU = std::string(sys::getHostCPUName());
2232 if (CPU == "generic")
2233 CPU = "(unknown)";
2234 OS << " Default target: " << sys::getDefaultTargetTriple() << '\n'
2235 << " Host CPU: " << CPU << '\n';
2236#endif
2237}
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:1693
std::string normalize() const
Return the normalized form of this triple's string.
Definition: Triple.h:376
llvm::Triple get64BitArchVariant() const
Form a triple with a 64-bit variant of the current architecture.
Definition: Triple.cpp:1772
const std::string & str() const
Definition: Triple.h:450
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1681
@ AArch64SubArch_arm64e
Definition: Triple.h:148
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1685
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:1741
StringRef getHostCPUNameForS390x(StringRef ProcCpuinfoContent)
Definition: Host.cpp:433
StringRef getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent)
Helper functions to extract HostCPUName from /proc/cpuinfo on linux.
Definition: Host.cpp:85
StringRef getHostCPUNameForBPF()
Definition: Host.cpp:498
StringRef getHostCPUNameForARM(StringRef ProcCpuinfoContent)
Definition: Host.cpp:169
StringRef getHostCPUNameForRISCV(StringRef ProcCpuinfoContent)
Definition: Host.cpp:478
StringRef getHostCPUNameForSPARC(StringRef ProcCpuinfoContent)
const StringMap< bool, MallocAllocator > getHostCPUFeatures()
getHostCPUFeatures - Get the LLVM names for the host CPU features.
Definition: Host.cpp:2177
StringRef getHostCPUName()
getHostCPUName - Get the LLVM name for the host CPU.
Definition: Host.cpp:1735
void printDefaultTargetAndDetectedCPU(raw_ostream &OS)
This is a function compatible with cl::AddExtraVersionPrinter, which adds info about the current targ...
Definition: Host.cpp:2229
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Host.cpp:2211
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.