| Server IP : 217.160.0.212 / Your IP : 216.73.216.230 Web Server : Apache System : Linux www 6.18.52-i1-ampere #1203 SMP Mon Sep 14 18:29:59 CEST 2026 aarch64 User : sws1073854427 ( 1073854427) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /usr/include/xsimd/config/ |
Upload File : |
/***************************************************************************
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
* Martin Renou *
* Copyright (c) QuantStack *
* Copyright (c) Serge Guelton *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/
#ifndef XSIMD_CPUID_HPP
#define XSIMD_CPUID_HPP
#include <algorithm>
#include <cstring>
#if defined(__linux__) && (defined(__ARM_NEON) || defined(_M_ARM))
#include <asm/hwcap.h>
#include <sys/auxv.h>
#endif
#if defined(_MSC_VER)
// Contains the definition of __cpuidex
#include <intrin.h>
#endif
#include "../types/xsimd_all_registers.hpp"
namespace xsimd
{
namespace detail
{
struct supported_arch
{
unsigned sse2 : 1;
unsigned sse3 : 1;
unsigned ssse3 : 1;
unsigned sse4_1 : 1;
unsigned sse4_2 : 1;
unsigned sse4a : 1;
unsigned fma3_sse : 1;
unsigned fma4 : 1;
unsigned xop : 1;
unsigned avx : 1;
unsigned fma3_avx : 1;
unsigned avx2 : 1;
unsigned fma3_avx2 : 1;
unsigned avx512f : 1;
unsigned avx512cd : 1;
unsigned avx512dq : 1;
unsigned avx512bw : 1;
unsigned neon : 1;
unsigned neon64 : 1;
// version number of the best arch available
unsigned best;
supported_arch() noexcept
{
memset(this, 0, sizeof(supported_arch));
#if defined(__aarch64__) || defined(_M_ARM64)
neon = 1;
neon64 = 1;
best = neon64::version();
#elif defined(__ARM_NEON) || defined(_M_ARM)
#if defined(__linux__)
neon = bool(getauxval(AT_HWCAP) & HWCAP_NEON);
#else
// that's very conservative :-/
neon = 0;
#endif
neon64 = 0;
best = neon::version() * neon;
#elif defined(__x86_64__) || defined(__i386__) || defined(_M_AMD64) || defined(_M_IX86)
auto get_cpuid = [](int reg[4], int func_id) noexcept
{
#if defined(_MSC_VER)
__cpuidex(reg, func_id, 0);
#elif defined(__INTEL_COMPILER)
__cpuid(reg, func_id);
#elif defined(__GNUC__) || defined(__clang__)
#if defined(__i386__) && defined(__PIC__)
// %ebx may be the PIC register
__asm__("xchg{l}\t{%%}ebx, %1\n\t"
"cpuid\n\t"
"xchg{l}\t{%%}ebx, %1\n\t"
: "=a"(reg[0]), "=r"(reg[1]), "=c"(reg[2]),
"=d"(reg[3])
: "a"(func_id), "c"(0));
#else
__asm__("cpuid\n\t"
: "=a"(reg[0]), "=b"(reg[1]), "=c"(reg[2]),
"=d"(reg[3])
: "a"(func_id), "c"(0));
#endif
#else
#error "Unsupported configuration"
#endif
};
int regs[4];
get_cpuid(regs, 0x1);
sse2 = regs[2] >> 26 & 1;
best = std::max(best, sse2::version() * sse2);
sse3 = regs[2] >> 0 & 1;
best = std::max(best, sse3::version() * sse3);
ssse3 = regs[2] >> 9 & 1;
best = std::max(best, ssse3::version() * ssse3);
sse4_1 = regs[2] >> 19 & 1;
best = std::max(best, sse4_1::version() * sse4_1);
sse4_2 = regs[2] >> 20 & 1;
best = std::max(best, sse4_2::version() * sse4_2);
fma3_sse = regs[2] >> 12 & 1;
if (sse4_2)
best = std::max(best, fma3<xsimd::sse4_2>::version() * fma3_sse);
get_cpuid(regs, 0x80000001);
fma4 = regs[2] >> 16 & 1;
best = std::max(best, fma4::version() * fma4);
// sse4a = regs[2] >> 6 & 1;
// best = std::max(best, XSIMD_X86_AMD_SSE4A_VERSION * sse4a);
// xop = regs[2] >> 11 & 1;
// best = std::max(best, XSIMD_X86_AMD_XOP_VERSION * xop);
avx = regs[2] >> 28 & 1;
best = std::max(best, avx::version() * avx);
fma3_avx = avx && fma3_sse;
best = std::max(best, fma3<xsimd::avx>::version() * fma3_avx);
get_cpuid(regs, 0x7);
avx2 = regs[1] >> 5 & 1;
best = std::max(best, avx2::version() * avx2);
fma3_avx2 = avx2 && fma3_sse;
best = std::max(best, fma3<xsimd::avx2>::version() * fma3_avx2);
avx512f = regs[1] >> 16 & 1;
best = std::max(best, avx512f::version() * avx512f);
avx512cd = regs[1] >> 28 & 1;
best = std::max(best, avx512cd::version() * avx512cd * avx512f);
avx512dq = regs[1] >> 17 & 1;
best = std::max(best, avx512dq::version() * avx512dq * avx512cd * avx512f);
avx512bw = regs[1] >> 30 & 1;
best = std::max(best, avx512bw::version() * avx512bw * avx512dq * avx512cd * avx512f);
#endif
}
};
}
inline detail::supported_arch available_architectures() noexcept
{
static detail::supported_arch supported;
return supported;
}
}
#endif