arch.go 6.7 KB

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