• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.4
/src/lib/utils/cpuid/cpuid.cpp
1
/*
2
* Runtime CPU detection
3
* (C) 2009,2010,2013,2017,2023 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/internal/cpuid.h>
9

10
#include <botan/exceptn.h>
11
#include <botan/types.h>
12
#include <botan/internal/os_utils.h>
13
#include <botan/internal/parsing.h>
14
#include <ostream>
15

16
namespace Botan {
17

18
bool CPUID::has_simd_32() {
299,533✔
19
#if defined(BOTAN_TARGET_SUPPORTS_SSE2)
20
   return CPUID::has_sse2();
299,533✔
21
#elif defined(BOTAN_TARGET_SUPPORTS_ALTIVEC)
22
   return CPUID::has_altivec();
23
#elif defined(BOTAN_TARGET_SUPPORTS_NEON)
24
   return CPUID::has_neon();
25
#else
26
   return true;
27
#endif
28
}
29

30
//static
31
std::string CPUID::to_string() {
16✔
32
   std::vector<std::string> flags;
16✔
33

34
   auto append_fn = [&](bool flag, const char* flag_name) {
240✔
35
      if(flag)
224✔
36
         flags.push_back(flag_name);
288✔
37
   };
224✔
38

39
   // NOLINTNEXTLINE(*-macro-usage)
40
#define CPUID_PRINT(flag) append_fn(has_##flag(), #flag)
41

42
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
43
   CPUID_PRINT(rdtsc);
16✔
44

45
   CPUID_PRINT(sse2);
16✔
46
   CPUID_PRINT(ssse3);
16✔
47
   CPUID_PRINT(avx2);
16✔
48

49
   CPUID_PRINT(bmi2);
16✔
50
   CPUID_PRINT(adx);
16✔
51

52
   CPUID_PRINT(aes_ni);
16✔
53
   CPUID_PRINT(clmul);
16✔
54
   CPUID_PRINT(rdrand);
16✔
55
   CPUID_PRINT(rdseed);
16✔
56
   CPUID_PRINT(intel_sha);
16✔
57

58
   CPUID_PRINT(avx512);
16✔
59
   CPUID_PRINT(avx512_aes);
16✔
60
   CPUID_PRINT(avx512_clmul);
16✔
61
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
62
   CPUID_PRINT(altivec);
63
   CPUID_PRINT(power_crypto);
64
   CPUID_PRINT(darn_rng);
65
#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
66
   CPUID_PRINT(neon);
67
   CPUID_PRINT(arm_sve);
68

69
   CPUID_PRINT(arm_sha1);
70
   CPUID_PRINT(arm_sha2);
71
   CPUID_PRINT(arm_aes);
72
   CPUID_PRINT(arm_pmull);
73
   CPUID_PRINT(arm_sha2_512);
74
   CPUID_PRINT(arm_sha3);
75
   CPUID_PRINT(arm_sm3);
76
   CPUID_PRINT(arm_sm4);
77
#else
78
   BOTAN_UNUSED(append_fn);
79
#endif
80

81
#undef CPUID_PRINT
82

83
   return string_join(flags, ' ');
32✔
84
}
16✔
85

86
//static
87
void CPUID::initialize() { state() = CPUID_Data(); }
5,603✔
88

89
namespace {
90

91
// Returns true if big-endian
92
bool runtime_check_if_big_endian() {
12,840✔
93
   // Check runtime endian
94
   const uint32_t endian32 = 0x01234567;
12,840✔
95
   const uint8_t* e8 = reinterpret_cast<const uint8_t*>(&endian32);
12,840✔
96

97
   bool is_big_endian = false;
12,840✔
98

99
   if(e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67) {
12,840✔
100
      is_big_endian = true;
101
   } else if(e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01) {
12,840✔
102
      is_big_endian = false;
103
   } else {
104
      throw Internal_Error("Unexpected endian at runtime, neither big nor little");
105
   }
106

107
   // If we were compiled with a known endian, verify it matches at runtime
108
#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
109
   BOTAN_ASSERT(!is_big_endian, "Build and runtime endian match");
12,840✔
110
#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
111
   BOTAN_ASSERT(is_big_endian, "Build and runtime endian match");
112
#endif
113

114
   return is_big_endian;
12,840✔
115
}
116

117
}
118

119
CPUID::CPUID_Data::CPUID_Data() {
12,840✔
120
   m_processor_features = 0;
12,840✔
121

122
#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
123
   defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
124

125
   m_processor_features = detect_cpu_features();
12,840✔
126

127
#endif
128

129
   m_processor_features |= CPUID::CPUID_INITIALIZED_BIT;
12,840✔
130

131
   if(runtime_check_if_big_endian())
12,840✔
132
      m_processor_features |= CPUID::CPUID_IS_BIG_ENDIAN_BIT;
133

134
   std::string clear_cpuid_env;
12,840✔
135
   if(OS::read_env_variable(clear_cpuid_env, "BOTAN_CLEAR_CPUID")) {
12,840✔
136
      for(const auto& cpuid : split_on(clear_cpuid_env, ',')) {
286✔
137
         for(auto& bit : CPUID::bit_from_string(cpuid)) {
286✔
138
            const uint32_t cleared = ~static_cast<uint32_t>(bit);
143✔
139
            m_processor_features &= cleared;
143✔
140
         }
143✔
141
      }
143✔
142
   }
143
}
12,840✔
144

145
std::vector<CPUID::CPUID_bits> CPUID::bit_from_string(std::string_view tok) {
183✔
146
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
147
   if(tok == "sse2" || tok == "simd")
215✔
148
      return {CPUID::CPUID_SSE2_BIT};
7✔
149
   if(tok == "ssse3")
185✔
150
      return {CPUID::CPUID_SSSE3_BIT};
6✔
151
   // aes_ni is the string printed on the console when running "botan cpuid"
152
   if(tok == "aesni" || tok == "aes_ni")
318✔
153
      return {CPUID::CPUID_AESNI_BIT};
4✔
154
   if(tok == "clmul")
169✔
155
      return {CPUID::CPUID_CLMUL_BIT};
3✔
156
   if(tok == "avx2")
169✔
157
      return {CPUID::CPUID_AVX2_BIT};
6✔
158
   if(tok == "avx512")
293✔
159
      return {CPUID::CPUID_AVX512_BIT};
2✔
160
   // there were two if statements testing "sha" and "intel_sha" separately; combined
161
   if(tok == "sha" || tok == "intel_sha")
161✔
162
      return {CPUID::CPUID_SHA_BIT};
3✔
163
   if(tok == "rdtsc")
154✔
164
      return {CPUID::CPUID_RDTSC_BIT};
1✔
165
   if(tok == "bmi2")
153✔
166
      return {CPUID::CPUID_BMI_BIT};
4✔
167
   if(tok == "adx")
147✔
168
      return {CPUID::CPUID_ADX_BIT};
1✔
169
   if(tok == "rdrand")
281✔
170
      return {CPUID::CPUID_RDRAND_BIT};
1✔
171
   if(tok == "rdseed")
146✔
172
      return {CPUID::CPUID_RDSEED_BIT};
134✔
173
   if(tok == "avx512_aes")
11✔
174
      return {CPUID::CPUID_AVX512_AES_BIT};
×
175
   if(tok == "avx512_clmul")
12✔
176
      return {CPUID::CPUID_AVX512_CLMUL_BIT};
×
177

178
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
179
   if(tok == "altivec" || tok == "simd")
180
      return {CPUID::CPUID_ALTIVEC_BIT};
181
   if(tok == "power_crypto")
182
      return {CPUID::CPUID_POWER_CRYPTO_BIT};
183
   if(tok == "darn_rng")
184
      return {CPUID::CPUID_DARN_BIT};
185

186
#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
187
   if(tok == "neon" || tok == "simd")
188
      return {CPUID::CPUID_ARM_NEON_BIT};
189
   if(tok == "arm_sve")
190
      return {CPUID::CPUID_ARM_SVE_BIT};
191
   if(tok == "armv8sha1" || tok == "arm_sha1")
192
      return {CPUID::CPUID_ARM_SHA1_BIT};
193
   if(tok == "armv8sha2" || tok == "arm_sha2")
194
      return {CPUID::CPUID_ARM_SHA2_BIT};
195
   if(tok == "armv8aes" || tok == "arm_aes")
196
      return {CPUID::CPUID_ARM_AES_BIT};
197
   if(tok == "armv8pmull" || tok == "arm_pmull")
198
      return {CPUID::CPUID_ARM_PMULL_BIT};
199
   if(tok == "armv8sha3" || tok == "arm_sha3")
200
      return {CPUID::CPUID_ARM_SHA3_BIT};
201
   if(tok == "armv8sha2_512" || tok == "arm_sha2_512")
202
      return {CPUID::CPUID_ARM_SHA2_512_BIT};
203
   if(tok == "armv8sm3" || tok == "arm_sm3")
204
      return {CPUID::CPUID_ARM_SM3_BIT};
205
   if(tok == "armv8sm4" || tok == "arm_sm4")
206
      return {CPUID::CPUID_ARM_SM4_BIT};
207

208
#else
209
   BOTAN_UNUSED(tok);
210
#endif
211

212
   return {};
11✔
213
}
214

215
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc