encodings.go raw

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