11#include <botan/types.h>
44 static void initialize();
46 static bool has_simd_32();
52 BOTAN_DEPRECATED(
"Use CPUID::to_string")
53 static void print(std::ostream& o);
70 return state().cache_line_size();
75#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
77#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
80 return state().endian_status() == Endian_Status::Little;
86#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
88#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
91 return state().endian_status() == Endian_Status::Big;
96#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
100 CPUID_SSE2_BIT = (1ULL << 0),
101 CPUID_SSSE3_BIT = (1ULL << 1),
102 CPUID_SSE41_BIT = (1ULL << 2),
103 CPUID_SSE42_BIT = (1ULL << 3),
104 CPUID_AVX2_BIT = (1ULL << 4),
105 CPUID_AVX512F_BIT = (1ULL << 5),
107 CPUID_AVX512DQ_BIT = (1ULL << 6),
108 CPUID_AVX512BW_BIT = (1ULL << 7),
111 CPUID_AVX512_ICL_BIT = (1ULL << 11),
114 CPUID_AESNI_BIT = (1ULL << 16),
115 CPUID_CLMUL_BIT = (1ULL << 17),
116 CPUID_RDRAND_BIT = (1ULL << 18),
117 CPUID_RDSEED_BIT = (1ULL << 19),
118 CPUID_SHA_BIT = (1ULL << 20),
119 CPUID_AVX512_AES_BIT = (1ULL << 21),
120 CPUID_AVX512_CLMUL_BIT = (1ULL << 22),
123 CPUID_RDTSC_BIT = (1ULL << 48),
124 CPUID_ADX_BIT = (1ULL << 49),
125 CPUID_BMI1_BIT = (1ULL << 50),
126 CPUID_BMI2_BIT = (1ULL << 51),
129#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
130 CPUID_ALTIVEC_BIT = (1ULL << 0),
131 CPUID_POWER_CRYPTO_BIT = (1ULL << 1),
132 CPUID_DARN_BIT = (1ULL << 2),
135#
if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
136 CPUID_ARM_NEON_BIT = (1ULL << 0),
137 CPUID_ARM_SVE_BIT = (1ULL << 1),
138 CPUID_ARM_AES_BIT = (1ULL << 16),
139 CPUID_ARM_PMULL_BIT = (1ULL << 17),
140 CPUID_ARM_SHA1_BIT = (1ULL << 18),
141 CPUID_ARM_SHA2_BIT = (1ULL << 19),
142 CPUID_ARM_SHA3_BIT = (1ULL << 20),
143 CPUID_ARM_SHA2_512_BIT = (1ULL << 21),
144 CPUID_ARM_SM3_BIT = (1ULL << 22),
145 CPUID_ARM_SM4_BIT = (1ULL << 23),
148 CPUID_INITIALIZED_BIT = (1ULL << 63)
151#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
155 static bool has_altivec()
156 {
return has_cpuid_bit(CPUID_ALTIVEC_BIT); }
161 static bool has_power_crypto()
162 {
return has_cpuid_bit(CPUID_POWER_CRYPTO_BIT); }
167 static bool has_darn_rng()
168 {
return has_cpuid_bit(CPUID_DARN_BIT); }
172#if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
176 static bool has_neon()
177 {
return has_cpuid_bit(CPUID_ARM_NEON_BIT); }
182 static bool has_arm_sve()
183 {
return has_cpuid_bit(CPUID_ARM_SVE_BIT); }
188 static bool has_arm_sha1()
189 {
return has_cpuid_bit(CPUID_ARM_SHA1_BIT); }
194 static bool has_arm_sha2()
195 {
return has_cpuid_bit(CPUID_ARM_SHA2_BIT); }
200 static bool has_arm_aes()
201 {
return has_cpuid_bit(CPUID_ARM_AES_BIT); }
206 static bool has_arm_pmull()
207 {
return has_cpuid_bit(CPUID_ARM_PMULL_BIT); }
212 static bool has_arm_sha2_512()
213 {
return has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); }
218 static bool has_arm_sha3()
219 {
return has_cpuid_bit(CPUID_ARM_SHA3_BIT); }
224 static bool has_arm_sm3()
225 {
return has_cpuid_bit(CPUID_ARM_SM3_BIT); }
230 static bool has_arm_sm4()
231 {
return has_cpuid_bit(CPUID_ARM_SM4_BIT); }
235#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
240 static bool has_rdtsc()
241 {
return has_cpuid_bit(CPUID_RDTSC_BIT); }
246 static bool has_sse2()
247 {
return has_cpuid_bit(CPUID_SSE2_BIT); }
252 static bool has_ssse3()
253 {
return has_cpuid_bit(CPUID_SSSE3_BIT); }
258 static bool has_sse41()
259 {
return has_cpuid_bit(CPUID_SSE41_BIT); }
264 static bool has_sse42()
265 {
return has_cpuid_bit(CPUID_SSE42_BIT); }
270 static bool has_avx2()
271 {
return has_cpuid_bit(CPUID_AVX2_BIT); }
276 static bool has_avx512f()
277 {
return has_cpuid_bit(CPUID_AVX512F_BIT); }
282 static bool has_avx512dq()
283 {
return has_cpuid_bit(CPUID_AVX512DQ_BIT); }
288 static bool has_avx512bw()
289 {
return has_cpuid_bit(CPUID_AVX512BW_BIT); }
294 static bool has_avx512_icelake()
295 {
return has_cpuid_bit(CPUID_AVX512_ICL_BIT); }
300 static bool has_avx512_aes()
301 {
return has_cpuid_bit(CPUID_AVX512_AES_BIT); }
306 static bool has_avx512_clmul()
307 {
return has_cpuid_bit(CPUID_AVX512_CLMUL_BIT); }
312 static bool has_bmi1()
313 {
return has_cpuid_bit(CPUID_BMI1_BIT); }
318 static bool has_bmi2()
319 {
return has_cpuid_bit(CPUID_BMI2_BIT); }
324 static bool has_aes_ni()
325 {
return has_cpuid_bit(CPUID_AESNI_BIT); }
330 static bool has_clmul()
331 {
return has_cpuid_bit(CPUID_CLMUL_BIT); }
336 static bool has_intel_sha()
337 {
return has_cpuid_bit(CPUID_SHA_BIT); }
342 static bool has_adx()
343 {
return has_cpuid_bit(CPUID_ADX_BIT); }
348 static bool has_rdrand()
349 {
return has_cpuid_bit(CPUID_RDRAND_BIT); }
354 static bool has_rdseed()
355 {
return has_cpuid_bit(CPUID_RDSEED_BIT); }
364#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
366#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
368#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
369 return has_altivec();
380#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
382#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
383 return has_arm_aes();
384#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
385 return has_power_crypto();
397#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
399#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
400 return has_arm_pmull();
401#elif defined(BOTAN_TARGET_ARCH_IS_PPC64)
402 return has_power_crypto();
417 state().clear_cpuid_bit(
static_cast<uint64_t
>(bit));
426 const uint64_t elem64 =
static_cast<uint64_t
>(elem);
427 return state().has_bit(elem64);
430 static std::vector<CPUID::CPUID_bits> bit_from_string(
const std::string& tok);
432 enum class Endian_Status : uint32_t {
443 CPUID_Data(
const CPUID_Data& other) =
default;
444 CPUID_Data& operator=(
const CPUID_Data& other) =
default;
446 void clear_cpuid_bit(uint64_t bit)
448 m_processor_features &= ~bit;
451 bool has_bit(uint64_t bit)
const
453 return (m_processor_features & bit) == bit;
456 uint64_t processor_features()
const {
return m_processor_features; }
457 Endian_Status endian_status()
const {
return m_endian_status; }
458 size_t cache_line_size()
const {
return m_cache_line_size; }
461 static Endian_Status runtime_check_endian();
463#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \
464 defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
465 defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
467 static uint64_t detect_cpu_features(
size_t* cache_line_size);
470 uint64_t m_processor_features;
471 size_t m_cache_line_size;
472 Endian_Status m_endian_status;
475 static CPUID_Data& state()
477 static CPUID::CPUID_Data g_cpuid;
static bool is_little_endian()
static bool is_big_endian()
static size_t cache_line_size()
static bool has_cpuid_bit(CPUID_bits elem)
static bool has_carryless_multiply()
static void clear_cpuid_bit(CPUID_bits bit)
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
#define BOTAN_FUTURE_INTERNAL_HEADER(hdr)
std::string to_string(const BER_Object &obj)