diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2018-06-24 10:44:02 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2018-06-24 10:51:07 -0700 |
commit | 268400d3188200c9e3dcd3482c4853354388a721 (patch) | |
tree | 15a0a7cd1a433573aaf130fc7d8e53827a176da1 | |
parent | b1dc39df6ec878d06fc7217a3d7bf07397edf3ea (diff) |
[Refactor] CPU feature detection logic for SHA256
-rw-r--r-- | src/crypto/sha256.cpp | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index e62ddc125e..e788390d4b 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -552,32 +552,50 @@ std::string SHA256AutoDetect() { std::string ret = "standard"; #if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__)) - (void)AVXEnabled; // Silence unused warning (in case ENABLE_AVX2 is not defined) + bool have_sse4 = false; + bool have_xsave = false; + bool have_avx = false; + bool have_avx2 = false; + bool enabled_avx = false; + + (void)AVXEnabled; + (void)have_sse4; + (void)have_avx; + (void)have_xsave; + (void)have_avx2; + (void)enabled_avx; + uint32_t eax, ebx, ecx, edx; cpuid(1, 0, eax, ebx, ecx, edx); - if ((ecx >> 19) & 1) { + have_sse4 = (ecx >> 19) & 1; + have_xsave = (ecx >> 27) & 1; + have_avx = (ecx >> 28) & 1; + if (have_xsave && have_avx) { + enabled_avx = AVXEnabled(); + } + if (have_sse4) { + cpuid(7, 0, eax, ebx, ecx, edx); + have_avx2 = (ebx >> 5) & 1; + } + + if (have_sse4) { #if defined(__x86_64__) || defined(__amd64__) Transform = sha256_sse4::Transform; TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>; + ret = "sse4(1way)"; #endif #if defined(ENABLE_SSE41) && !defined(BUILD_BITCOIN_INTERNAL) TransformD64_4way = sha256d64_sse41::Transform_4way; - ret = "sse4(1way+4way)"; -#if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL) - if (((ecx >> 27) & 1) && ((ecx >> 28) & 1)) { // XSAVE and AVX - cpuid(7, 0, eax, ebx, ecx, edx); - if ((ebx >> 5) & 1) { // AVX2 flag - if (AVXEnabled()) { // OS has enabled AVX registers - TransformD64_8way = sha256d64_avx2::Transform_8way; - ret += ",avx2(8way)"; - } - } - } -#endif -#else - ret = "sse4"; + ret += ",sse41(4way)"; #endif } + +#if defined(ENABLE_AVX2) && !defined(BUILD_BITCOIN_INTERNAL) + if (have_avx2 && have_avx && enabled_avx) { + TransformD64_8way = sha256d64_avx2::Transform_8way; + ret += ",avx2(8way)"; + } +#endif #endif assert(SelfTest()); |