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