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