aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils/cpuid
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-05-27 11:38:30 -0400
committerJack Lloyd <[email protected]>2018-05-27 12:01:55 -0400
commit8df48e74987fb2ab3c97adb2b48c2cafc0ea381b (patch)
tree624df6b225783f611e893a16ffc1fe23f730fd2d /src/lib/utils/cpuid
parentf256e603ab93e2587fe0e38bcf06c437fcd41abf (diff)
Add BMI2-specific SHA-256
Currently just a copy of the baseline compression function, but compiled with BMI2 flags. On Skylake improves performance by about 40%.
Diffstat (limited to 'src/lib/utils/cpuid')
-rw-r--r--src/lib/utils/cpuid/cpuid.cpp5
-rw-r--r--src/lib/utils/cpuid/cpuid.h7
-rw-r--r--src/lib/utils/cpuid/cpuid_x86.cpp15
3 files changed, 25 insertions, 2 deletions
diff --git a/src/lib/utils/cpuid/cpuid.cpp b/src/lib/utils/cpuid/cpuid.cpp
index 9dc56d59c..d0489cb67 100644
--- a/src/lib/utils/cpuid/cpuid.cpp
+++ b/src/lib/utils/cpuid/cpuid.cpp
@@ -46,6 +46,7 @@ std::string CPUID::to_string()
CPUID_PRINT(avx512f);
CPUID_PRINT(rdtsc);
+ CPUID_PRINT(bmi1);
CPUID_PRINT(bmi2);
CPUID_PRINT(adx);
@@ -145,6 +146,10 @@ CPUID::bit_from_string(const std::string& tok)
return {Botan::CPUID::CPUID_AVX2_BIT};
if(tok == "sha")
return {Botan::CPUID::CPUID_SHA_BIT};
+ if(tok == "bmi2")
+ return {Botan::CPUID::CPUID_BMI2_BIT};
+ if(tok == "adx")
+ return {Botan::CPUID::CPUID_ADX_BIT};
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
if(tok == "altivec" || tok == "simd")
diff --git a/src/lib/utils/cpuid/cpuid.h b/src/lib/utils/cpuid/cpuid.h
index 4c0f1668b..633824a6c 100644
--- a/src/lib/utils/cpuid/cpuid.h
+++ b/src/lib/utils/cpuid/cpuid.h
@@ -98,6 +98,7 @@ class BOTAN_PUBLIC_API(2,1) CPUID final
CPUID_RDTSC_BIT = (1ULL << 10),
CPUID_BMI2_BIT = (1ULL << 11),
CPUID_ADX_BIT = (1ULL << 12),
+ CPUID_BMI1_BIT = (1ULL << 13),
// Crypto-specific ISAs
CPUID_AESNI_BIT = (1ULL << 16),
@@ -215,6 +216,12 @@ class BOTAN_PUBLIC_API(2,1) CPUID final
{ return has_cpuid_bit(CPUID_AVX512F_BIT); }
/**
+ * Check if the processor supports BMI1
+ */
+ static bool has_bmi1()
+ { return has_cpuid_bit(CPUID_BMI1_BIT); }
+
+ /**
* Check if the processor supports BMI2
*/
static bool has_bmi2()
diff --git a/src/lib/utils/cpuid/cpuid_x86.cpp b/src/lib/utils/cpuid/cpuid_x86.cpp
index be6c75a55..5387a801e 100644
--- a/src/lib/utils/cpuid/cpuid_x86.cpp
+++ b/src/lib/utils/cpuid/cpuid_x86.cpp
@@ -121,6 +121,7 @@ uint64_t CPUID::detect_cpu_features(size_t* cache_line_size)
X86_CPUID_SUBLEVEL(7, 0, cpuid);
enum x86_CPUID_7_bits : uint64_t {
+ BMI1 = (1ULL << 3),
AVX2 = (1ULL << 5),
BMI2 = (1ULL << 8),
AVX512F = (1ULL << 16),
@@ -132,8 +133,18 @@ uint64_t CPUID::detect_cpu_features(size_t* cache_line_size)
if(flags7 & x86_CPUID_7_bits::AVX2)
features_detected |= CPUID::CPUID_AVX2_BIT;
- if(flags7 & x86_CPUID_7_bits::BMI2)
- features_detected |= CPUID::CPUID_BMI2_BIT;
+ if(flags7 & x86_CPUID_7_bits::BMI1)
+ {
+ features_detected |= CPUID::CPUID_BMI1_BIT;
+ /*
+ We only set the BMI2 bit if BMI1 is also supported, so BMI2
+ code can safely use both extensions. No known processor
+ implements BMI2 but not BMI1.
+ */
+ if(flags7 & x86_CPUID_7_bits::BMI2)
+ features_detected |= CPUID::CPUID_BMI2_BIT;
+ }
+
if(flags7 & x86_CPUID_7_bits::AVX512F)
features_detected |= CPUID::CPUID_AVX512F_BIT;
if(flags7 & x86_CPUID_7_bits::RDSEED)