Source file src/cmd/vendor/golang.org/x/arch/arm64/arm64asm/inst.go
1
2
3
4
5 package arm64asm
6
7 import (
8 "fmt"
9 "strings"
10 )
11
12
13 type Op uint16
14
15
16
17
18
19
20 func (op Op) String() string {
21 if op >= Op(len(opstr)) || opstr[op] == "" {
22 return fmt.Sprintf("Op(%d)", int(op))
23 }
24 return opstr[op]
25 }
26
27
28 type Inst struct {
29 Op Op
30 Enc uint32
31 Args Args
32 }
33
34 func (i Inst) String() string {
35 var args []string
36 for _, arg := range i.Args {
37 if arg == nil {
38 break
39 }
40 args = append(args, arg.String())
41 }
42 return i.Op.String() + " " + strings.Join(args, ", ")
43 }
44
45
46
47
48 type Args [5]Arg
49
50
51
52
53
54
55 type Arg interface {
56 isArg()
57 String() string
58 }
59
60
61
62 type Reg uint16
63
64 const (
65 W0 Reg = iota
66 W1
67 W2
68 W3
69 W4
70 W5
71 W6
72 W7
73 W8
74 W9
75 W10
76 W11
77 W12
78 W13
79 W14
80 W15
81 W16
82 W17
83 W18
84 W19
85 W20
86 W21
87 W22
88 W23
89 W24
90 W25
91 W26
92 W27
93 W28
94 W29
95 W30
96 WZR
97
98 X0
99 X1
100 X2
101 X3
102 X4
103 X5
104 X6
105 X7
106 X8
107 X9
108 X10
109 X11
110 X12
111 X13
112 X14
113 X15
114 X16
115 X17
116 X18
117 X19
118 X20
119 X21
120 X22
121 X23
122 X24
123 X25
124 X26
125 X27
126 X28
127 X29
128 X30
129 XZR
130
131 B0
132 B1
133 B2
134 B3
135 B4
136 B5
137 B6
138 B7
139 B8
140 B9
141 B10
142 B11
143 B12
144 B13
145 B14
146 B15
147 B16
148 B17
149 B18
150 B19
151 B20
152 B21
153 B22
154 B23
155 B24
156 B25
157 B26
158 B27
159 B28
160 B29
161 B30
162 B31
163
164 H0
165 H1
166 H2
167 H3
168 H4
169 H5
170 H6
171 H7
172 H8
173 H9
174 H10
175 H11
176 H12
177 H13
178 H14
179 H15
180 H16
181 H17
182 H18
183 H19
184 H20
185 H21
186 H22
187 H23
188 H24
189 H25
190 H26
191 H27
192 H28
193 H29
194 H30
195 H31
196
197 S0
198 S1
199 S2
200 S3
201 S4
202 S5
203 S6
204 S7
205 S8
206 S9
207 S10
208 S11
209 S12
210 S13
211 S14
212 S15
213 S16
214 S17
215 S18
216 S19
217 S20
218 S21
219 S22
220 S23
221 S24
222 S25
223 S26
224 S27
225 S28
226 S29
227 S30
228 S31
229
230 D0
231 D1
232 D2
233 D3
234 D4
235 D5
236 D6
237 D7
238 D8
239 D9
240 D10
241 D11
242 D12
243 D13
244 D14
245 D15
246 D16
247 D17
248 D18
249 D19
250 D20
251 D21
252 D22
253 D23
254 D24
255 D25
256 D26
257 D27
258 D28
259 D29
260 D30
261 D31
262
263 Q0
264 Q1
265 Q2
266 Q3
267 Q4
268 Q5
269 Q6
270 Q7
271 Q8
272 Q9
273 Q10
274 Q11
275 Q12
276 Q13
277 Q14
278 Q15
279 Q16
280 Q17
281 Q18
282 Q19
283 Q20
284 Q21
285 Q22
286 Q23
287 Q24
288 Q25
289 Q26
290 Q27
291 Q28
292 Q29
293 Q30
294 Q31
295
296 V0
297 V1
298 V2
299 V3
300 V4
301 V5
302 V6
303 V7
304 V8
305 V9
306 V10
307 V11
308 V12
309 V13
310 V14
311 V15
312 V16
313 V17
314 V18
315 V19
316 V20
317 V21
318 V22
319 V23
320 V24
321 V25
322 V26
323 V27
324 V28
325 V29
326 V30
327 V31
328
329 WSP = WZR
330 SP = XZR
331 )
332
333 func (Reg) isArg() {}
334
335 func (r Reg) String() string {
336 switch {
337 case r == WZR:
338 return "WZR"
339 case r == XZR:
340 return "XZR"
341 case W0 <= r && r <= W30:
342 return fmt.Sprintf("W%d", int(r-W0))
343 case X0 <= r && r <= X30:
344 return fmt.Sprintf("X%d", int(r-X0))
345
346 case B0 <= r && r <= B31:
347 return fmt.Sprintf("B%d", int(r-B0))
348 case H0 <= r && r <= H31:
349 return fmt.Sprintf("H%d", int(r-H0))
350 case S0 <= r && r <= S31:
351 return fmt.Sprintf("S%d", int(r-S0))
352 case D0 <= r && r <= D31:
353 return fmt.Sprintf("D%d", int(r-D0))
354 case Q0 <= r && r <= Q31:
355 return fmt.Sprintf("Q%d", int(r-Q0))
356
357 case V0 <= r && r <= V31:
358 return fmt.Sprintf("V%d", int(r-V0))
359 default:
360 return fmt.Sprintf("Reg(%d)", int(r))
361 }
362 }
363
364
365 type RegSP Reg
366
367 func (RegSP) isArg() {}
368
369 func (r RegSP) String() string {
370 switch Reg(r) {
371 case WSP:
372 return "WSP"
373 case SP:
374 return "SP"
375 default:
376 return Reg(r).String()
377 }
378 }
379
380 type ImmShift struct {
381 imm uint16
382 shift uint8
383 }
384
385 func (ImmShift) isArg() {}
386
387 func (is ImmShift) String() string {
388 if is.shift == 0 {
389 return fmt.Sprintf("#%#x", is.imm)
390 }
391 if is.shift < 128 {
392 return fmt.Sprintf("#%#x, LSL #%d", is.imm, is.shift)
393 }
394 return fmt.Sprintf("#%#x, MSL #%d", is.imm, is.shift-128)
395 }
396
397 type ExtShift uint8
398
399 const (
400 _ ExtShift = iota
401 uxtb
402 uxth
403 uxtw
404 uxtx
405 sxtb
406 sxth
407 sxtw
408 sxtx
409 lsl
410 lsr
411 asr
412 ror
413 )
414
415 func (extShift ExtShift) String() string {
416 switch extShift {
417 case uxtb:
418 return "UXTB"
419
420 case uxth:
421 return "UXTH"
422
423 case uxtw:
424 return "UXTW"
425
426 case uxtx:
427 return "UXTX"
428
429 case sxtb:
430 return "SXTB"
431
432 case sxth:
433 return "SXTH"
434
435 case sxtw:
436 return "SXTW"
437
438 case sxtx:
439 return "SXTX"
440
441 case lsl:
442 return "LSL"
443
444 case lsr:
445 return "LSR"
446
447 case asr:
448 return "ASR"
449
450 case ror:
451 return "ROR"
452 }
453 return ""
454 }
455
456 type RegExtshiftAmount struct {
457 reg Reg
458 extShift ExtShift
459 amount uint8
460 show_zero bool
461 }
462
463 func (RegExtshiftAmount) isArg() {}
464
465 func (rea RegExtshiftAmount) String() string {
466 buf := rea.reg.String()
467 if rea.extShift != ExtShift(0) {
468 buf += ", " + rea.extShift.String()
469 if rea.amount != 0 {
470 buf += fmt.Sprintf(" #%d", rea.amount)
471 } else {
472 if rea.show_zero == true {
473 buf += fmt.Sprintf(" #%d", rea.amount)
474 }
475 }
476 }
477 return buf
478 }
479
480
481
482 type PCRel int64
483
484 func (PCRel) isArg() {}
485
486 func (r PCRel) String() string {
487 return fmt.Sprintf(".%+#x", uint64(r))
488 }
489
490
491 type AddrMode uint8
492
493 const (
494 _ AddrMode = iota
495 AddrPostIndex
496 AddrPreIndex
497 AddrOffset
498 AddrPostReg
499 )
500
501
502
503 type MemImmediate struct {
504 Base RegSP
505 Mode AddrMode
506 imm int32
507 }
508
509 func (MemImmediate) isArg() {}
510
511 func (m MemImmediate) String() string {
512 R := m.Base.String()
513 X := fmt.Sprintf("#%d", m.imm)
514
515 switch m.Mode {
516 case AddrOffset:
517 if X == "#0" {
518 return fmt.Sprintf("[%s]", R)
519 }
520 return fmt.Sprintf("[%s,%s]", R, X)
521 case AddrPreIndex:
522 return fmt.Sprintf("[%s,%s]!", R, X)
523 case AddrPostIndex:
524 return fmt.Sprintf("[%s],%s", R, X)
525 case AddrPostReg:
526 post := Reg(X0) + Reg(m.imm)
527 postR := post.String()
528 return fmt.Sprintf("[%s], %s", R, postR)
529 }
530 return fmt.Sprintf("unimplemented!")
531 }
532
533
534
535 type MemExtend struct {
536 Base RegSP
537 Index Reg
538 Extend ExtShift
539
540 Amount uint8
541
542
543
544
545 ShiftMustBeZero bool
546 }
547
548 func (MemExtend) isArg() {}
549
550 func (m MemExtend) String() string {
551 Rbase := m.Base.String()
552 RIndex := m.Index.String()
553 if m.ShiftMustBeZero {
554 if m.Amount != 0 {
555 return fmt.Sprintf("[%s,%s,%s #0]", Rbase, RIndex, m.Extend.String())
556 } else {
557 if m.Extend != lsl {
558 return fmt.Sprintf("[%s,%s,%s]", Rbase, RIndex, m.Extend.String())
559 } else {
560 return fmt.Sprintf("[%s,%s]", Rbase, RIndex)
561 }
562 }
563 } else {
564 if m.Amount != 0 {
565 return fmt.Sprintf("[%s,%s,%s #%d]", Rbase, RIndex, m.Extend.String(), m.Amount)
566 } else {
567 if m.Extend != lsl {
568 return fmt.Sprintf("[%s,%s,%s]", Rbase, RIndex, m.Extend.String())
569 } else {
570 return fmt.Sprintf("[%s,%s]", Rbase, RIndex)
571 }
572 }
573 }
574 }
575
576
577 type Imm struct {
578 Imm uint32
579 Decimal bool
580 }
581
582 func (Imm) isArg() {}
583
584 func (i Imm) String() string {
585 if !i.Decimal {
586 return fmt.Sprintf("#%#x", i.Imm)
587 } else {
588 return fmt.Sprintf("#%d", i.Imm)
589 }
590 }
591
592 type Imm64 struct {
593 Imm uint64
594 Decimal bool
595 }
596
597 func (Imm64) isArg() {}
598
599 func (i Imm64) String() string {
600 if !i.Decimal {
601 return fmt.Sprintf("#%#x", i.Imm)
602 } else {
603 return fmt.Sprintf("#%d", i.Imm)
604 }
605 }
606
607
608 type Imm_hint uint8
609
610 func (Imm_hint) isArg() {}
611
612 func (i Imm_hint) String() string {
613 return fmt.Sprintf("#%#x", uint32(i))
614 }
615
616
617 type Imm_clrex uint8
618
619 func (Imm_clrex) isArg() {}
620
621 func (i Imm_clrex) String() string {
622 if i == 15 {
623 return ""
624 }
625 return fmt.Sprintf("#%#x", uint32(i))
626 }
627
628
629 type Imm_dcps uint16
630
631 func (Imm_dcps) isArg() {}
632
633 func (i Imm_dcps) String() string {
634 if i == 0 {
635 return ""
636 }
637 return fmt.Sprintf("#%#x", uint32(i))
638 }
639
640
641 type Cond struct {
642 Value uint8
643 Invert bool
644 }
645
646 func (Cond) isArg() {}
647
648 func (c Cond) String() string {
649 cond31 := c.Value >> 1
650 invert := bool((c.Value & 1) == 1)
651 invert = (invert != c.Invert)
652 switch cond31 {
653 case 0:
654 if invert {
655 return "NE"
656 } else {
657 return "EQ"
658 }
659 case 1:
660 if invert {
661 return "CC"
662 } else {
663 return "CS"
664 }
665 case 2:
666 if invert {
667 return "PL"
668 } else {
669 return "MI"
670 }
671 case 3:
672 if invert {
673 return "VC"
674 } else {
675 return "VS"
676 }
677 case 4:
678 if invert {
679 return "LS"
680 } else {
681 return "HI"
682 }
683 case 5:
684 if invert {
685 return "LT"
686 } else {
687 return "GE"
688 }
689 case 6:
690 if invert {
691 return "LE"
692 } else {
693 return "GT"
694 }
695 case 7:
696 return "AL"
697 }
698 return ""
699 }
700
701
702 type Imm_c uint8
703
704 func (Imm_c) isArg() {}
705
706 func (i Imm_c) String() string {
707 return fmt.Sprintf("C%d", uint8(i))
708 }
709
710
711 type Imm_option uint8
712
713 func (Imm_option) isArg() {}
714
715 func (i Imm_option) String() string {
716 switch uint8(i) {
717 case 15:
718 return "SY"
719 case 14:
720 return "ST"
721 case 13:
722 return "LD"
723 case 11:
724 return "ISH"
725 case 10:
726 return "ISHST"
727 case 9:
728 return "ISHLD"
729 case 7:
730 return "NSH"
731 case 6:
732 return "NSHST"
733 case 5:
734 return "NSHLD"
735 case 3:
736 return "OSH"
737 case 2:
738 return "OSHST"
739 case 1:
740 return "OSHLD"
741 }
742 return fmt.Sprintf("#%#02x", uint8(i))
743 }
744
745
746 type Imm_prfop uint8
747
748 func (Imm_prfop) isArg() {}
749
750 func (i Imm_prfop) String() string {
751 prf_type := (i >> 3) & (1<<2 - 1)
752 prf_target := (i >> 1) & (1<<2 - 1)
753 prf_policy := i & 1
754 var result string
755
756 switch prf_type {
757 case 0:
758 result = "PLD"
759 case 1:
760 result = "PLI"
761 case 2:
762 result = "PST"
763 case 3:
764 return fmt.Sprintf("#%#02x", uint8(i))
765 }
766 switch prf_target {
767 case 0:
768 result += "L1"
769 case 1:
770 result += "L2"
771 case 2:
772 result += "L3"
773 case 3:
774 return fmt.Sprintf("#%#02x", uint8(i))
775 }
776 if prf_policy == 0 {
777 result += "KEEP"
778 } else {
779 result += "STRM"
780 }
781 return result
782 }
783
784 type Pstatefield uint8
785
786 const (
787 SPSel Pstatefield = iota
788 DAIFSet
789 DAIFClr
790 )
791
792 func (Pstatefield) isArg() {}
793
794 func (p Pstatefield) String() string {
795 switch p {
796 case SPSel:
797 return "SPSel"
798 case DAIFSet:
799 return "DAIFSet"
800 case DAIFClr:
801 return "DAIFClr"
802 default:
803 return "unimplemented"
804 }
805 }
806
807 type Systemreg struct {
808 op0 uint8
809 op1 uint8
810 cn uint8
811 cm uint8
812 op2 uint8
813 }
814
815 func (Systemreg) isArg() {}
816
817 func (s Systemreg) String() string {
818 return fmt.Sprintf("S%d_%d_C%d_C%d_%d",
819 s.op0, s.op1, s.cn, s.cm, s.op2)
820 }
821
822
823 type Imm_fp struct {
824 s uint8
825 exp int8
826 pre uint8
827 }
828
829 func (Imm_fp) isArg() {}
830
831 func (i Imm_fp) String() string {
832 var s, pre, numerator, denominator int16
833 var result float64
834 if i.s == 0 {
835 s = 1
836 } else {
837 s = -1
838 }
839 pre = s * int16(16+i.pre)
840 if i.exp > 0 {
841 numerator = (pre << uint8(i.exp))
842 denominator = 16
843 } else {
844 numerator = pre
845 denominator = (16 << uint8(-1*i.exp))
846 }
847 result = float64(numerator) / float64(denominator)
848 return fmt.Sprintf("#%.18e", result)
849 }
850
851 type Arrangement uint8
852
853 const (
854 _ Arrangement = iota
855 ArrangementB
856 Arrangement8B
857 Arrangement16B
858 ArrangementH
859 Arrangement4H
860 Arrangement8H
861 ArrangementS
862 Arrangement2S
863 Arrangement4S
864 ArrangementD
865 Arrangement1D
866 Arrangement2D
867 Arrangement1Q
868 )
869
870 func (a Arrangement) String() (result string) {
871 switch a {
872 case ArrangementB:
873 result = ".B"
874 case Arrangement8B:
875 result = ".8B"
876 case Arrangement16B:
877 result = ".16B"
878 case ArrangementH:
879 result = ".H"
880 case Arrangement4H:
881 result = ".4H"
882 case Arrangement8H:
883 result = ".8H"
884 case ArrangementS:
885 result = ".S"
886 case Arrangement2S:
887 result = ".2S"
888 case Arrangement4S:
889 result = ".4S"
890 case ArrangementD:
891 result = ".D"
892 case Arrangement1D:
893 result = ".1D"
894 case Arrangement2D:
895 result = ".2D"
896 case Arrangement1Q:
897 result = ".1Q"
898 }
899 return
900 }
901
902
903 type RegisterWithArrangement struct {
904 r Reg
905 a Arrangement
906 cnt uint8
907 }
908
909 func (RegisterWithArrangement) isArg() {}
910
911 func (r RegisterWithArrangement) String() string {
912 result := r.r.String()
913 result += r.a.String()
914 if r.cnt > 0 {
915 result = "{" + result
916 if r.cnt == 2 {
917 r1 := V0 + Reg((uint16(r.r)-uint16(V0)+1)&31)
918 result += ", " + r1.String() + r.a.String()
919 } else if r.cnt > 2 {
920 if (uint16(r.cnt) + ((uint16(r.r) - uint16(V0)) & 31)) > 32 {
921 for i := 1; i < int(r.cnt); i++ {
922 cur := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(i))&31)
923 result += ", " + cur.String() + r.a.String()
924 }
925 } else {
926 r1 := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(r.cnt)-1)&31)
927 result += "-" + r1.String() + r.a.String()
928 }
929 }
930 result += "}"
931 }
932 return result
933 }
934
935
936
937 type RegisterWithArrangementAndIndex struct {
938 r Reg
939 a Arrangement
940 index uint8
941 cnt uint8
942 }
943
944 func (RegisterWithArrangementAndIndex) isArg() {}
945
946 func (r RegisterWithArrangementAndIndex) String() string {
947 result := r.r.String()
948 result += r.a.String()
949 if r.cnt > 0 {
950 result = "{" + result
951 if r.cnt == 2 {
952 r1 := V0 + Reg((uint16(r.r)-uint16(V0)+1)&31)
953 result += ", " + r1.String() + r.a.String()
954 } else if r.cnt > 2 {
955 if (uint16(r.cnt) + ((uint16(r.r) - uint16(V0)) & 31)) > 32 {
956 for i := 1; i < int(r.cnt); i++ {
957 cur := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(i))&31)
958 result += ", " + cur.String() + r.a.String()
959 }
960 } else {
961 r1 := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(r.cnt)-1)&31)
962 result += "-" + r1.String() + r.a.String()
963 }
964 }
965 result += "}"
966 }
967 return fmt.Sprintf("%s[%d]", result, r.index)
968 }
969
View as plain text