summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLion Yang <lion@aosc.xyz>2017-01-05 05:13:53 +0800
committerIan Lance Taylor <iant@golang.org>2017-01-05 15:37:37 +0000
commita2b615d5270f0bc2ee1dfcdd7849bdd05ee76a14 (patch)
tree2446db40f137cdf160d3c16c8299ed5dae6381d7
parentf5608c20f7b88c20fa2cd70090d9917df63f5c8e (diff)
downloadgo-git-a2b615d5270f0bc2ee1dfcdd7849bdd05ee76a14.tar.gz
crypto: detect BMI usability on AMD64 for sha1 and sha256
The existing implementations on AMD64 only detects AVX2 usability, when they also contains BMI (bit-manipulation instructions). These instructions crash the running program as 'unknown instructions' on the architecture, e.g. i3-4000M, which supports AVX2 but not support BMI. This change added the detections for BMI1 and BMI2 to AMD64 runtime with two flags as the result, `support_bmi1` and `support_bmi2`, in runtime/runtime2.go. It also completed the condition to run AVX2 version in packages crypto/sha1 and crypto/sha256. Fixes #18512 Change-Id: I917bf0de365237740999de3e049d2e8f2a4385ad Reviewed-on: https://go-review.googlesource.com/34850 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/crypto/sha1/sha1block_amd64.s18
-rw-r--r--src/crypto/sha256/sha256block_amd64.s5
-rw-r--r--src/runtime/asm_amd64.s15
-rw-r--r--src/runtime/runtime2.go2
4 files changed, 31 insertions, 9 deletions
diff --git a/src/crypto/sha1/sha1block_amd64.s b/src/crypto/sha1/sha1block_amd64.s
index 0cdb43b422..77c8ec3906 100644
--- a/src/crypto/sha1/sha1block_amd64.s
+++ b/src/crypto/sha1/sha1block_amd64.s
@@ -225,7 +225,7 @@ end:
RET
-// This is the implementation using AVX2. It is based on:
+// This is the implementation using AVX2, BMI1 and BMI2. It is based on:
// "SHA-1 implementation with Intel(R) AVX2 instruction set extensions"
// From http://software.intel.com/en-us/articles
// (look for improving-the-performance-of-the-secure-hash-algorithm-1)
@@ -1459,15 +1459,19 @@ TEXT ·blockAVX2(SB),$1408-32
// func checkAVX2() bool
-// returns whether AVX2 is supported
+// returns whether AVX2, BMI1 and BMI2 are supported
TEXT ·checkAVX2(SB),NOSPLIT,$0
- CMPB runtime·support_avx2(SB), $1
- JE has
- MOVB $0, ret+0(FP)
- RET
-has:
+ CMPB runtime·support_avx2(SB), $0
+ JE noavx2
+ CMPB runtime·support_bmi1(SB), $0 // check for ANDNL instruction
+ JE noavx2
+ CMPB runtime·support_bmi2(SB), $0 // check for RORXL instruction
+ JE noavx2
MOVB $1, ret+0(FP)
RET
+noavx2:
+ MOVB $0, ret+0(FP)
+ RET
DATA K_XMM_AR<>+0x00(SB)/4,$0x5a827999
diff --git a/src/crypto/sha256/sha256block_amd64.s b/src/crypto/sha256/sha256block_amd64.s
index edf7ad1a3b..e9705b94b1 100644
--- a/src/crypto/sha256/sha256block_amd64.s
+++ b/src/crypto/sha256/sha256block_amd64.s
@@ -559,8 +559,11 @@
ADDL y3, h // h = t1 + S0 + MAJ // --
TEXT ·block(SB), 0, $536-32
- CMPB runtime·support_avx2(SB), $1
+ CMPB runtime·support_avx2(SB), $0
+ JE noavx2bmi2
+ CMPB runtime·support_bmi2(SB), $1 // check for RORXL instruction
JE avx2
+noavx2bmi2:
MOVQ p_base+8(FP), SI
MOVQ p_len+16(FP), DX
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index 0070e9d203..cb428d6de3 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -75,11 +75,24 @@ no7:
TESTL $(1<<5), runtime·cpuid_ebx7(SB) // check for AVX2 bit
JEQ noavx2
MOVB $1, runtime·support_avx2(SB)
- JMP nocpuinfo
+ JMP testbmi1
noavx:
MOVB $0, runtime·support_avx(SB)
noavx2:
MOVB $0, runtime·support_avx2(SB)
+testbmi1:
+ // Detect BMI1 and BMI2 extensions as per
+ // 5.1.16.1 Detection of VEX-encoded GPR Instructions,
+ // LZCNT and TZCNT, PREFETCHW chapter of [1]
+ MOVB $0, runtime·support_bmi1(SB)
+ TESTL $(1<<3), runtime·cpuid_ebx7(SB) // check for BMI1 bit
+ JEQ testbmi2
+ MOVB $1, runtime·support_bmi1(SB)
+testbmi2:
+ MOVB $0, runtime·support_bmi2(SB)
+ TESTL $(1<<8), runtime·cpuid_ebx7(SB) // check for BMI2 bit
+ JEQ nocpuinfo
+ MOVB $1, runtime·support_bmi2(SB)
nocpuinfo:
// if there is an _cgo_init, call it.
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index acc9426142..1ceab0ad8c 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -745,6 +745,8 @@ var (
lfenceBeforeRdtsc bool
support_avx bool
support_avx2 bool
+ support_bmi1 bool
+ support_bmi2 bool
goarm uint8 // set by cmd/link on arm systems
framepointer_enabled bool // set by cmd/link