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