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