Skip to content

Commit 5eca4e8

Browse files
committed
Merge #13471: For AVX2 code, also check for AVX, XSAVE, and OS support
32d153f For AVX2 code, also check for AVX, XSAVE, and OS support (Pieter Wuille) Pull request description: Fixes #12903. Tree-SHA512: 01e71efb5d3a43c49a145a5b1dc4fe7d0a491e1e78479e7df830a2aaac57c3dcfc316e28984c695206c76f93b68e4350fc037ca36756ca579b7070e39c835da2
2 parents 3a45493 + 32d153f commit 5eca4e8

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
@@ -536,6 +536,14 @@ void inline cpuid(uint32_t leaf, uint32_t subleaf, uint32_t& a, uint32_t& b, uin
536536
{
537537
__asm__ ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(leaf), "2"(subleaf));
538538
}
539+
540+
/** Check whether the OS has enabled AVX registers. */
541+
bool AVXEnabled()
542+
{
543+
uint32_t a, d;
544+
__asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0));
545+
return (a & 6) == 6;
546+
}
539547
#endif
540548
} // namespace
541549

@@ -544,6 +552,7 @@ std::string SHA256AutoDetect()
544552
{
545553
std::string ret = "standard";
546554
#if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
555+
(void)AVXEnabled; // Silence unused warning (in case ENABLE_AVX2 is not defined)
547556
uint32_t eax, ebx, ecx, edx;
548557
cpuid(1, 0, eax, ebx, ecx, edx);
549558
if ((ecx >> 19) & 1) {
@@ -555,10 +564,14 @@ std::string SHA256AutoDetect()
555564
TransformD64_4way = sha256d64_sse41::Transform_4way;
556565
ret = "sse4(1way+4way)";
557566
#if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL)
558-
cpuid(7, 0, eax, ebx, ecx, edx);
559-
if ((ebx >> 5) & 1) {
560-
TransformD64_8way = sha256d64_avx2::Transform_8way;
561-
ret += ",avx2(8way)";
567+
if (((ecx >> 27) & 1) && ((ecx >> 28) & 1)) { // XSAVE and AVX
568+
cpuid(7, 0, eax, ebx, ecx, edx);
569+
if ((ebx >> 5) & 1) { // AVX2 flag
570+
if (AVXEnabled()) { // OS has enabled AVX registers
571+
TransformD64_8way = sha256d64_avx2::Transform_8way;
572+
ret += ",avx2(8way)";
573+
}
574+
}
562575
}
563576
#endif
564577
#else

0 commit comments

Comments
 (0)