21 #include "llvm/Config/llvm-config.h" 39 #if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) 40 #include <mach/host_info.h> 41 #include <mach/mach.h> 42 #include <mach/mach_host.h> 43 #include <mach/machine.h> 46 #define DEBUG_TYPE "host-detection" 56 static std::unique_ptr<llvm::MemoryBuffer>
60 if (std::error_code EC = Text.
getError()) {
62 <<
"/proc/cpuinfo: " << EC.message() <<
"\n";
65 return std::move(*Text);
72 const char *
generic =
"generic";
86 while (CIP < CPUInfoEnd && CPUStart == 0) {
87 if (CIP < CPUInfoEnd && *CIP ==
'\n')
90 if (CIP < CPUInfoEnd && *CIP ==
'c') {
92 if (CIP < CPUInfoEnd && *CIP ==
'p') {
94 if (CIP < CPUInfoEnd && *CIP ==
'u') {
96 while (CIP < CPUInfoEnd && (*CIP ==
' ' || *CIP ==
'\t'))
99 if (CIP < CPUInfoEnd && *CIP ==
':') {
101 while (CIP < CPUInfoEnd && (*CIP ==
' ' || *CIP ==
'\t'))
104 if (CIP < CPUInfoEnd) {
106 while (CIP < CPUInfoEnd && (*CIP !=
' ' && *CIP !=
'\t' &&
107 *CIP !=
',' && *CIP !=
'\n'))
109 CPULen = CIP - CPUStart;
117 while (CIP < CPUInfoEnd && *CIP !=
'\n')
125 .Case(
"604e",
"604e")
127 .
Case(
"7400",
"7400")
128 .
Case(
"7410",
"7400")
129 .
Case(
"7447",
"7400")
130 .
Case(
"7455",
"7450")
132 .
Case(
"POWER4",
"970")
133 .
Case(
"PPC970FX",
"970")
134 .
Case(
"PPC970MP",
"970")
136 .
Case(
"POWER5",
"g5")
138 .
Case(
"POWER6",
"pwr6")
139 .
Case(
"POWER7",
"pwr7")
140 .
Case(
"POWER8",
"pwr8")
141 .
Case(
"POWER8E",
"pwr8")
142 .
Case(
"POWER8NVL",
"pwr8")
143 .
Case(
"POWER9",
"pwr9")
154 ProcCpuinfoContent.
split(Lines,
"\n");
159 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I) {
161 Implementer = Lines[
I].substr(15).ltrim(
"\t :");
163 Hardware = Lines[
I].substr(8).ltrim(
"\t :");
166 if (Implementer ==
"0x41") {
174 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
180 .Case(
"0x926",
"arm926ej-s")
181 .
Case(
"0xb02",
"mpcore")
182 .
Case(
"0xb36",
"arm1136j-s")
183 .
Case(
"0xb56",
"arm1156t2-s")
184 .
Case(
"0xb76",
"arm1176jz-s")
185 .
Case(
"0xc08",
"cortex-a8")
186 .
Case(
"0xc09",
"cortex-a9")
187 .
Case(
"0xc0f",
"cortex-a15")
188 .
Case(
"0xc20",
"cortex-m0")
189 .
Case(
"0xc23",
"cortex-m3")
190 .
Case(
"0xc24",
"cortex-m4")
191 .
Case(
"0xd04",
"cortex-a35")
192 .
Case(
"0xd03",
"cortex-a53")
193 .
Case(
"0xd07",
"cortex-a57")
194 .
Case(
"0xd08",
"cortex-a72")
195 .
Case(
"0xd09",
"cortex-a73")
199 if (Implementer ==
"0x42" || Implementer ==
"0x43") {
200 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I) {
203 .Case(
"0x516",
"thunderx2t99")
204 .
Case(
"0x0516",
"thunderx2t99")
205 .
Case(
"0xaf",
"thunderx2t99")
206 .
Case(
"0x0af",
"thunderx2t99")
207 .
Case(
"0xa1",
"thunderxt88")
208 .
Case(
"0x0a1",
"thunderxt88")
214 if (Implementer ==
"0x48")
216 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
222 .Case(
"0xd01",
"tsv110")
225 if (Implementer ==
"0x51")
227 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
233 .Case(
"0x06f",
"krait")
234 .
Case(
"0x201",
"kryo")
235 .
Case(
"0x205",
"kryo")
236 .
Case(
"0x211",
"kryo")
237 .
Case(
"0x800",
"cortex-a73")
238 .
Case(
"0x801",
"cortex-a73")
239 .
Case(
"0xc00",
"falkor")
240 .
Case(
"0xc01",
"saphira")
243 if (Implementer ==
"0x53") {
246 unsigned Variant = 0, Part = 0;
251 if (
I.consume_front(
"CPU variant"))
252 I.ltrim(
"\t :").getAsInteger(0, Variant);
257 if (
I.consume_front(
"CPU part"))
258 I.ltrim(
"\t :").getAsInteger(0, Part);
260 unsigned Exynos = (Variant << 12) | Part;
283 ProcCpuinfoContent.
split(Lines,
"\n");
287 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
289 size_t Pos = Lines[
I].find(
":");
291 Lines[
I].drop_front(Pos + 1).split(CPUFeatures,
' ');
299 bool HaveVectorSupport =
false;
300 for (
unsigned I = 0,
E = CPUFeatures.
size();
I !=
E; ++
I) {
301 if (CPUFeatures[
I] ==
"vx")
302 HaveVectorSupport =
true;
306 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I) {
308 size_t Pos = Lines[
I].find(
"machine = ");
310 Pos +=
sizeof(
"machine = ") - 1;
312 if (!Lines[
I].drop_front(Pos).getAsInteger(10, Id)) {
313 if (Id >= 3906 && HaveVectorSupport)
315 if (Id >= 2964 && HaveVectorSupport)
331 #if !defined(__linux__) || !defined(__x86_64__) 334 uint8_t insns[40] __attribute__ ((
aligned (8))) =
336 { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
338 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
340 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
342 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
344 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
346 struct bpf_prog_load_attr {
359 attr.insns = (uint64_t)insns;
360 attr.license = (uint64_t)
"DUMMY";
362 int fd = syscall(321 , 5 , &attr,
sizeof(attr));
371 #if defined(__i386__) || defined(_M_IX86) || \ 372 defined(__x86_64__) || defined(_M_X64) 374 enum VendorSignatures {
375 SIG_INTEL = 0x756e6547 ,
386 static bool isCpuIdSupported() {
387 #if defined(__GNUC__) || defined(__clang__) 388 #if defined(__i386__) 389 int __cpuid_supported;
392 " movl %%eax,%%ecx\n" 393 " xorl $0x00200000,%%eax\n" 399 " cmpl %%eax,%%ecx\n" 403 :
"=r"(__cpuid_supported)
406 if (!__cpuid_supported)
416 static bool getX86CpuIDAndInfo(
unsigned value,
unsigned *rEAX,
unsigned *rEBX,
417 unsigned *rECX,
unsigned *rEDX) {
418 #if defined(__GNUC__) || defined(__clang__) 419 #if defined(__x86_64__) 422 __asm__(
"movq\t%%rbx, %%rsi\n\t" 424 "xchgq\t%%rbx, %%rsi\n\t" 425 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
428 #elif defined(__i386__) 429 __asm__(
"movl\t%%ebx, %%esi\n\t" 431 "xchgl\t%%ebx, %%esi\n\t" 432 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
438 #elif defined(_MSC_VER) 441 __cpuid(registers, value);
442 *rEAX = registers[0];
443 *rEBX = registers[1];
444 *rECX = registers[2];
445 *rEDX = registers[3];
455 static bool getX86CpuIDAndInfoEx(
unsigned value,
unsigned subleaf,
456 unsigned *rEAX,
unsigned *rEBX,
unsigned *rECX,
458 #if defined(__GNUC__) || defined(__clang__) 459 #if defined(__x86_64__) 462 __asm__(
"movq\t%%rbx, %%rsi\n\t" 464 "xchgq\t%%rbx, %%rsi\n\t" 465 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
466 :
"a"(value),
"c"(subleaf));
468 #elif defined(__i386__) 469 __asm__(
"movl\t%%ebx, %%esi\n\t" 471 "xchgl\t%%ebx, %%esi\n\t" 472 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
473 :
"a"(value),
"c"(subleaf));
478 #elif defined(_MSC_VER) 480 __cpuidex(registers, value, subleaf);
481 *rEAX = registers[0];
482 *rEBX = registers[1];
483 *rECX = registers[2];
484 *rEDX = registers[3];
492 static bool getX86XCR0(
unsigned *rEAX,
unsigned *rEDX) {
493 #if defined(__GNUC__) || defined(__clang__) 497 __asm__(
".byte 0x0f, 0x01, 0xd0" :
"=a"(*rEAX),
"=d"(*rEDX) :
"c"(0));
499 #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) 500 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
502 *rEDX = Result >> 32;
509 static void detectX86FamilyModel(
unsigned EAX,
unsigned *Family,
511 *Family = (EAX >> 8) & 0xf;
512 *Model = (EAX >> 4) & 0xf;
513 if (*Family == 6 || *Family == 0xf) {
516 *Family += (EAX >> 20) & 0xff;
518 *Model += ((EAX >> 16) & 0xf) << 4;
523 getIntelProcessorTypeAndSubtype(
unsigned Family,
unsigned Model,
524 unsigned Brand_id,
unsigned Features,
525 unsigned Features2,
unsigned Features3,
526 unsigned *
Type,
unsigned *Subtype) {
531 *Type = X86::INTEL_i386;
534 *Type = X86::INTEL_i486;
537 if (Features & (1 << X86::FEATURE_MMX)) {
538 *Type = X86::INTEL_PENTIUM_MMX;
541 *Type = X86::INTEL_PENTIUM;
546 *Type = X86::INTEL_PENTIUM_PRO;
553 *Type = X86::INTEL_PENTIUM_II;
561 *Type = X86::INTEL_PENTIUM_III;
568 *Type = X86::INTEL_PENTIUM_M;
572 *Type = X86::INTEL_CORE_DUO;
581 *Type = X86::INTEL_CORE2;
582 *Subtype = X86::INTEL_CORE2_65;
590 *Type = X86::INTEL_CORE2;
591 *Subtype = X86::INTEL_CORE2_45;
599 *Type = X86::INTEL_COREI7;
600 *Subtype = X86::INTEL_COREI7_NEHALEM;
606 *Type = X86::INTEL_COREI7;
607 *Subtype = X86::INTEL_COREI7_WESTMERE;
612 *Type = X86::INTEL_COREI7;
613 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
617 *Type = X86::INTEL_COREI7;
618 *Subtype = X86::INTEL_COREI7_IVYBRIDGE;
626 *Type = X86::INTEL_COREI7;
627 *Subtype = X86::INTEL_COREI7_HASWELL;
635 *Type = X86::INTEL_COREI7;
636 *Subtype = X86::INTEL_COREI7_BROADWELL;
644 *Type = X86::INTEL_COREI7;
645 *Subtype = X86::INTEL_COREI7_SKYLAKE;
650 *Type = X86::INTEL_COREI7;
651 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
656 *Type = X86::INTEL_COREI7;
657 *Subtype = X86::INTEL_COREI7_CANNONLAKE;
665 *Type = X86::INTEL_BONNELL;
675 *Type = X86::INTEL_SILVERMONT;
680 *Type = X86::INTEL_GOLDMONT;
683 *Type = X86::INTEL_GOLDMONT_PLUS;
686 *Type = X86::INTEL_KNL;
689 *Type = X86::INTEL_KNM;
693 if (Features & (1 << X86::FEATURE_AVX512VBMI2)) {
694 *Type = X86::INTEL_COREI7;
695 *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT;
699 if (Features & (1 << X86::FEATURE_AVX512VBMI)) {
700 *Type = X86::INTEL_COREI7;
701 *Subtype = X86::INTEL_COREI7_CANNONLAKE;
705 if (Features2 & (1 << (X86::FEATURE_AVX512VNNI - 32))) {
706 *Type = X86::INTEL_COREI7;
707 *Subtype = X86::INTEL_COREI7_CASCADELAKE;
711 if (Features & (1 << X86::FEATURE_AVX512VL)) {
712 *Type = X86::INTEL_COREI7;
713 *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
717 if (Features & (1 << X86::FEATURE_AVX512ER)) {
718 *Type = X86::INTEL_KNL;
722 if (Features3 & (1 << (X86::FEATURE_CLFLUSHOPT - 64))) {
723 if (Features3 & (1 << (X86::FEATURE_SHA - 64))) {
724 *Type = X86::INTEL_GOLDMONT;
726 *Type = X86::INTEL_COREI7;
727 *Subtype = X86::INTEL_COREI7_SKYLAKE;
731 if (Features3 & (1 << (X86::FEATURE_ADX - 64))) {
732 *Type = X86::INTEL_COREI7;
733 *Subtype = X86::INTEL_COREI7_BROADWELL;
736 if (Features & (1 << X86::FEATURE_AVX2)) {
737 *Type = X86::INTEL_COREI7;
738 *Subtype = X86::INTEL_COREI7_HASWELL;
741 if (Features & (1 << X86::FEATURE_AVX)) {
742 *Type = X86::INTEL_COREI7;
743 *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
746 if (Features & (1 << X86::FEATURE_SSE4_2)) {
747 if (Features3 & (1 << (X86::FEATURE_MOVBE - 64))) {
748 *Type = X86::INTEL_SILVERMONT;
750 *Type = X86::INTEL_COREI7;
751 *Subtype = X86::INTEL_COREI7_NEHALEM;
755 if (Features & (1 << X86::FEATURE_SSE4_1)) {
756 *Type = X86::INTEL_CORE2;
757 *Subtype = X86::INTEL_CORE2_45;
760 if (Features & (1 << X86::FEATURE_SSSE3)) {
761 if (Features3 & (1 << (X86::FEATURE_MOVBE - 64))) {
762 *Type = X86::INTEL_BONNELL;
764 *Type = X86::INTEL_CORE2;
765 *Subtype = X86::INTEL_CORE2_65;
769 if (Features3 & (1 << (X86::FEATURE_EM64T - 64))) {
770 *Type = X86::INTEL_CORE2;
771 *Subtype = X86::INTEL_CORE2_65;
774 if (Features & (1 << X86::FEATURE_SSE3)) {
775 *Type = X86::INTEL_CORE_DUO;
778 if (Features & (1 << X86::FEATURE_SSE2)) {
779 *Type = X86::INTEL_PENTIUM_M;
782 if (Features & (1 << X86::FEATURE_SSE)) {
783 *Type = X86::INTEL_PENTIUM_III;
786 if (Features & (1 << X86::FEATURE_MMX)) {
787 *Type = X86::INTEL_PENTIUM_II;
790 *Type = X86::INTEL_PENTIUM_PRO;
795 if (Features3 & (1 << (X86::FEATURE_EM64T - 64))) {
796 *Type = X86::INTEL_NOCONA;
799 if (Features & (1 << X86::FEATURE_SSE3)) {
800 *Type = X86::INTEL_PRESCOTT;
803 *Type = X86::INTEL_PENTIUM_IV;
811 static void getAMDProcessorTypeAndSubtype(
unsigned Family,
unsigned Model,
812 unsigned Features,
unsigned *Type,
819 *Type = X86::AMD_i486;
822 *Type = X86::AMDPENTIUM;
826 *Subtype = X86::AMDPENTIUM_K6;
829 *Subtype = X86::AMDPENTIUM_K62;
833 *Subtype = X86::AMDPENTIUM_K63;
836 *Subtype = X86::AMDPENTIUM_GEODE;
841 if (Features & (1 << X86::FEATURE_SSE)) {
842 *Type = X86::AMD_ATHLON_XP;
845 *Type = X86::AMD_ATHLON;
848 if (Features & (1 << X86::FEATURE_SSE3)) {
849 *Type = X86::AMD_K8SSE3;
855 *Type = X86::AMDFAM10H;
858 *Subtype = X86::AMDFAM10H_BARCELONA;
861 *Subtype = X86::AMDFAM10H_SHANGHAI;
864 *Subtype = X86::AMDFAM10H_ISTANBUL;
869 *Type = X86::AMD_BTVER1;
872 *Type = X86::AMDFAM15H;
873 if (Model >= 0x60 && Model <= 0x7f) {
874 *Subtype = X86::AMDFAM15H_BDVER4;
877 if (Model >= 0x30 && Model <= 0x3f) {
878 *Subtype = X86::AMDFAM15H_BDVER3;
881 if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) {
882 *Subtype = X86::AMDFAM15H_BDVER2;
886 *Subtype = X86::AMDFAM15H_BDVER1;
891 *Type = X86::AMD_BTVER2;
894 *Type = X86::AMDFAM17H;
895 *Subtype = X86::AMDFAM17H_ZNVER1;
902 static void getAvailableFeatures(
unsigned ECX,
unsigned EDX,
unsigned MaxLeaf,
903 unsigned *FeaturesOut,
unsigned *Features2Out,
904 unsigned *Features3Out) {
905 unsigned Features = 0;
906 unsigned Features2 = 0;
907 unsigned Features3 = 0;
910 auto setFeature = [&](
unsigned F) {
912 Features |= 1U << (
F & 0x1f);
914 Features2 |= 1U << ((
F - 32) & 0x1f);
916 Features3 |= 1U << ((
F - 64) & 0x1f);
922 setFeature(X86::FEATURE_CMOV);
924 setFeature(X86::FEATURE_MMX);
926 setFeature(X86::FEATURE_SSE);
928 setFeature(X86::FEATURE_SSE2);
931 setFeature(X86::FEATURE_SSE3);
933 setFeature(X86::FEATURE_PCLMUL);
935 setFeature(X86::FEATURE_SSSE3);
939 setFeature(X86::FEATURE_SSE4_1);
941 setFeature(X86::FEATURE_SSE4_2);
943 setFeature(X86::FEATURE_POPCNT);
945 setFeature(X86::FEATURE_AES);
948 setFeature(X86::FEATURE_MOVBE);
953 const unsigned AVXBits = (1 << 27) | (1 << 28);
954 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
955 ((EAX & 0x6) == 0x6);
956 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
959 setFeature(X86::FEATURE_AVX);
962 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
964 if (HasLeaf7 && ((EBX >> 3) & 1))
965 setFeature(X86::FEATURE_BMI);
966 if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
967 setFeature(X86::FEATURE_AVX2);
968 if (HasLeaf7 && ((EBX >> 9) & 1))
969 setFeature(X86::FEATURE_BMI2);
970 if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
971 setFeature(X86::FEATURE_AVX512F);
972 if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
973 setFeature(X86::FEATURE_AVX512DQ);
974 if (HasLeaf7 && ((EBX >> 19) & 1))
975 setFeature(X86::FEATURE_ADX);
976 if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
977 setFeature(X86::FEATURE_AVX512IFMA);
978 if (HasLeaf7 && ((EBX >> 23) & 1))
979 setFeature(X86::FEATURE_CLFLUSHOPT);
980 if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
981 setFeature(X86::FEATURE_AVX512PF);
982 if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
983 setFeature(X86::FEATURE_AVX512ER);
984 if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
985 setFeature(X86::FEATURE_AVX512CD);
986 if (HasLeaf7 && ((EBX >> 29) & 1))
987 setFeature(X86::FEATURE_SHA);
988 if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
989 setFeature(X86::FEATURE_AVX512BW);
990 if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
991 setFeature(X86::FEATURE_AVX512VL);
993 if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
994 setFeature(X86::FEATURE_AVX512VBMI);
995 if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save)
996 setFeature(X86::FEATURE_AVX512VBMI2);
997 if (HasLeaf7 && ((ECX >> 8) & 1))
998 setFeature(X86::FEATURE_GFNI);
999 if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX)
1000 setFeature(X86::FEATURE_VPCLMULQDQ);
1001 if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save)
1002 setFeature(X86::FEATURE_AVX512VNNI);
1003 if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save)
1004 setFeature(X86::FEATURE_AVX512BITALG);
1005 if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
1006 setFeature(X86::FEATURE_AVX512VPOPCNTDQ);
1008 if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
1009 setFeature(X86::FEATURE_AVX5124VNNIW);
1010 if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
1011 setFeature(X86::FEATURE_AVX5124FMAPS);
1013 unsigned MaxExtLevel;
1014 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1016 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1017 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1018 if (HasExtLeaf1 && ((ECX >> 6) & 1))
1019 setFeature(X86::FEATURE_SSE4_A);
1020 if (HasExtLeaf1 && ((ECX >> 11) & 1))
1021 setFeature(X86::FEATURE_XOP);
1022 if (HasExtLeaf1 && ((ECX >> 16) & 1))
1023 setFeature(X86::FEATURE_FMA4);
1025 if (HasExtLeaf1 && ((EDX >> 29) & 1))
1026 setFeature(X86::FEATURE_EM64T);
1029 *Features2Out = Features2;
1030 *Features3Out = Features3;
1034 unsigned EAX = 0,
EBX = 0, ECX = 0, EDX = 0;
1035 unsigned MaxLeaf, Vendor;
1037 #if defined(__GNUC__) || defined(__clang__) 1042 if(!isCpuIdSupported())
1045 if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1)
1047 getX86CpuIDAndInfo(0x1, &EAX, &
EBX, &ECX, &EDX);
1049 unsigned Brand_id =
EBX & 0xff;
1050 unsigned Family = 0, Model = 0;
1051 unsigned Features = 0, Features2 = 0, Features3 = 0;
1052 detectX86FamilyModel(EAX, &Family, &Model);
1053 getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2, &Features3);
1056 unsigned Subtype = 0;
1058 if (Vendor == SIG_INTEL) {
1059 getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features,
1060 Features2, Features3, &Type, &Subtype);
1061 }
else if (Vendor == SIG_AMD) {
1062 getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
1066 #define X86_CPU_SUBTYPE(ARCHNAME, ENUM) \ 1067 if (Subtype == X86::ENUM) \ 1069 #include "llvm/Support/X86TargetParser.def" 1072 #define X86_CPU_TYPE(ARCHNAME, ENUM) \ 1073 if (Type == X86::ENUM) \ 1075 #include "llvm/Support/X86TargetParser.def" 1080 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) 1082 host_basic_info_data_t hostInfo;
1083 mach_msg_type_number_t infoCount;
1085 infoCount = HOST_BASIC_INFO_COUNT;
1086 mach_port_t hostPort = mach_host_self();
1087 host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
1089 mach_port_deallocate(mach_task_self(), hostPort);
1094 switch (hostInfo.cpu_subtype) {
1124 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)) 1127 StringRef Content = P ? P->getBuffer() :
"";
1130 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) 1133 StringRef Content = P ? P->getBuffer() :
"";
1136 #elif defined(__linux__) && defined(__s390x__) 1139 StringRef Content = P ? P->getBuffer() :
"";
1146 #if defined(__linux__) && defined(__x86_64__) 1155 if (std::error_code EC = Text.
getError()) {
1157 <<
"/proc/cpuinfo: " << EC.message() <<
"\n";
1161 (*Text)->getBuffer().split(strs,
"\n", -1,
1163 int CurPhysicalId = -1;
1166 for (
auto &Line : strs) {
1168 if (!Line.startswith(
"physical id") && !Line.startswith(
"core id"))
1170 std::pair<StringRef, StringRef>
Data = Line.split(
':');
1171 auto Name = Data.first.trim();
1172 auto Val = Data.second.trim();
1173 if (
Name ==
"physical id") {
1174 assert(CurPhysicalId == -1 &&
1175 "Expected a core id before seeing another physical id");
1176 Val.getAsInteger(10, CurPhysicalId);
1178 if (
Name ==
"core id") {
1179 assert(CurCoreId == -1 &&
1180 "Expected a physical id before seeing another core id");
1181 Val.getAsInteger(10, CurCoreId);
1183 if (CurPhysicalId != -1 && CurCoreId != -1) {
1184 UniqueItems.
insert(std::make_pair(CurPhysicalId, CurCoreId));
1189 return UniqueItems.
size();
1191 #elif defined(__APPLE__) && defined(__x86_64__) 1192 #include <sys/param.h> 1193 #include <sys/sysctl.h> 1198 size_t len =
sizeof(
count);
1199 sysctlbyname(
"hw.physicalcpu", &count, &len, NULL, 0);
1203 nm[1] = HW_AVAILCPU;
1204 sysctl(nm, 2, &count, &len, NULL, 0);
1220 #if defined(__i386__) || defined(_M_IX86) || \ 1221 defined(__x86_64__) || defined(_M_X64) 1223 unsigned EAX = 0,
EBX = 0, ECX = 0, EDX = 0;
1230 if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
1234 getX86CpuIDAndInfo(1, &EAX, &
EBX, &ECX, &EDX);
1236 Features[
"cmov"] = (EDX >> 15) & 1;
1237 Features[
"mmx"] = (EDX >> 23) & 1;
1238 Features[
"sse"] = (EDX >> 25) & 1;
1239 Features[
"sse2"] = (EDX >> 26) & 1;
1241 Features[
"sse3"] = (ECX >> 0) & 1;
1242 Features[
"pclmul"] = (ECX >> 1) & 1;
1243 Features[
"ssse3"] = (ECX >> 9) & 1;
1244 Features[
"cx16"] = (ECX >> 13) & 1;
1245 Features[
"sse4.1"] = (ECX >> 19) & 1;
1246 Features[
"sse4.2"] = (ECX >> 20) & 1;
1247 Features[
"movbe"] = (ECX >> 22) & 1;
1248 Features[
"popcnt"] = (ECX >> 23) & 1;
1249 Features[
"aes"] = (ECX >> 25) & 1;
1250 Features[
"rdrnd"] = (ECX >> 30) & 1;
1255 bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
1256 !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
1258 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
1260 Features[
"avx"] = HasAVXSave;
1261 Features[
"fma"] = ((ECX >> 12) & 1) && HasAVXSave;
1263 Features[
"xsave"] = ((ECX >> 26) & 1) && HasAVXSave;
1264 Features[
"f16c"] = ((ECX >> 29) & 1) && HasAVXSave;
1266 unsigned MaxExtLevel;
1267 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &
EBX, &ECX, &EDX);
1269 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1270 !getX86CpuIDAndInfo(0x80000001, &EAX, &
EBX, &ECX, &EDX);
1271 Features[
"sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1);
1272 Features[
"lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1273 Features[
"sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1274 Features[
"prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1275 Features[
"xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
1276 Features[
"lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1);
1277 Features[
"fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1278 Features[
"tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
1279 Features[
"mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
1281 Features[
"64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1);
1285 bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
1286 !getX86CpuIDAndInfo(0x80000008, &EAX, &
EBX, &ECX, &EDX);
1287 Features[
"clzero"] = HasExtLeaf8 && ((
EBX >> 0) & 1);
1288 Features[
"wbnoinvd"] = HasExtLeaf8 && ((
EBX >> 9) & 1);
1291 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &
EBX, &ECX, &EDX);
1293 Features[
"fsgsbase"] = HasLeaf7 && ((
EBX >> 0) & 1);
1294 Features[
"sgx"] = HasLeaf7 && ((
EBX >> 2) & 1);
1295 Features[
"bmi"] = HasLeaf7 && ((
EBX >> 3) & 1);
1297 Features[
"avx2"] = HasLeaf7 && ((
EBX >> 5) & 1) && HasAVXSave;
1298 Features[
"bmi2"] = HasLeaf7 && ((
EBX >> 8) & 1);
1299 Features[
"invpcid"] = HasLeaf7 && ((
EBX >> 10) & 1);
1300 Features[
"rtm"] = HasLeaf7 && ((
EBX >> 11) & 1);
1302 Features[
"avx512f"] = HasLeaf7 && ((
EBX >> 16) & 1) && HasAVX512Save;
1303 Features[
"avx512dq"] = HasLeaf7 && ((
EBX >> 17) & 1) && HasAVX512Save;
1304 Features[
"rdseed"] = HasLeaf7 && ((
EBX >> 18) & 1);
1305 Features[
"adx"] = HasLeaf7 && ((
EBX >> 19) & 1);
1306 Features[
"avx512ifma"] = HasLeaf7 && ((
EBX >> 21) & 1) && HasAVX512Save;
1307 Features[
"clflushopt"] = HasLeaf7 && ((
EBX >> 23) & 1);
1308 Features[
"clwb"] = HasLeaf7 && ((
EBX >> 24) & 1);
1309 Features[
"avx512pf"] = HasLeaf7 && ((
EBX >> 26) & 1) && HasAVX512Save;
1310 Features[
"avx512er"] = HasLeaf7 && ((
EBX >> 27) & 1) && HasAVX512Save;
1311 Features[
"avx512cd"] = HasLeaf7 && ((
EBX >> 28) & 1) && HasAVX512Save;
1312 Features[
"sha"] = HasLeaf7 && ((
EBX >> 29) & 1);
1313 Features[
"avx512bw"] = HasLeaf7 && ((
EBX >> 30) & 1) && HasAVX512Save;
1314 Features[
"avx512vl"] = HasLeaf7 && ((
EBX >> 31) & 1) && HasAVX512Save;
1316 Features[
"prefetchwt1"] = HasLeaf7 && ((ECX >> 0) & 1);
1317 Features[
"avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
1318 Features[
"pku"] = HasLeaf7 && ((ECX >> 4) & 1);
1319 Features[
"waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1);
1320 Features[
"avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save;
1321 Features[
"shstk"] = HasLeaf7 && ((ECX >> 7) & 1);
1322 Features[
"gfni"] = HasLeaf7 && ((ECX >> 8) & 1);
1323 Features[
"vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave;
1324 Features[
"vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave;
1325 Features[
"avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save;
1326 Features[
"avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
1327 Features[
"avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
1328 Features[
"rdpid"] = HasLeaf7 && ((ECX >> 22) & 1);
1329 Features[
"cldemote"] = HasLeaf7 && ((ECX >> 25) & 1);
1330 Features[
"movdiri"] = HasLeaf7 && ((ECX >> 27) & 1);
1331 Features[
"movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1);
1343 Features[
"pconfig"] = HasLeaf7 && ((EDX >> 18) & 1);
1345 bool HasLeafD = MaxLevel >= 0xd &&
1346 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &
EBX, &ECX, &EDX);
1349 Features[
"xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave;
1350 Features[
"xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave;
1351 Features[
"xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave;
1353 bool HasLeaf14 = MaxLevel >= 0x14 &&
1354 !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &
EBX, &ECX, &EDX);
1356 Features[
"ptwrite"] = HasLeaf14 && ((
EBX >> 4) & 1);
1360 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) 1367 P->getBuffer().split(Lines,
"\n");
1372 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
1374 Lines[
I].split(CPUFeatures,
' ');
1378 #if defined(__aarch64__) 1380 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1384 for (
unsigned I = 0,
E = CPUFeatures.
size();
I !=
E; ++
I) {
1386 #
if defined(__aarch64__)
1387 .
Case(
"asimd",
"neon")
1388 .
Case(
"fp",
"fp-armv8")
1389 .
Case(
"crc32",
"crc")
1391 .
Case(
"half",
"fp16")
1392 .
Case(
"neon",
"neon")
1393 .
Case(
"vfpv3",
"vfp3")
1394 .
Case(
"vfpv3d16",
"d16")
1395 .
Case(
"vfpv4",
"vfp4")
1396 .
Case(
"idiva",
"hwdiv-arm")
1397 .
Case(
"idivt",
"hwdiv")
1401 #if defined(__aarch64__) 1404 if (CPUFeatures[
I] ==
"aes")
1406 else if (CPUFeatures[
I] ==
"pmull")
1407 crypto |= CAP_PMULL;
1408 else if (CPUFeatures[
I] ==
"sha1")
1410 else if (CPUFeatures[
I] ==
"sha2")
1414 if (LLVMFeatureStr !=
"")
1415 Features[LLVMFeatureStr] =
true;
1418 #if defined(__aarch64__) 1420 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
1421 Features[
"crypto"] =
true;
1431 std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
Represents either an error or a value T.
static std::unique_ptr< llvm::MemoryBuffer > LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent()
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
This class represents lattice values for constants.
StringRef getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent)
Helper functions to extract HostCPUName from /proc/cpuinfo on linux.
const FeatureBitset Features
StringRef getHostCPUNameForS390x(StringRef ProcCpuinfoContent)
int getHostNumPhysicalCores()
Get the number of physical cores (as opposed to logical cores returned from thread::hardware_concurre...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
static bool startswith(StringRef Magic, const char(&S)[N])
bool isArch32Bit() const
Test whether the architecture is 32-bit.
const std::string & str() const
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
A switch()-like statement whose cases are string literals.
llvm::Triple get32BitArchVariant() const
Form a triple with a 32-bit variant of the current architecture.
StringRef getHostCPUNameForBPF()
The instances of the Type class are immutable: once they are created, they are never changed...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::error_code getError() const
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
std::string normalize() const
Return the normalized form of this triple's string.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
StringRef getHostCPUName()
getHostCPUName - Get the LLVM name for the host CPU.
bool isArch64Bit() const
Test whether the architecture is 64-bit.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileAsStream(const Twine &Filename)
Read all of the specified file into a MemoryBuffer as a stream (i.e.
StringRef getHostCPUNameForARM(StringRef ProcCpuinfoContent)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::Triple get64BitArchVariant() const
Form a triple with a 64-bit variant of the current architecture.
StringRef - Represent a constant reference to a string, i.e.
bool getHostCPUFeatures(StringMap< bool > &Features)
getHostCPUFeatures - Get the LLVM names for the host CPU features.
#define LLVM_ATTRIBUTE_UNUSED
static int computeHostNumPhysicalCores()