[clang][bytecode] Fix reporting failed local constexpr initializers (#123588)
[llvm-project.git] / llvm / lib / TargetParser / Host.cpp
blob979b44b22338e1850b2389666a4226973cfd16fa
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.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/TargetParser/Host.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringMap.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/Config/llvm-config.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/TargetParser/Triple.h"
22 #include "llvm/TargetParser/X86TargetParser.h"
23 #include <string.h>
25 // Include the platform-specific parts of this class.
26 #ifdef LLVM_ON_UNIX
27 #include "Unix/Host.inc"
28 #include <sched.h>
29 #endif
30 #ifdef _WIN32
31 #include "Windows/Host.inc"
32 #endif
33 #ifdef _MSC_VER
34 #include <intrin.h>
35 #endif
36 #ifdef __MVS__
37 #include "llvm/Support/BCD.h"
38 #endif
39 #if defined(__APPLE__)
40 #include <mach/host_info.h>
41 #include <mach/mach.h>
42 #include <mach/mach_host.h>
43 #include <mach/machine.h>
44 #include <sys/param.h>
45 #include <sys/sysctl.h>
46 #endif
47 #ifdef _AIX
48 #include <sys/systemcfg.h>
49 #endif
50 #if defined(__sun__) && defined(__svr4__)
51 #include <kstat.h>
52 #endif
53 #if defined(__GNUC__) || defined(__clang__)
54 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
55 #include <cpuid.h>
56 #endif
57 #endif
59 #define DEBUG_TYPE "host-detection"
61 //===----------------------------------------------------------------------===//
63 // Implementations of the CPU detection routines
65 //===----------------------------------------------------------------------===//
67 using namespace llvm;
69 static std::unique_ptr<llvm::MemoryBuffer>
70 LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent() {
71 const char *CPUInfoFile = "/proc/cpuinfo";
72 if (const char *CpuinfoIntercept = std::getenv("LLVM_CPUINFO"))
73 CPUInfoFile = CpuinfoIntercept;
74 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
75 llvm::MemoryBuffer::getFileAsStream(CPUInfoFile);
77 if (std::error_code EC = Text.getError()) {
78 llvm::errs() << "Can't read " << CPUInfoFile << ": " << EC.message()
79 << "\n";
80 return nullptr;
82 return std::move(*Text);
85 StringRef sys::detail::getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent) {
86 // Access to the Processor Version Register (PVR) on PowerPC is privileged,
87 // and so we must use an operating-system interface to determine the current
88 // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
89 const char *generic = "generic";
91 // The cpu line is second (after the 'processor: 0' line), so if this
92 // buffer is too small then something has changed (or is wrong).
93 StringRef::const_iterator CPUInfoStart = ProcCpuinfoContent.begin();
94 StringRef::const_iterator CPUInfoEnd = ProcCpuinfoContent.end();
96 StringRef::const_iterator CIP = CPUInfoStart;
98 StringRef::const_iterator CPUStart = nullptr;
99 size_t CPULen = 0;
101 // We need to find the first line which starts with cpu, spaces, and a colon.
102 // After the colon, there may be some additional spaces and then the cpu type.
103 while (CIP < CPUInfoEnd && CPUStart == nullptr) {
104 if (CIP < CPUInfoEnd && *CIP == '\n')
105 ++CIP;
107 if (CIP < CPUInfoEnd && *CIP == 'c') {
108 ++CIP;
109 if (CIP < CPUInfoEnd && *CIP == 'p') {
110 ++CIP;
111 if (CIP < CPUInfoEnd && *CIP == 'u') {
112 ++CIP;
113 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
114 ++CIP;
116 if (CIP < CPUInfoEnd && *CIP == ':') {
117 ++CIP;
118 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
119 ++CIP;
121 if (CIP < CPUInfoEnd) {
122 CPUStart = CIP;
123 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
124 *CIP != ',' && *CIP != '\n'))
125 ++CIP;
126 CPULen = CIP - CPUStart;
133 if (CPUStart == nullptr)
134 while (CIP < CPUInfoEnd && *CIP != '\n')
135 ++CIP;
138 if (CPUStart == nullptr)
139 return generic;
141 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
142 .Case("604e", "604e")
143 .Case("604", "604")
144 .Case("7400", "7400")
145 .Case("7410", "7400")
146 .Case("7447", "7400")
147 .Case("7455", "7450")
148 .Case("G4", "g4")
149 .Case("POWER4", "970")
150 .Case("PPC970FX", "970")
151 .Case("PPC970MP", "970")
152 .Case("G5", "g5")
153 .Case("POWER5", "g5")
154 .Case("A2", "a2")
155 .Case("POWER6", "pwr6")
156 .Case("POWER7", "pwr7")
157 .Case("POWER8", "pwr8")
158 .Case("POWER8E", "pwr8")
159 .Case("POWER8NVL", "pwr8")
160 .Case("POWER9", "pwr9")
161 .Case("POWER10", "pwr10")
162 .Case("POWER11", "pwr11")
163 // FIXME: If we get a simulator or machine with the capabilities of
164 // mcpu=future, we should revisit this and add the name reported by the
165 // simulator/machine.
166 .Default(generic);
169 StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) {
170 // The cpuid register on arm is not accessible from user space. On Linux,
171 // it is exposed through the /proc/cpuinfo file.
173 // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line
174 // in all cases.
175 SmallVector<StringRef, 32> Lines;
176 ProcCpuinfoContent.split(Lines, '\n');
178 // Look for the CPU implementer line.
179 StringRef Implementer;
180 StringRef Hardware;
181 StringRef Part;
182 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
183 if (Lines[I].starts_with("CPU implementer"))
184 Implementer = Lines[I].substr(15).ltrim("\t :");
185 if (Lines[I].starts_with("Hardware"))
186 Hardware = Lines[I].substr(8).ltrim("\t :");
187 if (Lines[I].starts_with("CPU part"))
188 Part = Lines[I].substr(8).ltrim("\t :");
191 if (Implementer == "0x41") { // ARM Ltd.
192 // MSM8992/8994 may give cpu part for the core that the kernel is running on,
193 // which is undeterministic and wrong. Always return cortex-a53 for these SoC.
194 if (Hardware.ends_with("MSM8994") || Hardware.ends_with("MSM8996"))
195 return "cortex-a53";
198 // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
199 // values correspond to the "Part number" in the CP15/c0 register. The
200 // contents are specified in the various processor manuals.
201 // This corresponds to the Main ID Register in Technical Reference Manuals.
202 // and is used in programs like sys-utils
203 return StringSwitch<const char *>(Part)
204 .Case("0x926", "arm926ej-s")
205 .Case("0xb02", "mpcore")
206 .Case("0xb36", "arm1136j-s")
207 .Case("0xb56", "arm1156t2-s")
208 .Case("0xb76", "arm1176jz-s")
209 .Case("0xc05", "cortex-a5")
210 .Case("0xc07", "cortex-a7")
211 .Case("0xc08", "cortex-a8")
212 .Case("0xc09", "cortex-a9")
213 .Case("0xc0f", "cortex-a15")
214 .Case("0xc0e", "cortex-a17")
215 .Case("0xc20", "cortex-m0")
216 .Case("0xc23", "cortex-m3")
217 .Case("0xc24", "cortex-m4")
218 .Case("0xc27", "cortex-m7")
219 .Case("0xd20", "cortex-m23")
220 .Case("0xd21", "cortex-m33")
221 .Case("0xd24", "cortex-m52")
222 .Case("0xd22", "cortex-m55")
223 .Case("0xd23", "cortex-m85")
224 .Case("0xc18", "cortex-r8")
225 .Case("0xd13", "cortex-r52")
226 .Case("0xd16", "cortex-r52plus")
227 .Case("0xd15", "cortex-r82")
228 .Case("0xd14", "cortex-r82ae")
229 .Case("0xd02", "cortex-a34")
230 .Case("0xd04", "cortex-a35")
231 .Case("0xd03", "cortex-a53")
232 .Case("0xd05", "cortex-a55")
233 .Case("0xd46", "cortex-a510")
234 .Case("0xd80", "cortex-a520")
235 .Case("0xd88", "cortex-a520ae")
236 .Case("0xd07", "cortex-a57")
237 .Case("0xd06", "cortex-a65")
238 .Case("0xd43", "cortex-a65ae")
239 .Case("0xd08", "cortex-a72")
240 .Case("0xd09", "cortex-a73")
241 .Case("0xd0a", "cortex-a75")
242 .Case("0xd0b", "cortex-a76")
243 .Case("0xd0e", "cortex-a76ae")
244 .Case("0xd0d", "cortex-a77")
245 .Case("0xd41", "cortex-a78")
246 .Case("0xd42", "cortex-a78ae")
247 .Case("0xd4b", "cortex-a78c")
248 .Case("0xd47", "cortex-a710")
249 .Case("0xd4d", "cortex-a715")
250 .Case("0xd81", "cortex-a720")
251 .Case("0xd89", "cortex-a720ae")
252 .Case("0xd87", "cortex-a725")
253 .Case("0xd44", "cortex-x1")
254 .Case("0xd4c", "cortex-x1c")
255 .Case("0xd48", "cortex-x2")
256 .Case("0xd4e", "cortex-x3")
257 .Case("0xd82", "cortex-x4")
258 .Case("0xd85", "cortex-x925")
259 .Case("0xd4a", "neoverse-e1")
260 .Case("0xd0c", "neoverse-n1")
261 .Case("0xd49", "neoverse-n2")
262 .Case("0xd8e", "neoverse-n3")
263 .Case("0xd40", "neoverse-v1")
264 .Case("0xd4f", "neoverse-v2")
265 .Case("0xd84", "neoverse-v3")
266 .Case("0xd83", "neoverse-v3ae")
267 .Default("generic");
270 if (Implementer == "0x42" || Implementer == "0x43") { // Broadcom | Cavium.
271 return StringSwitch<const char *>(Part)
272 .Case("0x516", "thunderx2t99")
273 .Case("0x0516", "thunderx2t99")
274 .Case("0xaf", "thunderx2t99")
275 .Case("0x0af", "thunderx2t99")
276 .Case("0xa1", "thunderxt88")
277 .Case("0x0a1", "thunderxt88")
278 .Default("generic");
281 if (Implementer == "0x46") { // Fujitsu Ltd.
282 return StringSwitch<const char *>(Part)
283 .Case("0x001", "a64fx")
284 .Case("0x003", "fujitsu-monaka")
285 .Default("generic");
288 if (Implementer == "0x4e") { // NVIDIA Corporation
289 return StringSwitch<const char *>(Part)
290 .Case("0x004", "carmel")
291 .Default("generic");
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");
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 unsigned Variant = 0, Part = 0;
326 // Look for the CPU variant line, whose value is a 1 digit hexadecimal
327 // number, corresponding to the Variant bits in the CP15/C0 register.
328 for (auto I : Lines)
329 if (I.consume_front("CPU variant"))
330 I.ltrim("\t :").getAsInteger(0, Variant);
332 // Look for the CPU part line, whose value is a 3 digit hexadecimal
333 // number, corresponding to the PartNum bits in the CP15/C0 register.
334 for (auto I : Lines)
335 if (I.consume_front("CPU part"))
336 I.ltrim("\t :").getAsInteger(0, Part);
338 unsigned Exynos = (Variant << 12) | Part;
339 switch (Exynos) {
340 default:
341 // Default by falling through to Exynos M3.
342 [[fallthrough]];
343 case 0x1002:
344 return "exynos-m3";
345 case 0x1003:
346 return "exynos-m4";
350 if (Implementer == "0x61") { // Apple
351 return StringSwitch<const char *>(Part)
352 .Case("0x020", "apple-m1")
353 .Case("0x021", "apple-m1")
354 .Case("0x022", "apple-m1")
355 .Case("0x023", "apple-m1")
356 .Case("0x024", "apple-m1")
357 .Case("0x025", "apple-m1")
358 .Case("0x028", "apple-m1")
359 .Case("0x029", "apple-m1")
360 .Case("0x030", "apple-m2")
361 .Case("0x031", "apple-m2")
362 .Case("0x032", "apple-m2")
363 .Case("0x033", "apple-m2")
364 .Case("0x034", "apple-m2")
365 .Case("0x035", "apple-m2")
366 .Case("0x038", "apple-m2")
367 .Case("0x039", "apple-m2")
368 .Case("0x049", "apple-m3")
369 .Case("0x048", "apple-m3")
370 .Default("generic");
373 if (Implementer == "0x63") { // Arm China.
374 return StringSwitch<const char *>(Part)
375 .Case("0x132", "star-mc1")
376 .Default("generic");
379 if (Implementer == "0x6d") { // Microsoft Corporation.
380 // The Microsoft Azure Cobalt 100 CPU is handled as a Neoverse N2.
381 return StringSwitch<const char *>(Part)
382 .Case("0xd49", "neoverse-n2")
383 .Default("generic");
386 if (Implementer == "0xc0") { // Ampere Computing
387 return StringSwitch<const char *>(Part)
388 .Case("0xac3", "ampere1")
389 .Case("0xac4", "ampere1a")
390 .Case("0xac5", "ampere1b")
391 .Default("generic");
394 return "generic";
397 namespace {
398 StringRef getCPUNameFromS390Model(unsigned int Id, bool HaveVectorSupport) {
399 switch (Id) {
400 case 2064: // z900 not supported by LLVM
401 case 2066:
402 case 2084: // z990 not supported by LLVM
403 case 2086:
404 case 2094: // z9-109 not supported by LLVM
405 case 2096:
406 return "generic";
407 case 2097:
408 case 2098:
409 return "z10";
410 case 2817:
411 case 2818:
412 return "z196";
413 case 2827:
414 case 2828:
415 return "zEC12";
416 case 2964:
417 case 2965:
418 return HaveVectorSupport? "z13" : "zEC12";
419 case 3906:
420 case 3907:
421 return HaveVectorSupport? "z14" : "zEC12";
422 case 8561:
423 case 8562:
424 return HaveVectorSupport? "z15" : "zEC12";
425 case 3931:
426 case 3932:
427 default:
428 return HaveVectorSupport? "z16" : "zEC12";
431 } // end anonymous namespace
433 StringRef sys::detail::getHostCPUNameForS390x(StringRef ProcCpuinfoContent) {
434 // STIDP is a privileged operation, so use /proc/cpuinfo instead.
436 // The "processor 0:" line comes after a fair amount of other information,
437 // including a cache breakdown, but this should be plenty.
438 SmallVector<StringRef, 32> Lines;
439 ProcCpuinfoContent.split(Lines, '\n');
441 // Look for the CPU features.
442 SmallVector<StringRef, 32> CPUFeatures;
443 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
444 if (Lines[I].starts_with("features")) {
445 size_t Pos = Lines[I].find(':');
446 if (Pos != StringRef::npos) {
447 Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
448 break;
452 // We need to check for the presence of vector support independently of
453 // the machine type, since we may only use the vector register set when
454 // supported by the kernel (and hypervisor).
455 bool HaveVectorSupport = false;
456 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
457 if (CPUFeatures[I] == "vx")
458 HaveVectorSupport = true;
461 // Now check the processor machine type.
462 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
463 if (Lines[I].starts_with("processor ")) {
464 size_t Pos = Lines[I].find("machine = ");
465 if (Pos != StringRef::npos) {
466 Pos += sizeof("machine = ") - 1;
467 unsigned int Id;
468 if (!Lines[I].drop_front(Pos).getAsInteger(10, Id))
469 return getCPUNameFromS390Model(Id, HaveVectorSupport);
471 break;
475 return "generic";
478 StringRef sys::detail::getHostCPUNameForRISCV(StringRef ProcCpuinfoContent) {
479 // There are 24 lines in /proc/cpuinfo
480 SmallVector<StringRef> Lines;
481 ProcCpuinfoContent.split(Lines, '\n');
483 // Look for uarch line to determine cpu name
484 StringRef UArch;
485 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
486 if (Lines[I].starts_with("uarch")) {
487 UArch = Lines[I].substr(5).ltrim("\t :");
488 break;
492 return StringSwitch<const char *>(UArch)
493 .Case("sifive,u74-mc", "sifive-u74")
494 .Case("sifive,bullet0", "sifive-u74")
495 .Default("");
498 StringRef sys::detail::getHostCPUNameForBPF() {
499 #if !defined(__linux__) || !defined(__x86_64__)
500 return "generic";
501 #else
502 uint8_t v3_insns[40] __attribute__ ((aligned (8))) =
503 /* BPF_MOV64_IMM(BPF_REG_0, 0) */
504 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
505 /* BPF_MOV64_IMM(BPF_REG_2, 1) */
506 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
507 /* BPF_JMP32_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
508 0xae, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
509 /* BPF_MOV64_IMM(BPF_REG_0, 1) */
510 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
511 /* BPF_EXIT_INSN() */
512 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
514 uint8_t v2_insns[40] __attribute__ ((aligned (8))) =
515 /* BPF_MOV64_IMM(BPF_REG_0, 0) */
516 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
517 /* BPF_MOV64_IMM(BPF_REG_2, 1) */
518 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
519 /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
520 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
521 /* BPF_MOV64_IMM(BPF_REG_0, 1) */
522 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
523 /* BPF_EXIT_INSN() */
524 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
526 struct bpf_prog_load_attr {
527 uint32_t prog_type;
528 uint32_t insn_cnt;
529 uint64_t insns;
530 uint64_t license;
531 uint32_t log_level;
532 uint32_t log_size;
533 uint64_t log_buf;
534 uint32_t kern_version;
535 uint32_t prog_flags;
536 } attr = {};
537 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
538 attr.insn_cnt = 5;
539 attr.insns = (uint64_t)v3_insns;
540 attr.license = (uint64_t)"DUMMY";
542 int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr,
543 sizeof(attr));
544 if (fd >= 0) {
545 close(fd);
546 return "v3";
549 /* Clear the whole attr in case its content changed by syscall. */
550 memset(&attr, 0, sizeof(attr));
551 attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
552 attr.insn_cnt = 5;
553 attr.insns = (uint64_t)v2_insns;
554 attr.license = (uint64_t)"DUMMY";
555 fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr));
556 if (fd >= 0) {
557 close(fd);
558 return "v2";
560 return "v1";
561 #endif
564 #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
565 defined(_M_X64)
567 /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
568 /// the specified arguments. If we can't run cpuid on the host, return true.
569 static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
570 unsigned *rECX, unsigned *rEDX) {
571 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
572 return !__get_cpuid(value, rEAX, rEBX, rECX, rEDX);
573 #elif defined(_MSC_VER)
574 // The MSVC intrinsic is portable across x86 and x64.
575 int registers[4];
576 __cpuid(registers, value);
577 *rEAX = registers[0];
578 *rEBX = registers[1];
579 *rECX = registers[2];
580 *rEDX = registers[3];
581 return false;
582 #else
583 return true;
584 #endif
587 namespace llvm {
588 namespace sys {
589 namespace detail {
590 namespace x86 {
592 VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
593 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
594 if (MaxLeaf == nullptr)
595 MaxLeaf = &EAX;
596 else
597 *MaxLeaf = 0;
599 if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1)
600 return VendorSignatures::UNKNOWN;
602 // "Genu ineI ntel"
603 if (EBX == 0x756e6547 && EDX == 0x49656e69 && ECX == 0x6c65746e)
604 return VendorSignatures::GENUINE_INTEL;
606 // "Auth enti cAMD"
607 if (EBX == 0x68747541 && EDX == 0x69746e65 && ECX == 0x444d4163)
608 return VendorSignatures::AUTHENTIC_AMD;
610 return VendorSignatures::UNKNOWN;
613 } // namespace x86
614 } // namespace detail
615 } // namespace sys
616 } // namespace llvm
618 using namespace llvm::sys::detail::x86;
620 /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
621 /// the 4 values in the specified arguments. If we can't run cpuid on the host,
622 /// return true.
623 static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
624 unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
625 unsigned *rEDX) {
626 // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
627 // are such that __cpuidex is defined within cpuid.h for both, we can remove
628 // the __get_cpuid_count function and share the MSVC implementation between
629 // all three.
630 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
631 return !__get_cpuid_count(value, subleaf, rEAX, rEBX, rECX, rEDX);
632 #elif defined(_MSC_VER)
633 int registers[4];
634 __cpuidex(registers, value, subleaf);
635 *rEAX = registers[0];
636 *rEBX = registers[1];
637 *rECX = registers[2];
638 *rEDX = registers[3];
639 return false;
640 #else
641 return true;
642 #endif
645 // Read control register 0 (XCR0). Used to detect features such as AVX.
646 static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
647 // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang
648 // are such that _xgetbv is supported by both, we can unify the implementation
649 // with MSVC and remove all inline assembly.
650 #if defined(__GNUC__) || defined(__clang__)
651 // Check xgetbv; this uses a .byte sequence instead of the instruction
652 // directly because older assemblers do not include support for xgetbv and
653 // there is no easy way to conditionally compile based on the assembler used.
654 __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
655 return false;
656 #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
657 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
658 *rEAX = Result;
659 *rEDX = Result >> 32;
660 return false;
661 #else
662 return true;
663 #endif
666 static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
667 unsigned *Model) {
668 *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
669 *Model = (EAX >> 4) & 0xf; // Bits 4 - 7
670 if (*Family == 6 || *Family == 0xf) {
671 if (*Family == 0xf)
672 // Examine extended family ID if family ID is F.
673 *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
674 // Examine extended model ID if family ID is 6 or F.
675 *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
679 #define testFeature(F) (Features[F / 32] & (1 << (F % 32))) != 0
681 static StringRef getIntelProcessorTypeAndSubtype(unsigned Family,
682 unsigned Model,
683 const unsigned *Features,
684 unsigned *Type,
685 unsigned *Subtype) {
686 StringRef CPU;
688 switch (Family) {
689 case 3:
690 CPU = "i386";
691 break;
692 case 4:
693 CPU = "i486";
694 break;
695 case 5:
696 if (testFeature(X86::FEATURE_MMX)) {
697 CPU = "pentium-mmx";
698 break;
700 CPU = "pentium";
701 break;
702 case 6:
703 switch (Model) {
704 case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
705 // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
706 // mobile processor, Intel Core 2 Extreme processor, Intel
707 // Pentium Dual-Core processor, Intel Xeon processor, model
708 // 0Fh. All processors are manufactured using the 65 nm process.
709 case 0x16: // Intel Celeron processor model 16h. All processors are
710 // manufactured using the 65 nm process
711 CPU = "core2";
712 *Type = X86::INTEL_CORE2;
713 break;
714 case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
715 // 17h. All processors are manufactured using the 45 nm process.
717 // 45nm: Penryn , Wolfdale, Yorkfield (XE)
718 case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
719 // the 45 nm process.
720 CPU = "penryn";
721 *Type = X86::INTEL_CORE2;
722 break;
723 case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
724 // processors are manufactured using the 45 nm process.
725 case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
726 // As found in a Summer 2010 model iMac.
727 case 0x1f:
728 case 0x2e: // Nehalem EX
729 CPU = "nehalem";
730 *Type = X86::INTEL_COREI7;
731 *Subtype = X86::INTEL_COREI7_NEHALEM;
732 break;
733 case 0x25: // Intel Core i7, laptop version.
734 case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
735 // processors are manufactured using the 32 nm process.
736 case 0x2f: // Westmere EX
737 CPU = "westmere";
738 *Type = X86::INTEL_COREI7;
739 *Subtype = X86::INTEL_COREI7_WESTMERE;
740 break;
741 case 0x2a: // Intel Core i7 processor. All processors are manufactured
742 // using the 32 nm process.
743 case 0x2d:
744 CPU = "sandybridge";
745 *Type = X86::INTEL_COREI7;
746 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
747 break;
748 case 0x3a:
749 case 0x3e: // Ivy Bridge EP
750 CPU = "ivybridge";
751 *Type = X86::INTEL_COREI7;
752 *Subtype = X86::INTEL_COREI7_IVYBRIDGE;
753 break;
755 // Haswell:
756 case 0x3c:
757 case 0x3f:
758 case 0x45:
759 case 0x46:
760 CPU = "haswell";
761 *Type = X86::INTEL_COREI7;
762 *Subtype = X86::INTEL_COREI7_HASWELL;
763 break;
765 // Broadwell:
766 case 0x3d:
767 case 0x47:
768 case 0x4f:
769 case 0x56:
770 CPU = "broadwell";
771 *Type = X86::INTEL_COREI7;
772 *Subtype = X86::INTEL_COREI7_BROADWELL;
773 break;
775 // Skylake:
776 case 0x4e: // Skylake mobile
777 case 0x5e: // Skylake desktop
778 case 0x8e: // Kaby Lake mobile
779 case 0x9e: // Kaby Lake desktop
780 case 0xa5: // Comet Lake-H/S
781 case 0xa6: // Comet Lake-U
782 CPU = "skylake";
783 *Type = X86::INTEL_COREI7;
784 *Subtype = X86::INTEL_COREI7_SKYLAKE;
785 break;
787 // Rocketlake:
788 case 0xa7:
789 CPU = "rocketlake";
790 *Type = X86::INTEL_COREI7;
791 *Subtype = X86::INTEL_COREI7_ROCKETLAKE;
792 break;
794 // Skylake Xeon:
795 case 0x55:
796 *Type = X86::INTEL_COREI7;
797 if (testFeature(X86::FEATURE_AVX512BF16)) {
798 CPU = "cooperlake";
799 *Subtype = X86::INTEL_COREI7_COOPERLAKE;
800 } else if (testFeature(X86::FEATURE_AVX512VNNI)) {
801 CPU = "cascadelake";
802 *Subtype = X86::INTEL_COREI7_CASCADELAKE;
803 } else {
804 CPU = "skylake-avx512";
805 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
807 break;
809 // Cannonlake:
810 case 0x66:
811 CPU = "cannonlake";
812 *Type = X86::INTEL_COREI7;
813 *Subtype = X86::INTEL_COREI7_CANNONLAKE;
814 break;
816 // Icelake:
817 case 0x7d:
818 case 0x7e:
819 CPU = "icelake-client";
820 *Type = X86::INTEL_COREI7;
821 *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT;
822 break;
824 // Tigerlake:
825 case 0x8c:
826 case 0x8d:
827 CPU = "tigerlake";
828 *Type = X86::INTEL_COREI7;
829 *Subtype = X86::INTEL_COREI7_TIGERLAKE;
830 break;
832 // Alderlake:
833 case 0x97:
834 case 0x9a:
835 CPU = "alderlake";
836 *Type = X86::INTEL_COREI7;
837 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
838 break;
840 // Gracemont
841 case 0xbe:
842 CPU = "gracemont";
843 *Type = X86::INTEL_COREI7;
844 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
845 break;
847 // Raptorlake:
848 case 0xb7:
849 case 0xba:
850 case 0xbf:
851 CPU = "raptorlake";
852 *Type = X86::INTEL_COREI7;
853 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
854 break;
856 // Meteorlake:
857 case 0xaa:
858 case 0xac:
859 CPU = "meteorlake";
860 *Type = X86::INTEL_COREI7;
861 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
862 break;
864 // Arrowlake:
865 case 0xc5:
866 // Arrowlake U:
867 case 0xb5:
868 CPU = "arrowlake";
869 *Type = X86::INTEL_COREI7;
870 *Subtype = X86::INTEL_COREI7_ARROWLAKE;
871 break;
873 // Arrowlake S:
874 case 0xc6:
875 CPU = "arrowlake-s";
876 *Type = X86::INTEL_COREI7;
877 *Subtype = X86::INTEL_COREI7_ARROWLAKE_S;
878 break;
880 // Lunarlake:
881 case 0xbd:
882 CPU = "lunarlake";
883 *Type = X86::INTEL_COREI7;
884 *Subtype = X86::INTEL_COREI7_ARROWLAKE_S;
885 break;
887 // Pantherlake:
888 case 0xcc:
889 CPU = "pantherlake";
890 *Type = X86::INTEL_COREI7;
891 *Subtype = X86::INTEL_COREI7_PANTHERLAKE;
892 break;
894 // Graniterapids:
895 case 0xad:
896 CPU = "graniterapids";
897 *Type = X86::INTEL_COREI7;
898 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS;
899 break;
901 // Granite Rapids D:
902 case 0xae:
903 CPU = "graniterapids-d";
904 *Type = X86::INTEL_COREI7;
905 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS_D;
906 break;
908 // Icelake Xeon:
909 case 0x6a:
910 case 0x6c:
911 CPU = "icelake-server";
912 *Type = X86::INTEL_COREI7;
913 *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER;
914 break;
916 // Emerald Rapids:
917 case 0xcf:
918 CPU = "emeraldrapids";
919 *Type = X86::INTEL_COREI7;
920 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
921 break;
923 // Sapphire Rapids:
924 case 0x8f:
925 CPU = "sapphirerapids";
926 *Type = X86::INTEL_COREI7;
927 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
928 break;
930 case 0x1c: // Most 45 nm Intel Atom processors
931 case 0x26: // 45 nm Atom Lincroft
932 case 0x27: // 32 nm Atom Medfield
933 case 0x35: // 32 nm Atom Midview
934 case 0x36: // 32 nm Atom Midview
935 CPU = "bonnell";
936 *Type = X86::INTEL_BONNELL;
937 break;
939 // Atom Silvermont codes from the Intel software optimization guide.
940 case 0x37:
941 case 0x4a:
942 case 0x4d:
943 case 0x5a:
944 case 0x5d:
945 case 0x4c: // really airmont
946 CPU = "silvermont";
947 *Type = X86::INTEL_SILVERMONT;
948 break;
949 // Goldmont:
950 case 0x5c: // Apollo Lake
951 case 0x5f: // Denverton
952 CPU = "goldmont";
953 *Type = X86::INTEL_GOLDMONT;
954 break;
955 case 0x7a:
956 CPU = "goldmont-plus";
957 *Type = X86::INTEL_GOLDMONT_PLUS;
958 break;
959 case 0x86:
960 case 0x8a: // Lakefield
961 case 0x96: // Elkhart Lake
962 case 0x9c: // Jasper Lake
963 CPU = "tremont";
964 *Type = X86::INTEL_TREMONT;
965 break;
967 // Sierraforest:
968 case 0xaf:
969 CPU = "sierraforest";
970 *Type = X86::INTEL_SIERRAFOREST;
971 break;
973 // Grandridge:
974 case 0xb6:
975 CPU = "grandridge";
976 *Type = X86::INTEL_GRANDRIDGE;
977 break;
979 // Clearwaterforest:
980 case 0xdd:
981 CPU = "clearwaterforest";
982 *Type = X86::INTEL_CLEARWATERFOREST;
983 break;
985 // Xeon Phi (Knights Landing + Knights Mill):
986 case 0x57:
987 CPU = "knl";
988 *Type = X86::INTEL_KNL;
989 break;
990 case 0x85:
991 CPU = "knm";
992 *Type = X86::INTEL_KNM;
993 break;
995 default: // Unknown family 6 CPU, try to guess.
996 // Don't both with Type/Subtype here, they aren't used by the caller.
997 // They're used above to keep the code in sync with compiler-rt.
998 // TODO detect tigerlake host from model
999 if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) {
1000 CPU = "tigerlake";
1001 } else if (testFeature(X86::FEATURE_AVX512VBMI2)) {
1002 CPU = "icelake-client";
1003 } else if (testFeature(X86::FEATURE_AVX512VBMI)) {
1004 CPU = "cannonlake";
1005 } else if (testFeature(X86::FEATURE_AVX512BF16)) {
1006 CPU = "cooperlake";
1007 } else if (testFeature(X86::FEATURE_AVX512VNNI)) {
1008 CPU = "cascadelake";
1009 } else if (testFeature(X86::FEATURE_AVX512VL)) {
1010 CPU = "skylake-avx512";
1011 } else if (testFeature(X86::FEATURE_CLFLUSHOPT)) {
1012 if (testFeature(X86::FEATURE_SHA))
1013 CPU = "goldmont";
1014 else
1015 CPU = "skylake";
1016 } else if (testFeature(X86::FEATURE_ADX)) {
1017 CPU = "broadwell";
1018 } else if (testFeature(X86::FEATURE_AVX2)) {
1019 CPU = "haswell";
1020 } else if (testFeature(X86::FEATURE_AVX)) {
1021 CPU = "sandybridge";
1022 } else if (testFeature(X86::FEATURE_SSE4_2)) {
1023 if (testFeature(X86::FEATURE_MOVBE))
1024 CPU = "silvermont";
1025 else
1026 CPU = "nehalem";
1027 } else if (testFeature(X86::FEATURE_SSE4_1)) {
1028 CPU = "penryn";
1029 } else if (testFeature(X86::FEATURE_SSSE3)) {
1030 if (testFeature(X86::FEATURE_MOVBE))
1031 CPU = "bonnell";
1032 else
1033 CPU = "core2";
1034 } else if (testFeature(X86::FEATURE_64BIT)) {
1035 CPU = "core2";
1036 } else if (testFeature(X86::FEATURE_SSE3)) {
1037 CPU = "yonah";
1038 } else if (testFeature(X86::FEATURE_SSE2)) {
1039 CPU = "pentium-m";
1040 } else if (testFeature(X86::FEATURE_SSE)) {
1041 CPU = "pentium3";
1042 } else if (testFeature(X86::FEATURE_MMX)) {
1043 CPU = "pentium2";
1044 } else {
1045 CPU = "pentiumpro";
1047 break;
1049 break;
1050 case 15: {
1051 if (testFeature(X86::FEATURE_64BIT)) {
1052 CPU = "nocona";
1053 break;
1055 if (testFeature(X86::FEATURE_SSE3)) {
1056 CPU = "prescott";
1057 break;
1059 CPU = "pentium4";
1060 break;
1062 case 19:
1063 switch (Model) {
1064 // Diamond Rapids:
1065 case 0x01:
1066 CPU = "diamondrapids";
1067 *Type = X86::INTEL_COREI7;
1068 *Subtype = X86::INTEL_COREI7_DIAMONDRAPIDS;
1069 break;
1071 default: // Unknown family 19 CPU.
1072 break;
1074 break;
1075 default:
1076 break; // Unknown.
1079 return CPU;
1082 static const char *getAMDProcessorTypeAndSubtype(unsigned Family,
1083 unsigned Model,
1084 const unsigned *Features,
1085 unsigned *Type,
1086 unsigned *Subtype) {
1087 const char *CPU = 0;
1089 switch (Family) {
1090 case 4:
1091 CPU = "i486";
1092 break;
1093 case 5:
1094 CPU = "pentium";
1095 switch (Model) {
1096 case 6:
1097 case 7:
1098 CPU = "k6";
1099 break;
1100 case 8:
1101 CPU = "k6-2";
1102 break;
1103 case 9:
1104 case 13:
1105 CPU = "k6-3";
1106 break;
1107 case 10:
1108 CPU = "geode";
1109 break;
1111 break;
1112 case 6:
1113 if (testFeature(X86::FEATURE_SSE)) {
1114 CPU = "athlon-xp";
1115 break;
1117 CPU = "athlon";
1118 break;
1119 case 15:
1120 if (testFeature(X86::FEATURE_SSE3)) {
1121 CPU = "k8-sse3";
1122 break;
1124 CPU = "k8";
1125 break;
1126 case 16:
1127 case 18:
1128 CPU = "amdfam10";
1129 *Type = X86::AMDFAM10H; // "amdfam10"
1130 switch (Model) {
1131 case 2:
1132 *Subtype = X86::AMDFAM10H_BARCELONA;
1133 break;
1134 case 4:
1135 *Subtype = X86::AMDFAM10H_SHANGHAI;
1136 break;
1137 case 8:
1138 *Subtype = X86::AMDFAM10H_ISTANBUL;
1139 break;
1141 break;
1142 case 20:
1143 CPU = "btver1";
1144 *Type = X86::AMD_BTVER1;
1145 break;
1146 case 21:
1147 CPU = "bdver1";
1148 *Type = X86::AMDFAM15H;
1149 if (Model >= 0x60 && Model <= 0x7f) {
1150 CPU = "bdver4";
1151 *Subtype = X86::AMDFAM15H_BDVER4;
1152 break; // 60h-7Fh: Excavator
1154 if (Model >= 0x30 && Model <= 0x3f) {
1155 CPU = "bdver3";
1156 *Subtype = X86::AMDFAM15H_BDVER3;
1157 break; // 30h-3Fh: Steamroller
1159 if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) {
1160 CPU = "bdver2";
1161 *Subtype = X86::AMDFAM15H_BDVER2;
1162 break; // 02h, 10h-1Fh: Piledriver
1164 if (Model <= 0x0f) {
1165 *Subtype = X86::AMDFAM15H_BDVER1;
1166 break; // 00h-0Fh: Bulldozer
1168 break;
1169 case 22:
1170 CPU = "btver2";
1171 *Type = X86::AMD_BTVER2;
1172 break;
1173 case 23:
1174 CPU = "znver1";
1175 *Type = X86::AMDFAM17H;
1176 if ((Model >= 0x30 && Model <= 0x3f) || (Model == 0x47) ||
1177 (Model >= 0x60 && Model <= 0x67) || (Model >= 0x68 && Model <= 0x6f) ||
1178 (Model >= 0x70 && Model <= 0x7f) || (Model >= 0x84 && Model <= 0x87) ||
1179 (Model >= 0x90 && Model <= 0x97) || (Model >= 0x98 && Model <= 0x9f) ||
1180 (Model >= 0xa0 && Model <= 0xaf)) {
1181 // Family 17h Models 30h-3Fh (Starship) Zen 2
1182 // Family 17h Models 47h (Cardinal) Zen 2
1183 // Family 17h Models 60h-67h (Renoir) Zen 2
1184 // Family 17h Models 68h-6Fh (Lucienne) Zen 2
1185 // Family 17h Models 70h-7Fh (Matisse) Zen 2
1186 // Family 17h Models 84h-87h (ProjectX) Zen 2
1187 // Family 17h Models 90h-97h (VanGogh) Zen 2
1188 // Family 17h Models 98h-9Fh (Mero) Zen 2
1189 // Family 17h Models A0h-AFh (Mendocino) Zen 2
1190 CPU = "znver2";
1191 *Subtype = X86::AMDFAM17H_ZNVER2;
1192 break;
1194 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x20 && Model <= 0x2f)) {
1195 // Family 17h Models 10h-1Fh (Raven1) Zen
1196 // Family 17h Models 10h-1Fh (Picasso) Zen+
1197 // Family 17h Models 20h-2Fh (Raven2 x86) Zen
1198 *Subtype = X86::AMDFAM17H_ZNVER1;
1199 break;
1201 break;
1202 case 25:
1203 CPU = "znver3";
1204 *Type = X86::AMDFAM19H;
1205 if (Model <= 0x0f || (Model >= 0x20 && Model <= 0x2f) ||
1206 (Model >= 0x30 && Model <= 0x3f) || (Model >= 0x40 && Model <= 0x4f) ||
1207 (Model >= 0x50 && Model <= 0x5f)) {
1208 // Family 19h Models 00h-0Fh (Genesis, Chagall) Zen 3
1209 // Family 19h Models 20h-2Fh (Vermeer) Zen 3
1210 // Family 19h Models 30h-3Fh (Badami) Zen 3
1211 // Family 19h Models 40h-4Fh (Rembrandt) Zen 3+
1212 // Family 19h Models 50h-5Fh (Cezanne) Zen 3
1213 *Subtype = X86::AMDFAM19H_ZNVER3;
1214 break;
1216 if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x60 && Model <= 0x6f) ||
1217 (Model >= 0x70 && Model <= 0x77) || (Model >= 0x78 && Model <= 0x7f) ||
1218 (Model >= 0xa0 && Model <= 0xaf)) {
1219 // Family 19h Models 10h-1Fh (Stones; Storm Peak) Zen 4
1220 // Family 19h Models 60h-6Fh (Raphael) Zen 4
1221 // Family 19h Models 70h-77h (Phoenix, Hawkpoint1) Zen 4
1222 // Family 19h Models 78h-7Fh (Phoenix 2, Hawkpoint2) Zen 4
1223 // Family 19h Models A0h-AFh (Stones-Dense) Zen 4
1224 CPU = "znver4";
1225 *Subtype = X86::AMDFAM19H_ZNVER4;
1226 break; // "znver4"
1228 break; // family 19h
1229 case 26:
1230 CPU = "znver5";
1231 *Type = X86::AMDFAM1AH;
1232 if (Model <= 0x77) {
1233 // Models 00h-0Fh (Breithorn).
1234 // Models 10h-1Fh (Breithorn-Dense).
1235 // Models 20h-2Fh (Strix 1).
1236 // Models 30h-37h (Strix 2).
1237 // Models 38h-3Fh (Strix 3).
1238 // Models 40h-4Fh (Granite Ridge).
1239 // Models 50h-5Fh (Weisshorn).
1240 // Models 60h-6Fh (Krackan1).
1241 // Models 70h-77h (Sarlak).
1242 CPU = "znver5";
1243 *Subtype = X86::AMDFAM1AH_ZNVER5;
1244 break; // "znver5"
1246 break;
1248 default:
1249 break; // Unknown AMD CPU.
1252 return CPU;
1255 #undef testFeature
1257 static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
1258 unsigned *Features) {
1259 unsigned EAX, EBX;
1261 auto setFeature = [&](unsigned F) {
1262 Features[F / 32] |= 1U << (F % 32);
1265 if ((EDX >> 15) & 1)
1266 setFeature(X86::FEATURE_CMOV);
1267 if ((EDX >> 23) & 1)
1268 setFeature(X86::FEATURE_MMX);
1269 if ((EDX >> 25) & 1)
1270 setFeature(X86::FEATURE_SSE);
1271 if ((EDX >> 26) & 1)
1272 setFeature(X86::FEATURE_SSE2);
1274 if ((ECX >> 0) & 1)
1275 setFeature(X86::FEATURE_SSE3);
1276 if ((ECX >> 1) & 1)
1277 setFeature(X86::FEATURE_PCLMUL);
1278 if ((ECX >> 9) & 1)
1279 setFeature(X86::FEATURE_SSSE3);
1280 if ((ECX >> 12) & 1)
1281 setFeature(X86::FEATURE_FMA);
1282 if ((ECX >> 19) & 1)
1283 setFeature(X86::FEATURE_SSE4_1);
1284 if ((ECX >> 20) & 1) {
1285 setFeature(X86::FEATURE_SSE4_2);
1286 setFeature(X86::FEATURE_CRC32);
1288 if ((ECX >> 23) & 1)
1289 setFeature(X86::FEATURE_POPCNT);
1290 if ((ECX >> 25) & 1)
1291 setFeature(X86::FEATURE_AES);
1293 if ((ECX >> 22) & 1)
1294 setFeature(X86::FEATURE_MOVBE);
1296 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1297 // indicates that the AVX registers will be saved and restored on context
1298 // switch, then we have full AVX support.
1299 const unsigned AVXBits = (1 << 27) | (1 << 28);
1300 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
1301 ((EAX & 0x6) == 0x6);
1302 #if defined(__APPLE__)
1303 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
1304 // save the AVX512 context if we use AVX512 instructions, even the bit is not
1305 // set right now.
1306 bool HasAVX512Save = true;
1307 #else
1308 // AVX512 requires additional context to be saved by the OS.
1309 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
1310 #endif
1312 if (HasAVX)
1313 setFeature(X86::FEATURE_AVX);
1315 bool HasLeaf7 =
1316 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1318 if (HasLeaf7 && ((EBX >> 3) & 1))
1319 setFeature(X86::FEATURE_BMI);
1320 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
1321 setFeature(X86::FEATURE_AVX2);
1322 if (HasLeaf7 && ((EBX >> 8) & 1))
1323 setFeature(X86::FEATURE_BMI2);
1324 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) {
1325 setFeature(X86::FEATURE_AVX512F);
1326 setFeature(X86::FEATURE_EVEX512);
1328 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
1329 setFeature(X86::FEATURE_AVX512DQ);
1330 if (HasLeaf7 && ((EBX >> 19) & 1))
1331 setFeature(X86::FEATURE_ADX);
1332 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
1333 setFeature(X86::FEATURE_AVX512IFMA);
1334 if (HasLeaf7 && ((EBX >> 23) & 1))
1335 setFeature(X86::FEATURE_CLFLUSHOPT);
1336 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
1337 setFeature(X86::FEATURE_AVX512CD);
1338 if (HasLeaf7 && ((EBX >> 29) & 1))
1339 setFeature(X86::FEATURE_SHA);
1340 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
1341 setFeature(X86::FEATURE_AVX512BW);
1342 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
1343 setFeature(X86::FEATURE_AVX512VL);
1345 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
1346 setFeature(X86::FEATURE_AVX512VBMI);
1347 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
1348 setFeature(X86::FEATURE_AVX512VBMI2);
1349 if (HasLeaf7 && ((ECX >> 8) & 1))
1350 setFeature(X86::FEATURE_GFNI);
1351 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
1352 setFeature(X86::FEATURE_VPCLMULQDQ);
1353 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
1354 setFeature(X86::FEATURE_AVX512VNNI);
1355 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
1356 setFeature(X86::FEATURE_AVX512BITALG);
1357 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
1358 setFeature(X86::FEATURE_AVX512VPOPCNTDQ);
1360 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
1361 setFeature(X86::FEATURE_AVX5124VNNIW);
1362 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
1363 setFeature(X86::FEATURE_AVX5124FMAPS);
1364 if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
1365 setFeature(X86::FEATURE_AVX512VP2INTERSECT);
1367 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1368 // return all 0s for invalid subleaves so check the limit.
1369 bool HasLeaf7Subleaf1 =
1370 HasLeaf7 && EAX >= 1 &&
1371 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1372 if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
1373 setFeature(X86::FEATURE_AVX512BF16);
1375 unsigned MaxExtLevel;
1376 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1378 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1379 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1380 if (HasExtLeaf1 && ((ECX >> 6) & 1))
1381 setFeature(X86::FEATURE_SSE4_A);
1382 if (HasExtLeaf1 && ((ECX >> 11) & 1))
1383 setFeature(X86::FEATURE_XOP);
1384 if (HasExtLeaf1 && ((ECX >> 16) & 1))
1385 setFeature(X86::FEATURE_FMA4);
1387 if (HasExtLeaf1 && ((EDX >> 29) & 1))
1388 setFeature(X86::FEATURE_64BIT);
1391 StringRef sys::getHostCPUName() {
1392 unsigned MaxLeaf = 0;
1393 const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
1394 if (Vendor == VendorSignatures::UNKNOWN)
1395 return "generic";
1397 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1398 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
1400 unsigned Family = 0, Model = 0;
1401 unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0};
1402 detectX86FamilyModel(EAX, &Family, &Model);
1403 getAvailableFeatures(ECX, EDX, MaxLeaf, Features);
1405 // These aren't consumed in this file, but we try to keep some source code the
1406 // same or similar to compiler-rt.
1407 unsigned Type = 0;
1408 unsigned Subtype = 0;
1410 StringRef CPU;
1412 if (Vendor == VendorSignatures::GENUINE_INTEL) {
1413 CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
1414 &Subtype);
1415 } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
1416 CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
1417 &Subtype);
1420 if (!CPU.empty())
1421 return CPU;
1423 return "generic";
1426 #elif defined(__APPLE__) && defined(__powerpc__)
1427 StringRef sys::getHostCPUName() {
1428 host_basic_info_data_t hostInfo;
1429 mach_msg_type_number_t infoCount;
1431 infoCount = HOST_BASIC_INFO_COUNT;
1432 mach_port_t hostPort = mach_host_self();
1433 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1434 &infoCount);
1435 mach_port_deallocate(mach_task_self(), hostPort);
1437 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
1438 return "generic";
1440 switch (hostInfo.cpu_subtype) {
1441 case CPU_SUBTYPE_POWERPC_601:
1442 return "601";
1443 case CPU_SUBTYPE_POWERPC_602:
1444 return "602";
1445 case CPU_SUBTYPE_POWERPC_603:
1446 return "603";
1447 case CPU_SUBTYPE_POWERPC_603e:
1448 return "603e";
1449 case CPU_SUBTYPE_POWERPC_603ev:
1450 return "603ev";
1451 case CPU_SUBTYPE_POWERPC_604:
1452 return "604";
1453 case CPU_SUBTYPE_POWERPC_604e:
1454 return "604e";
1455 case CPU_SUBTYPE_POWERPC_620:
1456 return "620";
1457 case CPU_SUBTYPE_POWERPC_750:
1458 return "750";
1459 case CPU_SUBTYPE_POWERPC_7400:
1460 return "7400";
1461 case CPU_SUBTYPE_POWERPC_7450:
1462 return "7450";
1463 case CPU_SUBTYPE_POWERPC_970:
1464 return "970";
1465 default:;
1468 return "generic";
1470 #elif defined(__linux__) && defined(__powerpc__)
1471 StringRef sys::getHostCPUName() {
1472 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1473 StringRef Content = P ? P->getBuffer() : "";
1474 return detail::getHostCPUNameForPowerPC(Content);
1476 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1477 StringRef sys::getHostCPUName() {
1478 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1479 StringRef Content = P ? P->getBuffer() : "";
1480 return detail::getHostCPUNameForARM(Content);
1482 #elif defined(__linux__) && defined(__s390x__)
1483 StringRef sys::getHostCPUName() {
1484 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1485 StringRef Content = P ? P->getBuffer() : "";
1486 return detail::getHostCPUNameForS390x(Content);
1488 #elif defined(__MVS__)
1489 StringRef sys::getHostCPUName() {
1490 // Get pointer to Communications Vector Table (CVT).
1491 // The pointer is located at offset 16 of the Prefixed Save Area (PSA).
1492 // It is stored as 31 bit pointer and will be zero-extended to 64 bit.
1493 int *StartToCVTOffset = reinterpret_cast<int *>(0x10);
1494 // Since its stored as a 31-bit pointer, get the 4 bytes from the start
1495 // of address.
1496 int ReadValue = *StartToCVTOffset;
1497 // Explicitly clear the high order bit.
1498 ReadValue = (ReadValue & 0x7FFFFFFF);
1499 char *CVT = reinterpret_cast<char *>(ReadValue);
1500 // The model number is located in the CVT prefix at offset -6 and stored as
1501 // signless packed decimal.
1502 uint16_t Id = *(uint16_t *)&CVT[-6];
1503 // Convert number to integer.
1504 Id = decodePackedBCD<uint16_t>(Id, false);
1505 // Check for vector support. It's stored in field CVTFLAG5 (offset 244),
1506 // bit CVTVEF (X'80'). The facilities list is part of the PSA but the vector
1507 // extension can only be used if bit CVTVEF is on.
1508 bool HaveVectorSupport = CVT[244] & 0x80;
1509 return getCPUNameFromS390Model(Id, HaveVectorSupport);
1511 #elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__))
1512 // Copied from <mach/machine.h> in the macOS SDK.
1514 // Also available here, though usually not as up-to-date:
1515 // https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/mach/machine.h#L403-L452.
1516 #define CPUFAMILY_UNKNOWN 0
1517 #define CPUFAMILY_ARM_9 0xe73283ae
1518 #define CPUFAMILY_ARM_11 0x8ff620d8
1519 #define CPUFAMILY_ARM_XSCALE 0x53b005f5
1520 #define CPUFAMILY_ARM_12 0xbd1b0ae9
1521 #define CPUFAMILY_ARM_13 0x0cc90e64
1522 #define CPUFAMILY_ARM_14 0x96077ef1
1523 #define CPUFAMILY_ARM_15 0xa8511bca
1524 #define CPUFAMILY_ARM_SWIFT 0x1e2d6381
1525 #define CPUFAMILY_ARM_CYCLONE 0x37a09642
1526 #define CPUFAMILY_ARM_TYPHOON 0x2c91a47e
1527 #define CPUFAMILY_ARM_TWISTER 0x92fb37c8
1528 #define CPUFAMILY_ARM_HURRICANE 0x67ceee93
1529 #define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6
1530 #define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f
1531 #define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2
1532 #define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3
1533 #define CPUFAMILY_ARM_BLIZZARD_AVALANCHE 0xda33d83d
1534 #define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea
1535 #define CPUFAMILY_ARM_IBIZA 0xfa33415e
1536 #define CPUFAMILY_ARM_PALMA 0x72015832
1537 #define CPUFAMILY_ARM_COLL 0x2876f5b5
1538 #define CPUFAMILY_ARM_LOBOS 0x5f4dea93
1539 #define CPUFAMILY_ARM_DONAN 0x6f5129ac
1540 #define CPUFAMILY_ARM_BRAVA 0x17d5b93a
1541 #define CPUFAMILY_ARM_TAHITI 0x75d4acb9
1542 #define CPUFAMILY_ARM_TUPAI 0x204526d0
1544 StringRef sys::getHostCPUName() {
1545 uint32_t Family;
1546 size_t Length = sizeof(Family);
1547 sysctlbyname("hw.cpufamily", &Family, &Length, NULL, 0);
1549 // This is found by testing on actual hardware, and by looking at:
1550 // https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/arm/cpuid.c#L109-L231.
1552 // Another great resource is
1553 // https://github.com/AsahiLinux/docs/wiki/Codenames.
1555 // NOTE: We choose to return `apple-mX` instead of `apple-aX`, since the M1,
1556 // M2, M3 etc. aliases are more widely known to users than A14, A15, A16 etc.
1557 // (and this code is basically only used on host macOS anyways).
1558 switch (Family) {
1559 case CPUFAMILY_UNKNOWN:
1560 return "generic";
1561 case CPUFAMILY_ARM_9:
1562 return "arm920t"; // or arm926ej-s
1563 case CPUFAMILY_ARM_11:
1564 return "arm1136jf-s";
1565 case CPUFAMILY_ARM_XSCALE:
1566 return "xscale";
1567 case CPUFAMILY_ARM_12: // Seems unused by the kernel
1568 return "generic";
1569 case CPUFAMILY_ARM_13:
1570 return "cortex-a8";
1571 case CPUFAMILY_ARM_14:
1572 return "cortex-a9";
1573 case CPUFAMILY_ARM_15:
1574 return "cortex-a7";
1575 case CPUFAMILY_ARM_SWIFT:
1576 return "swift";
1577 case CPUFAMILY_ARM_CYCLONE:
1578 return "apple-a7";
1579 case CPUFAMILY_ARM_TYPHOON:
1580 return "apple-a8";
1581 case CPUFAMILY_ARM_TWISTER:
1582 return "apple-a9";
1583 case CPUFAMILY_ARM_HURRICANE:
1584 return "apple-a10";
1585 case CPUFAMILY_ARM_MONSOON_MISTRAL:
1586 return "apple-a11";
1587 case CPUFAMILY_ARM_VORTEX_TEMPEST:
1588 return "apple-a12";
1589 case CPUFAMILY_ARM_LIGHTNING_THUNDER:
1590 return "apple-a13";
1591 case CPUFAMILY_ARM_FIRESTORM_ICESTORM: // A14 / M1
1592 return "apple-m1";
1593 case CPUFAMILY_ARM_BLIZZARD_AVALANCHE: // A15 / M2
1594 return "apple-m2";
1595 case CPUFAMILY_ARM_EVEREST_SAWTOOTH: // A16
1596 case CPUFAMILY_ARM_IBIZA: // M3
1597 case CPUFAMILY_ARM_PALMA: // M3 Max
1598 case CPUFAMILY_ARM_LOBOS: // M3 Pro
1599 return "apple-m3";
1600 case CPUFAMILY_ARM_COLL: // A17 Pro
1601 return "apple-a17";
1602 case CPUFAMILY_ARM_DONAN: // M4
1603 case CPUFAMILY_ARM_BRAVA: // M4 Max
1604 case CPUFAMILY_ARM_TAHITI: // A18 Pro
1605 case CPUFAMILY_ARM_TUPAI: // A18
1606 return "apple-m4";
1607 default:
1608 // Default to the newest CPU we know about.
1609 return "apple-m4";
1612 #elif defined(_AIX)
1613 StringRef sys::getHostCPUName() {
1614 switch (_system_configuration.implementation) {
1615 case POWER_4:
1616 if (_system_configuration.version == PV_4_3)
1617 return "970";
1618 return "pwr4";
1619 case POWER_5:
1620 if (_system_configuration.version == PV_5)
1621 return "pwr5";
1622 return "pwr5x";
1623 case POWER_6:
1624 if (_system_configuration.version == PV_6_Compat)
1625 return "pwr6";
1626 return "pwr6x";
1627 case POWER_7:
1628 return "pwr7";
1629 case POWER_8:
1630 return "pwr8";
1631 case POWER_9:
1632 return "pwr9";
1633 // TODO: simplify this once the macro is available in all OS levels.
1634 #ifdef POWER_10
1635 case POWER_10:
1636 #else
1637 case 0x40000:
1638 #endif
1639 return "pwr10";
1640 #ifdef POWER_11
1641 case POWER_11:
1642 #else
1643 case 0x80000:
1644 #endif
1645 return "pwr11";
1646 default:
1647 return "generic";
1650 #elif defined(__loongarch__)
1651 StringRef sys::getHostCPUName() {
1652 // Use processor id to detect cpu name.
1653 uint32_t processor_id;
1654 __asm__("cpucfg %[prid], $zero\n\t" : [prid] "=r"(processor_id));
1655 // Refer PRID_SERIES_MASK in linux kernel: arch/loongarch/include/asm/cpu.h.
1656 switch (processor_id & 0xf000) {
1657 case 0xc000: // Loongson 64bit, 4-issue
1658 return "la464";
1659 case 0xd000: // Loongson 64bit, 6-issue
1660 return "la664";
1661 // TODO: Others.
1662 default:
1663 break;
1665 return "generic";
1667 #elif defined(__riscv)
1668 StringRef sys::getHostCPUName() {
1669 #if defined(__linux__)
1670 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1671 StringRef Content = P ? P->getBuffer() : "";
1672 StringRef Name = detail::getHostCPUNameForRISCV(Content);
1673 if (!Name.empty())
1674 return Name;
1675 #endif
1676 #if __riscv_xlen == 64
1677 return "generic-rv64";
1678 #elif __riscv_xlen == 32
1679 return "generic-rv32";
1680 #else
1681 #error "Unhandled value of __riscv_xlen"
1682 #endif
1684 #elif defined(__sparc__)
1685 #if defined(__linux__)
1686 StringRef sys::detail::getHostCPUNameForSPARC(StringRef ProcCpuinfoContent) {
1687 SmallVector<StringRef> Lines;
1688 ProcCpuinfoContent.split(Lines, '\n');
1690 // Look for cpu line to determine cpu name
1691 StringRef Cpu;
1692 for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
1693 if (Lines[I].starts_with("cpu")) {
1694 Cpu = Lines[I].substr(5).ltrim("\t :");
1695 break;
1699 return StringSwitch<const char *>(Cpu)
1700 .StartsWith("SuperSparc", "supersparc")
1701 .StartsWith("HyperSparc", "hypersparc")
1702 .StartsWith("SpitFire", "ultrasparc")
1703 .StartsWith("BlackBird", "ultrasparc")
1704 .StartsWith("Sabre", " ultrasparc")
1705 .StartsWith("Hummingbird", "ultrasparc")
1706 .StartsWith("Cheetah", "ultrasparc3")
1707 .StartsWith("Jalapeno", "ultrasparc3")
1708 .StartsWith("Jaguar", "ultrasparc3")
1709 .StartsWith("Panther", "ultrasparc3")
1710 .StartsWith("Serrano", "ultrasparc3")
1711 .StartsWith("UltraSparc T1", "niagara")
1712 .StartsWith("UltraSparc T2", "niagara2")
1713 .StartsWith("UltraSparc T3", "niagara3")
1714 .StartsWith("UltraSparc T4", "niagara4")
1715 .StartsWith("UltraSparc T5", "niagara4")
1716 .StartsWith("LEON", "leon3")
1717 // niagara7/m8 not supported by LLVM yet.
1718 .StartsWith("SPARC-M7", "niagara4" /* "niagara7" */)
1719 .StartsWith("SPARC-S7", "niagara4" /* "niagara7" */)
1720 .StartsWith("SPARC-M8", "niagara4" /* "m8" */)
1721 .Default("generic");
1723 #endif
1725 StringRef sys::getHostCPUName() {
1726 #if defined(__linux__)
1727 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
1728 StringRef Content = P ? P->getBuffer() : "";
1729 return detail::getHostCPUNameForSPARC(Content);
1730 #elif defined(__sun__) && defined(__svr4__)
1731 char *buf = NULL;
1732 kstat_ctl_t *kc;
1733 kstat_t *ksp;
1734 kstat_named_t *brand = NULL;
1736 kc = kstat_open();
1737 if (kc != NULL) {
1738 ksp = kstat_lookup(kc, const_cast<char *>("cpu_info"), -1, NULL);
1739 if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1 &&
1740 ksp->ks_type == KSTAT_TYPE_NAMED)
1741 brand =
1742 (kstat_named_t *)kstat_data_lookup(ksp, const_cast<char *>("brand"));
1743 if (brand != NULL && brand->data_type == KSTAT_DATA_STRING)
1744 buf = KSTAT_NAMED_STR_PTR(brand);
1746 kstat_close(kc);
1748 return StringSwitch<const char *>(buf)
1749 .Case("TMS390S10", "supersparc") // Texas Instruments microSPARC I
1750 .Case("TMS390Z50", "supersparc") // Texas Instruments SuperSPARC I
1751 .Case("TMS390Z55",
1752 "supersparc") // Texas Instruments SuperSPARC I with SuperCache
1753 .Case("MB86904", "supersparc") // Fujitsu microSPARC II
1754 .Case("MB86907", "supersparc") // Fujitsu TurboSPARC
1755 .Case("RT623", "hypersparc") // Ross hyperSPARC
1756 .Case("RT625", "hypersparc")
1757 .Case("RT626", "hypersparc")
1758 .Case("UltraSPARC-I", "ultrasparc")
1759 .Case("UltraSPARC-II", "ultrasparc")
1760 .Case("UltraSPARC-IIe", "ultrasparc")
1761 .Case("UltraSPARC-IIi", "ultrasparc")
1762 .Case("SPARC64-III", "ultrasparc")
1763 .Case("SPARC64-IV", "ultrasparc")
1764 .Case("UltraSPARC-III", "ultrasparc3")
1765 .Case("UltraSPARC-III+", "ultrasparc3")
1766 .Case("UltraSPARC-IIIi", "ultrasparc3")
1767 .Case("UltraSPARC-IIIi+", "ultrasparc3")
1768 .Case("UltraSPARC-IV", "ultrasparc3")
1769 .Case("UltraSPARC-IV+", "ultrasparc3")
1770 .Case("SPARC64-V", "ultrasparc3")
1771 .Case("SPARC64-VI", "ultrasparc3")
1772 .Case("SPARC64-VII", "ultrasparc3")
1773 .Case("UltraSPARC-T1", "niagara")
1774 .Case("UltraSPARC-T2", "niagara2")
1775 .Case("UltraSPARC-T2", "niagara2")
1776 .Case("UltraSPARC-T2+", "niagara2")
1777 .Case("SPARC-T3", "niagara3")
1778 .Case("SPARC-T4", "niagara4")
1779 .Case("SPARC-T5", "niagara4")
1780 // niagara7/m8 not supported by LLVM yet.
1781 .Case("SPARC-M7", "niagara4" /* "niagara7" */)
1782 .Case("SPARC-S7", "niagara4" /* "niagara7" */)
1783 .Case("SPARC-M8", "niagara4" /* "m8" */)
1784 .Default("generic");
1785 #else
1786 return "generic";
1787 #endif
1789 #else
1790 StringRef sys::getHostCPUName() { return "generic"; }
1791 namespace llvm {
1792 namespace sys {
1793 namespace detail {
1794 namespace x86 {
1796 VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
1797 return VendorSignatures::UNKNOWN;
1800 } // namespace x86
1801 } // namespace detail
1802 } // namespace sys
1803 } // namespace llvm
1804 #endif
1806 #if defined(__i386__) || defined(_M_IX86) || \
1807 defined(__x86_64__) || defined(_M_X64)
1808 const StringMap<bool> sys::getHostCPUFeatures() {
1809 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1810 unsigned MaxLevel;
1811 StringMap<bool> Features;
1813 if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1)
1814 return Features;
1816 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1818 Features["cx8"] = (EDX >> 8) & 1;
1819 Features["cmov"] = (EDX >> 15) & 1;
1820 Features["mmx"] = (EDX >> 23) & 1;
1821 Features["fxsr"] = (EDX >> 24) & 1;
1822 Features["sse"] = (EDX >> 25) & 1;
1823 Features["sse2"] = (EDX >> 26) & 1;
1825 Features["sse3"] = (ECX >> 0) & 1;
1826 Features["pclmul"] = (ECX >> 1) & 1;
1827 Features["ssse3"] = (ECX >> 9) & 1;
1828 Features["cx16"] = (ECX >> 13) & 1;
1829 Features["sse4.1"] = (ECX >> 19) & 1;
1830 Features["sse4.2"] = (ECX >> 20) & 1;
1831 Features["crc32"] = Features["sse4.2"];
1832 Features["movbe"] = (ECX >> 22) & 1;
1833 Features["popcnt"] = (ECX >> 23) & 1;
1834 Features["aes"] = (ECX >> 25) & 1;
1835 Features["rdrnd"] = (ECX >> 30) & 1;
1837 // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
1838 // indicates that the AVX registers will be saved and restored on context
1839 // switch, then we have full AVX support.
1840 bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX);
1841 bool HasAVXSave = HasXSave && ((ECX >> 28) & 1) && ((EAX & 0x6) == 0x6);
1842 #if defined(__APPLE__)
1843 // Darwin lazily saves the AVX512 context on first use: trust that the OS will
1844 // save the AVX512 context if we use AVX512 instructions, even the bit is not
1845 // set right now.
1846 bool HasAVX512Save = true;
1847 #else
1848 // AVX512 requires additional context to be saved by the OS.
1849 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
1850 #endif
1851 // AMX requires additional context to be saved by the OS.
1852 const unsigned AMXBits = (1 << 17) | (1 << 18);
1853 bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits);
1855 Features["avx"] = HasAVXSave;
1856 Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave;
1857 // Only enable XSAVE if OS has enabled support for saving YMM state.
1858 Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave;
1859 Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave;
1861 unsigned MaxExtLevel;
1862 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1864 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1865 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1866 Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1);
1867 Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1868 Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1869 Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1870 Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
1871 Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
1872 Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1873 Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
1874 Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
1876 Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1);
1878 // Miscellaneous memory related features, detected by
1879 // using the 0x80000008 leaf of the CPUID instruction
1880 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
1881 !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
1882 Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1);
1883 Features["rdpru"] = HasExtLeaf8 && ((EBX >> 4) & 1);
1884 Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1);
1886 bool HasLeaf7 =
1887 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1889 Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
1890 Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
1891 Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
1892 // AVX2 is only supported if we have the OS save support from AVX.
1893 Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave;
1894 Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
1895 Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
1896 Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
1897 // AVX512 is only supported if the OS supports the context save for it.
1898 Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
1899 if (Features["avx512f"])
1900 Features["evex512"] = true;
1901 Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
1902 Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
1903 Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1);
1904 Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
1905 Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
1906 Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
1907 Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
1908 Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1);
1909 Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
1910 Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
1912 Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
1913 Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1);
1914 Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1);
1915 Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save;
1916 Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1);
1917 Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1);
1918 Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave;
1919 Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave;
1920 Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save;
1921 Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
1922 Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
1923 Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1);
1924 Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker
1925 Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1);
1926 Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
1927 Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
1928 Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1);
1930 Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1);
1931 Features["avx512vp2intersect"] =
1932 HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save;
1933 Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1);
1934 Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1);
1935 // There are two CPUID leafs which information associated with the pconfig
1936 // instruction:
1937 // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
1938 // bit of EDX), while the EAX=0x1b leaf returns information on the
1939 // availability of specific pconfig leafs.
1940 // The target feature here only refers to the the first of these two.
1941 // Users might need to check for the availability of specific pconfig
1942 // leaves using cpuid, since that information is ignored while
1943 // detecting features using the "-march=native" flag.
1944 // For more info, see X86 ISA docs.
1945 Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1);
1946 Features["amx-bf16"] = HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave;
1947 Features["avx512fp16"] = HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save;
1948 Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave;
1949 Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave;
1950 // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1951 // return all 0s for invalid subleaves so check the limit.
1952 bool HasLeaf7Subleaf1 =
1953 HasLeaf7 && EAX >= 1 &&
1954 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1955 Features["sha512"] = HasLeaf7Subleaf1 && ((EAX >> 0) & 1);
1956 Features["sm3"] = HasLeaf7Subleaf1 && ((EAX >> 1) & 1);
1957 Features["sm4"] = HasLeaf7Subleaf1 && ((EAX >> 2) & 1);
1958 Features["raoint"] = HasLeaf7Subleaf1 && ((EAX >> 3) & 1);
1959 Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave;
1960 Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save;
1961 Features["amx-fp16"] = HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave;
1962 Features["cmpccxadd"] = HasLeaf7Subleaf1 && ((EAX >> 7) & 1);
1963 Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1);
1964 Features["avxifma"] = HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave;
1965 Features["movrs"] = HasLeaf7Subleaf1 && ((EAX >> 31) & 1);
1966 Features["avxvnniint8"] = HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave;
1967 Features["avxneconvert"] = HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave;
1968 Features["amx-complex"] = HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave;
1969 Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave;
1970 Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1);
1971 Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1);
1972 bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1);
1973 bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1);
1974 Features["egpr"] = HasAPXF;
1975 Features["push2pop2"] = HasAPXF;
1976 Features["ppx"] = HasAPXF;
1977 Features["ndd"] = HasAPXF;
1978 Features["ccmp"] = HasAPXF;
1979 Features["nf"] = HasAPXF;
1980 Features["cf"] = HasAPXF;
1981 Features["zu"] = HasAPXF;
1983 bool HasLeafD = MaxLevel >= 0xd &&
1984 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
1986 // Only enable XSAVE if OS has enabled support for saving YMM state.
1987 Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave;
1988 Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave;
1989 Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave;
1991 bool HasLeaf14 = MaxLevel >= 0x14 &&
1992 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
1994 Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1);
1996 bool HasLeaf19 =
1997 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
1998 Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1);
2000 bool HasLeaf1E = MaxLevel >= 0x1e &&
2001 !getX86CpuIDAndInfoEx(0x1e, 0x1, &EAX, &EBX, &ECX, &EDX);
2002 Features["amx-fp8"] = HasLeaf1E && ((EAX >> 4) & 1) && HasAMXSave;
2003 Features["amx-transpose"] = HasLeaf1E && ((EAX >> 5) & 1) && HasAMXSave;
2004 Features["amx-tf32"] = HasLeaf1E && ((EAX >> 6) & 1) && HasAMXSave;
2005 Features["amx-avx512"] = HasLeaf1E && ((EAX >> 7) & 1) && HasAMXSave;
2006 Features["amx-movrs"] = HasLeaf1E && ((EAX >> 8) & 1) && HasAMXSave;
2008 bool HasLeaf24 =
2009 MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX);
2011 int AVX10Ver = HasLeaf24 && (EBX & 0xff);
2012 int Has512Len = HasLeaf24 && ((EBX >> 18) & 1);
2013 Features["avx10.1-256"] = HasAVX10 && AVX10Ver >= 1;
2014 Features["avx10.1-512"] = HasAVX10 && AVX10Ver >= 1 && Has512Len;
2015 Features["avx10.2-256"] = HasAVX10 && AVX10Ver >= 2;
2016 Features["avx10.2-512"] = HasAVX10 && AVX10Ver >= 2 && Has512Len;
2018 return Features;
2020 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
2021 const StringMap<bool> sys::getHostCPUFeatures() {
2022 StringMap<bool> Features;
2023 std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
2024 if (!P)
2025 return Features;
2027 SmallVector<StringRef, 32> Lines;
2028 P->getBuffer().split(Lines, '\n');
2030 SmallVector<StringRef, 32> CPUFeatures;
2032 // Look for the CPU features.
2033 for (unsigned I = 0, E = Lines.size(); I != E; ++I)
2034 if (Lines[I].starts_with("Features")) {
2035 Lines[I].split(CPUFeatures, ' ');
2036 break;
2039 #if defined(__aarch64__)
2040 // All of these are "crypto" features, but we must sift out actual features
2041 // as the former meaning of "crypto" as a single feature is no more.
2042 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
2043 uint32_t crypto = 0;
2044 #endif
2046 for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
2047 StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
2048 #if defined(__aarch64__)
2049 .Case("asimd", "neon")
2050 .Case("fp", "fp-armv8")
2051 .Case("crc32", "crc")
2052 .Case("atomics", "lse")
2053 .Case("sve", "sve")
2054 .Case("sve2", "sve2")
2055 #else
2056 .Case("half", "fp16")
2057 .Case("neon", "neon")
2058 .Case("vfpv3", "vfp3")
2059 .Case("vfpv3d16", "vfp3d16")
2060 .Case("vfpv4", "vfp4")
2061 .Case("idiva", "hwdiv-arm")
2062 .Case("idivt", "hwdiv")
2063 #endif
2064 .Default("");
2066 #if defined(__aarch64__)
2067 // We need to check crypto separately since we need all of the crypto
2068 // extensions to enable the subtarget feature
2069 if (CPUFeatures[I] == "aes")
2070 crypto |= CAP_AES;
2071 else if (CPUFeatures[I] == "pmull")
2072 crypto |= CAP_PMULL;
2073 else if (CPUFeatures[I] == "sha1")
2074 crypto |= CAP_SHA1;
2075 else if (CPUFeatures[I] == "sha2")
2076 crypto |= CAP_SHA2;
2077 #endif
2079 if (LLVMFeatureStr != "")
2080 Features[LLVMFeatureStr] = true;
2083 #if defined(__aarch64__)
2084 // LLVM has decided some AArch64 CPUs have all the instructions they _may_
2085 // have, as opposed to all the instructions they _must_ have, so allow runtime
2086 // information to correct us on that.
2087 uint32_t Aes = CAP_AES | CAP_PMULL;
2088 uint32_t Sha2 = CAP_SHA1 | CAP_SHA2;
2089 Features["aes"] = (crypto & Aes) == Aes;
2090 Features["sha2"] = (crypto & Sha2) == Sha2;
2091 #endif
2093 return Features;
2095 #elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64))
2096 const StringMap<bool> sys::getHostCPUFeatures() {
2097 StringMap<bool> Features;
2099 // If we're asking the OS at runtime, believe what the OS says
2100 Features["neon"] =
2101 IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE);
2102 Features["crc"] =
2103 IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
2105 // Avoid inferring "crypto" means more than the traditional AES + SHA2
2106 bool TradCrypto =
2107 IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE);
2108 Features["aes"] = TradCrypto;
2109 Features["sha2"] = TradCrypto;
2111 return Features;
2113 #elif defined(__linux__) && defined(__loongarch__)
2114 #include <sys/auxv.h>
2115 const StringMap<bool> sys::getHostCPUFeatures() {
2116 unsigned long hwcap = getauxval(AT_HWCAP);
2117 bool HasFPU = hwcap & (1UL << 3); // HWCAP_LOONGARCH_FPU
2118 uint32_t cpucfg2 = 0x2, cpucfg3 = 0x3;
2119 __asm__("cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2] "+r"(cpucfg2));
2120 __asm__("cpucfg %[cpucfg3], %[cpucfg3]\n\t" : [cpucfg3] "+r"(cpucfg3));
2122 StringMap<bool> Features;
2124 Features["f"] = HasFPU && (cpucfg2 & (1U << 1)); // CPUCFG.2.FP_SP
2125 Features["d"] = HasFPU && (cpucfg2 & (1U << 2)); // CPUCFG.2.FP_DP
2127 Features["lsx"] = hwcap & (1UL << 4); // HWCAP_LOONGARCH_LSX
2128 Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX
2129 Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ
2131 Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE
2132 Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32
2133 Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH
2134 Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS
2136 Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA
2138 // TODO: Need to complete.
2139 // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL
2140 // Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ
2141 return Features;
2143 #elif defined(__linux__) && defined(__riscv)
2144 // struct riscv_hwprobe
2145 struct RISCVHwProbe {
2146 int64_t Key;
2147 uint64_t Value;
2149 const StringMap<bool> sys::getHostCPUFeatures() {
2150 RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
2151 {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0},
2152 {/*RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF=*/9, 0}};
2153 int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
2154 /*pair_count=*/std::size(Query), /*cpu_count=*/0,
2155 /*cpus=*/0, /*flags=*/0);
2156 if (Ret != 0)
2157 return {};
2159 StringMap<bool> Features;
2160 uint64_t BaseMask = Query[0].Value;
2161 // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set.
2162 if (BaseMask & 1) {
2163 Features["i"] = true;
2164 Features["m"] = true;
2165 Features["a"] = true;
2168 uint64_t ExtMask = Query[1].Value;
2169 Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
2170 Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD
2171 Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C
2172 Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V
2173 Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA
2174 Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB
2175 Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS
2176 Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ
2177 Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC
2178 Features["zbkb"] = ExtMask & (1 << 8); // RISCV_HWPROBE_EXT_ZBKB
2179 Features["zbkc"] = ExtMask & (1 << 9); // RISCV_HWPROBE_EXT_ZBKC
2180 Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX
2181 Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND
2182 Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE
2183 Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH
2184 Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED
2185 Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH
2186 Features["zkt"] = ExtMask & (1 << 16); // RISCV_HWPROBE_EXT_ZKT
2187 Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB
2188 Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC
2189 Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB
2190 Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG
2191 Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED
2192 Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA
2193 Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB
2194 Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED
2195 Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH
2196 Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT
2197 Features["zfh"] = ExtMask & (1 << 27); // RISCV_HWPROBE_EXT_ZFH
2198 Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN
2199 Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL
2200 Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH
2201 Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
2202 Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA
2203 Features["ztso"] = ExtMask & (1ULL << 33); // RISCV_HWPROBE_EXT_ZTSO
2204 Features["zacas"] = ExtMask & (1ULL << 34); // RISCV_HWPROBE_EXT_ZACAS
2205 Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
2206 Features["zihintpause"] =
2207 ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
2208 Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X
2209 Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F
2210 Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X
2211 Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F
2212 Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D
2213 Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP
2214 Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA
2215 Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB
2216 Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD
2217 Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF
2218 Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP
2219 Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS
2221 // Check whether the processor supports fast misaligned scalar memory access.
2222 // NOTE: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF is only available on
2223 // Linux 6.11 or later. If it is not recognized, the key field will be cleared
2224 // to -1.
2225 if (Query[2].Key != -1 &&
2226 Query[2].Value == /*RISCV_HWPROBE_MISALIGNED_SCALAR_FAST=*/3)
2227 Features["unaligned-scalar-mem"] = true;
2229 return Features;
2231 #else
2232 const StringMap<bool> sys::getHostCPUFeatures() { return {}; }
2233 #endif
2235 #if __APPLE__
2236 /// \returns the \p triple, but with the Host's arch spliced in.
2237 static Triple withHostArch(Triple T) {
2238 #if defined(__arm__)
2239 T.setArch(Triple::arm);
2240 T.setArchName("arm");
2241 #elif defined(__arm64e__)
2242 T.setArch(Triple::aarch64, Triple::AArch64SubArch_arm64e);
2243 T.setArchName("arm64e");
2244 #elif defined(__aarch64__)
2245 T.setArch(Triple::aarch64);
2246 T.setArchName("arm64");
2247 #elif defined(__x86_64h__)
2248 T.setArch(Triple::x86_64);
2249 T.setArchName("x86_64h");
2250 #elif defined(__x86_64__)
2251 T.setArch(Triple::x86_64);
2252 T.setArchName("x86_64");
2253 #elif defined(__i386__)
2254 T.setArch(Triple::x86);
2255 T.setArchName("i386");
2256 #elif defined(__powerpc__)
2257 T.setArch(Triple::ppc);
2258 T.setArchName("powerpc");
2259 #else
2260 # error "Unimplemented host arch fixup"
2261 #endif
2262 return T;
2264 #endif
2266 std::string sys::getProcessTriple() {
2267 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
2268 Triple PT(Triple::normalize(TargetTripleString));
2270 #if __APPLE__
2271 /// In Universal builds, LLVM_HOST_TRIPLE will have the wrong arch in one of
2272 /// the slices. This fixes that up.
2273 PT = withHostArch(PT);
2274 #endif
2276 if (sizeof(void *) == 8 && PT.isArch32Bit())
2277 PT = PT.get64BitArchVariant();
2278 if (sizeof(void *) == 4 && PT.isArch64Bit())
2279 PT = PT.get32BitArchVariant();
2281 return PT.str();
2284 void sys::printDefaultTargetAndDetectedCPU(raw_ostream &OS) {
2285 #if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
2286 std::string CPU = std::string(sys::getHostCPUName());
2287 if (CPU == "generic")
2288 CPU = "(unknown)";
2289 OS << " Default target: " << sys::getDefaultTargetTriple() << '\n'
2290 << " Host CPU: " << CPU << '\n';
2291 #endif