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