diff --git a/src/Makefile.am b/src/Makefile.am --- a/src/Makefile.am +++ b/src/Makefile.am @@ -138,6 +138,7 @@ compat.h \ compat/assumptions.h \ compat/byteswap.h \ + compat/cpuid.h \ compat/endian.h \ compat/sanity.h \ compat/setenv.h \ diff --git a/src/compat/cpuid.h b/src/compat/cpuid.h new file mode 100644 --- /dev/null +++ b/src/compat/cpuid.h @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2019 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_COMPAT_CPUID_H +#define BITCOIN_COMPAT_CPUID_H + +#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) +#define HAVE_GETCPUID + +#include + +// We can't use cpuid.h's __get_cpuid as it does not support subleafs. +void static inline GetCPUID(uint32_t leaf, uint32_t subleaf, uint32_t &a, + uint32_t &b, uint32_t &c, uint32_t &d) { +#ifdef __GNUC__ + __cpuid_count(leaf, subleaf, a, b, c, d); +#else + __asm__("cpuid" + : "=a"(a), "=b"(b), "=c"(c), "=d"(d) + : "0"(leaf), "2"(subleaf)); +#endif +} + +#endif // defined(__x86_64__) || defined(__amd64__) || defined(__i386__) +#endif // BITCOIN_COMPAT_CPUID_H diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -2,16 +2,17 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include +#include +#include + #include #include #include #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) #if defined(USE_ASM) -#include namespace sha256_sse4 { void Transform(uint32_t *s, const uint8_t *chunk, size_t blocks); } @@ -734,18 +735,6 @@ #if defined(USE_ASM) && \ (defined(__x86_64__) || defined(__amd64__) || defined(__i386__)) -// We can't use cpuid.h's __get_cpuid as it does not support subleafs. -inline void cpuid(uint32_t leaf, uint32_t subleaf, uint32_t &a, uint32_t &b, - uint32_t &c, uint32_t &d) { -#ifdef __GNUC__ - __cpuid_count(leaf, subleaf, a, b, c, d); -#else - __asm__("cpuid" - : "=a"(a), "=b"(b), "=c"(c), "=d"(d) - : "0"(leaf), "2"(subleaf)); -#endif -} - /** Check whether the OS has enabled AVX registers. */ bool AVXEnabled() { uint32_t a, d; @@ -757,8 +746,7 @@ std::string SHA256AutoDetect() { std::string ret = "standard"; -#if defined(USE_ASM) && \ - (defined(__x86_64__) || defined(__amd64__) || defined(__i386__)) +#if defined(USE_ASM) && defined(HAVE_GETCPUID) bool have_sse4 = false; bool have_xsave = false; bool have_avx = false; @@ -775,7 +763,7 @@ (void)enabled_avx; uint32_t eax, ebx, ecx, edx; - cpuid(1, 0, eax, ebx, ecx, edx); + GetCPUID(1, 0, eax, ebx, ecx, edx); have_sse4 = (ecx >> 19) & 1; have_xsave = (ecx >> 27) & 1; have_avx = (ecx >> 28) & 1; @@ -783,7 +771,7 @@ enabled_avx = AVXEnabled(); } if (have_sse4) { - cpuid(7, 0, eax, ebx, ecx, edx); + GetCPUID(7, 0, eax, ebx, ecx, edx); have_avx2 = (ebx >> 5) & 1; have_shani = (ebx >> 29) & 1; } diff --git a/src/random.cpp b/src/random.cpp --- a/src/random.cpp +++ b/src/random.cpp @@ -9,6 +9,7 @@ #include // for Windows API #include #endif +#include #include #include // for LogPrintf() #include @@ -48,10 +49,6 @@ #include // for ARRAYLEN #endif -#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) -#include -#endif - [[noreturn]] static void RandFailure() { LogPrintf("Failed to read randomness, aborting\n"); std::abort(); @@ -79,7 +76,7 @@ #endif } -#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) +#ifdef HAVE_GETCPUID static bool g_rdrand_supported = false; static bool g_rdseed_supported = false; static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000; @@ -92,17 +89,6 @@ static_assert(CPUID_F7_EBX_RDSEED == bit_RDSEED, "Unexpected value for bit_RDSEED"); #endif -static void inline GetCPUID(uint32_t leaf, uint32_t subleaf, uint32_t &a, - uint32_t &b, uint32_t &c, uint32_t &d) { - // We can't use __get_cpuid as it doesn't support subleafs. -#ifdef __GNUC__ - __cpuid_count(leaf, subleaf, a, b, c, d); -#else - __asm__("cpuid" - : "=a"(a), "=b"(b), "=c"(c), "=d"(d) - : "0"(leaf), "2"(subleaf)); -#endif -} static void InitHardwareRand() { uint32_t eax, ebx, ecx, edx;