github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/internal/cpu/cpu.go (about) 1 // Copyright 2017 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 // Package cpu implements processor feature detection 6 // used by the Go standard library. 7 package cpu 8 9 // DebugOptions is set to true by the runtime if the OS supports GODEBUGCPU. 10 // This should not be changed after it is initialized. 11 var DebugOptions bool 12 13 // CacheLinePad is used to pad structs to avoid false sharing. 14 type CacheLinePad struct{ _ [CacheLinePadSize]byte } 15 16 // CacheLineSize is the CPU's assumed cache line size. 17 // There is currently no runtime detection of the real cache line size 18 // so we use the constant per GOARCH CacheLinePadSize as an approximation. 19 var CacheLineSize uintptr = CacheLinePadSize 20 21 var X86 x86 22 23 // The booleans in x86 contain the correspondingly named cpuid feature bit. 24 // HasAVX and HasAVX2 are only set if the OS does support XMM and YMM registers 25 // in addition to the cpuid feature bit being set. 26 // The struct is padded to avoid false sharing. 27 type x86 struct { 28 _ CacheLinePad 29 HasAES bool 30 HasADX bool 31 HasAVX bool 32 HasAVX2 bool 33 HasBMI1 bool 34 HasBMI2 bool 35 HasERMS bool 36 HasFMA bool 37 HasOSXSAVE bool 38 HasPCLMULQDQ bool 39 HasPOPCNT bool 40 HasSSE2 bool 41 HasSSE3 bool 42 HasSSSE3 bool 43 HasSSE41 bool 44 HasSSE42 bool 45 _ CacheLinePad 46 } 47 48 var PPC64 ppc64 49 50 // For ppc64x, it is safe to check only for ISA level starting on ISA v3.00, 51 // since there are no optional categories. There are some exceptions that also 52 // require kernel support to work (darn, scv), so there are feature bits for 53 // those as well. The minimum processor requirement is POWER8 (ISA 2.07), so we 54 // maintain some of the old feature checks for optional categories for 55 // safety. 56 // The struct is padded to avoid false sharing. 57 type ppc64 struct { 58 _ CacheLinePad 59 HasVMX bool // Vector unit (Altivec) 60 HasDFP bool // Decimal Floating Point unit 61 HasVSX bool // Vector-scalar unit 62 HasHTM bool // Hardware Transactional Memory 63 HasISEL bool // Integer select 64 HasVCRYPTO bool // Vector cryptography 65 HasHTMNOSC bool // HTM: kernel-aborted transaction in syscalls 66 HasDARN bool // Hardware random number generator (requires kernel enablement) 67 HasSCV bool // Syscall vectored (requires kernel enablement) 68 IsPOWER8 bool // ISA v2.07 (POWER8) 69 IsPOWER9 bool // ISA v3.00 (POWER9) 70 _ CacheLinePad 71 } 72 73 var ARM arm 74 75 // The booleans in arm contain the correspondingly named cpu feature bit. 76 // The struct is padded to avoid false sharing. 77 type arm struct { 78 _ CacheLinePad 79 HasVFPv4 bool 80 HasIDIVA bool 81 _ CacheLinePad 82 } 83 84 var ARM64 arm64 85 86 // The booleans in arm64 contain the correspondingly named cpu feature bit. 87 // The struct is padded to avoid false sharing. 88 type arm64 struct { 89 _ CacheLinePad 90 HasFP bool 91 HasASIMD bool 92 HasEVTSTRM bool 93 HasAES bool 94 HasPMULL bool 95 HasSHA1 bool 96 HasSHA2 bool 97 HasCRC32 bool 98 HasATOMICS bool 99 HasFPHP bool 100 HasASIMDHP bool 101 HasCPUID bool 102 HasASIMDRDM bool 103 HasJSCVT bool 104 HasFCMA bool 105 HasLRCPC bool 106 HasDCPOP bool 107 HasSHA3 bool 108 HasSM3 bool 109 HasSM4 bool 110 HasASIMDDP bool 111 HasSHA512 bool 112 HasSVE bool 113 HasASIMDFHM bool 114 _ CacheLinePad 115 } 116 117 var S390X s390x 118 119 type s390x struct { 120 _ CacheLinePad 121 HasZArch bool // z architecture mode is active [mandatory] 122 HasSTFLE bool // store facility list extended [mandatory] 123 HasLDisp bool // long (20-bit) displacements [mandatory] 124 HasEImm bool // 32-bit immediates [mandatory] 125 HasDFP bool // decimal floating point 126 HasETF3Enhanced bool // ETF-3 enhanced 127 HasMSA bool // message security assist (CPACF) 128 HasAES bool // KM-AES{128,192,256} functions 129 HasAESCBC bool // KMC-AES{128,192,256} functions 130 HasAESCTR bool // KMCTR-AES{128,192,256} functions 131 HasAESGCM bool // KMA-GCM-AES{128,192,256} functions 132 HasGHASH bool // KIMD-GHASH function 133 HasSHA1 bool // K{I,L}MD-SHA-1 functions 134 HasSHA256 bool // K{I,L}MD-SHA-256 functions 135 HasSHA512 bool // K{I,L}MD-SHA-512 functions 136 HasVX bool // vector facility. Note: the runtime sets this when it processes auxv records. 137 _ CacheLinePad 138 } 139 140 // Initialize examines the processor and sets the relevant variables above. 141 // This is called by the runtime package early in program initialization, 142 // before normal init functions are run. env is set by runtime if the OS supports GODEBUGCPU. 143 func Initialize(env string) { 144 doinit() 145 processOptions(env) 146 } 147 148 // options contains the cpu debug options that can be used in GODEBUGCPU. 149 // Options are arch dependent and are added by the arch specific doinit functions. 150 // Features that are mandatory for the specific GOARCH should not be added to options 151 // (e.g. SSE2 on amd64). 152 var options []option 153 154 // Option names should be lower case. e.g. avx instead of AVX. 155 type option struct { 156 Name string 157 Feature *bool 158 Specified bool // whether feature value was specified in GODEBUGCPU 159 Enable bool // whether feature should be enabled 160 Required bool // whether feature is mandatory and can not be disabled 161 } 162 163 // processOptions enables or disables CPU feature values based on the parsed env string. 164 // The env string is expected to be of the form feature1=value1,feature2=value2... 165 // where feature names is one of the architecture specifc list stored in the 166 // cpu packages options variable and values are either 'on' or 'off'. 167 // If env contains all=off then all cpu features referenced through the options 168 // variable are disabled. Other feature names and values result in warning messages. 169 func processOptions(env string) { 170 field: 171 for env != "" { 172 field := "" 173 i := indexByte(env, ',') 174 if i < 0 { 175 field, env = env, "" 176 } else { 177 field, env = env[:i], env[i+1:] 178 } 179 i = indexByte(field, '=') 180 if i < 0 { 181 print("GODEBUGCPU: no value specified for \"", field, "\"\n") 182 continue 183 } 184 key, value := field[:i], field[i+1:] 185 186 var enable bool 187 switch value { 188 case "on": 189 enable = true 190 case "off": 191 enable = false 192 default: 193 print("GODEBUGCPU: value \"", value, "\" not supported for option ", key, "\n") 194 continue field 195 } 196 197 if key == "all" { 198 for i := range options { 199 options[i].Specified = true 200 options[i].Enable = enable || options[i].Required 201 } 202 continue field 203 } 204 205 for i := range options { 206 if options[i].Name == key { 207 options[i].Specified = true 208 options[i].Enable = enable 209 continue field 210 } 211 } 212 213 print("GODEBUGCPU: unknown cpu feature \"", key, "\"\n") 214 } 215 216 for _, o := range options { 217 if !o.Specified { 218 continue 219 } 220 221 if o.Enable && !*o.Feature { 222 print("GODEBUGCPU: can not enable \"", o.Name, "\", missing hardware support\n") 223 continue 224 } 225 226 if !o.Enable && o.Required { 227 print("GODEBUGCPU: can not disable \"", o.Name, "\", required feature\n") 228 continue 229 } 230 231 *o.Feature = o.Enable 232 } 233 } 234 235 // indexByte returns the index of the first instance of c in s, 236 // or -1 if c is not present in s. 237 func indexByte(s string, c byte) int { 238 for i := 0; i < len(s); i++ { 239 if s[i] == c { 240 return i 241 } 242 } 243 return -1 244 }