Skip to content

Commit ae8bce0

Browse files
Andreas Auernhammerbradfitz
Andreas Auernhammer
authored andcommitted
crypto/{blake2b,blake2s,argon2,chacha20poly1305}: replace CPU feature detection
This change removes package specific CPU-feature detection code and replaces it with x/sys/cpu. Fixes golang/go#24843 Change-Id: I150dd7b3aeb8eef428c91f9b1df741ceb8a87a24 Reviewed-on: https://go-review.googlesource.com/110355 Run-TryBot: Ilya Tocar <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent db7d123 commit ae8bce0

11 files changed

+41
-182
lines changed

argon2/blamka_amd64.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66

77
package argon2
88

9+
import "golang.org/x/sys/cpu"
10+
911
func init() {
10-
useSSE4 = supportsSSE4()
12+
useSSE4 = cpu.X86.HasSSE41
1113
}
1214

13-
//go:noescape
14-
func supportsSSE4() bool
15-
1615
//go:noescape
1716
func mixBlocksSSE2(out, a, b, c *block)
1817

argon2/blamka_amd64.s

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,3 @@ loop:
241241
SUBQ $2, BP
242242
JA loop
243243
RET
244-
245-
// func supportsSSE4() bool
246-
TEXT ·supportsSSE4(SB), 4, $0-1
247-
MOVL $1, AX
248-
CPUID
249-
SHRL $19, CX // Bit 19 indicates SSE4 support
250-
ANDL $1, CX // CX != 0 if support SSE4
251-
MOVB CX, ret+0(FP)
252-
RET

blake2b/blake2bAVX2_amd64.go

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,14 @@
66

77
package blake2b
88

9+
import "golang.org/x/sys/cpu"
10+
911
func init() {
10-
useAVX2 = supportsAVX2()
11-
useAVX = supportsAVX()
12-
useSSE4 = supportsSSE4()
12+
useAVX2 = cpu.X86.HasAVX2
13+
useAVX = cpu.X86.HasAVX
14+
useSSE4 = cpu.X86.HasSSE41
1315
}
1416

15-
//go:noescape
16-
func supportsSSE4() bool
17-
18-
//go:noescape
19-
func supportsAVX() bool
20-
21-
//go:noescape
22-
func supportsAVX2() bool
23-
2417
//go:noescape
2518
func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
2619

@@ -31,13 +24,14 @@ func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
3124
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
3225

3326
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
34-
if useAVX2 {
27+
switch {
28+
case useAVX2:
3529
hashBlocksAVX2(h, c, flag, blocks)
36-
} else if useAVX {
30+
case useAVX:
3731
hashBlocksAVX(h, c, flag, blocks)
38-
} else if useSSE4 {
32+
case useSSE4:
3933
hashBlocksSSE4(h, c, flag, blocks)
40-
} else {
34+
default:
4135
hashBlocksGeneric(h, c, flag, blocks)
4236
}
4337
}

blake2b/blake2bAVX2_amd64.s

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -748,15 +748,3 @@ noinc:
748748

749749
MOVQ BP, SP
750750
RET
751-
752-
// func supportsAVX2() bool
753-
TEXT ·supportsAVX2(SB), 4, $0-1
754-
MOVQ runtime·support_avx2(SB), AX
755-
MOVB AX, ret+0(FP)
756-
RET
757-
758-
// func supportsAVX() bool
759-
TEXT ·supportsAVX(SB), 4, $0-1
760-
MOVQ runtime·support_avx(SB), AX
761-
MOVB AX, ret+0(FP)
762-
RET

blake2b/blake2b_amd64.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66

77
package blake2b
88

9+
import "golang.org/x/sys/cpu"
10+
911
func init() {
10-
useSSE4 = supportsSSE4()
12+
useSSE4 = cpu.X86.HasSSE41
1113
}
1214

13-
//go:noescape
14-
func supportsSSE4() bool
15-
1615
//go:noescape
1716
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
1817

blake2b/blake2b_amd64.s

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,3 @@ noinc:
279279

280280
MOVQ BP, SP
281281
RET
282-
283-
// func supportsSSE4() bool
284-
TEXT ·supportsSSE4(SB), 4, $0-1
285-
MOVL $1, AX
286-
CPUID
287-
SHRL $19, CX // Bit 19 indicates SSE4 support
288-
ANDL $1, CX // CX != 0 if support SSE4
289-
MOVB CX, ret+0(FP)
290-
RET

blake2s/blake2s_386.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,27 @@
66

77
package blake2s
88

9+
import "golang.org/x/sys/cpu"
10+
911
var (
1012
useSSE4 = false
11-
useSSSE3 = supportSSSE3()
12-
useSSE2 = supportSSE2()
13+
useSSSE3 = cpu.X86.HasSSSE3
14+
useSSE2 = cpu.X86.HasSSE2
1315
)
1416

15-
//go:noescape
16-
func supportSSE2() bool
17-
18-
//go:noescape
19-
func supportSSSE3() bool
20-
2117
//go:noescape
2218
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
2319

2420
//go:noescape
2521
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
2622

2723
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
28-
if useSSSE3 {
24+
switch {
25+
case useSSSE3:
2926
hashBlocksSSSE3(h, c, flag, blocks)
30-
} else if useSSE2 {
27+
case useSSE2:
3128
hashBlocksSSE2(h, c, flag, blocks)
32-
} else {
29+
default:
3330
hashBlocksGeneric(h, c, flag, blocks)
3431
}
3532
}

blake2s/blake2s_386.s

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -433,28 +433,3 @@ loop:
433433

434434
MOVL BP, SP
435435
RET
436-
437-
// func supportSSSE3() bool
438-
TEXT ·supportSSSE3(SB), 4, $0-1
439-
MOVL $1, AX
440-
CPUID
441-
MOVL CX, BX
442-
ANDL $0x1, BX // supports SSE3
443-
JZ FALSE
444-
ANDL $0x200, CX // supports SSSE3
445-
JZ FALSE
446-
MOVB $1, ret+0(FP)
447-
RET
448-
449-
FALSE:
450-
MOVB $0, ret+0(FP)
451-
RET
452-
453-
// func supportSSE2() bool
454-
TEXT ·supportSSE2(SB), 4, $0-1
455-
MOVL $1, AX
456-
CPUID
457-
SHRL $26, DX
458-
ANDL $1, DX // DX != 0 if support SSE2
459-
MOVB DX, ret+0(FP)
460-
RET

blake2s/blake2s_amd64.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,14 @@
66

77
package blake2s
88

9+
import "golang.org/x/sys/cpu"
10+
911
var (
10-
useSSE4 = supportSSE4()
11-
useSSSE3 = supportSSSE3()
12-
useSSE2 = true // Always available on amd64
12+
useSSE4 = cpu.X86.HasSSE41
13+
useSSSE3 = cpu.X86.HasSSSE3
14+
useSSE2 = cpu.X86.HasSSE2
1315
)
1416

15-
//go:noescape
16-
func supportSSSE3() bool
17-
18-
//go:noescape
19-
func supportSSE4() bool
20-
2117
//go:noescape
2218
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
2319

@@ -28,13 +24,14 @@ func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
2824
func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
2925

3026
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
31-
if useSSE4 {
27+
switch {
28+
case useSSE4:
3229
hashBlocksSSE4(h, c, flag, blocks)
33-
} else if useSSSE3 {
30+
case useSSSE3:
3431
hashBlocksSSSE3(h, c, flag, blocks)
35-
} else if useSSE2 {
32+
case useSSE2:
3633
hashBlocksSSE2(h, c, flag, blocks)
37-
} else {
34+
default:
3835
hashBlocksGeneric(h, c, flag, blocks)
3936
}
4037
}

blake2s/blake2s_amd64.s

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -436,28 +436,3 @@ TEXT ·hashBlocksSSSE3(SB), 0, $672-48 // frame = 656 + 16 byte alignment
436436
TEXT ·hashBlocksSSE4(SB), 0, $32-48 // frame = 16 + 16 byte alignment
437437
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE4)
438438
RET
439-
440-
// func supportSSE4() bool
441-
TEXT ·supportSSE4(SB), 4, $0-1
442-
MOVL $1, AX
443-
CPUID
444-
SHRL $19, CX // Bit 19 indicates SSE4.1.
445-
ANDL $1, CX
446-
MOVB CX, ret+0(FP)
447-
RET
448-
449-
// func supportSSSE3() bool
450-
TEXT ·supportSSSE3(SB), 4, $0-1
451-
MOVL $1, AX
452-
CPUID
453-
MOVL CX, BX
454-
ANDL $0x1, BX // Bit zero indicates SSE3 support.
455-
JZ FALSE
456-
ANDL $0x200, CX // Bit nine indicates SSSE3 support.
457-
JZ FALSE
458-
MOVB $1, ret+0(FP)
459-
RET
460-
461-
FALSE:
462-
MOVB $0, ret+0(FP)
463-
RET

chacha20poly1305/chacha20poly1305_amd64.go

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,70 +6,23 @@
66

77
package chacha20poly1305
88

9-
import "encoding/binary"
9+
import (
10+
"encoding/binary"
11+
12+
"golang.org/x/sys/cpu"
13+
)
1014

1115
//go:noescape
1216
func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
1317

1418
//go:noescape
1519
func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
1620

17-
// cpuid is implemented in chacha20poly1305_amd64.s.
18-
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
19-
20-
// xgetbv with ecx = 0 is implemented in chacha20poly1305_amd64.s.
21-
func xgetbv() (eax, edx uint32)
22-
2321
var (
24-
useASM bool
25-
useAVX2 bool
22+
useASM = cpu.X86.HasSSSE3
23+
useAVX2 = cpu.X86.HasAVX2
2624
)
2725

28-
func init() {
29-
detectCPUFeatures()
30-
}
31-
32-
// detectCPUFeatures is used to detect if cpu instructions
33-
// used by the functions implemented in assembler in
34-
// chacha20poly1305_amd64.s are supported.
35-
func detectCPUFeatures() {
36-
maxID, _, _, _ := cpuid(0, 0)
37-
if maxID < 1 {
38-
return
39-
}
40-
41-
_, _, ecx1, _ := cpuid(1, 0)
42-
43-
haveSSSE3 := isSet(9, ecx1)
44-
useASM = haveSSSE3
45-
46-
haveOSXSAVE := isSet(27, ecx1)
47-
48-
osSupportsAVX := false
49-
// For XGETBV, OSXSAVE bit is required and sufficient.
50-
if haveOSXSAVE {
51-
eax, _ := xgetbv()
52-
// Check if XMM and YMM registers have OS support.
53-
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
54-
}
55-
haveAVX := isSet(28, ecx1) && osSupportsAVX
56-
57-
if maxID < 7 {
58-
return
59-
}
60-
61-
_, ebx7, _, _ := cpuid(7, 0)
62-
haveAVX2 := isSet(5, ebx7) && haveAVX
63-
haveBMI2 := isSet(8, ebx7)
64-
65-
useAVX2 = haveAVX2 && haveBMI2
66-
}
67-
68-
// isSet checks if bit at bitpos is set in value.
69-
func isSet(bitpos uint, value uint32) bool {
70-
return value&(1<<bitpos) != 0
71-
}
72-
7326
// setupState writes a ChaCha20 input matrix to state. See
7427
// https://tools.ietf.org/html/rfc7539#section-2.3.
7528
func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) {

0 commit comments

Comments
 (0)