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