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
546
547 ShiftMustBeZero bool
548 }
549
550 func (MemExtend) isArg() {}
551
552 func (m MemExtend) String() string {
553 Rbase := m.Base.String()
554 RIndex := m.Index.String()
555 if m.ShiftMustBeZero {
556 if m.Amount != 0 {
557 return fmt.Sprintf("[%s,%s,%s #0]", Rbase, RIndex, m.Extend.String())
558 } else {
559 if m.Extend != lsl {
560 return fmt.Sprintf("[%s,%s,%s]", Rbase, RIndex, m.Extend.String())
561 } else {
562 return fmt.Sprintf("[%s,%s]", Rbase, RIndex)
563 }
564 }
565 } else {
566 if m.Amount != 0 {
567 return fmt.Sprintf("[%s,%s,%s #%d]", Rbase, RIndex, m.Extend.String(), m.Amount)
568 } else {
569 if m.Extend != lsl {
570 return fmt.Sprintf("[%s,%s,%s]", Rbase, RIndex, m.Extend.String())
571 } else {
572 return fmt.Sprintf("[%s,%s]", Rbase, RIndex)
573 }
574 }
575 }
576 }
577
578
579 type Imm struct {
580 Imm uint32
581 Decimal bool
582 }
583
584 func (Imm) isArg() {}
585
586 func (i Imm) String() string {
587 if !i.Decimal {
588 return fmt.Sprintf("#%#x", i.Imm)
589 } else {
590 return fmt.Sprintf("#%d", i.Imm)
591 }
592 }
593
594 type Imm64 struct {
595 Imm uint64
596 Decimal bool
597 }
598
599 func (Imm64) isArg() {}
600
601 func (i Imm64) String() string {
602 if !i.Decimal {
603 return fmt.Sprintf("#%#x", i.Imm)
604 } else {
605 return fmt.Sprintf("#%d", i.Imm)
606 }
607 }
608
609
610 type Imm_hint uint8
611
612 func (Imm_hint) isArg() {}
613
614 func (i Imm_hint) String() string {
615 return fmt.Sprintf("#%#x", uint32(i))
616 }
617
618
619 type Imm_clrex uint8
620
621 func (Imm_clrex) isArg() {}
622
623 func (i Imm_clrex) String() string {
624 if i == 15 {
625 return ""
626 }
627 return fmt.Sprintf("#%#x", uint32(i))
628 }
629
630
631 type Imm_dcps uint16
632
633 func (Imm_dcps) isArg() {}
634
635 func (i Imm_dcps) String() string {
636 if i == 0 {
637 return ""
638 }
639 return fmt.Sprintf("#%#x", uint32(i))
640 }
641
642
643 type Cond struct {
644 Value uint8
645 Invert bool
646 }
647
648 func (Cond) isArg() {}
649
650 func (c Cond) String() string {
651 cond31 := c.Value >> 1
652 invert := bool((c.Value & 1) == 1)
653 invert = (invert != c.Invert)
654 switch cond31 {
655 case 0:
656 if invert {
657 return "NE"
658 } else {
659 return "EQ"
660 }
661 case 1:
662 if invert {
663 return "CC"
664 } else {
665 return "CS"
666 }
667 case 2:
668 if invert {
669 return "PL"
670 } else {
671 return "MI"
672 }
673 case 3:
674 if invert {
675 return "VC"
676 } else {
677 return "VS"
678 }
679 case 4:
680 if invert {
681 return "LS"
682 } else {
683 return "HI"
684 }
685 case 5:
686 if invert {
687 return "LT"
688 } else {
689 return "GE"
690 }
691 case 6:
692 if invert {
693 return "LE"
694 } else {
695 return "GT"
696 }
697 case 7:
698 return "AL"
699 }
700 return ""
701 }
702
703
704 type Imm_c uint8
705
706 func (Imm_c) isArg() {}
707
708 func (i Imm_c) String() string {
709 return fmt.Sprintf("C%d", uint8(i))
710 }
711
712
713 type Imm_option uint8
714
715 func (Imm_option) isArg() {}
716
717 func (i Imm_option) String() string {
718 switch uint8(i) {
719 case 15:
720 return "SY"
721 case 14:
722 return "ST"
723 case 13:
724 return "LD"
725 case 11:
726 return "ISH"
727 case 10:
728 return "ISHST"
729 case 9:
730 return "ISHLD"
731 case 7:
732 return "NSH"
733 case 6:
734 return "NSHST"
735 case 5:
736 return "NSHLD"
737 case 3:
738 return "OSH"
739 case 2:
740 return "OSHST"
741 case 1:
742 return "OSHLD"
743 }
744 return fmt.Sprintf("#%#02x", uint8(i))
745 }
746
747
748 type Imm_prfop uint8
749
750 func (Imm_prfop) isArg() {}
751
752 func (i Imm_prfop) String() string {
753 prf_type := (i >> 3) & (1<<2 - 1)
754 prf_target := (i >> 1) & (1<<2 - 1)
755 prf_policy := i & 1
756 var result string
757
758 switch prf_type {
759 case 0:
760 result = "PLD"
761 case 1:
762 result = "PLI"
763 case 2:
764 result = "PST"
765 case 3:
766 return fmt.Sprintf("#%#02x", uint8(i))
767 }
768 switch prf_target {
769 case 0:
770 result += "L1"
771 case 1:
772 result += "L2"
773 case 2:
774 result += "L3"
775 case 3:
776 return fmt.Sprintf("#%#02x", uint8(i))
777 }
778 if prf_policy == 0 {
779 result += "KEEP"
780 } else {
781 result += "STRM"
782 }
783 return result
784 }
785
786 type Pstatefield uint8
787
788 const (
789 SPSel Pstatefield = iota
790 DAIFSet
791 DAIFClr
792 )
793
794 func (Pstatefield) isArg() {}
795
796 func (p Pstatefield) String() string {
797 switch p {
798 case SPSel:
799 return "SPSel"
800 case DAIFSet:
801 return "DAIFSet"
802 case DAIFClr:
803 return "DAIFClr"
804 default:
805 return "unimplemented"
806 }
807 }
808
809 type Systemreg struct {
810 op0 uint8
811 op1 uint8
812 cn uint8
813 cm uint8
814 op2 uint8
815 }
816
817 func (Systemreg) isArg() {}
818
819 func (s Systemreg) String() string {
820 return fmt.Sprintf("S%d_%d_C%d_C%d_%d",
821 s.op0, s.op1, s.cn, s.cm, s.op2)
822 }
823
824
825 type Imm_fp struct {
826 s uint8
827 exp int8
828 pre uint8
829 }
830
831 func (Imm_fp) isArg() {}
832
833 func (i Imm_fp) String() string {
834 var s, pre, numerator, denominator int16
835 var result float64
836 if i.s == 0 {
837 s = 1
838 } else {
839 s = -1
840 }
841 pre = s * int16(16+i.pre)
842 if i.exp > 0 {
843 numerator = (pre << uint8(i.exp))
844 denominator = 16
845 } else {
846 numerator = pre
847 denominator = (16 << uint8(-1*i.exp))
848 }
849 result = float64(numerator) / float64(denominator)
850 return fmt.Sprintf("#%.18e", result)
851 }
852
853 type Arrangement uint8
854
855 const (
856 _ Arrangement = iota
857 ArrangementB
858 Arrangement8B
859 Arrangement16B
860 ArrangementH
861 Arrangement4H
862 Arrangement8H
863 ArrangementS
864 Arrangement2S
865 Arrangement4S
866 ArrangementD
867 Arrangement1D
868 Arrangement2D
869 Arrangement1Q
870 )
871
872 func (a Arrangement) String() (result string) {
873 switch a {
874 case ArrangementB:
875 result = ".B"
876 case Arrangement8B:
877 result = ".8B"
878 case Arrangement16B:
879 result = ".16B"
880 case ArrangementH:
881 result = ".H"
882 case Arrangement4H:
883 result = ".4H"
884 case Arrangement8H:
885 result = ".8H"
886 case ArrangementS:
887 result = ".S"
888 case Arrangement2S:
889 result = ".2S"
890 case Arrangement4S:
891 result = ".4S"
892 case ArrangementD:
893 result = ".D"
894 case Arrangement1D:
895 result = ".1D"
896 case Arrangement2D:
897 result = ".2D"
898 case Arrangement1Q:
899 result = ".1Q"
900 }
901 return
902 }
903
904
905 type RegisterWithArrangement struct {
906 r Reg
907 a Arrangement
908 cnt uint8
909 }
910
911 func (RegisterWithArrangement) isArg() {}
912
913 func (r RegisterWithArrangement) String() string {
914 result := r.r.String()
915 result += r.a.String()
916 if r.cnt > 0 {
917 result = "{" + result
918 if r.cnt == 2 {
919 r1 := V0 + Reg((uint16(r.r)-uint16(V0)+1)&31)
920 result += ", " + r1.String() + r.a.String()
921 } else if r.cnt > 2 {
922 if (uint16(r.cnt) + ((uint16(r.r) - uint16(V0)) & 31)) > 32 {
923 for i := 1; i < int(r.cnt); i++ {
924 cur := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(i))&31)
925 result += ", " + cur.String() + r.a.String()
926 }
927 } else {
928 r1 := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(r.cnt)-1)&31)
929 result += "-" + r1.String() + r.a.String()
930 }
931 }
932 result += "}"
933 }
934 return result
935 }
936
937
938
939 type RegisterWithArrangementAndIndex struct {
940 r Reg
941 a Arrangement
942 index uint8
943 cnt uint8
944 }
945
946 func (RegisterWithArrangementAndIndex) isArg() {}
947
948 func (r RegisterWithArrangementAndIndex) String() string {
949 result := r.r.String()
950 result += r.a.String()
951 if r.cnt > 0 {
952 result = "{" + result
953 if r.cnt == 2 {
954 r1 := V0 + Reg((uint16(r.r)-uint16(V0)+1)&31)
955 result += ", " + r1.String() + r.a.String()
956 } else if r.cnt > 2 {
957 if (uint16(r.cnt) + ((uint16(r.r) - uint16(V0)) & 31)) > 32 {
958 for i := 1; i < int(r.cnt); i++ {
959 cur := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(i))&31)
960 result += ", " + cur.String() + r.a.String()
961 }
962 } else {
963 r1 := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(r.cnt)-1)&31)
964 result += "-" + r1.String() + r.a.String()
965 }
966 }
967 result += "}"
968 }
969 return fmt.Sprintf("%s[%d]", result, r.index)
970 }
971
View as plain text