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

randombit / botan / 13597425450

28 Feb 2025 10:16PM UTC coverage: 91.687% (-0.006%) from 91.693%
13597425450

push

github

web-flow
Merge pull request #4728 from randombit/jack/use-std-endian

Use std::endian more, remove endian checks in `CPUID`

95836 of 104525 relevant lines covered (91.69%)

11717992.75 hits per line

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

95.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/assert.h>
11
#include <botan/exceptn.h>
12
#include <botan/types.h>
13
#include <botan/internal/parsing.h>
14
#include <botan/internal/target_info.h>
15
#include <ostream>
16

17
#if defined(BOTAN_HAS_OS_UTILS)
18
   #include <botan/internal/os_utils.h>
19
#endif
20

21
namespace Botan {
22

23
//static
24
std::string CPUID::to_string() {
19✔
25
   std::vector<std::string> flags;
19✔
26

27
   auto append_fn = [&](bool flag, const char* flag_name) {
399✔
28
      if(flag) {
380✔
29
         flags.push_back(flag_name);
442✔
30
      }
31
   };
380✔
32

33
   // NOLINTNEXTLINE(*-macro-usage)
34
#define CPUID_PRINT(flag) append_fn(has_##flag(), #flag)
35

36
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
37
   CPUID_PRINT(rdtsc);
19✔
38

39
   CPUID_PRINT(sse2);
19✔
40
   CPUID_PRINT(ssse3);
19✔
41
   CPUID_PRINT(avx2);
19✔
42

43
   CPUID_PRINT(bmi2);
19✔
44
   CPUID_PRINT(adx);
19✔
45
   CPUID_PRINT(gfni);
19✔
46

47
   CPUID_PRINT(aes_ni);
19✔
48
   CPUID_PRINT(clmul);
19✔
49
   CPUID_PRINT(rdrand);
19✔
50
   CPUID_PRINT(rdseed);
19✔
51
   CPUID_PRINT(intel_sha);
19✔
52
   CPUID_PRINT(intel_sha512);
19✔
53

54
   CPUID_PRINT(avx2_vaes);
19✔
55
   CPUID_PRINT(avx2_clmul);
19✔
56

57
   CPUID_PRINT(avx512);
19✔
58
   CPUID_PRINT(avx512_aes);
19✔
59
   CPUID_PRINT(avx512_clmul);
19✔
60

61
   CPUID_PRINT(intel_sm3);
19✔
62
   CPUID_PRINT(intel_sm4);
19✔
63

64
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
65
   CPUID_PRINT(altivec);
66
   CPUID_PRINT(power_crypto);
67
   CPUID_PRINT(darn_rng);
68
#elif defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY)
69
   CPUID_PRINT(neon);
70
   CPUID_PRINT(arm_sve);
71

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

84
#undef CPUID_PRINT
85

86
   return string_join(flags, ' ');
38✔
87
}
19✔
88

89
//static
90
void CPUID::initialize() {
5,629✔
91
   state() = CPUID_Data();
5,629✔
92
}
5,629✔
93

94
namespace {
95

96
#if defined(BOTAN_CPUID_HAS_DETECTION)
97
uint32_t cleared_cpuid_bits() {
13,016✔
98
   uint32_t cleared = 0;
13,016✔
99

100
   #if defined(BOTAN_HAS_OS_UTILS)
101
   std::string clear_cpuid_env;
13,016✔
102
   if(OS::read_env_variable(clear_cpuid_env, "BOTAN_CLEAR_CPUID")) {
13,016✔
103
      for(const auto& cpuid : split_on(clear_cpuid_env, ',')) {
336✔
104
         for(auto& bit : CPUID::bit_from_string(cpuid)) {
336✔
105
            cleared |= bit;
168✔
106
         }
168✔
107
      }
168✔
108
   }
109
   #endif
110

111
   return cleared;
13,016✔
112
}
13,016✔
113
#endif
114

115
}  // namespace
116

117
CPUID::CPUID_Data::CPUID_Data() {
13,016✔
118
   m_processor_features = 0;
13,016✔
119

120
#if defined(BOTAN_CPUID_HAS_DETECTION)
121
   m_processor_features = detect_cpu_features(~cleared_cpuid_bits());
13,016✔
122
#endif
123

124
   m_processor_features |= CPUID::CPUID_INITIALIZED_BIT;
13,016✔
125
}
13,016✔
126

127
std::vector<CPUID::CPUID_bits> CPUID::bit_from_string(std::string_view tok) {
211✔
128
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
129
   if(tok == "sse2" || tok == "simd") {
232✔
130
      return {CPUID::CPUID_SSE2_BIT};
7✔
131
   } else if(tok == "ssse3") {
204✔
132
      return {CPUID::CPUID_SSSE3_BIT};
6✔
133
   } else if(tok == "aesni" || tok == "aes_ni") {
208✔
134
      // aes_ni is the string printed on the console when running "botan cpuid"
135
      return {CPUID::CPUID_AESNI_BIT};
4✔
136
   } else if(tok == "clmul") {
194✔
137
      return {CPUID::CPUID_CLMUL_BIT};
3✔
138
   } else if(tok == "avx2") {
191✔
139
      return {CPUID::CPUID_AVX2_BIT};
6✔
140
   } else if(tok == "avx512") {
370✔
141
      return {CPUID::CPUID_AVX512_BIT};
2✔
142
   }
143
   // there were two if statements testing "sha" and "intel_sha" separately; combined
144
   else if(tok == "sha" || tok == "intel_sha") {
188✔
145
      return {CPUID::CPUID_SHA_BIT};
4✔
146
   } else if(tok == "rdtsc") {
179✔
147
      return {CPUID::CPUID_RDTSC_BIT};
1✔
148
   } else if(tok == "bmi2") {
178✔
149
      return {CPUID::CPUID_BMI_BIT};
4✔
150
   } else if(tok == "adx") {
174✔
151
      return {CPUID::CPUID_ADX_BIT};
1✔
152
   } else if(tok == "gfni") {
173✔
153
      return {CPUID::CPUID_GFNI_BIT};
1✔
154
   } else if(tok == "rdrand") {
172✔
155
      return {CPUID::CPUID_RDRAND_BIT};
1✔
156
   } else if(tok == "rdseed") {
171✔
157
      return {CPUID::CPUID_RDSEED_BIT};
1✔
158
   } else if(tok == "avx512_aes") {
170✔
159
      return {CPUID::CPUID_AVX512_AES_BIT};
×
160
   } else if(tok == "avx512_clmul") {
170✔
161
      return {CPUID::CPUID_AVX512_CLMUL_BIT};
×
162
   } else if(tok == "avx2_vaes") {
170✔
163
      return {CPUID::CPUID_AVX2_AES_BIT};
4✔
164
   } else if(tok == "avx2_clmul") {
168✔
165
      return {CPUID::CPUID_AVX2_CLMUL_BIT};
156✔
166
   } else if(tok == "intel_sm3") {
12✔
167
      return {CPUID::CPUID_SM3_BIT};
×
168
   } else if(tok == "intel_sm4") {
12✔
169
      return {CPUID::CPUID_SM4_BIT};
×
170
   }
171

172
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
173
   if(tok == "altivec" || tok == "simd") {
174
      return {CPUID::CPUID_ALTIVEC_BIT};
175
   } else if(tok == "power_crypto") {
176
      return {CPUID::CPUID_POWER_CRYPTO_BIT};
177
   } else if(tok == "darn_rng") {
178
      return {CPUID::CPUID_DARN_BIT};
179
   }
180

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

204
#else
205
   BOTAN_UNUSED(tok);
206
#endif
207

208
   return {};
12✔
209
}
210

211
}  // namespace Botan
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