Skip to content

Commit 32d153f

Browse files
committed
For AVX2 code, also check for AVX, XSAVE, and OS support
1 parent 4a7e64f commit 32d153f

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

src/crypto/sha256.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,14 @@ void inline cpuid(uint32_t leaf, uint32_t subleaf, uint32_t& a, uint32_t& b, uin
484484
{
485485
__asm__ ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(leaf), "2"(subleaf));
486486
}
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+
}
487495
#endif
488496
} // namespace
489497

@@ -492,6 +500,7 @@ std::string SHA256AutoDetect()
492500
{
493501
std::string ret = "standard";
494502
#if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
503+
(void)AVXEnabled; // Silence unused warning (in case ENABLE_AVX2 is not defined)
495504
uint32_t eax, ebx, ecx, edx;
496505
cpuid(1, 0, eax, ebx, ecx, edx);
497506
if ((ecx >> 19) & 1) {
@@ -503,10 +512,14 @@ std::string SHA256AutoDetect()
503512
TransformD64_4way = sha256d64_sse41::Transform_4way;
504513
ret = "sse4(1way+4way)";
505514
#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+
}
510523
}
511524
#endif
512525
#else

0 commit comments

Comments
 (0)