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
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("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 // Wildcatlake:
968 case 0xd5:
969 CPU = "wildcatlake";
970 *Type = X86::INTEL_COREI7;
971 *Subtype = X86::INTEL_COREI7_PANTHERLAKE;
972 break;
973
974 // Graniterapids:
975 case 0xad:
976 CPU = "graniterapids";
977 *Type = X86::INTEL_COREI7;
978 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS;
979 break;
980
981 // Granite Rapids D:
982 case 0xae:
983 CPU = "graniterapids-d";
984 *Type = X86::INTEL_COREI7;
985 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS_D;
986 break;
987
988 // Icelake Xeon:
989 case 0x6a:
990 case 0x6c:
991 CPU = "icelake-server";
992 *Type = X86::INTEL_COREI7;
993 *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER;
994 break;
995
996 // Emerald Rapids:
997 case 0xcf:
998 CPU = "emeraldrapids";
999 *Type = X86::INTEL_COREI7;
1000 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
1001 break;
1002
1003 // Sapphire Rapids:
1004 case 0x8f:
1005 CPU = "sapphirerapids";
1006 *Type = X86::INTEL_COREI7;
1007 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
1008 break;
1009
1010 case 0x1c: // Most 45 nm Intel Atom processors
1011 case 0x26: // 45 nm Atom Lincroft
1012 case 0x27: // 32 nm Atom Medfield
1013 case 0x35: // 32 nm Atom Midview
1014 case 0x36: // 32 nm Atom Midview
1015 CPU = "bonnell";
1016 *Type = X86::INTEL_BONNELL;
1017 break;
1018
1019 // Atom Silvermont codes from the Intel software optimization guide.
1020 case 0x37:
1021 case 0x4a:
1022 case 0x4d:
1023 case 0x5a:
1024 case 0x5d:
1025 case 0x4c: // really airmont
1026 CPU = "silvermont";
1027 *Type = X86::INTEL_SILVERMONT;
1028 break;
1029 // Goldmont:
1030 case 0x5c: // Apollo Lake
1031 case 0x5f: // Denverton
1032 CPU = "goldmont";
1033 *Type = X86::INTEL_GOLDMONT;
1034 break;
1035 case 0x7a:
1036 CPU = "goldmont-plus";
1037 *Type = X86::INTEL_GOLDMONT_PLUS;
1038 break;
1039 case 0x86:
1040 case 0x8a: // Lakefield
1041 case 0x96: // Elkhart Lake
1042 case 0x9c: // Jasper Lake
1043 CPU = "tremont";
1044 *Type = X86::INTEL_TREMONT;
1045 break;
1046
1047 // Sierraforest:
1048 case 0xaf:
1049 CPU = "sierraforest";
1050 *Type = X86::INTEL_SIERRAFOREST;
1051 break;
1052
1053 // Grandridge:
1054 case 0xb6:
1055 CPU = "grandridge";
1056 *Type = X86::INTEL_GRANDRIDGE;
1057 break;
1058
1059 // Clearwaterforest:
1060 case 0xdd:
1061 CPU = "clearwaterforest";
1062 *Type = X86::INTEL_CLEARWATERFOREST;
1063 break;
1064
1065 // Xeon Phi (Knights Landing + Knights Mill):
1066 case 0x57:
1067 CPU = "knl";
1068 *Type = X86::INTEL_KNL;
1069 break;
1070 case 0x85:
1071 CPU = "knm";
1072 *Type = X86::INTEL_KNM;
1073 break;
1074
1075 default: // Unknown family 6 CPU, try to guess.
1076 // Don't both with Type/Subtype here, they aren't used by the caller.
1077 // They're used above to keep the code in sync with compiler-rt.
1078 // TODO detect tigerlake host from model
1079 if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) {
1080 CPU = "tigerlake";
1081 } else if (testFeature(X86::FEATURE_AVX512VBMI2)) {
1082 CPU = "icelake-client";
1083 } else if (testFeature(X86::FEATURE_AVX512VBMI)) {
1084 CPU = "cannonlake";
1085 } else if (testFeature(X86::FEATURE_AVX512BF16)) {
1086 CPU = "cooperlake";
1087 } else if (testFeature(X86::FEATURE_AVX512VNNI)) {
1088 CPU = "cascadelake";
1089 } else if (testFeature(X86::FEATURE_AVX512VL)) {
1090 CPU = "skylake-avx512";
1091 } else if (testFeature(X86::FEATURE_CLFLUSHOPT)) {
1092 if (testFeature(X86::FEATURE_SHA))
1093 CPU = "goldmont";
1094 else
1095 CPU = "skylake";
1096 } else if (testFeature(X86::FEATURE_ADX)) {
1097 CPU = "broadwell";
1098 } else if (testFeature(X86::FEATURE_AVX2)) {
1099 CPU = "haswell";
1100 } else if (testFeature(X86::FEATURE_AVX)) {
1101 CPU = "sandybridge";
1102 } else if (testFeature(X86::FEATURE_SSE4_2)) {
1103 if (testFeature(X86::FEATURE_MOVBE))
1104 CPU = "silvermont";
1105 else
1106 CPU = "nehalem";
1107 } else if (testFeature(X86::FEATURE_SSE4_1)) {
1108 CPU = "penryn";
1109 } else if (testFeature(X86::FEATURE_SSSE3)) {
1110 if (testFeature(X86::FEATURE_MOVBE))
1111 CPU = "bonnell";
1112 else
1113 CPU = "core2";
1114 } else if (testFeature(X86::FEATURE_64BIT)) {
1115 CPU = "core2";
1116 } else if (testFeature(X86::FEATURE_SSE3)) {
1117 CPU = "yonah";
1118 } else if (testFeature(X86::FEATURE_SSE2)) {
1119 CPU = "pentium-m";
1120 } else if (testFeature(X86::FEATURE_SSE)) {
1121 CPU = "pentium3";
1122 } else if (testFeature(X86::FEATURE_MMX)) {
1123 CPU = "pentium2";
1124 } else {
1125 CPU = "pentiumpro";
1126 }
1127 break;
1128 }
1129 break;
1130 case 0xf: {
1131 if (testFeature(X86::FEATURE_64BIT)) {
1132 CPU = "nocona";
1133 break;
1134 }
1135 if (testFeature(X86::FEATURE_SSE3)) {
1136 CPU = "prescott";
1137 break;
1138 }
1139 CPU = "pentium4";
1140 break;
1141 }
1142 case 0x13:
1143 switch (Model) {
1144 // Diamond Rapids:
1145 case 0x01:
1146 CPU = "diamondrapids";
1147 *Type = X86::INTEL_COREI7;
1148 *Subtype = X86::INTEL_COREI7_DIAMONDRAPIDS;
1149 break;
1150
1151 default: // Unknown family 19 CPU.
1152 break;
1153 }
1154 break;
1155 case 0x12:
1156 switch (Model) {
1157 // Novalake:
1158 case 0x1:
1159 case 0x3:
1160 CPU = "novalake";
1161 *Type = X86::INTEL_COREI7;
1162 *Subtype = X86::INTEL_COREI7_NOVALAKE;
1163 break;
1164 default: // Unknown family 0x12 CPU.
1165 break;
1166 }
1167 break;
1168
1169 default:
1170 break; // Unknown.
1171 }
1172
1173 return CPU;
1174}
1175
1176static const char *getAMDProcessorTypeAndSubtype(unsigned Family,
1177 unsigned Model,
1178 const unsigned *Features,
1179 unsigned *Type,
1180 unsigned *Subtype) {
1181 const char *CPU = 0;
1182
1183 switch (Family) {
1184 case 4:
1185 CPU = "i486";
1186 break;
1187 case 5:
1188 CPU = "pentium";
1189 switch (Model) {
1190 case 6:
1191 case 7:
1192 CPU = "k6";
1193 break;
1194 case 8:
1195 CPU = "k6-2";
1196 break;
1197 case 9:
1198 case 13:
1199 CPU = "k6-3";
1200 break;
1201 case 10:
1202 CPU = "geode";
1203 break;
1204 }
1205 break;
1206 case 6:
1207 if (testFeature(X86::FEATURE_SSE)) {
1208 CPU = "athlon-xp";
1209 break;
1210 }
1211 CPU = "athlon";
1212 break;
1213 case 15:
1214 if (testFeature(X86::FEATURE_SSE3)) {
1215 CPU = "k8-sse3";
1216 break;
1217 }
1218 CPU = "k8";
1219 break;
1220 case 16:
1221 case 18:
1222 CPU = "amdfam10";
1223 *Type = X86::AMDFAM10H; // "amdfam10"
1224 switch (Model) {
1225 case 2:
1226 *Subtype = X86::AMDFAM10H_BARCELONA;
1227 break;
1228 case 4:
1229 *Subtype = X86::AMDFAM10H_SHANGHAI;
1230 break;
1231 case 8:
1232 *Subtype = X86::AMDFAM10H_ISTANBUL;
1233 break;
1234 }
1235 break;
1236 case 20:
1237 CPU = "btver1";
1238 *Type = X86::AMD_BTVER1;
1239 break;
1240 case 21:
1241 CPU = "bdver1";
1242 *Type = X86::AMDFAM15H;
1243 if (Model >= 0x60 && Model <= 0x7f) {
1244 CPU = "bdver4";
1245 *Subtype = X86::AMDFAM15H_BDVER4;
1246 break; // 60h-7Fh: Excavator
1247 }
1248 if (Model >= 0x30 && Model <= 0x3f) {
1249 CPU = "bdver3";
1250 *Subtype = X86::AMDFAM15H_BDVER3;
1251 break; // 30h-3Fh: Steamroller
1252 }
1253 if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) {
1254 CPU = "bdver2";
1255 *Subtype = X86::AMDFAM15H_BDVER2;
1256 break; // 02h, 10h-1Fh: Piledriver
1257 }
1258 if (Model <= 0x0f) {
1259 *Subtype = X86::AMDFAM15H_BDVER1;
1260 break; // 00h-0Fh: Bulldozer
1261 }
1262 break;
1263 case 22:
1264 CPU = "btver2";
1265 *Type = X86::AMD_BTVER2;
1266 break;
1267 case 23:
1268 CPU = "znver1";
1269 *Type = X86::AMDFAM17H;
1270 if ((Model >= 0x30 && Model <= 0x3f) || (Model == 0x47) ||
1271 (Model >= 0x60 && Model <= 0x67) || (Model >= 0x68 && Model <= 0x6f) ||
1272 (Model >= 0x70 && Model <= 0x7f) || (Model >= 0x84 && Model <= 0x87) ||
1273 (Model >= 0x90 && Model <= 0x97) || (Model >= 0x98 && Model <= 0x9f) ||
1274 (Model >= 0xa0 && Model <= 0xaf)) {
1275 // Family 17h Models 30h-3Fh (Starship) Zen 2
1276 // Family 17h Models 47h (Cardinal) Zen 2
1277 // Family 17h Models 60h-67h (Renoir) Zen 2
1278 // Family 17h Models 68h-6Fh (Lucienne) Zen 2
1279 // Family 17h Models 70h-7Fh (Matisse) Zen 2
1280 // Family 17h Models 84h-87h (ProjectX) Zen 2
1281 // Family 17h Models 90h-97h (VanGogh) Zen 2
1282 // Family 17h Models 98h-9Fh (Mero) Zen 2
1283 // Family 17h Models A0h-AFh (Mendocino) Zen 2
1284 CPU = "znver2";
1285 *Subtype = X86::AMDFAM17H_ZNVER2;
1286 break;
1287 }
1288 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x20 && Model <= 0x2f)) {
1289 // Family 17h Models 10h-1Fh (Raven1) Zen
1290 // Family 17h Models 10h-1Fh (Picasso) Zen+
1291 // Family 17h Models 20h-2Fh (Raven2 x86) Zen
1292 *Subtype = X86::AMDFAM17H_ZNVER1;
1293 break;
1294 }
1295 break;
1296 case 25:
1297 CPU = "znver3";
1298 *Type = X86::AMDFAM19H;
1299 if (Model <= 0x0f || (Model >= 0x20 && Model <= 0x2f) ||
1300 (Model >= 0x30 && Model <= 0x3f) || (Model >= 0x40 && Model <= 0x4f) ||
1301 (Model >= 0x50 && Model <= 0x5f)) {
1302 // Family 19h Models 00h-0Fh (Genesis, Chagall) Zen 3
1303 // Family 19h Models 20h-2Fh (Vermeer) Zen 3
1304 // Family 19h Models 30h-3Fh (Badami) Zen 3
1305 // Family 19h Models 40h-4Fh (Rembrandt) Zen 3+
1306 // Family 19h Models 50h-5Fh (Cezanne) Zen 3
1307 *Subtype = X86::AMDFAM19H_ZNVER3;
1308 break;
1309 }
1310 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x60 && Model <= 0x6f) ||
1311 (Model >= 0x70 && Model <= 0x77) || (Model >= 0x78 && Model <= 0x7f) ||
1312 (Model >= 0xa0 && Model <= 0xaf)) {
1313 // Family 19h Models 10h-1Fh (Stones; Storm Peak) Zen 4
1314 // Family 19h Models 60h-6Fh (Raphael) Zen 4
1315 // Family 19h Models 70h-77h (Phoenix, Hawkpoint1) Zen 4
1316 // Family 19h Models 78h-7Fh (Phoenix 2, Hawkpoint2) Zen 4
1317 // Family 19h Models A0h-AFh (Stones-Dense) Zen 4
1318 CPU = "znver4";
1319 *Subtype = X86::AMDFAM19H_ZNVER4;
1320 break; // "znver4"
1321 }
1322 break; // family 19h
1323 case 26:
1324 CPU = "znver5";
1325 *Type = X86::AMDFAM1AH;
1326 if (Model <= 0x4f || (Model >= 0x60 && Model <= 0x77) ||
1327 (Model >= 0xd0 && Model <= 0xd7)) {
1328 // Models 00h-0Fh (Breithorn).
1329 // Models 10h-1Fh (Breithorn-Dense).
1330 // Models 20h-2Fh (Strix 1).
1331 // Models 30h-37h (Strix 2).
1332 // Models 38h-3Fh (Strix 3).
1333 // Models 40h-4Fh (Granite Ridge).
1334 // Models 60h-6Fh (Krackan1).
1335 // Models 70h-77h (Sarlak).
1336 // Models D0h-D7h (Annapurna).
1337 CPU = "znver5";
1338 *Subtype = X86::AMDFAM1AH_ZNVER5;
1339 break; // "znver5"
1340 }
1341 break;
1342
1343 default:
1344 break; // Unknown AMD CPU.
1345 }
1346
1347 return CPU;
1348}
1349
1350#undef testFeature
1351
1352static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
1353 unsigned *Features) {
1354 unsigned EAX, EBX;
1355
1356 auto setFeature = [&](unsigned F) {
1357 Features[F / 32] |= 1U << (F % 32);
1358 };
1359
1360 if ((EDX >> 15) & 1)
1361 setFeature(X86::FEATURE_CMOV);
1362 if ((EDX >> 23) & 1)
1363 setFeature(X86::FEATURE_MMX);
1364 if ((EDX >> 25) & 1)
1365 setFeature(X86::FEATURE_SSE);
1366 if ((EDX >> 26) & 1)
1367 setFeature(X86::FEATURE_SSE2);
1368
1369 if ((ECX >> 0) & 1)
1370 setFeature(X86::FEATURE_SSE3);
1371 if ((ECX >> 1) & 1)
1372 setFeature(X86::FEATURE_PCLMUL);
1373 if ((ECX >> 9) & 1)
1374 setFeature(X86::FEATURE_SSSE3);
1375 if ((ECX >> 12) & 1)
1376 setFeature(X86::FEATURE_FMA);
1377 if ((ECX >> 19) & 1)
1378 setFeature(X86::FEATURE_SSE4_1);
1379 if ((ECX >> 20) & 1) {
1380 setFeature(X86::FEATURE_SSE4_2);
1381 setFeature(X86::FEATURE_CRC32);
1382 }
1383 if ((ECX >> 23) & 1)
1384 setFeature(X86::FEATURE_POPCNT);
1385 if ((ECX >> 25) & 1)
1386 setFeature(X86::FEATURE_AES);
1387
1388 if ((ECX >> 22) & 1)
1389 setFeature(X86::FEATURE_MOVBE);
1390
1391 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1392 // indicates that the AVX registers will be saved and restored on context
1393 // switch, then we have full AVX support.
1394 const unsigned AVXBits = (1 << 27) | (1 << 28);
1395 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
1396 ((EAX & 0x6) == 0x6);
1397#if defined(__APPLE__)
1398 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
1399 // save the AVX512 context if we use AVX512 instructions, even the bit is not
1400 // set right now.
1401 bool HasAVX512Save = true;
1402#else
1403 // AVX512 requires additional context to be saved by the OS.
1404 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
1405#endif
1406
1407 if (HasAVX)
1408 setFeature(X86::FEATURE_AVX);
1409
1410 bool HasLeaf7 =
1411 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1412
1413 if (HasLeaf7 && ((EBX >> 3) & 1))
1414 setFeature(X86::FEATURE_BMI);
1415 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
1416 setFeature(X86::FEATURE_AVX2);
1417 if (HasLeaf7 && ((EBX >> 8) & 1))
1418 setFeature(X86::FEATURE_BMI2);
1419 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) {
1420 setFeature(X86::FEATURE_AVX512F);
1421 }
1422 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
1423 setFeature(X86::FEATURE_AVX512DQ);
1424 if (HasLeaf7 && ((EBX >> 19) & 1))
1425 setFeature(X86::FEATURE_ADX);
1426 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
1427 setFeature(X86::FEATURE_AVX512IFMA);
1428 if (HasLeaf7 && ((EBX >> 23) & 1))
1429 setFeature(X86::FEATURE_CLFLUSHOPT);
1430 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
1431 setFeature(X86::FEATURE_AVX512CD);
1432 if (HasLeaf7 && ((EBX >> 29) & 1))
1433 setFeature(X86::FEATURE_SHA);
1434 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
1435 setFeature(X86::FEATURE_AVX512BW);
1436 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
1437 setFeature(X86::FEATURE_AVX512VL);
1438
1439 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
1440 setFeature(X86::FEATURE_AVX512VBMI);
1441 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
1442 setFeature(X86::FEATURE_AVX512VBMI2);
1443 if (HasLeaf7 && ((ECX >> 8) & 1))
1444 setFeature(X86::FEATURE_GFNI);
1445 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
1446 setFeature(X86::FEATURE_VPCLMULQDQ);
1447 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
1448 setFeature(X86::FEATURE_AVX512VNNI);
1449 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
1450 setFeature(X86::FEATURE_AVX512BITALG);
1451 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
1452 setFeature(X86::FEATURE_AVX512VPOPCNTDQ);
1453
1454 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
1455 setFeature(X86::FEATURE_AVX5124VNNIW);
1456 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
1457 setFeature(X86::FEATURE_AVX5124FMAPS);
1458 if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
1459 setFeature(X86::FEATURE_AVX512VP2INTERSECT);
1460
1461 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1462 // return all 0s for invalid subleaves so check the limit.
1463 bool HasLeaf7Subleaf1 =
1464 HasLeaf7 && EAX >= 1 &&
1465 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1466 if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
1467 setFeature(X86::FEATURE_AVX512BF16);
1468
1469 unsigned MaxExtLevel;
1470 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1471
1472 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1473 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1474 if (HasExtLeaf1 && ((ECX >> 6) & 1))
1475 setFeature(X86::FEATURE_SSE4_A);
1476 if (HasExtLeaf1 && ((ECX >> 11) & 1))
1477 setFeature(X86::FEATURE_XOP);
1478 if (HasExtLeaf1 && ((ECX >> 16) & 1))
1479 setFeature(X86::FEATURE_FMA4);
1480
1481 if (HasExtLeaf1 && ((EDX >> 29) & 1))
1482 setFeature(X86::FEATURE_64BIT);
1483}
1484
1486 unsigned MaxLeaf = 0;
1487 const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
1488 if (Vendor == VendorSignatures::UNKNOWN)
1489 return "generic";
1490
1491 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1492 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
1493
1494 unsigned Family = 0, Model = 0;
1495 unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0};
1496 detectX86FamilyModel(EAX, &Family, &Model);
1497 getAvailableFeatures(ECX, EDX, MaxLeaf, Features);
1498
1499 // These aren't consumed in this file, but we try to keep some source code the
1500 // same or similar to compiler-rt.
1501 unsigned Type = 0;
1502 unsigned Subtype = 0;
1503
1504 StringRef CPU;
1505
1506 if (Vendor == VendorSignatures::GENUINE_INTEL) {
1507 CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
1508 &Subtype);
1509 } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
1510 CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
1511 &Subtype);
1512 }
1513
1514 if (!CPU.empty())
1515 return CPU;
1516
1517 return "generic";
1518}
1519
1520#elif defined(_M_ARM64) || defined(_M_ARM64EC)
1521
1523 constexpr char CentralProcessorKeyName[] =
1524 "HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
1525 // Sub keys names are simple numbers ("0", "1", etc.) so 10 chars should be
1526 // enough for the slash and name.
1527 constexpr size_t SubKeyNameMaxSize = ARRAYSIZE(CentralProcessorKeyName) + 10;
1528
1529 SmallVector<uint64_t> Values;
1530 uint64_t PrimaryCpuInfo;
1531 char PrimaryPartKeyName[SubKeyNameMaxSize];
1532 DWORD PrimaryPartKeyNameSize = 0;
1533 HKEY CentralProcessorKey;
1534 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, CentralProcessorKeyName, 0, KEY_READ,
1535 &CentralProcessorKey) == ERROR_SUCCESS) {
1536 for (unsigned Index = 0; Index < UINT32_MAX; ++Index) {
1537 char SubKeyName[SubKeyNameMaxSize];
1538 DWORD SubKeySize = SubKeyNameMaxSize;
1539 HKEY SubKey;
1540 if ((RegEnumKeyExA(CentralProcessorKey, Index, SubKeyName, &SubKeySize,
1541 nullptr, nullptr, nullptr,
1542 nullptr) == ERROR_SUCCESS) &&
1543 (RegOpenKeyExA(CentralProcessorKey, SubKeyName, 0, KEY_READ,
1544 &SubKey) == ERROR_SUCCESS)) {
1545 // The "CP 4000" registry key contains a cached copy of the MIDR_EL1
1546 // register.
1547 uint64_t RegValue;
1548 DWORD ActualType;
1549 DWORD RegValueSize = sizeof(RegValue);
1550 if ((RegQueryValueExA(SubKey, "CP 4000", nullptr, &ActualType,
1551 (PBYTE)&RegValue,
1552 &RegValueSize) == ERROR_SUCCESS) &&
1553 (ActualType == REG_QWORD) && RegValueSize == sizeof(RegValue)) {
1554 // Assume that the part with the "highest" reg key name is the primary
1555 // part (to match the way that Linux's cpuinfo is written). Win32
1556 // makes no guarantees about the order of sub keys, so we have to
1557 // compare the names.
1558 if (PrimaryPartKeyNameSize < SubKeySize ||
1559 (PrimaryPartKeyNameSize == SubKeySize &&
1560 ::memcmp(SubKeyName, PrimaryPartKeyName, SubKeySize) > 0)) {
1561 PrimaryCpuInfo = RegValue;
1562 ::memcpy(PrimaryPartKeyName, SubKeyName, SubKeySize + 1);
1563 PrimaryPartKeyNameSize = SubKeySize;
1564 }
1565 if (!llvm::is_contained(Values, RegValue)) {
1566 Values.push_back(RegValue);
1567 }
1568 }
1569 RegCloseKey(SubKey);
1570 } else {
1571 // No more sub keys.
1572 break;
1573 }
1574 }
1575 RegCloseKey(CentralProcessorKey);
1576 }
1577
1578 if (Values.empty()) {
1579 return "generic";
1580 }
1581
1582 // Win32 makes no guarantees about the order of sub keys, so sort to ensure
1583 // reproducibility.
1584 llvm::sort(Values);
1585
1586 return detail::getHostCPUNameForARM(PrimaryCpuInfo, Values);
1587}
1588
1589#elif defined(__APPLE__) && defined(__powerpc__)
1591 host_basic_info_data_t hostInfo;
1592 mach_msg_type_number_t infoCount;
1593
1594 infoCount = HOST_BASIC_INFO_COUNT;
1595 mach_port_t hostPort = mach_host_self();
1596 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1597 &infoCount);
1598 mach_port_deallocate(mach_task_self(), hostPort);
1599
1600 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
1601 return "generic";
1602
1603 switch (hostInfo.cpu_subtype) {
1605 return "601";
1607 return "602";
1609 return "603";
1611 return "603e";
1613 return "603ev";
1615 return "604";
1617 return "604e";
1619 return "620";
1621 return "750";
1623 return "7400";
1625 return "7450";
1627 return "970";
1628 default:;
1629 }
1630
1631 return "generic";
1632}
1633#elif defined(__linux__) && defined(__powerpc__)
1635 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1636 StringRef Content = P ? P->getBuffer() : "";
1637 return detail::getHostCPUNameForPowerPC(Content);
1638}
1639#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1641 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1642 StringRef Content = P ? P->getBuffer() : "";
1643 return detail::getHostCPUNameForARM(Content);
1644}
1645#elif defined(__linux__) && defined(__s390x__)
1647 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1648 StringRef Content = P ? P->getBuffer() : "";
1649 return detail::getHostCPUNameForS390x(Content);
1650}
1651#elif defined(__MVS__)
1653 // Get pointer to Communications Vector Table (CVT).
1654 // The pointer is located at offset 16 of the Prefixed Save Area (PSA).
1655 // It is stored as 31 bit pointer and will be zero-extended to 64 bit.
1656 int *StartToCVTOffset = reinterpret_cast<int *>(0x10);
1657 // Since its stored as a 31-bit pointer, get the 4 bytes from the start
1658 // of address.
1659 int ReadValue = *StartToCVTOffset;
1660 // Explicitly clear the high order bit.
1661 ReadValue = (ReadValue & 0x7FFFFFFF);
1662 char *CVT = reinterpret_cast<char *>(ReadValue);
1663 // The model number is located in the CVT prefix at offset -6 and stored as
1664 // signless packed decimal.
1665 uint16_t Id = *(uint16_t *)&CVT[-6];
1666 // Convert number to integer.
1667 Id = decodePackedBCD<uint16_t>(Id, false);
1668 // Check for vector support. It's stored in field CVTFLAG5 (offset 244),
1669 // bit CVTVEF (X'80'). The facilities list is part of the PSA but the vector
1670 // extension can only be used if bit CVTVEF is on.
1671 bool HaveVectorSupport = CVT[244] & 0x80;
1672 return getCPUNameFromS390Model(Id, HaveVectorSupport);
1673}
1674#elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__))
1675// Copied from <mach/machine.h> in the macOS SDK.
1676//
1677// Also available here, though usually not as up-to-date:
1678// https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/mach/machine.h#L403-L452.
1679#define CPUFAMILY_UNKNOWN 0
1680#define CPUFAMILY_ARM_9 0xe73283ae
1681#define CPUFAMILY_ARM_11 0x8ff620d8
1682#define CPUFAMILY_ARM_XSCALE 0x53b005f5
1683#define CPUFAMILY_ARM_12 0xbd1b0ae9
1684#define CPUFAMILY_ARM_13 0x0cc90e64
1685#define CPUFAMILY_ARM_14 0x96077ef1
1686#define CPUFAMILY_ARM_15 0xa8511bca
1687#define CPUFAMILY_ARM_SWIFT 0x1e2d6381
1688#define CPUFAMILY_ARM_CYCLONE 0x37a09642
1689#define CPUFAMILY_ARM_TYPHOON 0x2c91a47e
1690#define CPUFAMILY_ARM_TWISTER 0x92fb37c8
1691#define CPUFAMILY_ARM_HURRICANE 0x67ceee93
1692#define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6
1693#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f
1694#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2
1695#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3
1696#define CPUFAMILY_ARM_BLIZZARD_AVALANCHE 0xda33d83d
1697#define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea
1698#define CPUFAMILY_ARM_IBIZA 0xfa33415e
1699#define CPUFAMILY_ARM_PALMA 0x72015832
1700#define CPUFAMILY_ARM_COLL 0x2876f5b5
1701#define CPUFAMILY_ARM_LOBOS 0x5f4dea93
1702#define CPUFAMILY_ARM_DONAN 0x6f5129ac
1703#define CPUFAMILY_ARM_BRAVA 0x17d5b93a
1704#define CPUFAMILY_ARM_TAHITI 0x75d4acb9
1705#define CPUFAMILY_ARM_TUPAI 0x204526d0
1706
1708 uint32_t Family;
1709 size_t Length = sizeof(Family);
1710 sysctlbyname("hw.cpufamily", &Family, &Length, NULL, 0);
1711
1712 // This is found by testing on actual hardware, and by looking at:
1713 // https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/arm/cpuid.c#L109-L231.
1714 //
1715 // Another great resource is
1716 // https://github.com/AsahiLinux/docs/wiki/Codenames.
1717 //
1718 // NOTE: We choose to return `apple-mX` instead of `apple-aX`, since the M1,
1719 // M2, M3 etc. aliases are more widely known to users than A14, A15, A16 etc.
1720 // (and this code is basically only used on host macOS anyways).
1721 switch (Family) {
1722 case CPUFAMILY_UNKNOWN:
1723 return "generic";
1724 case CPUFAMILY_ARM_9:
1725 return "arm920t"; // or arm926ej-s
1726 case CPUFAMILY_ARM_11:
1727 return "arm1136jf-s";
1728 case CPUFAMILY_ARM_XSCALE:
1729 return "xscale";
1730 case CPUFAMILY_ARM_12: // Seems unused by the kernel
1731 return "generic";
1732 case CPUFAMILY_ARM_13:
1733 return "cortex-a8";
1734 case CPUFAMILY_ARM_14:
1735 return "cortex-a9";
1736 case CPUFAMILY_ARM_15:
1737 return "cortex-a7";
1738 case CPUFAMILY_ARM_SWIFT:
1739 return "swift";
1740 case CPUFAMILY_ARM_CYCLONE:
1741 return "apple-a7";
1742 case CPUFAMILY_ARM_TYPHOON:
1743 return "apple-a8";
1744 case CPUFAMILY_ARM_TWISTER:
1745 return "apple-a9";
1746 case CPUFAMILY_ARM_HURRICANE:
1747 return "apple-a10";
1748 case CPUFAMILY_ARM_MONSOON_MISTRAL:
1749 return "apple-a11";
1750 case CPUFAMILY_ARM_VORTEX_TEMPEST:
1751 return "apple-a12";
1752 case CPUFAMILY_ARM_LIGHTNING_THUNDER:
1753 return "apple-a13";
1754 case CPUFAMILY_ARM_FIRESTORM_ICESTORM: // A14 / M1
1755 return "apple-m1";
1756 case CPUFAMILY_ARM_BLIZZARD_AVALANCHE: // A15 / M2
1757 return "apple-m2";
1758 case CPUFAMILY_ARM_EVEREST_SAWTOOTH: // A16
1759 case CPUFAMILY_ARM_IBIZA: // M3
1760 case CPUFAMILY_ARM_PALMA: // M3 Max
1761 case CPUFAMILY_ARM_LOBOS: // M3 Pro
1762 return "apple-m3";
1763 case CPUFAMILY_ARM_COLL: // A17 Pro
1764 return "apple-a17";
1765 case CPUFAMILY_ARM_DONAN: // M4
1766 case CPUFAMILY_ARM_BRAVA: // M4 Max
1767 case CPUFAMILY_ARM_TAHITI: // A18 Pro
1768 case CPUFAMILY_ARM_TUPAI: // A18
1769 return "apple-m4";
1770 default:
1771 // Default to the newest CPU we know about.
1772 return "apple-m4";
1773 }
1774}
1775#elif defined(_AIX)
1777 switch (_system_configuration.implementation) {
1778 case POWER_4:
1779 if (_system_configuration.version == PV_4_3)
1780 return "970";
1781 return "pwr4";
1782 case POWER_5:
1783 if (_system_configuration.version == PV_5)
1784 return "pwr5";
1785 return "pwr5x";
1786 case POWER_6:
1787 if (_system_configuration.version == PV_6_Compat)
1788 return "pwr6";
1789 return "pwr6x";
1790 case POWER_7:
1791 return "pwr7";
1792 case POWER_8:
1793 return "pwr8";
1794 case POWER_9:
1795 return "pwr9";
1796// TODO: simplify this once the macro is available in all OS levels.
1797#ifdef POWER_10
1798 case POWER_10:
1799#else
1800 case 0x40000:
1801#endif
1802 return "pwr10";
1803#ifdef POWER_11
1804 case POWER_11:
1805#else
1806 case 0x80000:
1807#endif
1808 return "pwr11";
1809 default:
1810 return "generic";
1811 }
1812}
1813#elif defined(__loongarch__)
1815 // Use processor id to detect cpu name.
1816 uint32_t processor_id;
1817 __asm__("cpucfg %[prid], $zero\n\t" : [prid] "=r"(processor_id));
1818 // Refer PRID_SERIES_MASK in linux kernel: arch/loongarch/include/asm/cpu.h.
1819 switch (processor_id & 0xf000) {
1820 case 0xc000: // Loongson 64bit, 4-issue
1821 return "la464";
1822 case 0xd000: // Loongson 64bit, 6-issue
1823 return "la664";
1824 // TODO: Others.
1825 default:
1826 break;
1827 }
1828 return "generic";
1829}
1830#elif defined(__riscv)
1831#if defined(__linux__)
1832// struct riscv_hwprobe
1833struct RISCVHwProbe {
1834 int64_t Key;
1835 uint64_t Value;
1836};
1837#endif
1838
1840#if defined(__linux__)
1841 // Try the hwprobe way first.
1842 RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_MVENDORID=*/0, 0},
1843 {/*RISCV_HWPROBE_KEY_MARCHID=*/1, 0},
1844 {/*RISCV_HWPROBE_KEY_MIMPID=*/2, 0}};
1845 int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
1846 /*pair_count=*/std::size(Query), /*cpu_count=*/0,
1847 /*cpus=*/0, /*flags=*/0);
1848 if (Ret == 0) {
1849 RISCV::CPUModel Model{static_cast<uint32_t>(Query[0].Value), Query[1].Value,
1850 Query[2].Value};
1852 if (!Name.empty())
1853 return Name;
1854 }
1855
1856 // Then try the cpuinfo way.
1857 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1858 StringRef Content = P ? P->getBuffer() : "";
1860 if (!Name.empty())
1861 return Name;
1862#endif
1863#if __riscv_xlen == 64
1864 return "generic-rv64";
1865#elif __riscv_xlen == 32
1866 return "generic-rv32";
1867#else
1868#error "Unhandled value of __riscv_xlen"
1869#endif
1870}
1871#elif defined(__sparc__)
1872#if defined(__linux__)
1875 ProcCpuinfoContent.split(Lines, '\n');
1876
1877 // Look for cpu line to determine cpu name
1878 StringRef Cpu;
1879 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
1880 if (Lines[I].starts_with("cpu")) {
1881 Cpu = Lines[I].substr(5).ltrim("\t :");
1882 break;
1883 }
1884 }
1885
1886 return StringSwitch<const char *>(Cpu)
1887 .StartsWith("SuperSparc", "supersparc")
1888 .StartsWith("HyperSparc", "hypersparc")
1889 .StartsWith("SpitFire", "ultrasparc")
1890 .StartsWith("BlackBird", "ultrasparc")
1891 .StartsWith("Sabre", " ultrasparc")
1892 .StartsWith("Hummingbird", "ultrasparc")
1893 .StartsWith("Cheetah", "ultrasparc3")
1894 .StartsWith("Jalapeno", "ultrasparc3")
1895 .StartsWith("Jaguar", "ultrasparc3")
1896 .StartsWith("Panther", "ultrasparc3")
1897 .StartsWith("Serrano", "ultrasparc3")
1898 .StartsWith("UltraSparc T1", "niagara")
1899 .StartsWith("UltraSparc T2", "niagara2")
1900 .StartsWith("UltraSparc T3", "niagara3")
1901 .StartsWith("UltraSparc T4", "niagara4")
1902 .StartsWith("UltraSparc T5", "niagara4")
1903 .StartsWith("LEON", "leon3")
1904 // niagara7/m8 not supported by LLVM yet.
1905 .StartsWith("SPARC-M7", "niagara4" /* "niagara7" */)
1906 .StartsWith("SPARC-S7", "niagara4" /* "niagara7" */)
1907 .StartsWith("SPARC-M8", "niagara4" /* "m8" */)
1908 .Default("generic");
1909}
1910#endif
1911
1913#if defined(__linux__)
1914 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1915 StringRef Content = P ? P->getBuffer() : "";
1916 return detail::getHostCPUNameForSPARC(Content);
1917#elif defined(__sun__) && defined(__svr4__)
1918 char *buf = NULL;
1919 kstat_ctl_t *kc;
1920 kstat_t *ksp;
1921 kstat_named_t *brand = NULL;
1922
1923 kc = kstat_open();
1924 if (kc != NULL) {
1925 ksp = kstat_lookup(kc, const_cast<char *>("cpu_info"), -1, NULL);
1926 if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1 &&
1927 ksp->ks_type == KSTAT_TYPE_NAMED)
1928 brand =
1929 (kstat_named_t *)kstat_data_lookup(ksp, const_cast<char *>("brand"));
1930 if (brand != NULL && brand->data_type == KSTAT_DATA_STRING)
1931 buf = KSTAT_NAMED_STR_PTR(brand);
1932 }
1933 kstat_close(kc);
1934
1935 return StringSwitch<const char *>(buf)
1936 .Case("TMS390S10", "supersparc") // Texas Instruments microSPARC I
1937 .Case("TMS390Z50", "supersparc") // Texas Instruments SuperSPARC I
1938 .Case("TMS390Z55",
1939 "supersparc") // Texas Instruments SuperSPARC I with SuperCache
1940 .Case("MB86904", "supersparc") // Fujitsu microSPARC II
1941 .Case("MB86907", "supersparc") // Fujitsu TurboSPARC
1942 .Case("RT623", "hypersparc") // Ross hyperSPARC
1943 .Case("RT625", "hypersparc")
1944 .Case("RT626", "hypersparc")
1945 .Case("UltraSPARC-I", "ultrasparc")
1946 .Case("UltraSPARC-II", "ultrasparc")
1947 .Case("UltraSPARC-IIe", "ultrasparc")
1948 .Case("UltraSPARC-IIi", "ultrasparc")
1949 .Case("SPARC64-III", "ultrasparc")
1950 .Case("SPARC64-IV", "ultrasparc")
1951 .Case("UltraSPARC-III", "ultrasparc3")
1952 .Case("UltraSPARC-III+", "ultrasparc3")
1953 .Case("UltraSPARC-IIIi", "ultrasparc3")
1954 .Case("UltraSPARC-IIIi+", "ultrasparc3")
1955 .Case("UltraSPARC-IV", "ultrasparc3")
1956 .Case("UltraSPARC-IV+", "ultrasparc3")
1957 .Case("SPARC64-V", "ultrasparc3")
1958 .Case("SPARC64-VI", "ultrasparc3")
1959 .Case("SPARC64-VII", "ultrasparc3")
1960 .Case("UltraSPARC-T1", "niagara")
1961 .Case("UltraSPARC-T2", "niagara2")
1962 .Case("UltraSPARC-T2", "niagara2")
1963 .Case("UltraSPARC-T2+", "niagara2")
1964 .Case("SPARC-T3", "niagara3")
1965 .Case("SPARC-T4", "niagara4")
1966 .Case("SPARC-T5", "niagara4")
1967 // niagara7/m8 not supported by LLVM yet.
1968 .Case("SPARC-M7", "niagara4" /* "niagara7" */)
1969 .Case("SPARC-S7", "niagara4" /* "niagara7" */)
1970 .Case("SPARC-M8", "niagara4" /* "m8" */)
1971 .Default("generic");
1972#else
1973 return "generic";
1974#endif
1975}
1976#else
1977StringRef sys::getHostCPUName() { return "generic"; }
1978namespace llvm {
1979namespace sys {
1980namespace detail {
1981namespace x86 {
1982
1985}
1986
1987} // namespace x86
1988} // namespace detail
1989} // namespace sys
1990} // namespace llvm
1991#endif
1992
1993#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
1994 defined(_M_X64)) && \
1995 !defined(_M_ARM64EC)
1997 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1998 unsigned MaxLevel;
1999 StringMap<bool> Features;
2000
2001 if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1)
2002 return Features;
2003
2004 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
2005
2006 Features["cx8"] = (EDX >> 8) & 1;
2007 Features["cmov"] = (EDX >> 15) & 1;
2008 Features["mmx"] = (EDX >> 23) & 1;
2009 Features["fxsr"] = (EDX >> 24) & 1;
2010 Features["sse"] = (EDX >> 25) & 1;
2011 Features["sse2"] = (EDX >> 26) & 1;
2012
2013 Features["sse3"] = (ECX >> 0) & 1;
2014 Features["pclmul"] = (ECX >> 1) & 1;
2015 Features["ssse3"] = (ECX >> 9) & 1;
2016 Features["cx16"] = (ECX >> 13) & 1;
2017 Features["sse4.1"] = (ECX >> 19) & 1;
2018 Features["sse4.2"] = (ECX >> 20) & 1;
2019 Features["crc32"] = Features["sse4.2"];
2020 Features["movbe"] = (ECX >> 22) & 1;
2021 Features["popcnt"] = (ECX >> 23) & 1;
2022 Features["aes"] = (ECX >> 25) & 1;
2023 Features["rdrnd"] = (ECX >> 30) & 1;
2024
2025 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
2026 // indicates that the AVX registers will be saved and restored on context
2027 // switch, then we have full AVX support.
2028 bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX);
2029 bool HasAVXSave = HasXSave && ((ECX >> 28) & 1) && ((EAX & 0x6) == 0x6);
2030#if defined(__APPLE__)
2031 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
2032 // save the AVX512 context if we use AVX512 instructions, even the bit is not
2033 // set right now.
2034 bool HasAVX512Save = true;
2035#else
2036 // AVX512 requires additional context to be saved by the OS.
2037 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
2038#endif
2039 // AMX requires additional context to be saved by the OS.
2040 const unsigned AMXBits = (1 << 17) | (1 << 18);
2041 bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits);
2042
2043 Features["avx"] = HasAVXSave;
2044 Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave;
2045 // Only enable XSAVE if OS has enabled support for saving YMM state.
2046 Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave;
2047 Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave;
2048
2049 unsigned MaxExtLevel;
2050 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
2051
2052 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
2053 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
2054 Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1);
2055 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
2056 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
2057 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
2058 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
2059 Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
2060 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
2061 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
2062 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
2063
2064 Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1);
2065
2066 // Miscellaneous memory related features, detected by
2067 // using the 0x80000008 leaf of the CPUID instruction
2068 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
2069 !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
2070 Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1);
2071 Features["rdpru"] = HasExtLeaf8 && ((EBX >> 4) & 1);
2072 Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1);
2073
2074 bool HasExtLeaf21 = MaxExtLevel >= 0x80000021 &&
2075 !getX86CpuIDAndInfo(0x80000021, &EAX, &EBX, &ECX, &EDX);
2076 // AMD cpuid bit for prefetchi is different from Intel
2077 Features["prefetchi"] = HasExtLeaf21 && ((EAX >> 20) & 1);
2078
2079 bool HasLeaf7 =
2080 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
2081
2082 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
2083 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
2084 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
2085 // AVX2 is only supported if we have the OS save support from AVX.
2086 Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave;
2087 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
2088 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
2089 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
2090 // AVX512 is only supported if the OS supports the context save for it.
2091 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
2092 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
2093 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
2094 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
2095 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
2096 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
2097 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
2098 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
2099 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
2100 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
2101 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
2102
2103 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
2104 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
2105 Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1);
2106 Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save;
2107 Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1);
2108 Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1);
2109 Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave;
2110 Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave;
2111 Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save;
2112 Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
2113 Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
2114 Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1);
2115 Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker
2116 Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1);
2117 Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
2118 Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
2119 Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1);
2120
2121 Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1);
2122 Features["avx512vp2intersect"] =
2123 HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save;
2124 Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1);
2125 Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1);
2126 // There are two CPUID leafs which information associated with the pconfig
2127 // instruction:
2128 // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
2129 // bit of EDX), while the EAX=0x1b leaf returns information on the
2130 // availability of specific pconfig leafs.
2131 // The target feature here only refers to the the first of these two.
2132 // Users might need to check for the availability of specific pconfig
2133 // leaves using cpuid, since that information is ignored while
2134 // detecting features using the "-march=native" flag.
2135 // For more info, see X86 ISA docs.
2136 Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1);
2137 Features["amx-bf16"] = HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave;
2138 Features["avx512fp16"] = HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save;
2139 Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave;
2140 Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave;
2141 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
2142 // return all 0s for invalid subleaves so check the limit.
2143 bool HasLeaf7Subleaf1 =
2144 HasLeaf7 && EAX >= 1 &&
2145 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
2146 Features["sha512"] = HasLeaf7Subleaf1 && ((EAX >> 0) & 1);
2147 Features["sm3"] = HasLeaf7Subleaf1 && ((EAX >> 1) & 1);
2148 Features["sm4"] = HasLeaf7Subleaf1 && ((EAX >> 2) & 1);
2149 Features["raoint"] = HasLeaf7Subleaf1 && ((EAX >> 3) & 1);
2150 Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
2151 Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save;
2152 Features["amx-fp16"] = HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave;
2153 Features["cmpccxadd"] = HasLeaf7Subleaf1 && ((EAX >> 7) & 1);
2154 Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
2155 Features["avxifma"] = HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave;
2156 Features["movrs"] = HasLeaf7Subleaf1 && ((EAX >> 31) & 1);
2157 Features["avxvnniint8"] = HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave;
2158 Features["avxneconvert"] = HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave;
2159 Features["amx-complex"] = HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave;
2160 Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave;
2161 Features["prefetchi"] |= HasLeaf7Subleaf1 && ((EDX >> 14) & 1);
2162 Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1);
2163 bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1);
2164 bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1);
2165 Features["egpr"] = HasAPXF;
2166 Features["push2pop2"] = HasAPXF;
2167 Features["ppx"] = HasAPXF;
2168 Features["ndd"] = HasAPXF;
2169 Features["ccmp"] = HasAPXF;
2170 Features["nf"] = HasAPXF;
2171 Features["cf"] = HasAPXF;
2172 Features["zu"] = HasAPXF;
2173
2174 bool HasLeafD = MaxLevel >= 0xd &&
2175 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
2176
2177 // Only enable XSAVE if OS has enabled support for saving YMM state.
2178 Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave;
2179 Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave;
2180 Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave;
2181
2182 bool HasLeaf14 = MaxLevel >= 0x14 &&
2183 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
2184
2185 Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1);
2186
2187 bool HasLeaf19 =
2188 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
2189 Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1);
2190
2191 bool HasLeaf1E = MaxLevel >= 0x1e &&
2192 !getX86CpuIDAndInfoEx(0x1e, 0x1, &EAX, &EBX, &ECX, &EDX);
2193 Features["amx-fp8"] = HasLeaf1E && ((EAX >> 4) & 1) && HasAMXSave;
2194 Features["amx-transpose"] = HasLeaf1E && ((EAX >> 5) & 1) && HasAMXSave;
2195 Features["amx-tf32"] = HasLeaf1E && ((EAX >> 6) & 1) && HasAMXSave;
2196 Features["amx-avx512"] = HasLeaf1E && ((EAX >> 7) & 1) && HasAMXSave;
2197 Features["amx-movrs"] = HasLeaf1E && ((EAX >> 8) & 1) && HasAMXSave;
2198
2199 bool HasLeaf24 =
2200 MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX);
2201
2202 int AVX10Ver = HasLeaf24 && (EBX & 0xff);
2203 Features["avx10.1"] = HasAVX10 && AVX10Ver >= 1;
2204 Features["avx10.2"] = HasAVX10 && AVX10Ver >= 2;
2205
2206 return Features;
2207}
2208#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
2210 StringMap<bool> Features;
2211 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
2212 if (!P)
2213 return Features;
2214
2216 P->getBuffer().split(Lines, '\n');
2217
2218 SmallVector<StringRef, 32> CPUFeatures;
2219
2220 // Look for the CPU features.
2221 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
2222 if (Lines[I].starts_with("Features")) {
2223 Lines[I].split(CPUFeatures, ' ');
2224 break;
2225 }
2226
2227#if defined(__aarch64__)
2228 // All of these are "crypto" features, but we must sift out actual features
2229 // as the former meaning of "crypto" as a single feature is no more.
2230 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
2231 uint32_t crypto = 0;
2232#endif
2233
2234 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
2235 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
2236#if defined(__aarch64__)
2237 .Case("asimd", "neon")
2238 .Case("fp", "fp-armv8")
2239 .Case("crc32", "crc")
2240 .Case("atomics", "lse")
2241 .Case("sha3", "sha3")
2242 .Case("sm4", "sm4")
2243 .Case("sve", "sve")
2244 .Case("sve2", "sve2")
2245 .Case("sveaes", "sve-aes")
2246 .Case("svesha3", "sve-sha3")
2247 .Case("svesm4", "sve-sm4")
2248#else
2249 .Case("half", "fp16")
2250 .Case("neon", "neon")
2251 .Case("vfpv3", "vfp3")
2252 .Case("vfpv3d16", "vfp3d16")
2253 .Case("vfpv4", "vfp4")
2254 .Case("idiva", "hwdiv-arm")
2255 .Case("idivt", "hwdiv")
2256#endif
2257 .Default("");
2258
2259#if defined(__aarch64__)
2260 // We need to check crypto separately since we need all of the crypto
2261 // extensions to enable the subtarget feature
2262 if (CPUFeatures[I] == "aes")
2263 crypto |= CAP_AES;
2264 else if (CPUFeatures[I] == "pmull")
2265 crypto |= CAP_PMULL;
2266 else if (CPUFeatures[I] == "sha1")
2267 crypto |= CAP_SHA1;
2268 else if (CPUFeatures[I] == "sha2")
2269 crypto |= CAP_SHA2;
2270#endif
2271
2272 if (LLVMFeatureStr != "")
2273 Features[LLVMFeatureStr] = true;
2274 }
2275
2276#if defined(__aarch64__)
2277 // LLVM has decided some AArch64 CPUs have all the instructions they _may_
2278 // have, as opposed to all the instructions they _must_ have, so allow runtime
2279 // information to correct us on that.
2280 uint32_t Aes = CAP_AES | CAP_PMULL;
2281 uint32_t Sha2 = CAP_SHA1 | CAP_SHA2;
2282 Features["aes"] = (crypto & Aes) == Aes;
2283 Features["sha2"] = (crypto & Sha2) == Sha2;
2284#endif
2285
2286 return Features;
2287}
2288#elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64) || \
2289 defined(__arm64ec__) || defined(_M_ARM64EC))
2291 StringMap<bool> Features;
2292
2293 // If we're asking the OS at runtime, believe what the OS says
2294 Features["neon"] =
2295 IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE);
2296 Features["crc"] =
2297 IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
2298
2299 // Avoid inferring "crypto" means more than the traditional AES + SHA2
2300 bool TradCrypto =
2301 IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE);
2302 Features["aes"] = TradCrypto;
2303 Features["sha2"] = TradCrypto;
2304
2305 return Features;
2306}
2307#elif defined(__linux__) && defined(__loongarch__)
2308#include <sys/auxv.h>
2310 unsigned long hwcap = getauxval(AT_HWCAP);
2311 bool HasFPU = hwcap & (1UL << 3); // HWCAP_LOONGARCH_FPU
2312 uint32_t cpucfg2 = 0x2, cpucfg3 = 0x3;
2313 __asm__("cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2] "+r"(cpucfg2));
2314 __asm__("cpucfg %[cpucfg3], %[cpucfg3]\n\t" : [cpucfg3] "+r"(cpucfg3));
2315
2316 StringMap<bool> Features;
2317
2318 Features["f"] = HasFPU && (cpucfg2 & (1U << 1)); // CPUCFG.2.FP_SP
2319 Features["d"] = HasFPU && (cpucfg2 & (1U << 2)); // CPUCFG.2.FP_DP
2320
2321 Features["lsx"] = hwcap & (1UL << 4); // HWCAP_LOONGARCH_LSX
2322 Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX
2323 Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ
2324
2325 Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE
2326 Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32
2327 Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH
2328 Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS
2329 Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ
2330
2331 Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA
2332
2333 // TODO: Need to complete.
2334 // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL
2335 return Features;
2336}
2337#elif defined(__linux__) && defined(__riscv)
2339 RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
2340 {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0},
2341 {/*RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF=*/9, 0}};
2342 int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
2343 /*pair_count=*/std::size(Query), /*cpu_count=*/0,
2344 /*cpus=*/0, /*flags=*/0);
2345 if (Ret != 0)
2346 return {};
2347
2348 StringMap<bool> Features;
2349 uint64_t BaseMask = Query[0].Value;
2350 // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set.
2351 if (BaseMask & 1) {
2352 Features["i"] = true;
2353 Features["m"] = true;
2354 Features["a"] = true;
2355 }
2356
2357 uint64_t ExtMask = Query[1].Value;
2358 Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
2359 Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
2360 Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C
2361 Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V
2362 Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA
2363 Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB
2364 Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS
2365 Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ
2366 Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC
2367 Features["zbkb"] = ExtMask & (1 << 8); // RISCV_HWPROBE_EXT_ZBKB
2368 Features["zbkc"] = ExtMask & (1 << 9); // RISCV_HWPROBE_EXT_ZBKC
2369 Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX
2370 Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND
2371 Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE
2372 Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH
2373 Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED
2374 Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH
2375 Features["zkt"] = ExtMask & (1 << 16); // RISCV_HWPROBE_EXT_ZKT
2376 Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB
2377 Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC
2378 Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB
2379 Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG
2380 Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED
2381 Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA
2382 Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB
2383 Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED
2384 Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH
2385 Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT
2386 Features["zfh"] = ExtMask & (1 << 27); // RISCV_HWPROBE_EXT_ZFH
2387 Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN
2388 Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL
2389 Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH
2390 Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
2391 Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA
2392 Features["ztso"] = ExtMask & (1ULL << 33); // RISCV_HWPROBE_EXT_ZTSO
2393 Features["zacas"] = ExtMask & (1ULL << 34); // RISCV_HWPROBE_EXT_ZACAS
2394 Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
2395 Features["zihintpause"] =
2396 ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
2397 Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X
2398 Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F
2399 Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X
2400 Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F
2401 Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D
2402 Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP
2403 Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA
2404 Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB
2405 Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD
2406 Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF
2407 Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP
2408 Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS
2409
2410 // Check whether the processor supports fast misaligned scalar memory access.
2411 // NOTE: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF is only available on
2412 // Linux 6.11 or later. If it is not recognized, the key field will be cleared
2413 // to -1.
2414 if (Query[2].Key != -1 &&
2415 Query[2].Value == /*RISCV_HWPROBE_MISALIGNED_SCALAR_FAST=*/3)
2416 Features["unaligned-scalar-mem"] = true;
2417
2418 return Features;
2419}
2420#else
2422#endif
2423
2424#if __APPLE__
2425/// \returns the \p triple, but with the Host's arch spliced in.
2426static Triple withHostArch(Triple T) {
2427#if defined(__arm__)
2428 T.setArch(Triple::arm);
2429 T.setArchName("arm");
2430#elif defined(__arm64e__)
2432 T.setArchName("arm64e");
2433#elif defined(__aarch64__)
2434 T.setArch(Triple::aarch64);
2435 T.setArchName("arm64");
2436#elif defined(__x86_64h__)
2437 T.setArch(Triple::x86_64);
2438 T.setArchName("x86_64h");
2439#elif defined(__x86_64__)
2440 T.setArch(Triple::x86_64);
2441 T.setArchName("x86_64");
2442#elif defined(__i386__)
2443 T.setArch(Triple::x86);
2444 T.setArchName("i386");
2445#elif defined(__powerpc__)
2446 T.setArch(Triple::ppc);
2447 T.setArchName("powerpc");
2448#else
2449# error "Unimplemented host arch fixup"
2450#endif
2451 return T;
2452}
2453#endif
2454
2456 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
2457 Triple PT(Triple::normalize(TargetTripleString));
2458
2459#if __APPLE__
2460 /// In Universal builds, LLVM_HOST_TRIPLE will have the wrong arch in one of
2461 /// the slices. This fixes that up.
2462 PT = withHostArch(PT);
2463#endif
2464
2465 if (sizeof(void *) == 8 && PT.isArch32Bit())
2466 PT = PT.get64BitArchVariant();
2467 if (sizeof(void *) == 4 && PT.isArch64Bit())
2468 PT = PT.get32BitArchVariant();
2469
2470 return PT.str();
2471}
2472
2474#if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
2475 std::string CPU = std::string(sys::getHostCPUName());
2476 if (CPU == "generic")
2477 CPU = "(unknown)";
2478 OS << " Default target: " << sys::getDefaultTargetTriple() << '\n'
2479 << " Host CPU: " << CPU << '\n';
2480#endif
2481}
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: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:702
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:472
iterator begin() const
Definition StringRef.h:112
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:792
iterator end() const
Definition StringRef.h:114
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:273
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:1801
LLVM_ABI llvm::Triple get64BitArchVariant() const
Form a triple with a 64-bit variant of the current architecture.
Definition Triple.cpp:1884
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:1170
const std::string & str() const
Definition Triple.h:479
LLVM_ABI bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition Triple.cpp:1789
@ AArch64SubArch_arm64e
Definition Triple.h:153
LLVM_ABI bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition Triple.cpp:1793
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:1983
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:2421
LLVM_ABI StringRef getHostCPUName()
getHostCPUName - Get the LLVM name for the host CPU.
Definition Host.cpp:1977
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:2473
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:2455
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:2076
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1622
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:1897
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