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 setFeature(X86::FEATURE_EVEX512);
1400 }
1401 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
1402 setFeature(X86::FEATURE_AVX512DQ);
1403 if (HasLeaf7 && ((EBX >> 19) & 1))
1404 setFeature(X86::FEATURE_ADX);
1405 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
1406 setFeature(X86::FEATURE_AVX512IFMA);
1407 if (HasLeaf7 && ((EBX >> 23) & 1))
1408 setFeature(X86::FEATURE_CLFLUSHOPT);
1409 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
1410 setFeature(X86::FEATURE_AVX512CD);
1411 if (HasLeaf7 && ((EBX >> 29) & 1))
1412 setFeature(X86::FEATURE_SHA);
1413 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
1414 setFeature(X86::FEATURE_AVX512BW);
1415 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
1416 setFeature(X86::FEATURE_AVX512VL);
1417
1418 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
1419 setFeature(X86::FEATURE_AVX512VBMI);
1420 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
1421 setFeature(X86::FEATURE_AVX512VBMI2);
1422 if (HasLeaf7 && ((ECX >> 8) & 1))
1423 setFeature(X86::FEATURE_GFNI);
1424 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
1425 setFeature(X86::FEATURE_VPCLMULQDQ);
1426 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
1427 setFeature(X86::FEATURE_AVX512VNNI);
1428 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
1429 setFeature(X86::FEATURE_AVX512BITALG);
1430 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
1431 setFeature(X86::FEATURE_AVX512VPOPCNTDQ);
1432
1433 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
1434 setFeature(X86::FEATURE_AVX5124VNNIW);
1435 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
1436 setFeature(X86::FEATURE_AVX5124FMAPS);
1437 if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
1438 setFeature(X86::FEATURE_AVX512VP2INTERSECT);
1439
1440 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1441 // return all 0s for invalid subleaves so check the limit.
1442 bool HasLeaf7Subleaf1 =
1443 HasLeaf7 && EAX >= 1 &&
1444 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1445 if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
1446 setFeature(X86::FEATURE_AVX512BF16);
1447
1448 unsigned MaxExtLevel;
1449 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1450
1451 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1452 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1453 if (HasExtLeaf1 && ((ECX >> 6) & 1))
1454 setFeature(X86::FEATURE_SSE4_A);
1455 if (HasExtLeaf1 && ((ECX >> 11) & 1))
1456 setFeature(X86::FEATURE_XOP);
1457 if (HasExtLeaf1 && ((ECX >> 16) & 1))
1458 setFeature(X86::FEATURE_FMA4);
1459
1460 if (HasExtLeaf1 && ((EDX >> 29) & 1))
1461 setFeature(X86::FEATURE_64BIT);
1462}
1463
1465 unsigned MaxLeaf = 0;
1466 const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
1467 if (Vendor == VendorSignatures::UNKNOWN)
1468 return "generic";
1469
1470 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1471 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
1472
1473 unsigned Family = 0, Model = 0;
1474 unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0};
1475 detectX86FamilyModel(EAX, &Family, &Model);
1476 getAvailableFeatures(ECX, EDX, MaxLeaf, Features);
1477
1478 // These aren't consumed in this file, but we try to keep some source code the
1479 // same or similar to compiler-rt.
1480 unsigned Type = 0;
1481 unsigned Subtype = 0;
1482
1483 StringRef CPU;
1484
1485 if (Vendor == VendorSignatures::GENUINE_INTEL) {
1486 CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
1487 &Subtype);
1488 } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
1489 CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
1490 &Subtype);
1491 }
1492
1493 if (!CPU.empty())
1494 return CPU;
1495
1496 return "generic";
1497}
1498
1499#elif defined(_M_ARM64) || defined(_M_ARM64EC)
1500
1502 constexpr char CentralProcessorKeyName[] =
1503 "HARDWARE\\DESCRIPTION\\System\\CentralProcessor";
1504 // Sub keys names are simple numbers ("0", "1", etc.) so 10 chars should be
1505 // enough for the slash and name.
1506 constexpr size_t SubKeyNameMaxSize = ARRAYSIZE(CentralProcessorKeyName) + 10;
1507
1508 SmallVector<uint64_t> Values;
1509 uint64_t PrimaryCpuInfo;
1510 char PrimaryPartKeyName[SubKeyNameMaxSize];
1511 DWORD PrimaryPartKeyNameSize = 0;
1512 HKEY CentralProcessorKey;
1513 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, CentralProcessorKeyName, 0, KEY_READ,
1514 &CentralProcessorKey) == ERROR_SUCCESS) {
1515 for (unsigned Index = 0; Index < UINT32_MAX; ++Index) {
1516 char SubKeyName[SubKeyNameMaxSize];
1517 DWORD SubKeySize = SubKeyNameMaxSize;
1518 HKEY SubKey;
1519 if ((RegEnumKeyExA(CentralProcessorKey, Index, SubKeyName, &SubKeySize,
1520 nullptr, nullptr, nullptr,
1521 nullptr) == ERROR_SUCCESS) &&
1522 (RegOpenKeyExA(CentralProcessorKey, SubKeyName, 0, KEY_READ,
1523 &SubKey) == ERROR_SUCCESS)) {
1524 // The "CP 4000" registry key contains a cached copy of the MIDR_EL1
1525 // register.
1526 uint64_t RegValue;
1527 DWORD ActualType;
1528 DWORD RegValueSize = sizeof(RegValue);
1529 if ((RegQueryValueExA(SubKey, "CP 4000", nullptr, &ActualType,
1530 (PBYTE)&RegValue,
1531 &RegValueSize) == ERROR_SUCCESS) &&
1532 (ActualType == REG_QWORD) && RegValueSize == sizeof(RegValue)) {
1533 // Assume that the part with the "highest" reg key name is the primary
1534 // part (to match the way that Linux's cpuinfo is written). Win32
1535 // makes no guarantees about the order of sub keys, so we have to
1536 // compare the names.
1537 if (PrimaryPartKeyNameSize < SubKeySize ||
1538 (PrimaryPartKeyNameSize == SubKeySize &&
1539 ::memcmp(SubKeyName, PrimaryPartKeyName, SubKeySize) > 0)) {
1540 PrimaryCpuInfo = RegValue;
1541 ::memcpy(PrimaryPartKeyName, SubKeyName, SubKeySize + 1);
1542 PrimaryPartKeyNameSize = SubKeySize;
1543 }
1544 if (!llvm::is_contained(Values, RegValue)) {
1545 Values.push_back(RegValue);
1546 }
1547 }
1548 RegCloseKey(SubKey);
1549 } else {
1550 // No more sub keys.
1551 break;
1552 }
1553 }
1554 RegCloseKey(CentralProcessorKey);
1555 }
1556
1557 if (Values.empty()) {
1558 return "generic";
1559 }
1560
1561 // Win32 makes no guarantees about the order of sub keys, so sort to ensure
1562 // reproducibility.
1563 llvm::sort(Values);
1564
1565 return detail::getHostCPUNameForARM(PrimaryCpuInfo, Values);
1566}
1567
1568#elif defined(__APPLE__) && defined(__powerpc__)
1570 host_basic_info_data_t hostInfo;
1571 mach_msg_type_number_t infoCount;
1572
1573 infoCount = HOST_BASIC_INFO_COUNT;
1574 mach_port_t hostPort = mach_host_self();
1575 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1576 &infoCount);
1577 mach_port_deallocate(mach_task_self(), hostPort);
1578
1579 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
1580 return "generic";
1581
1582 switch (hostInfo.cpu_subtype) {
1584 return "601";
1586 return "602";
1588 return "603";
1590 return "603e";
1592 return "603ev";
1594 return "604";
1596 return "604e";
1598 return "620";
1600 return "750";
1602 return "7400";
1604 return "7450";
1606 return "970";
1607 default:;
1608 }
1609
1610 return "generic";
1611}
1612#elif defined(__linux__) && defined(__powerpc__)
1614 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1615 StringRef Content = P ? P->getBuffer() : "";
1616 return detail::getHostCPUNameForPowerPC(Content);
1617}
1618#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1620 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1621 StringRef Content = P ? P->getBuffer() : "";
1622 return detail::getHostCPUNameForARM(Content);
1623}
1624#elif defined(__linux__) && defined(__s390x__)
1626 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1627 StringRef Content = P ? P->getBuffer() : "";
1628 return detail::getHostCPUNameForS390x(Content);
1629}
1630#elif defined(__MVS__)
1632 // Get pointer to Communications Vector Table (CVT).
1633 // The pointer is located at offset 16 of the Prefixed Save Area (PSA).
1634 // It is stored as 31 bit pointer and will be zero-extended to 64 bit.
1635 int *StartToCVTOffset = reinterpret_cast<int *>(0x10);
1636 // Since its stored as a 31-bit pointer, get the 4 bytes from the start
1637 // of address.
1638 int ReadValue = *StartToCVTOffset;
1639 // Explicitly clear the high order bit.
1640 ReadValue = (ReadValue & 0x7FFFFFFF);
1641 char *CVT = reinterpret_cast<char *>(ReadValue);
1642 // The model number is located in the CVT prefix at offset -6 and stored as
1643 // signless packed decimal.
1644 uint16_t Id = *(uint16_t *)&CVT[-6];
1645 // Convert number to integer.
1646 Id = decodePackedBCD<uint16_t>(Id, false);
1647 // Check for vector support. It's stored in field CVTFLAG5 (offset 244),
1648 // bit CVTVEF (X'80'). The facilities list is part of the PSA but the vector
1649 // extension can only be used if bit CVTVEF is on.
1650 bool HaveVectorSupport = CVT[244] & 0x80;
1651 return getCPUNameFromS390Model(Id, HaveVectorSupport);
1652}
1653#elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__))
1654// Copied from <mach/machine.h> in the macOS SDK.
1655//
1656// Also available here, though usually not as up-to-date:
1657// https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/mach/machine.h#L403-L452.
1658#define CPUFAMILY_UNKNOWN 0
1659#define CPUFAMILY_ARM_9 0xe73283ae
1660#define CPUFAMILY_ARM_11 0x8ff620d8
1661#define CPUFAMILY_ARM_XSCALE 0x53b005f5
1662#define CPUFAMILY_ARM_12 0xbd1b0ae9
1663#define CPUFAMILY_ARM_13 0x0cc90e64
1664#define CPUFAMILY_ARM_14 0x96077ef1
1665#define CPUFAMILY_ARM_15 0xa8511bca
1666#define CPUFAMILY_ARM_SWIFT 0x1e2d6381
1667#define CPUFAMILY_ARM_CYCLONE 0x37a09642
1668#define CPUFAMILY_ARM_TYPHOON 0x2c91a47e
1669#define CPUFAMILY_ARM_TWISTER 0x92fb37c8
1670#define CPUFAMILY_ARM_HURRICANE 0x67ceee93
1671#define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6
1672#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f
1673#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2
1674#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3
1675#define CPUFAMILY_ARM_BLIZZARD_AVALANCHE 0xda33d83d
1676#define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea
1677#define CPUFAMILY_ARM_IBIZA 0xfa33415e
1678#define CPUFAMILY_ARM_PALMA 0x72015832
1679#define CPUFAMILY_ARM_COLL 0x2876f5b5
1680#define CPUFAMILY_ARM_LOBOS 0x5f4dea93
1681#define CPUFAMILY_ARM_DONAN 0x6f5129ac
1682#define CPUFAMILY_ARM_BRAVA 0x17d5b93a
1683#define CPUFAMILY_ARM_TAHITI 0x75d4acb9
1684#define CPUFAMILY_ARM_TUPAI 0x204526d0
1685
1687 uint32_t Family;
1688 size_t Length = sizeof(Family);
1689 sysctlbyname("hw.cpufamily", &Family, &Length, NULL, 0);
1690
1691 // This is found by testing on actual hardware, and by looking at:
1692 // https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/arm/cpuid.c#L109-L231.
1693 //
1694 // Another great resource is
1695 // https://github.com/AsahiLinux/docs/wiki/Codenames.
1696 //
1697 // NOTE: We choose to return `apple-mX` instead of `apple-aX`, since the M1,
1698 // M2, M3 etc. aliases are more widely known to users than A14, A15, A16 etc.
1699 // (and this code is basically only used on host macOS anyways).
1700 switch (Family) {
1701 case CPUFAMILY_UNKNOWN:
1702 return "generic";
1703 case CPUFAMILY_ARM_9:
1704 return "arm920t"; // or arm926ej-s
1705 case CPUFAMILY_ARM_11:
1706 return "arm1136jf-s";
1707 case CPUFAMILY_ARM_XSCALE:
1708 return "xscale";
1709 case CPUFAMILY_ARM_12: // Seems unused by the kernel
1710 return "generic";
1711 case CPUFAMILY_ARM_13:
1712 return "cortex-a8";
1713 case CPUFAMILY_ARM_14:
1714 return "cortex-a9";
1715 case CPUFAMILY_ARM_15:
1716 return "cortex-a7";
1717 case CPUFAMILY_ARM_SWIFT:
1718 return "swift";
1719 case CPUFAMILY_ARM_CYCLONE:
1720 return "apple-a7";
1721 case CPUFAMILY_ARM_TYPHOON:
1722 return "apple-a8";
1723 case CPUFAMILY_ARM_TWISTER:
1724 return "apple-a9";
1725 case CPUFAMILY_ARM_HURRICANE:
1726 return "apple-a10";
1727 case CPUFAMILY_ARM_MONSOON_MISTRAL:
1728 return "apple-a11";
1729 case CPUFAMILY_ARM_VORTEX_TEMPEST:
1730 return "apple-a12";
1731 case CPUFAMILY_ARM_LIGHTNING_THUNDER:
1732 return "apple-a13";
1733 case CPUFAMILY_ARM_FIRESTORM_ICESTORM: // A14 / M1
1734 return "apple-m1";
1735 case CPUFAMILY_ARM_BLIZZARD_AVALANCHE: // A15 / M2
1736 return "apple-m2";
1737 case CPUFAMILY_ARM_EVEREST_SAWTOOTH: // A16
1738 case CPUFAMILY_ARM_IBIZA: // M3
1739 case CPUFAMILY_ARM_PALMA: // M3 Max
1740 case CPUFAMILY_ARM_LOBOS: // M3 Pro
1741 return "apple-m3";
1742 case CPUFAMILY_ARM_COLL: // A17 Pro
1743 return "apple-a17";
1744 case CPUFAMILY_ARM_DONAN: // M4
1745 case CPUFAMILY_ARM_BRAVA: // M4 Max
1746 case CPUFAMILY_ARM_TAHITI: // A18 Pro
1747 case CPUFAMILY_ARM_TUPAI: // A18
1748 return "apple-m4";
1749 default:
1750 // Default to the newest CPU we know about.
1751 return "apple-m4";
1752 }
1753}
1754#elif defined(_AIX)
1756 switch (_system_configuration.implementation) {
1757 case POWER_4:
1758 if (_system_configuration.version == PV_4_3)
1759 return "970";
1760 return "pwr4";
1761 case POWER_5:
1762 if (_system_configuration.version == PV_5)
1763 return "pwr5";
1764 return "pwr5x";
1765 case POWER_6:
1766 if (_system_configuration.version == PV_6_Compat)
1767 return "pwr6";
1768 return "pwr6x";
1769 case POWER_7:
1770 return "pwr7";
1771 case POWER_8:
1772 return "pwr8";
1773 case POWER_9:
1774 return "pwr9";
1775// TODO: simplify this once the macro is available in all OS levels.
1776#ifdef POWER_10
1777 case POWER_10:
1778#else
1779 case 0x40000:
1780#endif
1781 return "pwr10";
1782#ifdef POWER_11
1783 case POWER_11:
1784#else
1785 case 0x80000:
1786#endif
1787 return "pwr11";
1788 default:
1789 return "generic";
1790 }
1791}
1792#elif defined(__loongarch__)
1794 // Use processor id to detect cpu name.
1795 uint32_t processor_id;
1796 __asm__("cpucfg %[prid], $zero\n\t" : [prid] "=r"(processor_id));
1797 // Refer PRID_SERIES_MASK in linux kernel: arch/loongarch/include/asm/cpu.h.
1798 switch (processor_id & 0xf000) {
1799 case 0xc000: // Loongson 64bit, 4-issue
1800 return "la464";
1801 case 0xd000: // Loongson 64bit, 6-issue
1802 return "la664";
1803 // TODO: Others.
1804 default:
1805 break;
1806 }
1807 return "generic";
1808}
1809#elif defined(__riscv)
1810#if defined(__linux__)
1811// struct riscv_hwprobe
1812struct RISCVHwProbe {
1813 int64_t Key;
1815};
1816#endif
1817
1819#if defined(__linux__)
1820 // Try the hwprobe way first.
1821 RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_MVENDORID=*/0, 0},
1822 {/*RISCV_HWPROBE_KEY_MARCHID=*/1, 0},
1823 {/*RISCV_HWPROBE_KEY_MIMPID=*/2, 0}};
1824 int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
1825 /*pair_count=*/std::size(Query), /*cpu_count=*/0,
1826 /*cpus=*/0, /*flags=*/0);
1827 if (Ret == 0) {
1828 RISCV::CPUModel Model{static_cast<uint32_t>(Query[0].Value), Query[1].Value,
1829 Query[2].Value};
1831 if (!Name.empty())
1832 return Name;
1833 }
1834
1835 // Then try the cpuinfo way.
1836 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1837 StringRef Content = P ? P->getBuffer() : "";
1838 StringRef Name = detail::getHostCPUNameForRISCV(Content);
1839 if (!Name.empty())
1840 return Name;
1841#endif
1842#if __riscv_xlen == 64
1843 return "generic-rv64";
1844#elif __riscv_xlen == 32
1845 return "generic-rv32";
1846#else
1847#error "Unhandled value of __riscv_xlen"
1848#endif
1849}
1850#elif defined(__sparc__)
1851#if defined(__linux__)
1854 ProcCpuinfoContent.split(Lines, '\n');
1855
1856 // Look for cpu line to determine cpu name
1857 StringRef Cpu;
1858 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
1859 if (Lines[I].starts_with("cpu")) {
1860 Cpu = Lines[I].substr(5).ltrim("\t :");
1861 break;
1862 }
1863 }
1864
1865 return StringSwitch<const char *>(Cpu)
1866 .StartsWith("SuperSparc", "supersparc")
1867 .StartsWith("HyperSparc", "hypersparc")
1868 .StartsWith("SpitFire", "ultrasparc")
1869 .StartsWith("BlackBird", "ultrasparc")
1870 .StartsWith("Sabre", " ultrasparc")
1871 .StartsWith("Hummingbird", "ultrasparc")
1872 .StartsWith("Cheetah", "ultrasparc3")
1873 .StartsWith("Jalapeno", "ultrasparc3")
1874 .StartsWith("Jaguar", "ultrasparc3")
1875 .StartsWith("Panther", "ultrasparc3")
1876 .StartsWith("Serrano", "ultrasparc3")
1877 .StartsWith("UltraSparc T1", "niagara")
1878 .StartsWith("UltraSparc T2", "niagara2")
1879 .StartsWith("UltraSparc T3", "niagara3")
1880 .StartsWith("UltraSparc T4", "niagara4")
1881 .StartsWith("UltraSparc T5", "niagara4")
1882 .StartsWith("LEON", "leon3")
1883 // niagara7/m8 not supported by LLVM yet.
1884 .StartsWith("SPARC-M7", "niagara4" /* "niagara7" */)
1885 .StartsWith("SPARC-S7", "niagara4" /* "niagara7" */)
1886 .StartsWith("SPARC-M8", "niagara4" /* "m8" */)
1887 .Default("generic");
1888}
1889#endif
1890
1892#if defined(__linux__)
1893 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1894 StringRef Content = P ? P->getBuffer() : "";
1895 return detail::getHostCPUNameForSPARC(Content);
1896#elif defined(__sun__) && defined(__svr4__)
1897 char *buf = NULL;
1898 kstat_ctl_t *kc;
1899 kstat_t *ksp;
1900 kstat_named_t *brand = NULL;
1901
1902 kc = kstat_open();
1903 if (kc != NULL) {
1904 ksp = kstat_lookup(kc, const_cast<char *>("cpu_info"), -1, NULL);
1905 if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1 &&
1906 ksp->ks_type == KSTAT_TYPE_NAMED)
1907 brand =
1908 (kstat_named_t *)kstat_data_lookup(ksp, const_cast<char *>("brand"));
1909 if (brand != NULL && brand->data_type == KSTAT_DATA_STRING)
1910 buf = KSTAT_NAMED_STR_PTR(brand);
1911 }
1912 kstat_close(kc);
1913
1914 return StringSwitch<const char *>(buf)
1915 .Case("TMS390S10", "supersparc") // Texas Instruments microSPARC I
1916 .Case("TMS390Z50", "supersparc") // Texas Instruments SuperSPARC I
1917 .Case("TMS390Z55",
1918 "supersparc") // Texas Instruments SuperSPARC I with SuperCache
1919 .Case("MB86904", "supersparc") // Fujitsu microSPARC II
1920 .Case("MB86907", "supersparc") // Fujitsu TurboSPARC
1921 .Case("RT623", "hypersparc") // Ross hyperSPARC
1922 .Case("RT625", "hypersparc")
1923 .Case("RT626", "hypersparc")
1924 .Case("UltraSPARC-I", "ultrasparc")
1925 .Case("UltraSPARC-II", "ultrasparc")
1926 .Case("UltraSPARC-IIe", "ultrasparc")
1927 .Case("UltraSPARC-IIi", "ultrasparc")
1928 .Case("SPARC64-III", "ultrasparc")
1929 .Case("SPARC64-IV", "ultrasparc")
1930 .Case("UltraSPARC-III", "ultrasparc3")
1931 .Case("UltraSPARC-III+", "ultrasparc3")
1932 .Case("UltraSPARC-IIIi", "ultrasparc3")
1933 .Case("UltraSPARC-IIIi+", "ultrasparc3")
1934 .Case("UltraSPARC-IV", "ultrasparc3")
1935 .Case("UltraSPARC-IV+", "ultrasparc3")
1936 .Case("SPARC64-V", "ultrasparc3")
1937 .Case("SPARC64-VI", "ultrasparc3")
1938 .Case("SPARC64-VII", "ultrasparc3")
1939 .Case("UltraSPARC-T1", "niagara")
1940 .Case("UltraSPARC-T2", "niagara2")
1941 .Case("UltraSPARC-T2", "niagara2")
1942 .Case("UltraSPARC-T2+", "niagara2")
1943 .Case("SPARC-T3", "niagara3")
1944 .Case("SPARC-T4", "niagara4")
1945 .Case("SPARC-T5", "niagara4")
1946 // niagara7/m8 not supported by LLVM yet.
1947 .Case("SPARC-M7", "niagara4" /* "niagara7" */)
1948 .Case("SPARC-S7", "niagara4" /* "niagara7" */)
1949 .Case("SPARC-M8", "niagara4" /* "m8" */)
1950 .Default("generic");
1951#else
1952 return "generic";
1953#endif
1954}
1955#else
1956StringRef sys::getHostCPUName() { return "generic"; }
1957namespace llvm {
1958namespace sys {
1959namespace detail {
1960namespace x86 {
1961
1964}
1965
1966} // namespace x86
1967} // namespace detail
1968} // namespace sys
1969} // namespace llvm
1970#endif
1971
1972#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
1973 defined(_M_X64)) && \
1974 !defined(_M_ARM64EC)
1976 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1977 unsigned MaxLevel;
1978 StringMap<bool> Features;
1979
1980 if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1)
1981 return Features;
1982
1983 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1984
1985 Features["cx8"] = (EDX >> 8) & 1;
1986 Features["cmov"] = (EDX >> 15) & 1;
1987 Features["mmx"] = (EDX >> 23) & 1;
1988 Features["fxsr"] = (EDX >> 24) & 1;
1989 Features["sse"] = (EDX >> 25) & 1;
1990 Features["sse2"] = (EDX >> 26) & 1;
1991
1992 Features["sse3"] = (ECX >> 0) & 1;
1993 Features["pclmul"] = (ECX >> 1) & 1;
1994 Features["ssse3"] = (ECX >> 9) & 1;
1995 Features["cx16"] = (ECX >> 13) & 1;
1996 Features["sse4.1"] = (ECX >> 19) & 1;
1997 Features["sse4.2"] = (ECX >> 20) & 1;
1998 Features["crc32"] = Features["sse4.2"];
1999 Features["movbe"] = (ECX >> 22) & 1;
2000 Features["popcnt"] = (ECX >> 23) & 1;
2001 Features["aes"] = (ECX >> 25) & 1;
2002 Features["rdrnd"] = (ECX >> 30) & 1;
2003
2004 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
2005 // indicates that the AVX registers will be saved and restored on context
2006 // switch, then we have full AVX support.
2007 bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX);
2008 bool HasAVXSave = HasXSave && ((ECX >> 28) & 1) && ((EAX & 0x6) == 0x6);
2009#if defined(__APPLE__)
2010 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
2011 // save the AVX512 context if we use AVX512 instructions, even the bit is not
2012 // set right now.
2013 bool HasAVX512Save = true;
2014#else
2015 // AVX512 requires additional context to be saved by the OS.
2016 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
2017#endif
2018 // AMX requires additional context to be saved by the OS.
2019 const unsigned AMXBits = (1 << 17) | (1 << 18);
2020 bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits);
2021
2022 Features["avx"] = HasAVXSave;
2023 Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave;
2024 // Only enable XSAVE if OS has enabled support for saving YMM state.
2025 Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave;
2026 Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave;
2027
2028 unsigned MaxExtLevel;
2029 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
2030
2031 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
2032 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
2033 Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1);
2034 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
2035 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
2036 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
2037 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
2038 Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
2039 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
2040 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
2041 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
2042
2043 Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1);
2044
2045 // Miscellaneous memory related features, detected by
2046 // using the 0x80000008 leaf of the CPUID instruction
2047 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
2048 !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
2049 Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1);
2050 Features["rdpru"] = HasExtLeaf8 && ((EBX >> 4) & 1);
2051 Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1);
2052
2053 bool HasLeaf7 =
2054 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
2055
2056 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
2057 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
2058 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
2059 // AVX2 is only supported if we have the OS save support from AVX.
2060 Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave;
2061 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
2062 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
2063 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
2064 // AVX512 is only supported if the OS supports the context save for it.
2065 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
2066 if (Features["avx512f"])
2067 Features["evex512"] = true;
2068 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
2069 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
2070 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
2071 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
2072 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
2073 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
2074 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
2075 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
2076 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
2077 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
2078
2079 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
2080 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
2081 Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1);
2082 Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save;
2083 Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1);
2084 Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1);
2085 Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave;
2086 Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave;
2087 Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save;
2088 Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
2089 Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
2090 Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1);
2091 Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker
2092 Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1);
2093 Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
2094 Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
2095 Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1);
2096
2097 Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1);
2098 Features["avx512vp2intersect"] =
2099 HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save;
2100 Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1);
2101 Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1);
2102 // There are two CPUID leafs which information associated with the pconfig
2103 // instruction:
2104 // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
2105 // bit of EDX), while the EAX=0x1b leaf returns information on the
2106 // availability of specific pconfig leafs.
2107 // The target feature here only refers to the the first of these two.
2108 // Users might need to check for the availability of specific pconfig
2109 // leaves using cpuid, since that information is ignored while
2110 // detecting features using the "-march=native" flag.
2111 // For more info, see X86 ISA docs.
2112 Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1);
2113 Features["amx-bf16"] = HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave;
2114 Features["avx512fp16"] = HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save;
2115 Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave;
2116 Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave;
2117 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
2118 // return all 0s for invalid subleaves so check the limit.
2119 bool HasLeaf7Subleaf1 =
2120 HasLeaf7 && EAX >= 1 &&
2121 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
2122 Features["sha512"] = HasLeaf7Subleaf1 && ((EAX >> 0) & 1);
2123 Features["sm3"] = HasLeaf7Subleaf1 && ((EAX >> 1) & 1);
2124 Features["sm4"] = HasLeaf7Subleaf1 && ((EAX >> 2) & 1);
2125 Features["raoint"] = HasLeaf7Subleaf1 && ((EAX >> 3) & 1);
2126 Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
2127 Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save;
2128 Features["amx-fp16"] = HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave;
2129 Features["cmpccxadd"] = HasLeaf7Subleaf1 && ((EAX >> 7) & 1);
2130 Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
2131 Features["avxifma"] = HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave;
2132 Features["movrs"] = HasLeaf7Subleaf1 && ((EAX >> 31) & 1);
2133 Features["avxvnniint8"] = HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave;
2134 Features["avxneconvert"] = HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave;
2135 Features["amx-complex"] = HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave;
2136 Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave;
2137 Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1);
2138 Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1);
2139 bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1);
2140 bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1);
2141 Features["egpr"] = HasAPXF;
2142 Features["push2pop2"] = HasAPXF;
2143 Features["ppx"] = HasAPXF;
2144 Features["ndd"] = HasAPXF;
2145 Features["ccmp"] = HasAPXF;
2146 Features["nf"] = HasAPXF;
2147 Features["cf"] = HasAPXF;
2148 Features["zu"] = HasAPXF;
2149
2150 bool HasLeafD = MaxLevel >= 0xd &&
2151 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
2152
2153 // Only enable XSAVE if OS has enabled support for saving YMM state.
2154 Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave;
2155 Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave;
2156 Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave;
2157
2158 bool HasLeaf14 = MaxLevel >= 0x14 &&
2159 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
2160
2161 Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1);
2162
2163 bool HasLeaf19 =
2164 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
2165 Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1);
2166
2167 bool HasLeaf1E = MaxLevel >= 0x1e &&
2168 !getX86CpuIDAndInfoEx(0x1e, 0x1, &EAX, &EBX, &ECX, &EDX);
2169 Features["amx-fp8"] = HasLeaf1E && ((EAX >> 4) & 1) && HasAMXSave;
2170 Features["amx-transpose"] = HasLeaf1E && ((EAX >> 5) & 1) && HasAMXSave;
2171 Features["amx-tf32"] = HasLeaf1E && ((EAX >> 6) & 1) && HasAMXSave;
2172 Features["amx-avx512"] = HasLeaf1E && ((EAX >> 7) & 1) && HasAMXSave;
2173 Features["amx-movrs"] = HasLeaf1E && ((EAX >> 8) & 1) && HasAMXSave;
2174
2175 bool HasLeaf24 =
2176 MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX);
2177
2178 int AVX10Ver = HasLeaf24 && (EBX & 0xff);
2179 int Has512Len = HasLeaf24 && ((EBX >> 18) & 1);
2180 Features["avx10.1-256"] = HasAVX10 && AVX10Ver >= 1;
2181 Features["avx10.1-512"] = HasAVX10 && AVX10Ver >= 1 && Has512Len;
2182 Features["avx10.2-256"] = HasAVX10 && AVX10Ver >= 2;
2183 Features["avx10.2-512"] = HasAVX10 && AVX10Ver >= 2 && Has512Len;
2184
2185 return Features;
2186}
2187#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
2189 StringMap<bool> Features;
2190 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
2191 if (!P)
2192 return Features;
2193
2195 P->getBuffer().split(Lines, '\n');
2196
2197 SmallVector<StringRef, 32> CPUFeatures;
2198
2199 // Look for the CPU features.
2200 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
2201 if (Lines[I].starts_with("Features")) {
2202 Lines[I].split(CPUFeatures, ' ');
2203 break;
2204 }
2205
2206#if defined(__aarch64__)
2207 // All of these are "crypto" features, but we must sift out actual features
2208 // as the former meaning of "crypto" as a single feature is no more.
2209 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
2210 uint32_t crypto = 0;
2211#endif
2212
2213 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
2214 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
2215#if defined(__aarch64__)
2216 .Case("asimd", "neon")
2217 .Case("fp", "fp-armv8")
2218 .Case("crc32", "crc")
2219 .Case("atomics", "lse")
2220 .Case("sha3", "sha3")
2221 .Case("sm4", "sm4")
2222 .Case("sve", "sve")
2223 .Case("sve2", "sve2")
2224 .Case("sveaes", "sve-aes")
2225 .Case("svesha3", "sve-sha3")
2226 .Case("svesm4", "sve-sm4")
2227#else
2228 .Case("half", "fp16")
2229 .Case("neon", "neon")
2230 .Case("vfpv3", "vfp3")
2231 .Case("vfpv3d16", "vfp3d16")
2232 .Case("vfpv4", "vfp4")
2233 .Case("idiva", "hwdiv-arm")
2234 .Case("idivt", "hwdiv")
2235#endif
2236 .Default("");
2237
2238#if defined(__aarch64__)
2239 // We need to check crypto separately since we need all of the crypto
2240 // extensions to enable the subtarget feature
2241 if (CPUFeatures[I] == "aes")
2242 crypto |= CAP_AES;
2243 else if (CPUFeatures[I] == "pmull")
2244 crypto |= CAP_PMULL;
2245 else if (CPUFeatures[I] == "sha1")
2246 crypto |= CAP_SHA1;
2247 else if (CPUFeatures[I] == "sha2")
2248 crypto |= CAP_SHA2;
2249#endif
2250
2251 if (LLVMFeatureStr != "")
2252 Features[LLVMFeatureStr] = true;
2253 }
2254
2255#if defined(__aarch64__)
2256 // LLVM has decided some AArch64 CPUs have all the instructions they _may_
2257 // have, as opposed to all the instructions they _must_ have, so allow runtime
2258 // information to correct us on that.
2259 uint32_t Aes = CAP_AES | CAP_PMULL;
2260 uint32_t Sha2 = CAP_SHA1 | CAP_SHA2;
2261 Features["aes"] = (crypto & Aes) == Aes;
2262 Features["sha2"] = (crypto & Sha2) == Sha2;
2263#endif
2264
2265 return Features;
2266}
2267#elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64) || \
2268 defined(__arm64ec__) || defined(_M_ARM64EC))
2270 StringMap<bool> Features;
2271
2272 // If we're asking the OS at runtime, believe what the OS says
2273 Features["neon"] =
2274 IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE);
2275 Features["crc"] =
2276 IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
2277
2278 // Avoid inferring "crypto" means more than the traditional AES + SHA2
2279 bool TradCrypto =
2280 IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE);
2281 Features["aes"] = TradCrypto;
2282 Features["sha2"] = TradCrypto;
2283
2284 return Features;
2285}
2286#elif defined(__linux__) && defined(__loongarch__)
2287#include <sys/auxv.h>
2289 unsigned long hwcap = getauxval(AT_HWCAP);
2290 bool HasFPU = hwcap & (1UL << 3); // HWCAP_LOONGARCH_FPU
2291 uint32_t cpucfg2 = 0x2, cpucfg3 = 0x3;
2292 __asm__("cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2] "+r"(cpucfg2));
2293 __asm__("cpucfg %[cpucfg3], %[cpucfg3]\n\t" : [cpucfg3] "+r"(cpucfg3));
2294
2295 StringMap<bool> Features;
2296
2297 Features["f"] = HasFPU && (cpucfg2 & (1U << 1)); // CPUCFG.2.FP_SP
2298 Features["d"] = HasFPU && (cpucfg2 & (1U << 2)); // CPUCFG.2.FP_DP
2299
2300 Features["lsx"] = hwcap & (1UL << 4); // HWCAP_LOONGARCH_LSX
2301 Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX
2302 Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ
2303
2304 Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE
2305 Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32
2306 Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH
2307 Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS
2308 Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ
2309
2310 Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA
2311
2312 // TODO: Need to complete.
2313 // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL
2314 return Features;
2315}
2316#elif defined(__linux__) && defined(__riscv)
2318 RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
2319 {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0},
2320 {/*RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF=*/9, 0}};
2321 int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
2322 /*pair_count=*/std::size(Query), /*cpu_count=*/0,
2323 /*cpus=*/0, /*flags=*/0);
2324 if (Ret != 0)
2325 return {};
2326
2327 StringMap<bool> Features;
2328 uint64_t BaseMask = Query[0].Value;
2329 // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set.
2330 if (BaseMask & 1) {
2331 Features["i"] = true;
2332 Features["m"] = true;
2333 Features["a"] = true;
2334 }
2335
2336 uint64_t ExtMask = Query[1].Value;
2337 Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
2338 Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
2339 Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C
2340 Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V
2341 Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA
2342 Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB
2343 Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS
2344 Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ
2345 Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC
2346 Features["zbkb"] = ExtMask & (1 << 8); // RISCV_HWPROBE_EXT_ZBKB
2347 Features["zbkc"] = ExtMask & (1 << 9); // RISCV_HWPROBE_EXT_ZBKC
2348 Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX
2349 Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND
2350 Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE
2351 Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH
2352 Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED
2353 Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH
2354 Features["zkt"] = ExtMask & (1 << 16); // RISCV_HWPROBE_EXT_ZKT
2355 Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB
2356 Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC
2357 Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB
2358 Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG
2359 Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED
2360 Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA
2361 Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB
2362 Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED
2363 Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH
2364 Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT
2365 Features["zfh"] = ExtMask & (1 << 27); // RISCV_HWPROBE_EXT_ZFH
2366 Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN
2367 Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL
2368 Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH
2369 Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
2370 Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA
2371 Features["ztso"] = ExtMask & (1ULL << 33); // RISCV_HWPROBE_EXT_ZTSO
2372 Features["zacas"] = ExtMask & (1ULL << 34); // RISCV_HWPROBE_EXT_ZACAS
2373 Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
2374 Features["zihintpause"] =
2375 ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
2376 Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X
2377 Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F
2378 Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X
2379 Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F
2380 Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D
2381 Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP
2382 Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA
2383 Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB
2384 Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD
2385 Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF
2386 Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP
2387 Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS
2388
2389 // Check whether the processor supports fast misaligned scalar memory access.
2390 // NOTE: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF is only available on
2391 // Linux 6.11 or later. If it is not recognized, the key field will be cleared
2392 // to -1.
2393 if (Query[2].Key != -1 &&
2394 Query[2].Value == /*RISCV_HWPROBE_MISALIGNED_SCALAR_FAST=*/3)
2395 Features["unaligned-scalar-mem"] = true;
2396
2397 return Features;
2398}
2399#else
2401#endif
2402
2403#if __APPLE__
2404/// \returns the \p triple, but with the Host's arch spliced in.
2405static Triple withHostArch(Triple T) {
2406#if defined(__arm__)
2407 T.setArch(Triple::arm);
2408 T.setArchName("arm");
2409#elif defined(__arm64e__)
2411 T.setArchName("arm64e");
2412#elif defined(__aarch64__)
2413 T.setArch(Triple::aarch64);
2414 T.setArchName("arm64");
2415#elif defined(__x86_64h__)
2416 T.setArch(Triple::x86_64);
2417 T.setArchName("x86_64h");
2418#elif defined(__x86_64__)
2419 T.setArch(Triple::x86_64);
2420 T.setArchName("x86_64");
2421#elif defined(__i386__)
2422 T.setArch(Triple::x86);
2423 T.setArchName("i386");
2424#elif defined(__powerpc__)
2425 T.setArch(Triple::ppc);
2426 T.setArchName("powerpc");
2427#else
2428# error "Unimplemented host arch fixup"
2429#endif
2430 return T;
2431}
2432#endif
2433
2435 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
2436 Triple PT(Triple::normalize(TargetTripleString));
2437
2438#if __APPLE__
2439 /// In Universal builds, LLVM_HOST_TRIPLE will have the wrong arch in one of
2440 /// the slices. This fixes that up.
2441 PT = withHostArch(PT);
2442#endif
2443
2444 if (sizeof(void *) == 8 && PT.isArch32Bit())
2445 PT = PT.get64BitArchVariant();
2446 if (sizeof(void *) == 4 && PT.isArch64Bit())
2447 PT = PT.get32BitArchVariant();
2448
2449 return PT.str();
2450}
2451
2453#if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
2454 std::string CPU = std::string(sys::getHostCPUName());
2455 if (CPU == "generic")
2456 CPU = "(unknown)";
2457 OS << " Default target: " << sys::getDefaultTargetTriple() << '\n'
2458 << " Host CPU: " << CPU << '\n';
2459#endif
2460}
This file defines the StringMap class.
This file implements methods to test, set and extract typed bits from packed unsigned integers.
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:298
Given that RA is a live value
T Content
std::string Name
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
Definition: MergeICmps.cpp:915
#define P(N)
raw_pwrite_stream & OS
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.
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:938
void reserve(size_type N)
Definition: SmallVector.h:664
iterator erase(const_iterator CI)
Definition: SmallVector.h:738
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
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
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
iterator begin() const
Definition: StringRef.h:120
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.
Definition: StringSwitch.h:43
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:68
R Default(T Value)
Definition: StringSwitch.h:177
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:80
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:1783
LLVM_ABI llvm::Triple get64BitArchVariant() const
Form a triple with a 64-bit variant of the current architecture.
Definition: Triple.cpp:1866
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:1152
const std::string & str() const
Definition: Triple.h:475
LLVM_ABI bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1771
@ AArch64SubArch_arm64e
Definition: Triple.h:153
LLVM_ABI bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1775
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
Key
PAL metadata keys.
@ 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:1962
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:2400
LLVM_ABI StringRef getHostCPUName()
getHostCPUName - Get the LLVM name for the host CPU.
Definition: Host.cpp:1956
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:2452
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:2434
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:477
auto unique(Range &&R, Predicate P)
Definition: STLExtras.h:2095
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1669
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:1916
Describes an element of a Bitfield.
Definition: Bitfields.h:223