20 #include "llvm/Config/config.h"
38 #if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
39 #include <mach/host_info.h>
40 #include <mach/mach.h>
41 #include <mach/mach_host.h>
42 #include <mach/machine.h>
45 #define DEBUG_TYPE "host-detection"
55 #if defined(__linux__)
64 DEBUG(
dbgs() <<
"Unable to open /proc/cpuinfo: " << EC.message() <<
"\n");
68 int CloseStatus = close(FD);
75 #if defined(__i386__) || defined(_M_IX86) || \
76 defined(__x86_64__) || defined(_M_X64)
78 enum VendorSignatures {
79 SIG_INTEL = 0x756e6547 ,
83 enum ProcessorVendors {
118 enum ProcessorSubtypes {
119 INTEL_COREI7_NEHALEM = 1,
120 INTEL_COREI7_WESTMERE,
121 INTEL_COREI7_SANDYBRIDGE,
130 INTEL_COREI7_IVYBRIDGE,
131 INTEL_COREI7_HASWELL,
132 INTEL_COREI7_BROADWELL,
133 INTEL_COREI7_SKYLAKE,
134 INTEL_COREI7_SKYLAKE_AVX512,
136 INTEL_ATOM_SILVERMONT,
137 INTEL_KNIGHTS_LANDING,
157 enum ProcessorFeatures {
183 static bool isCpuIdSupported() {
184 #if defined(__GNUC__) || defined(__clang__)
185 #if defined(__i386__)
186 int __cpuid_supported;
189 " movl %%eax,%%ecx\n"
190 " xorl $0x00200000,%%eax\n"
196 " cmpl %%eax,%%ecx\n"
200 :
"=r"(__cpuid_supported)
203 if (!__cpuid_supported)
213 static bool getX86CpuIDAndInfo(
unsigned value,
unsigned *rEAX,
unsigned *rEBX,
214 unsigned *rECX,
unsigned *rEDX) {
215 #if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
216 #if defined(__GNUC__) || defined(__clang__)
217 #if defined(__x86_64__)
220 __asm__(
"movq\t%%rbx, %%rsi\n\t"
222 "xchgq\t%%rbx, %%rsi\n\t"
223 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
225 #elif defined(__i386__)
226 __asm__(
"movl\t%%ebx, %%esi\n\t"
228 "xchgl\t%%ebx, %%esi\n\t"
229 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
232 assert(0 &&
"This method is defined only for x86.");
234 #elif defined(_MSC_VER)
237 __cpuid(registers, value);
238 *rEAX = registers[0];
239 *rEBX = registers[1];
240 *rECX = registers[2];
241 *rEDX = registers[3];
252 static bool getX86CpuIDAndInfoEx(
unsigned value,
unsigned subleaf,
253 unsigned *rEAX,
unsigned *rEBX,
unsigned *rECX,
255 #if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
256 #if defined(__x86_64__) || defined(_M_X64)
257 #if defined(__GNUC__) || defined(__clang__)
260 __asm__(
"movq\t%%rbx, %%rsi\n\t"
262 "xchgq\t%%rbx, %%rsi\n\t"
263 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
264 :
"a"(value),
"c"(subleaf));
265 #elif defined(_MSC_VER)
267 __cpuidex(registers, value, subleaf);
268 *rEAX = registers[0];
269 *rEBX = registers[1];
270 *rECX = registers[2];
271 *rEDX = registers[3];
273 #elif defined(__i386__) || defined(_M_IX86)
274 #if defined(__GNUC__) || defined(__clang__)
275 __asm__(
"movl\t%%ebx, %%esi\n\t"
277 "xchgl\t%%ebx, %%esi\n\t"
278 :
"=a"(*rEAX),
"=S"(*rEBX),
"=c"(*rECX),
"=d"(*rEDX)
279 :
"a"(value),
"c"(subleaf));
280 #elif defined(_MSC_VER)
286 mov dword ptr [esi],eax
288 mov dword ptr [esi],ebx
290 mov dword ptr [esi],ecx
292 mov dword ptr [esi],edx
296 assert(0 &&
"This method is defined only for x86.");
304 static bool getX86XCR0(
unsigned *rEAX,
unsigned *rEDX) {
305 #if defined(__GNUC__) || defined(__clang__)
309 __asm__(
".byte 0x0f, 0x01, 0xd0" :
"=a"(*rEAX),
"=d"(*rEDX) :
"c"(0));
311 #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
312 unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
314 *rEDX = Result >> 32;
321 static void detectX86FamilyModel(
unsigned EAX,
unsigned *Family,
323 *Family = (EAX >> 8) & 0xf;
324 *Model = (EAX >> 4) & 0xf;
325 if (*Family == 6 || *Family == 0xf) {
328 *Family += (EAX >> 20) & 0xff;
330 *Model += ((EAX >> 16) & 0xf) << 4;
335 getIntelProcessorTypeAndSubtype(
unsigned int Family,
unsigned int Model,
336 unsigned int Brand_id,
unsigned int Features,
337 unsigned *
Type,
unsigned *Subtype) {
369 *Type = INTEL_PENTIUM;
374 *Type = INTEL_PENTIUM;
375 *Subtype = INTEL_PENTIUM_MMX;
378 *Type = INTEL_PENTIUM;
385 *Type = INTEL_PENTIUM_PRO;
392 *Type = INTEL_PENTIUM_II;
400 *Type = INTEL_PENTIUM_III;
407 *Type = INTEL_PENTIUM_M;
411 *Type = INTEL_CORE_DUO;
421 *Subtype = INTEL_CORE2_65;
430 *Subtype = INTEL_CORE2_45;
438 *Type = INTEL_COREI7;
439 *Subtype = INTEL_COREI7_NEHALEM;
445 *Type = INTEL_COREI7;
446 *Subtype = INTEL_COREI7_WESTMERE;
451 *Type = INTEL_COREI7;
452 *Subtype = INTEL_COREI7_SANDYBRIDGE;
456 *Type = INTEL_COREI7;
457 *Subtype = INTEL_COREI7_IVYBRIDGE;
465 *Type = INTEL_COREI7;
466 *Subtype = INTEL_COREI7_HASWELL;
474 *Type = INTEL_COREI7;
475 *Subtype = INTEL_COREI7_BROADWELL;
483 *Type = INTEL_COREI7;
484 *Subtype = INTEL_COREI7_SKYLAKE;
489 *Type = INTEL_COREI7;
491 if (Features & (1 << FEATURE_AVX512)) {
492 *Subtype = INTEL_COREI7_SKYLAKE_AVX512;
494 *Subtype = INTEL_COREI7_SKYLAKE;
504 *Subtype = INTEL_ATOM_BONNELL;
515 *Subtype = INTEL_ATOM_SILVERMONT;
519 *Type = INTEL_XEONPHI;
520 *Subtype = INTEL_KNIGHTS_LANDING;
524 if (Features & (1 << FEATURE_AVX512)) {
525 *Type = INTEL_XEONPHI;
526 *Subtype = INTEL_KNIGHTS_LANDING;
529 if (Features & (1 << FEATURE_ADX)) {
530 *Type = INTEL_COREI7;
531 *Subtype = INTEL_COREI7_BROADWELL;
534 if (Features & (1 << FEATURE_AVX2)) {
535 *Type = INTEL_COREI7;
536 *Subtype = INTEL_COREI7_HASWELL;
539 if (Features & (1 << FEATURE_AVX)) {
540 *Type = INTEL_COREI7;
541 *Subtype = INTEL_COREI7_SANDYBRIDGE;
544 if (Features & (1 << FEATURE_SSE4_2)) {
545 if (Features & (1 << FEATURE_MOVBE)) {
547 *Subtype = INTEL_ATOM_SILVERMONT;
549 *Type = INTEL_COREI7;
550 *Subtype = INTEL_COREI7_NEHALEM;
554 if (Features & (1 << FEATURE_SSE4_1)) {
556 *Subtype = INTEL_CORE2_45;
559 if (Features & (1 << FEATURE_SSSE3)) {
560 if (Features & (1 << FEATURE_MOVBE)) {
562 *Subtype = INTEL_ATOM_BONNELL;
565 *Subtype = INTEL_CORE2_65;
569 if (Features & (1 << FEATURE_EM64T)) {
570 *Type = INTEL_X86_64;
573 if (Features & (1 << FEATURE_SSE2)) {
574 *Type = INTEL_PENTIUM_M;
577 if (Features & (1 << FEATURE_SSE)) {
578 *Type = INTEL_PENTIUM_III;
581 if (Features & (1 << FEATURE_MMX)) {
582 *Type = INTEL_PENTIUM_II;
585 *Type = INTEL_PENTIUM_PRO;
601 ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV);
616 ((Features & (1 << FEATURE_EM64T)) ? INTEL_NOCONA : INTEL_PRESCOTT);
621 ((Features & (1 << FEATURE_EM64T)) ? INTEL_X86_64 : INTEL_PENTIUM_IV);
631 static void getAMDProcessorTypeAndSubtype(
unsigned int Family,
633 unsigned int Features,
648 *Subtype = AMDPENTIUM_K6;
651 *Subtype = AMDPENTIUM_K62;
655 *Subtype = AMDPENTIUM_K63;
658 *Subtype = AMDPENTIUM_GEODE;
666 *Subtype = AMDATHLON_TBIRD;
671 *Subtype = AMDATHLON_MP;
674 *Subtype = AMDATHLON_XP;
680 if (Features & (1 << FEATURE_SSE3)) {
681 *Subtype = AMDATHLON_K8SSE3;
686 *Subtype = AMDATHLON_OPTERON;
689 *Subtype = AMDATHLON_FX;
692 *Subtype = AMDATHLON_64;
700 *Subtype = AMDFAM10H_BARCELONA;
703 *Subtype = AMDFAM10H_SHANGHAI;
706 *Subtype = AMDFAM10H_ISTANBUL;
712 *Subtype = AMD_BTVER1;
717 (1 << FEATURE_AVX))) {
718 *Subtype = AMD_BTVER1;
721 if (Model >= 0x50 && Model <= 0x6f) {
722 *Subtype = AMDFAM15H_BDVER4;
725 if (Model >= 0x30 && Model <= 0x3f) {
726 *Subtype = AMDFAM15H_BDVER3;
729 if (Model >= 0x10 && Model <= 0x1f) {
730 *Subtype = AMDFAM15H_BDVER2;
734 *Subtype = AMDFAM15H_BDVER1;
741 (1 << FEATURE_AVX))) {
742 *Subtype = AMD_BTVER1;
745 *Subtype = AMD_BTVER2;
749 if (Features & (1 << FEATURE_ADX)) {
750 *Subtype = AMDFAM17H_ZNVER1;
753 *Subtype = AMD_BTVER1;
760 static unsigned getAvailableFeatures(
unsigned int ECX,
unsigned int EDX,
762 unsigned Features = 0;
763 unsigned int EAX,
EBX;
764 Features |= (((EDX >> 23) & 1) << FEATURE_MMX);
765 Features |= (((EDX >> 25) & 1) << FEATURE_SSE);
766 Features |= (((EDX >> 26) & 1) << FEATURE_SSE2);
767 Features |= (((ECX >> 0) & 1) << FEATURE_SSE3);
768 Features |= (((ECX >> 9) & 1) << FEATURE_SSSE3);
769 Features |= (((ECX >> 19) & 1) << FEATURE_SSE4_1);
770 Features |= (((ECX >> 20) & 1) << FEATURE_SSE4_2);
771 Features |= (((ECX >> 22) & 1) << FEATURE_MOVBE);
776 const unsigned AVXBits = (1 << 27) | (1 << 28);
777 bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
778 ((EAX & 0x6) == 0x6);
779 bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
781 MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
782 bool HasADX = HasLeaf7 && ((EBX >> 19) & 1);
783 bool HasAVX2 = HasAVX && HasLeaf7 && (
EBX & 0x20);
784 bool HasAVX512 = HasLeaf7 && HasAVX512Save && ((
EBX >> 16) & 1);
785 Features |= (HasAVX << FEATURE_AVX);
786 Features |= (HasAVX2 << FEATURE_AVX2);
787 Features |= (HasAVX512 << FEATURE_AVX512);
788 Features |= (HasAVX512Save << FEATURE_AVX512SAVE);
789 Features |= (HasADX << FEATURE_ADX);
791 getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
792 Features |= (((
EDX >> 29) & 0x1) << FEATURE_EM64T);
797 unsigned EAX = 0,
EBX = 0,
ECX = 0,
EDX = 0;
798 unsigned MaxLeaf, Vendor;
800 #if defined(__GNUC__) || defined(__clang__)
805 if(!isCpuIdSupported())
808 if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX))
810 if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
813 unsigned Brand_id =
EBX & 0xff;
814 unsigned Family = 0, Model = 0;
815 unsigned Features = 0;
816 detectX86FamilyModel(EAX, &Family, &Model);
817 Features = getAvailableFeatures(ECX, EDX, MaxLeaf);
822 if (Vendor == SIG_INTEL) {
823 getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features, &Type,
831 if (Subtype == INTEL_PENTIUM_MMX)
832 return "pentium-mmx";
834 case INTEL_PENTIUM_PRO:
836 case INTEL_PENTIUM_II:
838 case INTEL_PENTIUM_III:
840 case INTEL_PENTIUM_IV:
842 case INTEL_PENTIUM_M:
857 case INTEL_COREI7_NEHALEM:
859 case INTEL_COREI7_WESTMERE:
861 case INTEL_COREI7_SANDYBRIDGE:
862 return "sandybridge";
863 case INTEL_COREI7_IVYBRIDGE:
865 case INTEL_COREI7_HASWELL:
867 case INTEL_COREI7_BROADWELL:
869 case INTEL_COREI7_SKYLAKE:
871 case INTEL_COREI7_SKYLAKE_AVX512:
872 return "skylake-avx512";
878 case INTEL_ATOM_BONNELL:
880 case INTEL_ATOM_SILVERMONT:
896 }
else if (Vendor == SIG_AMD) {
897 getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
909 case AMDPENTIUM_GEODE:
916 case AMDATHLON_TBIRD:
917 return "athlon-tbird";
922 case AMDATHLON_K8SSE3:
924 case AMDATHLON_OPTERON:
934 if(Subtype == AMDFAM10H_BARCELONA)
941 case AMDFAM15H_BDVER1:
943 case AMDFAM15H_BDVER2:
945 case AMDFAM15H_BDVER3:
947 case AMDFAM15H_BDVER4:
967 case AMDFAM17H_ZNVER1:
979 #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
981 host_basic_info_data_t hostInfo;
982 mach_msg_type_number_t infoCount;
984 infoCount = HOST_BASIC_INFO_COUNT;
985 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
991 switch (hostInfo.cpu_subtype) {
1021 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
1026 const char *
generic =
"generic";
1031 ssize_t CPUInfoSize = readCpuInfo(buffer,
sizeof(buffer));
1032 if (CPUInfoSize == -1)
1035 const char *CPUInfoStart = buffer;
1036 const char *CPUInfoEnd = buffer + CPUInfoSize;
1038 const char *CIP = CPUInfoStart;
1040 const char *CPUStart = 0;
1045 while (CIP < CPUInfoEnd && CPUStart == 0) {
1046 if (CIP < CPUInfoEnd && *CIP ==
'\n')
1049 if (CIP < CPUInfoEnd && *CIP ==
'c') {
1051 if (CIP < CPUInfoEnd && *CIP ==
'p') {
1053 if (CIP < CPUInfoEnd && *CIP ==
'u') {
1055 while (CIP < CPUInfoEnd && (*CIP ==
' ' || *CIP ==
'\t'))
1058 if (CIP < CPUInfoEnd && *CIP ==
':') {
1060 while (CIP < CPUInfoEnd && (*CIP ==
' ' || *CIP ==
'\t'))
1063 if (CIP < CPUInfoEnd) {
1065 while (CIP < CPUInfoEnd && (*CIP !=
' ' && *CIP !=
'\t' &&
1066 *CIP !=
',' && *CIP !=
'\n'))
1068 CPULen = CIP - CPUStart;
1076 while (CIP < CPUInfoEnd && *CIP !=
'\n')
1084 .Case(
"604e",
"604e")
1086 .
Case(
"7400",
"7400")
1087 .
Case(
"7410",
"7400")
1088 .
Case(
"7447",
"7400")
1089 .
Case(
"7455",
"7450")
1091 .
Case(
"POWER4",
"970")
1092 .
Case(
"PPC970FX",
"970")
1093 .
Case(
"PPC970MP",
"970")
1095 .
Case(
"POWER5",
"g5")
1097 .
Case(
"POWER6",
"pwr6")
1098 .
Case(
"POWER7",
"pwr7")
1099 .
Case(
"POWER8",
"pwr8")
1100 .
Case(
"POWER8E",
"pwr8")
1101 .
Case(
"POWER8NVL",
"pwr8")
1102 .
Case(
"POWER9",
"pwr9")
1105 #elif defined(__linux__) && defined(__arm__)
1113 ssize_t CPUInfoSize = readCpuInfo(buffer,
sizeof(buffer));
1114 if (CPUInfoSize == -1)
1120 Str.split(Lines,
"\n");
1124 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
1126 Implementer = Lines[
I].substr(15).ltrim(
"\t :");
1128 if (Implementer ==
"0x41")
1130 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
1136 .Case(
"0x926",
"arm926ej-s")
1137 .
Case(
"0xb02",
"mpcore")
1138 .
Case(
"0xb36",
"arm1136j-s")
1139 .
Case(
"0xb56",
"arm1156t2-s")
1140 .
Case(
"0xb76",
"arm1176jz-s")
1141 .
Case(
"0xc08",
"cortex-a8")
1142 .
Case(
"0xc09",
"cortex-a9")
1143 .
Case(
"0xc0f",
"cortex-a15")
1144 .
Case(
"0xc20",
"cortex-m0")
1145 .
Case(
"0xc23",
"cortex-m3")
1146 .
Case(
"0xc24",
"cortex-m4")
1149 if (Implementer ==
"0x51")
1151 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
1157 .Case(
"0x06f",
"krait")
1162 #elif defined(__linux__) && defined(__s390x__)
1169 ssize_t CPUInfoSize = readCpuInfo(buffer,
sizeof(buffer));
1170 if (CPUInfoSize == -1)
1175 Str.split(Lines,
"\n");
1179 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
1181 size_t Pos = Lines[
I].find(
":");
1183 Lines[
I].drop_front(Pos + 1).split(CPUFeatures,
' ');
1191 bool HaveVectorSupport =
false;
1192 for (
unsigned I = 0,
E = CPUFeatures.
size();
I !=
E; ++
I) {
1193 if (CPUFeatures[
I] ==
"vx")
1194 HaveVectorSupport =
true;
1198 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I) {
1200 size_t Pos = Lines[
I].find(
"machine = ");
1202 Pos +=
sizeof(
"machine = ") - 1;
1204 if (!Lines[
I].drop_front(Pos).getAsInteger(10, Id)) {
1205 if (Id >= 2964 && HaveVectorSupport)
1223 #if defined(__linux__) && defined(__x86_64__)
1232 if (std::error_code EC = Text.
getError()) {
1234 <<
"/proc/cpuinfo: " << EC.message() <<
"\n";
1237 (*Text)->getBuffer().split(strs,
"\n", -1,
1239 int CurPhysicalId = -1;
1242 for (
auto &Line : strs) {
1244 if (!Line.startswith(
"physical id") && !Line.startswith(
"core id"))
1246 std::pair<StringRef, StringRef> Data = Line.split(
':');
1247 auto Name = Data.first.trim();
1248 auto Val = Data.second.trim();
1249 if (
Name ==
"physical id") {
1250 assert(CurPhysicalId == -1 &&
1251 "Expected a core id before seeing another physical id");
1252 Val.getAsInteger(10, CurPhysicalId);
1254 if (
Name ==
"core id") {
1255 assert(CurCoreId == -1 &&
1256 "Expected a physical id before seeing another core id");
1257 Val.getAsInteger(10, CurCoreId);
1259 if (CurPhysicalId != -1 && CurCoreId != -1) {
1260 UniqueItems.
insert(std::make_pair(CurPhysicalId, CurCoreId));
1265 return UniqueItems.
size();
1267 #elif defined(__APPLE__) && defined(__x86_64__)
1268 #include <sys/param.h>
1269 #include <sys/sysctl.h>
1274 size_t len =
sizeof(
count);
1275 sysctlbyname(
"hw.physicalcpu", &count, &len, NULL, 0);
1279 nm[1] = HW_AVAILCPU;
1280 sysctl(nm, 2, &count, &len, NULL, 0);
1296 #if defined(__i386__) || defined(_M_IX86) || \
1297 defined(__x86_64__) || defined(_M_X64)
1299 unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1306 if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
1310 getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
1312 Features[
"cmov"] = (EDX >> 15) & 1;
1313 Features[
"mmx"] = (EDX >> 23) & 1;
1314 Features[
"sse"] = (EDX >> 25) & 1;
1315 Features[
"sse2"] = (EDX >> 26) & 1;
1316 Features[
"sse3"] = (ECX >> 0) & 1;
1317 Features[
"ssse3"] = (ECX >> 9) & 1;
1318 Features[
"sse4.1"] = (ECX >> 19) & 1;
1319 Features[
"sse4.2"] = (ECX >> 20) & 1;
1321 Features[
"pclmul"] = (ECX >> 1) & 1;
1322 Features[
"cx16"] = (ECX >> 13) & 1;
1323 Features[
"movbe"] = (ECX >> 22) & 1;
1324 Features[
"popcnt"] = (ECX >> 23) & 1;
1325 Features[
"aes"] = (ECX >> 25) & 1;
1326 Features[
"rdrnd"] = (ECX >> 30) & 1;
1331 bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
1332 !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
1333 Features[
"avx"] = HasAVXSave;
1334 Features[
"fma"] = HasAVXSave && (ECX >> 12) & 1;
1335 Features[
"f16c"] = HasAVXSave && (ECX >> 29) & 1;
1338 Features[
"xsave"] = HasAVXSave && (ECX >> 26) & 1;
1341 bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
1343 unsigned MaxExtLevel;
1344 getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
1346 bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
1347 !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
1348 Features[
"lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
1349 Features[
"sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
1350 Features[
"prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
1351 Features[
"xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
1352 Features[
"fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
1353 Features[
"tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
1354 Features[
"mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
1357 MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
1360 Features[
"avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
1362 Features[
"fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
1363 Features[
"sgx"] = HasLeaf7 && ((EBX >> 2) & 1);
1364 Features[
"bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
1365 Features[
"hle"] = HasLeaf7 && ((EBX >> 4) & 1);
1366 Features[
"bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
1367 Features[
"invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
1368 Features[
"rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
1369 Features[
"rdseed"] = HasLeaf7 && ((EBX >> 18) & 1);
1370 Features[
"adx"] = HasLeaf7 && ((EBX >> 19) & 1);
1371 Features[
"smap"] = HasLeaf7 && ((EBX >> 20) & 1);
1372 Features[
"pcommit"] = HasLeaf7 && ((EBX >> 22) & 1);
1373 Features[
"clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
1374 Features[
"clwb"] = HasLeaf7 && ((EBX >> 24) & 1);
1375 Features[
"sha"] = HasLeaf7 && ((EBX >> 29) & 1);
1378 Features[
"avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
1379 Features[
"avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
1380 Features[
"avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
1381 Features[
"avx512pf"] = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
1382 Features[
"avx512er"] = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
1383 Features[
"avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
1384 Features[
"avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
1385 Features[
"avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
1387 Features[
"prefetchwt1"] = HasLeaf7 && (ECX & 1);
1388 Features[
"avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save;
1390 Features[
"pku"] = HasLeaf7 && ((ECX >> 4) & 1);
1392 bool HasLeafD = MaxLevel >= 0xd &&
1393 !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
1396 Features[
"xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
1397 Features[
"xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
1398 Features[
"xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);
1402 #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
1407 ssize_t CPUInfoSize = readCpuInfo(buffer,
sizeof(buffer));
1408 if (CPUInfoSize == -1)
1414 Str.split(Lines,
"\n");
1419 for (
unsigned I = 0,
E = Lines.
size();
I !=
E; ++
I)
1421 Lines[
I].split(CPUFeatures,
' ');
1425 #if defined(__aarch64__)
1427 enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
1431 for (
unsigned I = 0,
E = CPUFeatures.
size();
I !=
E; ++
I) {
1433 #
if defined(__aarch64__)
1434 .
Case(
"asimd",
"neon")
1435 .
Case(
"fp",
"fp-armv8")
1436 .
Case(
"crc32",
"crc")
1438 .
Case(
"half",
"fp16")
1439 .
Case(
"neon",
"neon")
1440 .
Case(
"vfpv3",
"vfp3")
1441 .
Case(
"vfpv3d16",
"d16")
1442 .
Case(
"vfpv4",
"vfp4")
1443 .
Case(
"idiva",
"hwdiv-arm")
1444 .
Case(
"idivt",
"hwdiv")
1448 #if defined(__aarch64__)
1451 if (CPUFeatures[
I] ==
"aes")
1453 else if (CPUFeatures[
I] ==
"pmull")
1454 crypto |= CAP_PMULL;
1455 else if (CPUFeatures[
I] ==
"sha1")
1457 else if (CPUFeatures[
I] ==
"sha2")
1461 if (LLVMFeatureStr !=
"")
1462 Features[LLVMFeatureStr] =
true;
1465 #if defined(__aarch64__)
1467 if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
1468 Features[
"crypto"] =
true;
std::error_code getError() const
Represents either an error or a value T.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
value_type read(const void *memory)
Read a value of a particular endianness from memory.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, SmallVectorImpl< char > *RealPath=nullptr)
const std::string & str() const
int getHostNumPhysicalCores()
Get the number of physical cores (as opposed to logical cores returned from thread::hardware_concurre...
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
bool isArch64Bit() const
Test whether the architecture is 64-bit.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
llvm::Triple get32BitArchVariant() const
Form a triple with a 32-bit variant of the current architecture.
A switch()-like statement whose cases are string literals.
The instances of the Type class are immutable: once they are created, they are never changed...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
#define LLVM_ATTRIBUTE_UNUSED
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
std::string normalize() const
Return the normalized form of this triple's string.
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool startswith(StringRef Magic, const char(&S)[N])
llvm::Triple get64BitArchVariant() const
Form a triple with a 64-bit variant of the current architecture.
StringRef getHostCPUName()
getHostCPUName - Get the LLVM name for the host CPU.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileAsStream(const Twine &Filename)
Read all of the specified file into a MemoryBuffer as a stream (i.e.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const FeatureBitset Features
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.
bool isArch32Bit() const
Test whether the architecture is 32-bit.
static int computeHostNumPhysicalCores()