2017-09-14 19:11:35 +02:00
|
|
|
// Copyright 2017 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.
|
|
|
|
|
|
|
|
// Package cpu implements processor feature detection
|
2018-01-09 02:23:08 +01:00
|
|
|
// used by the Go standard library.
|
2017-09-14 19:11:35 +02:00
|
|
|
package cpu
|
|
|
|
|
2018-09-24 23:46:21 +02:00
|
|
|
// DebugOptions is set to true by the runtime if go was compiled with GOEXPERIMENT=debugcpu
|
|
|
|
// and GOOS is Linux or Darwin.
|
|
|
|
// This should not be changed after it is initialized.
|
|
|
|
var DebugOptions bool
|
|
|
|
|
2017-09-14 19:11:35 +02:00
|
|
|
var X86 x86
|
|
|
|
|
|
|
|
// The booleans in x86 contain the correspondingly named cpuid feature bit.
|
|
|
|
// HasAVX and HasAVX2 are only set if the OS does support XMM and YMM registers
|
|
|
|
// in addition to the cpuid feature bit being set.
|
|
|
|
// The struct is padded to avoid false sharing.
|
|
|
|
type x86 struct {
|
|
|
|
_ [CacheLineSize]byte
|
|
|
|
HasAES bool
|
2018-01-09 02:23:08 +01:00
|
|
|
HasADX bool
|
2017-09-14 19:11:35 +02:00
|
|
|
HasAVX bool
|
|
|
|
HasAVX2 bool
|
|
|
|
HasBMI1 bool
|
|
|
|
HasBMI2 bool
|
|
|
|
HasERMS bool
|
2018-01-09 02:23:08 +01:00
|
|
|
HasFMA bool
|
2017-09-14 19:11:35 +02:00
|
|
|
HasOSXSAVE bool
|
|
|
|
HasPCLMULQDQ bool
|
|
|
|
HasPOPCNT bool
|
|
|
|
HasSSE2 bool
|
|
|
|
HasSSE3 bool
|
|
|
|
HasSSSE3 bool
|
|
|
|
HasSSE41 bool
|
|
|
|
HasSSE42 bool
|
|
|
|
_ [CacheLineSize]byte
|
|
|
|
}
|
2018-01-09 02:23:08 +01:00
|
|
|
|
|
|
|
var PPC64 ppc64
|
|
|
|
|
|
|
|
// For ppc64x, it is safe to check only for ISA level starting on ISA v3.00,
|
|
|
|
// since there are no optional categories. There are some exceptions that also
|
2018-09-24 23:46:21 +02:00
|
|
|
// require kernel support to work (darn, scv), so there are feature bits for
|
2018-01-09 02:23:08 +01:00
|
|
|
// those as well. The minimum processor requirement is POWER8 (ISA 2.07), so we
|
2018-09-24 23:46:21 +02:00
|
|
|
// maintain some of the old feature checks for optional categories for
|
2018-01-09 02:23:08 +01:00
|
|
|
// safety.
|
|
|
|
// The struct is padded to avoid false sharing.
|
|
|
|
type ppc64 struct {
|
|
|
|
_ [CacheLineSize]byte
|
|
|
|
HasVMX bool // Vector unit (Altivec)
|
|
|
|
HasDFP bool // Decimal Floating Point unit
|
|
|
|
HasVSX bool // Vector-scalar unit
|
|
|
|
HasHTM bool // Hardware Transactional Memory
|
|
|
|
HasISEL bool // Integer select
|
|
|
|
HasVCRYPTO bool // Vector cryptography
|
|
|
|
HasHTMNOSC bool // HTM: kernel-aborted transaction in syscalls
|
|
|
|
HasDARN bool // Hardware random number generator (requires kernel enablement)
|
|
|
|
HasSCV bool // Syscall vectored (requires kernel enablement)
|
|
|
|
IsPOWER8 bool // ISA v2.07 (POWER8)
|
|
|
|
IsPOWER9 bool // ISA v3.00 (POWER9)
|
|
|
|
_ [CacheLineSize]byte
|
|
|
|
}
|
|
|
|
|
|
|
|
var ARM64 arm64
|
|
|
|
|
|
|
|
// The booleans in arm64 contain the correspondingly named cpu feature bit.
|
|
|
|
// The struct is padded to avoid false sharing.
|
|
|
|
type arm64 struct {
|
2018-09-24 23:46:21 +02:00
|
|
|
_ [CacheLineSize]byte
|
|
|
|
HasFP bool
|
|
|
|
HasASIMD bool
|
|
|
|
HasEVTSTRM bool
|
|
|
|
HasAES bool
|
|
|
|
HasPMULL bool
|
|
|
|
HasSHA1 bool
|
|
|
|
HasSHA2 bool
|
|
|
|
HasCRC32 bool
|
|
|
|
HasATOMICS bool
|
|
|
|
HasFPHP bool
|
|
|
|
HasASIMDHP bool
|
|
|
|
HasCPUID bool
|
|
|
|
HasASIMDRDM bool
|
|
|
|
HasJSCVT bool
|
|
|
|
HasFCMA bool
|
|
|
|
HasLRCPC bool
|
|
|
|
HasDCPOP bool
|
|
|
|
HasSHA3 bool
|
|
|
|
HasSM3 bool
|
|
|
|
HasSM4 bool
|
|
|
|
HasASIMDDP bool
|
|
|
|
HasSHA512 bool
|
|
|
|
HasSVE bool
|
|
|
|
HasASIMDFHM bool
|
|
|
|
_ [CacheLineSize]byte
|
|
|
|
}
|
|
|
|
|
|
|
|
var S390X s390x
|
|
|
|
|
|
|
|
type s390x struct {
|
|
|
|
_ [CacheLineSize]byte
|
|
|
|
HasZArch bool // z architecture mode is active [mandatory]
|
|
|
|
HasSTFLE bool // store facility list extended [mandatory]
|
|
|
|
HasLDisp bool // long (20-bit) displacements [mandatory]
|
|
|
|
HasEImm bool // 32-bit immediates [mandatory]
|
|
|
|
HasDFP bool // decimal floating point
|
|
|
|
HasETF3Enhanced bool // ETF-3 enhanced
|
|
|
|
HasMSA bool // message security assist (CPACF)
|
|
|
|
HasAES bool // KM-AES{128,192,256} functions
|
|
|
|
HasAESCBC bool // KMC-AES{128,192,256} functions
|
|
|
|
HasAESCTR bool // KMCTR-AES{128,192,256} functions
|
|
|
|
HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
|
|
|
|
HasGHASH bool // KIMD-GHASH function
|
|
|
|
HasSHA1 bool // K{I,L}MD-SHA-1 functions
|
|
|
|
HasSHA256 bool // K{I,L}MD-SHA-256 functions
|
|
|
|
HasSHA512 bool // K{I,L}MD-SHA-512 functions
|
|
|
|
HasVX bool // vector facility. Note: the runtime sets this when it processes auxv records.
|
|
|
|
_ [CacheLineSize]byte
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize examines the processor and sets the relevant variables above.
|
|
|
|
// This is called by the runtime package early in program initialization,
|
|
|
|
// before normal init functions are run. env is set by runtime on Linux and Darwin
|
|
|
|
// if go was compiled with GOEXPERIMENT=debugcpu.
|
|
|
|
func Initialize(env string) {
|
|
|
|
doinit()
|
|
|
|
processOptions(env)
|
|
|
|
}
|
|
|
|
|
|
|
|
// options contains the cpu debug options that can be used in GODEBUGCPU.
|
|
|
|
// Options are arch dependent and are added by the arch specific doinit functions.
|
|
|
|
// Features that are mandatory for the specific GOARCH should not be added to options
|
|
|
|
// (e.g. SSE2 on amd64).
|
|
|
|
var options []option
|
|
|
|
|
|
|
|
// Option names should be lower case. e.g. avx instead of AVX.
|
|
|
|
type option struct {
|
|
|
|
Name string
|
|
|
|
Feature *bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// processOptions disables CPU feature values based on the parsed env string.
|
|
|
|
// The env string is expected to be of the form feature1=0,feature2=0...
|
|
|
|
// where feature names is one of the architecture specifc list stored in the
|
|
|
|
// cpu packages options variable. If env contains all=0 then all capabilities
|
|
|
|
// referenced through the options variable are disabled. Other feature
|
|
|
|
// names and values other than 0 are silently ignored.
|
|
|
|
func processOptions(env string) {
|
|
|
|
field:
|
|
|
|
for env != "" {
|
|
|
|
field := ""
|
|
|
|
i := indexByte(env, ',')
|
|
|
|
if i < 0 {
|
|
|
|
field, env = env, ""
|
|
|
|
} else {
|
|
|
|
field, env = env[:i], env[i+1:]
|
|
|
|
}
|
|
|
|
i = indexByte(field, '=')
|
|
|
|
if i < 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
key, value := field[:i], field[i+1:]
|
|
|
|
|
|
|
|
// Only allow turning off CPU features by specifying '0'.
|
|
|
|
if value == "0" {
|
|
|
|
if key == "all" {
|
|
|
|
for _, v := range options {
|
|
|
|
*v.Feature = false
|
|
|
|
}
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
for _, v := range options {
|
|
|
|
if v.Name == key {
|
|
|
|
*v.Feature = false
|
|
|
|
continue field
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// indexByte returns the index of the first instance of c in s,
|
|
|
|
// or -1 if c is not present in s.
|
|
|
|
func indexByte(s string, c byte) int {
|
|
|
|
for i := 0; i < len(s); i++ {
|
|
|
|
if s[i] == c {
|
|
|
|
return i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1
|
2018-01-09 02:23:08 +01:00
|
|
|
}
|