Source File
cpu.go
Belonging Package
internal/cpu
// 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// used by the Go standard library.package cpu// DebugOptions is set to true by the runtime if the OS supports reading// GODEBUG early in runtime startup.// This should not be changed after it is initialized.var DebugOptions bool// CacheLinePad is used to pad structs to avoid false sharing.type CacheLinePad struct{ _ [CacheLinePadSize]byte }// CacheLineSize is the CPU's assumed cache line size.// There is currently no runtime detection of the real cache line size// so we use the constant per GOARCH CacheLinePadSize as an approximation.var CacheLineSize uintptr = CacheLinePadSize// 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.var X86 struct {_ CacheLinePadHasAES boolHasADX boolHasAVX boolHasAVX2 boolHasBMI1 boolHasBMI2 boolHasERMS boolHasFMA boolHasOSXSAVE boolHasPCLMULQDQ boolHasPOPCNT boolHasSSE2 boolHasSSE3 boolHasSSSE3 boolHasSSE41 boolHasSSE42 bool_ CacheLinePad}// The booleans in ARM contain the correspondingly named cpu feature bit.// The struct is padded to avoid false sharing.var ARM struct {_ CacheLinePadHasVFPv4 boolHasIDIVA bool_ CacheLinePad}// The booleans in ARM64 contain the correspondingly named cpu feature bit.// The struct is padded to avoid false sharing.var ARM64 struct {_ CacheLinePadHasAES boolHasPMULL boolHasSHA1 boolHasSHA2 boolHasCRC32 boolHasATOMICS boolHasCPUID boolIsNeoverseN1 boolIsZeus bool_ CacheLinePad}var MIPS64X struct {_ CacheLinePadHasMSA bool // MIPS SIMD architecture_ CacheLinePad}// For ppc64(le), 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// require kernel support to work (darn, scv), so there are feature bits for// those as well. The minimum processor requirement is POWER8 (ISA 2.07).// The struct is padded to avoid false sharing.var PPC64 struct {_ CacheLinePadHasDARN 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)_ CacheLinePad}var S390X struct {_ CacheLinePadHasZARCH 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 pointHasETF3EH bool // ETF-3 enhancedHasMSA bool // message security assist (CPACF)HasAES bool // KM-AES{128,192,256} functionsHasAESCBC bool // KMC-AES{128,192,256} functionsHasAESCTR bool // KMCTR-AES{128,192,256} functionsHasAESGCM bool // KMA-GCM-AES{128,192,256} functionsHasGHASH bool // KIMD-GHASH functionHasSHA1 bool // K{I,L}MD-SHA-1 functionsHasSHA256 bool // K{I,L}MD-SHA-256 functionsHasSHA512 bool // K{I,L}MD-SHA-512 functionsHasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functionsHasVX bool // vector facility. Note: the runtime sets this when it processes auxv records.HasVXE bool // vector-enhancements facility 1HasKDSA bool // elliptic curve functionsHasECDSA bool // NIST curvesHasEDDSA bool // Edwards curves_ CacheLinePad}// 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 if the OS supports// cpu feature options in GODEBUG.func ( string) {doinit()processOptions()}// options contains the cpu debug options that can be used in GODEBUG.// 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 stringFeature *boolSpecified bool // whether feature value was specified in GODEBUGEnable bool // whether feature should be enabledRequired bool // whether feature is mandatory and can not be disabled}// processOptions enables or disables CPU feature values based on the parsed env string.// The env string is expected to be of the form cpu.feature1=value1,cpu.feature2=value2...// where feature names is one of the architecture specific list stored in the// cpu packages options variable and values are either 'on' or 'off'.// If env contains cpu.all=off then all cpu features referenced through the options// variable are disabled. Other feature names and values result in warning messages.func ( string) {:for != "" {:= "":= indexByte(, ',')if < 0 {, = , ""} else {, = [:], [+1:]}if len() < 4 || [:4] != "cpu." {continue}= indexByte(, '=')if < 0 {print("GODEBUG: no value specified for \"", , "\"\n")continue}, := [4:], [+1:] // e.g. "SSE2", "on"var boolswitch {case "on":= truecase "off":= falsedefault:print("GODEBUG: value \"", , "\" not supported for cpu option \"", , "\"\n")continue}if == "all" {for := range options {options[].Specified = trueoptions[].Enable = || options[].Required}continue}for := range options {if options[].Name == {options[].Specified = trueoptions[].Enable =continue}}print("GODEBUG: unknown cpu feature \"", , "\"\n")}for , := range options {if !.Specified {continue}if .Enable && !*.Feature {print("GODEBUG: can not enable \"", .Name, "\", missing CPU support\n")continue}if !.Enable && .Required {print("GODEBUG: can not disable \"", .Name, "\", required CPU feature\n")continue}*.Feature = .Enable}}// indexByte returns the index of the first instance of c in s,// or -1 if c is not present in s.func ( string, byte) int {for := 0; < len(); ++ {if [] == {return}}return -1}