Commit a2b615d5 authored by Lion Yang's avatar Lion Yang Committed by Ian Lance Taylor

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/34850Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent f5608c20
...@@ -225,7 +225,7 @@ end: ...@@ -225,7 +225,7 @@ end:
RET 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" // "SHA-1 implementation with Intel(R) AVX2 instruction set extensions"
// From http://software.intel.com/en-us/articles // From http://software.intel.com/en-us/articles
// (look for improving-the-performance-of-the-secure-hash-algorithm-1) // (look for improving-the-performance-of-the-secure-hash-algorithm-1)
...@@ -1459,15 +1459,19 @@ TEXT ·blockAVX2(SB),$1408-32 ...@@ -1459,15 +1459,19 @@ TEXT ·blockAVX2(SB),$1408-32
// func checkAVX2() bool // func checkAVX2() bool
// returns whether AVX2 is supported // returns whether AVX2, BMI1 and BMI2 are supported
TEXT ·checkAVX2(SB),NOSPLIT,$0 TEXT ·checkAVX2(SB),NOSPLIT,$0
CMPB runtime·support_avx2(SB), $1 CMPB runtime·support_avx2(SB), $0
JE has JE noavx2
MOVB $0, ret+0(FP) CMPB runtime·support_bmi1(SB), $0 // check for ANDNL instruction
RET JE noavx2
has: CMPB runtime·support_bmi2(SB), $0 // check for RORXL instruction
JE noavx2
MOVB $1, ret+0(FP) MOVB $1, ret+0(FP)
RET RET
noavx2:
MOVB $0, ret+0(FP)
RET
DATA K_XMM_AR<>+0x00(SB)/4,$0x5a827999 DATA K_XMM_AR<>+0x00(SB)/4,$0x5a827999
......
...@@ -559,8 +559,11 @@ ...@@ -559,8 +559,11 @@
ADDL y3, h // h = t1 + S0 + MAJ // -- ADDL y3, h // h = t1 + S0 + MAJ // --
TEXT ·block(SB), 0, $536-32 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 JE avx2
noavx2bmi2:
MOVQ p_base+8(FP), SI MOVQ p_base+8(FP), SI
MOVQ p_len+16(FP), DX MOVQ p_len+16(FP), DX
......
...@@ -75,11 +75,24 @@ no7: ...@@ -75,11 +75,24 @@ no7:
TESTL $(1<<5), runtime·cpuid_ebx7(SB) // check for AVX2 bit TESTL $(1<<5), runtime·cpuid_ebx7(SB) // check for AVX2 bit
JEQ noavx2 JEQ noavx2
MOVB $1, runtime·support_avx2(SB) MOVB $1, runtime·support_avx2(SB)
JMP nocpuinfo JMP testbmi1
noavx: noavx:
MOVB $0, runtime·support_avx(SB) MOVB $0, runtime·support_avx(SB)
noavx2: noavx2:
MOVB $0, runtime·support_avx2(SB) 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: nocpuinfo:
// if there is an _cgo_init, call it. // if there is an _cgo_init, call it.
......
...@@ -745,6 +745,8 @@ var ( ...@@ -745,6 +745,8 @@ var (
lfenceBeforeRdtsc bool lfenceBeforeRdtsc bool
support_avx bool support_avx bool
support_avx2 bool support_avx2 bool
support_bmi1 bool
support_bmi2 bool
goarm uint8 // set by cmd/link on arm systems goarm uint8 // set by cmd/link on arm systems
framepointer_enabled bool // set by cmd/link framepointer_enabled bool // set by cmd/link
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment