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