github.com/chenzhuoyu/iasm@v0.9.1/x86_64/encodings.go (about)

     1  package x86_64
     2  
     3  import (
     4      `encoding/binary`
     5      `math`
     6  )
     7  
     8  /** Operand Encoding Helpers **/
     9  
    10  func imml(v interface{}) byte {
    11      return byte(toImmAny(v) & 0x0f)
    12  }
    13  
    14  func relv(v interface{}) int64 {
    15      switch r := v.(type) {
    16          case *Label         : return 0
    17          case RelativeOffset : return int64(r)
    18          default             : panic("invalid relative offset")
    19      }
    20  }
    21  
    22  func addr(v interface{}) interface{} {
    23      switch a := v.(*MemoryOperand).Addr; a.Type {
    24          case Memory    : return a.Memory
    25          case Offset    : return a.Offset
    26          case Reference : return a.Reference
    27          default        : panic("invalid memory operand type")
    28      }
    29  }
    30  
    31  func bcode(v interface{}) byte {
    32      if m, ok := v.(*MemoryOperand); !ok {
    33          panic("v is not a memory operand")
    34      } else if m.Broadcast == 0 {
    35          return 0
    36      } else {
    37          return 1
    38      }
    39  }
    40  
    41  func vcode(v interface{}) byte {
    42      switch r := v.(type) {
    43          case XMMRegister    : return byte(r)
    44          case YMMRegister    : return byte(r)
    45          case ZMMRegister    : return byte(r)
    46          case MaskedRegister : return vcode(r.Reg)
    47          default             : panic("v is not a vector register")
    48      }
    49  }
    50  
    51  func kcode(v interface{}) byte {
    52      switch r := v.(type) {
    53          case KRegister      : return byte(r)
    54          case XMMRegister    : return 0
    55          case YMMRegister    : return 0
    56          case ZMMRegister    : return 0
    57          case RegisterMask   : return byte(r.K)
    58          case MaskedRegister : return byte(r.Mask.K)
    59          case *MemoryOperand : return toKcodeMem(r)
    60          default             : panic("v is not a maskable operand")
    61      }
    62  }
    63  
    64  func zcode(v interface{}) byte {
    65      switch r := v.(type) {
    66          case KRegister      : return 0
    67          case XMMRegister    : return 0
    68          case YMMRegister    : return 0
    69          case ZMMRegister    : return 0
    70          case RegisterMask   : return toZcodeRegM(r)
    71          case MaskedRegister : return toZcodeRegM(r.Mask)
    72          case *MemoryOperand : return toZcodeMem(r)
    73          default             : panic("v is not a maskable operand")
    74      }
    75  }
    76  
    77  func lcode(v interface{}) byte {
    78      switch r := v.(type) {
    79          case Register8      : return byte(r & 0x07)
    80          case Register16     : return byte(r & 0x07)
    81          case Register32     : return byte(r & 0x07)
    82          case Register64     : return byte(r & 0x07)
    83          case KRegister      : return byte(r & 0x07)
    84          case MMRegister     : return byte(r & 0x07)
    85          case XMMRegister    : return byte(r & 0x07)
    86          case YMMRegister    : return byte(r & 0x07)
    87          case ZMMRegister    : return byte(r & 0x07)
    88          case MaskedRegister : return lcode(r.Reg)
    89          default             : panic("v is not a register")
    90      }
    91  }
    92  
    93  func hcode(v interface{}) byte {
    94      switch r := v.(type) {
    95          case Register8      : return byte(r >> 3) & 1
    96          case Register16     : return byte(r >> 3) & 1
    97          case Register32     : return byte(r >> 3) & 1
    98          case Register64     : return byte(r >> 3) & 1
    99          case KRegister      : return byte(r >> 3) & 1
   100          case MMRegister     : return byte(r >> 3) & 1
   101          case XMMRegister    : return byte(r >> 3) & 1
   102          case YMMRegister    : return byte(r >> 3) & 1
   103          case ZMMRegister    : return byte(r >> 3) & 1
   104          case MaskedRegister : return hcode(r.Reg)
   105          default             : panic("v is not a register")
   106      }
   107  }
   108  
   109  func ecode(v interface{}) byte {
   110      switch r := v.(type) {
   111          case Register8      : return byte(r >> 4) & 1
   112          case Register16     : return byte(r >> 4) & 1
   113          case Register32     : return byte(r >> 4) & 1
   114          case Register64     : return byte(r >> 4) & 1
   115          case KRegister      : return byte(r >> 4) & 1
   116          case MMRegister     : return byte(r >> 4) & 1
   117          case XMMRegister    : return byte(r >> 4) & 1
   118          case YMMRegister    : return byte(r >> 4) & 1
   119          case ZMMRegister    : return byte(r >> 4) & 1
   120          case MaskedRegister : return ecode(r.Reg)
   121          default             : panic("v is not a register")
   122      }
   123  }
   124  
   125  func hlcode(v interface{}) byte {
   126      switch r := v.(type) {
   127          case Register8      : return toHLcodeReg8(r)
   128          case Register16     : return byte(r & 0x0f)
   129          case Register32     : return byte(r & 0x0f)
   130          case Register64     : return byte(r & 0x0f)
   131          case KRegister      : return byte(r & 0x0f)
   132          case MMRegister     : return byte(r & 0x0f)
   133          case XMMRegister    : return byte(r & 0x0f)
   134          case YMMRegister    : return byte(r & 0x0f)
   135          case ZMMRegister    : return byte(r & 0x0f)
   136          case MaskedRegister : return hlcode(r.Reg)
   137          default             : panic("v is not a register")
   138      }
   139  }
   140  
   141  func ehcode(v interface{}) byte {
   142      switch r := v.(type) {
   143          case Register8      : return byte(r >> 3) & 0x03
   144          case Register16     : return byte(r >> 3) & 0x03
   145          case Register32     : return byte(r >> 3) & 0x03
   146          case Register64     : return byte(r >> 3) & 0x03
   147          case KRegister      : return byte(r >> 3) & 0x03
   148          case MMRegister     : return byte(r >> 3) & 0x03
   149          case XMMRegister    : return byte(r >> 3) & 0x03
   150          case YMMRegister    : return byte(r >> 3) & 0x03
   151          case ZMMRegister    : return byte(r >> 3) & 0x03
   152          case MaskedRegister : return ehcode(r.Reg)
   153          default             : panic("v is not a register")
   154      }
   155  }
   156  
   157  func toImmAny(v interface{}) int64 {
   158      if x, ok := asInt64(v); ok {
   159          return x
   160      } else {
   161          panic("value is not an integer")
   162      }
   163  }
   164  
   165  func toHcodeOpt(v interface{}) byte {
   166      if v == nil {
   167          return 0
   168      } else {
   169          return hcode(v)
   170      }
   171  }
   172  
   173  func toEcodeVMM(v interface{}, x byte) byte {
   174      switch r := v.(type) {
   175          case XMMRegister : return ecode(r)
   176          case YMMRegister : return ecode(r)
   177          case ZMMRegister : return ecode(r)
   178          default          : return x
   179      }
   180  }
   181  
   182  func toKcodeMem(v *MemoryOperand) byte {
   183      if !v.Masked {
   184          return 0
   185      } else {
   186          return byte(v.Mask.K)
   187      }
   188  }
   189  
   190  func toZcodeMem(v *MemoryOperand) byte {
   191      if !v.Masked || v.Mask.Z {
   192          return 0
   193      } else {
   194          return 1
   195      }
   196  }
   197  
   198  func toZcodeRegM(v RegisterMask) byte {
   199      if v.Z {
   200          return 1
   201      } else {
   202          return 0
   203      }
   204  }
   205  
   206  func toHLcodeReg8(v Register8) byte {
   207      switch v {
   208          case AH: fallthrough
   209          case BH: fallthrough
   210          case CH: fallthrough
   211          case DH: panic("ah/bh/ch/dh registers never use 4-bit encoding")
   212          default: return byte(v & 0x0f)
   213      }
   214  }
   215  
   216  /** Instruction Encoding Helpers **/
   217  
   218  const (
   219      _N_inst = 16
   220  )
   221  
   222  const (
   223      _F_rel1 = 1 << iota
   224      _F_rel4
   225  )
   226  
   227  type _Encoding struct {
   228      len     int
   229      flags   int
   230      bytes   [_N_inst]byte
   231      encoder func(m *_Encoding, v []interface{})
   232  }
   233  
   234  // buf ensures len + n <= len(bytes).
   235  func (self *_Encoding) buf(n int) []byte {
   236      if i := self.len; i + n > _N_inst {
   237          panic("instruction too long")
   238      } else {
   239          return self.bytes[i:]
   240      }
   241  }
   242  
   243  // emit encodes a single byte.
   244  func (self *_Encoding) emit(v byte) {
   245      self.buf(1)[0] = v
   246      self.len++
   247  }
   248  
   249  // imm1 encodes a single byte immediate value.
   250  func (self *_Encoding) imm1(v int64) {
   251      self.emit(byte(v))
   252  }
   253  
   254  // imm2 encodes a two-byte immediate value in little-endian.
   255  func (self *_Encoding) imm2(v int64) {
   256      binary.LittleEndian.PutUint16(self.buf(2), uint16(v))
   257      self.len += 2
   258  }
   259  
   260  // imm4 encodes a 4-byte immediate value in little-endian.
   261  func (self *_Encoding) imm4(v int64) {
   262      binary.LittleEndian.PutUint32(self.buf(4), uint32(v))
   263      self.len += 4
   264  }
   265  
   266  // imm8 encodes an 8-byte immediate value in little-endian.
   267  func (self *_Encoding) imm8(v int64) {
   268      binary.LittleEndian.PutUint64(self.buf(8), uint64(v))
   269      self.len += 8
   270  }
   271  
   272  // vex2 encodes a 2-byte or 3-byte VEX prefix.
   273  //
   274  //                          2-byte VEX prefix:
   275  // Requires: VEX.W = 0, VEX.mmmmm = 0b00001 and VEX.B = VEX.X = 0
   276  //         +----------------+
   277  // Byte 0: | Bits 0-7: 0xc5 |
   278  //         +----------------+
   279  //
   280  //         +-----------+----------------+----------+--------------+
   281  // Byte 1: | Bit 7: ~R | Bits 3-6 ~vvvv | Bit 2: L | Bits 0-1: pp |
   282  //         +-----------+----------------+----------+--------------+
   283  //
   284  //                          3-byte VEX prefix:
   285  //         +----------------+
   286  // Byte 0: | Bits 0-7: 0xc4 |
   287  //         +----------------+
   288  //
   289  //         +-----------+-----------+-----------+-------------------+
   290  // Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: 0b00001 |
   291  //         +-----------+-----------+-----------+-------------------+
   292  //
   293  //         +----------+-----------------+----------+--------------+
   294  // Byte 2: | Bit 7: 0 | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
   295  //         +----------+-----------------+----------+--------------+
   296  //
   297  func (self *_Encoding) vex2(lpp byte, r byte, rm interface{}, vvvv byte) {
   298      var b byte
   299      var x byte
   300  
   301      /* VEX.R must be a single-bit mask */
   302      if r > 1 {
   303          panic("VEX.R must be a 1-bit mask")
   304      }
   305  
   306      /* VEX.Lpp must be a 3-bit mask */
   307      if lpp &^ 0b111 != 0 {
   308          panic("VEX.Lpp must be a 3-bit mask")
   309      }
   310  
   311      /* VEX.vvvv must be a 4-bit mask */
   312      if vvvv &^ 0b1111 != 0 {
   313          panic("VEX.vvvv must be a 4-bit mask")
   314      }
   315  
   316      /* encode the RM bits if any */
   317      if rm != nil {
   318          switch v := rm.(type) {
   319              case *Label         : break
   320              case Register       : b = hcode(v)
   321              case MemoryAddress  : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
   322              case RelativeOffset : break
   323              default             : panic("rm is expected to be a register or a memory address")
   324          }
   325      }
   326  
   327      /* if VEX.B and VEX.X are zeroes, 2-byte VEX prefix can be used */
   328      if x == 0 && b == 0 {
   329          self.emit(0xc5)
   330          self.emit(0xf8 ^ (r << 7) ^ (vvvv << 3) ^ lpp)
   331      } else {
   332          self.emit(0xc4)
   333          self.emit(0xe1 ^ (r << 7) ^ (x << 6) ^ (b << 5))
   334          self.emit(0x78 ^ (vvvv << 3) ^ lpp)
   335      }
   336  }
   337  
   338  // vex3 encodes a 3-byte VEX or XOP prefix.
   339  //
   340  //                         3-byte VEX/XOP prefix
   341  //         +-----------------------------------+
   342  // Byte 0: | Bits 0-7: 0xc4 (VEX) / 0x8f (XOP) |
   343  //         +-----------------------------------+
   344  //
   345  //         +-----------+-----------+-----------+-----------------+
   346  // Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: mmmmm |
   347  //         +-----------+-----------+-----------+-----------------+
   348  //
   349  //         +----------+-----------------+----------+--------------+
   350  // Byte 2: | Bit 7: W | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
   351  //         +----------+-----------------+----------+--------------+
   352  //
   353  func (self *_Encoding) vex3(esc byte, mmmmm byte, wlpp byte, r byte, rm interface{}, vvvv byte) {
   354      var b byte
   355      var x byte
   356  
   357      /* VEX.R must be a single-bit mask */
   358      if r > 1 {
   359          panic("VEX.R must be a 1-bit mask")
   360      }
   361  
   362      /* VEX.vvvv must be a 4-bit mask */
   363      if vvvv &^ 0b1111 != 0 {
   364          panic("VEX.vvvv must be a 4-bit mask")
   365      }
   366  
   367      /* escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix */
   368      if esc != 0xc4 && esc != 0x8f {
   369          panic("escape must be a 3-byte VEX (0xc4) or XOP (0x8f) prefix")
   370      }
   371  
   372      /* VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7 */
   373      if wlpp &^ 0b10000111 != 0 {
   374          panic("VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7")
   375      }
   376  
   377      /* VEX.m-mmmm is expected to be a 5-bit mask */
   378      if mmmmm &^ 0b11111 != 0 {
   379          panic("VEX.m-mmmm is expected to be a 5-bit mask")
   380      }
   381  
   382      /* encode the RM bits */
   383      switch v := rm.(type) {
   384          case *Label         : break
   385          case MemoryAddress  : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
   386          case RelativeOffset : break
   387          default             : panic("rm is expected to be a register or a memory address")
   388      }
   389  
   390      /* encode the 3-byte VEX or XOP prefix */
   391      self.emit(esc)
   392      self.emit(0xe0 ^ (r << 7) ^ (x << 6) ^ (b << 5) ^ mmmmm)
   393      self.emit(0x78 ^ (vvvv << 3) ^ wlpp)
   394  }
   395  
   396  // evex encodes a 4-byte EVEX prefix.
   397  func (self *_Encoding) evex(mm byte, w1pp byte, ll byte, rr byte, rm interface{}, vvvvv byte, aaa byte, zz byte, bb byte) {
   398      var b byte
   399      var x byte
   400  
   401      /* EVEX.b must be a single-bit mask */
   402      if bb > 1 {
   403          panic("EVEX.b must be a 1-bit mask")
   404      }
   405  
   406      /* EVEX.z must be a single-bit mask */
   407      if zz > 1 {
   408          panic("EVEX.z must be a 1-bit mask")
   409      }
   410  
   411      /* EVEX.mm must be a 2-bit mask */
   412      if mm &^ 0b11 != 0 {
   413          panic("EVEX.mm must be a 2-bit mask")
   414      }
   415  
   416      /* EVEX.L'L must be a 2-bit mask */
   417      if ll &^ 0b11 != 0 {
   418          panic("EVEX.L'L must be a 2-bit mask")
   419      }
   420  
   421      /* EVEX.R'R must be a 2-bit mask */
   422      if rr &^ 0b11 != 0 {
   423          panic("EVEX.R'R must be a 2-bit mask")
   424      }
   425  
   426      /* EVEX.aaa must be a 3-bit mask */
   427      if aaa &^ 0b111 != 0 {
   428          panic("EVEX.aaa must be a 3-bit mask")
   429      }
   430  
   431      /* EVEX.v'vvvv must be a 5-bit mask */
   432      if vvvvv &^ 0b11111 != 0 {
   433          panic("EVEX.v'vvvv must be a 5-bit mask")
   434      }
   435  
   436      /* EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7 */
   437      if w1pp &^ 0b10000011 != 0b100 {
   438          panic("EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7")
   439      }
   440  
   441      /* extract bits from EVEX.R'R and EVEX.v'vvvv */
   442      r1, r0 := rr >> 1, rr & 1
   443      v1, v0 := vvvvv >> 4, vvvvv & 0b1111
   444  
   445      /* encode the RM bits if any */
   446      if rm != nil {
   447          switch m := rm.(type) {
   448              case *Label         : break
   449              case Register       : b, x = hcode(m), ecode(m)
   450              case MemoryAddress  : b, x, v1 = toHcodeOpt(m.Base), toHcodeOpt(m.Index), toEcodeVMM(m.Index, v1)
   451              case RelativeOffset : break
   452              default             : panic("rm is expected to be a register or a memory address")
   453          }
   454      }
   455  
   456      /* EVEX prefix bytes */
   457      p0 := (r0 << 7) | (x << 6) | (b << 5) | (r1 << 4) | mm
   458      p1 := (v0 << 3) | w1pp
   459      p2 := (zz << 7) | (ll << 5) | (b << 4) | (v1 << 3) | aaa
   460  
   461      /* p0: invert RXBR' (bits 4-7)
   462       * p1: invert vvvv  (bits 3-6)
   463       * p2: invert V'    (bit  3) */
   464      self.emit(0x62)
   465      self.emit(p0 ^ 0xf0)
   466      self.emit(p1 ^ 0x78)
   467      self.emit(p2 ^ 0x08)
   468  }
   469  
   470  // rexm encodes a mandatory REX prefix.
   471  func (self *_Encoding) rexm(w byte, r byte, rm interface{}) {
   472      var b byte
   473      var x byte
   474  
   475      /* REX.R must be 0 or 1 */
   476      if r != 0 && r != 1 {
   477          panic("REX.R must be 0 or 1")
   478      }
   479  
   480      /* REX.W must be 0 or 1 */
   481      if w != 0 && w != 1 {
   482          panic("REX.W must be 0 or 1")
   483      }
   484  
   485      /* encode the RM bits */
   486      switch v := rm.(type) {
   487          case *Label         : break
   488          case MemoryAddress  : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
   489          case RelativeOffset : break
   490          default             : panic("rm is expected to be a register or a memory address")
   491      }
   492  
   493      /* encode the REX prefix */
   494      self.emit(0x40 | (w << 3) | (r << 2) | (x << 1) | b)
   495  }
   496  
   497  // rexo encodes an optional REX prefix.
   498  func (self *_Encoding) rexo(r byte, rm interface{}, force bool) {
   499      var b byte
   500      var x byte
   501  
   502      /* REX.R must be 0 or 1 */
   503      if r != 0 && r != 1 {
   504          panic("REX.R must be 0 or 1")
   505      }
   506  
   507      /* encode the RM bits */
   508      switch v := rm.(type) {
   509          case *Label         : break
   510          case Register       : b = hcode(v)
   511          case MemoryAddress  : b, x = toHcodeOpt(v.Base), toHcodeOpt(v.Index)
   512          case RelativeOffset : break
   513          default             : panic("rm is expected to be a register or a memory address")
   514      }
   515  
   516      /* if REX.R, REX.X, and REX.B are all zeroes, REX prefix can be omitted */
   517      if force || r != 0 || x != 0 || b != 0 {
   518          self.emit(0x40 | (r << 2) | (x << 1) | b)
   519      }
   520  }
   521  
   522  // mrsd encodes ModR/M, SIB and Displacement.
   523  //
   524  //                    ModR/M byte
   525  // +----------------+---------------+---------------+
   526  // | Bits 6-7: Mode | Bits 3-5: Reg | Bits 0-2: R/M |
   527  // +----------------+---------------+---------------+
   528  //
   529  //                         SIB byte
   530  // +-----------------+-----------------+----------------+
   531  // | Bits 6-7: Scale | Bits 3-5: Index | Bits 0-2: Base |
   532  // +-----------------+-----------------+----------------+
   533  //
   534  func (self *_Encoding) mrsd(reg byte, rm interface{}, disp8v int32) {
   535      var ok bool
   536      var mm MemoryAddress
   537      var ro RelativeOffset
   538  
   539      /* ModRM encodes the lower 3-bit of the register */
   540      if reg > 7 {
   541          panic("invalid register bits")
   542      }
   543  
   544      /* check the displacement scale */
   545      switch disp8v {
   546          case  1: break
   547          case  2: break
   548          case  4: break
   549          case  8: break
   550          case 16: break
   551          case 32: break
   552          case 64: break
   553          default: panic("invalid displacement size")
   554      }
   555  
   556      /* special case: unresolved labels, assuming a zero offset */
   557      if _, ok = rm.(*Label); ok {
   558          self.emit(0x05 | (reg << 3))
   559          self.imm4(0)
   560          return
   561      }
   562  
   563      /* special case: RIP-relative offset
   564       * ModRM.Mode == 0 and ModeRM.R/M == 5 indicates (rip + disp32) addressing */
   565      if ro, ok = rm.(RelativeOffset); ok {
   566          self.emit(0x05 | (reg << 3))
   567          self.imm4(int64(ro))
   568          return
   569      }
   570  
   571      /* must be a generic memory address */
   572      if mm, ok = rm.(MemoryAddress); !ok {
   573          panic("rm must be a memory address")
   574      }
   575  
   576      /* absolute addressing, encoded as disp(%rbp,%rsp,1) */
   577      if mm.Base == nil && mm.Index == nil {
   578          self.emit(0x04 | (reg << 3))
   579          self.emit(0x25)
   580          self.imm4(int64(mm.Displacement))
   581          return
   582      }
   583  
   584      /* no SIB byte */
   585      if mm.Index == nil && lcode(mm.Base) != 0b100 {
   586          cc := lcode(mm.Base)
   587          dv := mm.Displacement
   588  
   589          /* ModRM.Mode == 0 (no displacement) */
   590          if dv == 0 && mm.Base != RBP && mm.Base != R13 {
   591              if cc == 0b101 {
   592                  panic("rbp/r13 is not encodable as a base register (interpreted as disp32 address)")
   593              } else {
   594                  self.emit((reg << 3) | cc)
   595                  return
   596              }
   597          }
   598  
   599          /* ModRM.Mode == 1 (8-bit displacement) */
   600          if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv % disp8v == 0 {
   601              self.emit(0x40 | (reg << 3) | cc)
   602              self.imm1(int64(dq))
   603              return
   604          }
   605  
   606          /* ModRM.Mode == 2 (32-bit displacement) */
   607          self.emit(0x80 | (reg << 3) | cc)
   608          self.imm4(int64(mm.Displacement))
   609          return
   610      }
   611  
   612      /* all encodings below use ModRM.R/M = 4 (0b100) to indicate the presence of SIB */
   613      if mm.Index == RSP {
   614          panic("rsp is not encodable as an index register (interpreted as no index)")
   615      }
   616  
   617      /* index = 4 (0b100) denotes no-index encoding */
   618      var scale byte
   619      var index byte = 0x04
   620  
   621      /* encode the scale byte */
   622      if mm.Scale != 0 {
   623          switch mm.Scale {
   624              case 1  : scale = 0
   625              case 2  : scale = 1
   626              case 4  : scale = 2
   627              case 8  : scale = 3
   628              default : panic("invalid scale value")
   629          }
   630      }
   631  
   632      /* encode the index byte */
   633      if mm.Index != nil {
   634          index = lcode(mm.Index)
   635      }
   636  
   637      /* SIB.Base = 5 (0b101) and ModRM.Mode = 0 indicates no-base encoding with disp32 */
   638      if mm.Base == nil {
   639          self.emit((reg << 3) | 0b100)
   640          self.emit((scale << 6) | (index << 3) | 0b101)
   641          self.imm4(int64(mm.Displacement))
   642          return
   643      }
   644  
   645      /* base L-code & displacement value */
   646      cc := lcode(mm.Base)
   647      dv := mm.Displacement
   648  
   649      /* ModRM.Mode == 0 (no displacement) */
   650      if dv == 0 && cc != 0b101 {
   651          self.emit((reg << 3) | 0b100)
   652          self.emit((scale << 6) | (index << 3) | cc)
   653          return
   654      }
   655  
   656      /* ModRM.Mode == 1 (8-bit displacement) */
   657      if dq := dv / disp8v; dq >= math.MinInt8 && dq <= math.MaxInt8 && dv % disp8v == 0 {
   658          self.emit(0x44 | (reg << 3))
   659          self.emit((scale << 6) | (index << 3) | cc)
   660          self.imm1(int64(dq))
   661          return
   662      }
   663  
   664      /* ModRM.Mode == 2 (32-bit displacement) */
   665      self.emit(0x84 | (reg << 3))
   666      self.emit((scale << 6) | (index << 3) | cc)
   667      self.imm4(int64(mm.Displacement))
   668  }
   669  
   670  // encode invokes the encoder to encode this instruction.
   671  func (self *_Encoding) encode(v []interface{}) int {
   672      self.len = 0
   673      self.encoder(self, v)
   674      return self.len
   675  }