18#include "llvm/Config/llvm-config.h"
40#include <mach/host_info.h>
42#include <mach/mach_host.h>
43#include <mach/machine.h>
45#include <sys/sysctl.h>
48#include <sys/systemcfg.h>
50#if defined(__sun__) && defined(__svr4__)
54#define DEBUG_TYPE "host-detection"
64static std::unique_ptr<llvm::MemoryBuffer>
68 if (std::error_code EC = Text.getError()) {
70 <<
"/proc/cpuinfo: " << EC.message() <<
"\n";
73 return std::move(*Text);
80 const char *
generic =
"generic";
94 while (CIP < CPUInfoEnd && CPUStart ==
nullptr) {
95 if (CIP < CPUInfoEnd && *CIP ==
'\n')
98 if (CIP < CPUInfoEnd && *CIP ==
'c') {
100 if (CIP < CPUInfoEnd && *CIP ==
'p') {
102 if (CIP < CPUInfoEnd && *CIP ==
'u') {
104 while (CIP < CPUInfoEnd && (*CIP ==
' ' || *CIP ==
'\t'))
107 if (CIP < CPUInfoEnd && *CIP ==
':') {
109 while (CIP < CPUInfoEnd && (*CIP ==
' ' || *CIP ==
'\t'))
112 if (CIP < CPUInfoEnd) {
114 while (CIP < CPUInfoEnd && (*CIP !=
' ' && *CIP !=
'\t' &&
115 *CIP !=
',' && *CIP !=
'\n'))
117 CPULen = CIP - CPUStart;
124 if (CPUStart ==
nullptr)
125 while (CIP < CPUInfoEnd && *CIP !=
'\n')
129 if (CPUStart ==
nullptr)
133 .
Case(
"604e",
"604e")
135 .
Case(
"7400",
"7400")
136 .
Case(
"7410",
"7400")
137 .
Case(
"7447",
"7400")
138 .
Case(
"7455",
"7450")
140 .
Case(
"POWER4",
"970")
141 .
Case(
"PPC970FX",
"970")
142 .
Case(
"PPC970MP",
"970")
144 .
Case(
"POWER5",
"g5")
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")
166 ProcCpuinfoContent.
split(Lines,
"\n");
172 for (
unsigned I = 0, E = Lines.size();
I != E; ++
I) {
174 Implementer = Lines[
I].substr(15).ltrim(
"\t :");
176 Hardware = Lines[
I].substr(8).ltrim(
"\t :");
178 Part = Lines[
I].substr(8).ltrim(
"\t :");
181 if (Implementer ==
"0x41") {
194 .
Case(
"0x926",
"arm926ej-s")
195 .
Case(
"0xb02",
"mpcore")
196 .
Case(
"0xb36",
"arm1136j-s")
197 .
Case(
"0xb56",
"arm1156t2-s")
198 .
Case(
"0xb76",
"arm1176jz-s")
199 .
Case(
"0xc05",
"cortex-a5")
200 .
Case(
"0xc07",
"cortex-a7")
201 .
Case(
"0xc08",
"cortex-a8")
202 .
Case(
"0xc09",
"cortex-a9")
203 .
Case(
"0xc0f",
"cortex-a15")
204 .
Case(
"0xc0e",
"cortex-a17")
205 .
Case(
"0xc20",
"cortex-m0")
206 .
Case(
"0xc23",
"cortex-m3")
207 .
Case(
"0xc24",
"cortex-m4")
208 .
Case(
"0xc27",
"cortex-m7")
209 .
Case(
"0xd20",
"cortex-m23")
210 .
Case(
"0xd21",
"cortex-m33")
211 .
Case(
"0xd24",
"cortex-m52")
212 .
Case(
"0xd22",
"cortex-m55")
213 .
Case(
"0xd23",
"cortex-m85")
214 .
Case(
"0xc18",
"cortex-r8")
215 .
Case(
"0xd13",
"cortex-r52")
216 .
Case(
"0xd15",
"cortex-r82")
217 .
Case(
"0xd02",
"cortex-a34")
218 .
Case(
"0xd04",
"cortex-a35")
219 .
Case(
"0xd03",
"cortex-a53")
220 .
Case(
"0xd05",
"cortex-a55")
221 .
Case(
"0xd46",
"cortex-a510")
222 .
Case(
"0xd80",
"cortex-a520")
223 .
Case(
"0xd88",
"cortex-a520ae")
224 .
Case(
"0xd07",
"cortex-a57")
225 .
Case(
"0xd06",
"cortex-a65")
226 .
Case(
"0xd43",
"cortex-a65ae")
227 .
Case(
"0xd08",
"cortex-a72")
228 .
Case(
"0xd09",
"cortex-a73")
229 .
Case(
"0xd0a",
"cortex-a75")
230 .
Case(
"0xd0b",
"cortex-a76")
231 .
Case(
"0xd0e",
"cortex-a76ae")
232 .
Case(
"0xd0d",
"cortex-a77")
233 .
Case(
"0xd41",
"cortex-a78")
234 .
Case(
"0xd42",
"cortex-a78ae")
235 .
Case(
"0xd4b",
"cortex-a78c")
236 .
Case(
"0xd47",
"cortex-a710")
237 .
Case(
"0xd4d",
"cortex-a715")
238 .
Case(
"0xd81",
"cortex-a720")
239 .
Case(
"0xd89",
"cortex-a720ae")
240 .
Case(
"0xd44",
"cortex-x1")
241 .
Case(
"0xd4c",
"cortex-x1c")
242 .
Case(
"0xd48",
"cortex-x2")
243 .
Case(
"0xd4e",
"cortex-x3")
244 .
Case(
"0xd82",
"cortex-x4")
245 .
Case(
"0xd4a",
"neoverse-e1")
246 .
Case(
"0xd0c",
"neoverse-n1")
247 .
Case(
"0xd49",
"neoverse-n2")
248 .
Case(
"0xd40",
"neoverse-v1")
249 .
Case(
"0xd4f",
"neoverse-v2")
253 if (Implementer ==
"0x42" || Implementer ==
"0x43") {
255 .
Case(
"0x516",
"thunderx2t99")
256 .
Case(
"0x0516",
"thunderx2t99")
257 .
Case(
"0xaf",
"thunderx2t99")
258 .
Case(
"0x0af",
"thunderx2t99")
259 .
Case(
"0xa1",
"thunderxt88")
260 .
Case(
"0x0a1",
"thunderxt88")
264 if (Implementer ==
"0x46") {
266 .
Case(
"0x001",
"a64fx")
270 if (Implementer ==
"0x4e") {
272 .
Case(
"0x004",
"carmel")
276 if (Implementer ==
"0x48")
281 .
Case(
"0xd01",
"tsv110")
284 if (Implementer ==
"0x51")
289 .
Case(
"0x06f",
"krait")
290 .
Case(
"0x201",
"kryo")
291 .
Case(
"0x205",
"kryo")
292 .
Case(
"0x211",
"kryo")
293 .
Case(
"0x800",
"cortex-a73")
294 .
Case(
"0x801",
"cortex-a73")
295 .
Case(
"0x802",
"cortex-a75")
296 .
Case(
"0x803",
"cortex-a75")
297 .
Case(
"0x804",
"cortex-a76")
298 .
Case(
"0x805",
"cortex-a76")
299 .
Case(
"0xc00",
"falkor")
300 .
Case(
"0xc01",
"saphira")
302 if (Implementer ==
"0x53") {
305 unsigned Variant = 0, Part = 0;
310 if (
I.consume_front(
"CPU variant"))
311 I.ltrim(
"\t :").getAsInteger(0, Variant);
316 if (
I.consume_front(
"CPU part"))
317 I.ltrim(
"\t :").getAsInteger(0, Part);
319 unsigned Exynos = (Variant << 12) | Part;
331 if (Implementer ==
"0x6d") {
334 .
Case(
"0xd49",
"neoverse-n2")
338 if (Implementer ==
"0xc0") {
340 .
Case(
"0xac3",
"ampere1")
341 .
Case(
"0xac4",
"ampere1a")
342 .
Case(
"0xac5",
"ampere1b")
350StringRef getCPUNameFromS390Model(
unsigned int Id,
bool HaveVectorSupport) {
370 return HaveVectorSupport?
"z13" :
"zEC12";
373 return HaveVectorSupport?
"z14" :
"zEC12";
376 return HaveVectorSupport?
"z15" :
"zEC12";
380 return HaveVectorSupport?
"z16" :
"zEC12";
391 ProcCpuinfoContent.
split(Lines,
"\n");
395 for (
unsigned I = 0, E = Lines.size();
I != E; ++
I)
397 size_t Pos = Lines[
I].find(
':');
399 Lines[
I].drop_front(Pos + 1).split(CPUFeatures,
' ');
407 bool HaveVectorSupport =
false;
408 for (
unsigned I = 0, E = CPUFeatures.size();
I != E; ++
I) {
409 if (CPUFeatures[
I] ==
"vx")
410 HaveVectorSupport =
true;
414 for (
unsigned I = 0, E = Lines.size();
I != E; ++
I) {
416 size_t Pos = Lines[
I].find(
"machine = ");
418 Pos +=
sizeof(
"machine = ") - 1;
420 if (!Lines[
I].drop_front(Pos).getAsInteger(10, Id))
421 return getCPUNameFromS390Model(Id, HaveVectorSupport);
433 ProcCpuinfoContent.
split(Lines,
"\n");
437 for (
unsigned I = 0, E = Lines.size();
I != E; ++
I) {
439 UArch = Lines[
I].substr(5).ltrim(
"\t :");
445 .
Case(
"sifive,u74-mc",
"sifive-u74")
446 .
Case(
"sifive,bullet0",
"sifive-u74")
451#if !defined(__linux__) || !defined(__x86_64__)
454 uint8_t v3_insns[40] __attribute__ ((aligned (8))) =
456 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
458 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
460 0xae, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
462 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
464 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
466 uint8_t v2_insns[40] __attribute__ ((aligned (8))) =
468 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
470 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
472 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
474 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
476 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
478 struct bpf_prog_load_attr {
494 int fd = syscall(321 , 5 , &attr,
502 memset(&attr, 0,
sizeof(attr));
507 fd = syscall(321 , 5 , &attr,
sizeof(attr));
516#if defined(__i386__) || defined(_M_IX86) || \
517 defined(__x86_64__) || defined(_M_X64)
526static bool isCpuIdSupported() {
527#if defined(__GNUC__) || defined(__clang__)
529 int __cpuid_supported;
532 " movl %%eax,%%ecx\n"
533 " xorl $0x00200000,%%eax\n"
539 " cmpl %%eax,%%ecx\n"
543 :
"=r"(__cpuid_supported)
546 if (!__cpuid_supported)
556static bool getX86CpuIDAndInfo(
unsigned value,
unsigned *rEAX,
unsigned *rEBX,
557 unsigned *rECX,
unsigned *rEDX) {
558#if defined(__GNUC__) || defined(__clang__)
559#if defined(__x86_64__)
562 __asm__(
"movq\t%%rbx, %%rsi\n\t"
564 "xchgq\t%%rbx, %%rsi\n\t"
565 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
568#elif defined(__i386__)
569 __asm__(
"movl\t%%ebx, %%esi\n\t"
571 "xchgl\t%%ebx, %%esi\n\t"
572 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
578#elif defined(_MSC_VER)
581 __cpuid(registers,
value);
582 *rEAX = registers[0];
583 *rEBX = registers[1];
584 *rECX = registers[2];
585 *rEDX = registers[3];
597VendorSignatures getVendorSignature(
unsigned *MaxLeaf) {
598 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
599 if (MaxLeaf ==
nullptr)
604 if (!isCpuIdSupported())
605 return VendorSignatures::UNKNOWN;
607 if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1)
608 return VendorSignatures::UNKNOWN;
611 if (EBX == 0x756e6547 && EDX == 0x49656e69 && ECX == 0x6c65746e)
612 return VendorSignatures::GENUINE_INTEL;
615 if (EBX == 0x68747541 && EDX == 0x69746e65 && ECX == 0x444d4163)
616 return VendorSignatures::AUTHENTIC_AMD;
618 return VendorSignatures::UNKNOWN;
631static bool getX86CpuIDAndInfoEx(
unsigned value,
unsigned subleaf,
632 unsigned *rEAX,
unsigned *rEBX,
unsigned *rECX,
634#if defined(__GNUC__) || defined(__clang__)
635#if defined(__x86_64__)
638 __asm__(
"movq\t%%rbx, %%rsi\n\t"
640 "xchgq\t%%rbx, %%rsi\n\t"
641 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
642 :
"a"(
value),
"c"(subleaf));
644#elif defined(__i386__)
645 __asm__(
"movl\t%%ebx, %%esi\n\t"
647 "xchgl\t%%ebx, %%esi\n\t"
648 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
649 :
"a"(
value),
"c"(subleaf));
654#elif defined(_MSC_VER)
656 __cpuidex(registers,
value, subleaf);
657 *rEAX = registers[0];
658 *rEBX = registers[1];
659 *rECX = registers[2];
660 *rEDX = registers[3];
668static bool getX86XCR0(
unsigned *rEAX,
unsigned *rEDX) {
669#if defined(__GNUC__) || defined(__clang__)
673 __asm__(
".byte 0x0f, 0x01, 0xd0" :
"=a"(*rEAX),
"=d"(*rEDX) :
"c"(0));
675#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
676 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
685static void detectX86FamilyModel(
unsigned EAX,
unsigned *Family,
687 *Family = (
EAX >> 8) & 0xf;
689 if (*Family == 6 || *Family == 0xf) {
692 *Family += (
EAX >> 20) & 0xff;
699getIntelProcessorTypeAndSubtype(
unsigned Family,
unsigned Model,
700 const unsigned *Features,
701 unsigned *
Type,
unsigned *Subtype) {
702 auto testFeature = [&](
unsigned F) {
703 return (Features[
F / 32] & (1U << (
F % 32))) != 0;
716 if (testFeature(X86::FEATURE_MMX)) {
732 *
Type = X86::INTEL_CORE2;
741 *
Type = X86::INTEL_CORE2;
750 *
Type = X86::INTEL_COREI7;
751 *Subtype = X86::INTEL_COREI7_NEHALEM;
758 *
Type = X86::INTEL_COREI7;
759 *Subtype = X86::INTEL_COREI7_WESTMERE;
765 *
Type = X86::INTEL_COREI7;
766 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
771 *
Type = X86::INTEL_COREI7;
772 *Subtype = X86::INTEL_COREI7_IVYBRIDGE;
781 *
Type = X86::INTEL_COREI7;
782 *Subtype = X86::INTEL_COREI7_HASWELL;
791 *
Type = X86::INTEL_COREI7;
792 *Subtype = X86::INTEL_COREI7_BROADWELL;
803 *
Type = X86::INTEL_COREI7;
804 *Subtype = X86::INTEL_COREI7_SKYLAKE;
810 *
Type = X86::INTEL_COREI7;
811 *Subtype = X86::INTEL_COREI7_ROCKETLAKE;
816 *
Type = X86::INTEL_COREI7;
817 if (testFeature(X86::FEATURE_AVX512BF16)) {
819 *Subtype = X86::INTEL_COREI7_COOPERLAKE;
820 }
else if (testFeature(X86::FEATURE_AVX512VNNI)) {
822 *Subtype = X86::INTEL_COREI7_CASCADELAKE;
824 CPU =
"skylake-avx512";
825 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
832 *
Type = X86::INTEL_COREI7;
833 *Subtype = X86::INTEL_COREI7_CANNONLAKE;
839 CPU =
"icelake-client";
840 *
Type = X86::INTEL_COREI7;
841 *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT;
848 *
Type = X86::INTEL_COREI7;
849 *Subtype = X86::INTEL_COREI7_TIGERLAKE;
865 *
Type = X86::INTEL_COREI7;
866 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
872 *
Type = X86::INTEL_COREI7;
873 *Subtype = X86::INTEL_COREI7_ARROWLAKE;
881 *
Type = X86::INTEL_COREI7;
882 *Subtype = X86::INTEL_COREI7_ARROWLAKE_S;
888 *
Type = X86::INTEL_COREI7;
889 *Subtype = X86::INTEL_COREI7_PANTHERLAKE;
894 CPU =
"graniterapids";
895 *
Type = X86::INTEL_COREI7;
896 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS;
901 CPU =
"graniterapids-d";
902 *
Type = X86::INTEL_COREI7;
903 *Subtype = X86::INTEL_COREI7_GRANITERAPIDS_D;
909 CPU =
"icelake-server";
910 *
Type = X86::INTEL_COREI7;
911 *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER;
918 CPU =
"sapphirerapids";
919 *
Type = X86::INTEL_COREI7;
920 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
929 *
Type = X86::INTEL_BONNELL;
940 *
Type = X86::INTEL_SILVERMONT;
946 *
Type = X86::INTEL_GOLDMONT;
949 CPU =
"goldmont-plus";
950 *
Type = X86::INTEL_GOLDMONT_PLUS;
957 *
Type = X86::INTEL_TREMONT;
962 CPU =
"sierraforest";
963 *
Type = X86::INTEL_SIERRAFOREST;
969 *
Type = X86::INTEL_GRANDRIDGE;
974 CPU =
"clearwaterforest";
975 *
Type = X86::INTEL_CLEARWATERFOREST;
981 *
Type = X86::INTEL_KNL;
985 *
Type = X86::INTEL_KNM;
992 if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) {
994 }
else if (testFeature(X86::FEATURE_AVX512VBMI2)) {
995 CPU =
"icelake-client";
996 }
else if (testFeature(X86::FEATURE_AVX512VBMI)) {
998 }
else if (testFeature(X86::FEATURE_AVX512BF16)) {
1000 }
else if (testFeature(X86::FEATURE_AVX512VNNI)) {
1001 CPU =
"cascadelake";
1002 }
else if (testFeature(X86::FEATURE_AVX512VL)) {
1003 CPU =
"skylake-avx512";
1004 }
else if (testFeature(X86::FEATURE_AVX512ER)) {
1006 }
else if (testFeature(X86::FEATURE_CLFLUSHOPT)) {
1007 if (testFeature(X86::FEATURE_SHA))
1011 }
else if (testFeature(X86::FEATURE_ADX)) {
1013 }
else if (testFeature(X86::FEATURE_AVX2)) {
1015 }
else if (testFeature(X86::FEATURE_AVX)) {
1016 CPU =
"sandybridge";
1017 }
else if (testFeature(X86::FEATURE_SSE4_2)) {
1018 if (testFeature(X86::FEATURE_MOVBE))
1022 }
else if (testFeature(X86::FEATURE_SSE4_1)) {
1024 }
else if (testFeature(X86::FEATURE_SSSE3)) {
1025 if (testFeature(X86::FEATURE_MOVBE))
1029 }
else if (testFeature(X86::FEATURE_64BIT)) {
1031 }
else if (testFeature(X86::FEATURE_SSE3)) {
1033 }
else if (testFeature(X86::FEATURE_SSE2)) {
1035 }
else if (testFeature(X86::FEATURE_SSE)) {
1037 }
else if (testFeature(X86::FEATURE_MMX)) {
1046 if (testFeature(X86::FEATURE_64BIT)) {
1050 if (testFeature(X86::FEATURE_SSE3)) {
1065getAMDProcessorTypeAndSubtype(
unsigned Family,
unsigned Model,
1066 const unsigned *Features,
1067 unsigned *
Type,
unsigned *Subtype) {
1068 auto testFeature = [&](
unsigned F) {
1069 return (Features[
F / 32] & (1U << (
F % 32))) != 0;
1098 if (testFeature(X86::FEATURE_SSE)) {
1105 if (testFeature(X86::FEATURE_SSE3)) {
1113 *
Type = X86::AMDFAM10H;
1116 *Subtype = X86::AMDFAM10H_BARCELONA;
1119 *Subtype = X86::AMDFAM10H_SHANGHAI;
1122 *Subtype = X86::AMDFAM10H_ISTANBUL;
1128 *
Type = X86::AMD_BTVER1;
1132 *
Type = X86::AMDFAM15H;
1133 if (Model >= 0x60 && Model <= 0x7f) {
1135 *Subtype = X86::AMDFAM15H_BDVER4;
1138 if (Model >= 0x30 && Model <= 0x3f) {
1140 *Subtype = X86::AMDFAM15H_BDVER3;
1143 if ((Model >= 0x10 && Model <= 0x1f) ||
Model == 0x02) {
1145 *Subtype = X86::AMDFAM15H_BDVER2;
1148 if (Model <= 0x0f) {
1149 *Subtype = X86::AMDFAM15H_BDVER1;
1155 *
Type = X86::AMD_BTVER2;
1159 *
Type = X86::AMDFAM17H;
1160 if ((Model >= 0x30 && Model <= 0x3f) || (
Model == 0x47) ||
1161 (Model >= 0x60 && Model <= 0x67) || (
Model >= 0x68 &&
Model <= 0x6f) ||
1162 (Model >= 0x70 && Model <= 0x7f) || (
Model >= 0x84 &&
Model <= 0x87) ||
1163 (Model >= 0x90 && Model <= 0x97) || (
Model >= 0x98 &&
Model <= 0x9f) ||
1164 (Model >= 0xa0 && Model <= 0xaf)) {
1175 *Subtype = X86::AMDFAM17H_ZNVER2;
1178 if ((Model >= 0x10 && Model <= 0x1f) || (
Model >= 0x20 &&
Model <= 0x2f)) {
1182 *Subtype = X86::AMDFAM17H_ZNVER1;
1188 *
Type = X86::AMDFAM19H;
1189 if (Model <= 0x0f || (Model >= 0x20 && Model <= 0x2f) ||
1190 (
Model >= 0x30 &&
Model <= 0x3f) || (Model >= 0x40 && Model <= 0x4f) ||
1197 *Subtype = X86::AMDFAM19H_ZNVER3;
1200 if ((Model >= 0x10 && Model <= 0x1f) || (
Model >= 0x60 &&
Model <= 0x6f) ||
1201 (Model >= 0x70 && Model <= 0x77) || (
Model >= 0x78 &&
Model <= 0x7f) ||
1202 (Model >= 0xa0 && Model <= 0xaf)) {
1209 *Subtype = X86::AMDFAM19H_ZNVER4;
1220static void getAvailableFeatures(
unsigned ECX,
unsigned EDX,
unsigned MaxLeaf,
1221 unsigned *Features) {
1224 auto setFeature = [&](
unsigned F) {
1225 Features[
F / 32] |= 1U << (
F % 32);
1228 if ((EDX >> 15) & 1)
1229 setFeature(X86::FEATURE_CMOV);
1230 if ((EDX >> 23) & 1)
1231 setFeature(X86::FEATURE_MMX);
1232 if ((EDX >> 25) & 1)
1233 setFeature(X86::FEATURE_SSE);
1234 if ((EDX >> 26) & 1)
1235 setFeature(X86::FEATURE_SSE2);
1238 setFeature(X86::FEATURE_SSE3);
1240 setFeature(X86::FEATURE_PCLMUL);
1242 setFeature(X86::FEATURE_SSSE3);
1243 if ((ECX >> 12) & 1)
1244 setFeature(X86::FEATURE_FMA);
1245 if ((ECX >> 19) & 1)
1246 setFeature(X86::FEATURE_SSE4_1);
1247 if ((ECX >> 20) & 1) {
1248 setFeature(X86::FEATURE_SSE4_2);
1249 setFeature(X86::FEATURE_CRC32);
1251 if ((ECX >> 23) & 1)
1252 setFeature(X86::FEATURE_POPCNT);
1253 if ((ECX >> 25) & 1)
1254 setFeature(X86::FEATURE_AES);
1256 if ((ECX >> 22) & 1)
1257 setFeature(X86::FEATURE_MOVBE);
1262 const unsigned AVXBits = (1 << 27) | (1 << 28);
1263 bool HasAVX = ((
ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
1264 ((
EAX & 0x6) == 0x6);
1265#if defined(__APPLE__)
1269 bool HasAVX512Save =
true;
1272 bool HasAVX512Save = HasAVX && ((
EAX & 0xe0) == 0xe0);
1276 setFeature(X86::FEATURE_AVX);
1279 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1281 if (HasLeaf7 && ((EBX >> 3) & 1))
1282 setFeature(X86::FEATURE_BMI);
1283 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
1284 setFeature(X86::FEATURE_AVX2);
1285 if (HasLeaf7 && ((EBX >> 8) & 1))
1286 setFeature(X86::FEATURE_BMI2);
1287 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
1288 setFeature(X86::FEATURE_AVX512F);
1289 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
1290 setFeature(X86::FEATURE_AVX512DQ);
1291 if (HasLeaf7 && ((EBX >> 19) & 1))
1292 setFeature(X86::FEATURE_ADX);
1293 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
1294 setFeature(X86::FEATURE_AVX512IFMA);
1295 if (HasLeaf7 && ((EBX >> 23) & 1))
1296 setFeature(X86::FEATURE_CLFLUSHOPT);
1297 if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
1298 setFeature(X86::FEATURE_AVX512PF);
1299 if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
1300 setFeature(X86::FEATURE_AVX512ER);
1301 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
1302 setFeature(X86::FEATURE_AVX512CD);
1303 if (HasLeaf7 && ((EBX >> 29) & 1))
1304 setFeature(X86::FEATURE_SHA);
1305 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
1306 setFeature(X86::FEATURE_AVX512BW);
1307 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
1308 setFeature(X86::FEATURE_AVX512VL);
1310 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
1311 setFeature(X86::FEATURE_AVX512VBMI);
1312 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
1313 setFeature(X86::FEATURE_AVX512VBMI2);
1314 if (HasLeaf7 && ((ECX >> 8) & 1))
1315 setFeature(X86::FEATURE_GFNI);
1316 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
1317 setFeature(X86::FEATURE_VPCLMULQDQ);
1318 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
1319 setFeature(X86::FEATURE_AVX512VNNI);
1320 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
1321 setFeature(X86::FEATURE_AVX512BITALG);
1322 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
1323 setFeature(X86::FEATURE_AVX512VPOPCNTDQ);
1325 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
1326 setFeature(X86::FEATURE_AVX5124VNNIW);
1327 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
1328 setFeature(X86::FEATURE_AVX5124FMAPS);
1329 if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
1330 setFeature(X86::FEATURE_AVX512VP2INTERSECT);
1334 bool HasLeaf7Subleaf1 =
1335 HasLeaf7 &&
EAX >= 1 &&
1336 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1337 if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
1338 setFeature(X86::FEATURE_AVX512BF16);
1340 unsigned MaxExtLevel;
1341 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1343 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1344 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1345 if (HasExtLeaf1 && ((ECX >> 6) & 1))
1346 setFeature(X86::FEATURE_SSE4_A);
1347 if (HasExtLeaf1 && ((ECX >> 11) & 1))
1348 setFeature(X86::FEATURE_XOP);
1349 if (HasExtLeaf1 && ((ECX >> 16) & 1))
1350 setFeature(X86::FEATURE_FMA4);
1352 if (HasExtLeaf1 && ((EDX >> 29) & 1))
1353 setFeature(X86::FEATURE_64BIT);
1357 unsigned MaxLeaf = 0;
1359 if (Vendor == VendorSignatures::UNKNOWN)
1363 getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
1365 unsigned Family = 0,
Model = 0;
1367 detectX86FamilyModel(EAX, &Family, &Model);
1368 getAvailableFeatures(ECX, EDX, MaxLeaf, Features);
1373 unsigned Subtype = 0;
1377 if (Vendor == VendorSignatures::GENUINE_INTEL) {
1378 CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &
Type,
1380 }
else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
1381 CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &
Type,
1391#elif defined(__APPLE__) && defined(__powerpc__)
1393 host_basic_info_data_t hostInfo;
1394 mach_msg_type_number_t infoCount;
1396 infoCount = HOST_BASIC_INFO_COUNT;
1397 mach_port_t hostPort = mach_host_self();
1398 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1400 mach_port_deallocate(mach_task_self(), hostPort);
1402 if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
1405 switch (hostInfo.cpu_subtype) {
1435#elif defined(__linux__) && defined(__powerpc__)
1439 return detail::getHostCPUNameForPowerPC(
Content);
1441#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1445 return detail::getHostCPUNameForARM(
Content);
1447#elif defined(__linux__) && defined(__s390x__)
1451 return detail::getHostCPUNameForS390x(
Content);
1453#elif defined(__MVS__)
1458 int *StartToCVTOffset =
reinterpret_cast<int *
>(0x10);
1461 int ReadValue = *StartToCVTOffset;
1463 ReadValue = (ReadValue & 0x7FFFFFFF);
1464 char *CVT =
reinterpret_cast<char *
>(ReadValue);
1469 Id = decodePackedBCD<uint16_t>(Id,
false);
1473 bool HaveVectorSupport = CVT[244] & 0x80;
1474 return getCPUNameFromS390Model(Id, HaveVectorSupport);
1476#elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__))
1477#define CPUFAMILY_ARM_SWIFT 0x1e2d6381
1478#define CPUFAMILY_ARM_CYCLONE 0x37a09642
1479#define CPUFAMILY_ARM_TYPHOON 0x2c91a47e
1480#define CPUFAMILY_ARM_TWISTER 0x92fb37c8
1481#define CPUFAMILY_ARM_HURRICANE 0x67ceee93
1482#define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6
1483#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f
1484#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2
1485#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3
1486#define CPUFAMILY_ARM_BLIZZARD_AVALANCHE 0xda33d83d
1487#define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea
1491 size_t Length =
sizeof(Family);
1492 sysctlbyname(
"hw.cpufamily", &Family, &
Length, NULL, 0);
1495 case CPUFAMILY_ARM_SWIFT:
1497 case CPUFAMILY_ARM_CYCLONE:
1499 case CPUFAMILY_ARM_TYPHOON:
1501 case CPUFAMILY_ARM_TWISTER:
1503 case CPUFAMILY_ARM_HURRICANE:
1505 case CPUFAMILY_ARM_MONSOON_MISTRAL:
1507 case CPUFAMILY_ARM_VORTEX_TEMPEST:
1509 case CPUFAMILY_ARM_LIGHTNING_THUNDER:
1511 case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
1513 case CPUFAMILY_ARM_BLIZZARD_AVALANCHE:
1515 case CPUFAMILY_ARM_EVEREST_SAWTOOTH:
1524 switch (_system_configuration.implementation) {
1526 if (_system_configuration.version == PV_4_3)
1530 if (_system_configuration.version == PV_5)
1534 if (_system_configuration.version == PV_6_Compat)
1554#elif defined(__loongarch__)
1558 __asm__(
"cpucfg %[prid], $zero\n\t" : [prid]
"=r"(processor_id));
1560 switch (processor_id & 0xf000) {
1569#elif defined(__riscv)
1571#if defined(__linux__)
1574 return detail::getHostCPUNameForRISCV(
Content);
1576#if __riscv_xlen == 64
1577 return "generic-rv64";
1578#elif __riscv_xlen == 32
1579 return "generic-rv32";
1581#error "Unhandled value of __riscv_xlen"
1585#elif defined(__sparc__)
1586#if defined(__linux__)
1589 ProcCpuinfoContent.
split(Lines,
"\n");
1593 for (
unsigned I = 0, E =
Lines.size();
I != E; ++
I) {
1595 Cpu =
Lines[
I].substr(5).ltrim(
"\t :");
1627#if defined(__linux__)
1630 return detail::getHostCPUNameForSPARC(
Content);
1631#elif defined(__sun__) && defined(__svr4__)
1635 kstat_named_t *brand = NULL;
1639 ksp = kstat_lookup(kc,
const_cast<char *
>(
"cpu_info"), -1, NULL);
1640 if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1 &&
1641 ksp->ks_type == KSTAT_TYPE_NAMED)
1643 (kstat_named_t *)kstat_data_lookup(ksp,
const_cast<char *
>(
"brand"));
1644 if (brand != NULL && brand->data_type == KSTAT_DATA_STRING)
1645 buf = KSTAT_NAMED_STR_PTR(brand);
1650 .
Case(
"TMS390S10",
"supersparc")
1651 .
Case(
"TMS390Z50",
"supersparc")
1654 .
Case(
"MB86904",
"supersparc")
1655 .
Case(
"MB86907",
"supersparc")
1656 .
Case(
"RT623",
"hypersparc")
1657 .
Case(
"RT625",
"hypersparc")
1658 .
Case(
"RT626",
"hypersparc")
1659 .
Case(
"UltraSPARC-I",
"ultrasparc")
1660 .
Case(
"UltraSPARC-II",
"ultrasparc")
1661 .
Case(
"UltraSPARC-IIe",
"ultrasparc")
1662 .
Case(
"UltraSPARC-IIi",
"ultrasparc")
1663 .
Case(
"SPARC64-III",
"ultrasparc")
1664 .
Case(
"SPARC64-IV",
"ultrasparc")
1665 .
Case(
"UltraSPARC-III",
"ultrasparc3")
1666 .
Case(
"UltraSPARC-III+",
"ultrasparc3")
1667 .
Case(
"UltraSPARC-IIIi",
"ultrasparc3")
1668 .
Case(
"UltraSPARC-IIIi+",
"ultrasparc3")
1669 .
Case(
"UltraSPARC-IV",
"ultrasparc3")
1670 .
Case(
"UltraSPARC-IV+",
"ultrasparc3")
1671 .
Case(
"SPARC64-V",
"ultrasparc3")
1672 .
Case(
"SPARC64-VI",
"ultrasparc3")
1673 .
Case(
"SPARC64-VII",
"ultrasparc3")
1674 .
Case(
"UltraSPARC-T1",
"niagara")
1675 .
Case(
"UltraSPARC-T2",
"niagara2")
1676 .
Case(
"UltraSPARC-T2",
"niagara2")
1677 .
Case(
"UltraSPARC-T2+",
"niagara2")
1678 .
Case(
"SPARC-T3",
"niagara3")
1679 .
Case(
"SPARC-T4",
"niagara4")
1680 .
Case(
"SPARC-T5",
"niagara4")
1682 .
Case(
"SPARC-M7",
"niagara4" )
1683 .
Case(
"SPARC-S7",
"niagara4" )
1684 .
Case(
"SPARC-M8",
"niagara4" )
1707#if defined(__i386__) || defined(_M_IX86) || \
1708 defined(__x86_64__) || defined(_M_X64)
1713 if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1)
1716 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1718 Features[
"cx8"] = (
EDX >> 8) & 1;
1719 Features[
"cmov"] = (
EDX >> 15) & 1;
1720 Features[
"mmx"] = (
EDX >> 23) & 1;
1721 Features[
"fxsr"] = (
EDX >> 24) & 1;
1722 Features[
"sse"] = (
EDX >> 25) & 1;
1723 Features[
"sse2"] = (
EDX >> 26) & 1;
1725 Features[
"sse3"] = (
ECX >> 0) & 1;
1726 Features[
"pclmul"] = (
ECX >> 1) & 1;
1727 Features[
"ssse3"] = (
ECX >> 9) & 1;
1728 Features[
"cx16"] = (
ECX >> 13) & 1;
1729 Features[
"sse4.1"] = (
ECX >> 19) & 1;
1730 Features[
"sse4.2"] = (
ECX >> 20) & 1;
1731 Features[
"crc32"] = Features[
"sse4.2"];
1732 Features[
"movbe"] = (
ECX >> 22) & 1;
1733 Features[
"popcnt"] = (
ECX >> 23) & 1;
1734 Features[
"aes"] = (
ECX >> 25) & 1;
1735 Features[
"rdrnd"] = (
ECX >> 30) & 1;
1740 bool HasXSave = ((
ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX);
1741 bool HasAVXSave = HasXSave && ((
ECX >> 28) & 1) && ((
EAX & 0x6) == 0x6);
1742#if defined(__APPLE__)
1746 bool HasAVX512Save =
true;
1749 bool HasAVX512Save = HasAVXSave && ((
EAX & 0xe0) == 0xe0);
1752 const unsigned AMXBits = (1 << 17) | (1 << 18);
1753 bool HasAMXSave = HasXSave && ((
EAX & AMXBits) == AMXBits);
1755 Features[
"avx"] = HasAVXSave;
1756 Features[
"fma"] = ((
ECX >> 12) & 1) && HasAVXSave;
1758 Features[
"xsave"] = ((
ECX >> 26) & 1) && HasAVXSave;
1759 Features[
"f16c"] = ((
ECX >> 29) & 1) && HasAVXSave;
1761 unsigned MaxExtLevel;
1762 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1764 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1765 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1766 Features[
"sahf"] = HasExtLeaf1 && ((
ECX >> 0) & 1);
1767 Features[
"lzcnt"] = HasExtLeaf1 && ((
ECX >> 5) & 1);
1768 Features[
"sse4a"] = HasExtLeaf1 && ((
ECX >> 6) & 1);
1769 Features[
"prfchw"] = HasExtLeaf1 && ((
ECX >> 8) & 1);
1770 Features[
"xop"] = HasExtLeaf1 && ((
ECX >> 11) & 1) && HasAVXSave;
1771 Features[
"lwp"] = HasExtLeaf1 && ((
ECX >> 15) & 1);
1772 Features[
"fma4"] = HasExtLeaf1 && ((
ECX >> 16) & 1) && HasAVXSave;
1773 Features[
"tbm"] = HasExtLeaf1 && ((
ECX >> 21) & 1);
1774 Features[
"mwaitx"] = HasExtLeaf1 && ((
ECX >> 29) & 1);
1776 Features[
"64bit"] = HasExtLeaf1 && ((
EDX >> 29) & 1);
1780 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
1781 !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
1782 Features[
"clzero"] = HasExtLeaf8 && ((
EBX >> 0) & 1);
1783 Features[
"rdpru"] = HasExtLeaf8 && ((
EBX >> 4) & 1);
1784 Features[
"wbnoinvd"] = HasExtLeaf8 && ((
EBX >> 9) & 1);
1787 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1789 Features[
"fsgsbase"] = HasLeaf7 && ((
EBX >> 0) & 1);
1790 Features[
"sgx"] = HasLeaf7 && ((
EBX >> 2) & 1);
1791 Features[
"bmi"] = HasLeaf7 && ((
EBX >> 3) & 1);
1793 Features[
"avx2"] = HasLeaf7 && ((
EBX >> 5) & 1) && HasAVXSave;
1794 Features[
"bmi2"] = HasLeaf7 && ((
EBX >> 8) & 1);
1795 Features[
"invpcid"] = HasLeaf7 && ((
EBX >> 10) & 1);
1796 Features[
"rtm"] = HasLeaf7 && ((
EBX >> 11) & 1);
1798 Features[
"avx512f"] = HasLeaf7 && ((
EBX >> 16) & 1) && HasAVX512Save;
1799 Features[
"avx512dq"] = HasLeaf7 && ((
EBX >> 17) & 1) && HasAVX512Save;
1800 Features[
"rdseed"] = HasLeaf7 && ((
EBX >> 18) & 1);
1801 Features[
"adx"] = HasLeaf7 && ((
EBX >> 19) & 1);
1802 Features[
"avx512ifma"] = HasLeaf7 && ((
EBX >> 21) & 1) && HasAVX512Save;
1803 Features[
"clflushopt"] = HasLeaf7 && ((
EBX >> 23) & 1);
1804 Features[
"clwb"] = HasLeaf7 && ((
EBX >> 24) & 1);
1805 Features[
"avx512pf"] = HasLeaf7 && ((
EBX >> 26) & 1) && HasAVX512Save;
1806 Features[
"avx512er"] = HasLeaf7 && ((
EBX >> 27) & 1) && HasAVX512Save;
1807 Features[
"avx512cd"] = HasLeaf7 && ((
EBX >> 28) & 1) && HasAVX512Save;
1808 Features[
"sha"] = HasLeaf7 && ((
EBX >> 29) & 1);
1809 Features[
"avx512bw"] = HasLeaf7 && ((
EBX >> 30) & 1) && HasAVX512Save;
1810 Features[
"avx512vl"] = HasLeaf7 && ((
EBX >> 31) & 1) && HasAVX512Save;
1812 Features[
"prefetchwt1"] = HasLeaf7 && ((
ECX >> 0) & 1);
1813 Features[
"avx512vbmi"] = HasLeaf7 && ((
ECX >> 1) & 1) && HasAVX512Save;
1814 Features[
"pku"] = HasLeaf7 && ((
ECX >> 4) & 1);
1815 Features[
"waitpkg"] = HasLeaf7 && ((
ECX >> 5) & 1);
1816 Features[
"avx512vbmi2"] = HasLeaf7 && ((
ECX >> 6) & 1) && HasAVX512Save;
1817 Features[
"shstk"] = HasLeaf7 && ((
ECX >> 7) & 1);
1818 Features[
"gfni"] = HasLeaf7 && ((
ECX >> 8) & 1);
1819 Features[
"vaes"] = HasLeaf7 && ((
ECX >> 9) & 1) && HasAVXSave;
1820 Features[
"vpclmulqdq"] = HasLeaf7 && ((
ECX >> 10) & 1) && HasAVXSave;
1821 Features[
"avx512vnni"] = HasLeaf7 && ((
ECX >> 11) & 1) && HasAVX512Save;
1822 Features[
"avx512bitalg"] = HasLeaf7 && ((
ECX >> 12) & 1) && HasAVX512Save;
1823 Features[
"avx512vpopcntdq"] = HasLeaf7 && ((
ECX >> 14) & 1) && HasAVX512Save;
1824 Features[
"rdpid"] = HasLeaf7 && ((
ECX >> 22) & 1);
1825 Features[
"kl"] = HasLeaf7 && ((
ECX >> 23) & 1);
1826 Features[
"cldemote"] = HasLeaf7 && ((
ECX >> 25) & 1);
1827 Features[
"movdiri"] = HasLeaf7 && ((
ECX >> 27) & 1);
1828 Features[
"movdir64b"] = HasLeaf7 && ((
ECX >> 28) & 1);
1829 Features[
"enqcmd"] = HasLeaf7 && ((
ECX >> 29) & 1);
1831 Features[
"uintr"] = HasLeaf7 && ((
EDX >> 5) & 1);
1832 Features[
"avx512vp2intersect"] =
1833 HasLeaf7 && ((
EDX >> 8) & 1) && HasAVX512Save;
1834 Features[
"serialize"] = HasLeaf7 && ((
EDX >> 14) & 1);
1835 Features[
"tsxldtrk"] = HasLeaf7 && ((
EDX >> 16) & 1);
1846 Features[
"pconfig"] = HasLeaf7 && ((
EDX >> 18) & 1);
1847 Features[
"amx-bf16"] = HasLeaf7 && ((
EDX >> 22) & 1) && HasAMXSave;
1848 Features[
"avx512fp16"] = HasLeaf7 && ((
EDX >> 23) & 1) && HasAVX512Save;
1849 Features[
"amx-tile"] = HasLeaf7 && ((
EDX >> 24) & 1) && HasAMXSave;
1850 Features[
"amx-int8"] = HasLeaf7 && ((
EDX >> 25) & 1) && HasAMXSave;
1853 bool HasLeaf7Subleaf1 =
1854 HasLeaf7 &&
EAX >= 1 &&
1855 !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1856 Features[
"sha512"] = HasLeaf7Subleaf1 && ((
EAX >> 0) & 1);
1857 Features[
"sm3"] = HasLeaf7Subleaf1 && ((
EAX >> 1) & 1);
1858 Features[
"sm4"] = HasLeaf7Subleaf1 && ((
EAX >> 2) & 1);
1859 Features[
"raoint"] = HasLeaf7Subleaf1 && ((
EAX >> 3) & 1);
1860 Features[
"avxvnni"] = HasLeaf7Subleaf1 && ((
EAX >> 4) & 1) && HasAVXSave;
1861 Features[
"avx512bf16"] = HasLeaf7Subleaf1 && ((
EAX >> 5) & 1) && HasAVX512Save;
1862 Features[
"amx-fp16"] = HasLeaf7Subleaf1 && ((
EAX >> 21) & 1) && HasAMXSave;
1863 Features[
"cmpccxadd"] = HasLeaf7Subleaf1 && ((
EAX >> 7) & 1);
1864 Features[
"hreset"] = HasLeaf7Subleaf1 && ((
EAX >> 22) & 1);
1865 Features[
"avxifma"] = HasLeaf7Subleaf1 && ((
EAX >> 23) & 1) && HasAVXSave;
1866 Features[
"avxvnniint8"] = HasLeaf7Subleaf1 && ((
EDX >> 4) & 1) && HasAVXSave;
1867 Features[
"avxneconvert"] = HasLeaf7Subleaf1 && ((
EDX >> 5) & 1) && HasAVXSave;
1868 Features[
"amx-complex"] = HasLeaf7Subleaf1 && ((
EDX >> 8) & 1) && HasAMXSave;
1869 Features[
"avxvnniint16"] = HasLeaf7Subleaf1 && ((
EDX >> 10) & 1) && HasAVXSave;
1870 Features[
"prefetchi"] = HasLeaf7Subleaf1 && ((
EDX >> 14) & 1);
1871 Features[
"usermsr"] = HasLeaf7Subleaf1 && ((
EDX >> 15) & 1);
1872 Features[
"avx10.1-256"] = HasLeaf7Subleaf1 && ((
EDX >> 19) & 1);
1873 bool HasAPXF = HasLeaf7Subleaf1 && ((
EDX >> 21) & 1);
1874 Features[
"egpr"] = HasAPXF;
1875 Features[
"push2pop2"] = HasAPXF;
1876 Features[
"ppx"] = HasAPXF;
1877 Features[
"ndd"] = HasAPXF;
1878 Features[
"ccmp"] = HasAPXF;
1879 Features[
"cf"] = HasAPXF;
1881 bool HasLeafD = MaxLevel >= 0xd &&
1882 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
1885 Features[
"xsaveopt"] = HasLeafD && ((
EAX >> 0) & 1) && HasAVXSave;
1886 Features[
"xsavec"] = HasLeafD && ((
EAX >> 1) & 1) && HasAVXSave;
1887 Features[
"xsaves"] = HasLeafD && ((
EAX >> 3) & 1) && HasAVXSave;
1889 bool HasLeaf14 = MaxLevel >= 0x14 &&
1890 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
1892 Features[
"ptwrite"] = HasLeaf14 && ((
EBX >> 4) & 1);
1895 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX);
1896 Features[
"widekl"] = HasLeaf7 && HasLeaf19 && ((
EBX >> 2) & 1);
1899 MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX);
1900 Features[
"avx10.1-512"] =
1901 Features[
"avx10.1-256"] && HasLeaf24 && ((
EBX >> 18) & 1);
1905#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1912 P->getBuffer().split(Lines,
"\n");
1917 for (
unsigned I = 0, E =
Lines.size();
I != E; ++
I)
1919 Lines[
I].split(CPUFeatures,
' ');
1923#if defined(__aarch64__)
1925 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1931#if defined(__aarch64__)
1932 .
Case(
"asimd",
"neon")
1933 .
Case(
"fp",
"fp-armv8")
1934 .
Case(
"crc32",
"crc")
1935 .
Case(
"atomics",
"lse")
1937 .
Case(
"sve2",
"sve2")
1939 .
Case(
"half",
"fp16")
1940 .
Case(
"neon",
"neon")
1941 .
Case(
"vfpv3",
"vfp3")
1942 .
Case(
"vfpv3d16",
"vfp3d16")
1943 .
Case(
"vfpv4",
"vfp4")
1944 .
Case(
"idiva",
"hwdiv-arm")
1945 .
Case(
"idivt",
"hwdiv")
1949#if defined(__aarch64__)
1952 if (CPUFeatures[
I] ==
"aes")
1954 else if (CPUFeatures[
I] ==
"pmull")
1955 crypto |= CAP_PMULL;
1956 else if (CPUFeatures[
I] ==
"sha1")
1958 else if (CPUFeatures[
I] ==
"sha2")
1962 if (LLVMFeatureStr !=
"")
1963 Features[LLVMFeatureStr] =
true;
1966#if defined(__aarch64__)
1968 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
1969 Features[
"crypto"] =
true;
1974#elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64))
1976 if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE))
1977 Features[
"neon"] =
true;
1978 if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE))
1979 Features[
"crc"] =
true;
1980 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE))
1981 Features[
"crypto"] =
true;
1985#elif defined(__linux__) && defined(__loongarch__)
1986#include <sys/auxv.h>
1988 unsigned long hwcap = getauxval(AT_HWCAP);
1989 bool HasFPU = hwcap & (1UL << 3);
1991 __asm__(
"cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2]
"+r"(cpucfg2));
1993 Features[
"f"] = HasFPU && (cpucfg2 & (1U << 1));
1994 Features[
"d"] = HasFPU && (cpucfg2 & (1U << 2));
1996 Features[
"lsx"] = hwcap & (1UL << 4);
1997 Features[
"lasx"] = hwcap & (1UL << 5);
1998 Features[
"lvz"] = hwcap & (1UL << 9);
2011 T.setArchName(
"arm");
2012#elif defined(__arm64e__)
2014 T.setArchName(
"arm64e");
2015#elif defined(__aarch64__)
2017 T.setArchName(
"arm64");
2018#elif defined(__x86_64h__)
2020 T.setArchName(
"x86_64h");
2021#elif defined(__x86_64__)
2023 T.setArchName(
"x86_64");
2024#elif defined(__i386__)
2026 T.setArchName(
"i386");
2027#elif defined(__powerpc__)
2029 T.setArchName(
"powerpc");
2031# error "Unimplemented host arch fixup"
2038 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
2044 PT = withHostArch(PT);
2056#if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
2058 if (CPU ==
"generic")
2061 <<
" Host CPU: " << CPU <<
'\n';
This file defines the StringMap class.
#define LLVM_ATTRIBUTE_UNUSED
Given that RA is a live value
static std::unique_ptr< llvm::MemoryBuffer > LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent()
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Represents either an error or a value T.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileAsStream(const Twine &Filename)
Read all of the specified file into a MemoryBuffer as a stream (i.e.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr bool empty() const
empty - Check if the string is empty.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
static constexpr size_t npos
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & StartsWith(StringLiteral S, T Value)
Triple - Helper class for working with autoconf configuration names.
llvm::Triple get32BitArchVariant() const
Form a triple with a 32-bit variant of the current architecture.
std::string normalize() const
Return the normalized form of this triple's string.
llvm::Triple get64BitArchVariant() const
Form a triple with a 64-bit variant of the current architecture.
const std::string & str() const
bool isArch64Bit() const
Test whether the architecture is 64-bit.
bool isArch32Bit() const
Test whether the architecture is 32-bit.
The instances of the Type class are immutable: once they are created, they are never changed.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ CPU_SUBTYPE_POWERPC_970
@ CPU_SUBTYPE_POWERPC_604e
@ CPU_SUBTYPE_POWERPC_603e
@ CPU_SUBTYPE_POWERPC_7400
@ CPU_SUBTYPE_POWERPC_604
@ CPU_SUBTYPE_POWERPC_750
@ CPU_SUBTYPE_POWERPC_601
@ CPU_SUBTYPE_POWERPC_620
@ CPU_SUBTYPE_POWERPC_603ev
@ CPU_SUBTYPE_POWERPC_603
@ CPU_SUBTYPE_POWERPC_7450
@ CPU_SUBTYPE_POWERPC_602
Helper functions to extract CPU details from CPUID on x86.
VendorSignatures getVendorSignature(unsigned *MaxLeaf=nullptr)
Returns the host CPU's vendor.
StringRef getHostCPUNameForS390x(StringRef ProcCpuinfoContent)
StringRef getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent)
Helper functions to extract HostCPUName from /proc/cpuinfo on linux.
StringRef getHostCPUNameForBPF()
StringRef getHostCPUNameForARM(StringRef ProcCpuinfoContent)
StringRef getHostCPUNameForRISCV(StringRef ProcCpuinfoContent)
StringRef getHostCPUNameForSPARC(StringRef ProcCpuinfoContent)
StringRef getHostCPUName()
getHostCPUName - Get the LLVM name for the host CPU.
void printDefaultTargetAndDetectedCPU(raw_ostream &OS)
This is a function compatible with cl::AddExtraVersionPrinter, which adds info about the current targ...
bool getHostCPUFeatures(StringMap< bool, MallocAllocator > &Features)
getHostCPUFeatures - Get the LLVM names for the host CPU features.
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
std::string getDefaultTargetTriple()
getDefaultTargetTriple() - Return the default target triple the compiler has been configured to produ...
This is an optimization pass for GlobalISel generic memory operations.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.