Crypto++  8.0
Free C++ class library of cryptographic schemes
cpu.cpp
1 // cpu.cpp - originally written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 #include "config.h"
5 
6 #ifndef EXCEPTION_EXECUTE_HANDLER
7 # define EXCEPTION_EXECUTE_HANDLER 1
8 #endif
9 
10 #ifndef CRYPTOPP_IMPORTS
11 
12 #include "cpu.h"
13 #include "misc.h"
14 #include "stdcpp.h"
15 
16 #ifdef _AIX
17 # include <sys/systemcfg.h>
18 #endif
19 
20 #ifdef __linux__
21 # include <unistd.h>
22 #endif
23 
24 // Capability queries, requires Glibc 2.16, http://lwn.net/Articles/519085/
25 // CRYPTOPP_GLIBC_VERSION not used because config.h is missing <feature.h>
26 #if (((__GLIBC__ * 100) + __GLIBC_MINOR__) >= 216)
27 # define CRYPTOPP_GETAUXV_AVAILABLE 1
28 #endif
29 
30 #if CRYPTOPP_GETAUXV_AVAILABLE
31 # include <sys/auxv.h>
32 #else
33 #ifndef AT_HWCAP
34 # define AT_HWCAP 16
35 #endif
36 #ifndef AT_HWCAP2
37 # define AT_HWCAP2 26
38 #endif
39 unsigned long int getauxval(unsigned long int) { return 0; }
40 #endif
41 
42 #if defined(__APPLE__)
43 # include <sys/utsname.h>
44 #endif
45 
46 // The cpu-features header and source file are located in
47 // "$ANDROID_NDK_ROOT/sources/android/cpufeatures".
48 // setenv-android.sh will copy the header and source file
49 // into PWD and the makefile will build it in place.
50 #if defined(__ANDROID__)
51 # include "cpu-features.h"
52 #endif
53 
54 #ifdef CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
55 # include <signal.h>
56 # include <setjmp.h>
57 #endif
58 
59 // Visual Studio 2008 and below is missing _xgetbv. See x64dll.asm for the body.
60 #if defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_X64)
61 extern "C" unsigned long long __fastcall ExtendedControlRegister(unsigned int);
62 #endif
63 
64 ANONYMOUS_NAMESPACE_BEGIN
65 
66 #if defined(__APPLE__)
67 enum {PowerMac=1, Mac, iPhone, iPod, iPad, AppleTV, AppleWatch};
68 void GetAppleMachineInfo(unsigned int& device, unsigned int& version)
69 {
70  device = version = 0;
71 
72  struct utsname systemInfo;
73  systemInfo.machine[0] = '\0';
74  uname(&systemInfo);
75 
76  std::string machine(systemInfo.machine);
77  if (machine.find("PowerMac") != std::string::npos ||
78  machine.find("Power Macintosh") != std::string::npos)
79  device = PowerMac;
80  else if (machine.find("Mac") != std::string::npos ||
81  machine.find("Macintosh") != std::string::npos)
82  device = Mac;
83  else if (machine.find("iPhone") != std::string::npos)
84  device = iPhone;
85  else if (machine.find("iPod") != std::string::npos)
86  device = iPod;
87  else if (machine.find("iPad") != std::string::npos)
88  device = iPad;
89  else if (machine.find("AppleTV") != std::string::npos)
90  device = AppleTV;
91  else if (machine.find("AppleWatch") != std::string::npos)
92  device = AppleWatch;
93 
94  std::string::size_type pos = machine.find_first_of("0123456789");
95  if (pos != std::string::npos)
96  version = std::atoi(machine.substr(pos).c_str());
97 }
98 
99 // http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
100 bool IsAppleMachineARMv8(unsigned int device, unsigned int version)
101 {
102  if ((device == iPhone && version >= 6) ||
103  (device == iPad && version >= 4))
104  {
105  return true;
106  }
107  return false;
108 }
109 
110 bool IsAppleMachineARMv84(unsigned int device, unsigned int version)
111 {
112  return false;
113 }
114 #endif // __APPLE__
115 
116 ANONYMOUS_NAMESPACE_END
117 
118 NAMESPACE_BEGIN(CryptoPP)
119 
120 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
121 extern "C" {
122  typedef void (*SigHandler)(int);
123 }
124 
125 extern "C"
126 {
127  static jmp_buf s_jmpNoCPUID;
128  static void SigIllHandlerCPUID(int unused)
129  {
130  CRYPTOPP_UNUSED(unused);
131  longjmp(s_jmpNoCPUID, 1);
132  }
133 }
134 #endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
135 
136 // *************************** IA-32 CPUs ***************************
137 
138 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
139 
140 extern bool CPU_ProbeSSE2();
141 
142 #if _MSC_VER >= 1600
143 
144 inline bool CpuId(word32 func, word32 subfunc, word32 output[4])
145 {
146  __cpuidex((int *)output, func, subfunc);
147  return true;
148 }
149 
150 #elif _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64
151 
152 inline bool CpuId(word32 func, word32 subfunc, word32 output[4])
153 {
154  if (subfunc != 0)
155  return false;
156 
157  __cpuid((int *)output, func);
158  return true;
159 }
160 
161 #else
162 
163 // Borland/Embarcadero and Issue 498
164 // cpu.cpp (131): E2211 Inline assembly not allowed in inline and template functions
165 bool CpuId(word32 func, word32 subfunc, word32 output[4])
166 {
167 #if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) || defined(__BORLANDC__)
168  __try
169  {
170  // Borland/Embarcadero and Issue 500
171  // Local variables for cpuid output
172  word32 a, b, c, d;
173  __asm
174  {
175  mov eax, func
176  mov ecx, subfunc
177  cpuid
178  mov [a], eax
179  mov [b], ebx
180  mov [c], ecx
181  mov [d], edx
182  }
183  output[0] = a;
184  output[1] = b;
185  output[2] = c;
186  output[3] = d;
187  }
188  // GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION
189  __except (EXCEPTION_EXECUTE_HANDLER)
190  {
191  return false;
192  }
193 
194  // func = 0 returns the highest basic function understood in EAX. If the CPU does
195  // not return non-0, then it is mostly useless. The code below converts basic
196  // function value to a true/false return value.
197  if(func == 0)
198  return output[0] != 0;
199 
200  return true;
201 #else
202  // longjmp and clobber warnings. Volatile is required.
203  // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
204  volatile bool result = true;
205 
206  volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
207  if (oldHandler == SIG_ERR)
208  return false;
209 
210 # ifndef __MINGW32__
211  volatile sigset_t oldMask;
212  if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask) != 0)
213  return false;
214 # endif
215 
216  if (setjmp(s_jmpNoCPUID))
217  result = false;
218  else
219  {
220  asm volatile
221  (
222  // save ebx in case -fPIC is being used
223  // TODO: this might need an early clobber on EDI.
224 # if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
225  "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
226 # else
227  "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
228 # endif
229  : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3])
230  : "a" (func), "c" (subfunc)
231  : "cc"
232  );
233  }
234 
235 # ifndef __MINGW32__
236  sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
237 # endif
238 
239  signal(SIGILL, oldHandler);
240  return result;
241 #endif
242 }
243 
244 #endif
245 
246 bool CRYPTOPP_SECTION_INIT g_x86DetectionDone = false;
247 bool CRYPTOPP_SECTION_INIT g_hasSSE2 = false;
248 bool CRYPTOPP_SECTION_INIT g_hasSSSE3 = false;
249 bool CRYPTOPP_SECTION_INIT g_hasSSE41 = false;
250 bool CRYPTOPP_SECTION_INIT g_hasSSE42 = false;
251 bool CRYPTOPP_SECTION_INIT g_hasAVX = false;
252 bool CRYPTOPP_SECTION_INIT g_hasAVX2 = false;
253 bool CRYPTOPP_SECTION_INIT g_hasAESNI = false;
254 bool CRYPTOPP_SECTION_INIT g_hasCLMUL = false;
255 bool CRYPTOPP_SECTION_INIT g_hasADX = false;
256 bool CRYPTOPP_SECTION_INIT g_hasSHA = false;
257 bool CRYPTOPP_SECTION_INIT g_hasRDRAND = false;
258 bool CRYPTOPP_SECTION_INIT g_hasRDSEED = false;
259 bool CRYPTOPP_SECTION_INIT g_isP4 = false;
260 bool CRYPTOPP_SECTION_INIT g_hasPadlockRNG = false;
261 bool CRYPTOPP_SECTION_INIT g_hasPadlockACE = false;
262 bool CRYPTOPP_SECTION_INIT g_hasPadlockACE2 = false;
263 bool CRYPTOPP_SECTION_INIT g_hasPadlockPHE = false;
264 bool CRYPTOPP_SECTION_INIT g_hasPadlockPMM = false;
265 word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
266 
267 static inline bool IsIntel(const word32 output[4])
268 {
269  // This is the "GenuineIntel" string
270  return (output[1] /*EBX*/ == 0x756e6547) &&
271  (output[2] /*ECX*/ == 0x6c65746e) &&
272  (output[3] /*EDX*/ == 0x49656e69);
273 }
274 
275 static inline bool IsAMD(const word32 output[4])
276 {
277  // This is the "AuthenticAMD" string. Some early K5's can return "AMDisbetter!"
278  return (output[1] /*EBX*/ == 0x68747541) &&
279  (output[2] /*ECX*/ == 0x444D4163) &&
280  (output[3] /*EDX*/ == 0x69746E65);
281 }
282 
283 static inline bool IsHygon(const word32 output[4])
284 {
285  // This is the "HygonGenuine" string.
286  return (output[1] /*EBX*/ == 0x6f677948) &&
287  (output[2] /*ECX*/ == 0x656e6975) &&
288  (output[3] /*EDX*/ == 0x6e65476e);
289 }
290 
291 static inline bool IsVIA(const word32 output[4])
292 {
293  // This is the "CentaurHauls" string. Some non-PadLock's can return "VIA VIA VIA "
294  return (output[1] /*EBX*/ == 0x746e6543) &&
295  (output[2] /*ECX*/ == 0x736c7561) &&
296  (output[3] /*EDX*/ == 0x48727561);
297 }
298 
299 void DetectX86Features()
300 {
301  // Coverity finding CID 171239...
302  word32 cpuid0[4]={0}, cpuid1[4]={0}, cpuid2[4]={0};
303  if (!CpuId(0, 0, cpuid0))
304  return;
305  if (!CpuId(1, 0, cpuid1))
306  return;
307 
308  // cpuid1[2] & (1 << 27) is XSAVE/XRESTORE and signals OS support for SSE; use it to avoid probes.
309  // See http://github.com/weidai11/cryptopp/issues/511 and http://stackoverflow.com/a/22521619/608639
310  if ((cpuid1[3] & (1 << 26)) != 0)
311  g_hasSSE2 = ((cpuid1[2] & (1 << 27)) != 0) || CPU_ProbeSSE2();
312 
313  g_hasSSSE3 = g_hasSSE2 && ((cpuid1[2] & (1<< 9)) != 0);
314  g_hasSSE41 = g_hasSSE2 && ((cpuid1[2] & (1<<19)) != 0);
315  g_hasSSE42 = g_hasSSE2 && ((cpuid1[2] & (1<<20)) != 0);
316  g_hasAESNI = g_hasSSE2 && ((cpuid1[2] & (1<<25)) != 0);
317  g_hasCLMUL = g_hasSSE2 && ((cpuid1[2] & (1<< 1)) != 0);
318 
319  // AVX is similar to SSE, but check both bits 27 (SSE) and 28 (AVX).
320  // https://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled
321  CRYPTOPP_CONSTANT(YMM_FLAG = (3 << 1))
322  CRYPTOPP_CONSTANT(AVX_FLAG = (3 << 27))
323  if ((cpuid1[2] & AVX_FLAG) == AVX_FLAG)
324  {
325 // GCC 4.1/Binutils 2.17 cannot consume xgetbv
326 #if defined(__GNUC__) || (__SUNPRO_CC >= 0x5100) || defined(__BORLANDC__)
327  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71659 and
328  // http://www.agner.org/optimize/vectorclass/read.php?i=65
329  word32 a=0, d=0;
330  __asm __volatile
331  (
332  // "xgetbv" : "=a"(a), "=d"(d) : "c"(0) :
333  ".byte 0x0f, 0x01, 0xd0" "\n\t"
334  : "=a"(a), "=d"(d) : "c"(0) :
335  );
336  word64 xcr0 = a | static_cast<word64>(d) << 32;
337  g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
338 
339 // Visual Studio 2008 and below lack xgetbv
340 #elif defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_IX86)
341  word32 a=0, d=0;
342  __asm {
343  push eax
344  push edx
345  push ecx
346  mov ecx, 0
347  _emit 0x0f
348  _emit 0x01
349  _emit 0xd0
350  mov a, eax
351  mov d, edx
352  pop ecx
353  pop edx
354  pop eax
355  }
356  word64 xcr0 = a | static_cast<word64>(d) << 32;
357  g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
358 
359 // Visual Studio 2008 and below lack xgetbv
360 #elif defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_X64)
361  word64 xcr0 = ExtendedControlRegister(0);
362  g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
363 #elif defined(__SUNPRO_CC) // fall into
364  g_hasAVX = false;
365 #else
366  word64 xcr0 = _xgetbv(0);
367  g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
368 #endif
369  }
370 
371  if (IsIntel(cpuid0))
372  {
373  CRYPTOPP_CONSTANT(RDRAND_FLAG = (1 << 30))
374  CRYPTOPP_CONSTANT(RDSEED_FLAG = (1 << 18))
375  CRYPTOPP_CONSTANT( ADX_FLAG = (1 << 19))
376  CRYPTOPP_CONSTANT( SHA_FLAG = (1 << 29))
377  CRYPTOPP_CONSTANT( AVX2_FLAG = (1 << 5))
378 
379  g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
380  g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
381  g_hasRDRAND = (cpuid1[2] /*ECX*/ & RDRAND_FLAG) != 0;
382 
383  if (cpuid0[0] /*EAX*/ >= 7)
384  {
385  if (CpuId(7, 0, cpuid2))
386  {
387  g_hasRDSEED = (cpuid2[1] /*EBX*/ & RDSEED_FLAG) != 0;
388  g_hasADX = (cpuid2[1] /*EBX*/ & ADX_FLAG) != 0;
389  g_hasSHA = (cpuid2[1] /*EBX*/ & SHA_FLAG) != 0;
390  g_hasAVX2 = (cpuid2[1] /*EBX*/ & AVX2_FLAG) != 0;
391  }
392  }
393  }
394  else if (IsAMD(cpuid0) || IsHygon(cpuid0))
395  {
396  CRYPTOPP_CONSTANT(RDRAND_FLAG = (1 << 30))
397  CRYPTOPP_CONSTANT(RDSEED_FLAG = (1 << 18))
398  CRYPTOPP_CONSTANT( ADX_FLAG = (1 << 19))
399  CRYPTOPP_CONSTANT( SHA_FLAG = (1 << 29))
400  CRYPTOPP_CONSTANT( AVX2_FLAG = (1 << 5))
401 
402  CpuId(0x80000005, 0, cpuid2);
403  g_cacheLineSize = GETBYTE(cpuid2[2], 0);
404  g_hasRDRAND = (cpuid1[2] /*ECX*/ & RDRAND_FLAG) != 0;
405 
406  if (cpuid0[0] /*EAX*/ >= 7)
407  {
408  if (CpuId(7, 0, cpuid2))
409  {
410  g_hasRDSEED = (cpuid2[1] /*EBX*/ & RDSEED_FLAG) != 0;
411  g_hasADX = (cpuid2[1] /*EBX*/ & ADX_FLAG) != 0;
412  g_hasSHA = (cpuid2[1] /*EBX*/ & SHA_FLAG) != 0;
413  g_hasAVX2 = (cpuid2[1] /*EBX*/ & AVX2_FLAG) != 0;
414  }
415  }
416  }
417  else if (IsVIA(cpuid0))
418  {
419  CRYPTOPP_CONSTANT( RNG_FLAGS = (0x3 << 2))
420  CRYPTOPP_CONSTANT( ACE_FLAGS = (0x3 << 6))
421  CRYPTOPP_CONSTANT(ACE2_FLAGS = (0x3 << 8))
422  CRYPTOPP_CONSTANT( PHE_FLAGS = (0x3 << 10))
423  CRYPTOPP_CONSTANT( PMM_FLAGS = (0x3 << 12))
424 
425  CpuId(0xC0000000, 0, cpuid2);
426  if (cpuid2[0] >= 0xC0000001)
427  {
428  // Extended features available
429  CpuId(0xC0000001, 0, cpuid2);
430  g_hasPadlockRNG = (cpuid2[3] /*EDX*/ & RNG_FLAGS) == RNG_FLAGS;
431  g_hasPadlockACE = (cpuid2[3] /*EDX*/ & ACE_FLAGS) == ACE_FLAGS;
432  g_hasPadlockACE2 = (cpuid2[3] /*EDX*/ & ACE2_FLAGS) == ACE2_FLAGS;
433  g_hasPadlockPHE = (cpuid2[3] /*EDX*/ & PHE_FLAGS) == PHE_FLAGS;
434  g_hasPadlockPMM = (cpuid2[3] /*EDX*/ & PMM_FLAGS) == PMM_FLAGS;
435  }
436  }
437 
438  if (g_cacheLineSize == 0)
439  g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
440 
441  *const_cast<volatile bool*>(&g_x86DetectionDone) = true;
442 }
443 
444 // *************************** ARM-32, Aarch32 and Aarch64 ***************************
445 
446 #elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8)
447 
448 bool CRYPTOPP_SECTION_INIT g_ArmDetectionDone = false;
449 bool CRYPTOPP_SECTION_INIT g_hasARMv7 = false;
450 bool CRYPTOPP_SECTION_INIT g_hasNEON = false;
451 bool CRYPTOPP_SECTION_INIT g_hasPMULL = false;
452 bool CRYPTOPP_SECTION_INIT g_hasCRC32 = false;
453 bool CRYPTOPP_SECTION_INIT g_hasAES = false;
454 bool CRYPTOPP_SECTION_INIT g_hasSHA1 = false;
455 bool CRYPTOPP_SECTION_INIT g_hasSHA2 = false;
456 bool CRYPTOPP_SECTION_INIT g_hasSHA512 = false;
457 bool CRYPTOPP_SECTION_INIT g_hasSHA3 = false;
458 bool CRYPTOPP_SECTION_INIT g_hasSM3 = false;
459 bool CRYPTOPP_SECTION_INIT g_hasSM4 = false;
460 word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
461 
462 // ARM does not have an unprivliged equivalent to CPUID on IA-32. We have to jump through some
463 // hoops to detect features on a wide array of platforms. Our strategy is two part. First,
464 // attempt to *Query* the OS for a feature, like using getauxval on Linux. If that fails,
465 // then *Probe* the cpu executing an instruction and an observe a SIGILL if unsupported.
466 // The probes are in source files where compilation options like -march=armv8-a+crc make
467 // intrinsics available. They are expensive when compared to a standard OS feature query.
468 // Always perform the feature quesry first. For Linux see
469 // http://sourceware.org/ml/libc-help/2017-08/msg00012.html
470 // Avoid probes on Apple platforms because Apple's signal handling for SIGILLs appears broken.
471 // We are trying to figure out a way to feature test without probes. Also see
472 // http://stackoverflow.com/a/11197770/608639 and
473 // http://gist.github.com/erkanyildiz/390a480f27e86f8cd6ba
474 
475 extern bool CPU_ProbeARMv7();
476 extern bool CPU_ProbeNEON();
477 extern bool CPU_ProbeCRC32();
478 extern bool CPU_ProbeAES();
479 extern bool CPU_ProbeSHA1();
480 extern bool CPU_ProbeSHA2();
481 extern bool CPU_ProbeSHA512();
482 extern bool CPU_ProbeSHA3();
483 extern bool CPU_ProbeSM3();
484 extern bool CPU_ProbeSM4();
485 extern bool CPU_ProbePMULL();
486 
487 // https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h
488 #ifndef HWCAP_ARMv7
489 # define HWCAP_ARMv7 (1 << 29)
490 #endif
491 #ifndef HWCAP_ASIMD
492 # define HWCAP_ASIMD (1 << 1)
493 #endif
494 #ifndef HWCAP_ARM_NEON
495 # define HWCAP_ARM_NEON 4096
496 #endif
497 #ifndef HWCAP_CRC32
498 # define HWCAP_CRC32 (1 << 7)
499 #endif
500 #ifndef HWCAP2_CRC32
501 # define HWCAP2_CRC32 (1 << 4)
502 #endif
503 #ifndef HWCAP_PMULL
504 # define HWCAP_PMULL (1 << 4)
505 #endif
506 #ifndef HWCAP2_PMULL
507 # define HWCAP2_PMULL (1 << 1)
508 #endif
509 #ifndef HWCAP_AES
510 # define HWCAP_AES (1 << 3)
511 #endif
512 #ifndef HWCAP2_AES
513 # define HWCAP2_AES (1 << 0)
514 #endif
515 #ifndef HWCAP_SHA1
516 # define HWCAP_SHA1 (1 << 5)
517 #endif
518 #ifndef HWCAP_SHA2
519 # define HWCAP_SHA2 (1 << 6)
520 #endif
521 #ifndef HWCAP2_SHA1
522 # define HWCAP2_SHA1 (1 << 2)
523 #endif
524 #ifndef HWCAP2_SHA2
525 # define HWCAP2_SHA2 (1 << 3)
526 #endif
527 #ifndef HWCAP_SHA3
528 # define HWCAP_SHA3 (1 << 17)
529 #endif
530 #ifndef HWCAP_SM3
531 # define HWCAP_SM3 (1 << 18)
532 #endif
533 #ifndef HWCAP_SM4
534 # define HWCAP_SM4 (1 << 19)
535 #endif
536 #ifndef HWCAP_SHA512
537 # define HWCAP_SHA512 (1 << 21)
538 #endif
539 
540 inline bool CPU_QueryARMv7()
541 {
542 #if defined(__aarch32__) || defined(__aarch64__)
543  // ARMv7 or above
544  return true;
545 #elif defined(__ANDROID__) && defined(__arm__)
546  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
547  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0))
548  return true;
549 #elif defined(__linux__) && defined(__arm__)
550  if ((getauxval(AT_HWCAP) & HWCAP_ARMv7) != 0)
551  return true;
552 #elif defined(__APPLE__) && defined(__arm__)
553  // Apple hardware is ARMv7 or above.
554  return true;
555 #endif
556  return false;
557 }
558 
559 inline bool CPU_QueryNEON()
560 {
561 #if defined(__ANDROID__) && defined(__aarch64__)
562  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
563  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD) != 0))
564  return true;
565 #elif defined(__ANDROID__) && defined(__arm__)
566  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
567  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0))
568  return true;
569 #elif defined(__linux__) && defined(__aarch64__)
570  if ((getauxval(AT_HWCAP) & HWCAP_ASIMD) != 0)
571  return true;
572 #elif defined(__linux__) && defined(__aarch32__)
573  if ((getauxval(AT_HWCAP2) & HWCAP2_ASIMD) != 0)
574  return true;
575 #elif defined(__linux__) && defined(__arm__)
576  if ((getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0)
577  return true;
578 #elif defined(__APPLE__) && defined(__aarch64__)
579  // Core feature set for Aarch32 and Aarch64.
580  return true;
581 #endif
582  return false;
583 }
584 
585 inline bool CPU_QueryCRC32()
586 {
587 #if defined(__ANDROID__) && defined(__aarch64__)
588  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
589  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_CRC32) != 0))
590  return true;
591 #elif defined(__ANDROID__) && defined(__aarch32__)
592  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
593  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_CRC32) != 0))
594  return true;
595 #elif defined(__linux__) && defined(__aarch64__)
596  if ((getauxval(AT_HWCAP) & HWCAP_CRC32) != 0)
597  return true;
598 #elif defined(__linux__) && defined(__aarch32__)
599  if ((getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0)
600  return true;
601 #elif defined(__APPLE__) && defined(__aarch64__)
602  // No compiler support. CRC intrinsics result in a failed compiled.
603  return false;
604 #endif
605  return false;
606 }
607 
608 inline bool CPU_QueryPMULL()
609 {
610 #if defined(__ANDROID__) && defined(__aarch64__)
611  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
612  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_PMULL) != 0))
613  return true;
614 #elif defined(__ANDROID__) && defined(__aarch32__)
615  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
616  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_PMULL) != 0))
617  return true;
618 #elif defined(__linux__) && defined(__aarch64__)
619  if ((getauxval(AT_HWCAP) & HWCAP_PMULL) != 0)
620  return true;
621 #elif defined(__linux__) && defined(__aarch32__)
622  if ((getauxval(AT_HWCAP2) & HWCAP2_PMULL) != 0)
623  return true;
624 #elif defined(__APPLE__) && defined(__aarch64__)
625  // No compiler support. PMULL intrinsics result in a failed compiled.
626  return false;
627 #endif
628  return false;
629 }
630 
631 inline bool CPU_QueryAES()
632 {
633 #if defined(__ANDROID__) && defined(__aarch64__)
634  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
635  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_AES) != 0))
636  return true;
637 #elif defined(__ANDROID__) && defined(__aarch32__)
638  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
639  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES) != 0))
640  return true;
641 #elif defined(__linux__) && defined(__aarch64__)
642  if ((getauxval(AT_HWCAP) & HWCAP_AES) != 0)
643  return true;
644 #elif defined(__linux__) && defined(__aarch32__)
645  if ((getauxval(AT_HWCAP2) & HWCAP2_AES) != 0)
646  return true;
647 #elif defined(__APPLE__) && defined(__aarch64__)
648  unsigned int device, version;
649  GetAppleMachineInfo(device, version);
650  return IsAppleMachineARMv8(device, version);
651 #endif
652  return false;
653 }
654 
655 inline bool CPU_QuerySHA1()
656 {
657 #if defined(__ANDROID__) && defined(__aarch64__)
658  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
659  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA1) != 0))
660  return true;
661 #elif defined(__ANDROID__) && defined(__aarch32__)
662  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
663  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA1) != 0))
664  return true;
665 #elif defined(__linux__) && defined(__aarch64__)
666  if ((getauxval(AT_HWCAP) & HWCAP_SHA1) != 0)
667  return true;
668 #elif defined(__linux__) && defined(__aarch32__)
669  if ((getauxval(AT_HWCAP2) & HWCAP2_SHA1) != 0)
670  return true;
671 #elif defined(__APPLE__) && defined(__aarch64__)
672  unsigned int device, version;
673  GetAppleMachineInfo(device, version);
674  return IsAppleMachineARMv8(device, version);
675 #endif
676  return false;
677 }
678 
679 inline bool CPU_QuerySHA2()
680 {
681 #if defined(__ANDROID__) && defined(__aarch64__)
682  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
683  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA2) != 0))
684  return true;
685 #elif defined(__ANDROID__) && defined(__aarch32__)
686  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
687  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA2) != 0))
688  return true;
689 #elif defined(__linux__) && defined(__aarch64__)
690  if ((getauxval(AT_HWCAP) & HWCAP_SHA2) != 0)
691  return true;
692 #elif defined(__linux__) && defined(__aarch32__)
693  if ((getauxval(AT_HWCAP2) & HWCAP2_SHA2) != 0)
694  return true;
695 #elif defined(__APPLE__) && defined(__aarch64__)
696  unsigned int device, version;
697  GetAppleMachineInfo(device, version);
698  return IsAppleMachineARMv8(device, version);
699 #endif
700  return false;
701 }
702 
703 inline bool CPU_QuerySHA512()
704 {
705 // Some ARMv8.4 features are disabled at the moment
706 #if defined(__ANDROID__) && defined(__aarch64__) && 0
707  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
708  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA512) != 0))
709  return true;
710 #elif defined(__ANDROID__) && defined(__aarch32__) && 0
711  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
712  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA512) != 0))
713  return true;
714 #elif defined(__linux__) && defined(__aarch64__)
715  if ((getauxval(AT_HWCAP) & HWCAP_SHA512) != 0)
716  return true;
717 #elif defined(__linux__) && defined(__aarch32__)
718  if ((getauxval(AT_HWCAP2) & HWCAP2_SHA512) != 0)
719  return true;
720 #elif defined(__APPLE__) && defined(__aarch64__) && 0
721  unsigned int device, version;
722  GetAppleMachineInfo(device, version);
723  return IsAppleMachineARMv84(device, version);
724 #endif
725  return false;
726 }
727 
728 inline bool CPU_QuerySHA3()
729 {
730 // Some ARMv8.4 features are disabled at the moment
731 #if defined(__ANDROID__) && defined(__aarch64__) && 0
732  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
733  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA3) != 0))
734  return true;
735 #elif defined(__ANDROID__) && defined(__aarch32__) && 0
736  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
737  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA3) != 0))
738  return true;
739 #elif defined(__linux__) && defined(__aarch64__)
740  if ((getauxval(AT_HWCAP) & HWCAP_SHA3) != 0)
741  return true;
742 #elif defined(__linux__) && defined(__aarch32__)
743  if ((getauxval(AT_HWCAP2) & HWCAP2_SHA3) != 0)
744  return true;
745 #elif defined(__APPLE__) && defined(__aarch64__) && 0
746  unsigned int device, version;
747  GetAppleMachineInfo(device, version);
748  return IsAppleMachineARMv84(device, version);
749 #endif
750  return false;
751 }
752 
753 inline bool CPU_QuerySM3()
754 {
755 // Some ARMv8.4 features are disabled at the moment
756 #if defined(__ANDROID__) && defined(__aarch64__) && 0
757  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
758  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SM3) != 0))
759  return true;
760 #elif defined(__ANDROID__) && defined(__aarch32__) && 0
761  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
762  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SM3) != 0))
763  return true;
764 #elif defined(__linux__) && defined(__aarch64__)
765  if ((getauxval(AT_HWCAP) & HWCAP_SM3) != 0)
766  return true;
767 #elif defined(__linux__) && defined(__aarch32__)
768  if ((getauxval(AT_HWCAP2) & HWCAP2_SM3) != 0)
769  return true;
770 #elif defined(__APPLE__) && defined(__aarch64__) && 0
771  unsigned int device, version;
772  GetAppleMachineInfo(device, version);
773  return IsAppleMachineARMv84(device, version);
774 #endif
775  return false;
776 }
777 
778 inline bool CPU_QuerySM4()
779 {
780 // Some ARMv8.4 features are disabled at the moment
781 #if defined(__ANDROID__) && defined(__aarch64__) && 0
782  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
783  ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SM4) != 0))
784  return true;
785 #elif defined(__ANDROID__) && defined(__aarch32__) && 0
786  if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
787  ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SM4) != 0))
788  return true;
789 #elif defined(__linux__) && defined(__aarch64__)
790  if ((getauxval(AT_HWCAP) & HWCAP_SM4) != 0)
791  return true;
792 #elif defined(__linux__) && defined(__aarch32__)
793  if ((getauxval(AT_HWCAP2) & HWCAP2_SM4) != 0)
794  return true;
795 #elif defined(__APPLE__) && defined(__aarch64__) && 0
796  unsigned int device, version;
797  GetAppleMachineInfo(device, version);
798  return IsAppleMachineARMv84(device, version);
799 #endif
800  return false;
801 }
802 
803 void DetectArmFeatures()
804 {
805  // The CPU_ProbeXXX's return false for OSes which
806  // can't tolerate SIGILL-based probes
807  g_hasARMv7 = CPU_QueryARMv7() || CPU_ProbeARMv7();
808  g_hasNEON = CPU_QueryNEON() || CPU_ProbeNEON();
809  g_hasCRC32 = CPU_QueryCRC32() || CPU_ProbeCRC32();
810  g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
811  g_hasAES = CPU_QueryAES() || CPU_ProbeAES();
812  g_hasSHA1 = CPU_QuerySHA1() || CPU_ProbeSHA1();
813  g_hasSHA2 = CPU_QuerySHA2() || CPU_ProbeSHA2();
814  g_hasSHA512 = CPU_QuerySHA512(); // || CPU_ProbeSHA512();
815  g_hasSHA3 = CPU_QuerySHA3(); // || CPU_ProbeSHA3();
816  g_hasSM3 = CPU_QuerySM3(); // || CPU_ProbeSM3();
817  g_hasSM4 = CPU_QuerySM4(); // || CPU_ProbeSM4();
818 
819 #if defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE)
820  // Glibc does not implement on some platforms. The runtime returns 0 instead of error.
821  // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
822  int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
823  if (cacheLineSize > 0)
824  g_cacheLineSize = cacheLineSize;
825 #endif
826 
827  *const_cast<volatile bool*>(&g_ArmDetectionDone) = true;
828 }
829 
830 // *************************** PowerPC and PowerPC64 ***************************
831 
832 #elif (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
833 
834 bool CRYPTOPP_SECTION_INIT g_PowerpcDetectionDone = false;
835 bool CRYPTOPP_SECTION_INIT g_hasAltivec = false;
836 bool CRYPTOPP_SECTION_INIT g_hasPower7 = false;
837 bool CRYPTOPP_SECTION_INIT g_hasPower8 = false;
838 bool CRYPTOPP_SECTION_INIT g_hasPower9 = false;
839 bool CRYPTOPP_SECTION_INIT g_hasAES = false;
840 bool CRYPTOPP_SECTION_INIT g_hasPMULL = false;
841 bool CRYPTOPP_SECTION_INIT g_hasSHA256 = false;
842 bool CRYPTOPP_SECTION_INIT g_hasSHA512 = false;
843 bool CRYPTOPP_SECTION_INIT g_hasDARN = false;
844 word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
845 
846 extern bool CPU_ProbeAltivec();
847 extern bool CPU_ProbePower7();
848 extern bool CPU_ProbePower8();
849 extern bool CPU_ProbePower9();
850 extern bool CPU_ProbeAES();
851 extern bool CPU_ProbePMULL();
852 extern bool CPU_ProbeSHA256();
853 extern bool CPU_ProbeSHA512();
854 extern bool CPU_ProbeDARN();
855 
856 // Linux define values from 64-Bit ELF V2 ABI Specification.
857 // http://openpowerfoundation.org/wp-content/uploads/resources/leabi/content/ch_preface.html
858 #ifndef PPC_FEATURE_HAS_ALTIVEC
859 # define PPC_FEATURE_HAS_ALTIVEC 0x10000000
860 #endif
861 #ifndef PPC_FEATURE_ARCH_2_06
862 # define PPC_FEATURE_ARCH_2_06 0x00000100
863 #endif
864 #ifndef PPC_FEATURE2_ARCH_2_07
865 # define PPC_FEATURE2_ARCH_2_07 0x80000000
866 #endif
867 #ifndef PPC_FEATURE2_ARCH_3_00
868 # define PPC_FEATURE2_ARCH_3_00 0x00800000
869 #endif
870 #ifndef PPC_FEATURE2_VEC_CRYPTO
871 # define PPC_FEATURE2_VEC_CRYPTO 0x02000000
872 #endif
873 
874 // AIX defines. We used to just call __power_7_andup()
875 // and friends but at Power9, too many compilers were
876 // missing __power_9_andup(). Instead we switched to
877 // a pattern similar to OpenSSL caps testing.
878 #ifndef __power_6_andup
879 # define __power_6_andup() __power_set(0xffffffffU<<14)
880 #endif
881 #ifndef __power_7_andup
882 # define __power_7_andup() __power_set(0xffffffffU<<15)
883 #endif
884 #ifndef __power_8_andup
885 # define __power_8_andup() __power_set(0xffffffffU<<16)
886 #endif
887 #ifndef __power_9_andup
888 # define __power_9_andup() __power_set(0xffffffffU<<17)
889 #endif
890 
891 // AIX first supported Altivec at Power6, though it
892 // was available much earlier for other vendors.
893 inline bool CPU_QueryAltivec()
894 {
895 #if defined(__linux__)
896  if ((getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) != 0)
897  return true;
898 #elif defined(_AIX)
899  if (__power_6_andup() != 0)
900  return true;
901 #elif defined(__APPLE__) && defined(__POWERPC__)
902  unsigned int device, version;
903  GetAppleMachineInfo(device, version);
904  return device == PowerMac;
905 #endif
906  return false;
907 }
908 
909 inline bool CPU_QueryPower7()
910 {
911  // Power7 and ISA 2.06
912 #if defined(__linux__)
913  if ((getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) != 0)
914  return true;
915 #elif defined(_AIX)
916  if (__power_7_andup() != 0)
917  return true;
918 #endif
919  return false;
920 }
921 
922 inline bool CPU_QueryPower8()
923 {
924  // Power8 and ISA 2.07 provide in-core crypto.
925 #if defined(__linux__)
926  if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) != 0)
927  return true;
928 #elif defined(_AIX)
929  if (__power_8_andup() != 0)
930  return true;
931 #endif
932  return false;
933 }
934 
935 inline bool CPU_QueryPower9()
936 {
937  // Power9 and ISA 3.0.
938 #if defined(__linux__)
939  if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0)
940  return true;
941 #elif defined(_AIX)
942  if (__power_9_andup() != 0)
943  return true;
944 #endif
945  return false;
946 }
947 
948 inline bool CPU_QueryAES()
949 {
950  // Power8 and ISA 2.07 provide in-core crypto. Glibc
951  // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
952 #if defined(__linux__)
953  if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
954  return true;
955 #elif defined(_AIX)
956  if (__power_8_andup() != 0)
957  return true;
958 #endif
959  return false;
960 }
961 
962 inline bool CPU_QueryPMULL()
963 {
964  // Power8 and ISA 2.07 provide in-core crypto. Glibc
965  // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
966 #if defined(__linux__)
967  if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
968  return true;
969 #elif defined(_AIX)
970  if (__power_8_andup() != 0)
971  return true;
972 #endif
973  return false;
974 }
975 
976 inline bool CPU_QuerySHA256()
977 {
978  // Power8 and ISA 2.07 provide in-core crypto. Glibc
979  // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
980 #if defined(__linux__)
981  if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
982  return true;
983 #elif defined(_AIX)
984  if (__power_8_andup() != 0)
985  return true;
986 #endif
987  return false;
988 }
989 inline bool CPU_QuerySHA512()
990 {
991  // Power8 and ISA 2.07 provide in-core crypto. Glibc
992  // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
993 #if defined(__linux__)
994  if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
995  return true;
996 #elif defined(_AIX)
997  if (__power_8_andup() != 0)
998  return true;
999 #endif
1000  return false;
1001 }
1002 
1003 // Power9 random number generator
1004 inline bool CPU_QueryDARN()
1005 {
1006  // Power9 and ISA 3.0 provide DARN.
1007 #if defined(__linux__)
1008  if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0)
1009  return true;
1010 #elif defined(_AIX)
1011  if (__power_9_andup() != 0)
1012  return true;
1013 #endif
1014  return false;
1015 }
1016 
1017 void DetectPowerpcFeatures()
1018 {
1019  // The CPU_ProbeXXX's return false for OSes which
1020  // can't tolerate SIGILL-based probes, like Apple
1021  g_hasAltivec = CPU_QueryAltivec() || CPU_ProbeAltivec();
1022  g_hasPower7 = CPU_QueryPower7() || CPU_ProbePower7();
1023  g_hasPower8 = CPU_QueryPower8() || CPU_ProbePower8();
1024  g_hasPower9 = CPU_QueryPower9() || CPU_ProbePower9();
1025  g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
1026  g_hasAES = CPU_QueryAES() || CPU_ProbeAES();
1027  g_hasSHA256 = CPU_QuerySHA256() || CPU_ProbeSHA256();
1028  g_hasSHA512 = CPU_QuerySHA512() || CPU_ProbeSHA512();
1029  g_hasDARN = CPU_QueryDARN() || CPU_ProbeDARN();
1030 
1031 #if defined(_AIX) && defined(SC_L1C_DLS)
1032  // /usr/include/sys/systemcfg.h
1033  int cacheLineSize = getsystemcfg(SC_L1C_DLS);
1034  if (cacheLineSize > 0)
1035  g_cacheLineSize = cacheLineSize;
1036 #elif defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE)
1037  // Glibc does not implement on some platforms. The runtime returns 0 instead of error.
1038  // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
1039  int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
1040  if (cacheLineSize > 0)
1041  g_cacheLineSize = cacheLineSize;
1042 #endif
1043 
1044  *const_cast<volatile bool*>(&g_PowerpcDetectionDone) = true;
1045 }
1046 
1047 #endif
1048 NAMESPACE_END
1049 
1050 // *************************** C++ Static Initialization ***************************
1051 
1052 ANONYMOUS_NAMESPACE_BEGIN
1053 
1054 class InitCpu
1055 {
1056 public:
1057  InitCpu()
1058  {
1059 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
1060  CryptoPP::DetectX86Features();
1061 #elif CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8
1062  CryptoPP::DetectArmFeatures();
1063 #elif CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64
1064  CryptoPP::DetectPowerpcFeatures();
1065 #endif
1066  }
1067 };
1068 
1069 // This is not really needed because HasSSE() and friends can dynamically initialize.
1070 // Everything depends on CPU features so we initialize it once at load time.
1071 // Dynamic initialization will be used if init priorities are not available.
1072 
1073 #if HAVE_GCC_INIT_PRIORITY
1074  const InitCpu s_init __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 10))) = InitCpu();
1075 #elif HAVE_MSC_INIT_PRIORITY
1076  #pragma warning(disable: 4075)
1077  #pragma init_seg(".CRT$XCU")
1078  const InitCpu s_init;
1079  #pragma warning(default: 4075)
1080 #elif HAVE_XLC_INIT_PRIORITY
1081  // XLC needs constant, not a define
1082  #pragma priority(270)
1083  const InitCpu s_init;
1084 #else
1085  const InitCpu s_init;
1086 #endif
1087 
1088 ANONYMOUS_NAMESPACE_END
1089 
1090 #endif // CRYPTOPP_IMPORTS
Utility functions for the Crypto++ library.
Library configuration file.
Common C++ header files.
Precompiled header file.
Functions for CPU features and intrinsics.
Crypto++ library namespace.