6 #ifndef EXCEPTION_EXECUTE_HANDLER 7 # define EXCEPTION_EXECUTE_HANDLER 1 10 #ifndef CRYPTOPP_IMPORTS 16 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 21 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 22 #include <emmintrin.h> 27 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 30 #define HAVE_GCC_CONSTRUCTOR1 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && ((CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 300)) && !(MACPORTS_GCC_COMPILER > 0)) 31 #define HAVE_GCC_CONSTRUCTOR0 (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0)) 34 typedef void (*SigHandler)(int);
36 #endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 38 #ifdef CRYPTOPP_CPUID_AVAILABLE 40 #if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 42 bool CpuId(word32 input, word32 output[4])
44 __cpuid((
int *)output, input);
50 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 53 static jmp_buf s_jmpNoCPUID;
54 static void SigIllHandlerCPUID(
int)
56 longjmp(s_jmpNoCPUID, 1);
59 static jmp_buf s_jmpNoSSE2;
60 static void SigIllHandlerSSE2(
int)
62 longjmp(s_jmpNoSSE2, 1);
67 bool CpuId(word32 input, word32 output[4])
69 #if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 85 __except (EXCEPTION_EXECUTE_HANDLER)
98 volatile bool result =
true;
100 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
101 if (oldHandler == SIG_ERR)
105 volatile sigset_t oldMask;
106 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
110 if (setjmp(s_jmpNoCPUID))
118 # if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 119 "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" 121 "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" 123 :
"=a" (output[0]),
"=D" (output[1]),
"=c" (output[2]),
"=d" (output[3])
124 :
"a" (input),
"c" (0)
129 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
132 signal(SIGILL, oldHandler);
139 static bool TrySSE2()
141 #if CRYPTOPP_BOOL_X64 143 #elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 146 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 148 #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 149 __m128i x = _mm_setzero_si128();
150 return _mm_cvtsi128_si32(x) == 0;
154 __except (EXCEPTION_EXECUTE_HANDLER)
162 volatile bool result =
true;
164 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
165 if (oldHandler == SIG_ERR)
169 volatile sigset_t oldMask;
170 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
174 if (setjmp(s_jmpNoSSE2))
178 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 179 __asm __volatile (
"por %xmm0, %xmm0");
180 #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 181 __m128i x = _mm_setzero_si128();
182 result = _mm_cvtsi128_si32(x) == 0;
187 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
190 signal(SIGILL, oldHandler);
195 bool CRYPTOPP_SECTION_INIT g_x86DetectionDone =
false;
196 bool CRYPTOPP_SECTION_INIT g_hasMMX =
false, CRYPTOPP_SECTION_INIT g_hasISSE =
false, CRYPTOPP_SECTION_INIT g_hasSSE2 =
false, CRYPTOPP_SECTION_INIT g_hasSSSE3 =
false;
197 bool CRYPTOPP_SECTION_INIT g_hasSSE4 =
false, CRYPTOPP_SECTION_INIT g_hasAESNI =
false, CRYPTOPP_SECTION_INIT g_hasCLMUL =
false, CRYPTOPP_SECTION_INIT g_isP4 =
false;
198 bool CRYPTOPP_SECTION_INIT g_hasRDRAND =
false, CRYPTOPP_SECTION_INIT g_hasRDSEED =
false;
199 bool CRYPTOPP_SECTION_INIT g_hasPadlockRNG =
false, CRYPTOPP_SECTION_INIT g_hasPadlockACE =
false, CRYPTOPP_SECTION_INIT g_hasPadlockACE2 =
false;
200 bool CRYPTOPP_SECTION_INIT g_hasPadlockPHE =
false, CRYPTOPP_SECTION_INIT g_hasPadlockPMM =
false;
201 word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
203 static inline bool IsIntel(
const word32 output[4])
206 return (output[1] == 0x756e6547) &&
207 (output[2] == 0x6c65746e) &&
208 (output[3] == 0x49656e69);
211 static inline bool IsAMD(
const word32 output[4])
214 return (output[1] == 0x68747541) &&
215 (output[2] == 0x444D4163) &&
216 (output[3] == 0x69746E65);
219 static inline bool IsVIA(
const word32 output[4])
222 return (output[1] == 0x746e6543) &&
223 (output[2] == 0x736c7561) &&
224 (output[3] == 0x48727561);
227 #if HAVE_GCC_CONSTRUCTOR1 228 void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 50))) DetectX86Features()
229 #elif HAVE_GCC_CONSTRUCTOR0 230 void __attribute__ ((constructor)) DetectX86Features()
232 void DetectX86Features()
235 word32 cpuid[4], cpuid1[4];
236 if (!CpuId(0, cpuid))
238 if (!CpuId(1, cpuid1))
241 g_hasMMX = (cpuid1[3] & (1 << 23)) != 0;
242 if ((cpuid1[3] & (1 << 26)) != 0)
243 g_hasSSE2 = TrySSE2();
244 g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9));
245 g_hasSSE4 = g_hasSSE2 && ((cpuid1[2] & (1<<19)) && (cpuid1[2] & (1<<20)));
246 g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25));
247 g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1));
249 if ((cpuid1[3] & (1 << 25)) != 0)
254 CpuId(0x080000000, cpuid2);
255 if (cpuid2[0] >= 0x080000001)
257 CpuId(0x080000001, cpuid2);
258 g_hasISSE = (cpuid2[3] & (1 << 22)) != 0;
264 static const unsigned int RDRAND_FLAG = (1 << 30);
265 static const unsigned int RDSEED_FLAG = (1 << 18);
267 g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf;
268 g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
269 g_hasRDRAND = !!(cpuid1[2] & RDRAND_FLAG);
274 if (CpuId(7, cpuid3))
275 g_hasRDSEED = !!(cpuid3[1] & RDSEED_FLAG);
278 else if (IsAMD(cpuid))
280 static const unsigned int RDRAND_FLAG = (1 << 30);
283 g_hasRDRAND = !!(cpuid[2] & RDRAND_FLAG);
285 CpuId(0x80000005, cpuid);
286 g_cacheLineSize = GETBYTE(cpuid[2], 0);
288 else if (IsVIA(cpuid))
290 static const unsigned int RNG_FLAGS = (0x3 << 2);
291 static const unsigned int ACE_FLAGS = (0x3 << 6);
292 static const unsigned int ACE2_FLAGS = (0x3 << 8);
293 static const unsigned int PHE_FLAGS = (0x3 << 10);
294 static const unsigned int PMM_FLAGS = (0x3 << 12);
296 CpuId(0xC0000000, cpuid);
297 if (cpuid[0] >= 0xC0000001)
300 CpuId(0xC0000001, cpuid);
301 g_hasPadlockRNG = !!(cpuid[3] & RNG_FLAGS);
302 g_hasPadlockACE = !!(cpuid[3] & ACE_FLAGS);
303 g_hasPadlockACE2 = !!(cpuid[3] & ACE2_FLAGS);
304 g_hasPadlockPHE = !!(cpuid[3] & PHE_FLAGS);
305 g_hasPadlockPMM = !!(cpuid[3] & PMM_FLAGS);
309 if (!g_cacheLineSize)
310 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
312 *((
volatile bool*)&g_x86DetectionDone) =
true;
315 #elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) 331 bool CRYPTOPP_SECTION_INIT g_ArmDetectionDone =
false;
332 bool CRYPTOPP_SECTION_INIT g_hasNEON =
false, CRYPTOPP_SECTION_INIT g_hasPMULL =
false, CRYPTOPP_SECTION_INIT g_hasCRC32 =
false;
333 bool CRYPTOPP_SECTION_INIT g_hasAES =
false, CRYPTOPP_SECTION_INIT g_hasSHA1 =
false, CRYPTOPP_SECTION_INIT g_hasSHA2 =
false;
334 word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
336 #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 339 static jmp_buf s_jmpNoNEON;
340 static void SigIllHandlerNEON(
int)
342 longjmp(s_jmpNoNEON, 1);
345 static jmp_buf s_jmpNoPMULL;
346 static void SigIllHandlerPMULL(
int)
348 longjmp(s_jmpNoPMULL, 1);
351 static jmp_buf s_jmpNoCRC32;
352 static void SigIllHandlerCRC32(
int)
354 longjmp(s_jmpNoCRC32, 1);
357 static jmp_buf s_jmpNoAES;
358 static void SigIllHandlerAES(
int)
360 longjmp(s_jmpNoAES, 1);
363 static jmp_buf s_jmpNoSHA1;
364 static void SigIllHandlerSHA1(
int)
366 longjmp(s_jmpNoSHA1, 1);
369 static jmp_buf s_jmpNoSHA2;
370 static void SigIllHandlerSHA2(
int)
372 longjmp(s_jmpNoSHA2, 1);
375 #endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 377 static bool TryNEON()
379 #if (CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE) 380 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 381 volatile bool result =
true;
384 uint32_t v1[4] = {1,1,1,1};
385 uint32x4_t x1 = vld1q_u32(v1);
386 uint64_t v2[2] = {1,1};
387 uint64x2_t x2 = vld1q_u64(v2);
389 uint32x4_t x3 = vdupq_n_u32(2);
390 x3 = vsetq_lane_u32(vgetq_lane_u32(x1,0),x3,0);
391 x3 = vsetq_lane_u32(vgetq_lane_u32(x1,3),x3,3);
392 uint64x2_t x4 = vdupq_n_u64(2);
393 x4 = vsetq_lane_u64(vgetq_lane_u64(x2,0),x4,0);
394 x4 = vsetq_lane_u64(vgetq_lane_u64(x2,1),x4,1);
396 result = !!(vgetq_lane_u32(x3,0) | vgetq_lane_u64(x4,1));
398 __except (EXCEPTION_EXECUTE_HANDLER)
406 volatile bool result =
true;
408 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerNEON);
409 if (oldHandler == SIG_ERR)
412 volatile sigset_t oldMask;
413 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
416 if (setjmp(s_jmpNoNEON))
420 uint32_t v1[4] = {1,1,1,1};
421 uint32x4_t x1 = vld1q_u32(v1);
422 uint64_t v2[2] = {1,1};
423 uint64x2_t x2 = vld1q_u64(v2);
425 uint32x4_t x3 = {0,0,0,0};
426 x3 = vsetq_lane_u32(vgetq_lane_u32(x1,0),x3,0);
427 x3 = vsetq_lane_u32(vgetq_lane_u32(x1,3),x3,3);
428 uint64x2_t x4 = {0,0};
429 x4 = vsetq_lane_u64(vgetq_lane_u64(x2,0),x4,0);
430 x4 = vsetq_lane_u64(vgetq_lane_u64(x2,1),x4,1);
433 result = !!(vgetq_lane_u32(x3,0) | vgetq_lane_u64(x4,1));
436 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
437 signal(SIGILL, oldHandler);
442 #endif // CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE 445 static bool TryPMULL()
447 #if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) 448 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 449 volatile bool result =
true;
452 const poly64_t a1={2}, b1={3};
453 const poly64x2_t a2={4,5}, b2={6,7};
454 const poly64x2_t a3={0x8080808080808080,0xa0a0a0a0a0a0a0a0}, b3={0xc0c0c0c0c0c0c0c0, 0xe0e0e0e0e0e0e0e0};
456 const poly128_t r1 = vmull_p64(a1, b1);
457 const poly128_t r2 = vmull_high_p64(a2, b2);
458 const poly128_t r3 = vmull_high_p64(a3, b3);
461 const uint64x2_t& t1 = vreinterpretq_u64_p128(r1);
462 const uint64x2_t& t2 = vreinterpretq_u64_p128(r2);
463 const uint64x2_t& t3 = vreinterpretq_u64_p128(r3);
465 result = !!(vgetq_lane_u64(t1,0) == 0x06 && vgetq_lane_u64(t1,1) == 0x00 && vgetq_lane_u64(t2,0) == 0x1b &&
466 vgetq_lane_u64(t2,1) == 0x00 && vgetq_lane_u64(t3,0) == 0x6c006c006c006c00 && vgetq_lane_u64(t3,1) == 0x6c006c006c006c00);
468 __except (EXCEPTION_EXECUTE_HANDLER)
476 volatile bool result =
true;
478 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerPMULL);
479 if (oldHandler == SIG_ERR)
482 volatile sigset_t oldMask;
483 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
486 if (setjmp(s_jmpNoPMULL))
490 const poly64_t a1={2}, b1={3};
491 const poly64x2_t a2={4,5}, b2={6,7};
492 const poly64x2_t a3={0x8080808080808080,0xa0a0a0a0a0a0a0a0}, b3={0xc0c0c0c0c0c0c0c0, 0xe0e0e0e0e0e0e0e0};
494 const poly128_t r1 = vmull_p64(a1, b1);
495 const poly128_t r2 = vmull_high_p64(a2, b2);
496 const poly128_t r3 = vmull_high_p64(a3, b3);
499 const uint64x2_t& t1 = (uint64x2_t)(r1);
500 const uint64x2_t& t2 = (uint64x2_t)(r2);
501 const uint64x2_t& t3 = (uint64x2_t)(r3);
503 result = !!(vgetq_lane_u64(t1,0) == 0x06 && vgetq_lane_u64(t1,1) == 0x00 && vgetq_lane_u64(t2,0) == 0x1b &&
504 vgetq_lane_u64(t2,1) == 0x00 && vgetq_lane_u64(t3,0) == 0x6c006c006c006c00 && vgetq_lane_u64(t3,1) == 0x6c006c006c006c00);
507 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
508 signal(SIGILL, oldHandler);
513 #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 516 static bool TryCRC32()
518 #if (CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE) 519 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 520 volatile bool result =
true;
523 word32 w=0, x=1; word16 y=2; byte z=3;
530 __except (EXCEPTION_EXECUTE_HANDLER)
538 volatile bool result =
true;
540 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerCRC32);
541 if (oldHandler == SIG_ERR)
544 volatile sigset_t oldMask;
545 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
548 if (setjmp(s_jmpNoCRC32))
552 word32 w=0, x=1; word16 y=2; byte z=3;
561 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
562 signal(SIGILL, oldHandler);
567 #endif // CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE 572 #if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) 573 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 574 volatile bool result =
true;
578 uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0);
579 uint8x16_t r1 = vaeseq_u8(data, key);
580 uint8x16_t r2 = vaesdq_u8(data, key);
582 result = !!(vgetq_lane_u8(r1,0) | vgetq_lane_u8(r2,7));
584 __except (EXCEPTION_EXECUTE_HANDLER)
592 volatile bool result =
true;
594 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerAES);
595 if (oldHandler == SIG_ERR)
598 volatile sigset_t oldMask;
599 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
602 if (setjmp(s_jmpNoAES))
606 uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0);
607 uint8x16_t r1 = vaeseq_u8(data, key);
608 uint8x16_t r2 = vaesdq_u8(data, key);
611 result = !!(vgetq_lane_u8(r1,0) | vgetq_lane_u8(r2,7));
614 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
615 signal(SIGILL, oldHandler);
620 #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 623 static bool TrySHA1()
625 #if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) 626 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 627 volatile bool result =
true;
630 uint32x4_t data1 = {1,2,3,4}, data2 = {5,6,7,8}, data3 = {9,10,11,12};
632 uint32x4_t r1 = vsha1cq_u32 (data1, 0, data2);
633 uint32x4_t r2 = vsha1mq_u32 (data1, 0, data2);
634 uint32x4_t r3 = vsha1pq_u32 (data1, 0, data2);
635 uint32x4_t r4 = vsha1su0q_u32 (data1, data2, data3);
636 uint32x4_t r5 = vsha1su1q_u32 (data1, data2);
638 result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3) | vgetq_lane_u32(r5,0));
640 __except (EXCEPTION_EXECUTE_HANDLER)
648 volatile bool result =
true;
650 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerSHA1);
651 if (oldHandler == SIG_ERR)
654 volatile sigset_t oldMask;
655 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
658 if (setjmp(s_jmpNoSHA1))
662 uint32x4_t data1 = {1,2,3,4}, data2 = {5,6,7,8}, data3 = {9,10,11,12};
664 uint32x4_t r1 = vsha1cq_u32 (data1, 0, data2);
665 uint32x4_t r2 = vsha1mq_u32 (data1, 0, data2);
666 uint32x4_t r3 = vsha1pq_u32 (data1, 0, data2);
667 uint32x4_t r4 = vsha1su0q_u32 (data1, data2, data3);
668 uint32x4_t r5 = vsha1su1q_u32 (data1, data2);
671 result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3) | vgetq_lane_u32(r5,0));
674 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
675 signal(SIGILL, oldHandler);
680 #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 683 static bool TrySHA2()
685 #if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) 686 # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) 687 volatile bool result =
true;
690 uint32x4_t data1 = {1,2,3,4}, data2 = {5,6,7,8}, data3 = {9,10,11,12};
692 uint32x4_t r1 = vsha256hq_u32 (data1, data2, data3);
693 uint32x4_t r2 = vsha256h2q_u32 (data1, data2, data3);
694 uint32x4_t r3 = vsha256su0q_u32 (data1, data2);
695 uint32x4_t r4 = vsha256su1q_u32 (data1, data2, data3);
697 result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3));
699 __except (EXCEPTION_EXECUTE_HANDLER)
707 volatile bool result =
true;
709 volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerSHA2);
710 if (oldHandler == SIG_ERR)
713 volatile sigset_t oldMask;
714 if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
717 if (setjmp(s_jmpNoSHA2))
721 uint32x4_t data1 = {1,2,3,4}, data2 = {5,6,7,8}, data3 = {9,10,11,12};
723 uint32x4_t r1 = vsha256hq_u32 (data1, data2, data3);
724 uint32x4_t r2 = vsha256h2q_u32 (data1, data2, data3);
725 uint32x4_t r3 = vsha256su0q_u32 (data1, data2);
726 uint32x4_t r4 = vsha256su1q_u32 (data1, data2, data3);
729 result = !!(vgetq_lane_u32(r1,0) | vgetq_lane_u32(r2,1) | vgetq_lane_u32(r3,2) | vgetq_lane_u32(r4,3));
732 sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
733 signal(SIGILL, oldHandler);
738 #endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE 741 #if HAVE_GCC_CONSTRUCTOR1 742 void __attribute__ ((constructor (CRYPTOPP_INIT_PRIORITY + 50))) DetectArmFeatures()
743 #elif HAVE_GCC_CONSTRUCTOR0 744 void __attribute__ ((constructor)) DetectArmFeatures()
746 void DetectArmFeatures()
749 g_hasNEON = TryNEON();
750 g_hasPMULL = TryPMULL();
751 g_hasCRC32 = TryCRC32();
753 g_hasSHA1 = TrySHA1();
754 g_hasSHA2 = TrySHA2();
756 *((
volatile bool*)&g_ArmDetectionDone) =
true;
Utility functions for the Crypto++ library.
Library configuration file.
Functions for CPU features and intrinsics.
Crypto++ library namespace.