Skip to content

Commit 70b957f

Browse files
mengzhuotklauser
authored andcommitted
cpu: add linux/arm64
Port from Go internal/cpu Updates golang/go#25185 Change-Id: I8390980e38b61f6c428fafa0665a03952e7b00bb Reviewed-on: https://go-review.googlesource.com/c/150718 Run-TryBot: Tobias Klauser <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> Reviewed-by: Martin Möhrmann <[email protected]> Reviewed-by: Tobias Klauser <[email protected]>
1 parent a5c9d58 commit 70b957f

9 files changed

+169
-0
lines changed

cpu/cpu.go

+32
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,35 @@ var X86 struct {
3636
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
3737
_ CacheLinePad
3838
}
39+
40+
// ARM64 contains the supported CPU features of the
41+
// current ARMv8(aarch64) platform. If the current platform
42+
// is not arm64 then all feature flags are false.
43+
var ARM64 struct {
44+
_ CacheLinePad
45+
HasFP bool // Floating-point instruction set (always available)
46+
HasASIMD bool // Advanced SIMD (always available)
47+
HasEVTSTRM bool // Event stream support
48+
HasAES bool // AES hardware implementation
49+
HasPMULL bool // Polynomial multiplication instruction set
50+
HasSHA1 bool // SHA1 hardware implementation
51+
HasSHA2 bool // SHA2 hardware implementation
52+
HasCRC32 bool // CRC32 hardware implementation
53+
HasATOMICS bool // Atomic memory operation instruction set
54+
HasFPHP bool // Half precision floating-point instruction set
55+
HasASIMDHP bool // Advanced SIMD half precision instruction set
56+
HasCPUID bool // CPUID identification scheme registers
57+
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
58+
HasJSCVT bool // Javascript conversion from floating-point to integer
59+
HasFCMA bool // Floating-point multiplication and addition of complex numbers
60+
HasLRCPC bool // Release Consistent processor consistent support
61+
HasDCPOP bool // Persistent memory support
62+
HasSHA3 bool // SHA3 hardware implementation
63+
HasSM3 bool // SM3 hardware implementation
64+
HasSM4 bool // SM4 hardware implementation
65+
HasASIMDDP bool // Advanced SIMD double precision instruction set
66+
HasSHA512 bool // SHA512 hardware implementation
67+
HasSVE bool // Scalable Vector Extensions
68+
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
69+
_ CacheLinePad
70+
}

cpu/cpu_arm.go

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
package cpu
66

77
const cacheLineSize = 32
8+
9+
func doinit() {}

cpu/cpu_arm64.go

+60
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,63 @@
55
package cpu
66

77
const cacheLineSize = 64
8+
9+
// HWCAP/HWCAP2 bits. These are exposed by Linux.
10+
const (
11+
hwcap_FP = 1 << 0
12+
hwcap_ASIMD = 1 << 1
13+
hwcap_EVTSTRM = 1 << 2
14+
hwcap_AES = 1 << 3
15+
hwcap_PMULL = 1 << 4
16+
hwcap_SHA1 = 1 << 5
17+
hwcap_SHA2 = 1 << 6
18+
hwcap_CRC32 = 1 << 7
19+
hwcap_ATOMICS = 1 << 8
20+
hwcap_FPHP = 1 << 9
21+
hwcap_ASIMDHP = 1 << 10
22+
hwcap_CPUID = 1 << 11
23+
hwcap_ASIMDRDM = 1 << 12
24+
hwcap_JSCVT = 1 << 13
25+
hwcap_FCMA = 1 << 14
26+
hwcap_LRCPC = 1 << 15
27+
hwcap_DCPOP = 1 << 16
28+
hwcap_SHA3 = 1 << 17
29+
hwcap_SM3 = 1 << 18
30+
hwcap_SM4 = 1 << 19
31+
hwcap_ASIMDDP = 1 << 20
32+
hwcap_SHA512 = 1 << 21
33+
hwcap_SVE = 1 << 22
34+
hwcap_ASIMDFHM = 1 << 23
35+
)
36+
37+
func doinit() {
38+
// HWCAP feature bits
39+
ARM64.HasFP = isSet(HWCap, hwcap_FP)
40+
ARM64.HasASIMD = isSet(HWCap, hwcap_ASIMD)
41+
ARM64.HasEVTSTRM = isSet(HWCap, hwcap_EVTSTRM)
42+
ARM64.HasAES = isSet(HWCap, hwcap_AES)
43+
ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL)
44+
ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1)
45+
ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2)
46+
ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32)
47+
ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS)
48+
ARM64.HasFPHP = isSet(HWCap, hwcap_FPHP)
49+
ARM64.HasASIMDHP = isSet(HWCap, hwcap_ASIMDHP)
50+
ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID)
51+
ARM64.HasASIMDRDM = isSet(HWCap, hwcap_ASIMDRDM)
52+
ARM64.HasJSCVT = isSet(HWCap, hwcap_JSCVT)
53+
ARM64.HasFCMA = isSet(HWCap, hwcap_FCMA)
54+
ARM64.HasLRCPC = isSet(HWCap, hwcap_LRCPC)
55+
ARM64.HasDCPOP = isSet(HWCap, hwcap_DCPOP)
56+
ARM64.HasSHA3 = isSet(HWCap, hwcap_SHA3)
57+
ARM64.HasSM3 = isSet(HWCap, hwcap_SM3)
58+
ARM64.HasSM4 = isSet(HWCap, hwcap_SM4)
59+
ARM64.HasASIMDDP = isSet(HWCap, hwcap_ASIMDDP)
60+
ARM64.HasSHA512 = isSet(HWCap, hwcap_SHA512)
61+
ARM64.HasSVE = isSet(HWCap, hwcap_SVE)
62+
ARM64.HasASIMDFHM = isSet(HWCap, hwcap_ASIMDFHM)
63+
}
64+
65+
func isSet(hwc uint, value uint) bool {
66+
return hwc&value != 0
67+
}

cpu/cpu_linux.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//+build !amd64,!amd64p32,!386
6+
7+
package cpu
8+
9+
import (
10+
"encoding/binary"
11+
"io/ioutil"
12+
)
13+
14+
const (
15+
_AT_HWCAP = 16
16+
_AT_HWCAP2 = 26
17+
18+
procAuxv = "/proc/self/auxv"
19+
20+
uintSize uint = 32 << (^uint(0) >> 63)
21+
)
22+
23+
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
24+
// These are initialized in cpu_$GOARCH.go
25+
// and should not be changed after they are initialized.
26+
var HWCap uint
27+
var HWCap2 uint
28+
29+
func init() {
30+
buf, err := ioutil.ReadFile(procAuxv)
31+
if err != nil {
32+
panic("read proc auxv failed: " + err.Error())
33+
}
34+
35+
pb := int(uintSize / 8)
36+
37+
for i := 0; i < len(buf)-pb*2; i += pb * 2 {
38+
var tag, val uint
39+
switch uintSize {
40+
case 32:
41+
tag = uint(binary.LittleEndian.Uint32(buf[i:]))
42+
val = uint(binary.LittleEndian.Uint32(buf[i+pb:]))
43+
case 64:
44+
tag = uint(binary.LittleEndian.Uint64(buf[i:]))
45+
val = uint(binary.LittleEndian.Uint64(buf[i+pb:]))
46+
}
47+
switch tag {
48+
case _AT_HWCAP:
49+
HWCap = val
50+
case _AT_HWCAP2:
51+
HWCap2 = val
52+
}
53+
}
54+
doinit()
55+
}

cpu/cpu_mips64x.go

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
package cpu
88

99
const cacheLineSize = 32
10+
11+
func doinit() {}

cpu/cpu_mipsx.go

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
package cpu
88

99
const cacheLineSize = 32
10+
11+
func doinit() {}

cpu/cpu_ppc64x.go

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
package cpu
88

99
const cacheLineSize = 128
10+
11+
func doinit() {}

cpu/cpu_s390x.go

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
package cpu
66

77
const cacheLineSize = 256
8+
9+
func doinit() {}

cpu/cpu_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,15 @@ func TestAVX2hasAVX(t *testing.T) {
2626
}
2727
}
2828
}
29+
30+
func TestARM64minimalFeatures(t *testing.T) {
31+
if runtime.GOARCH != "arm64" || runtime.GOOS != "linux" {
32+
return
33+
}
34+
if !cpu.ARM64.HasASIMD {
35+
t.Fatal("HasASIMD expected true, got false")
36+
}
37+
if !cpu.ARM64.HasFP {
38+
t.Fatal("HasFP expected true, got false")
39+
}
40+
}

0 commit comments

Comments
 (0)