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