aboutsummaryrefslogtreecommitdiff
path: root/irc/kcpd/vendor/github.com
diff options
context:
space:
mode:
authorChristine Dodrill <me@christine.website>2017-04-14 02:11:51 -0700
committerChristine Dodrill <me@christine.website>2017-04-14 02:11:51 -0700
commitb48fc20b2d3792cb9030cd3e8d6b0b4c34d1c97b (patch)
treeb738c36946ac7d299976ec69e5a32629baab396f /irc/kcpd/vendor/github.com
parentdfa688ec71053f552386b2bbee6c8d45e01b6f46 (diff)
downloadx-b48fc20b2d3792cb9030cd3e8d6b0b4c34d1c97b.tar.xz
x-b48fc20b2d3792cb9030cd3e8d6b0b4c34d1c97b.zip
vendor
Diffstat (limited to 'irc/kcpd/vendor/github.com')
-rw-r--r--irc/kcpd/vendor/github.com/caarlos0/env/env.go275
-rw-r--r--irc/kcpd/vendor/github.com/joho/godotenv/autoload/autoload.go15
-rw-r--r--irc/kcpd/vendor/github.com/joho/godotenv/godotenv.go229
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/cpuid/cpuid.go1022
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/cpuid/cpuid_amd64.s42
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/cpuid/detect_intel.go17
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/cpuid/detect_ref.go23
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/cpuid/generate.go3
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/cpuid/private-gen.go476
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/galois.go134
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/galois_amd64.go73
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/galois_amd64.s164
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/galois_noasm.go19
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/gentables.go132
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/inversion_tree.go160
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/matrix.go279
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/options.go67
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/reedsolomon.go596
-rw-r--r--irc/kcpd/vendor/github.com/klauspost/reedsolomon/streaming.go575
-rw-r--r--irc/kcpd/vendor/github.com/pkg/errors/errors.go269
-rw-r--r--irc/kcpd/vendor/github.com/pkg/errors/stack.go178
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/kcp-go/crypt.go263
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/kcp-go/fec.go303
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/kcp-go/kcp.go1007
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/kcp-go/sess.go937
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/kcp-go/snmp.go164
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/kcp-go/updater.go107
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/kcp-go/xor.go110
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/smux/frame.go60
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/smux/mux.go80
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/smux/session.go334
-rw-r--r--irc/kcpd/vendor/github.com/xtaci/smux/stream.go261
32 files changed, 8374 insertions, 0 deletions
diff --git a/irc/kcpd/vendor/github.com/caarlos0/env/env.go b/irc/kcpd/vendor/github.com/caarlos0/env/env.go
new file mode 100644
index 0000000..25e5117
--- /dev/null
+++ b/irc/kcpd/vendor/github.com/caarlos0/env/env.go
@@ -0,0 +1,275 @@
+package env
+
+import (
+ "errors"
+ "os"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var (
+ // ErrNotAStructPtr is returned if you pass something that is not a pointer to a
+ // Struct to Parse
+ ErrNotAStructPtr = errors.New("Expected a pointer to a Struct")
+ // ErrUnsupportedType if the struct field type is not supported by env
+ ErrUnsupportedType = errors.New("Type is not supported")
+ // ErrUnsupportedSliceType if the slice element type is not supported by env
+ ErrUnsupportedSliceType = errors.New("Unsupported slice type")
+ // Friendly names for reflect types
+ sliceOfInts = reflect.TypeOf([]int(nil))
+ sliceOfInt64s = reflect.TypeOf([]int64(nil))
+ sliceOfStrings = reflect.TypeOf([]string(nil))
+ sliceOfBools = reflect.TypeOf([]bool(nil))
+ sliceOfFloat32s = reflect.TypeOf([]float32(nil))
+ sliceOfFloat64s = reflect.TypeOf([]float64(nil))
+)
+
+// Parse parses a struct containing `env` tags and loads its values from
+// environment variables.
+func Parse(v interface{}) error {
+ ptrRef := reflect.ValueOf(v)
+ if ptrRef.Kind() != reflect.Ptr {
+ return ErrNotAStructPtr
+ }
+ ref := ptrRef.Elem()
+ if ref.Kind() != reflect.Struct {
+ return ErrNotAStructPtr
+ }
+ return doParse(ref)
+}
+
+func doParse(ref reflect.Value) error {
+ refType := ref.Type()
+ for i := 0; i < refType.NumField(); i++ {
+ value, err := get(refType.Field(i))
+ if err != nil {
+ return err
+ }
+ if value == "" {
+ continue
+ }
+ if err := set(ref.Field(i), refType.Field(i), value); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func get(field reflect.StructField) (string, error) {
+ var (
+ val string
+ err error
+ )
+
+ key, opts := parseKeyForOption(field.Tag.Get("env"))
+
+ defaultValue := field.Tag.Get("envDefault")
+ val = getOr(key, defaultValue)
+
+ if len(opts) > 0 {
+ for _, opt := range opts {
+ // The only option supported is "required".
+ switch opt {
+ case "":
+ break
+ case "required":
+ val, err = getRequired(key)
+ default:
+ err = errors.New("Env tag option " + opt + " not supported.")
+ }
+ }
+ }
+
+ return val, err
+}
+
+// split the env tag's key into the expected key and desired option, if any.
+func parseKeyForOption(key string) (string, []string) {
+ opts := strings.Split(key, ",")
+ return opts[0], opts[1:]
+}
+
+func getRequired(key string) (string, error) {
+ if value := os.Getenv(key); value != "" {
+ return value, nil
+ }
+ // We do not use fmt.Errorf to avoid another import.
+ return "", errors.New("Required environment variable " + key + " is not set")
+}
+
+func getOr(key, defaultValue string) string {
+ value := os.Getenv(key)
+ if value != "" {
+ return value
+ }
+ return defaultValue
+}
+
+func set(field reflect.Value, refType reflect.StructField, value string) error {
+ switch field.Kind() {
+ case reflect.Slice:
+ separator := refType.Tag.Get("envSeparator")
+ return handleSlice(field, value, separator)
+ case reflect.String:
+ field.SetString(value)
+ case reflect.Bool:
+ bvalue, err := strconv.ParseBool(value)
+ if err != nil {
+ return err
+ }
+ field.SetBool(bvalue)
+ case reflect.Int:
+ intValue, err := strconv.ParseInt(value, 10, 32)
+ if err != nil {
+ return err
+ }
+ field.SetInt(intValue)
+ case reflect.Float32:
+ v, err := strconv.ParseFloat(value, 32)
+ if err != nil {
+ return err
+ }
+ field.SetFloat(v)
+ case reflect.Float64:
+ v, err := strconv.ParseFloat(value, 64)
+ if err != nil {
+ return err
+ }
+ field.Set(reflect.ValueOf(v))
+ case reflect.Int64:
+ if refType.Type.String() == "time.Duration" {
+ dValue, err := time.ParseDuration(value)
+ if err != nil {
+ return err
+ }
+ field.Set(reflect.ValueOf(dValue))
+ } else {
+ intValue, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ return err
+ }
+ field.SetInt(intValue)
+ }
+ default:
+ return ErrUnsupportedType
+ }
+ return nil
+}
+
+func handleSlice(field reflect.Value, value, separator string) error {
+ if separator == "" {
+ separator = ","
+ }
+
+ splitData := strings.Split(value, separator)
+
+ switch field.Type() {
+ case sliceOfStrings:
+ field.Set(reflect.ValueOf(splitData))
+ case sliceOfInts:
+ intData, err := parseInts(splitData)
+ if err != nil {
+ return err
+ }
+ field.Set(reflect.ValueOf(intData))
+ case sliceOfInt64s:
+ int64Data, err := parseInt64s(splitData)
+ if err != nil {
+ return err
+ }
+ field.Set(reflect.ValueOf(int64Data))
+
+ case sliceOfFloat32s:
+ data, err := parseFloat32s(splitData)
+ if err != nil {
+ return err
+ }
+ field.Set(reflect.ValueOf(data))
+ case sliceOfFloat64s:
+ data, err := parseFloat64s(splitData)
+ if err != nil {
+ return err
+ }
+ field.Set(reflect.ValueOf(data))
+ case sliceOfBools:
+ boolData, err := parseBools(splitData)
+ if err != nil {
+ return err
+ }
+ field.Set(reflect.ValueOf(boolData))
+ default:
+ return ErrUnsupportedSliceType
+ }
+ return nil
+}
+
+func parseInts(data []string) ([]int, error) {
+ var intSlice []int
+
+ for _, v := range data {
+ intValue, err := strconv.ParseInt(v, 10, 32)
+ if err != nil {
+ return nil, err
+ }
+ intSlice = append(intSlice, int(intValue))
+ }
+ return intSlice, nil
+}
+
+
+func parseInt64s(data []string) ([]int64, error) {
+ var intSlice []int64
+
+ for _, v := range data {
+ intValue, err := strconv.ParseInt(v, 10, 64)
+ if err != nil {
+ return nil, err
+ }
+ intSlice = append(intSlice, int64(intValue))
+ }
+ return intSlice, nil
+}
+
+
+
+func parseFloat32s(data []string) ([]float32, error) {
+ var float32Slice []float32
+
+ for _, v := range data {
+ data, err := strconv.ParseFloat(v, 32)
+ if err != nil {
+ return nil, err
+ }
+ float32Slice = append(float32Slice, float32(data))
+ }
+ return float32Slice, nil
+}
+
+func parseFloat64s(data []string) ([]float64, error) {
+ var float64Slice []float64
+
+ for _, v := range data {
+ data, err := strconv.ParseFloat(v, 64)
+ if err != nil {
+ return nil, err
+ }
+ float64Slice = append(float64Slice, float64(data))
+ }
+ return float64Slice, nil
+}
+
+func parseBools(data []string) ([]bool, error) {
+ var boolSlice []bool
+
+ for _, v := range data {
+ bvalue, err := strconv.ParseBool(v)
+ if err != nil {
+ return nil, err
+ }
+
+ boolSlice = append(boolSlice, bvalue)
+ }
+ return boolSlice, nil
+}
diff --git a/irc/kcpd/vendor/github.com/joho/godotenv/autoload/autoload.go b/irc/kcpd/vendor/github.com/joho/godotenv/autoload/autoload.go
new file mode 100644
index 0000000..fbcd2bd
--- /dev/null
+++ b/irc/kcpd/vendor/github.com/joho/godotenv/autoload/autoload.go
@@ -0,0 +1,15 @@
+package autoload
+
+/*
+ You can just read the .env file on import just by doing
+
+ import _ "github.com/joho/godotenv/autoload"
+
+ And bob's your mother's brother
+*/
+
+import "github.com/joho/godotenv"
+
+func init() {
+ godotenv.Load()
+}
diff --git a/irc/kcpd/vendor/github.com/joho/godotenv/godotenv.go b/irc/kcpd/vendor/github.com/joho/godotenv/godotenv.go
new file mode 100644
index 0000000..94b2676
--- /dev/null
+++ b/irc/kcpd/vendor/github.com/joho/godotenv/godotenv.go
@@ -0,0 +1,229 @@
+// Package godotenv is a go port of the ruby dotenv library (https://github.com/bkeepers/dotenv)
+//
+// Examples/readme can be found on the github page at https://github.com/joho/godotenv
+//
+// The TL;DR is that you make a .env file that looks something like
+//
+// SOME_ENV_VAR=somevalue
+//
+// and then in your go code you can call
+//
+// godotenv.Load()
+//
+// and all the env vars declared in .env will be avaiable through os.Getenv("SOME_ENV_VAR")
+package godotenv
+
+import (
+ "bufio"
+ "errors"
+ "os"
+ "os/exec"
+ "strings"
+)
+
+// Load will read your env file(s) and load them into ENV for this process.
+//
+// Call this function as close as possible to the start of your program (ideally in main)
+//
+// If you call Load without any args it will default to loading .env in the current path
+//
+// You can otherwise tell it which files to load (there can be more than one) like
+//
+// godotenv.Load("fileone", "filetwo")
+//
+// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults
+func Load(filenames ...string) (err error) {
+ filenames = filenamesOrDefault(filenames)
+
+ for _, filename := range filenames {
+ err = loadFile(filename, false)
+ if err != nil {
+ return // return early on a spazout
+ }
+ }
+ return
+}
+
+// Overload will read your env file(s) and load them into ENV for this process.
+//
+// Call this function as close as possible to the start of your program (ideally in main)
+//
+// If you call Overload without any args it will default to loading .env in the current path
+//
+// You can otherwise tell it which files to load (there can be more than one) like
+//
+// godotenv.Overload("fileone", "filetwo")
+//
+// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars.
+func Overload(filenames ...string) (err error) {
+ filenames = filenamesOrDefault(filenames)
+
+ for _, filename := range filenames {
+ err = loadFile(filename, true)
+ if err != nil {
+ return // return early on a spazout
+ }
+ }
+ return
+}
+
+// Read all env (with same file loading semantics as Load) but return values as
+// a map rather than automatically writing values into env
+func Read(filenames ...string) (envMap map[string]string, err error) {
+ filenames = filenamesOrDefault(filenames)
+ envMap = make(map[string]string)
+
+ for _, filename := range filenames {
+ individualEnvMap, individualErr := readFile(filename)
+
+ if individualErr != nil {
+ err = individualErr
+ return // return early on a spazout
+ }
+
+ for key, value := range individualEnvMap {
+ envMap[key] = value
+ }
+ }
+
+ return
+}
+
+// Exec loads env vars from the specified filenames (empty map falls back to default)
+// then executes the cmd specified.
+//
+// Simply hooks up os.Stdin/err/out to the command and calls Run()
+//
+// If you want more fine grained control over your command it's recommended
+// that you use `Load()` or `Read()` and the `os/exec` package yourself.
+func Exec(filenames []string, cmd string, cmdArgs []string) error {
+ Load(filenames...)
+
+ command := exec.Command(cmd, cmdArgs...)
+ command.Stdin = os.Stdin
+ command.Stdout = os.Stdout
+ command.Stderr = os.Stderr
+ return command.Run()
+}
+
+func filenamesOrDefault(filenames []string) []string {
+ if len(filenames) == 0 {
+ return []string{".env"}
+ }
+ return filenames
+}
+
+func loadFile(filename string, overload bool) error {
+ envMap, err := readFile(filename)
+ if err != nil {
+ return err
+ }
+
+ for key, value := range envMap {
+ if os.Getenv(key) == "" || overload {
+ os.Setenv(key, value)
+ }
+ }
+
+ return nil
+}
+
+func readFile(filename string) (envMap map[string]string, err error) {
+ file, err := os.Open(filename)
+ if err != nil {
+ return
+ }
+ defer file.Close()
+
+ envMap = make(map[string]string)
+
+ var lines []string
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ lines = append(lines, scanner.Text())
+ }
+
+ for _, fullLine := range lines {
+ if !isIgnoredLine(fullLine) {
+ key, value, err := parseLine(fullLine)
+
+ if err == nil {
+ envMap[key] = value
+ }
+ }
+ }
+ return
+}
+
+func parseLine(line string) (key string, value string, err error) {
+ if len(line) == 0 {
+ err = errors.New("zero length string")
+ return
+ }
+
+ // ditch the comments (but keep quoted hashes)
+ if strings.Contains(line, "#") {
+ segmentsBetweenHashes := strings.Split(line, "#")
+ quotesAreOpen := false
+ var segmentsToKeep []string
+ for _, segment := range segmentsBetweenHashes {
+ if strings.Count(segment, "\"") == 1 || strings.Count(segment, "'") == 1 {
+ if quotesAreOpen {
+ quotesAreOpen = false
+ segmentsToKeep = append(segmentsToKeep, segment)
+ } else {
+ quotesAreOpen = true
+ }
+ }
+
+ if len(segmentsToKeep) == 0 || quotesAreOpen {
+ segmentsToKeep = append(segmentsToKeep, segment)
+ }
+ }
+
+ line = strings.Join(segmentsToKeep, "#")
+ }
+
+ // now split key from value
+ splitString := strings.SplitN(line, "=", 2)
+
+ if len(splitString) != 2 {
+ // try yaml mode!
+ splitString = strings.SplitN(line, ":", 2)
+ }
+
+ if len(splitString) != 2 {
+ err = errors.New("Can't separate key from value")
+ return
+ }
+
+ // Parse the key
+ key = splitString[0]
+ if strings.HasPrefix(key, "export") {
+ key = strings.TrimPrefix(key, "export")
+ }
+ key = strings.Trim(key, " ")
+
+ // Parse the value
+ value = splitString[1]
+ // trim
+ value = strings.Trim(value, " ")
+
+ // check if we've got quoted values
+ if strings.Count(value, "\"") == 2 || strings.Count(value, "'") == 2 {
+ // pull the quotes off the edges
+ value = strings.Trim(value, "\"'")
+
+ // expand quotes
+ value = strings.Replace(value, "\\\"", "\"", -1)
+ // expand newlines
+ value = strings.Replace(value, "\\n", "\n", -1)
+ }
+
+ return
+}
+
+func isIgnoredLine(line string) bool {
+ trimmedLine := strings.Trim(line, " \n\t")
+ return len(trimmedLine) == 0 || strings.HasPrefix(trimmedLine, "#")
+}
diff --git a/irc/kcpd/vendor/github.com/klauspost/cpuid/cpuid.go b/irc/kcpd/vendor/github.com/klauspost/cpuid/cpuid.go
new file mode 100644
index 0000000..9230ca5
--- /dev/null
+++ b/irc/kcpd/vendor/github.com/klauspost/cpuid/cpuid.go
@@ -0,0 +1,1022 @@
+// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
+
+// Package cpuid provides information about the CPU running the current program.
+//
+// CPU features are detected on startup, and kept for fast access through the life of the application.
+// Currently x86 / x64 (AMD64) is supported.
+//
+// You can access the CPU information by accessing the shared CPU variable of the cpuid library.
+//
+// Package home: https://github.com/klauspost/cpuid
+package cpuid
+
+import "strings"
+
+// Vendor is a representation of a CPU vendor.
+type Vendor int
+
+const (
+ Other Vendor = iota
+ Intel
+ AMD
+ VIA
+ Transmeta
+ NSC
+ KVM // Kernel-based Virtual Machine
+ MSVM // Microsoft Hyper-V or Windows Virtual PC
+ VMware
+ XenHVM
+)
+
+const (
+ CMOV = 1 << iota // i686 CMOV
+ NX // NX (No-Execute) bit
+ AMD3DNOW // AMD 3DNOW
+ AMD3DNOWEXT // AMD 3DNowExt
+ MMX // standard MMX
+ MMXEXT // SSE integer functions or AMD MMX ext
+ SSE // SSE functions
+ SSE2 // P4 SSE functions
+ SSE3 // Prescott SSE3 functions
+ SSSE3 // Conroe SSSE3 functions
+ SSE4 // Penryn SSE4.1 functions
+ SSE4A // AMD Barcelona microarchitecture SSE4a instructions
+ SSE42 // Nehalem SSE4.2 functions
+ AVX // AVX functions
+ AVX2 // AVX2 functions
+ FMA3 // Intel FMA 3
+ FMA4 // Bulldozer FMA4 functions
+ XOP // Bulldozer XOP functions
+ F16C // Half-precision floating-point conversion
+ BMI1 // Bit Manipulation Instruction Set 1
+ BMI2 // Bit Manipulation Instruction Set 2
+ TBM // AMD Trailing Bit Manipulation
+ LZCNT // LZCNT instruction
+ POPCNT // POPCNT instruction
+ AESNI // Advanced Encryption Standard New Instructions
+ CLMUL // Carry-less Multiplication
+ HTT // Hyperthreading (enabled)
+ HLE // Hardware Lock Elision
+ RTM // Restricted Transactional Memory
+ RDRAND // RDRAND instruction is available
+ RDSEED // RDSEED instruction is available
+ ADX // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
+ SHA // Intel SHA Extensions
+ AVX512F // AVX-512 Foundation
+ AVX512DQ // AVX-512 Doubleword and Quadword Instructions
+ AVX512IFMA // AVX-512 Integer Fused Multiply-Add Instructions
+ AVX512PF // AVX-512 Prefetch Instructions
+ AVX512ER // AVX-512 Exponential and Reciprocal Instructions
+ AVX512CD // AVX-512 Conflict Detection Instructions
+ AVX512BW // AVX-512 Byte and Word Instructions
+ AVX512VL // AVX-512 Vector Length Extensions
+ AVX512VBMI // AVX-512 Vector Bit Manipulation Instructions
+ MPX // Intel MPX (Memory Protection Extensions)
+ ERMS // Enhanced REP MOVSB/STOSB
+ RDTSCP // RDTSCP Instruction
+ CX16 // CMPXCHG16B Instruction
+ SGX // Software Guard Extensions
+
+ // Performance indicators
+ SSE2SLOW // SSE2 is supported, but usually not faster
+ SSE3SLOW // SSE3 is supported, but usually not faster
+ ATOM // Atom processor, some SSSE3 instructions are slower
+)
+
+var flagNames = map[Flags]string{
+ CMOV: "CMOV", // i686 CMOV
+ NX: "NX", // NX (No-Execute) bit
+ AMD3DNOW: "AMD3DNOW", // AMD 3DNOW
+ AMD3DNOWEXT: "AMD3DNOWEXT", // AMD 3DNowExt
+ MMX: "MMX", // Standard MMX
+ MMXEXT: "MMXEXT", // SSE integer functions or AMD MMX ext
+ SSE: "SSE", // SSE functions
+ SSE2: "SSE2", // P4 SSE2 functions
+ SSE3: "SSE3", // Prescott SSE3 functions
+ SSSE3: "SSSE3", // Conroe SSSE3 functions
+ SSE4: "SSE4.1", // Penryn SSE4.1 functions
+ SSE4A: "SSE4A", // AMD Barcelona microarchitecture SSE4a instructions
+ SSE42: "SSE4.2", // Nehalem SSE4.2 functions
+ AVX: "AVX", // AVX functions
+ AVX2: "AVX2", // AVX functions
+ FMA3: "FMA3", // Intel FMA 3
+ FMA4: "FMA4", // Bulldozer FMA4 functions
+ XOP: "XOP", // Bulldozer XOP functions
+ F16C: "F16C", // Half-precision floating-point conversion
+ BMI1: "BMI1", // Bit Manipulation Instruction Set 1
+ BMI2: "BMI2", // Bit Manipulation Instruction Set 2
+ TBM: "TBM", // AMD Trailing Bit Manipulation
+ LZCNT: "LZCNT", // LZCNT instruction
+ POPCNT: "POPCNT", // POPCNT instruction
+ AESNI: "AESNI", // Advanced Encryption Standard New Instructions
+ CLMUL: "CLMUL", // Carry-less Multiplication
+ HTT: "HTT", // Hyperthreading (enabled)
+ HLE: "HLE", // Hardware Lock Elision
+ RTM: "RTM", // Restricted Transactional Memory
+ RDRAND: "RDRAND", // RDRAND instruction is available
+ RDSEED: "RDSEED", // RDSEED instruction is available
+ ADX: "ADX", // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
+ SHA: "SHA", // Intel SHA Extensions
+ AVX512F: "AVX512F", // AVX-512 Foundation
+ AVX512DQ: "AVX512DQ", // AVX-512 Doubleword and Quadword Instructions
+ AVX512IFMA: "AVX512IFMA", // AVX-512 Integer Fused Multiply-Add Instructions
+ AVX512PF: "AVX512PF", // AVX-512 Prefetch Instructions
+ AVX512ER: "AVX512ER", // AVX-512 Exponential and Reciprocal Instructions
+ AVX512CD: "AVX512CD", // AVX-512 Conflict Detection Instructions
+ AVX512BW: "AVX512BW", // AVX-512 Byte and Word Instructions
+ AVX512VL: "AVX512VL", // AVX-512 Vector Length Extensions
+ AVX512VBMI: "AVX512VBMI", // AVX-512 Vector Bit Manipulation Instructions
+ MPX: "MPX", // Intel MPX (Memory Protection Extensions)
+ ERMS: "ERMS", // Enhanced REP MOVSB/STOSB
+ RDTSCP: "RDTSCP", // RDTSCP Instruction
+ CX16: "CX16", // CMPXCHG16B Instruction
+ SGX: "SGX", // Software Guard Extensions
+
+ // Performance indicators
+ SSE2SLOW: "SSE2SLOW", // SSE2 supported, but usually not faster
+ SSE3SLOW: "SSE3SLOW", // SSE3 supported, but usually not faster
+ ATOM: "ATOM", // Atom processor, some SSSE3 instructions are slower
+
+}
+
+// CPUInfo contains information about the detected system CPU.
+type CPUInfo struct {
+ BrandName string // Brand name reported by the CPU
+ VendorID Vendor // Comparable CPU vendor ID
+ Features Flags // Features of the CPU
+ PhysicalCores int // Number of physical processor cores in your CPU. Will be 0 if undetectable.
+ ThreadsPerCore int // Number of threads per physical core. Will be 1 if undetectable.
+ LogicalCores int // Number of physical cores times threads that can run on each core through the use of hyperthreading. Will be 0 if undetectable.
+ Family int // CPU family number
+ Model int // CPU model number
+ CacheLine int // Cache line size in bytes. Will be 0 if undetectable.
+ Cache struct {
+ L1I int // L1 Instruction Cache (per core or shared). Will be -1 if undetected
+ L1D int // L1 Data Cache (per core or shared). Will be -1 if undetected
+ L2 int // L2 Cache (per core or shared). Will be -1 if undetected
+ L3 int // L3 Instruction Cache (per core or shared). Will be -1 if undetected
+ }
+ SGX SGXSupport
+ maxFunc uint32
+ maxExFunc uint32
+}
+
+var cpuid func(op uint32) (eax, ebx, ecx, edx uint32)
+var cpuidex func(op, op2 uint32) (eax, ebx, ecx, edx uint32)
+var xgetbv func(index uint32) (eax, edx uint32)
+var rdtscpAsm func() (eax, ebx, ecx, edx uint32)
+
+// CPU contains information about the CPU as detected on startup,
+// or when Detect last was called.
+//
+// Use this as the primary entry point to you data,
+// this way queries are
+var CPU CPUInfo
+
+func init() {
+ initCPU()
+ Detect()
+}
+
+// Detect will re-detect current CPU info.
+// This will replace the content of the exported CPU variable.
+//
+// Unless you expect the CPU to change while you are running your program
+// you should not need to call this function.
+// If you call this, you must ensure that no other goroutine is accessing the
+// exported CPU variable.
+func Detect() {
+ CPU.maxFunc = maxFunctionID()
+ CPU.maxExFunc = maxExtendedFunction()
+ CPU.BrandName = brandName()
+ CPU.CacheLine = cacheLine()
+ CPU.Family, CPU.Model = familyModel()
+ CPU.Features = support()
+ CPU.SGX = sgx(CPU.Features&SGX != 0)
+ CPU.ThreadsPerCore = threadsPerCore()
+ CPU.LogicalCores = logicalCores()
+ CPU.PhysicalCores = physicalCores()
+ CPU.VendorID = vendorID()
+ CPU.cacheSize()
+}
+
+// Generated here: http://play.golang.org/p/BxFH2Gdc0G
+
+// Cmov indicates support of CMOV instructions
+func (c CPUInfo) Cmov() bool {
+ return c.Features&CMOV != 0
+}
+
+// Amd3dnow indicates support of AMD 3DNOW! instructions
+func (c CPUInfo) Amd3dnow() bool {
+ return c.Features&AMD3DNOW != 0
+}
+
+// Amd3dnowExt indicates support of AMD 3DNOW! Extended instructions
+func (c CPUInfo) Amd3dnowExt() bool {
+ return c.Features&AMD3DNOWEXT != 0
+}
+
+// MMX indicates support of MMX instructions
+func (c CPUInfo) MMX() bool {
+ return c.Features&MMX != 0
+}
+
+// MMXExt indicates support of MMXEXT instructions
+// (SSE integer functions or AMD MMX ext)
+func (c CPUInfo) MMXExt() bool {
+ return c.Features&MMXEXT != 0
+}
+
+// SSE indicates support of SSE instructions
+func (c CPUInfo) SSE() bool {
+ return c.Features&SSE != 0
+}
+
+// SSE2 indicates support of SSE 2 instructions
+func (c CPUInfo) SSE2() bool {
+ return c.Features&SSE2 != 0
+}
+
+// SSE3 indicates support of SSE 3 instructions
+func (c CPUInfo) SSE3() bool {
+ return c.Features&SSE3 != 0
+}
+
+// SSSE3 indicates support of SSSE 3 instructions
+func (c CPUInfo) SSSE3() bool {
+ return c.Features&SSSE3 != 0
+}
+
+// SSE4 indicates support of SSE 4 (also called SSE 4.1) instructions
+func (c CPUInfo) SSE4() bool {
+ return c.Features&SSE4 != 0
+}
+
+// SSE42 indicates support of SSE4.2 instructions
+func (c CPUInfo) SSE42() bool {
+ return c.Features&SSE42 != 0
+}
+
+// AVX indicates support of AVX instructions
+// and operating system support of AVX instructions
+func (c CPUInfo) AVX() bool {
+ return c.Features&AVX != 0
+}
+
+// AVX2 indicates support of AVX2 instructions
+func (c CPUInfo) AVX2() bool {
+ return c.Features&AVX2 != 0
+}
+
+// FMA3 indicates support of FMA3 instructions
+func (c CPUInfo) FMA3() bool {
+ return c.Features&FMA3 != 0
+}
+
+// FMA4 indicates support of FMA4 instructions
+func (c CPUInfo) FMA4() bool {
+ return c.Features&FMA4 != 0
+}
+
+// XOP indicates support of XOP instructions
+func (c CPUInfo) XOP() bool {
+ return c.Features&XOP != 0
+}
+
+// F16C indicates support of F16C instructions
+func (c CPUInfo) F16C() bool {
+ return c.Features&F16C != 0
+}
+
+// BMI1 indicates support of BMI1 instructions
+func (c CPUInfo) BMI1() bool {
+ return c.Features&BMI1 != 0
+}
+