| 420 | } |
| 421 | |
| 422 | static void |
| 423 | npy__cpu_init_features(void) |
| 424 | { |
| 425 | memset(npy__cpu_have, 0, sizeof(npy__cpu_have[0]) * NPY_CPU_FEATURE_MAX); |
| 426 | |
| 427 | // validate platform support |
| 428 | int reg[] = {0, 0, 0, 0}; |
| 429 | npy__cpu_cpuid(reg, 0); |
| 430 | if (reg[0] == 0) { |
| 431 | npy__cpu_have[NPY_CPU_FEATURE_MMX] = 1; |
| 432 | npy__cpu_have[NPY_CPU_FEATURE_SSE] = 1; |
| 433 | npy__cpu_have[NPY_CPU_FEATURE_SSE2] = 1; |
| 434 | #ifdef NPY_CPU_AMD64 |
| 435 | npy__cpu_have[NPY_CPU_FEATURE_SSE3] = 1; |
| 436 | #endif |
| 437 | return; |
| 438 | } |
| 439 | |
| 440 | npy__cpu_cpuid(reg, 1); |
| 441 | npy__cpu_have[NPY_CPU_FEATURE_MMX] = (reg[3] & (1 << 23)) != 0; |
| 442 | npy__cpu_have[NPY_CPU_FEATURE_SSE] = (reg[3] & (1 << 25)) != 0; |
| 443 | npy__cpu_have[NPY_CPU_FEATURE_SSE2] = (reg[3] & (1 << 26)) != 0; |
| 444 | npy__cpu_have[NPY_CPU_FEATURE_SSE3] = (reg[2] & (1 << 0)) != 0; |
| 445 | npy__cpu_have[NPY_CPU_FEATURE_SSSE3] = (reg[2] & (1 << 9)) != 0; |
| 446 | npy__cpu_have[NPY_CPU_FEATURE_SSE41] = (reg[2] & (1 << 19)) != 0; |
| 447 | npy__cpu_have[NPY_CPU_FEATURE_POPCNT] = (reg[2] & (1 << 23)) != 0; |
| 448 | npy__cpu_have[NPY_CPU_FEATURE_SSE42] = (reg[2] & (1 << 20)) != 0; |
| 449 | npy__cpu_have[NPY_CPU_FEATURE_F16C] = (reg[2] & (1 << 29)) != 0; |
| 450 | |
| 451 | // check OSXSAVE |
| 452 | if ((reg[2] & (1 << 27)) == 0) |
| 453 | return; |
| 454 | // check AVX OS support |
| 455 | int xcr = npy__cpu_getxcr0(); |
| 456 | if ((xcr & 6) != 6) |
| 457 | return; |
| 458 | npy__cpu_have[NPY_CPU_FEATURE_AVX] = (reg[2] & (1 << 28)) != 0; |
| 459 | if (!npy__cpu_have[NPY_CPU_FEATURE_AVX]) |
| 460 | return; |
| 461 | npy__cpu_have[NPY_CPU_FEATURE_FMA3] = (reg[2] & (1 << 12)) != 0; |
| 462 | |
| 463 | // second call to the cpuid to get extended AMD feature bits |
| 464 | npy__cpu_cpuid(reg, 0x80000001); |
| 465 | npy__cpu_have[NPY_CPU_FEATURE_XOP] = (reg[2] & (1 << 11)) != 0; |
| 466 | npy__cpu_have[NPY_CPU_FEATURE_FMA4] = (reg[2] & (1 << 16)) != 0; |
| 467 | |
| 468 | // third call to the cpuid to get extended AVX2 & AVX512 feature bits |
| 469 | npy__cpu_cpuid(reg, 7); |
| 470 | npy__cpu_have[NPY_CPU_FEATURE_AVX2] = (reg[1] & (1 << 5)) != 0; |
| 471 | if (!npy__cpu_have[NPY_CPU_FEATURE_AVX2]) |
| 472 | return; |
| 473 | // detect AVX2 & FMA3 |
| 474 | npy__cpu_have[NPY_CPU_FEATURE_FMA] = npy__cpu_have[NPY_CPU_FEATURE_FMA3]; |
| 475 | |
| 476 | // check AVX512 OS support |
| 477 | int avx512_os = (xcr & 0xe6) == 0xe6; |
| 478 | #if defined(__APPLE__) && defined(__x86_64__) |
| 479 | /** |
no test coverage detected