mirror of
https://github.com/golang/sys.git
synced 2026-02-09 04:06:04 +03:00
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 <tobias.klauser@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Martin Möhrmann <moehrmann@google.com> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
This commit is contained in:
committed by
Tobias Klauser
parent
a5c9d58dba
commit
70b957f3b6
32
cpu/cpu.go
32
cpu/cpu.go
@@ -36,3 +36,35 @@ var X86 struct {
|
||||
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
// ARM64 contains the supported CPU features of the
|
||||
// current ARMv8(aarch64) platform. If the current platform
|
||||
// is not arm64 then all feature flags are false.
|
||||
var ARM64 struct {
|
||||
_ CacheLinePad
|
||||
HasFP bool // Floating-point instruction set (always available)
|
||||
HasASIMD bool // Advanced SIMD (always available)
|
||||
HasEVTSTRM bool // Event stream support
|
||||
HasAES bool // AES hardware implementation
|
||||
HasPMULL bool // Polynomial multiplication instruction set
|
||||
HasSHA1 bool // SHA1 hardware implementation
|
||||
HasSHA2 bool // SHA2 hardware implementation
|
||||
HasCRC32 bool // CRC32 hardware implementation
|
||||
HasATOMICS bool // Atomic memory operation instruction set
|
||||
HasFPHP bool // Half precision floating-point instruction set
|
||||
HasASIMDHP bool // Advanced SIMD half precision instruction set
|
||||
HasCPUID bool // CPUID identification scheme registers
|
||||
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
|
||||
HasJSCVT bool // Javascript conversion from floating-point to integer
|
||||
HasFCMA bool // Floating-point multiplication and addition of complex numbers
|
||||
HasLRCPC bool // Release Consistent processor consistent support
|
||||
HasDCPOP bool // Persistent memory support
|
||||
HasSHA3 bool // SHA3 hardware implementation
|
||||
HasSM3 bool // SM3 hardware implementation
|
||||
HasSM4 bool // SM4 hardware implementation
|
||||
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||
HasSHA512 bool // SHA512 hardware implementation
|
||||
HasSVE bool // Scalable Vector Extensions
|
||||
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||
_ CacheLinePad
|
||||
}
|
||||
|
||||
@@ -5,3 +5,5 @@
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func doinit() {}
|
||||
|
||||
@@ -5,3 +5,63 @@
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 64
|
||||
|
||||
// HWCAP/HWCAP2 bits. These are exposed by Linux.
|
||||
const (
|
||||
hwcap_FP = 1 << 0
|
||||
hwcap_ASIMD = 1 << 1
|
||||
hwcap_EVTSTRM = 1 << 2
|
||||
hwcap_AES = 1 << 3
|
||||
hwcap_PMULL = 1 << 4
|
||||
hwcap_SHA1 = 1 << 5
|
||||
hwcap_SHA2 = 1 << 6
|
||||
hwcap_CRC32 = 1 << 7
|
||||
hwcap_ATOMICS = 1 << 8
|
||||
hwcap_FPHP = 1 << 9
|
||||
hwcap_ASIMDHP = 1 << 10
|
||||
hwcap_CPUID = 1 << 11
|
||||
hwcap_ASIMDRDM = 1 << 12
|
||||
hwcap_JSCVT = 1 << 13
|
||||
hwcap_FCMA = 1 << 14
|
||||
hwcap_LRCPC = 1 << 15
|
||||
hwcap_DCPOP = 1 << 16
|
||||
hwcap_SHA3 = 1 << 17
|
||||
hwcap_SM3 = 1 << 18
|
||||
hwcap_SM4 = 1 << 19
|
||||
hwcap_ASIMDDP = 1 << 20
|
||||
hwcap_SHA512 = 1 << 21
|
||||
hwcap_SVE = 1 << 22
|
||||
hwcap_ASIMDFHM = 1 << 23
|
||||
)
|
||||
|
||||
func doinit() {
|
||||
// HWCAP feature bits
|
||||
ARM64.HasFP = isSet(HWCap, hwcap_FP)
|
||||
ARM64.HasASIMD = isSet(HWCap, hwcap_ASIMD)
|
||||
ARM64.HasEVTSTRM = isSet(HWCap, hwcap_EVTSTRM)
|
||||
ARM64.HasAES = isSet(HWCap, hwcap_AES)
|
||||
ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL)
|
||||
ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1)
|
||||
ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2)
|
||||
ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32)
|
||||
ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS)
|
||||
ARM64.HasFPHP = isSet(HWCap, hwcap_FPHP)
|
||||
ARM64.HasASIMDHP = isSet(HWCap, hwcap_ASIMDHP)
|
||||
ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID)
|
||||
ARM64.HasASIMDRDM = isSet(HWCap, hwcap_ASIMDRDM)
|
||||
ARM64.HasJSCVT = isSet(HWCap, hwcap_JSCVT)
|
||||
ARM64.HasFCMA = isSet(HWCap, hwcap_FCMA)
|
||||
ARM64.HasLRCPC = isSet(HWCap, hwcap_LRCPC)
|
||||
ARM64.HasDCPOP = isSet(HWCap, hwcap_DCPOP)
|
||||
ARM64.HasSHA3 = isSet(HWCap, hwcap_SHA3)
|
||||
ARM64.HasSM3 = isSet(HWCap, hwcap_SM3)
|
||||
ARM64.HasSM4 = isSet(HWCap, hwcap_SM4)
|
||||
ARM64.HasASIMDDP = isSet(HWCap, hwcap_ASIMDDP)
|
||||
ARM64.HasSHA512 = isSet(HWCap, hwcap_SHA512)
|
||||
ARM64.HasSVE = isSet(HWCap, hwcap_SVE)
|
||||
ARM64.HasASIMDFHM = isSet(HWCap, hwcap_ASIMDFHM)
|
||||
}
|
||||
|
||||
func isSet(hwc uint, value uint) bool {
|
||||
return hwc&value != 0
|
||||
}
|
||||
|
||||
55
cpu/cpu_linux.go
Normal file
55
cpu/cpu_linux.go
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !amd64,!amd64p32,!386
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
const (
|
||||
_AT_HWCAP = 16
|
||||
_AT_HWCAP2 = 26
|
||||
|
||||
procAuxv = "/proc/self/auxv"
|
||||
|
||||
uintSize uint = 32 << (^uint(0) >> 63)
|
||||
)
|
||||
|
||||
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
|
||||
// These are initialized in cpu_$GOARCH.go
|
||||
// and should not be changed after they are initialized.
|
||||
var HWCap uint
|
||||
var HWCap2 uint
|
||||
|
||||
func init() {
|
||||
buf, err := ioutil.ReadFile(procAuxv)
|
||||
if err != nil {
|
||||
panic("read proc auxv failed: " + err.Error())
|
||||
}
|
||||
|
||||
pb := int(uintSize / 8)
|
||||
|
||||
for i := 0; i < len(buf)-pb*2; i += pb * 2 {
|
||||
var tag, val uint
|
||||
switch uintSize {
|
||||
case 32:
|
||||
tag = uint(binary.LittleEndian.Uint32(buf[i:]))
|
||||
val = uint(binary.LittleEndian.Uint32(buf[i+pb:]))
|
||||
case 64:
|
||||
tag = uint(binary.LittleEndian.Uint64(buf[i:]))
|
||||
val = uint(binary.LittleEndian.Uint64(buf[i+pb:]))
|
||||
}
|
||||
switch tag {
|
||||
case _AT_HWCAP:
|
||||
HWCap = val
|
||||
case _AT_HWCAP2:
|
||||
HWCap2 = val
|
||||
}
|
||||
}
|
||||
doinit()
|
||||
}
|
||||
@@ -7,3 +7,5 @@
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func doinit() {}
|
||||
|
||||
@@ -7,3 +7,5 @@
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func doinit() {}
|
||||
|
||||
@@ -7,3 +7,5 @@
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 128
|
||||
|
||||
func doinit() {}
|
||||
|
||||
@@ -5,3 +5,5 @@
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 256
|
||||
|
||||
func doinit() {}
|
||||
|
||||
@@ -26,3 +26,15 @@ func TestAVX2hasAVX(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestARM64minimalFeatures(t *testing.T) {
|
||||
if runtime.GOARCH != "arm64" || runtime.GOOS != "linux" {
|
||||
return
|
||||
}
|
||||
if !cpu.ARM64.HasASIMD {
|
||||
t.Fatal("HasASIMD expected true, got false")
|
||||
}
|
||||
if !cpu.ARM64.HasFP {
|
||||
t.Fatal("HasFP expected true, got false")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user