8 #include <botan/cpuid.h>
9 #include <botan/types.h>
10 #include <botan/exceptn.h>
11 #include <botan/parsing.h>
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();
32 std::vector<std::string>
flags;
34 #define CPUID_PRINT(flag) do { if(has_##flag()) { flags.push_back(#flag); } } while(0)
36 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
56 #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
62 #if defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
90 state() = CPUID_Data();
93 CPUID::CPUID_Data::CPUID_Data()
95 #if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || \
96 defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
97 defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
99 m_cache_line_size = 0;
100 m_processor_features = detect_cpu_features(&m_cache_line_size);
106 if(m_cache_line_size == 0)
107 m_cache_line_size = BOTAN_TARGET_CPU_DEFAULT_CACHE_LINE_SIZE;
109 m_endian_status = runtime_check_endian();
113 CPUID::Endian_Status CPUID::CPUID_Data::runtime_check_endian()
116 const uint32_t endian32 = 0x01234567;
117 const uint8_t* e8 =
reinterpret_cast<const uint8_t*
>(&endian32);
121 if(e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67)
125 else if(e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01)
131 throw Internal_Error(
"Unexpected endian at runtime, neither big nor little");
135 #if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
137 #elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
144 std::vector<Botan::CPUID::CPUID_bits>
147 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
148 if(tok ==
"sse2" || tok ==
"simd")
149 return {Botan::CPUID::CPUID_SSE2_BIT};
151 return {Botan::CPUID::CPUID_SSSE3_BIT};
153 return {Botan::CPUID::CPUID_AESNI_BIT};
155 return {Botan::CPUID::CPUID_CLMUL_BIT};
157 return {Botan::CPUID::CPUID_AVX2_BIT};
159 return {Botan::CPUID::CPUID_SHA_BIT};
161 return {Botan::CPUID::CPUID_BMI2_BIT};
163 return {Botan::CPUID::CPUID_ADX_BIT};
164 if(tok ==
"intel_sha")
165 return {Botan::CPUID::CPUID_SHA_BIT};
167 #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
168 if(tok ==
"altivec" || tok ==
"simd")
169 return {Botan::CPUID::CPUID_ALTIVEC_BIT};
170 if(tok ==
"power_crypto")
171 return {Botan::CPUID::CPUID_POWER_CRYPTO_BIT};
173 #elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
174 if(tok ==
"neon" || tok ==
"simd")
175 return {Botan::CPUID::CPUID_ARM_NEON_BIT};
176 if(tok ==
"armv8sha1")
177 return {Botan::CPUID::CPUID_ARM_SHA1_BIT};
178 if(tok ==
"armv8sha2")
179 return {Botan::CPUID::CPUID_ARM_SHA2_BIT};
180 if(tok ==
"armv8aes")
181 return {Botan::CPUID::CPUID_ARM_AES_BIT};
182 if(tok ==
"armv8pmull")
183 return {Botan::CPUID::CPUID_ARM_PMULL_BIT};
184 if(tok ==
"armv8sha3")
185 return {Botan::CPUID::CPUID_ARM_SHA3_BIT};
186 if(tok ==
"armv8sha2_512")
187 return {Botan::CPUID::CPUID_ARM_SHA2_512_BIT};
188 if(tok ==
"armv8sm3")
189 return {Botan::CPUID::CPUID_ARM_SM3_BIT};
190 if(tok ==
"armv8sm4")
191 return {Botan::CPUID::CPUID_ARM_SM4_BIT};
static bool has_simd_32()
#define BOTAN_ASSERT(expr, assertion_made)
static std::string to_string()
static std::vector< CPUID::CPUID_bits > bit_from_string(const std::string &tok)
#define BOTAN_UNUSED(...)
static void print(std::ostream &o)
#define CPUID_PRINT(flag)
std::string string_join(const std::vector< std::string > &strs, char delim)