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  }