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),
108 CPUID_RDTSC_BIT = (1ULL << 10),
109 CPUID_BMI2_BIT = (1ULL << 11),
110 CPUID_ADX_BIT = (1ULL << 12),
111 CPUID_BMI1_BIT = (1ULL << 13),
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),
121 #
if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
122 CPUID_ALTIVEC_BIT = (1ULL << 0),
123 CPUID_POWER_CRYPTO_BIT = (1ULL << 1),
124 CPUID_DARN_BIT = (1ULL << 2),
127 #
if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
128 CPUID_ARM_NEON_BIT = (1ULL << 0),
129 CPUID_ARM_SVE_BIT = (1ULL << 1),
130 CPUID_ARM_AES_BIT = (1ULL << 16),
131 CPUID_ARM_PMULL_BIT = (1ULL << 17),
132 CPUID_ARM_SHA1_BIT = (1ULL << 18),
133 CPUID_ARM_SHA2_BIT = (1ULL << 19),
134 CPUID_ARM_SHA3_BIT = (1ULL << 20),
135 CPUID_ARM_SHA2_512_BIT = (1ULL << 21),
136 CPUID_ARM_SM3_BIT = (1ULL << 22),
137 CPUID_ARM_SM4_BIT = (1ULL << 23),
140 CPUID_INITIALIZED_BIT = (1ULL << 63)
143 #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
147 static bool has_altivec()
148 {
return has_cpuid_bit(CPUID_ALTIVEC_BIT); }
153 static bool has_power_crypto()
154 {
return has_cpuid_bit(CPUID_POWER_CRYPTO_BIT); }
159 static bool has_darn_rng()
160 {
return has_cpuid_bit(CPUID_DARN_BIT); }
164 #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
168 static bool has_neon()
169 {
return has_cpuid_bit(CPUID_ARM_NEON_BIT); }
174 static bool has_arm_sve()
175 {
return has_cpuid_bit(CPUID_ARM_SVE_BIT); }
180 static bool has_arm_sha1()
181 {
return has_cpuid_bit(CPUID_ARM_SHA1_BIT); }
186 static bool has_arm_sha2()
187 {
return has_cpuid_bit(CPUID_ARM_SHA2_BIT); }
192 static bool has_arm_aes()
193 {
return has_cpuid_bit(CPUID_ARM_AES_BIT); }
198 static bool has_arm_pmull()
199 {
return has_cpuid_bit(CPUID_ARM_PMULL_BIT); }
204 static bool has_arm_sha2_512()
205 {
return has_cpuid_bit(CPUID_ARM_SHA2_512_BIT); }
210 static bool has_arm_sha3()
211 {
return has_cpuid_bit(CPUID_ARM_SHA3_BIT); }
216 static bool has_arm_sm3()
217 {
return has_cpuid_bit(CPUID_ARM_SM3_BIT); }
222 static bool has_arm_sm4()
223 {
return has_cpuid_bit(CPUID_ARM_SM4_BIT); }
227 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
232 static bool has_rdtsc()
233 {
return has_cpuid_bit(CPUID_RDTSC_BIT); }
238 static bool has_sse2()
239 {
return has_cpuid_bit(CPUID_SSE2_BIT); }
244 static bool has_ssse3()
245 {
return has_cpuid_bit(CPUID_SSSE3_BIT); }
250 static bool has_sse41()
251 {
return has_cpuid_bit(CPUID_SSE41_BIT); }
256 static bool has_sse42()
257 {
return has_cpuid_bit(CPUID_SSE42_BIT); }
262 static bool has_avx2()
263 {
return has_cpuid_bit(CPUID_AVX2_BIT); }
268 static bool has_avx512f()
269 {
return has_cpuid_bit(CPUID_AVX512F_BIT); }
274 static bool has_bmi1()
275 {
return has_cpuid_bit(CPUID_BMI1_BIT); }
280 static bool has_bmi2()
281 {
return has_cpuid_bit(CPUID_BMI2_BIT); }
286 static bool has_aes_ni()
287 {
return has_cpuid_bit(CPUID_AESNI_BIT); }
292 static bool has_clmul()
293 {
return has_cpuid_bit(CPUID_CLMUL_BIT); }
298 static bool has_intel_sha()
299 {
return has_cpuid_bit(CPUID_SHA_BIT); }
304 static bool has_adx()
305 {
return has_cpuid_bit(CPUID_ADX_BIT); }
310 static bool has_rdrand()
311 {
return has_cpuid_bit(CPUID_RDRAND_BIT); }
316 static bool has_rdseed()
317 {
return has_cpuid_bit(CPUID_RDSEED_BIT); }
326 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
328 #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
330 #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
331 return has_altivec();
343 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
345 #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
346 return has_arm_pmull();
361 state().clear_cpuid_bit(static_cast<uint64_t>(bit));
370 const uint64_t elem64 =
static_cast<uint64_t
>(elem);
371 return state().has_bit(elem64);
374 static std::vector<CPUID::CPUID_bits> bit_from_string(
const std::string& tok);
376 enum class Endian_Status : uint32_t {
387 CPUID_Data(
const CPUID_Data& other) =
default;
388 CPUID_Data& operator=(
const CPUID_Data& other) =
default;
390 void clear_cpuid_bit(uint64_t bit)
392 m_processor_features &= ~bit;
395 bool has_bit(uint64_t bit)
const
397 return (m_processor_features & bit) == bit;
400 uint64_t processor_features()
const {
return m_processor_features; }
401 Endian_Status endian_status()
const {
return m_endian_status; }
402 size_t cache_line_size()
const {
return m_cache_line_size; }
405 static Endian_Status runtime_check_endian();
407 #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \
408 defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
409 defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
411 static uint64_t detect_cpu_features(
size_t* cache_line_size);
414 uint64_t m_processor_features;
415 size_t m_cache_line_size;
416 Endian_Status m_endian_status;
419 static CPUID_Data& state()
421 static CPUID::CPUID_Data g_cpuid;
static size_t cache_line_size()
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
std::string to_string(const BER_Object &obj)
static bool has_carryless_multiply()
static bool is_little_endian()
static void clear_cpuid_bit(CPUID_bits bit)
static bool has_cpuid_bit(CPUID_bits elem)
static bool is_big_endian()
#define BOTAN_FUTURE_INTERNAL_HEADER(hdr)