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