github.com/chenzhuoyu/iasm@v0.9.1/repl/regs_amd64.go (about) 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 //go:nosplit 48 //go:noescape 49 //goland:noinspection GoUnusedParameter 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 /* must be an AMD64 register file */ 62 if rf, ok = other.(*_RegFileAMD64); !ok { 63 panic("can only compare with AMD64 register file") 64 } 65 66 /* compare generic registers, %rip is always going 67 * to change, so ignore this in the comparison result */ 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 /* compare vector registers */ 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 /* add the vector registers */ 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 }