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