A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.Runtime.InteropServices;
4
5#if UNITY_EDITOR || BURST_INTERNAL
6namespace Unity.Burst.Editor
7{
8 internal partial class BurstDisassembler
9 {
10 internal class ARM64AsmTokenKindProvider : AsmTokenKindProvider
11 {
12 private static readonly string[] Registers = new[]
13 {
14 "nzcv",
15 "wsp",
16 "sp",
17 "lr",
18
19 "r0",
20 "r1",
21 "r2",
22 "r3",
23 "r4",
24 "r5",
25 "r6",
26 "r7",
27 "r8",
28 "r9",
29 "r10",
30 "r11",
31 "r12",
32 "r13",
33 "r14",
34 "r15",
35
36 "b0",
37 "b1",
38 "b2",
39 "b3",
40 "b4",
41 "b5",
42 "b6",
43 "b7",
44 "b8",
45 "b9",
46 "b10",
47 "b11",
48 "b12",
49 "b13",
50 "b14",
51 "b15",
52 "b16",
53 "b17",
54 "b18",
55 "b19",
56 "b20",
57 "b21",
58 "b22",
59 "b23",
60 "b24",
61 "b25",
62 "b26",
63 "b27",
64 "b28",
65 "b29",
66 "b30",
67 "b31",
68 "d0",
69 "d1",
70 "d2",
71 "d3",
72 "d4",
73 "d5",
74 "d6",
75 "d7",
76 "d8",
77 "d9",
78 "d10",
79 "d11",
80 "d12",
81 "d13",
82 "d14",
83 "d15",
84 "d16",
85 "d17",
86 "d18",
87 "d19",
88 "d20",
89 "d21",
90 "d22",
91 "d23",
92 "d24",
93 "d25",
94 "d26",
95 "d27",
96 "d28",
97 "d29",
98 "d30",
99 "d31",
100 "h0",
101 "h1",
102 "h2",
103 "h3",
104 "h4",
105 "h5",
106 "h6",
107 "h7",
108 "h8",
109 "h9",
110 "h10",
111 "h11",
112 "h12",
113 "h13",
114 "h14",
115 "h15",
116 "h16",
117 "h17",
118 "h18",
119 "h19",
120 "h20",
121 "h21",
122 "h22",
123 "h23",
124 "h24",
125 "h25",
126 "h26",
127 "h27",
128 "h28",
129 "h29",
130 "h30",
131 "h31",
132 "q0",
133 "q1",
134 "q2",
135 "q3",
136 "q4",
137 "q5",
138 "q6",
139 "q7",
140 "q8",
141 "q9",
142 "q10",
143 "q11",
144 "q12",
145 "q13",
146 "q14",
147 "q15",
148 "q16",
149 "q17",
150 "q18",
151 "q19",
152 "q20",
153 "q21",
154 "q22",
155 "q23",
156 "q24",
157 "q25",
158 "q26",
159 "q27",
160 "q28",
161 "q29",
162 "q30",
163 "q31",
164 "s0",
165 "s1",
166 "s2",
167 "s3",
168 "s4",
169 "s5",
170 "s6",
171 "s7",
172 "s8",
173 "s9",
174 "s10",
175 "s11",
176 "s12",
177 "s13",
178 "s14",
179 "s15",
180 "s16",
181 "s17",
182 "s18",
183 "s19",
184 "s20",
185 "s21",
186 "s22",
187 "s23",
188 "s24",
189 "s25",
190 "s26",
191 "s27",
192 "s28",
193 "s29",
194 "s30",
195 "s31",
196 "w0",
197 "w1",
198 "w2",
199 "w3",
200 "w4",
201 "w5",
202 "w6",
203 "w7",
204 "w8",
205 "w9",
206 "w10",
207 "w11",
208 "w12",
209 "w13",
210 "w14",
211 "w15",
212 "w16",
213 "w17",
214 "w18",
215 "w19",
216 "w20",
217 "w21",
218 "w22",
219 "w23",
220 "w24",
221 "w25",
222 "w26",
223 "w27",
224 "w28",
225 "w29",
226 "w30",
227 "wzr",
228 "x0",
229 "x1",
230 "x2",
231 "x3",
232 "x4",
233 "x5",
234 "x6",
235 "x7",
236 "x8",
237 "x9",
238 "x10",
239 "x11",
240 "x12",
241 "x13",
242 "x14",
243 "x15",
244 "x16",
245 "x17",
246 "x18",
247 "x19",
248 "x20",
249 "x21",
250 "x22",
251 "x23",
252 "x24",
253 "x25",
254 "x26",
255 "x27",
256 "x28",
257 "x29",
258 "x30",
259
260 "v0",
261 "v1",
262 "v2",
263 "v3",
264 "v4",
265 "v5",
266 "v6",
267 "v7",
268 "v8",
269 "v9",
270 "v10",
271 "v11",
272 "v12",
273 "v13",
274 "v14",
275 "v15",
276 "v16",
277 "v17",
278 "v18",
279 "v19",
280 "v20",
281 "v21",
282 "v22",
283 "v23",
284 "v24",
285 "v25",
286 "v26",
287 "v27",
288 "v28",
289 "v29",
290 "v30",
291 };
292
293 private static readonly string[] Instructions = new[]
294 {
295 "bkpt",
296 "usat",
297 "stm",
298 "stmia",
299 "stmib",
300 "stmda",
301 "stmdb",
302 "ldm",
303 "ldmia",
304 "ldmib",
305 "ldmda",
306 "ldmdb",
307 "it",
308 "itt",
309 "ittt",
310 "itttt",
311 "ite",
312 "itte",
313 "ittte",
314 "itee",
315 "ittee",
316 "uxtab",
317 "uxtah",
318 "abs",
319 "adc",
320 "add",
321 "addhi",
322 "adds",
323 "addhn",
324 "addhn2",
325 "addp",
326 "addv",
327 "addw",
328 "adr",
329 "adrp",
330 "aesd",
331 "aese",
332 "aesimc",
333 "aesmc",
334 "and",
335 "asr",
336 "asrs",
337 "at",
338 "bfi",
339 "bfm",
340 "bfxil",
341 "bic",
342 "bif",
343 "bit",
344 "brk",
345 "bsl",
346 "ccmn",
347 "ccmp",
348 "clrex",
349 "cls",
350 "clz",
351 "cmeq",
352 "cmge",
353 "cmgt",
354 "cmhi",
355 "cmhs",
356 "cmle",
357 "cmlt",
358 "cmn",
359 "cmp",
360 "cmtst",
361 "cnt",
362 "crc32b",
363 "crc32cb",
364 "crc32ch",
365 "crc32cw",
366 "crc32cx",
367 "crc32h",
368 "crc32w",
369 "crc32x",
370 "csel",
371 "csinc",
372 "csinv",
373 "csneg",
374 "dc",
375 "dcps1",
376 "dcps2",
377 "dcps3",
378 "dmb",
379 "drps",
380 "dsb",
381 "dup",
382 "eon",
383 "eor",
384 "eors",
385 "eret",
386 "ext",
387 "extr",
388 "fabd",
389 "fabs",
390 "facge",
391 "facgt",
392 "fadd",
393 "faddp",
394 "fccmp",
395 "fccmpe",
396 "fcmeq",
397 "fcmge",
398 "fcmgt",
399 "fcmle",
400 "fcmlt",
401 "fcmp",
402 "fcmpe",
403 "fcsel",
404 "fcvt",
405 "fcvtas",
406 "fcvtau",
407 "fcvtl",
408 "fcvtl2",
409 "fcvtms",
410 "fcvtmu",
411 "fcvtn",
412 "fcvtn2",
413 "fcvtns",
414 "fcvtnu",
415 "fcvtps",
416 "fcvtpu",
417 "fcvtxn",
418 "fcvtxn2",
419 "fcvtzs",
420 "fcvtzu",
421 "fdiv",
422 "fmadd",
423 "fmax",
424 "fmaxnm",
425 "fmaxnmp",
426 "fmaxnmv",
427 "fmaxp",
428 "fmaxv",
429 "fmin",
430 "fminnm",
431 "fminnmp",
432 "fminnmv",
433 "fminp",
434 "fminv",
435 "fmla",
436 "fmls",
437 "fmov",
438 "fmsub",
439 "fmul",
440 "fmulx",
441 "fneg",
442 "fnmadd",
443 "fnmsub",
444 "fnmul",
445 "frecpe",
446 "frecps",
447 "frecpx",
448 "frinta",
449 "frinti",
450 "frintm",
451 "frintn",
452 "frintp",
453 "frintx",
454 "frintz",
455 "frsqrte",
456 "frsqrts",
457 "fsqrt",
458 "fsub",
459 "hint",
460 "hlt",
461 "hvc",
462 "ic",
463 "ins",
464 "isb",
465 "ld1",
466 "ld1r",
467 "ld2",
468 "ld2r",
469 "ld3",
470 "ld3r",
471 "ld4",
472 "ld4r",
473 "ldar",
474 "ldarb",
475 "ldarh",
476 "ldaxp",
477 "ldaxr",
478 "ldaxrb",
479 "ldaxrh",
480 "ldnp",
481 "ldp",
482 "ldpsw",
483 "ldr",
484 "ldrb",
485 "ldrd",
486 "ldrh",
487 "ldrsb",
488 "ldrsh",
489 "ldrsw",
490 "ldtr",
491 "ldtrb",
492 "ldtrh",
493 "ldtrsb",
494 "ldtrsh",
495 "ldtrsw",
496 "ldur",
497 "ldurb",
498 "ldurh",
499 "ldursb",
500 "ldursh",
501 "ldursw",
502 "ldxp",
503 "ldxr",
504 "ldxrb",
505 "ldxrh",
506 "lsl",
507 "lsls",
508 "lsr",
509 "lsrs",
510 "umaal",
511 "smmul",
512 "madd",
513 "mla",
514 "mls",
515 "mneg",
516 "mov",
517 "movi",
518 "movk",
519 "movn",
520 "movt",
521 "movz",
522 "movw",
523 "mrs",
524 "msr",
525 "msub",
526 "mul",
527 "muls",
528 "mvn",
529 "mvns",
530 "mvni",
531 "neg",
532 "ngc",
533 "nop",
534 "not",
535 "orn",
536 "orr",
537 "orrs",
538 "pmul",
539 "pmull",
540 "pmull2",
541 "prfm",
542 "prfum",
543 "raddhn",
544 "raddhn2",
545 "rbit",
546 "rev",
547 "rev16",
548 "rev32",
549 "rev64",
550 "rrx",
551 "ror",
552 "rshrn",
553 "rshrn2",
554 "rsubhn",
555 "rsubhn2",
556 "saba",
557 "sabal",
558 "sabal2",
559 "sabd",
560 "sabdl",
561 "sabdl2",
562 "sadalp",
563 "saddl",
564 "saddl2",
565 "saddlp",
566 "saddlv",
567 "saddw",
568 "saddw2",
569 "sbc",
570 "sbfiz",
571 "sbfm",
572 "sbfx",
573 "scvtf",
574 "sdiv",
575 "sev",
576 "sevl",
577 "sha1c",
578 "sha1h",
579 "sha1m",
580 "sha1p",
581 "sha1su0",
582 "sha1su1",
583 "sha256h",
584 "sha256h2",
585 "sha256su0",
586 "sha256su1",
587 "shadd",
588 "shl",
589 "shll",
590 "shll2",
591 "shrn",
592 "shrn2",
593 "shsub",
594 "sli",
595 "smaddl",
596 "smax",
597 "smaxp",
598 "smaxv",
599 "smc",
600 "smin",
601 "sminp",
602 "sminv",
603 "smlabb",
604 "smlabt",
605 "smlatb",
606 "smlatt",
607 "smlal",
608 "smlal2",
609 "smlsl",
610 "smlsl2",
611 "smnegl",
612 "smov",
613 "smsubl",
614 "smulh",
615 "smull",
616 "smull2",
617 "sqabs",
618 "sqadd",
619 "sqdmlal",
620 "sqdmlal2",
621 "sqdmlsl",
622 "sqdmlsl2",
623 "sqdmulh",
624 "sqdmull",
625 "sqdmull2",
626 "sqneg",
627 "sqrdmulh",
628 "sqrshl",
629 "sqrshrn",
630 "sqrshrn2",
631 "sqrshrun",
632 "sqrshrun2",
633 "sqshl",
634 "sqshlu",
635 "sqshrn",
636 "sqshrn2",
637 "sqshrun",
638 "sqshrun2",
639 "sqsub",
640 "sqxtn",
641 "sqxtn2",
642 "sqxtun",
643 "sqxtun2",
644 "srhadd",
645 "sri",
646 "srshl",
647 "srshr",
648 "srsra",
649 "sshl",
650 "sshll",
651 "sshll2",
652 "sshr",
653 "ssra",
654 "ssubl",
655 "ssubl2",
656 "ssubw",
657 "ssubw2",
658 "st1",
659 "st2",
660 "st3",
661 "st4",
662 "stlr",
663 "stlrb",
664 "stlrh",
665 "stlxp",
666 "stlxr",
667 "stlxrb",
668 "stlxrh",
669 "stnp",
670 "stp",
671 "str",
672 "strd",
673 "strb",
674 "strh",
675 "sttr",
676 "sttrb",
677 "sttrh",
678 "stur",
679 "sturb",
680 "sturh",
681 "stxp",
682 "stxr",
683 "stxrb",
684 "stxrh",
685 "sub",
686 "subw",
687 "subs",
688 "rsb",
689 "rsbs",
690 "subhn",
691 "subhn2",
692 "suqadd",
693 "svc",
694 "sxtb",
695 "sxth",
696 "sxtw",
697 "sys",
698 "sysl",
699 "tbl",
700 "tbx",
701 "tbb",
702 "tbh",
703 "tlbi",
704 "trn1",
705 "trn2",
706 "tst",
707 "uaba",
708 "uabal",
709 "uabal2",
710 "uabd",
711 "uabdl",
712 "uabdl2",
713 "uadalp",
714 "uaddl",
715 "uaddl2",
716 "uaddlp",
717 "uaddlv",
718 "uaddw",
719 "uaddw2",
720 "ubfiz",
721 "ubfm",
722 "ubfx",
723 "ucvtf",
724 "udiv",
725 "uhadd",
726 "uhsub",
727 "umaddl",
728 "umax",
729 "umaxp",
730 "umaxv",
731 "umin",
732 "uminp",
733 "uminv",
734 "umlal",
735 "umlal2",
736 "umlsl",
737 "umlsl2",
738 "umnegl",
739 "umov",
740 "umsubl",
741 "umulh",
742 "umull",
743 "umull2",
744 "uqadd",
745 "uqrshl",
746 "uqrshrn",
747 "uqrshrn2",
748 "uqshl",
749 "uqshrn",
750 "uqshrn2",
751 "uqsub",
752 "uqxtn",
753 "uqxtn2",
754 "urecpe",
755 "urhadd",
756 "urshl",
757 "urshr",
758 "ursqrte",
759 "ursra",
760 "ushl",
761 "ushll",
762 "ushll2",
763 "ushr",
764 "usqadd",
765 "usra",
766 "usubl",
767 "usubl2",
768 "usubw",
769 "usubw2",
770 "uxtb",
771 "uxth",
772 "uzp1",
773 "uzp2",
774 "wfe",
775 "wfi",
776 "xtn",
777 "xtn2",
778 "yield",
779 "zip1",
780 "zip2",
781 "adcs",
782 "addg",
783 "adrl",
784 "ands",
785 "asrv",
786 "autda",
787 "autdza",
788 "autdb",
789 "autdzb",
790 "autia",
791 "autiza",
792 "autia1716",
793 "autiasp",
794 "autiaz",
795 "autib",
796 "autizb",
797 "autib1716",
798 "autibsp",
799 "autibz",
800 "axflag",
801 "b.cond",
802 "bfc",
803 "bics",
804 "cinc",
805 "cinv",
806 "cmpp",
807 "cneg",
808 "csdb",
809 "cset",
810 "csetm",
811 "eretaa",
812 "eretab",
813 "esb",
814 "irg",
815 "ldg",
816 "ldgv",
817 "lslv",
818 "lsrv",
819 "movl",
820 "negs",
821 "ngcs",
822 "pacda",
823 "pacdza",
824 "pacdb",
825 "pacdzb",
826 "pacga",
827 "pacia",
828 "paciza",
829 "pacia1716",
830 "paciasp",
831 "paciaz",
832 "pacib",
833 "pacizb",
834 "pacib1716",
835 "pacibsp",
836 "pacibz",
837 "psb",
838 "rorv",
839 "sbcs",
840 "st2g",
841 "stg",
842 "stgp",
843 "stgv",
844 "stz2g",
845 "stzg",
846 "subg",
847 "subp",
848 "subps",
849 "xaflag",
850 "xpacd",
851 "xpaci",
852 "xpaclri",
853 "casa",
854 "casal",
855 "cas",
856 "casl",
857 "casab",
858 "casalb",
859 "casb",
860 "caslb",
861 "casah",
862 "casalh",
863 "cash",
864 "caslh",
865 "caspa",
866 "caspal",
867 "casp",
868 "caspl",
869 "ldadda",
870 "ldaddal",
871 "ldadd",
872 "ldaddl",
873 "ldaddab",
874 "ldaddalb",
875 "ldaddb",
876 "ldaddlb",
877 "ldaddah",
878 "ldaddalh",
879 "ldaddh",
880 "ldaddlh",
881 "ldapr",
882 "ldaprb",
883 "ldaprh",
884 "ldclra",
885 "ldclral",
886 "ldclr",
887 "ldclrl",
888 "ldclrab",
889 "ldclralb",
890 "ldclrb",
891 "ldclrlb",
892 "ldclrah",
893 "ldclralh",
894 "ldclrh",
895 "ldclrlh",
896 "ldeora",
897 "ldeoral",
898 "ldeor",
899 "ldeorl",
900 "ldeorab",
901 "ldeoralb",
902 "ldeorb",
903 "ldeorlb",
904 "ldeorah",
905 "ldeoralh",
906 "ldeorh",
907 "ldeorlh",
908 "ldlar",
909 "ldlarb",
910 "ldlarh",
911 "ldraa",
912 "ldrab",
913 "ldrex",
914 "strex",
915 "ldseta",
916 "ldsetal",
917 "ldset",
918 "ldsetl",
919 "ldsetab",
920 "ldsetalb",
921 "ldsetb",
922 "ldsetlb",
923 "ldsetah",
924 "ldsetalh",
925 "ldseth",
926 "ldsetlh",
927 "ldsmaxa",
928 "ldsmaxal",
929 "ldsmax",
930 "ldsmaxl",
931 "ldsmaxab",
932 "ldsmaxalb",
933 "ldsmaxb",
934 "ldsmaxlb",
935 "ldsmaxah",
936 "ldsmaxalh",
937 "ldsmaxh",
938 "ldsmaxlh",
939 "ldsmina",
940 "ldsminal",
941 "ldsmin",
942 "ldsminl",
943 "ldsminab",
944 "ldsminalb",
945 "ldsminb",
946 "ldsminlb",
947 "ldsminah",
948 "ldsminalh",
949 "ldsminh",
950 "ldsminlh",
951 "ldumaxa",
952 "ldumaxal",
953 "ldumax",
954 "ldumaxl",
955 "ldumaxab",
956 "ldumaxalb",
957 "ldumaxb",
958 "ldumaxlb",
959 "ldumaxah",
960 "ldumaxalh",
961 "ldumaxh",
962 "ldumaxlh",
963 "ldumina",
964 "lduminal",
965 "ldumin",
966 "lduminl",
967 "lduminab",
968 "lduminalb",
969 "lduminb",
970 "lduminlb",
971 "lduminah",
972 "lduminalh",
973 "lduminh",
974 "lduminlh",
975 "stadd",
976 "staddl",
977 "staddb",
978 "staddlb",
979 "staddh",
980 "staddlh",
981 "stclr",
982 "stclrl",
983 "stclrb",
984 "stclrlb",
985 "stclrh",
986 "stclrlh",
987 "steor",
988 "steorl",
989 "steorb",
990 "steorlb",
991 "steorh",
992 "steorlh",
993 "stllr",
994 "stllrb",
995 "stllrh",
996 "stset",
997 "stsetl",
998 "stsetb",
999 "stsetlb",
1000 "stseth",
1001 "stsetlh",
1002 "stsmax",
1003 "stsmaxl",
1004 "stsmaxb",
1005 "stsmaxlb",
1006 "stsmaxh",
1007 "stsmaxlh",
1008 "stsmin",
1009 "stsminl",
1010 "stsminb",
1011 "stsminlb",
1012 "stsminh",
1013 "stsminlh",
1014 "stumax",
1015 "stumaxl",
1016 "stumaxb",
1017 "stumaxlb",
1018 "stumaxh",
1019 "stumaxlh",
1020 "stumin",
1021 "stuminl",
1022 "stuminb",
1023 "stuminlb",
1024 "stuminh",
1025 "stuminlh",
1026 "swpa",
1027 "swpal",
1028 "swp",
1029 "swpl",
1030 "swpab",
1031 "swpalb",
1032 "swpb",
1033 "swplb",
1034 "swpah",
1035 "swpalh",
1036 "swph",
1037 "swplh",
1038 "fjcvtzs",
1039 "fcmla",
1040 "fmlal",
1041 "fmlsl",
1042 "sqrdmlah",
1043 "sqrdmlsh",
1044 "fcadd",
1045 "sdot",
1046 "sxtl",
1047 "sxtl2",
1048 "udot",
1049 "uxtl",
1050 "uxtl2",
1051 "bcax",
1052 "eor3",
1053 "rax1",
1054 "sha512h2",
1055 "sha512h",
1056 "sha512su0",
1057 "sha512su1",
1058 "sm3partw1",
1059 "sm3partw2",
1060 "sm3ss1",
1061 "sm3tt1a",
1062 "sm3tt1b",
1063 "sm3tt2a",
1064 "sm3tt2b",
1065 "sm4e",
1066 "sm4ekey",
1067 "xar",
1068 };
1069
1070 private static readonly string[] BranchInstructions = new string[]
1071 {
1072 "beq",
1073 "bne",
1074 "bcs",
1075 "bhs",
1076 "bcc",
1077 "blo",
1078 "bmi",
1079 "bpl",
1080 "bvs",
1081 "bvc",
1082 "bhi",
1083 "bls",
1084 "bge",
1085 "blt",
1086 "bgt",
1087 "ble",
1088 "bal",
1089 "bnv",
1090
1091 "cbnz",
1092 "cbz",
1093 "tbnz",
1094 "tbz",
1095
1096 "blraa",
1097 "blraaz",
1098 "blrab",
1099 "blrabz",
1100
1101 "braa",
1102 "braaz",
1103 "brab",
1104 "brabz",
1105 };
1106
1107 private static readonly string[] JumpInstructions = new string[]
1108 {
1109 "b",
1110 "br",
1111 "blr",
1112 "bx",
1113 "bl",
1114 "blx",
1115 "bxj",
1116 };
1117
1118 private static readonly string[] ReturnInstructions = new string[]
1119 {
1120 "ret",
1121 "retaa",
1122 "retab",
1123 };
1124
1125 private static readonly string[] SimdInstructions = new string[]
1126 {
1127 // TODO: add missing instructions
1128 "vld1",
1129 "vld2",
1130 "vld3",
1131 "vld4",
1132 "vabs",
1133 "vadd",
1134 "vaddl",
1135 "vaddw",
1136 "vmov",
1137 "movs",
1138 "vmul",
1139 "vsub",
1140 "vaba",
1141 "vabl",
1142 "vabd",
1143 "vabdl",
1144 "vacge",
1145 "vacgt",
1146 "vacle",
1147 "vaclt",
1148 "vaddhn",
1149 "vand",
1150 "vbic",
1151 "vbif",
1152 "vbit",
1153 "vbsl",
1154 "vceq",
1155 "vcge",
1156 "vcgt",
1157 "vcle",
1158 "vcls",
1159 "vcnt",
1160 "vclt",
1161 "vclz",
1162 "vcvt",
1163 "vdup",
1164 "veor",
1165 "vext",
1166 "vfma",
1167 "vfms",
1168 "vhadd",
1169 "vhsub",
1170 "vld",
1171 "vmax",
1172 "vmin",
1173 "vmla",
1174 "vmls",
1175 "vmovl",
1176 "vmovn",
1177 "vmvn",
1178 "vneg",
1179 "vorn",
1180 "vorr",
1181 "vpadal",
1182 "vpadd",
1183 "vpmax",
1184 "vpmin",
1185 "vqabs",
1186 "vqadd",
1187 "vqdmlal",
1188 "vqdmlsl",
1189 "vqdmull",
1190 "vqdmulh",
1191 "vqmovn",
1192 "vqneg",
1193 "vqrdmulh",
1194 "vqrshl",
1195 "vqrshrn",
1196 "vqshl",
1197 "vqshrn",
1198 "vqsub",
1199 "vraddhn",
1200 "vrecpe",
1201 "vrecps",
1202 "vrev",
1203 "vrev16",
1204 "vrev32",
1205 "vrev64",
1206 "vrhadd",
1207 "vrshr",
1208 "vrshrn",
1209 "vrsqrte",
1210 "vrsqrts",
1211 "vrsra",
1212 "vrsubhn",
1213 "vshl",
1214 "vshr",
1215 "vshrn",
1216 "vsli",
1217 "vsra",
1218 "vsri",
1219 "vst",
1220 "vst1",
1221 "vst2",
1222 "vst3",
1223 "vst4",
1224 "vsubhn",
1225 "vswp",
1226 "vtbl",
1227 "vtbx",
1228 "vtrn",
1229 "vtst",
1230 "vuzp",
1231 "vzip",
1232 "vldm",
1233 "vldmia",
1234 "vldmdb",
1235 "vldr",
1236 "vmrs",
1237 "vmsr",
1238 "vpop",
1239 "vpush",
1240 "vstm",
1241 "vstmia",
1242 "vstr",
1243 "vcmp",
1244 "vcmpe",
1245 "vcvtb",
1246 "vcvtt",
1247 "vdiv",
1248 "vfnma",
1249 "vfnms",
1250 "vnmla",
1251 "vnmls",
1252 "vnmul",
1253 "vsqrt",
1254 "push",
1255 "pop",
1256 "pkhbt",
1257 "pkhtb",
1258 };
1259
1260 private ARM64AsmTokenKindProvider() : base(Registers.Length +
1261 Instructions.Length +
1262 BranchInstructions.Length +
1263 JumpInstructions.Length +
1264 ReturnInstructions.Length +
1265 SimdInstructions.Length)
1266 {
1267 foreach (var register in Registers)
1268 {
1269 AddTokenKind(register, AsmTokenKind.Register);
1270 }
1271
1272 foreach (var instruction in Instructions)
1273 {
1274 AddTokenKind(instruction, AsmTokenKind.Instruction);
1275 }
1276
1277 foreach (var instruction in BranchInstructions)
1278 {
1279 AddTokenKind(instruction, AsmTokenKind.BranchInstruction);
1280 }
1281
1282 foreach (var instruction in JumpInstructions)
1283 {
1284 AddTokenKind(instruction, AsmTokenKind.JumpInstruction);
1285 }
1286
1287 foreach (var instruction in ReturnInstructions)
1288 {
1289 AddTokenKind(instruction, AsmTokenKind.ReturnInstruction);
1290 }
1291
1292 foreach (var instruction in SimdInstructions)
1293 {
1294 AddTokenKind(instruction, AsmTokenKind.InstructionSIMD);
1295 }
1296 }
1297
1298 public override AsmTokenKind FindTokenKind(StringSlice instr)
1299 {
1300 instr = TryRemoveT(instr); // error here now that I added b.le etc.
1301
1302 var kind = base.FindTokenKind(instr);
1303 if (kind != AsmTokenKind.Identifier)
1304 {
1305 return kind;
1306 }
1307
1308 // Did not find instruction in listed instructions.
1309 // Try matching whether it ended on a condition flag.
1310 instr = TryRemoveCond(instr);
1311 kind = base.FindTokenKind(instr);
1312 return kind;
1313 }
1314
1315 private static bool IsConditional(string text)
1316 {
1317 switch (text)
1318 {
1319 case "eq":
1320 case "ne":
1321 case "cs":
1322 case "hs":
1323 case "cc":
1324 case "lo":
1325 case "mi":
1326 case "pl":
1327 case "vs":
1328 case "vc":
1329 case "hi":
1330 case "ls":
1331 case "ge":
1332 case "lt":
1333 case "gt":
1334 case "le":
1335 case "al":
1336 return true;
1337 default:
1338 return false;
1339 }
1340 }
1341
1342
1343 internal static StringSlice TryRemoveT(StringSlice instr)
1344 {
1345 var idx = instr.IndexOf('.');
1346 if (idx < 0)
1347 {
1348 return instr;
1349 }
1350
1351 var instrS = instr.ToString();
1352 if (IsConditional(instrS.Substring(idx+1)))
1353 {
1354 // remove '.' from string e.g. b.le => ble
1355 return new StringSlice(instrS.Remove(idx, 1));
1356 }
1357
1358 return new StringSlice(instrS, 0, idx);
1359 }
1360
1361 internal static StringSlice TryRemoveCond(StringSlice instr)
1362 {
1363 if (instr.Length < 2)
1364 {
1365 return instr;
1366 }
1367
1368 var instrS = instr.ToString();
1369 var idx = instr.Length - 2;
1370
1371 return IsConditional(instrS.Substring(idx, 2))
1372 ? new StringSlice(instrS, 0, idx)
1373 : instr;
1374 }
1375
1376 private static bool IsFloatingRegister(string reg)
1377 {
1378 if (reg == "sp")
1379 {
1380 return false;
1381 }
1382 var c = reg[0];
1383 return c == 'b' || c == 'h' || c == 's' || c == 'd' || c == 'q' || c == 'v';
1384 }
1385
1386 private static int StripSizeIdentifier(string reg, int idx)
1387 {
1388 // "sp" only register that defies the heuristic.
1389 if (reg != "sp")
1390 {
1391 switch (reg[idx])
1392 {
1393 case 'w':
1394 case 'x':
1395 case 's':
1396 case 'q':
1397 case 'h':
1398 case 'b':
1399 case 'd':
1400 case 'v':
1401 idx++;
1402 break;
1403 }
1404 }
1405
1406 return idx;
1407 }
1408
1409 public override bool RegisterEqual(string regA, string regB)
1410 {
1411 var isAFloat = IsFloatingRegister(regA);
1412 var isBFloat = IsFloatingRegister(regB);
1413
1414 if ((isAFloat && isBFloat) || (isAFloat == isBFloat))
1415 {
1416 var idxA = StripSizeIdentifier(regA, 0);
1417 var idxB = StripSizeIdentifier(regB, 0);
1418
1419 var lenA = regA.Length;
1420 var lenB = regB.Length;
1421
1422 while (idxA < lenA && idxB < lenB)
1423 {
1424 if (regA[idxA] != regB[idxB])
1425 {
1426 break;
1427 }
1428 if ((idxA == lenA - 1 || regA[idxA+1] == '.')
1429 && (idxB == lenB - 1 || regB[idxB+1] == '.'))
1430 {
1431 return true;
1432 }
1433 idxA++;
1434 idxB++;
1435 }
1436 }
1437
1438 return false;
1439 }
1440
1441 /// <summary>
1442 /// Assumes <see cref="instruction"/> is an arm SIMD instruction.
1443 /// Returns whether it's a packed or scalar SIMD instruction.
1444 /// </summary>
1445 public override SIMDkind SimdKind(StringSlice instruction) =>
1446 instruction.Contains('.')
1447 ? SIMDkind.Packed
1448 : SIMDkind.Scalar;
1449
1450 public static readonly ARM64AsmTokenKindProvider Instance = new ARM64AsmTokenKindProvider();
1451 }
1452 }
1453}
1454#endif