Affix

 view release on metacpan or  search on metacpan

infix/src/core/platform.c  view on Meta::CPAN

    // If this is 0, we can't use XGETBV.
    bool osxsave = false;
    bool avx2_hardware = false;

#if defined(INFIX_COMPILER_MSVC)
    int cpuInfo[4];
    __cpuid(cpuInfo, 1);
    osxsave = (cpuInfo[2] & (1 << 27)) != 0;

    __cpuidex(cpuInfo, 7, 0);
    avx2_hardware = (cpuInfo[1] & (1 << 5)) != 0;
#elif defined(INFIX_COMPILER_GCC) || defined(INFIX_COMPILER_CLANG)
    unsigned int eax, ebx, ecx, edx;
    __cpuid(1, eax, ebx, ecx, edx);
    osxsave = (ecx & (1 << 27)) != 0;

    if (__get_cpuid_max(0, NULL) >= 7) {
        __cpuid_count(7, 0, eax, ebx, ecx, edx);
        avx2_hardware = (ebx & (1 << 5)) != 0;
    }
#endif

    if (!osxsave || !avx2_hardware)
        return false;

    // 2. Check XCR0 to ensure OS has enabled YMM state saving.
    // Must have SSE(1) and AVX(2) bits set.
    uint64_t xcr0 = _infix_xgetbv();
    return (xcr0 & (XCR0_SSE | XCR0_AVX)) == (XCR0_SSE | XCR0_AVX);
}

bool infix_cpu_has_avx512f(void) {
    bool osxsave = false;
    bool avx512f_hardware = false;

#if defined(INFIX_COMPILER_MSVC)
    int cpuInfo[4];
    __cpuid(cpuInfo, 1);
    osxsave = (cpuInfo[2] & (1 << 27)) != 0;

    __cpuidex(cpuInfo, 7, 0);
    avx512f_hardware = (cpuInfo[1] & (1 << 16)) != 0;
#elif defined(INFIX_COMPILER_GCC) || defined(INFIX_COMPILER_CLANG)
    unsigned int eax, ebx, ecx, edx;
    __cpuid(1, eax, ebx, ecx, edx);
    osxsave = (ecx & (1 << 27)) != 0;

    if (__get_cpuid_max(0, NULL) >= 7) {
        __cpuid_count(7, 0, eax, ebx, ecx, edx);
        avx512f_hardware = (ebx & (1 << 16)) != 0;
    }
#endif

    if (!osxsave || !avx512f_hardware)
        return false;

    // 2. Check XCR0 for ZMM support.
    // Need SSE(1) | AVX(2) | opmask(5) | ZMM_Hi256(6) | Hi16_ZMM(7)
    uint64_t xcr0 = _infix_xgetbv();
    uint64_t required = XCR0_SSE | XCR0_AVX | XCR0_OPMASK | XCR0_ZMM_Hi256 | XCR0_Hi16_ZMM;
    return (xcr0 & required) == required;
}
#endif

#if defined(INFIX_ARCH_AARCH64)
bool infix_cpu_has_sve(void) {
#if defined(INFIX_OS_LINUX) && defined(HWCAP_SVE)
    return (getauxval(AT_HWCAP) & HWCAP_SVE) != 0;
#elif defined(INFIX_OS_MACOS)
    int sve_present = 0;
    size_t size = sizeof(sve_present);
    if (sysctlbyname("hw.optional.arm.FEAT_SVE", &sve_present, &size, NULL, 0) == 0)
        return sve_present == 1;
    return false;
#else
    // Add checks for other OS (e.g., Windows on ARM) if needed.
    return false;
#endif
}
#endif



( run in 0.416 second using v1.01-cache-2.11-cpan-483215c6ad5 )