19 #include "llvm/Config/llvm-config.h"
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>
48 #include <sys/systemcfg.h>
51 #define DEBUG_TYPE "host-detection"
61 static std::unique_ptr<llvm::MemoryBuffer>
65 if (std::error_code EC = Text.
getError()) {
67 <<
"/proc/cpuinfo: " << EC.message() <<
"\n";
77 const char *
generic =
"generic";
91 while (CIP < CPUInfoEnd && CPUStart ==
nullptr) {
92 if (CIP < CPUInfoEnd && *CIP ==
'\n')
95 if (CIP < CPUInfoEnd && *CIP ==
'c') {
97 if (CIP < CPUInfoEnd && *CIP ==
'p') {
99 if (CIP < CPUInfoEnd && *CIP ==
'u') {
101 while (CIP < CPUInfoEnd && (*CIP ==
' ' || *CIP ==
'\t'))
104 if (CIP < CPUInfoEnd && *CIP ==
':') {
106 while (CIP < CPUInfoEnd && (*CIP ==
' ' || *CIP ==
'\t'))
109 if (CIP < CPUInfoEnd) {
111 while (CIP < CPUInfoEnd && (*CIP !=
' ' && *CIP !=
'\t' &&
112 *CIP !=
',' && *CIP !=
'\n'))
114 CPULen = CIP - CPUStart;
121 if (CPUStart ==
nullptr)
122 while (CIP < CPUInfoEnd && *CIP !=
'\n')
126 if (CPUStart ==
nullptr)
130 .
Case(
"604e",
"604e")
132 .
Case(
"7400",
"7400")
133 .
Case(
"7410",
"7400")
134 .
Case(
"7447",
"7400")
135 .
Case(
"7455",
"7450")
137 .
Case(
"POWER4",
"970")
138 .
Case(
"PPC970FX",
"970")
139 .
Case(
"PPC970MP",
"970")
141 .
Case(
"POWER5",
"g5")
143 .
Case(
"POWER6",
"pwr6")
144 .
Case(
"POWER7",
"pwr7")
145 .
Case(
"POWER8",
"pwr8")
146 .
Case(
"POWER8E",
"pwr8")
147 .
Case(
"POWER8NVL",
"pwr8")
148 .
Case(
"POWER9",
"pwr9")
149 .
Case(
"POWER10",
"pwr10")
163 ProcCpuinfoContent.
split(Lines,
"\n");
169 for (
unsigned I = 0,
E = Lines.size();
I !=
E; ++
I) {
171 Implementer = Lines[
I].substr(15).ltrim(
"\t :");
173 Hardware = Lines[
I].substr(8).ltrim(
"\t :");
175 Part = Lines[
I].substr(8).ltrim(
"\t :");
178 if (Implementer ==
"0x41") {
191 .
Case(
"0x926",
"arm926ej-s")
192 .
Case(
"0xb02",
"mpcore")
193 .
Case(
"0xb36",
"arm1136j-s")
194 .
Case(
"0xb56",
"arm1156t2-s")
195 .
Case(
"0xb76",
"arm1176jz-s")
196 .
Case(
"0xc08",
"cortex-a8")
197 .
Case(
"0xc09",
"cortex-a9")
198 .
Case(
"0xc0f",
"cortex-a15")
199 .
Case(
"0xc20",
"cortex-m0")
200 .
Case(
"0xc23",
"cortex-m3")
201 .
Case(
"0xc24",
"cortex-m4")
202 .
Case(
"0xd22",
"cortex-m55")
203 .
Case(
"0xd02",
"cortex-a34")
204 .
Case(
"0xd04",
"cortex-a35")
205 .
Case(
"0xd03",
"cortex-a53")
206 .
Case(
"0xd07",
"cortex-a57")
207 .
Case(
"0xd08",
"cortex-a72")
208 .
Case(
"0xd09",
"cortex-a73")
209 .
Case(
"0xd0a",
"cortex-a75")
210 .
Case(
"0xd0b",
"cortex-a76")
211 .
Case(
"0xd0d",
"cortex-a77")
212 .
Case(
"0xd41",
"cortex-a78")
213 .
Case(
"0xd44",
"cortex-x1")
214 .
Case(
"0xd4c",
"cortex-x1c")
215 .
Case(
"0xd0c",
"neoverse-n1")
216 .
Case(
"0xd49",
"neoverse-n2")
217 .
Case(
"0xd40",
"neoverse-v1")
221 if (Implementer ==
"0x42" || Implementer ==
"0x43") {
223 .
Case(
"0x516",
"thunderx2t99")
224 .
Case(
"0x0516",
"thunderx2t99")
225 .
Case(
"0xaf",
"thunderx2t99")
226 .
Case(
"0x0af",
"thunderx2t99")
227 .
Case(
"0xa1",
"thunderxt88")
228 .
Case(
"0x0a1",
"thunderxt88")
232 if (Implementer ==
"0x46") {
234 .
Case(
"0x001",
"a64fx")
238 if (Implementer ==
"0x4e") {
240 .
Case(
"0x004",
"carmel")
244 if (Implementer ==
"0x48")
249 .
Case(
"0xd01",
"tsv110")
252 if (Implementer ==
"0x51")
257 .
Case(
"0x06f",
"krait")
258 .
Case(
"0x201",
"kryo")
259 .
Case(
"0x205",
"kryo")
260 .
Case(
"0x211",
"kryo")
261 .
Case(
"0x800",
"cortex-a73")
262 .
Case(
"0x801",
"cortex-a73")
263 .
Case(
"0x802",
"cortex-a75")
264 .
Case(
"0x803",
"cortex-a75")
265 .
Case(
"0x804",
"cortex-a76")
266 .
Case(
"0x805",
"cortex-a76")
267 .
Case(
"0xc00",
"falkor")
268 .
Case(
"0xc01",
"saphira")
270 if (Implementer ==
"0x53") {
273 unsigned Variant = 0, Part = 0;
278 if (
I.consume_front(
"CPU variant"))
279 I.ltrim(
"\t :").getAsInteger(0, Variant);
284 if (
I.consume_front(
"CPU part"))
285 I.ltrim(
"\t :").getAsInteger(0, Part);
287 unsigned Exynos = (Variant << 12) | Part;
299 if (Implementer ==
"0xc0") {
301 .
Case(
"0xac3",
"ampere1")
309 StringRef getCPUNameFromS390Model(
unsigned int Id,
bool HaveVectorSupport) {
329 return HaveVectorSupport?
"z13" :
"zEC12";
332 return HaveVectorSupport?
"z14" :
"zEC12";
335 return HaveVectorSupport?
"z15" :
"zEC12";
339 return HaveVectorSupport?
"z16" :
"zEC12";
350 ProcCpuinfoContent.
split(Lines,
"\n");
354 for (
unsigned I = 0,
E = Lines.size();
I !=
E; ++
I)
356 size_t Pos = Lines[
I].find(
':');
358 Lines[
I].drop_front(Pos + 1).split(CPUFeatures,
' ');
366 bool HaveVectorSupport =
false;
367 for (
unsigned I = 0,
E = CPUFeatures.size();
I !=
E; ++
I) {
368 if (CPUFeatures[
I] ==
"vx")
369 HaveVectorSupport =
true;
373 for (
unsigned I = 0,
E = Lines.size();
I !=
E; ++
I) {
375 size_t Pos = Lines[
I].find(
"machine = ");
377 Pos +=
sizeof(
"machine = ") - 1;
379 if (!Lines[
I].drop_front(Pos).getAsInteger(10,
Id))
380 return getCPUNameFromS390Model(
Id, HaveVectorSupport);
392 ProcCpuinfoContent.
split(Lines,
"\n");
396 for (
unsigned I = 0,
E = Lines.size();
I !=
E; ++
I) {
398 UArch = Lines[
I].substr(5).ltrim(
"\t :");
404 .
Case(
"sifive,u74-mc",
"sifive-u74")
405 .
Case(
"sifive,bullet0",
"sifive-u74")
410 #if !defined(__linux__) || !defined(__x86_64__)
413 uint8_t v3_insns[40] __attribute__ ((
aligned (8))) =
415 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
417 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
419 0xae, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
421 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
423 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
425 uint8_t v2_insns[40] __attribute__ ((
aligned (8))) =
427 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
429 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
431 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
433 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
435 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
437 struct bpf_prog_load_attr {
453 int fd = syscall(321 , 5 , &attr,
461 memset(&attr, 0,
sizeof(attr));
466 fd = syscall(321 , 5 , &attr,
sizeof(attr));
475 #if defined(__i386__) || defined(_M_IX86) || \
476 defined(__x86_64__) || defined(_M_X64)
485 static bool isCpuIdSupported() {
486 #if defined(__GNUC__) || defined(__clang__)
487 #if defined(__i386__)
488 int __cpuid_supported;
491 " movl %%eax,%%ecx\n"
492 " xorl $0x00200000,%%eax\n"
498 " cmpl %%eax,%%ecx\n"
502 :
"=r"(__cpuid_supported)
505 if (!__cpuid_supported)
515 static bool getX86CpuIDAndInfo(
unsigned value,
unsigned *rEAX,
unsigned *rEBX,
516 unsigned *rECX,
unsigned *rEDX) {
517 #if defined(__GNUC__) || defined(__clang__)
518 #if defined(__x86_64__)
521 __asm__(
"movq\t%%rbx, %%rsi\n\t"
523 "xchgq\t%%rbx, %%rsi\n\t"
524 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
527 #elif defined(__i386__)
528 __asm__(
"movl\t%%ebx, %%esi\n\t"
530 "xchgl\t%%ebx, %%esi\n\t"
531 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
537 #elif defined(_MSC_VER)
558 if (MaxLeaf ==
nullptr)
563 if (!isCpuIdSupported())
566 if (getX86CpuIDAndInfo(0, MaxLeaf, &
EBX, &
ECX, &
EDX) || *MaxLeaf < 1)
570 if (
EBX == 0x756e6547 &&
EDX == 0x49656e69 &&
ECX == 0x6c65746e)
571 return VendorSignatures::GENUINE_INTEL;
574 if (
EBX == 0x68747541 &&
EDX == 0x69746e65 &&
ECX == 0x444d4163)
575 return VendorSignatures::AUTHENTIC_AMD;
590 static bool getX86CpuIDAndInfoEx(
unsigned value,
unsigned subleaf,
591 unsigned *rEAX,
unsigned *rEBX,
unsigned *rECX,
593 #if defined(__GNUC__) || defined(__clang__)
594 #if defined(__x86_64__)
597 __asm__(
"movq\t%%rbx, %%rsi\n\t"
599 "xchgq\t%%rbx, %%rsi\n\t"
600 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
601 :
"a"(value),
"c"(subleaf));
603 #elif defined(__i386__)
604 __asm__(
"movl\t%%ebx, %%esi\n\t"
606 "xchgl\t%%ebx, %%esi\n\t"
607 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
608 :
"a"(value),
"c"(subleaf));
613 #elif defined(_MSC_VER)
627 static bool getX86XCR0(
unsigned *rEAX,
unsigned *rEDX) {
628 #if defined(__GNUC__) || defined(__clang__)
632 __asm__(
".byte 0x0f, 0x01, 0xd0" :
"=a"(*rEAX),
"=d"(*rEDX) :
"c"(0));
634 #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
635 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
644 static void detectX86FamilyModel(
unsigned EAX,
unsigned *Family,
646 *Family = (
EAX >> 8) & 0xf;
648 if (*Family == 6 || *Family == 0xf) {
651 *Family += (
EAX >> 20) & 0xff;
658 getIntelProcessorTypeAndSubtype(
unsigned Family,
unsigned Model,
659 const unsigned *Features,
660 unsigned *
Type,
unsigned *Subtype) {
661 auto testFeature = [&](
unsigned F) {
662 return (Features[
F / 32] & (1U << (
F % 32))) != 0;
675 if (testFeature(X86::FEATURE_MMX)) {
691 *
Type = X86::INTEL_CORE2;
700 *
Type = X86::INTEL_CORE2;
709 *
Type = X86::INTEL_COREI7;
710 *Subtype = X86::INTEL_COREI7_NEHALEM;
717 *
Type = X86::INTEL_COREI7;
718 *Subtype = X86::INTEL_COREI7_WESTMERE;
724 *
Type = X86::INTEL_COREI7;
725 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
730 *
Type = X86::INTEL_COREI7;
731 *Subtype = X86::INTEL_COREI7_IVYBRIDGE;
740 *
Type = X86::INTEL_COREI7;
741 *Subtype = X86::INTEL_COREI7_HASWELL;
750 *
Type = X86::INTEL_COREI7;
751 *Subtype = X86::INTEL_COREI7_BROADWELL;
762 *
Type = X86::INTEL_COREI7;
763 *Subtype = X86::INTEL_COREI7_SKYLAKE;
769 *
Type = X86::INTEL_COREI7;
770 *Subtype = X86::INTEL_COREI7_ROCKETLAKE;
775 *
Type = X86::INTEL_COREI7;
776 if (testFeature(X86::FEATURE_AVX512BF16)) {
778 *Subtype = X86::INTEL_COREI7_COOPERLAKE;
779 }
else if (testFeature(X86::FEATURE_AVX512VNNI)) {
781 *Subtype = X86::INTEL_COREI7_CASCADELAKE;
783 CPU =
"skylake-avx512";
784 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
791 *
Type = X86::INTEL_COREI7;
792 *Subtype = X86::INTEL_COREI7_CANNONLAKE;
798 CPU =
"icelake-client";
799 *
Type = X86::INTEL_COREI7;
800 *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT;
807 *
Type = X86::INTEL_COREI7;
808 *Subtype = X86::INTEL_COREI7_TIGERLAKE;
815 *
Type = X86::INTEL_COREI7;
816 *Subtype = X86::INTEL_COREI7_ALDERLAKE;
822 CPU =
"icelake-server";
823 *
Type = X86::INTEL_COREI7;
824 *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER;
829 CPU =
"sapphirerapids";
830 *
Type = X86::INTEL_COREI7;
831 *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS;
840 *
Type = X86::INTEL_BONNELL;
851 *
Type = X86::INTEL_SILVERMONT;
857 *
Type = X86::INTEL_GOLDMONT;
860 CPU =
"goldmont-plus";
861 *
Type = X86::INTEL_GOLDMONT_PLUS;
865 *
Type = X86::INTEL_TREMONT;
871 *
Type = X86::INTEL_KNL;
875 *
Type = X86::INTEL_KNM;
882 if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) {
884 }
else if (testFeature(X86::FEATURE_AVX512VBMI2)) {
885 CPU =
"icelake-client";
886 }
else if (testFeature(X86::FEATURE_AVX512VBMI)) {
888 }
else if (testFeature(X86::FEATURE_AVX512BF16)) {
890 }
else if (testFeature(X86::FEATURE_AVX512VNNI)) {
892 }
else if (testFeature(X86::FEATURE_AVX512VL)) {
893 CPU =
"skylake-avx512";
894 }
else if (testFeature(X86::FEATURE_AVX512ER)) {
896 }
else if (testFeature(X86::FEATURE_CLFLUSHOPT)) {
897 if (testFeature(X86::FEATURE_SHA))
901 }
else if (testFeature(X86::FEATURE_ADX)) {
903 }
else if (testFeature(X86::FEATURE_AVX2)) {
905 }
else if (testFeature(X86::FEATURE_AVX)) {
907 }
else if (testFeature(X86::FEATURE_SSE4_2)) {
908 if (testFeature(X86::FEATURE_MOVBE))
912 }
else if (testFeature(X86::FEATURE_SSE4_1)) {
914 }
else if (testFeature(X86::FEATURE_SSSE3)) {
915 if (testFeature(X86::FEATURE_MOVBE))
919 }
else if (testFeature(X86::FEATURE_64BIT)) {
921 }
else if (testFeature(X86::FEATURE_SSE3)) {
923 }
else if (testFeature(X86::FEATURE_SSE2)) {
925 }
else if (testFeature(X86::FEATURE_SSE)) {
927 }
else if (testFeature(X86::FEATURE_MMX)) {
936 if (testFeature(X86::FEATURE_64BIT)) {
940 if (testFeature(X86::FEATURE_SSE3)) {
955 getAMDProcessorTypeAndSubtype(
unsigned Family,
unsigned Model,
956 const unsigned *Features,
957 unsigned *
Type,
unsigned *Subtype) {
958 auto testFeature = [&](
unsigned F) {
959 return (Features[
F / 32] & (1U << (
F % 32))) != 0;
988 if (testFeature(X86::FEATURE_SSE)) {
995 if (testFeature(X86::FEATURE_SSE3)) {
1003 *
Type = X86::AMDFAM10H;
1006 *Subtype = X86::AMDFAM10H_BARCELONA;
1009 *Subtype = X86::AMDFAM10H_SHANGHAI;
1012 *Subtype = X86::AMDFAM10H_ISTANBUL;
1018 *
Type = X86::AMD_BTVER1;
1022 *
Type = X86::AMDFAM15H;
1025 *Subtype = X86::AMDFAM15H_BDVER4;
1030 *Subtype = X86::AMDFAM15H_BDVER3;
1035 *Subtype = X86::AMDFAM15H_BDVER2;
1038 if (
Model <= 0x0f) {
1039 *Subtype = X86::AMDFAM15H_BDVER1;
1045 *
Type = X86::AMD_BTVER2;
1049 *
Type = X86::AMDFAM17H;
1052 *Subtype = X86::AMDFAM17H_ZNVER2;
1055 if (
Model <= 0x0f) {
1056 *Subtype = X86::AMDFAM17H_ZNVER1;
1062 *
Type = X86::AMDFAM19H;
1064 *Subtype = X86::AMDFAM19H_ZNVER3;
1075 static void getAvailableFeatures(
unsigned ECX,
unsigned EDX,
unsigned MaxLeaf,
1076 unsigned *Features) {
1079 auto setFeature = [&](
unsigned F) {
1080 Features[
F / 32] |= 1U << (
F % 32);
1083 if ((
EDX >> 15) & 1)
1084 setFeature(X86::FEATURE_CMOV);
1085 if ((
EDX >> 23) & 1)
1086 setFeature(X86::FEATURE_MMX);
1087 if ((
EDX >> 25) & 1)
1088 setFeature(X86::FEATURE_SSE);
1089 if ((
EDX >> 26) & 1)
1090 setFeature(X86::FEATURE_SSE2);
1093 setFeature(X86::FEATURE_SSE3);
1095 setFeature(X86::FEATURE_PCLMUL);
1097 setFeature(X86::FEATURE_SSSE3);
1098 if ((
ECX >> 12) & 1)
1100 if ((
ECX >> 19) & 1)
1101 setFeature(X86::FEATURE_SSE4_1);
1102 if ((
ECX >> 20) & 1) {
1103 setFeature(X86::FEATURE_SSE4_2);
1104 setFeature(X86::FEATURE_CRC32);
1106 if ((
ECX >> 23) & 1)
1107 setFeature(X86::FEATURE_POPCNT);
1108 if ((
ECX >> 25) & 1)
1109 setFeature(X86::FEATURE_AES);
1111 if ((
ECX >> 22) & 1)
1112 setFeature(X86::FEATURE_MOVBE);
1117 const unsigned AVXBits = (1 << 27) | (1 << 28);
1118 bool HasAVX = ((
ECX & AVXBits) == AVXBits) && !getX86XCR0(&
EAX, &
EDX) &&
1119 ((
EAX & 0x6) == 0x6);
1120 #if defined(__APPLE__)
1124 bool HasAVX512Save =
true;
1127 bool HasAVX512Save = HasAVX && ((
EAX & 0xe0) == 0xe0);
1131 setFeature(X86::FEATURE_AVX);
1134 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &
EAX, &
EBX, &
ECX, &
EDX);
1136 if (HasLeaf7 && ((
EBX >> 3) & 1))
1137 setFeature(X86::FEATURE_BMI);
1138 if (HasLeaf7 && ((
EBX >> 5) & 1) && HasAVX)
1139 setFeature(X86::FEATURE_AVX2);
1140 if (HasLeaf7 && ((
EBX >> 8) & 1))
1141 setFeature(X86::FEATURE_BMI2);
1142 if (HasLeaf7 && ((
EBX >> 16) & 1) && HasAVX512Save)
1143 setFeature(X86::FEATURE_AVX512F);
1144 if (HasLeaf7 && ((
EBX >> 17) & 1) && HasAVX512Save)
1145 setFeature(X86::FEATURE_AVX512DQ);
1146 if (HasLeaf7 && ((
EBX >> 19) & 1))
1147 setFeature(X86::FEATURE_ADX);
1148 if (HasLeaf7 && ((
EBX >> 21) & 1) && HasAVX512Save)
1149 setFeature(X86::FEATURE_AVX512IFMA);
1150 if (HasLeaf7 && ((
EBX >> 23) & 1))
1151 setFeature(X86::FEATURE_CLFLUSHOPT);
1152 if (HasLeaf7 && ((
EBX >> 26) & 1) && HasAVX512Save)
1153 setFeature(X86::FEATURE_AVX512PF);
1154 if (HasLeaf7 && ((
EBX >> 27) & 1) && HasAVX512Save)
1155 setFeature(X86::FEATURE_AVX512ER);
1156 if (HasLeaf7 && ((
EBX >> 28) & 1) && HasAVX512Save)
1157 setFeature(X86::FEATURE_AVX512CD);
1158 if (HasLeaf7 && ((
EBX >> 29) & 1))
1159 setFeature(X86::FEATURE_SHA);
1160 if (HasLeaf7 && ((
EBX >> 30) & 1) && HasAVX512Save)
1161 setFeature(X86::FEATURE_AVX512BW);
1162 if (HasLeaf7 && ((
EBX >> 31) & 1) && HasAVX512Save)
1163 setFeature(X86::FEATURE_AVX512VL);
1165 if (HasLeaf7 && ((
ECX >> 1) & 1) && HasAVX512Save)
1166 setFeature(X86::FEATURE_AVX512VBMI);
1167 if (HasLeaf7 && ((
ECX >> 6) & 1) && HasAVX512Save)
1168 setFeature(X86::FEATURE_AVX512VBMI2);
1169 if (HasLeaf7 && ((
ECX >> 8) & 1))
1170 setFeature(X86::FEATURE_GFNI);
1171 if (HasLeaf7 && ((
ECX >> 10) & 1) && HasAVX)
1172 setFeature(X86::FEATURE_VPCLMULQDQ);
1173 if (HasLeaf7 && ((
ECX >> 11) & 1) && HasAVX512Save)
1174 setFeature(X86::FEATURE_AVX512VNNI);
1175 if (HasLeaf7 && ((
ECX >> 12) & 1) && HasAVX512Save)
1176 setFeature(X86::FEATURE_AVX512BITALG);
1177 if (HasLeaf7 && ((
ECX >> 14) & 1) && HasAVX512Save)
1178 setFeature(X86::FEATURE_AVX512VPOPCNTDQ);
1180 if (HasLeaf7 && ((
EDX >> 2) & 1) && HasAVX512Save)
1181 setFeature(X86::FEATURE_AVX5124VNNIW);
1182 if (HasLeaf7 && ((
EDX >> 3) & 1) && HasAVX512Save)
1183 setFeature(X86::FEATURE_AVX5124FMAPS);
1184 if (HasLeaf7 && ((
EDX >> 8) & 1) && HasAVX512Save)
1185 setFeature(X86::FEATURE_AVX512VP2INTERSECT);
1187 bool HasLeaf7Subleaf1 =
1188 MaxLeaf >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &
EAX, &
EBX, &
ECX, &
EDX);
1189 if (HasLeaf7Subleaf1 && ((
EAX >> 5) & 1) && HasAVX512Save)
1190 setFeature(X86::FEATURE_AVX512BF16);
1192 unsigned MaxExtLevel;
1193 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &
EBX, &
ECX, &
EDX);
1195 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1196 !getX86CpuIDAndInfo(0x80000001, &
EAX, &
EBX, &
ECX, &
EDX);
1197 if (HasExtLeaf1 && ((
ECX >> 6) & 1))
1198 setFeature(X86::FEATURE_SSE4_A);
1199 if (HasExtLeaf1 && ((
ECX >> 11) & 1))
1200 setFeature(X86::FEATURE_XOP);
1201 if (HasExtLeaf1 && ((
ECX >> 16) & 1))
1202 setFeature(X86::FEATURE_FMA4);
1204 if (HasExtLeaf1 && ((
EDX >> 29) & 1))
1205 setFeature(X86::FEATURE_64BIT);
1209 unsigned MaxLeaf = 0;
1217 unsigned Family = 0,
Model = 0;
1219 detectX86FamilyModel(
EAX, &Family, &
Model);
1220 getAvailableFeatures(
ECX,
EDX, MaxLeaf, Features);
1225 unsigned Subtype = 0;
1230 CPU = getIntelProcessorTypeAndSubtype(Family,
Model, Features, &
Type,
1233 CPU = getAMDProcessorTypeAndSubtype(Family,
Model, Features, &
Type,
1243 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
1245 host_basic_info_data_t hostInfo;
1246 mach_msg_type_number_t infoCount;
1248 infoCount = HOST_BASIC_INFO_COUNT;
1249 mach_port_t hostPort = mach_host_self();
1250 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1252 mach_port_deallocate(mach_task_self(), hostPort);
1257 switch (hostInfo.cpu_subtype) {
1287 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
1293 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1299 #elif defined(__linux__) && defined(__s390x__)
1305 #elif defined(__MVS__)
1310 int *StartToCVTOffset =
reinterpret_cast<int *
>(0x10);
1313 int ReadValue = *StartToCVTOffset;
1315 ReadValue = (ReadValue & 0x7FFFFFFF);
1316 char *CVT =
reinterpret_cast<char *
>(ReadValue);
1321 Id = decodePackedBCD<uint16_t>(
Id,
false);
1325 bool HaveVectorSupport = CVT[244] & 0x80;
1326 return getCPUNameFromS390Model(
Id, HaveVectorSupport);
1328 #elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__))
1329 #define CPUFAMILY_ARM_SWIFT 0x1e2d6381
1330 #define CPUFAMILY_ARM_CYCLONE 0x37a09642
1331 #define CPUFAMILY_ARM_TYPHOON 0x2c91a47e
1332 #define CPUFAMILY_ARM_TWISTER 0x92fb37c8
1333 #define CPUFAMILY_ARM_HURRICANE 0x67ceee93
1334 #define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6
1335 #define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f
1336 #define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2
1337 #define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3
1341 size_t Length =
sizeof(Family);
1342 sysctlbyname(
"hw.cpufamily", &Family, &Length, NULL, 0);
1345 case CPUFAMILY_ARM_SWIFT:
1347 case CPUFAMILY_ARM_CYCLONE:
1349 case CPUFAMILY_ARM_TYPHOON:
1351 case CPUFAMILY_ARM_TWISTER:
1353 case CPUFAMILY_ARM_HURRICANE:
1355 case CPUFAMILY_ARM_MONSOON_MISTRAL:
1357 case CPUFAMILY_ARM_VORTEX_TEMPEST:
1359 case CPUFAMILY_ARM_LIGHTNING_THUNDER:
1361 case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
1370 switch (_system_configuration.implementation) {
1372 if (_system_configuration.version == PV_4_3)
1376 if (_system_configuration.version == PV_5)
1380 if (_system_configuration.version == PV_6_Compat)
1400 #elif defined(__riscv)
1402 #if defined(__linux__)
1407 #if __riscv_xlen == 64
1408 return "generic-rv64";
1409 #elif __riscv_xlen == 32
1410 return "generic-rv32";
1412 #error "Unhandled value of __riscv_xlen"
1433 #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
1441 if (sched_getaffinity(0,
sizeof(Affinity), &Affinity) != 0)
1449 if (std::error_code EC = Text.
getError()) {
1451 <<
"/proc/cpuinfo: " <<
EC.message() <<
"\n";
1455 (*Text)->getBuffer().split(strs,
"\n", -1,
1457 int CurProcessor = -1;
1458 int CurPhysicalId = -1;
1459 int CurSiblings = -1;
1462 std::pair<StringRef, StringRef>
Data = Line.split(
':');
1464 auto Val =
Data.second.trim();
1466 if (
Name ==
"processor")
1467 Val.getAsInteger(10, CurProcessor);
1468 else if (
Name ==
"physical id")
1469 Val.getAsInteger(10, CurPhysicalId);
1470 else if (
Name ==
"siblings")
1471 Val.getAsInteger(10, CurSiblings);
1472 else if (
Name ==
"core id") {
1473 Val.getAsInteger(10, CurCoreId);
1475 if (CPU_ISSET(CurProcessor, &Affinity))
1476 CPU_SET(CurPhysicalId * CurSiblings + CurCoreId, &
Enabled);
1481 #elif defined(__linux__) && defined(__powerpc__)
1484 if (sched_getaffinity(0,
sizeof(Affinity), &Affinity) == 0)
1485 return CPU_COUNT(&Affinity);
1491 cpu_set_t *DynAffinity;
1492 DynAffinity = CPU_ALLOC(2048);
1493 if (sched_getaffinity(0, CPU_ALLOC_SIZE(2048), DynAffinity) == 0) {
1494 int NumCPUs = CPU_COUNT(DynAffinity);
1495 CPU_FREE(DynAffinity);
1500 #elif defined(__linux__) && defined(__s390x__)
1502 #elif defined(__APPLE__)
1506 size_t len =
sizeof(
count);
1507 sysctlbyname(
"hw.physicalcpu", &
count, &len, NULL, 0);
1511 nm[1] = HW_AVAILCPU;
1512 sysctl(nm, 2, &
count, &len, NULL, 0);
1518 #elif defined(__MVS__)
1531 CSD_NUMBER_ONLINE_STANDARD_CPS = 264,
1534 char *CVT =
reinterpret_cast<char *
>(
1535 static_cast<uintptr_t
>(
reinterpret_cast<unsigned int &
>(PSA[FLCCVT])));
1536 char *CSD =
reinterpret_cast<char *
>(
1537 static_cast<uintptr_t
>(
reinterpret_cast<unsigned int &
>(CVT[CVTCSD])));
1538 return reinterpret_cast<int &
>(CSD[CSD_NUMBER_ONLINE_STANDARD_CPS]);
1540 #elif defined(_WIN32) && LLVM_ENABLE_THREADS != 0
1553 #if defined(__i386__) || defined(_M_IX86) || \
1554 defined(__x86_64__) || defined(_M_X64)
1559 if (getX86CpuIDAndInfo(0, &MaxLevel, &
EBX, &
ECX, &
EDX) || MaxLevel < 1)
1564 Features[
"cx8"] = (
EDX >> 8) & 1;
1565 Features[
"cmov"] = (
EDX >> 15) & 1;
1566 Features[
"mmx"] = (
EDX >> 23) & 1;
1567 Features[
"fxsr"] = (
EDX >> 24) & 1;
1568 Features[
"sse"] = (
EDX >> 25) & 1;
1569 Features[
"sse2"] = (
EDX >> 26) & 1;
1571 Features[
"sse3"] = (
ECX >> 0) & 1;
1572 Features[
"pclmul"] = (
ECX >> 1) & 1;
1573 Features[
"ssse3"] = (
ECX >> 9) & 1;
1574 Features[
"cx16"] = (
ECX >> 13) & 1;
1575 Features[
"sse4.1"] = (
ECX >> 19) & 1;
1576 Features[
"sse4.2"] = (
ECX >> 20) & 1;
1577 Features[
"crc32"] = Features[
"sse4.2"];
1578 Features[
"movbe"] = (
ECX >> 22) & 1;
1579 Features[
"popcnt"] = (
ECX >> 23) & 1;
1580 Features[
"aes"] = (
ECX >> 25) & 1;
1581 Features[
"rdrnd"] = (
ECX >> 30) & 1;
1586 bool HasXSave = ((
ECX >> 27) & 1) && !getX86XCR0(&
EAX, &
EDX);
1587 bool HasAVXSave = HasXSave && ((
ECX >> 28) & 1) && ((
EAX & 0x6) == 0x6);
1588 #if defined(__APPLE__)
1592 bool HasAVX512Save =
true;
1595 bool HasAVX512Save = HasAVXSave && ((
EAX & 0xe0) == 0xe0);
1598 const unsigned AMXBits = (1 << 17) | (1 << 18);
1599 bool HasAMXSave = HasXSave && ((
EAX & AMXBits) == AMXBits);
1601 Features[
"avx"] = HasAVXSave;
1602 Features[
"fma"] = ((
ECX >> 12) & 1) && HasAVXSave;
1604 Features[
"xsave"] = ((
ECX >> 26) & 1) && HasAVXSave;
1605 Features[
"f16c"] = ((
ECX >> 29) & 1) && HasAVXSave;
1607 unsigned MaxExtLevel;
1608 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &
EBX, &
ECX, &
EDX);
1610 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1611 !getX86CpuIDAndInfo(0x80000001, &
EAX, &
EBX, &
ECX, &
EDX);
1612 Features[
"sahf"] = HasExtLeaf1 && ((
ECX >> 0) & 1);
1613 Features[
"lzcnt"] = HasExtLeaf1 && ((
ECX >> 5) & 1);
1614 Features[
"sse4a"] = HasExtLeaf1 && ((
ECX >> 6) & 1);
1615 Features[
"prfchw"] = HasExtLeaf1 && ((
ECX >> 8) & 1);
1616 Features[
"xop"] = HasExtLeaf1 && ((
ECX >> 11) & 1) && HasAVXSave;
1617 Features[
"lwp"] = HasExtLeaf1 && ((
ECX >> 15) & 1);
1618 Features[
"fma4"] = HasExtLeaf1 && ((
ECX >> 16) & 1) && HasAVXSave;
1619 Features[
"tbm"] = HasExtLeaf1 && ((
ECX >> 21) & 1);
1620 Features[
"mwaitx"] = HasExtLeaf1 && ((
ECX >> 29) & 1);
1622 Features[
"64bit"] = HasExtLeaf1 && ((
EDX >> 29) & 1);
1626 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
1627 !getX86CpuIDAndInfo(0x80000008, &
EAX, &
EBX, &
ECX, &
EDX);
1628 Features[
"clzero"] = HasExtLeaf8 && ((
EBX >> 0) & 1);
1629 Features[
"wbnoinvd"] = HasExtLeaf8 && ((
EBX >> 9) & 1);
1632 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &
EAX, &
EBX, &
ECX, &
EDX);
1634 Features[
"fsgsbase"] = HasLeaf7 && ((
EBX >> 0) & 1);
1635 Features[
"sgx"] = HasLeaf7 && ((
EBX >> 2) & 1);
1636 Features[
"bmi"] = HasLeaf7 && ((
EBX >> 3) & 1);
1638 Features[
"avx2"] = HasLeaf7 && ((
EBX >> 5) & 1) && HasAVXSave;
1639 Features[
"bmi2"] = HasLeaf7 && ((
EBX >> 8) & 1);
1640 Features[
"invpcid"] = HasLeaf7 && ((
EBX >> 10) & 1);
1641 Features[
"rtm"] = HasLeaf7 && ((
EBX >> 11) & 1);
1643 Features[
"avx512f"] = HasLeaf7 && ((
EBX >> 16) & 1) && HasAVX512Save;
1644 Features[
"avx512dq"] = HasLeaf7 && ((
EBX >> 17) & 1) && HasAVX512Save;
1645 Features[
"rdseed"] = HasLeaf7 && ((
EBX >> 18) & 1);
1646 Features[
"adx"] = HasLeaf7 && ((
EBX >> 19) & 1);
1647 Features[
"avx512ifma"] = HasLeaf7 && ((
EBX >> 21) & 1) && HasAVX512Save;
1648 Features[
"clflushopt"] = HasLeaf7 && ((
EBX >> 23) & 1);
1649 Features[
"clwb"] = HasLeaf7 && ((
EBX >> 24) & 1);
1650 Features[
"avx512pf"] = HasLeaf7 && ((
EBX >> 26) & 1) && HasAVX512Save;
1651 Features[
"avx512er"] = HasLeaf7 && ((
EBX >> 27) & 1) && HasAVX512Save;
1652 Features[
"avx512cd"] = HasLeaf7 && ((
EBX >> 28) & 1) && HasAVX512Save;
1653 Features[
"sha"] = HasLeaf7 && ((
EBX >> 29) & 1);
1654 Features[
"avx512bw"] = HasLeaf7 && ((
EBX >> 30) & 1) && HasAVX512Save;
1655 Features[
"avx512vl"] = HasLeaf7 && ((
EBX >> 31) & 1) && HasAVX512Save;
1657 Features[
"prefetchwt1"] = HasLeaf7 && ((
ECX >> 0) & 1);
1658 Features[
"avx512vbmi"] = HasLeaf7 && ((
ECX >> 1) & 1) && HasAVX512Save;
1659 Features[
"pku"] = HasLeaf7 && ((
ECX >> 4) & 1);
1660 Features[
"waitpkg"] = HasLeaf7 && ((
ECX >> 5) & 1);
1661 Features[
"avx512vbmi2"] = HasLeaf7 && ((
ECX >> 6) & 1) && HasAVX512Save;
1662 Features[
"shstk"] = HasLeaf7 && ((
ECX >> 7) & 1);
1663 Features[
"gfni"] = HasLeaf7 && ((
ECX >> 8) & 1);
1664 Features[
"vaes"] = HasLeaf7 && ((
ECX >> 9) & 1) && HasAVXSave;
1665 Features[
"vpclmulqdq"] = HasLeaf7 && ((
ECX >> 10) & 1) && HasAVXSave;
1666 Features[
"avx512vnni"] = HasLeaf7 && ((
ECX >> 11) & 1) && HasAVX512Save;
1667 Features[
"avx512bitalg"] = HasLeaf7 && ((
ECX >> 12) & 1) && HasAVX512Save;
1668 Features[
"avx512vpopcntdq"] = HasLeaf7 && ((
ECX >> 14) & 1) && HasAVX512Save;
1669 Features[
"rdpid"] = HasLeaf7 && ((
ECX >> 22) & 1);
1670 Features[
"kl"] = HasLeaf7 && ((
ECX >> 23) & 1);
1671 Features[
"cldemote"] = HasLeaf7 && ((
ECX >> 25) & 1);
1672 Features[
"movdiri"] = HasLeaf7 && ((
ECX >> 27) & 1);
1673 Features[
"movdir64b"] = HasLeaf7 && ((
ECX >> 28) & 1);
1674 Features[
"enqcmd"] = HasLeaf7 && ((
ECX >> 29) & 1);
1676 Features[
"uintr"] = HasLeaf7 && ((
EDX >> 5) & 1);
1677 Features[
"avx512vp2intersect"] =
1678 HasLeaf7 && ((
EDX >> 8) & 1) && HasAVX512Save;
1679 Features[
"serialize"] = HasLeaf7 && ((
EDX >> 14) & 1);
1680 Features[
"tsxldtrk"] = HasLeaf7 && ((
EDX >> 16) & 1);
1691 Features[
"pconfig"] = HasLeaf7 && ((
EDX >> 18) & 1);
1692 Features[
"amx-bf16"] = HasLeaf7 && ((
EDX >> 22) & 1) && HasAMXSave;
1693 Features[
"avx512fp16"] = HasLeaf7 && ((
EDX >> 23) & 1) && HasAVX512Save;
1694 Features[
"amx-tile"] = HasLeaf7 && ((
EDX >> 24) & 1) && HasAMXSave;
1695 Features[
"amx-int8"] = HasLeaf7 && ((
EDX >> 25) & 1) && HasAMXSave;
1696 bool HasLeaf7Subleaf1 =
1697 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &
EAX, &
EBX, &
ECX, &
EDX);
1698 Features[
"avxvnni"] = HasLeaf7Subleaf1 && ((
EAX >> 4) & 1) && HasAVXSave;
1699 Features[
"avx512bf16"] = HasLeaf7Subleaf1 && ((
EAX >> 5) & 1) && HasAVX512Save;
1700 Features[
"hreset"] = HasLeaf7Subleaf1 && ((
EAX >> 22) & 1);
1702 bool HasLeafD = MaxLevel >= 0xd &&
1703 !getX86CpuIDAndInfoEx(0xd, 0x1, &
EAX, &
EBX, &
ECX, &
EDX);
1706 Features[
"xsaveopt"] = HasLeafD && ((
EAX >> 0) & 1) && HasAVXSave;
1707 Features[
"xsavec"] = HasLeafD && ((
EAX >> 1) & 1) && HasAVXSave;
1708 Features[
"xsaves"] = HasLeafD && ((
EAX >> 3) & 1) && HasAVXSave;
1710 bool HasLeaf14 = MaxLevel >= 0x14 &&
1711 !getX86CpuIDAndInfoEx(0x14, 0x0, &
EAX, &
EBX, &
ECX, &
EDX);
1713 Features[
"ptwrite"] = HasLeaf14 && ((
EBX >> 4) & 1);
1716 MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &
EAX, &
EBX, &
ECX, &
EDX);
1717 Features[
"widekl"] = HasLeaf7 && HasLeaf19 && ((
EBX >> 2) & 1);
1721 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1728 P->getBuffer().split(Lines,
"\n");
1733 for (
unsigned I = 0,
E = Lines.size();
I !=
E; ++
I)
1735 Lines[
I].split(CPUFeatures,
' ');
1739 #if defined(__aarch64__)
1741 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1745 for (
unsigned I = 0,
E = CPUFeatures.size();
I !=
E; ++
I) {
1747 #if defined(__aarch64__)
1748 .
Case(
"asimd",
"neon")
1749 .
Case(
"fp",
"fp-armv8")
1750 .
Case(
"crc32",
"crc")
1751 .
Case(
"atomics",
"lse")
1753 .
Case(
"sve2",
"sve2")
1755 .
Case(
"half",
"fp16")
1756 .
Case(
"neon",
"neon")
1757 .
Case(
"vfpv3",
"vfp3")
1758 .
Case(
"vfpv3d16",
"d16")
1759 .
Case(
"vfpv4",
"vfp4")
1760 .
Case(
"idiva",
"hwdiv-arm")
1761 .
Case(
"idivt",
"hwdiv")
1765 #if defined(__aarch64__)
1768 if (CPUFeatures[
I] ==
"aes")
1770 else if (CPUFeatures[
I] ==
"pmull")
1771 crypto |= CAP_PMULL;
1772 else if (CPUFeatures[
I] ==
"sha1")
1774 else if (CPUFeatures[
I] ==
"sha2")
1778 if (LLVMFeatureStr !=
"")
1779 Features[LLVMFeatureStr] =
true;
1782 #if defined(__aarch64__)
1784 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
1785 Features[
"crypto"] =
true;
1790 #elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64))
1792 if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE))
1793 Features[
"neon"] =
true;
1794 if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE))
1795 Features[
"crc"] =
true;
1796 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE))
1797 Features[
"crypto"] =
true;
1806 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);