arch.go raw

   1  //
   2  // Copyright 2024 CloudWeGo Authors
   3  //
   4  // Licensed under the Apache License, Version 2.0 (the "License");
   5  // you may not use this file except in compliance with the License.
   6  // You may obtain a copy of the License at
   7  //
   8  //     http://www.apache.org/licenses/LICENSE-2.0
   9  //
  10  // Unless required by applicable law or agreed to in writing, software
  11  // distributed under the License is distributed on an "AS IS" BASIS,
  12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13  // See the License for the specific language governing permissions and
  14  // limitations under the License.
  15  //
  16  
  17  package x86_64
  18  
  19  import (
  20  	"fmt"
  21  )
  22  
  23  // ISA represents an extension to x86-64 instruction set.
  24  type ISA uint64
  25  
  26  const (
  27  	ISA_CPUID ISA = 1 << iota
  28  	ISA_RDTSC
  29  	ISA_RDTSCP
  30  	ISA_CMOV
  31  	ISA_MOVBE
  32  	ISA_POPCNT
  33  	ISA_LZCNT
  34  	ISA_TBM
  35  	ISA_BMI
  36  	ISA_BMI2
  37  	ISA_ADX
  38  	ISA_MMX
  39  	ISA_MMX_PLUS
  40  	ISA_FEMMS
  41  	ISA_3DNOW
  42  	ISA_3DNOW_PLUS
  43  	ISA_SSE
  44  	ISA_SSE2
  45  	ISA_SSE3
  46  	ISA_SSSE3
  47  	ISA_SSE4A
  48  	ISA_SSE4_1
  49  	ISA_SSE4_2
  50  	ISA_FMA3
  51  	ISA_FMA4
  52  	ISA_XOP
  53  	ISA_F16C
  54  	ISA_AVX
  55  	ISA_AVX2
  56  	ISA_AVX512F
  57  	ISA_AVX512BW
  58  	ISA_AVX512DQ
  59  	ISA_AVX512VL
  60  	ISA_AVX512PF
  61  	ISA_AVX512ER
  62  	ISA_AVX512CD
  63  	ISA_AVX512VBMI
  64  	ISA_AVX512IFMA
  65  	ISA_AVX512VPOPCNTDQ
  66  	ISA_AVX512_4VNNIW
  67  	ISA_AVX512_4FMAPS
  68  	ISA_PREFETCH
  69  	ISA_PREFETCHW
  70  	ISA_PREFETCHWT1
  71  	ISA_CLFLUSH
  72  	ISA_CLFLUSHOPT
  73  	ISA_CLWB
  74  	ISA_CLZERO
  75  	ISA_RDRAND
  76  	ISA_RDSEED
  77  	ISA_PCLMULQDQ
  78  	ISA_AES
  79  	ISA_SHA
  80  	ISA_MONITOR
  81  	ISA_MONITORX
  82  	ISA_ALL = ^ISA(0)
  83  )
  84  
  85  var _ISA_NAMES = map[ISA]string{
  86  	ISA_CPUID:           "CPUID",
  87  	ISA_RDTSC:           "RDTSC",
  88  	ISA_RDTSCP:          "RDTSCP",
  89  	ISA_CMOV:            "CMOV",
  90  	ISA_MOVBE:           "MOVBE",
  91  	ISA_POPCNT:          "POPCNT",
  92  	ISA_LZCNT:           "LZCNT",
  93  	ISA_TBM:             "TBM",
  94  	ISA_BMI:             "BMI",
  95  	ISA_BMI2:            "BMI2",
  96  	ISA_ADX:             "ADX",
  97  	ISA_MMX:             "MMX",
  98  	ISA_MMX_PLUS:        "MMX+",
  99  	ISA_FEMMS:           "FEMMS",
 100  	ISA_3DNOW:           "3dnow!",
 101  	ISA_3DNOW_PLUS:      "3dnow!+",
 102  	ISA_SSE:             "SSE",
 103  	ISA_SSE2:            "SSE2",
 104  	ISA_SSE3:            "SSE3",
 105  	ISA_SSSE3:           "SSSE3",
 106  	ISA_SSE4A:           "SSE4A",
 107  	ISA_SSE4_1:          "SSE4.1",
 108  	ISA_SSE4_2:          "SSE4.2",
 109  	ISA_FMA3:            "FMA3",
 110  	ISA_FMA4:            "FMA4",
 111  	ISA_XOP:             "XOP",
 112  	ISA_F16C:            "F16C",
 113  	ISA_AVX:             "AVX",
 114  	ISA_AVX2:            "AVX2",
 115  	ISA_AVX512F:         "AVX512F",
 116  	ISA_AVX512BW:        "AVX512BW",
 117  	ISA_AVX512DQ:        "AVX512DQ",
 118  	ISA_AVX512VL:        "AVX512VL",
 119  	ISA_AVX512PF:        "AVX512PF",
 120  	ISA_AVX512ER:        "AVX512ER",
 121  	ISA_AVX512CD:        "AVX512CD",
 122  	ISA_AVX512VBMI:      "AVX512VBMI",
 123  	ISA_AVX512IFMA:      "AVX512IFMA",
 124  	ISA_AVX512VPOPCNTDQ: "AVX512VPOPCNTDQ",
 125  	ISA_AVX512_4VNNIW:   "AVX512_4VNNIW",
 126  	ISA_AVX512_4FMAPS:   "AVX512_4FMAPS",
 127  	ISA_PREFETCH:        "PREFETCH",
 128  	ISA_PREFETCHW:       "PREFETCHW",
 129  	ISA_PREFETCHWT1:     "PREFETCHWT1",
 130  	ISA_CLFLUSH:         "CLFLUSH",
 131  	ISA_CLFLUSHOPT:      "CLFLUSHOPT",
 132  	ISA_CLWB:            "CLWB",
 133  	ISA_CLZERO:          "CLZERO",
 134  	ISA_RDRAND:          "RDRAND",
 135  	ISA_RDSEED:          "RDSEED",
 136  	ISA_PCLMULQDQ:       "PCLMULQDQ",
 137  	ISA_AES:             "AES",
 138  	ISA_SHA:             "SHA",
 139  	ISA_MONITOR:         "MONITOR",
 140  	ISA_MONITORX:        "MONITORX",
 141  }
 142  
 143  var _ISA_MAPPING = map[string]ISA{
 144  	"CPUID":           ISA_CPUID,
 145  	"RDTSC":           ISA_RDTSC,
 146  	"RDTSCP":          ISA_RDTSCP,
 147  	"CMOV":            ISA_CMOV,
 148  	"MOVBE":           ISA_MOVBE,
 149  	"POPCNT":          ISA_POPCNT,
 150  	"LZCNT":           ISA_LZCNT,
 151  	"TBM":             ISA_TBM,
 152  	"BMI":             ISA_BMI,
 153  	"BMI2":            ISA_BMI2,
 154  	"ADX":             ISA_ADX,
 155  	"MMX":             ISA_MMX,
 156  	"MMX+":            ISA_MMX_PLUS,
 157  	"FEMMS":           ISA_FEMMS,
 158  	"3dnow!":          ISA_3DNOW,
 159  	"3dnow!+":         ISA_3DNOW_PLUS,
 160  	"SSE":             ISA_SSE,
 161  	"SSE2":            ISA_SSE2,
 162  	"SSE3":            ISA_SSE3,
 163  	"SSSE3":           ISA_SSSE3,
 164  	"SSE4A":           ISA_SSE4A,
 165  	"SSE4.1":          ISA_SSE4_1,
 166  	"SSE4.2":          ISA_SSE4_2,
 167  	"FMA3":            ISA_FMA3,
 168  	"FMA4":            ISA_FMA4,
 169  	"XOP":             ISA_XOP,
 170  	"F16C":            ISA_F16C,
 171  	"AVX":             ISA_AVX,
 172  	"AVX2":            ISA_AVX2,
 173  	"AVX512F":         ISA_AVX512F,
 174  	"AVX512BW":        ISA_AVX512BW,
 175  	"AVX512DQ":        ISA_AVX512DQ,
 176  	"AVX512VL":        ISA_AVX512VL,
 177  	"AVX512PF":        ISA_AVX512PF,
 178  	"AVX512ER":        ISA_AVX512ER,
 179  	"AVX512CD":        ISA_AVX512CD,
 180  	"AVX512VBMI":      ISA_AVX512VBMI,
 181  	"AVX512IFMA":      ISA_AVX512IFMA,
 182  	"AVX512VPOPCNTDQ": ISA_AVX512VPOPCNTDQ,
 183  	"AVX512_4VNNIW":   ISA_AVX512_4VNNIW,
 184  	"AVX512_4FMAPS":   ISA_AVX512_4FMAPS,
 185  	"PREFETCH":        ISA_PREFETCH,
 186  	"PREFETCHW":       ISA_PREFETCHW,
 187  	"PREFETCHWT1":     ISA_PREFETCHWT1,
 188  	"CLFLUSH":         ISA_CLFLUSH,
 189  	"CLFLUSHOPT":      ISA_CLFLUSHOPT,
 190  	"CLWB":            ISA_CLWB,
 191  	"CLZERO":          ISA_CLZERO,
 192  	"RDRAND":          ISA_RDRAND,
 193  	"RDSEED":          ISA_RDSEED,
 194  	"PCLMULQDQ":       ISA_PCLMULQDQ,
 195  	"AES":             ISA_AES,
 196  	"SHA":             ISA_SHA,
 197  	"MONITOR":         ISA_MONITOR,
 198  	"MONITORX":        ISA_MONITORX,
 199  }
 200  
 201  func (self ISA) String() string {
 202  	if v, ok := _ISA_NAMES[self]; ok {
 203  		return v
 204  	} else {
 205  		return fmt.Sprintf("(invalid: %#x)", uint64(self))
 206  	}
 207  }
 208  
 209  // ParseISA parses name into ISA, it will panic if the name is invalid.
 210  func ParseISA(name string) ISA {
 211  	if v, ok := _ISA_MAPPING[name]; ok {
 212  		return v
 213  	} else {
 214  		panic("invalid ISA name: " + name)
 215  	}
 216  }
 217  
 218  // Arch represents the x86_64 architecture.
 219  type Arch struct {
 220  	isa ISA
 221  }
 222  
 223  // DefaultArch is the default architecture with all ISA enabled.
 224  var DefaultArch = CreateArch()
 225  
 226  // CreateArch creates a new Arch with all ISA enabled.
 227  func CreateArch() *Arch {
 228  	return new(Arch).EnableISA(ISA_ALL)
 229  }
 230  
 231  // HasISA checks if a particular ISA was enabled.
 232  func (self *Arch) HasISA(isa ISA) bool {
 233  	return (self.isa & isa) != 0
 234  }
 235  
 236  // EnableISA enables a particular ISA.
 237  func (self *Arch) EnableISA(isa ISA) *Arch {
 238  	self.isa |= isa
 239  	return self
 240  }
 241  
 242  // DisableISA disables a particular ISA.
 243  func (self *Arch) DisableISA(isa ISA) *Arch {
 244  	self.isa &^= isa
 245  	return self
 246  }
 247  
 248  // CreateProgram creates a new empty program.
 249  func (self *Arch) CreateProgram() *Program {
 250  	return newProgram(self)
 251  }
 252