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