@@ -484,6 +484,14 @@ void inline cpuid(uint32_t leaf, uint32_t subleaf, uint32_t& a, uint32_t& b, uin
484
484
{
485
485
__asm__ (" cpuid" : " =a" (a), " =b" (b), " =c" (c), " =d" (d) : " 0" (leaf), " 2" (subleaf));
486
486
}
487
+
488
+ /* * Check whether the OS has enabled AVX registers. */
489
+ bool AVXEnabled ()
490
+ {
491
+ uint32_t a, d;
492
+ __asm__ (" xgetbv" : " =a" (a), " =d" (d) : " c" (0 ));
493
+ return (a & 6 ) == 6 ;
494
+ }
487
495
#endif
488
496
} // namespace
489
497
@@ -492,6 +500,7 @@ std::string SHA256AutoDetect()
492
500
{
493
501
std::string ret = " standard" ;
494
502
#if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
503
+ (void )AVXEnabled; // Silence unused warning (in case ENABLE_AVX2 is not defined)
495
504
uint32_t eax, ebx, ecx, edx;
496
505
cpuid (1 , 0 , eax, ebx, ecx, edx);
497
506
if ((ecx >> 19 ) & 1 ) {
@@ -503,10 +512,14 @@ std::string SHA256AutoDetect()
503
512
TransformD64_4way = sha256d64_sse41::Transform_4way;
504
513
ret = " sse4(1way+4way)" ;
505
514
#if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL)
506
- cpuid (7 , 0 , eax, ebx, ecx, edx);
507
- if ((ebx >> 5 ) & 1 ) {
508
- TransformD64_8way = sha256d64_avx2::Transform_8way;
509
- ret += " ,avx2(8way)" ;
515
+ if (((ecx >> 27 ) & 1 ) && ((ecx >> 28 ) & 1 )) { // XSAVE and AVX
516
+ cpuid (7 , 0 , eax, ebx, ecx, edx);
517
+ if ((ebx >> 5 ) & 1 ) { // AVX2 flag
518
+ if (AVXEnabled ()) { // OS has enabled AVX registers
519
+ TransformD64_8way = sha256d64_avx2::Transform_8way;
520
+ ret += " ,avx2(8way)" ;
521
+ }
522
+ }
510
523
}
511
524
#endif
512
525
#else
0 commit comments