1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package repl
18
19 import (
20 `fmt`
21
22 `github.com/klauspost/cpuid/v2`
23 )
24
25 type _RegFileAMD64 struct {
26 rax uint64
27 rbx uint64
28 rcx uint64
29 rdx uint64
30 rdi uint64
31 rsi uint64
32 rbp uint64
33 rsp uint64
34 r8 uint64
35 r9 uint64
36 r10 uint64
37 r11 uint64
38 r12 uint64
39 r13 uint64
40 r14 uint64
41 r15 uint64
42 rip uint64
43 rflags uint64
44 cs uint16
45 _ [6]byte
46 fs uint16
47 _ [6]byte
48 gs uint16
49 _ [30]byte
50 xmm [32][16]byte
51 ymm [32][32]byte
52 zmm [32][64]byte
53 k [8]uint64
54 }
55
56 var (
57 hasAVX = cpuid.CPU.Has(cpuid.AVX)
58 hasAVX512F = cpuid.CPU.Has(cpuid.AVX512F)
59 hasAVX512BW = cpuid.CPU.Has(cpuid.AVX512BW)
60 hasAVX512VL = cpuid.CPU.Has(cpuid.AVX512VL)
61 )
62
63
64
65
66 func dumpregs(regs *_RegFileAMD64)
67
68 func (self *_RegFileAMD64) Dump(indent int) []_Reg {
69 dumpregs(self)
70 return self.format(indent)
71 }
72
73 func (self *_RegFileAMD64) Compare(other _RegFile, indent int) (v []_Reg) {
74 var ok bool
75 var rf *_RegFileAMD64
76
77
78 if rf, ok = other.(*_RegFileAMD64); !ok {
79 panic("can only compare with AMD64 register file")
80 }
81
82
84 if self.rax != rf.rax { v = append(v, _Reg{"rax" , fmt.Sprintf("%#016x -> %#016x", self.rax , rf.rax ), false}) }
85 if self.rbx != rf.rbx { v = append(v, _Reg{"rbx" , fmt.Sprintf("%#016x -> %#016x", self.rbx , rf.rbx ), false}) }
86 if self.rcx != rf.rcx { v = append(v, _Reg{"rcx" , fmt.Sprintf("%#016x -> %#016x", self.rcx , rf.rcx ), false}) }
87 if self.rdx != rf.rdx { v = append(v, _Reg{"rdx" , fmt.Sprintf("%#016x -> %#016x", self.rdx , rf.rdx ), false}) }
88 if self.rdi != rf.rdi { v = append(v, _Reg{"rdi" , fmt.Sprintf("%#016x -> %#016x", self.rdi , rf.rdi ), false}) }
89 if self.rsi != rf.rsi { v = append(v, _Reg{"rsi" , fmt.Sprintf("%#016x -> %#016x", self.rsi , rf.rsi ), false}) }
90 if self.rbp != rf.rbp { v = append(v, _Reg{"rbp" , fmt.Sprintf("%#016x -> %#016x", self.rbp , rf.rbp ), false}) }
91 if self.rsp != rf.rsp { v = append(v, _Reg{"rsp" , fmt.Sprintf("%#016x -> %#016x", self.rsp , rf.rsp ), false}) }
92 if self.r8 != rf.r8 { v = append(v, _Reg{"r8" , fmt.Sprintf("%#016x -> %#016x", self.r8 , rf.r8 ), false}) }
93 if self.r9 != rf.r9 { v = append(v, _Reg{"r9" , fmt.Sprintf("%#016x -> %#016x", self.r9 , rf.r9 ), false}) }
94 if self.r10 != rf.r10 { v = append(v, _Reg{"r10" , fmt.Sprintf("%#016x -> %#016x", self.r10 , rf.r10 ), false}) }
95 if self.r11 != rf.r11 { v = append(v, _Reg{"r11" , fmt.Sprintf("%#016x -> %#016x", self.r11 , rf.r11 ), false}) }
96 if self.r12 != rf.r12 { v = append(v, _Reg{"r12" , fmt.Sprintf("%#016x -> %#016x", self.r12 , rf.r12 ), false}) }
97 if self.r13 != rf.r13 { v = append(v, _Reg{"r13" , fmt.Sprintf("%#016x -> %#016x", self.r13 , rf.r13 ), false}) }
98 if self.r14 != rf.r14 { v = append(v, _Reg{"r14" , fmt.Sprintf("%#016x -> %#016x", self.r14 , rf.r14 ), false}) }
99 if self.r15 != rf.r15 { v = append(v, _Reg{"r15" , fmt.Sprintf("%#016x -> %#016x", self.r15 , rf.r15 ), false}) }
100 if self.rflags != rf.rflags { v = append(v, _Reg{"rflags", fmt.Sprintf("%#016x -> %#016x", self.rflags, rf.rflags), false}) }
101 if self.cs != rf.cs { v = append(v, _Reg{"cs" , fmt.Sprintf("%#04x -> %#04x" , self.cs , rf.cs ), false}) }
102 if self.fs != rf.fs { v = append(v, _Reg{"fs" , fmt.Sprintf("%#04x -> %#04x" , self.fs , rf.fs ), false}) }
103 if self.gs != rf.gs { v = append(v, _Reg{"gs" , fmt.Sprintf("%#04x -> %#04x" , self.gs , rf.gs ), false}) }
104
105
106 self.compareXmmStd(&v, rf, indent)
107 self.compareXmmExt(&v, rf, indent)
108 self.compareYmmStd(&v, rf, indent)
109 self.compareYmmExt(&v, rf, indent)
110 self.compareZmmAll(&v, rf, indent)
111 self.compareMaskQW(&v, rf)
112 return v
113 }
114
115 func (self *_RegFileAMD64) format(indent int) (v []_Reg) {
116 v = []_Reg {
117 { "rax" , fmt.Sprintf("%#016x %s", self.rax, symbol(self.rax)), false },
118 { "rbx" , fmt.Sprintf("%#016x %s", self.rbx, symbol(self.rbx)), false },
119 { "rcx" , fmt.Sprintf("%#016x %s", self.rcx, symbol(self.rcx)), false },
120 { "rdx" , fmt.Sprintf("%#016x %s", self.rdx, symbol(self.rdx)), false },
121 { "rdi" , fmt.Sprintf("%#016x %s", self.rdi, symbol(self.rdi)), false },
122 { "rsi" , fmt.Sprintf("%#016x %s", self.rsi, symbol(self.rsi)), false },
123 { "rbp" , fmt.Sprintf("%#016x %s", self.rbp, symbol(self.rbp)), false },
124 { "rsp" , fmt.Sprintf("%#016x %s", self.rsp, symbol(self.rsp)), false },
125 { "r8" , fmt.Sprintf("%#016x %s", self.r8 , symbol(self.r8 )), false },
126 { "r9" , fmt.Sprintf("%#016x %s", self.r9 , symbol(self.r9 )), false },
127 { "r10" , fmt.Sprintf("%#016x %s", self.r10, symbol(self.r10)), false },
128 { "r11" , fmt.Sprintf("%#016x %s", self.r11, symbol(self.r11)), false },
129 { "r12" , fmt.Sprintf("%#016x %s", self.r12, symbol(self.r12)), false },
130 { "r13" , fmt.Sprintf("%#016x %s", self.r13, symbol(self.r13)), false },
131 { "r14" , fmt.Sprintf("%#016x %s", self.r14, symbol(self.r14)), false },
132 { "r15" , fmt.Sprintf("%#016x %s", self.r15, symbol(self.r15)), false },
133 { "rip" , fmt.Sprintf("%#016x %s", self.rip, symbol(self.rip)), false },
134 { "rflags", fmt.Sprintf("%#016x" , self.rflags) , false },
135 { "cs" , fmt.Sprintf("%#04x" , self.cs) , false },
136 { "fs" , fmt.Sprintf("%#04x" , self.fs) , false },
137 { "gs" , fmt.Sprintf("%#04x" , self.gs) , false },
138 }
139
140
141 self.formatXmmStd(&v, indent)
142 self.formatXmmExt(&v, indent)
143 self.formatYmmStd(&v, indent)
144 self.formatYmmExt(&v, indent)
145 self.formatZmmAll(&v, indent)
146 self.formatMaskQW(&v)
147 return
148 }
149
150 func (self *_RegFileAMD64) formatXmmStd(v *[]_Reg, indent int) {
151 for i := 0; i < 16; i++ {
152 *v = append(*v, _Reg {
153 reg: fmt.Sprintf("xmm%d", i),
154 val: vector(self.xmm[i][:], indent),
155 vec: true,
156 })
157 }
158 }
159
160 func (self *_RegFileAMD64) formatXmmExt(v *[]_Reg, indent int) {
161 if hasAVX512VL {
162 for i := 16; i < 32; i++ {
163 *v = append(*v, _Reg {
164 reg: fmt.Sprintf("xmm%d", i),
165 val: vector(self.xmm[i][:], indent),
166 vec: true,
167 })
168 }
169 }
170 }
171
172 func (self *_RegFileAMD64) formatYmmStd(v *[]_Reg, indent int) {
173 if hasAVX {
174 for i := 0; i < 16; i++ {
175 *v = append(*v, _Reg {
176 reg: fmt.Sprintf("ymm%d", i),
177 val: vector(self.ymm[i][:], indent),
178 vec: true,
179 })
180 }
181 }
182 }
183
184 func (self *_RegFileAMD64) formatYmmExt(v *[]_Reg, indent int) {
185 if hasAVX512VL {
186 for i := 16; i < 32; i++ {
187 *v = append(*v, _Reg {
188 reg: fmt.Sprintf("ymm%d", i),
189 val: vector(self.ymm[i][:], indent),
190 vec: true,
191 })
192 }
193 }
194 }
195
196 func (self *_RegFileAMD64) formatZmmAll(v *[]_Reg, indent int) {
197 if hasAVX512F {
198 for i := 0; i < 32; i++ {
199 *v = append(*v, _Reg {
200 reg: fmt.Sprintf("zmm%d", i),
201 val: vector(self.zmm[i][:], indent),
202 vec: true,
203 })
204 }
205 }
206 }
207
208 func (self *_RegFileAMD64) formatMaskQW(v *[]_Reg) {
209 if hasAVX512BW {
210 for i := 0; i < 8; i++ {
211 *v = append(*v, _Reg {
212 reg: fmt.Sprintf("k%d", i),
213 val: fmt.Sprintf("%#016x", self.k[i]),
214 vec: true,
215 })
216 }
217 } else if hasAVX512F {
218 for i := 0; i < 8; i++ {
219 *v = append(*v, _Reg {
220 reg: fmt.Sprintf("k%d", i),
221 val: fmt.Sprintf("%#04x", self.k[i]),
222 vec: true,
223 })
224 }
225 }
226 }
227
228 func (self *_RegFileAMD64) compareXmmStd(v *[]_Reg, rf *_RegFileAMD64, indent int) {
229 for i := 0; i < 16; i++ {
230 if self.xmm[i] != rf.xmm[i] {
231 *v = append(*v, _Reg {
232 reg: fmt.Sprintf("xmm%d", i),
233 val: vecdiff(self.xmm[i][:], rf.xmm[i][:], indent),
234 vec: true,
235 })
236 }
237 }
238 }
239
240 func (self *_RegFileAMD64) compareXmmExt(v *[]_Reg, rf *_RegFileAMD64, indent int) {
241 if hasAVX512VL {
242 for i := 16; i < 32; i++ {
243 if self.xmm[i] != rf.xmm[i] {
244 *v = append(*v, _Reg {
245 reg: fmt.Sprintf("xmm%d", i),
246 val: vecdiff(self.xmm[i][:], rf.xmm[i][:], indent),
247 vec: true,
248 })
249 }
250 }
251 }
252 }
253
254 func (self *_RegFileAMD64) compareYmmStd(v *[]_Reg, rf *_RegFileAMD64, indent int) {
255 if hasAVX {
256 for i := 0; i < 16; i++ {
257 if self.ymm[i] != rf.ymm[i] {
258 *v = append(*v, _Reg {
259 reg: fmt.Sprintf("ymm%d", i),
260 val: vecdiff(self.ymm[i][:], rf.ymm[i][:], indent),
261 vec: true,
262 })
263 }
264 }
265 }
266 }
267
268 func (self *_RegFileAMD64) compareYmmExt(v *[]_Reg, rf *_RegFileAMD64, indent int) {
269 if hasAVX512VL {
270 for i := 16; i < 32; i++ {
271 if self.ymm[i] != rf.ymm[i] {
272 *v = append(*v, _Reg {
273 reg: fmt.Sprintf("ymm%d", i),
274 val: vecdiff(self.ymm[i][:], rf.ymm[i][:], indent),
275 vec: true,
276 })
277 }
278 }
279 }
280 }
281
282 func (self *_RegFileAMD64) compareZmmAll(v *[]_Reg, rf *_RegFileAMD64, indent int) {
283 if hasAVX512F {
284 for i := 0; i < 32; i++ {
285 if self.zmm[i] != rf.zmm[i] {
286 *v = append(*v, _Reg {
287 reg: fmt.Sprintf("zmm%d", i),
288 val: vecdiff(self.zmm[i][:], rf.zmm[i][:], indent),
289 vec: true,
290 })
291 }
292 }
293 }
294 }
295
296 func (self *_RegFileAMD64) compareMaskQW(v *[]_Reg, rf *_RegFileAMD64) {
297 if hasAVX512BW {
298 for i := 0; i < 8; i++ {
299 if self.k[i] != rf.k[i] {
300 *v = append(*v, _Reg {
301 reg: fmt.Sprintf("k%d", i),
302 val: fmt.Sprintf("%#016x -> %#016x", self.k[i], rf.k[i]),
303 vec: true,
304 })
305 }
306 }
307 } else if hasAVX512F {
308 for i := 0; i < 8; i++ {
309 if self.k[i] != rf.k[i] {
310 *v = append(*v, _Reg {
311 reg: fmt.Sprintf("k%d", i),
312 val: fmt.Sprintf("%#04x -> %#04x", self.k[i], rf.k[i]),
313 vec: true,
314 })
315 }
316 }
317 }
318 }
319
320 func init() {
321 _regs = new(_RegFileAMD64)
322 }
323
View as plain text