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