1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package x86_64
18
19 import (
20 "errors"
21 "fmt"
22 "math"
23 "reflect"
24 "strconv"
25 "strings"
26 "sync/atomic"
27 )
28
29
30 type RelativeOffset int32
31
32
33 func (self RelativeOffset) String() string {
34 if self == 0 {
35 return "(%rip)"
36 } else {
37 return fmt.Sprintf("%d(%%rip)", self)
38 }
39 }
40
41
42 type RoundingControl uint8
43
44 const (
45
46 RN_SAE RoundingControl = iota
47
48
49 RD_SAE
50
51
52 RU_SAE
53
54
55 RZ_SAE
56 )
57
58 var _RC_NAMES = map[RoundingControl]string{
59 RN_SAE: "rn-sae",
60 RD_SAE: "rd-sae",
61 RU_SAE: "ru-sae",
62 RZ_SAE: "rz-sae",
63 }
64
65 func (self RoundingControl) String() string {
66 if v, ok := _RC_NAMES[self]; ok {
67 return v
68 } else {
69 panic("invalid RoundingControl value")
70 }
71 }
72
73
74 type ExceptionControl uint8
75
76 const (
77
78 SAE ExceptionControl = iota
79 )
80
81 func (ExceptionControl) String() string {
82 return "sae"
83 }
84
85
86 type AddressType uint
87
88 const (
89
90 None AddressType = iota
91
92
93 Memory
94
95
96 Offset
97
98
99 Reference
100 )
101
102
103 type Disposable interface {
104 Free()
105 }
106
107
108 type Label struct {
109 refs int64
110 Name string
111 Dest *Instruction
112 }
113
114 func (self *Label) offset(p uintptr, n int) RelativeOffset {
115 if self.Dest == nil {
116 panic("unresolved label: " + self.Name)
117 } else {
118 return RelativeOffset(self.Dest.pc - p - uintptr(n))
119 }
120 }
121
122
123
124 func (self *Label) Free() {
125 if atomic.AddInt64(&self.refs, -1) == 0 {
126
127 }
128 }
129
130
131 func (self *Label) String() string {
132 if self.Dest == nil {
133 return fmt.Sprintf("%s(%%rip)", self.Name)
134 } else {
135 return fmt.Sprintf("%s(%%rip)@%#x", self.Name, self.Dest.pc)
136 }
137 }
138
139
140 func (self *Label) Retain() *Label {
141 atomic.AddInt64(&self.refs, 1)
142 return self
143 }
144
145
146 func (self *Label) Evaluate() (int64, error) {
147 if self.Dest != nil {
148 return int64(self.Dest.pc), nil
149 } else {
150 return 0, errors.New("unresolved label: " + self.Name)
151 }
152 }
153
154
155 type Addressable struct {
156 Type AddressType
157 Memory MemoryAddress
158 Offset RelativeOffset
159 Reference *Label
160 }
161
162
163 func (self *Addressable) String() string {
164 switch self.Type {
165 case None:
166 return "(not addressable)"
167 case Memory:
168 return self.Memory.String()
169 case Offset:
170 return self.Offset.String()
171 case Reference:
172 return self.Reference.String()
173 default:
174 return "(invalid addressable)"
175 }
176 }
177
178
179 type MemoryOperand struct {
180 refs int64
181 Size int
182 Addr Addressable
183 Mask RegisterMask
184 Masked bool
185 Broadcast uint8
186 }
187
188 const (
189 _Sizes = 0b10000000100010111
190 )
191
192 func (self *MemoryOperand) isVMX(evex bool) bool {
193 return self.Addr.Type == Memory && self.Addr.Memory.isVMX(evex)
194 }
195
196 func (self *MemoryOperand) isVMY(evex bool) bool {
197 return self.Addr.Type == Memory && self.Addr.Memory.isVMY(evex)
198 }
199
200 func (self *MemoryOperand) isVMZ() bool {
201 return self.Addr.Type == Memory && self.Addr.Memory.isVMZ()
202 }
203
204 func (self *MemoryOperand) isMem() bool {
205 if (_Sizes & (1 << self.Broadcast)) == 0 {
206 return false
207 } else if self.Addr.Type == Memory {
208 return self.Addr.Memory.isMem()
209 } else if self.Addr.Type == Offset {
210 return true
211 } else if self.Addr.Type == Reference {
212 return true
213 } else {
214 return false
215 }
216 }
217
218 func (self *MemoryOperand) isSize(n int) bool {
219 return self.Size == 0 || self.Size == n
220 }
221
222 func (self *MemoryOperand) isBroadcast(n int, b uint8) bool {
223 return self.Size == n && self.Broadcast == b
224 }
225
226 func (self *MemoryOperand) formatMask() string {
227 if !self.Masked {
228 return ""
229 } else {
230 return self.Mask.String()
231 }
232 }
233
234 func (self *MemoryOperand) formatBroadcast() string {
235 if self.Broadcast == 0 {
236 return ""
237 } else {
238 return fmt.Sprintf("{1to%d}", self.Broadcast)
239 }
240 }
241
242 func (self *MemoryOperand) ensureAddrValid() {
243 switch self.Addr.Type {
244 case None:
245 break
246 case Memory:
247 self.Addr.Memory.EnsureValid()
248 case Offset:
249 break
250 case Reference:
251 break
252 default:
253 panic("invalid address type")
254 }
255 }
256
257 func (self *MemoryOperand) ensureSizeValid() {
258 if (_Sizes & (1 << self.Size)) == 0 {
259 panic("invalid memory operand size")
260 }
261 }
262
263 func (self *MemoryOperand) ensureBroadcastValid() {
264 if (_Sizes & (1 << self.Broadcast)) == 0 {
265 panic("invalid memory operand broadcast")
266 }
267 }
268
269
270
271 func (self *MemoryOperand) Free() {
272 if atomic.AddInt64(&self.refs, -1) == 0 {
273
274 }
275 }
276
277
278 func (self *MemoryOperand) String() string {
279 return self.Addr.String() + self.formatMask() + self.formatBroadcast()
280 }
281
282
283 func (self *MemoryOperand) Retain() *MemoryOperand {
284 atomic.AddInt64(&self.refs, 1)
285 return self
286 }
287
288
289 func (self *MemoryOperand) EnsureValid() {
290 self.ensureAddrValid()
291 self.ensureSizeValid()
292 self.ensureBroadcastValid()
293 }
294
295
296 type MemoryAddress struct {
297 Base Register
298 Index Register
299 Scale uint8
300 Displacement int32
301 }
302
303 const (
304 _Scales = 0b100010111
305 )
306
307 func (self *MemoryAddress) isVMX(evex bool) bool {
308 return self.isMemBase() && (self.Index == nil || isXMM(self.Index) || (evex && isEVEXXMM(self.Index)))
309 }
310
311 func (self *MemoryAddress) isVMY(evex bool) bool {
312 return self.isMemBase() && (self.Index == nil || isYMM(self.Index) || (evex && isEVEXYMM(self.Index)))
313 }
314
315 func (self *MemoryAddress) isVMZ() bool {
316 return self.isMemBase() && (self.Index == nil || isZMM(self.Index))
317 }
318
319 func (self *MemoryAddress) isMem() bool {
320 return self.isMemBase() && (self.Index == nil || isReg64(self.Index))
321 }
322
323 func (self *MemoryAddress) isMemBase() bool {
324 return (self.Base == nil || isReg64(self.Base)) &&
325 (self.Scale == 0) == (self.Index == nil) &&
326 (_Scales&(1<<self.Scale)) != 0
327 }
328
329
330 func (self *MemoryAddress) String() string {
331 var dp int
332 var sb strings.Builder
333
334
335 if dp = int(self.Displacement); dp != 0 {
336 sb.WriteString(strconv.Itoa(dp))
337 }
338
339
340 if sb.WriteByte('('); self.Base != nil {
341 sb.WriteByte('%')
342 sb.WriteString(self.Base.String())
343 }
344
345
346 if self.Index != nil {
347 sb.WriteString(",%")
348 sb.WriteString(self.Index.String())
349
350
351 if self.Scale >= 2 {
352 sb.WriteByte(',')
353 sb.WriteString(strconv.Itoa(int(self.Scale)))
354 }
355 }
356
357
358 sb.WriteByte(')')
359 return sb.String()
360 }
361
362
363 func (self *MemoryAddress) EnsureValid() {
364 if !self.isMemBase() || (self.Index != nil && !isIndexable(self.Index)) {
365 panic("not a valid memory address")
366 }
367 }
368
369
370 func Ref(ref *Label) (v *MemoryOperand) {
371 v = CreateMemoryOperand()
372 v.Addr.Type = Reference
373 v.Addr.Reference = ref
374 return
375 }
376
377
378 func Abs(disp int32) *MemoryOperand {
379 return Sib(nil, nil, 0, disp)
380 }
381
382
383 func Ptr(base Register, disp int32) *MemoryOperand {
384 return Sib(base, nil, 0, disp)
385 }
386
387
388 func Sib(base Register, index Register, scale uint8, disp int32) (v *MemoryOperand) {
389 v = CreateMemoryOperand()
390 v.Addr.Type = Memory
391 v.Addr.Memory.Base = base
392 v.Addr.Memory.Index = index
393 v.Addr.Memory.Scale = scale
394 v.Addr.Memory.Displacement = disp
395 v.EnsureValid()
396 return
397 }
398
399
400
401 const _IntMask = (1 << reflect.Int) |
402 (1 << reflect.Int8) |
403 (1 << reflect.Int16) |
404 (1 << reflect.Int32) |
405 (1 << reflect.Int64) |
406 (1 << reflect.Uint) |
407 (1 << reflect.Uint8) |
408 (1 << reflect.Uint16) |
409 (1 << reflect.Uint32) |
410 (1 << reflect.Uint64) |
411 (1 << reflect.Uintptr)
412
413 func isInt(k reflect.Kind) bool {
414 return (_IntMask & (1 << k)) != 0
415 }
416
417 func asInt64(v interface{}) (int64, bool) {
418 if isSpecial(v) {
419 return 0, false
420 } else if x := efaceOf(v); isInt(x.kind()) {
421 return x.toInt64(), true
422 } else {
423 return 0, false
424 }
425 }
426
427 func inRange(v interface{}, low int64, high int64) bool {
428 x, ok := asInt64(v)
429 return ok && x >= low && x <= high
430 }
431
432 func isSpecial(v interface{}) bool {
433 switch v.(type) {
434 case Register8:
435 return true
436 case Register16:
437 return true
438 case Register32:
439 return true
440 case Register64:
441 return true
442 case KRegister:
443 return true
444 case MMRegister:
445 return true
446 case XMMRegister:
447 return true
448 case YMMRegister:
449 return true
450 case ZMMRegister:
451 return true
452 case RelativeOffset:
453 return true
454 case RoundingControl:
455 return true
456 case ExceptionControl:
457 return true
458 default:
459 return false
460 }
461 }
462
463 func isIndexable(v interface{}) bool {
464 return isZMM(v) || isReg64(v) || isEVEXXMM(v) || isEVEXYMM(v)
465 }
466
467 func isImm4(v interface{}) bool { return inRange(v, 0, 15) }
468 func isImm8(v interface{}) bool { return inRange(v, math.MinInt8, math.MaxUint8) }
469 func isImm16(v interface{}) bool { return inRange(v, math.MinInt16, math.MaxUint16) }
470 func isImm32(v interface{}) bool { return inRange(v, math.MinInt32, math.MaxUint32) }
471 func isImm64(v interface{}) bool { _, r := asInt64(v); return r }
472 func isConst1(v interface{}) bool { x, r := asInt64(v); return r && x == 1 }
473 func isConst3(v interface{}) bool { x, r := asInt64(v); return r && x == 3 }
474 func isRel8(v interface{}) bool {
475 x, r := v.(RelativeOffset)
476 return r && x >= math.MinInt8 && x <= math.MaxInt8
477 }
478 func isRel32(v interface{}) bool { _, r := v.(RelativeOffset); return r }
479 func isLabel(v interface{}) bool { _, r := v.(*Label); return r }
480 func isReg8(v interface{}) bool { _, r := v.(Register8); return r }
481 func isReg8REX(v interface{}) bool {
482 x, r := v.(Register8)
483 return r && (x&0x80) == 0 && x >= SPL
484 }
485 func isReg16(v interface{}) bool { _, r := v.(Register16); return r }
486 func isReg32(v interface{}) bool { _, r := v.(Register32); return r }
487 func isReg64(v interface{}) bool { _, r := v.(Register64); return r }
488 func isMM(v interface{}) bool { _, r := v.(MMRegister); return r }
489 func isXMM(v interface{}) bool { x, r := v.(XMMRegister); return r && x <= XMM15 }
490 func isEVEXXMM(v interface{}) bool { _, r := v.(XMMRegister); return r }
491 func isXMMk(v interface{}) bool {
492 x, r := v.(MaskedRegister)
493 return isXMM(v) || (r && isXMM(x.Reg) && !x.Mask.Z)
494 }
495 func isXMMkz(v interface{}) bool {
496 x, r := v.(MaskedRegister)
497 return isXMM(v) || (r && isXMM(x.Reg))
498 }
499 func isYMM(v interface{}) bool { x, r := v.(YMMRegister); return r && x <= YMM15 }
500 func isEVEXYMM(v interface{}) bool { _, r := v.(YMMRegister); return r }
501 func isYMMk(v interface{}) bool {
502 x, r := v.(MaskedRegister)
503 return isYMM(v) || (r && isYMM(x.Reg) && !x.Mask.Z)
504 }
505 func isYMMkz(v interface{}) bool {
506 x, r := v.(MaskedRegister)
507 return isYMM(v) || (r && isYMM(x.Reg))
508 }
509 func isZMM(v interface{}) bool { _, r := v.(ZMMRegister); return r }
510 func isZMMk(v interface{}) bool {
511 x, r := v.(MaskedRegister)
512 return isZMM(v) || (r && isZMM(x.Reg) && !x.Mask.Z)
513 }
514 func isZMMkz(v interface{}) bool {
515 x, r := v.(MaskedRegister)
516 return isZMM(v) || (r && isZMM(x.Reg))
517 }
518 func isK(v interface{}) bool { _, r := v.(KRegister); return r }
519 func isKk(v interface{}) bool {
520 x, r := v.(MaskedRegister)
521 return isK(v) || (r && isK(x.Reg) && !x.Mask.Z)
522 }
523 func isM(v interface{}) bool {
524 x, r := v.(*MemoryOperand)
525 return r && x.isMem() && x.Broadcast == 0 && !x.Masked
526 }
527 func isMk(v interface{}) bool {
528 x, r := v.(*MemoryOperand)
529 return r && x.isMem() && x.Broadcast == 0 && !(x.Masked && x.Mask.Z)
530 }
531 func isMkz(v interface{}) bool {
532 x, r := v.(*MemoryOperand)
533 return r && x.isMem() && x.Broadcast == 0
534 }
535 func isM8(v interface{}) bool {
536 x, r := v.(*MemoryOperand)
537 return r && isM(v) && x.isSize(1)
538 }
539 func isM16(v interface{}) bool {
540 x, r := v.(*MemoryOperand)
541 return r && isM(v) && x.isSize(2)
542 }
543 func isM16kz(v interface{}) bool {
544 x, r := v.(*MemoryOperand)
545 return r && isMkz(v) && x.isSize(2)
546 }
547 func isM32(v interface{}) bool {
548 x, r := v.(*MemoryOperand)
549 return r && isM(v) && x.isSize(4)
550 }
551 func isM32k(v interface{}) bool {
552 x, r := v.(*MemoryOperand)
553 return r && isMk(v) && x.isSize(4)
554 }
555 func isM32kz(v interface{}) bool {
556 x, r := v.(*MemoryOperand)
557 return r && isMkz(v) && x.isSize(4)
558 }
559 func isM64(v interface{}) bool {
560 x, r := v.(*MemoryOperand)
561 return r && isM(v) && x.isSize(8)
562 }
563 func isM64k(v interface{}) bool {
564 x, r := v.(*MemoryOperand)
565 return r && isMk(v) && x.isSize(8)
566 }
567 func isM64kz(v interface{}) bool {
568 x, r := v.(*MemoryOperand)
569 return r && isMkz(v) && x.isSize(8)
570 }
571 func isM128(v interface{}) bool {
572 x, r := v.(*MemoryOperand)
573 return r && isM(v) && x.isSize(16)
574 }
575 func isM128kz(v interface{}) bool {
576 x, r := v.(*MemoryOperand)
577 return r && isMkz(v) && x.isSize(16)
578 }
579 func isM256(v interface{}) bool {
580 x, r := v.(*MemoryOperand)
581 return r && isM(v) && x.isSize(32)
582 }
583 func isM256kz(v interface{}) bool {
584 x, r := v.(*MemoryOperand)
585 return r && isMkz(v) && x.isSize(32)
586 }
587 func isM512(v interface{}) bool {
588 x, r := v.(*MemoryOperand)
589 return r && isM(v) && x.isSize(64)
590 }
591 func isM512kz(v interface{}) bool {
592 x, r := v.(*MemoryOperand)
593 return r && isMkz(v) && x.isSize(64)
594 }
595 func isM64M32bcst(v interface{}) bool {
596 x, r := v.(*MemoryOperand)
597 return isM64(v) || (r && x.isBroadcast(4, 2))
598 }
599 func isM128M32bcst(v interface{}) bool {
600 x, r := v.(*MemoryOperand)
601 return isM128(v) || (r && x.isBroadcast(4, 4))
602 }
603 func isM256M32bcst(v interface{}) bool {
604 x, r := v.(*MemoryOperand)
605 return isM256(v) || (r && x.isBroadcast(4, 8))
606 }
607 func isM512M32bcst(v interface{}) bool {
608 x, r := v.(*MemoryOperand)
609 return isM512(v) || (r && x.isBroadcast(4, 16))
610 }
611 func isM128M64bcst(v interface{}) bool {
612 x, r := v.(*MemoryOperand)
613 return isM128(v) || (r && x.isBroadcast(8, 2))
614 }
615 func isM256M64bcst(v interface{}) bool {
616 x, r := v.(*MemoryOperand)
617 return isM256(v) || (r && x.isBroadcast(8, 4))
618 }
619 func isM512M64bcst(v interface{}) bool {
620 x, r := v.(*MemoryOperand)
621 return isM512(v) || (r && x.isBroadcast(8, 8))
622 }
623 func isVMX(v interface{}) bool {
624 x, r := v.(*MemoryOperand)
625 return r && x.isVMX(false) && !x.Masked
626 }
627 func isEVEXVMX(v interface{}) bool {
628 x, r := v.(*MemoryOperand)
629 return r && x.isVMX(true) && !x.Masked
630 }
631 func isVMXk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMX(true) }
632 func isVMY(v interface{}) bool {
633 x, r := v.(*MemoryOperand)
634 return r && x.isVMY(false) && !x.Masked
635 }
636 func isEVEXVMY(v interface{}) bool {
637 x, r := v.(*MemoryOperand)
638 return r && x.isVMY(true) && !x.Masked
639 }
640 func isVMYk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMY(true) }
641 func isVMZ(v interface{}) bool {
642 x, r := v.(*MemoryOperand)
643 return r && x.isVMZ() && !x.Masked
644 }
645 func isVMZk(v interface{}) bool { x, r := v.(*MemoryOperand); return r && x.isVMZ() }
646 func isSAE(v interface{}) bool { _, r := v.(ExceptionControl); return r }
647 func isER(v interface{}) bool { _, r := v.(RoundingControl); return r }
648
649 func isImmExt(v interface{}, ext int, min int64, max int64) bool {
650 if x, ok := asInt64(v); !ok {
651 return false
652 } else if m := int64(1) << (8 * ext); x < m && x >= m+min {
653 return true
654 } else {
655 return x <= max && x >= min
656 }
657 }
658
659 func isImm8Ext(v interface{}, ext int) bool {
660 return isImmExt(v, ext, math.MinInt8, math.MaxInt8)
661 }
662
663 func isImm32Ext(v interface{}, ext int) bool {
664 return isImmExt(v, ext, math.MinInt32, math.MaxInt32)
665 }
666
View as plain text