encodings.go 20 KB

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