Botan  2.18.1
Crypto and TLS for C++11
Classes | Public Types | Static Public Member Functions | List of all members
Botan::CPUID Class Referencefinal

#include <cpuid.h>

Public Types

enum  CPUID_bits : uint64_t { CPUID_INITIALIZED_BIT = (1ULL << 63) }
 

Static Public Member Functions

static std::vector< CPUID::CPUID_bitsbit_from_string (const std::string &tok)
 
static size_t cache_line_size ()
 
static void clear_cpuid_bit (CPUID_bits bit)
 
static bool has_carryless_multiply ()
 
static bool has_cpuid_bit (CPUID_bits elem)
 
static bool has_hw_aes ()
 
static bool has_simd_32 ()
 
static bool has_vperm ()
 
static void initialize ()
 
static bool is_big_endian ()
 
static bool is_little_endian ()
 
static void print (std::ostream &o)
 
static std::string to_string ()
 

Detailed Description

A class handling runtime CPU feature detection. It is limited to just the features necessary to implement CPU specific code in Botan, rather than being a general purpose utility.

This class supports:

Definition at line 38 of file cpuid.h.

Member Enumeration Documentation

◆ CPUID_bits

enum Botan::CPUID::CPUID_bits : uint64_t
Enumerator
CPUID_INITIALIZED_BIT 

Definition at line 95 of file cpuid.h.

95  : uint64_t {
96 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
97  // These values have no relation to cpuid bitfields
98 
99  // SIMD instruction sets
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),
106 
107  CPUID_AVX512DQ_BIT = (1ULL << 6),
108  CPUID_AVX512BW_BIT = (1ULL << 7),
109 
110  // Ice Lake profile: AVX-512 F, DQ, BW, IFMA, VBMI, VBMI2, BITALG
111  CPUID_AVX512_ICL_BIT = (1ULL << 11),
112 
113  // Crypto-specific ISAs
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),
121 
122  // Misc useful instructions
123  CPUID_RDTSC_BIT = (1ULL << 48),
124  CPUID_ADX_BIT = (1ULL << 49),
125  CPUID_BMI1_BIT = (1ULL << 50),
126  CPUID_BMI2_BIT = (1ULL << 51),
127 #endif
128 
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),
133 #endif
134 
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),
146 #endif
147 
148  CPUID_INITIALIZED_BIT = (1ULL << 63)
149  };

Member Function Documentation

◆ bit_from_string()

std::vector< Botan::CPUID::CPUID_bits > Botan::CPUID::bit_from_string ( const std::string &  tok)
static

Definition at line 152 of file cpuid.cpp.

References BOTAN_UNUSED.

153  {
154 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
155  if(tok == "sse2" || tok == "simd")
156  return {Botan::CPUID::CPUID_SSE2_BIT};
157  if(tok == "ssse3")
158  return {Botan::CPUID::CPUID_SSSE3_BIT};
159  if(tok == "sse41")
160  return {Botan::CPUID::CPUID_SSE41_BIT};
161  if(tok == "sse42")
162  return {Botan::CPUID::CPUID_SSE42_BIT};
163  // aes_ni is the string printed on the console when running "botan cpuid"
164  if(tok == "aesni" || tok == "aes_ni")
165  return {Botan::CPUID::CPUID_AESNI_BIT};
166  if(tok == "clmul")
167  return {Botan::CPUID::CPUID_CLMUL_BIT};
168  if(tok == "avx2")
169  return {Botan::CPUID::CPUID_AVX2_BIT};
170  if(tok == "avx512f")
171  return {Botan::CPUID::CPUID_AVX512F_BIT};
172  if(tok == "avx512_icelake")
173  return {Botan::CPUID::CPUID_AVX512_ICL_BIT};
174  // there were two if statements testing "sha" and "intel_sha" separately; combined
175  if(tok == "sha" || tok=="intel_sha")
176  return {Botan::CPUID::CPUID_SHA_BIT};
177  if(tok == "rdtsc")
178  return {Botan::CPUID::CPUID_RDTSC_BIT};
179  if(tok == "bmi1")
180  return {Botan::CPUID::CPUID_BMI1_BIT};
181  if(tok == "bmi2")
182  return {Botan::CPUID::CPUID_BMI2_BIT};
183  if(tok == "adx")
184  return {Botan::CPUID::CPUID_ADX_BIT};
185  if(tok == "rdrand")
186  return {Botan::CPUID::CPUID_RDRAND_BIT};
187  if(tok == "rdseed")
188  return {Botan::CPUID::CPUID_RDSEED_BIT};
189  if(tok == "avx512_aes")
190  return {Botan::CPUID::CPUID_AVX512_AES_BIT};
191  if(tok == "avx512_clmul")
192  return {Botan::CPUID::CPUID_AVX512_CLMUL_BIT};
193 
194 #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
195  if(tok == "altivec" || tok == "simd")
196  return {Botan::CPUID::CPUID_ALTIVEC_BIT};
197  if(tok == "power_crypto")
198  return {Botan::CPUID::CPUID_POWER_CRYPTO_BIT};
199  if(tok == "darn_rng")
200  return {Botan::CPUID::CPUID_DARN_BIT};
201 
202 #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
203  if(tok == "neon" || tok == "simd")
204  return {Botan::CPUID::CPUID_ARM_NEON_BIT};
205  if(tok == "arm_sve")
206  return {Botan::CPUID::CPUID_ARM_SVE_BIT};
207  if(tok == "armv8sha1" || tok == "arm_sha1")
208  return {Botan::CPUID::CPUID_ARM_SHA1_BIT};
209  if(tok == "armv8sha2" || tok == "arm_sha2")
210  return {Botan::CPUID::CPUID_ARM_SHA2_BIT};
211  if(tok == "armv8aes" || tok == "arm_aes")
212  return {Botan::CPUID::CPUID_ARM_AES_BIT};
213  if(tok == "armv8pmull" || tok == "arm_pmull")
214  return {Botan::CPUID::CPUID_ARM_PMULL_BIT};
215  if(tok == "armv8sha3" || tok == "arm_sha3")
216  return {Botan::CPUID::CPUID_ARM_SHA3_BIT};
217  if(tok == "armv8sha2_512" || tok == "arm_sha2_512")
218  return {Botan::CPUID::CPUID_ARM_SHA2_512_BIT};
219  if(tok == "armv8sm3" || tok == "arm_sm3")
220  return {Botan::CPUID::CPUID_ARM_SM3_BIT};
221  if(tok == "armv8sm4" || tok == "arm_sm4")
222  return {Botan::CPUID::CPUID_ARM_SM4_BIT};
223 
224 #else
225  BOTAN_UNUSED(tok);
226 #endif
227 
228  return {};
229  }
#define BOTAN_UNUSED(...)
Definition: assert.h:142

◆ cache_line_size()

static size_t Botan::CPUID::cache_line_size ( )
inlinestatic

Return a best guess of the cache line size

Definition at line 68 of file cpuid.h.

Referenced by Botan::prefetch_readonly(), and Botan::prefetch_readwrite().

69  {
70  return state().cache_line_size();
71  }

◆ clear_cpuid_bit()

static void Botan::CPUID::clear_cpuid_bit ( CPUID_bits  bit)
inlinestatic

Definition at line 415 of file cpuid.h.

416  {
417  state().clear_cpuid_bit(static_cast<uint64_t>(bit));
418  }

◆ has_carryless_multiply()

static bool Botan::CPUID::has_carryless_multiply ( )
inlinestatic

Check if the processor supports carryless multiply (CLMUL, PMULL)

Definition at line 395 of file cpuid.h.

Referenced by Botan::GHASH::provider().

396  {
397 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
398  return has_clmul();
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();
403 #else
404  return false;
405 #endif
406  }

◆ has_cpuid_bit()

static bool Botan::CPUID::has_cpuid_bit ( CPUID_bits  elem)
inlinestatic

Definition at line 424 of file cpuid.h.

425  {
426  const uint64_t elem64 = static_cast<uint64_t>(elem);
427  return state().has_bit(elem64);
428  }

◆ has_hw_aes()

static bool Botan::CPUID::has_hw_aes ( )
inlinestatic

Check if the processor supports hardware AES instructions

Definition at line 378 of file cpuid.h.

Referenced by Botan::AES_128::decrypt_n(), Botan::AES_192::decrypt_n(), Botan::AES_256::decrypt_n(), Botan::AES_128::encrypt_n(), Botan::AES_192::encrypt_n(), and Botan::AES_256::encrypt_n().

379  {
380 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
381  return has_aes_ni();
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();
386 #else
387  return false;
388 #endif
389  }

◆ has_simd_32()

bool Botan::CPUID::has_simd_32 ( )
static

Definition at line 16 of file cpuid.cpp.

Referenced by Botan::Noekeon::decrypt_n(), Botan::SHACAL2::decrypt_n(), Botan::Serpent::decrypt_n(), Botan::Noekeon::encrypt_n(), Botan::SHACAL2::encrypt_n(), Botan::Serpent::encrypt_n(), Botan::SHACAL2::parallelism(), Botan::Noekeon::parallelism(), Botan::Noekeon::provider(), Botan::SHACAL2::provider(), Botan::Serpent::provider(), and Botan::ChaCha::provider().

17  {
18 #if defined(BOTAN_TARGET_SUPPORTS_SSE2)
19  return CPUID::has_sse2();
20 #elif defined(BOTAN_TARGET_SUPPORTS_ALTIVEC)
21  return CPUID::has_altivec();
22 #elif defined(BOTAN_TARGET_SUPPORTS_NEON)
23  return CPUID::has_neon();
24 #else
25  return true;
26 #endif
27  }

◆ has_vperm()

static bool Botan::CPUID::has_vperm ( )
inlinestatic

Check if the processor supports byte-level vector permutes (SSSE3, NEON, Altivec)

Definition at line 362 of file cpuid.h.

Referenced by Botan::AES_128::decrypt_n(), Botan::AES_192::decrypt_n(), Botan::AES_256::decrypt_n(), Botan::AES_128::encrypt_n(), Botan::AES_192::encrypt_n(), Botan::AES_256::encrypt_n(), and Botan::GHASH::provider().

363  {
364 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
365  return has_ssse3();
366 #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
367  return has_neon();
368 #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
369  return has_altivec();
370 #else
371  return false;
372 #endif
373  }

◆ initialize()

void Botan::CPUID::initialize ( )
static

Probe the CPU and see what extensions are supported

Definition at line 93 of file cpuid.cpp.

94  {
95  state() = CPUID_Data();
96  }

◆ is_big_endian()

static bool Botan::CPUID::is_big_endian ( )
inlinestatic

Definition at line 84 of file cpuid.h.

Referenced by Botan::SIMD_4x32::load_le().

85  {
86 #if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
87  return true;
88 #elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
89  return false;
90 #else
91  return state().endian_status() == Endian_Status::Big;
92 #endif
93  }

◆ is_little_endian()

static bool Botan::CPUID::is_little_endian ( )
inlinestatic

Definition at line 73 of file cpuid.h.

Referenced by Botan::XMSS_Tools::concat(), Botan::SIMD_4x32::load_be(), Botan::SIMD_4x32::store_be(), and Botan::SIMD_4x32::store_le().

74  {
75 #if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
76  return true;
77 #elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
78  return false;
79 #else
80  return state().endian_status() == Endian_Status::Little;
81 #endif
82  }

◆ print()

void Botan::CPUID::print ( std::ostream &  o)
static

Deprecated equivalent to o << "CPUID flags: " << CPUID::to_string() << "\n";

Definition at line 87 of file cpuid.cpp.

References to_string().

88  {
89  o << "CPUID flags: " << CPUID::to_string() << "\n";
90  }
static std::string to_string()
Definition: cpuid.cpp:30

◆ to_string()

std::string Botan::CPUID::to_string ( )
static

Return a possibly empty string containing list of known CPU extensions. Each name will be seperated by a space, and the ordering will be arbitrary. This list only contains values that are useful to Botan (for example FMA instructions are not checked).

Example outputs "sse2 ssse3 rdtsc", "neon arm_aes", "altivec"

Definition at line 30 of file cpuid.cpp.

References CPUID_PRINT, Botan::PKCS11::flags(), and Botan::string_join().

Referenced by print().

31  {
32  std::vector<std::string> flags;
33 
34 #define CPUID_PRINT(flag) do { if(has_##flag()) { flags.push_back(#flag); } } while(0)
35 
36 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
37  CPUID_PRINT(sse2);
38  CPUID_PRINT(ssse3);
39  CPUID_PRINT(sse41);
40  CPUID_PRINT(sse42);
41  CPUID_PRINT(avx2);
42  CPUID_PRINT(avx512f);
43  CPUID_PRINT(avx512dq);
44  CPUID_PRINT(avx512bw);
45  CPUID_PRINT(avx512_icelake);
46 
47  CPUID_PRINT(rdtsc);
48  CPUID_PRINT(bmi1);
49  CPUID_PRINT(bmi2);
50  CPUID_PRINT(adx);
51 
52  CPUID_PRINT(aes_ni);
53  CPUID_PRINT(clmul);
54  CPUID_PRINT(rdrand);
55  CPUID_PRINT(rdseed);
56  CPUID_PRINT(intel_sha);
57  CPUID_PRINT(avx512_aes);
58  CPUID_PRINT(avx512_clmul);
59 #endif
60 
61 #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
62  CPUID_PRINT(altivec);
63  CPUID_PRINT(power_crypto);
64  CPUID_PRINT(darn_rng);
65 #endif
66 
67 #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
68  CPUID_PRINT(neon);
69  CPUID_PRINT(arm_sve);
70 
71  CPUID_PRINT(arm_sha1);
72  CPUID_PRINT(arm_sha2);
73  CPUID_PRINT(arm_aes);
74  CPUID_PRINT(arm_pmull);
75  CPUID_PRINT(arm_sha2_512);
76  CPUID_PRINT(arm_sha3);
77  CPUID_PRINT(arm_sm3);
78  CPUID_PRINT(arm_sm4);
79 #endif
80 
81 #undef CPUID_PRINT
82 
83  return string_join(flags, ' ');
84  }
Flags flags(Flag flags)
Definition: p11.h:860
#define CPUID_PRINT(flag)
std::string string_join(const std::vector< std::string > &strs, char delim)
Definition: parsing.cpp:182

The documentation for this class was generated from the following files: