Changeset View
Changeset View
Standalone View
Standalone View
src/crypto/sha256.cpp
// Copyright (c) 2014 The Bitcoin Core developers | // Copyright (c) 2014 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <crypto/common.h> | |||||
#include <crypto/sha256.h> | #include <crypto/sha256.h> | ||||
#include <compat/cpuid.h> | |||||
#include <crypto/common.h> | |||||
#include <atomic> | #include <atomic> | ||||
#include <cassert> | #include <cassert> | ||||
#include <cstring> | #include <cstring> | ||||
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) | #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) | ||||
#if defined(USE_ASM) | #if defined(USE_ASM) | ||||
#include <cpuid.h> | |||||
namespace sha256_sse4 { | namespace sha256_sse4 { | ||||
void Transform(uint32_t *s, const uint8_t *chunk, size_t blocks); | void Transform(uint32_t *s, const uint8_t *chunk, size_t blocks); | ||||
} | } | ||||
#endif | #endif | ||||
#endif | #endif | ||||
namespace sha256d64_sse41 { | namespace sha256d64_sse41 { | ||||
void Transform_4way(uint8_t *out, const uint8_t *in); | void Transform_4way(uint8_t *out, const uint8_t *in); | ||||
▲ Show 20 Lines • Show All 706 Lines • ▼ Show 20 Lines | if (TransformD64_8way) { | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
#if defined(USE_ASM) && \ | #if defined(USE_ASM) && \ | ||||
(defined(__x86_64__) || defined(__amd64__) || defined(__i386__)) | (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. */ | /** Check whether the OS has enabled AVX registers. */ | ||||
bool AVXEnabled() { | bool AVXEnabled() { | ||||
uint32_t a, d; | uint32_t a, d; | ||||
__asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0)); | __asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0)); | ||||
return (a & 6) == 6; | return (a & 6) == 6; | ||||
} | } | ||||
#endif | #endif | ||||
} // namespace | } // namespace | ||||
std::string SHA256AutoDetect() { | std::string SHA256AutoDetect() { | ||||
std::string ret = "standard"; | std::string ret = "standard"; | ||||
#if defined(USE_ASM) && \ | #if defined(USE_ASM) && defined(HAVE_GETCPUID) | ||||
(defined(__x86_64__) || defined(__amd64__) || defined(__i386__)) | |||||
bool have_sse4 = false; | bool have_sse4 = false; | ||||
bool have_xsave = false; | bool have_xsave = false; | ||||
bool have_avx = false; | bool have_avx = false; | ||||
bool have_avx2 = false; | bool have_avx2 = false; | ||||
bool have_shani = false; | bool have_shani = false; | ||||
bool enabled_avx = false; | bool enabled_avx = false; | ||||
(void)AVXEnabled; | (void)AVXEnabled; | ||||
(void)have_sse4; | (void)have_sse4; | ||||
(void)have_avx; | (void)have_avx; | ||||
(void)have_xsave; | (void)have_xsave; | ||||
(void)have_avx2; | (void)have_avx2; | ||||
(void)have_shani; | (void)have_shani; | ||||
(void)enabled_avx; | (void)enabled_avx; | ||||
uint32_t eax, ebx, ecx, edx; | 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_sse4 = (ecx >> 19) & 1; | ||||
have_xsave = (ecx >> 27) & 1; | have_xsave = (ecx >> 27) & 1; | ||||
have_avx = (ecx >> 28) & 1; | have_avx = (ecx >> 28) & 1; | ||||
if (have_xsave && have_avx) { | if (have_xsave && have_avx) { | ||||
enabled_avx = AVXEnabled(); | enabled_avx = AVXEnabled(); | ||||
} | } | ||||
if (have_sse4) { | if (have_sse4) { | ||||
cpuid(7, 0, eax, ebx, ecx, edx); | GetCPUID(7, 0, eax, ebx, ecx, edx); | ||||
have_avx2 = (ebx >> 5) & 1; | have_avx2 = (ebx >> 5) & 1; | ||||
have_shani = (ebx >> 29) & 1; | have_shani = (ebx >> 29) & 1; | ||||
} | } | ||||
#if defined(ENABLE_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) | #if defined(ENABLE_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) | ||||
if (have_shani) { | if (have_shani) { | ||||
Transform = sha256_shani::Transform; | Transform = sha256_shani::Transform; | ||||
TransformD64 = TransformD64Wrapper<sha256_shani::Transform>; | TransformD64 = TransformD64Wrapper<sha256_shani::Transform>; | ||||
▲ Show 20 Lines • Show All 116 Lines • Show Last 20 Lines |