46 #ifndef SIMDJSON_INTERNAL_ISADETECTION_H
47 #define SIMDJSON_INTERNAL_ISADETECTION_H
53 #elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID)
61 enum instruction_set {
81 #if defined(__PPC64__)
83 static inline uint32_t detect_supported_architectures() {
84 return instruction_set::ALTIVEC;
87 #elif defined(__aarch64__) || defined(_M_ARM64)
89 static inline uint32_t detect_supported_architectures() {
90 return instruction_set::NEON;
93 #elif defined(__x86_64__) || defined(_M_AMD64)
98 constexpr uint32_t cpuid_avx2_bit = 1 << 5;
99 constexpr uint32_t cpuid_bmi1_bit = 1 << 3;
100 constexpr uint32_t cpuid_bmi2_bit = 1 << 8;
101 constexpr uint32_t cpuid_avx512f_bit = 1 << 16;
102 constexpr uint32_t cpuid_avx512dq_bit = 1 << 17;
103 constexpr uint32_t cpuid_avx512ifma_bit = 1 << 21;
104 constexpr uint32_t cpuid_avx512pf_bit = 1 << 26;
105 constexpr uint32_t cpuid_avx512er_bit = 1 << 27;
106 constexpr uint32_t cpuid_avx512cd_bit = 1 << 28;
107 constexpr uint32_t cpuid_avx512bw_bit = 1 << 30;
108 constexpr uint32_t cpuid_avx512vl_bit = 1U << 31;
109 constexpr uint32_t cpuid_avx512vbmi2_bit = 1 << 6;
110 constexpr uint32_t cpuid_sse42_bit = 1 << 20;
111 constexpr uint32_t cpuid_pclmulqdq_bit = 1 << 1;
116 static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
118 #if defined(_MSC_VER)
120 __cpuid(cpu_info, *eax);
125 #elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID)
126 uint32_t level = *eax;
127 __get_cpuid(level, eax, ebx, ecx, edx);
129 uint32_t a = *eax, b, c = *ecx, d;
130 asm volatile(
"cpuid\n\t" :
"+a"(a),
"=b"(b),
"+c"(c),
"=d"(d));
138 static inline uint32_t detect_supported_architectures() {
139 uint32_t eax, ebx, ecx, edx;
140 uint32_t host_isa = 0x0;
145 cpuid(&eax, &ebx, &ecx, &edx);
146 if (ebx & cpuid_avx2_bit) {
147 host_isa |= instruction_set::AVX2;
149 if (ebx & cpuid_bmi1_bit) {
150 host_isa |= instruction_set::BMI1;
153 if (ebx & cpuid_bmi2_bit) {
154 host_isa |= instruction_set::BMI2;
157 if (ebx & cpuid_avx512f_bit) {
158 host_isa |= instruction_set::AVX512F;
161 if (ebx & cpuid_avx512dq_bit) {
162 host_isa |= instruction_set::AVX512DQ;
165 if (ebx & cpuid_avx512ifma_bit) {
166 host_isa |= instruction_set::AVX512IFMA;
169 if (ebx & cpuid_avx512pf_bit) {
170 host_isa |= instruction_set::AVX512PF;
173 if (ebx & cpuid_avx512er_bit) {
174 host_isa |= instruction_set::AVX512ER;
177 if (ebx & cpuid_avx512cd_bit) {
178 host_isa |= instruction_set::AVX512CD;
181 if (ebx & cpuid_avx512bw_bit) {
182 host_isa |= instruction_set::AVX512BW;
185 if (ebx & cpuid_avx512vl_bit) {
186 host_isa |= instruction_set::AVX512VL;
189 if (ecx & cpuid_avx512vbmi2_bit) {
190 host_isa |= instruction_set::AVX512VBMI2;
195 cpuid(&eax, &ebx, &ecx, &edx);
197 if (ecx & cpuid_sse42_bit) {
198 host_isa |= instruction_set::SSE42;
201 if (ecx & cpuid_pclmulqdq_bit) {
202 host_isa |= instruction_set::PCLMULQDQ;
210 static inline uint32_t detect_supported_architectures() {
211 return instruction_set::DEFAULT;
We want to support argument-dependent lookup (ADL).