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