]> Cypherpunks repositories - gostls13.git/commitdiff
crypto: detect BMI usability on AMD64 for sha1 and sha256
authorLion Yang <lion@aosc.xyz>
Wed, 4 Jan 2017 21:13:53 +0000 (05:13 +0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 5 Jan 2017 15:37:37 +0000 (15:37 +0000)
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>

src/crypto/sha1/sha1block_amd64.s
src/crypto/sha256/sha256block_amd64.s
src/runtime/asm_amd64.s
src/runtime/runtime2.go

index 0cdb43b422fdcccaaf3b1e03fe86723990fbb9fa..77c8ec39060e499db66d1b7853c69aaa4d72f4ee 100644 (file)
@@ -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
index edf7ad1a3bc6e3addc702e1e37d121c2505e2fea..e9705b94b12abf0bf8c62a430bfc6a3a0bacd047 100644 (file)
        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
index 0070e9d203845c244e899453d10d9b33fad54ae6..cb428d6de3cbf745d33cfb5b1dfd3cbca9eb6542 100644 (file)
@@ -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.
index acc9426142742b48eb7fb5fb764368373b870122..1ceab0ad8c4a0b43d28d63cdd2921ae7da0e1454 100644 (file)
@@ -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