encodings.go 20 KB

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