| 1361 | #if defined(__i386__) || defined(_M_IX86) || \ |
| 1362 | defined(__x86_64__) || defined(_M_X64) |
| 1363 | bool sys::getHostCPUFeatures(StringMap<bool> &Features) { |
| 1364 | unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; |
| 1365 | unsigned MaxLevel; |
| 1366 | union { |
| 1367 | unsigned u[3]; |
| 1368 | char c[12]; |
| 1369 | } text; |
| 1370 | |
| 1371 | if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) || |
| 1372 | MaxLevel < 1) |
| 1373 | return false; |
| 1374 | |
| 1375 | getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX); |
| 1376 | |
| 1377 | Features["cx8"] = (EDX >> 8) & 1; |
| 1378 | Features["cmov"] = (EDX >> 15) & 1; |
| 1379 | Features["mmx"] = (EDX >> 23) & 1; |
| 1380 | Features["fxsr"] = (EDX >> 24) & 1; |
| 1381 | Features["sse"] = (EDX >> 25) & 1; |
| 1382 | Features["sse2"] = (EDX >> 26) & 1; |
| 1383 | |
| 1384 | Features["sse3"] = (ECX >> 0) & 1; |
| 1385 | Features["pclmul"] = (ECX >> 1) & 1; |
| 1386 | Features["ssse3"] = (ECX >> 9) & 1; |
| 1387 | Features["cx16"] = (ECX >> 13) & 1; |
| 1388 | Features["sse4.1"] = (ECX >> 19) & 1; |
| 1389 | Features["sse4.2"] = (ECX >> 20) & 1; |
| 1390 | Features["movbe"] = (ECX >> 22) & 1; |
| 1391 | Features["popcnt"] = (ECX >> 23) & 1; |
| 1392 | Features["aes"] = (ECX >> 25) & 1; |
| 1393 | Features["rdrnd"] = (ECX >> 30) & 1; |
| 1394 | |
| 1395 | // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV |
| 1396 | // indicates that the AVX registers will be saved and restored on context |
| 1397 | // switch, then we have full AVX support. |
| 1398 | bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) && |
| 1399 | !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6); |
| 1400 | #if defined(__APPLE__) |
| 1401 | // Darwin lazily saves the AVX512 context on first use: trust that the OS will |
| 1402 | // save the AVX512 context if we use AVX512 instructions, even the bit is not |
| 1403 | // set right now. |
| 1404 | bool HasAVX512Save = true; |
| 1405 | #else |
| 1406 | // AVX512 requires additional context to be saved by the OS. |
| 1407 | bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0); |
| 1408 | #endif |
| 1409 | |
| 1410 | Features["avx"] = HasAVXSave; |
| 1411 | Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave; |
| 1412 | // Only enable XSAVE if OS has enabled support for saving YMM state. |
| 1413 | Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave; |
| 1414 | Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave; |
| 1415 | |
| 1416 | unsigned MaxExtLevel; |
| 1417 | getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); |
| 1418 | |
| 1419 | bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && |
| 1420 | !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); |
nothing calls this directly
no test coverage detected