gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

cpu.go (12154B)


      1 // Copyright 2018 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 for
      6 // various CPU architectures.
      7 package cpu
      8 
      9 import (
     10 	"os"
     11 	"strings"
     12 )
     13 
     14 // Initialized reports whether the CPU features were initialized.
     15 //
     16 // For some GOOS/GOARCH combinations initialization of the CPU features depends
     17 // on reading an operating specific file, e.g. /proc/self/auxv on linux/arm
     18 // Initialized will report false if reading the file fails.
     19 var Initialized bool
     20 
     21 // CacheLinePad is used to pad structs to avoid false sharing.
     22 type CacheLinePad struct{ _ [cacheLineSize]byte }
     23 
     24 // X86 contains the supported CPU features of the
     25 // current X86/AMD64 platform. If the current platform
     26 // is not X86/AMD64 then all feature flags are false.
     27 //
     28 // X86 is padded to avoid false sharing. Further the HasAVX
     29 // and HasAVX2 are only set if the OS supports XMM and YMM
     30 // registers in addition to the CPUID feature bit being set.
     31 var X86 struct {
     32 	_                   CacheLinePad
     33 	HasAES              bool // AES hardware implementation (AES NI)
     34 	HasADX              bool // Multi-precision add-carry instruction extensions
     35 	HasAVX              bool // Advanced vector extension
     36 	HasAVX2             bool // Advanced vector extension 2
     37 	HasAVX512           bool // Advanced vector extension 512
     38 	HasAVX512F          bool // Advanced vector extension 512 Foundation Instructions
     39 	HasAVX512CD         bool // Advanced vector extension 512 Conflict Detection Instructions
     40 	HasAVX512ER         bool // Advanced vector extension 512 Exponential and Reciprocal Instructions
     41 	HasAVX512PF         bool // Advanced vector extension 512 Prefetch Instructions Instructions
     42 	HasAVX512VL         bool // Advanced vector extension 512 Vector Length Extensions
     43 	HasAVX512BW         bool // Advanced vector extension 512 Byte and Word Instructions
     44 	HasAVX512DQ         bool // Advanced vector extension 512 Doubleword and Quadword Instructions
     45 	HasAVX512IFMA       bool // Advanced vector extension 512 Integer Fused Multiply Add
     46 	HasAVX512VBMI       bool // Advanced vector extension 512 Vector Byte Manipulation Instructions
     47 	HasAVX5124VNNIW     bool // Advanced vector extension 512 Vector Neural Network Instructions Word variable precision
     48 	HasAVX5124FMAPS     bool // Advanced vector extension 512 Fused Multiply Accumulation Packed Single precision
     49 	HasAVX512VPOPCNTDQ  bool // Advanced vector extension 512 Double and quad word population count instructions
     50 	HasAVX512VPCLMULQDQ bool // Advanced vector extension 512 Vector carry-less multiply operations
     51 	HasAVX512VNNI       bool // Advanced vector extension 512 Vector Neural Network Instructions
     52 	HasAVX512GFNI       bool // Advanced vector extension 512 Galois field New Instructions
     53 	HasAVX512VAES       bool // Advanced vector extension 512 Vector AES instructions
     54 	HasAVX512VBMI2      bool // Advanced vector extension 512 Vector Byte Manipulation Instructions 2
     55 	HasAVX512BITALG     bool // Advanced vector extension 512 Bit Algorithms
     56 	HasAVX512BF16       bool // Advanced vector extension 512 BFloat16 Instructions
     57 	HasBMI1             bool // Bit manipulation instruction set 1
     58 	HasBMI2             bool // Bit manipulation instruction set 2
     59 	HasCX16             bool // Compare and exchange 16 Bytes
     60 	HasERMS             bool // Enhanced REP for MOVSB and STOSB
     61 	HasFMA              bool // Fused-multiply-add instructions
     62 	HasOSXSAVE          bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
     63 	HasPCLMULQDQ        bool // PCLMULQDQ instruction - most often used for AES-GCM
     64 	HasPOPCNT           bool // Hamming weight instruction POPCNT.
     65 	HasRDRAND           bool // RDRAND instruction (on-chip random number generator)
     66 	HasRDSEED           bool // RDSEED instruction (on-chip random number generator)
     67 	HasSSE2             bool // Streaming SIMD extension 2 (always available on amd64)
     68 	HasSSE3             bool // Streaming SIMD extension 3
     69 	HasSSSE3            bool // Supplemental streaming SIMD extension 3
     70 	HasSSE41            bool // Streaming SIMD extension 4 and 4.1
     71 	HasSSE42            bool // Streaming SIMD extension 4 and 4.2
     72 	_                   CacheLinePad
     73 }
     74 
     75 // ARM64 contains the supported CPU features of the
     76 // current ARMv8(aarch64) platform. If the current platform
     77 // is not arm64 then all feature flags are false.
     78 var ARM64 struct {
     79 	_           CacheLinePad
     80 	HasFP       bool // Floating-point instruction set (always available)
     81 	HasASIMD    bool // Advanced SIMD (always available)
     82 	HasEVTSTRM  bool // Event stream support
     83 	HasAES      bool // AES hardware implementation
     84 	HasPMULL    bool // Polynomial multiplication instruction set
     85 	HasSHA1     bool // SHA1 hardware implementation
     86 	HasSHA2     bool // SHA2 hardware implementation
     87 	HasCRC32    bool // CRC32 hardware implementation
     88 	HasATOMICS  bool // Atomic memory operation instruction set
     89 	HasFPHP     bool // Half precision floating-point instruction set
     90 	HasASIMDHP  bool // Advanced SIMD half precision instruction set
     91 	HasCPUID    bool // CPUID identification scheme registers
     92 	HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
     93 	HasJSCVT    bool // Javascript conversion from floating-point to integer
     94 	HasFCMA     bool // Floating-point multiplication and addition of complex numbers
     95 	HasLRCPC    bool // Release Consistent processor consistent support
     96 	HasDCPOP    bool // Persistent memory support
     97 	HasSHA3     bool // SHA3 hardware implementation
     98 	HasSM3      bool // SM3 hardware implementation
     99 	HasSM4      bool // SM4 hardware implementation
    100 	HasASIMDDP  bool // Advanced SIMD double precision instruction set
    101 	HasSHA512   bool // SHA512 hardware implementation
    102 	HasSVE      bool // Scalable Vector Extensions
    103 	HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
    104 	_           CacheLinePad
    105 }
    106 
    107 // ARM contains the supported CPU features of the current ARM (32-bit) platform.
    108 // All feature flags are false if:
    109 //  1. the current platform is not arm, or
    110 //  2. the current operating system is not Linux.
    111 var ARM struct {
    112 	_           CacheLinePad
    113 	HasSWP      bool // SWP instruction support
    114 	HasHALF     bool // Half-word load and store support
    115 	HasTHUMB    bool // ARM Thumb instruction set
    116 	Has26BIT    bool // Address space limited to 26-bits
    117 	HasFASTMUL  bool // 32-bit operand, 64-bit result multiplication support
    118 	HasFPA      bool // Floating point arithmetic support
    119 	HasVFP      bool // Vector floating point support
    120 	HasEDSP     bool // DSP Extensions support
    121 	HasJAVA     bool // Java instruction set
    122 	HasIWMMXT   bool // Intel Wireless MMX technology support
    123 	HasCRUNCH   bool // MaverickCrunch context switching and handling
    124 	HasTHUMBEE  bool // Thumb EE instruction set
    125 	HasNEON     bool // NEON instruction set
    126 	HasVFPv3    bool // Vector floating point version 3 support
    127 	HasVFPv3D16 bool // Vector floating point version 3 D8-D15
    128 	HasTLS      bool // Thread local storage support
    129 	HasVFPv4    bool // Vector floating point version 4 support
    130 	HasIDIVA    bool // Integer divide instruction support in ARM mode
    131 	HasIDIVT    bool // Integer divide instruction support in Thumb mode
    132 	HasVFPD32   bool // Vector floating point version 3 D15-D31
    133 	HasLPAE     bool // Large Physical Address Extensions
    134 	HasEVTSTRM  bool // Event stream support
    135 	HasAES      bool // AES hardware implementation
    136 	HasPMULL    bool // Polynomial multiplication instruction set
    137 	HasSHA1     bool // SHA1 hardware implementation
    138 	HasSHA2     bool // SHA2 hardware implementation
    139 	HasCRC32    bool // CRC32 hardware implementation
    140 	_           CacheLinePad
    141 }
    142 
    143 // MIPS64X contains the supported CPU features of the current mips64/mips64le
    144 // platforms. If the current platform is not mips64/mips64le or the current
    145 // operating system is not Linux then all feature flags are false.
    146 var MIPS64X struct {
    147 	_      CacheLinePad
    148 	HasMSA bool // MIPS SIMD architecture
    149 	_      CacheLinePad
    150 }
    151 
    152 // PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
    153 // If the current platform is not ppc64/ppc64le then all feature flags are false.
    154 //
    155 // For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
    156 // since there are no optional categories. There are some exceptions that also
    157 // require kernel support to work (DARN, SCV), so there are feature bits for
    158 // those as well. The struct is padded to avoid false sharing.
    159 var PPC64 struct {
    160 	_        CacheLinePad
    161 	HasDARN  bool // Hardware random number generator (requires kernel enablement)
    162 	HasSCV   bool // Syscall vectored (requires kernel enablement)
    163 	IsPOWER8 bool // ISA v2.07 (POWER8)
    164 	IsPOWER9 bool // ISA v3.00 (POWER9), implies IsPOWER8
    165 	_        CacheLinePad
    166 }
    167 
    168 // S390X contains the supported CPU features of the current IBM Z
    169 // (s390x) platform. If the current platform is not IBM Z then all
    170 // feature flags are false.
    171 //
    172 // S390X is padded to avoid false sharing. Further HasVX is only set
    173 // if the OS supports vector registers in addition to the STFLE
    174 // feature bit being set.
    175 var S390X struct {
    176 	_         CacheLinePad
    177 	HasZARCH  bool // z/Architecture mode is active [mandatory]
    178 	HasSTFLE  bool // store facility list extended
    179 	HasLDISP  bool // long (20-bit) displacements
    180 	HasEIMM   bool // 32-bit immediates
    181 	HasDFP    bool // decimal floating point
    182 	HasETF3EH bool // ETF-3 enhanced
    183 	HasMSA    bool // message security assist (CPACF)
    184 	HasAES    bool // KM-AES{128,192,256} functions
    185 	HasAESCBC bool // KMC-AES{128,192,256} functions
    186 	HasAESCTR bool // KMCTR-AES{128,192,256} functions
    187 	HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
    188 	HasGHASH  bool // KIMD-GHASH function
    189 	HasSHA1   bool // K{I,L}MD-SHA-1 functions
    190 	HasSHA256 bool // K{I,L}MD-SHA-256 functions
    191 	HasSHA512 bool // K{I,L}MD-SHA-512 functions
    192 	HasSHA3   bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
    193 	HasVX     bool // vector facility
    194 	HasVXE    bool // vector-enhancements facility 1
    195 	_         CacheLinePad
    196 }
    197 
    198 func init() {
    199 	archInit()
    200 	initOptions()
    201 	processOptions()
    202 }
    203 
    204 // options contains the cpu debug options that can be used in GODEBUG.
    205 // Options are arch dependent and are added by the arch specific initOptions functions.
    206 // Features that are mandatory for the specific GOARCH should have the Required field set
    207 // (e.g. SSE2 on amd64).
    208 var options []option
    209 
    210 // Option names should be lower case. e.g. avx instead of AVX.
    211 type option struct {
    212 	Name      string
    213 	Feature   *bool
    214 	Specified bool // whether feature value was specified in GODEBUG
    215 	Enable    bool // whether feature should be enabled
    216 	Required  bool // whether feature is mandatory and can not be disabled
    217 }
    218 
    219 func processOptions() {
    220 	env := os.Getenv("GODEBUG")
    221 field:
    222 	for env != "" {
    223 		field := ""
    224 		i := strings.IndexByte(env, ',')
    225 		if i < 0 {
    226 			field, env = env, ""
    227 		} else {
    228 			field, env = env[:i], env[i+1:]
    229 		}
    230 		if len(field) < 4 || field[:4] != "cpu." {
    231 			continue
    232 		}
    233 		i = strings.IndexByte(field, '=')
    234 		if i < 0 {
    235 			print("GODEBUG sys/cpu: no value specified for \"", field, "\"\n")
    236 			continue
    237 		}
    238 		key, value := field[4:i], field[i+1:] // e.g. "SSE2", "on"
    239 
    240 		var enable bool
    241 		switch value {
    242 		case "on":
    243 			enable = true
    244 		case "off":
    245 			enable = false
    246 		default:
    247 			print("GODEBUG sys/cpu: value \"", value, "\" not supported for cpu option \"", key, "\"\n")
    248 			continue field
    249 		}
    250 
    251 		if key == "all" {
    252 			for i := range options {
    253 				options[i].Specified = true
    254 				options[i].Enable = enable || options[i].Required
    255 			}
    256 			continue field
    257 		}
    258 
    259 		for i := range options {
    260 			if options[i].Name == key {
    261 				options[i].Specified = true
    262 				options[i].Enable = enable
    263 				continue field
    264 			}
    265 		}
    266 
    267 		print("GODEBUG sys/cpu: unknown cpu feature \"", key, "\"\n")
    268 	}
    269 
    270 	for _, o := range options {
    271 		if !o.Specified {
    272 			continue
    273 		}
    274 
    275 		if o.Enable && !*o.Feature {
    276 			print("GODEBUG sys/cpu: can not enable \"", o.Name, "\", missing CPU support\n")
    277 			continue
    278 		}
    279 
    280 		if !o.Enable && o.Required {
    281 			print("GODEBUG sys/cpu: can not disable \"", o.Name, "\", required CPU feature\n")
    282 			continue
    283 		}
    284 
    285 		*o.Feature = o.Enable
    286 	}
    287 }