Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: src/arm64/disasm-arm64.cc

Issue 2622643005: ARM64: Add NEON support (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <assert.h> 5 #include <assert.h>
6 #include <stdarg.h> 6 #include <stdarg.h>
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #if V8_TARGET_ARCH_ARM64 10 #if V8_TARGET_ARCH_ARM64
11 11
12 #include "src/arm64/decoder-arm64-inl.h" 12 #include "src/arm64/decoder-arm64-inl.h"
13 #include "src/arm64/disasm-arm64.h" 13 #include "src/arm64/disasm-arm64.h"
14 #include "src/arm64/utils-arm64.h"
14 #include "src/base/platform/platform.h" 15 #include "src/base/platform/platform.h"
15 #include "src/disasm.h" 16 #include "src/disasm.h"
16 #include "src/macro-assembler.h" 17 #include "src/macro-assembler.h"
17 18
18 namespace v8 { 19 namespace v8 {
19 namespace internal { 20 namespace internal {
20 21
21 22
22 DisassemblingDecoder::DisassemblingDecoder() { 23 DisassemblingDecoder::DisassemblingDecoder() {
23 buffer_size_ = 256; 24 buffer_size_ = 256;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 default: UNREACHABLE(); 88 default: UNREACHABLE();
88 } 89 }
89 Format(instr, mnemonic, form); 90 Format(instr, mnemonic, form);
90 } 91 }
91 92
92 93
93 void DisassemblingDecoder::VisitAddSubShifted(Instruction* instr) { 94 void DisassemblingDecoder::VisitAddSubShifted(Instruction* instr) {
94 bool rd_is_zr = RdIsZROrSP(instr); 95 bool rd_is_zr = RdIsZROrSP(instr);
95 bool rn_is_zr = RnIsZROrSP(instr); 96 bool rn_is_zr = RnIsZROrSP(instr);
96 const char *mnemonic = ""; 97 const char *mnemonic = "";
97 const char *form = "'Rd, 'Rn, 'Rm'HDP"; 98 const char *form = "'Rd, 'Rn, 'Rm'NDP";
98 const char *form_cmp = "'Rn, 'Rm'HDP"; 99 const char *form_cmp = "'Rn, 'Rm'NDP";
99 const char *form_neg = "'Rd, 'Rm'HDP"; 100 const char *form_neg = "'Rd, 'Rm'NDP";
100 101
101 switch (instr->Mask(AddSubShiftedMask)) { 102 switch (instr->Mask(AddSubShiftedMask)) {
102 case ADD_w_shift: 103 case ADD_w_shift:
103 case ADD_x_shift: mnemonic = "add"; break; 104 case ADD_x_shift: mnemonic = "add"; break;
104 case ADDS_w_shift: 105 case ADDS_w_shift:
105 case ADDS_x_shift: { 106 case ADDS_x_shift: {
106 mnemonic = "adds"; 107 mnemonic = "adds";
107 if (rd_is_zr) { 108 if (rd_is_zr) {
108 mnemonic = "cmn"; 109 mnemonic = "cmn";
109 form = form_cmp; 110 form = form_cmp;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 return true; 280 return true;
280 } 281 }
281 return false; 282 return false;
282 } 283 }
283 284
284 285
285 void DisassemblingDecoder::VisitLogicalShifted(Instruction* instr) { 286 void DisassemblingDecoder::VisitLogicalShifted(Instruction* instr) {
286 bool rd_is_zr = RdIsZROrSP(instr); 287 bool rd_is_zr = RdIsZROrSP(instr);
287 bool rn_is_zr = RnIsZROrSP(instr); 288 bool rn_is_zr = RnIsZROrSP(instr);
288 const char *mnemonic = ""; 289 const char *mnemonic = "";
289 const char *form = "'Rd, 'Rn, 'Rm'HLo"; 290 const char *form = "'Rd, 'Rn, 'Rm'NLo";
290 291
291 switch (instr->Mask(LogicalShiftedMask)) { 292 switch (instr->Mask(LogicalShiftedMask)) {
292 case AND_w: 293 case AND_w:
293 case AND_x: mnemonic = "and"; break; 294 case AND_x: mnemonic = "and"; break;
294 case BIC_w: 295 case BIC_w:
295 case BIC_x: mnemonic = "bic"; break; 296 case BIC_x: mnemonic = "bic"; break;
296 case EOR_w: 297 case EOR_w:
297 case EOR_x: mnemonic = "eor"; break; 298 case EOR_x: mnemonic = "eor"; break;
298 case EON_w: 299 case EON_w:
299 case EON_x: mnemonic = "eon"; break; 300 case EON_x: mnemonic = "eon"; break;
300 case BICS_w: 301 case BICS_w:
301 case BICS_x: mnemonic = "bics"; break; 302 case BICS_x: mnemonic = "bics"; break;
302 case ANDS_w: 303 case ANDS_w:
303 case ANDS_x: { 304 case ANDS_x: {
304 mnemonic = "ands"; 305 mnemonic = "ands";
305 if (rd_is_zr) { 306 if (rd_is_zr) {
306 mnemonic = "tst"; 307 mnemonic = "tst";
307 form = "'Rn, 'Rm'HLo"; 308 form = "'Rn, 'Rm'NLo";
308 } 309 }
309 break; 310 break;
310 } 311 }
311 case ORR_w: 312 case ORR_w:
312 case ORR_x: { 313 case ORR_x: {
313 mnemonic = "orr"; 314 mnemonic = "orr";
314 if (rn_is_zr && (instr->ImmDPShift() == 0) && (instr->ShiftDP() == LSL)) { 315 if (rn_is_zr && (instr->ImmDPShift() == 0) && (instr->ShiftDP() == LSL)) {
315 mnemonic = "mov"; 316 mnemonic = "mov";
316 form = "'Rd, 'Rm"; 317 form = "'Rd, 'Rm";
317 } 318 }
318 break; 319 break;
319 } 320 }
320 case ORN_w: 321 case ORN_w:
321 case ORN_x: { 322 case ORN_x: {
322 mnemonic = "orn"; 323 mnemonic = "orn";
323 if (rn_is_zr) { 324 if (rn_is_zr) {
324 mnemonic = "mvn"; 325 mnemonic = "mvn";
325 form = "'Rd, 'Rm'HLo"; 326 form = "'Rd, 'Rm'NLo";
326 } 327 }
327 break; 328 break;
328 } 329 }
329 default: UNREACHABLE(); 330 default: UNREACHABLE();
330 } 331 }
331 332
332 Format(instr, mnemonic, form); 333 Format(instr, mnemonic, form);
333 } 334 }
334 335
335 336
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 switch (instr->Mask(PCRelAddressingMask)) { 521 switch (instr->Mask(PCRelAddressingMask)) {
521 case ADR: Format(instr, "adr", "'Xd, 'AddrPCRelByte"); break; 522 case ADR: Format(instr, "adr", "'Xd, 'AddrPCRelByte"); break;
522 // ADRP is not implemented. 523 // ADRP is not implemented.
523 default: Format(instr, "unimplemented", "(PCRelAddressing)"); 524 default: Format(instr, "unimplemented", "(PCRelAddressing)");
524 } 525 }
525 } 526 }
526 527
527 528
528 void DisassemblingDecoder::VisitConditionalBranch(Instruction* instr) { 529 void DisassemblingDecoder::VisitConditionalBranch(Instruction* instr) {
529 switch (instr->Mask(ConditionalBranchMask)) { 530 switch (instr->Mask(ConditionalBranchMask)) {
530 case B_cond: Format(instr, "b.'CBrn", "'BImmCond"); break; 531 case B_cond:
532 Format(instr, "b.'CBrn", "'TImmCond");
533 break;
531 default: UNREACHABLE(); 534 default: UNREACHABLE();
532 } 535 }
533 } 536 }
534 537
535 538
536 void DisassemblingDecoder::VisitUnconditionalBranchToRegister( 539 void DisassemblingDecoder::VisitUnconditionalBranchToRegister(
537 Instruction* instr) { 540 Instruction* instr) {
538 const char *mnemonic = "unimplemented"; 541 const char *mnemonic = "unimplemented";
539 const char *form = "'Xn"; 542 const char *form = "'Xn";
540 543
541 switch (instr->Mask(UnconditionalBranchToRegisterMask)) { 544 switch (instr->Mask(UnconditionalBranchToRegisterMask)) {
542 case BR: mnemonic = "br"; break; 545 case BR: mnemonic = "br"; break;
543 case BLR: mnemonic = "blr"; break; 546 case BLR: mnemonic = "blr"; break;
544 case RET: { 547 case RET: {
545 mnemonic = "ret"; 548 mnemonic = "ret";
546 if (instr->Rn() == kLinkRegCode) { 549 if (instr->Rn() == kLinkRegCode) {
547 form = NULL; 550 form = NULL;
548 } 551 }
549 break; 552 break;
550 } 553 }
551 default: form = "(UnconditionalBranchToRegister)"; 554 default: form = "(UnconditionalBranchToRegister)";
552 } 555 }
553 Format(instr, mnemonic, form); 556 Format(instr, mnemonic, form);
554 } 557 }
555 558
556 559
557 void DisassemblingDecoder::VisitUnconditionalBranch(Instruction* instr) { 560 void DisassemblingDecoder::VisitUnconditionalBranch(Instruction* instr) {
558 const char *mnemonic = ""; 561 const char *mnemonic = "";
559 const char *form = "'BImmUncn"; 562 const char *form = "'TImmUncn";
560 563
561 switch (instr->Mask(UnconditionalBranchMask)) { 564 switch (instr->Mask(UnconditionalBranchMask)) {
562 case B: mnemonic = "b"; break; 565 case B: mnemonic = "b"; break;
563 case BL: mnemonic = "bl"; break; 566 case BL: mnemonic = "bl"; break;
564 default: UNREACHABLE(); 567 default: UNREACHABLE();
565 } 568 }
566 Format(instr, mnemonic, form); 569 Format(instr, mnemonic, form);
567 } 570 }
568 571
569 572
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 break; 685 break;
683 } 686 }
684 default: UNREACHABLE(); 687 default: UNREACHABLE();
685 } 688 }
686 Format(instr, mnemonic, form); 689 Format(instr, mnemonic, form);
687 } 690 }
688 691
689 692
690 void DisassemblingDecoder::VisitCompareBranch(Instruction* instr) { 693 void DisassemblingDecoder::VisitCompareBranch(Instruction* instr) {
691 const char *mnemonic = ""; 694 const char *mnemonic = "";
692 const char *form = "'Rt, 'BImmCmpa"; 695 const char *form = "'Rt, 'TImmCmpa";
693 696
694 switch (instr->Mask(CompareBranchMask)) { 697 switch (instr->Mask(CompareBranchMask)) {
695 case CBZ_w: 698 case CBZ_w:
696 case CBZ_x: mnemonic = "cbz"; break; 699 case CBZ_x: mnemonic = "cbz"; break;
697 case CBNZ_w: 700 case CBNZ_w:
698 case CBNZ_x: mnemonic = "cbnz"; break; 701 case CBNZ_x: mnemonic = "cbnz"; break;
699 default: UNREACHABLE(); 702 default: UNREACHABLE();
700 } 703 }
701 Format(instr, mnemonic, form); 704 Format(instr, mnemonic, form);
702 } 705 }
703 706
704 707
705 void DisassemblingDecoder::VisitTestBranch(Instruction* instr) { 708 void DisassemblingDecoder::VisitTestBranch(Instruction* instr) {
706 const char *mnemonic = ""; 709 const char *mnemonic = "";
707 // If the top bit of the immediate is clear, the tested register is 710 // If the top bit of the immediate is clear, the tested register is
708 // disassembled as Wt, otherwise Xt. As the top bit of the immediate is 711 // disassembled as Wt, otherwise Xt. As the top bit of the immediate is
709 // encoded in bit 31 of the instruction, we can reuse the Rt form, which 712 // encoded in bit 31 of the instruction, we can reuse the Rt form, which
710 // uses bit 31 (normally "sf") to choose the register size. 713 // uses bit 31 (normally "sf") to choose the register size.
711 const char *form = "'Rt, 'IS, 'BImmTest"; 714 const char *form = "'Rt, 'IS, 'TImmTest";
712 715
713 switch (instr->Mask(TestBranchMask)) { 716 switch (instr->Mask(TestBranchMask)) {
714 case TBZ: mnemonic = "tbz"; break; 717 case TBZ: mnemonic = "tbz"; break;
715 case TBNZ: mnemonic = "tbnz"; break; 718 case TBNZ: mnemonic = "tbnz"; break;
716 default: UNREACHABLE(); 719 default: UNREACHABLE();
717 } 720 }
718 Format(instr, mnemonic, form); 721 Format(instr, mnemonic, form);
719 } 722 }
720 723
721 724
722 void DisassemblingDecoder::VisitMoveWideImmediate(Instruction* instr) { 725 void DisassemblingDecoder::VisitMoveWideImmediate(Instruction* instr) {
723 const char *mnemonic = ""; 726 const char *mnemonic = "";
724 const char *form = "'Rd, 'IMoveImm"; 727 const char *form = "'Rd, 'IMoveImm";
725 728
726 // Print the shift separately for movk, to make it clear which half word will 729 // Print the shift separately for movk, to make it clear which half word will
727 // be overwritten. Movn and movz print the computed immediate, which includes 730 // be overwritten. Movn and movz print the computed immediate, which includes
728 // shift calculation. 731 // shift calculation.
729 switch (instr->Mask(MoveWideImmediateMask)) { 732 switch (instr->Mask(MoveWideImmediateMask)) {
730 case MOVN_w: 733 case MOVN_w:
731 case MOVN_x: mnemonic = "movn"; break; 734 case MOVN_x: mnemonic = "movn"; break;
732 case MOVZ_w: 735 case MOVZ_w:
733 case MOVZ_x: mnemonic = "movz"; break; 736 case MOVZ_x: mnemonic = "movz"; break;
734 case MOVK_w: 737 case MOVK_w:
735 case MOVK_x: mnemonic = "movk"; form = "'Rd, 'IMoveLSL"; break; 738 case MOVK_x: mnemonic = "movk"; form = "'Rd, 'IMoveLSL"; break;
736 default: UNREACHABLE(); 739 default: UNREACHABLE();
737 } 740 }
738 Format(instr, mnemonic, form); 741 Format(instr, mnemonic, form);
739 } 742 }
740 743
741 744 #define LOAD_STORE_LIST(V) \
742 #define LOAD_STORE_LIST(V) \ 745 V(STRB_w, "strb", "'Wt") \
743 V(STRB_w, "strb", "'Wt") \ 746 V(STRH_w, "strh", "'Wt") \
744 V(STRH_w, "strh", "'Wt") \ 747 V(STR_w, "str", "'Wt") \
745 V(STR_w, "str", "'Wt") \ 748 V(STR_x, "str", "'Xt") \
746 V(STR_x, "str", "'Xt") \ 749 V(LDRB_w, "ldrb", "'Wt") \
747 V(LDRB_w, "ldrb", "'Wt") \ 750 V(LDRH_w, "ldrh", "'Wt") \
748 V(LDRH_w, "ldrh", "'Wt") \ 751 V(LDR_w, "ldr", "'Wt") \
749 V(LDR_w, "ldr", "'Wt") \ 752 V(LDR_x, "ldr", "'Xt") \
750 V(LDR_x, "ldr", "'Xt") \ 753 V(LDRSB_x, "ldrsb", "'Xt") \
751 V(LDRSB_x, "ldrsb", "'Xt") \ 754 V(LDRSH_x, "ldrsh", "'Xt") \
752 V(LDRSH_x, "ldrsh", "'Xt") \ 755 V(LDRSW_x, "ldrsw", "'Xt") \
753 V(LDRSW_x, "ldrsw", "'Xt") \ 756 V(LDRSB_w, "ldrsb", "'Wt") \
754 V(LDRSB_w, "ldrsb", "'Wt") \ 757 V(LDRSH_w, "ldrsh", "'Wt") \
755 V(LDRSH_w, "ldrsh", "'Wt") \ 758 V(STR_b, "str", "'Bt") \
756 V(STR_s, "str", "'St") \ 759 V(STR_h, "str", "'Ht") \
757 V(STR_d, "str", "'Dt") \ 760 V(STR_s, "str", "'St") \
758 V(LDR_s, "ldr", "'St") \ 761 V(STR_d, "str", "'Dt") \
759 V(LDR_d, "ldr", "'Dt") 762 V(LDR_b, "ldr", "'Bt") \
763 V(LDR_h, "ldr", "'Ht") \
764 V(LDR_s, "ldr", "'St") \
765 V(LDR_d, "ldr", "'Dt") \
766 V(STR_q, "str", "'Qt") \
767 V(LDR_q, "ldr", "'Qt")
760 768
761 void DisassemblingDecoder::VisitLoadStorePreIndex(Instruction* instr) { 769 void DisassemblingDecoder::VisitLoadStorePreIndex(Instruction* instr) {
762 const char *mnemonic = "unimplemented"; 770 const char *mnemonic = "unimplemented";
763 const char *form = "(LoadStorePreIndex)"; 771 const char *form = "(LoadStorePreIndex)";
764 772
765 switch (instr->Mask(LoadStorePreIndexMask)) { 773 switch (instr->Mask(LoadStorePreIndexMask)) {
766 #define LS_PREINDEX(A, B, C) \ 774 #define LS_PREINDEX(A, B, C) \
767 case A##_pre: mnemonic = B; form = C ", ['Xns'ILS]!"; break; 775 case A##_pre: mnemonic = B; form = C ", ['Xns'ILS]!"; break;
768 LOAD_STORE_LIST(LS_PREINDEX) 776 LOAD_STORE_LIST(LS_PREINDEX)
769 #undef LS_PREINDEX 777 #undef LS_PREINDEX
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 switch (instr->Mask(LoadLiteralMask)) { 862 switch (instr->Mask(LoadLiteralMask)) {
855 case LDR_w_lit: form = "'Wt, 'ILLiteral 'LValue"; break; 863 case LDR_w_lit: form = "'Wt, 'ILLiteral 'LValue"; break;
856 case LDR_x_lit: form = "'Xt, 'ILLiteral 'LValue"; break; 864 case LDR_x_lit: form = "'Xt, 'ILLiteral 'LValue"; break;
857 case LDR_s_lit: form = "'St, 'ILLiteral 'LValue"; break; 865 case LDR_s_lit: form = "'St, 'ILLiteral 'LValue"; break;
858 case LDR_d_lit: form = "'Dt, 'ILLiteral 'LValue"; break; 866 case LDR_d_lit: form = "'Dt, 'ILLiteral 'LValue"; break;
859 default: mnemonic = "unimplemented"; 867 default: mnemonic = "unimplemented";
860 } 868 }
861 Format(instr, mnemonic, form); 869 Format(instr, mnemonic, form);
862 } 870 }
863 871
864
865 #define LOAD_STORE_PAIR_LIST(V) \ 872 #define LOAD_STORE_PAIR_LIST(V) \
866 V(STP_w, "stp", "'Wt, 'Wt2", "4") \ 873 V(STP_w, "stp", "'Wt, 'Wt2", "2") \
867 V(LDP_w, "ldp", "'Wt, 'Wt2", "4") \ 874 V(LDP_w, "ldp", "'Wt, 'Wt2", "2") \
868 V(LDPSW_x, "ldpsw", "'Xt, 'Xt2", "4") \ 875 V(LDPSW_x, "ldpsw", "'Xt, 'Xt2", "2") \
869 V(STP_x, "stp", "'Xt, 'Xt2", "8") \ 876 V(STP_x, "stp", "'Xt, 'Xt2", "3") \
870 V(LDP_x, "ldp", "'Xt, 'Xt2", "8") \ 877 V(LDP_x, "ldp", "'Xt, 'Xt2", "3") \
871 V(STP_s, "stp", "'St, 'St2", "4") \ 878 V(STP_s, "stp", "'St, 'St2", "2") \
872 V(LDP_s, "ldp", "'St, 'St2", "4") \ 879 V(LDP_s, "ldp", "'St, 'St2", "2") \
873 V(STP_d, "stp", "'Dt, 'Dt2", "8") \ 880 V(STP_d, "stp", "'Dt, 'Dt2", "3") \
874 V(LDP_d, "ldp", "'Dt, 'Dt2", "8") 881 V(LDP_d, "ldp", "'Dt, 'Dt2", "3") \
882 V(LDP_q, "ldp", "'Qt, 'Qt2", "4") \
883 V(STP_q, "stp", "'Qt, 'Qt2", "4")
875 884
876 void DisassemblingDecoder::VisitLoadStorePairPostIndex(Instruction* instr) { 885 void DisassemblingDecoder::VisitLoadStorePairPostIndex(Instruction* instr) {
877 const char *mnemonic = "unimplemented"; 886 const char *mnemonic = "unimplemented";
878 const char *form = "(LoadStorePairPostIndex)"; 887 const char *form = "(LoadStorePairPostIndex)";
879 888
880 switch (instr->Mask(LoadStorePairPostIndexMask)) { 889 switch (instr->Mask(LoadStorePairPostIndexMask)) {
881 #define LSP_POSTINDEX(A, B, C, D) \ 890 #define LSP_POSTINDEX(A, B, C, D) \
882 case A##_post: mnemonic = B; form = C ", ['Xns]'ILP" D; break; 891 case A##_post: mnemonic = B; form = C ", ['Xns]'ILP" D; break;
883 LOAD_STORE_PAIR_LIST(LSP_POSTINDEX) 892 LOAD_STORE_PAIR_LIST(LSP_POSTINDEX)
884 #undef LSP_POSTINDEX 893 #undef LSP_POSTINDEX
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 FORMAT(FRINTN, "frintn"); 1011 FORMAT(FRINTN, "frintn");
1003 FORMAT(FRINTP, "frintp"); 1012 FORMAT(FRINTP, "frintp");
1004 FORMAT(FRINTM, "frintm"); 1013 FORMAT(FRINTM, "frintm");
1005 FORMAT(FRINTZ, "frintz"); 1014 FORMAT(FRINTZ, "frintz");
1006 FORMAT(FRINTA, "frinta"); 1015 FORMAT(FRINTA, "frinta");
1007 FORMAT(FRINTX, "frintx"); 1016 FORMAT(FRINTX, "frintx");
1008 FORMAT(FRINTI, "frinti"); 1017 FORMAT(FRINTI, "frinti");
1009 #undef FORMAT 1018 #undef FORMAT
1010 case FCVT_ds: mnemonic = "fcvt"; form = "'Dd, 'Sn"; break; 1019 case FCVT_ds: mnemonic = "fcvt"; form = "'Dd, 'Sn"; break;
1011 case FCVT_sd: mnemonic = "fcvt"; form = "'Sd, 'Dn"; break; 1020 case FCVT_sd: mnemonic = "fcvt"; form = "'Sd, 'Dn"; break;
1021 case FCVT_hs:
1022 mnemonic = "fcvt";
1023 form = "'Hd, 'Sn";
1024 break;
1025 case FCVT_sh:
1026 mnemonic = "fcvt";
1027 form = "'Sd, 'Hn";
1028 break;
1029 case FCVT_dh:
1030 mnemonic = "fcvt";
1031 form = "'Dd, 'Hn";
1032 break;
1033 case FCVT_hd:
1034 mnemonic = "fcvt";
1035 form = "'Hd, 'Dn";
1036 break;
1012 default: form = "(FPDataProcessing1Source)"; 1037 default: form = "(FPDataProcessing1Source)";
1013 } 1038 }
1014 Format(instr, mnemonic, form); 1039 Format(instr, mnemonic, form);
1015 } 1040 }
1016 1041
1017 1042
1018 void DisassemblingDecoder::VisitFPDataProcessing2Source(Instruction* instr) { 1043 void DisassemblingDecoder::VisitFPDataProcessing2Source(Instruction* instr) {
1019 const char *mnemonic = ""; 1044 const char *mnemonic = "";
1020 const char *form = "'Fd, 'Fn, 'Fm"; 1045 const char *form = "'Fd, 'Fn, 'Fm";
1021 1046
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 const char *mnemonic = "unimplemented"; 1100 const char *mnemonic = "unimplemented";
1076 const char *form = "(FPIntegerConvert)"; 1101 const char *form = "(FPIntegerConvert)";
1077 const char *form_rf = "'Rd, 'Fn"; 1102 const char *form_rf = "'Rd, 'Fn";
1078 const char *form_fr = "'Fd, 'Rn"; 1103 const char *form_fr = "'Fd, 'Rn";
1079 1104
1080 switch (instr->Mask(FPIntegerConvertMask)) { 1105 switch (instr->Mask(FPIntegerConvertMask)) {
1081 case FMOV_ws: 1106 case FMOV_ws:
1082 case FMOV_xd: mnemonic = "fmov"; form = form_rf; break; 1107 case FMOV_xd: mnemonic = "fmov"; form = form_rf; break;
1083 case FMOV_sw: 1108 case FMOV_sw:
1084 case FMOV_dx: mnemonic = "fmov"; form = form_fr; break; 1109 case FMOV_dx: mnemonic = "fmov"; form = form_fr; break;
1110 case FMOV_d1_x:
1111 mnemonic = "fmov";
1112 form = "'Vd.D[1], 'Rn";
1113 break;
1114 case FMOV_x_d1:
1115 mnemonic = "fmov";
1116 form = "'Rd, 'Vn.D[1]";
1117 break;
1085 case FCVTAS_ws: 1118 case FCVTAS_ws:
1086 case FCVTAS_xs: 1119 case FCVTAS_xs:
1087 case FCVTAS_wd: 1120 case FCVTAS_wd:
1088 case FCVTAS_xd: mnemonic = "fcvtas"; form = form_rf; break; 1121 case FCVTAS_xd: mnemonic = "fcvtas"; form = form_rf; break;
1089 case FCVTAU_ws: 1122 case FCVTAU_ws:
1090 case FCVTAU_xs: 1123 case FCVTAU_xs:
1091 case FCVTAU_wd: 1124 case FCVTAU_wd:
1092 case FCVTAU_xd: mnemonic = "fcvtau"; form = form_rf; break; 1125 case FCVTAU_xd: mnemonic = "fcvtau"; form = form_rf; break;
1093 case FCVTMS_ws: 1126 case FCVTMS_ws:
1094 case FCVTMS_xs: 1127 case FCVTMS_xs:
(...skipping 12 matching lines...) Expand all
1107 case FCVTNU_wd: 1140 case FCVTNU_wd:
1108 case FCVTNU_xd: mnemonic = "fcvtnu"; form = form_rf; break; 1141 case FCVTNU_xd: mnemonic = "fcvtnu"; form = form_rf; break;
1109 case FCVTZU_xd: 1142 case FCVTZU_xd:
1110 case FCVTZU_ws: 1143 case FCVTZU_ws:
1111 case FCVTZU_wd: 1144 case FCVTZU_wd:
1112 case FCVTZU_xs: mnemonic = "fcvtzu"; form = form_rf; break; 1145 case FCVTZU_xs: mnemonic = "fcvtzu"; form = form_rf; break;
1113 case FCVTZS_xd: 1146 case FCVTZS_xd:
1114 case FCVTZS_wd: 1147 case FCVTZS_wd:
1115 case FCVTZS_xs: 1148 case FCVTZS_xs:
1116 case FCVTZS_ws: mnemonic = "fcvtzs"; form = form_rf; break; 1149 case FCVTZS_ws: mnemonic = "fcvtzs"; form = form_rf; break;
1150 case FCVTPU_xd:
1151 case FCVTPU_ws:
1152 case FCVTPU_wd:
1153 case FCVTPU_xs:
1154 mnemonic = "fcvtpu";
1155 form = form_rf;
1156 break;
1157 case FCVTPS_xd:
1158 case FCVTPS_wd:
1159 case FCVTPS_xs:
1160 case FCVTPS_ws:
1161 mnemonic = "fcvtps";
1162 form = form_rf;
1163 break;
1117 case SCVTF_sw: 1164 case SCVTF_sw:
1118 case SCVTF_sx: 1165 case SCVTF_sx:
1119 case SCVTF_dw: 1166 case SCVTF_dw:
1120 case SCVTF_dx: mnemonic = "scvtf"; form = form_fr; break; 1167 case SCVTF_dx: mnemonic = "scvtf"; form = form_fr; break;
1121 case UCVTF_sw: 1168 case UCVTF_sw:
1122 case UCVTF_sx: 1169 case UCVTF_sx:
1123 case UCVTF_dw: 1170 case UCVTF_dw:
1124 case UCVTF_dx: mnemonic = "ucvtf"; form = form_fr; break; 1171 case UCVTF_dx: mnemonic = "ucvtf"; form = form_fr; break;
1125 } 1172 }
1126 Format(instr, mnemonic, form); 1173 Format(instr, mnemonic, form);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 case HVC: mnemonic = "hvc"; break; 1273 case HVC: mnemonic = "hvc"; break;
1227 case SMC: mnemonic = "smc"; break; 1274 case SMC: mnemonic = "smc"; break;
1228 case DCPS1: mnemonic = "dcps1"; form = "{'IDebug}"; break; 1275 case DCPS1: mnemonic = "dcps1"; form = "{'IDebug}"; break;
1229 case DCPS2: mnemonic = "dcps2"; form = "{'IDebug}"; break; 1276 case DCPS2: mnemonic = "dcps2"; form = "{'IDebug}"; break;
1230 case DCPS3: mnemonic = "dcps3"; form = "{'IDebug}"; break; 1277 case DCPS3: mnemonic = "dcps3"; form = "{'IDebug}"; break;
1231 default: form = "(Exception)"; 1278 default: form = "(Exception)";
1232 } 1279 }
1233 Format(instr, mnemonic, form); 1280 Format(instr, mnemonic, form);
1234 } 1281 }
1235 1282
1236 1283 void DisassemblingDecoder::VisitNEON3Same(Instruction *instr) {
1237 void DisassemblingDecoder::VisitUnimplemented(Instruction* instr) { 1284 const char *mnemonic = "unimplemented";
1285 const char *form = "'Vd.%s, 'Vn.%s, 'Vm.%s";
1286 NEONFormatDecoder nfd(instr);
1287
1288 if (instr->Mask(NEON3SameLogicalFMask) == NEON3SameLogicalFixed) {
1289 switch (instr->Mask(NEON3SameLogicalMask)) {
1290 case NEON_AND:
1291 mnemonic = "and";
1292 break;
1293 case NEON_ORR:
1294 mnemonic = "orr";
1295 if (instr->Rm() == instr->Rn()) {
1296 mnemonic = "mov";
1297 form = "'Vd.%s, 'Vn.%s";
1298 }
1299 break;
1300 case NEON_ORN:
1301 mnemonic = "orn";
1302 break;
1303 case NEON_EOR:
1304 mnemonic = "eor";
1305 break;
1306 case NEON_BIC:
1307 mnemonic = "bic";
1308 break;
1309 case NEON_BIF:
1310 mnemonic = "bif";
1311 break;
1312 case NEON_BIT:
1313 mnemonic = "bit";
1314 break;
1315 case NEON_BSL:
1316 mnemonic = "bsl";
1317 break;
1318 default:
1319 form = "(NEON3Same)";
1320 }
1321 nfd.SetFormatMaps(nfd.LogicalFormatMap());
1322 } else {
1323 static const char *mnemonics[] = {
1324 "shadd", "uhadd", "shadd", "uhadd",
1325 "sqadd", "uqadd", "sqadd", "uqadd",
1326 "srhadd", "urhadd", "srhadd", "urhadd",
1327 NULL, NULL, NULL,
1328 NULL, // Handled by logical cases above.
1329 "shsub", "uhsub", "shsub", "uhsub",
1330 "sqsub", "uqsub", "sqsub", "uqsub",
1331 "cmgt", "cmhi", "cmgt", "cmhi",
1332 "cmge", "cmhs", "cmge", "cmhs",
1333 "sshl", "ushl", "sshl", "ushl",
1334 "sqshl", "uqshl", "sqshl", "uqshl",
1335 "srshl", "urshl", "srshl", "urshl",
1336 "sqrshl", "uqrshl", "sqrshl", "uqrshl",
1337 "smax", "umax", "smax", "umax",
1338 "smin", "umin", "smin", "umin",
1339 "sabd", "uabd", "sabd", "uabd",
1340 "saba", "uaba", "saba", "uaba",
1341 "add", "sub", "add", "sub",
1342 "cmtst", "cmeq", "cmtst", "cmeq",
1343 "mla", "mls", "mla", "mls",
1344 "mul", "pmul", "mul", "pmul",
1345 "smaxp", "umaxp", "smaxp", "umaxp",
1346 "sminp", "uminp", "sminp", "uminp",
1347 "sqdmulh", "sqrdmulh", "sqdmulh", "sqrdmulh",
1348 "addp", "unallocated", "addp", "unallocated",
1349 "fmaxnm", "fmaxnmp", "fminnm", "fminnmp",
1350 "fmla", "unallocated", "fmls", "unallocated",
1351 "fadd", "faddp", "fsub", "fabd",
1352 "fmulx", "fmul", "unallocated", "unallocated",
1353 "fcmeq", "fcmge", "unallocated", "fcmgt",
1354 "unallocated", "facge", "unallocated", "facgt",
1355 "fmax", "fmaxp", "fmin", "fminp",
1356 "frecps", "fdiv", "frsqrts", "unallocated"};
1357
1358 // Operation is determined by the opcode bits (15-11), the top bit of
1359 // size (23) and the U bit (29).
1360 unsigned index =
1361 (instr->Bits(15, 11) << 2) | (instr->Bit(23) << 1) | instr->Bit(29);
1362 DCHECK_LT(index, arraysize(mnemonics));
1363 mnemonic = mnemonics[index];
1364 // Assert that index is not one of the previously handled logical
1365 // instructions.
1366 DCHECK_NOT_NULL(mnemonic);
1367
1368 if (instr->Mask(NEON3SameFPFMask) == NEON3SameFPFixed) {
1369 nfd.SetFormatMaps(nfd.FPFormatMap());
1370 }
1371 }
1372 Format(instr, mnemonic, nfd.Substitute(form));
1373 }
1374
1375 void DisassemblingDecoder::VisitNEON2RegMisc(Instruction *instr) {
1376 const char *mnemonic = "unimplemented";
1377 const char *form = "'Vd.%s, 'Vn.%s";
1378 const char *form_cmp_zero = "'Vd.%s, 'Vn.%s, #0";
1379 const char *form_fcmp_zero = "'Vd.%s, 'Vn.%s, #0.0";
1380 NEONFormatDecoder nfd(instr);
1381
1382 static const NEONFormatMap map_lp_ta = {
1383 {23, 22, 30}, {NF_4H, NF_8H, NF_2S, NF_4S, NF_1D, NF_2D}};
bbudge 2017/01/31 01:41:32 Could you define some constants to make it clearer
martyn.capewell 2017/02/03 11:01:31 They're just bit positions in the instruction, so
bbudge 2017/02/08 01:39:11 I see. It's OK like this then.
1384
1385 static const NEONFormatMap map_cvt_ta = {{22}, {NF_4S, NF_2D}};
1386
1387 static const NEONFormatMap map_cvt_tb = {{22, 30},
1388 {NF_4H, NF_8H, NF_2S, NF_4S}};
1389
1390 if (instr->Mask(NEON2RegMiscOpcode) <= NEON_NEG_opcode) {
1391 // These instructions all use a two bit size field, except NOT and RBIT,
1392 // which use the field to encode the operation.
1393 switch (instr->Mask(NEON2RegMiscMask)) {
1394 case NEON_REV64:
1395 mnemonic = "rev64";
1396 break;
1397 case NEON_REV32:
1398 mnemonic = "rev32";
1399 break;
1400 case NEON_REV16:
1401 mnemonic = "rev16";
1402 break;
1403 case NEON_SADDLP:
1404 mnemonic = "saddlp";
1405 nfd.SetFormatMap(0, &map_lp_ta);
1406 break;
1407 case NEON_UADDLP:
1408 mnemonic = "uaddlp";
1409 nfd.SetFormatMap(0, &map_lp_ta);
1410 break;
1411 case NEON_SUQADD:
1412 mnemonic = "suqadd";
1413 break;
1414 case NEON_USQADD:
1415 mnemonic = "usqadd";
1416 break;
1417 case NEON_CLS:
1418 mnemonic = "cls";
1419 break;
1420 case NEON_CLZ:
1421 mnemonic = "clz";
1422 break;
1423 case NEON_CNT:
1424 mnemonic = "cnt";
1425 break;
1426 case NEON_SADALP:
1427 mnemonic = "sadalp";
1428 nfd.SetFormatMap(0, &map_lp_ta);
1429 break;
1430 case NEON_UADALP:
1431 mnemonic = "uadalp";
1432 nfd.SetFormatMap(0, &map_lp_ta);
1433 break;
1434 case NEON_SQABS:
1435 mnemonic = "sqabs";
1436 break;
1437 case NEON_SQNEG:
1438 mnemonic = "sqneg";
1439 break;
1440 case NEON_CMGT_zero:
1441 mnemonic = "cmgt";
1442 form = form_cmp_zero;
1443 break;
1444 case NEON_CMGE_zero:
1445 mnemonic = "cmge";
1446 form = form_cmp_zero;
1447 break;
1448 case NEON_CMEQ_zero:
1449 mnemonic = "cmeq";
1450 form = form_cmp_zero;
1451 break;
1452 case NEON_CMLE_zero:
1453 mnemonic = "cmle";
1454 form = form_cmp_zero;
1455 break;
1456 case NEON_CMLT_zero:
1457 mnemonic = "cmlt";
1458 form = form_cmp_zero;
1459 break;
1460 case NEON_ABS:
1461 mnemonic = "abs";
1462 break;
1463 case NEON_NEG:
1464 mnemonic = "neg";
1465 break;
1466 case NEON_RBIT_NOT:
1467 switch (instr->FPType()) {
1468 case 0:
1469 mnemonic = "mvn";
1470 break;
1471 case 1:
1472 mnemonic = "rbit";
1473 break;
1474 default:
1475 form = "(NEON2RegMisc)";
1476 }
1477 nfd.SetFormatMaps(nfd.LogicalFormatMap());
1478 break;
1479 }
1480 } else {
1481 // These instructions all use a one bit size field, except XTN, SQXTUN,
1482 // SHLL, SQXTN and UQXTN, which use a two bit size field.
1483 nfd.SetFormatMaps(nfd.FPFormatMap());
1484 switch (instr->Mask(NEON2RegMiscFPMask)) {
1485 case NEON_FABS:
1486 mnemonic = "fabs";
1487 break;
1488 case NEON_FNEG:
1489 mnemonic = "fneg";
1490 break;
1491 case NEON_FCVTN:
1492 mnemonic = instr->Mask(NEON_Q) ? "fcvtn2" : "fcvtn";
1493 nfd.SetFormatMap(0, &map_cvt_tb);
1494 nfd.SetFormatMap(1, &map_cvt_ta);
1495 break;
1496 case NEON_FCVTXN:
1497 mnemonic = instr->Mask(NEON_Q) ? "fcvtxn2" : "fcvtxn";
1498 nfd.SetFormatMap(0, &map_cvt_tb);
1499 nfd.SetFormatMap(1, &map_cvt_ta);
1500 break;
1501 case NEON_FCVTL:
1502 mnemonic = instr->Mask(NEON_Q) ? "fcvtl2" : "fcvtl";
1503 nfd.SetFormatMap(0, &map_cvt_ta);
1504 nfd.SetFormatMap(1, &map_cvt_tb);
1505 break;
1506 case NEON_FRINTN:
1507 mnemonic = "frintn";
1508 break;
1509 case NEON_FRINTA:
1510 mnemonic = "frinta";
1511 break;
1512 case NEON_FRINTP:
1513 mnemonic = "frintp";
1514 break;
1515 case NEON_FRINTM:
1516 mnemonic = "frintm";
1517 break;
1518 case NEON_FRINTX:
1519 mnemonic = "frintx";
1520 break;
1521 case NEON_FRINTZ:
1522 mnemonic = "frintz";
1523 break;
1524 case NEON_FRINTI:
1525 mnemonic = "frinti";
1526 break;
1527 case NEON_FCVTNS:
1528 mnemonic = "fcvtns";
1529 break;
1530 case NEON_FCVTNU:
1531 mnemonic = "fcvtnu";
1532 break;
1533 case NEON_FCVTPS:
1534 mnemonic = "fcvtps";
1535 break;
1536 case NEON_FCVTPU:
1537 mnemonic = "fcvtpu";
1538 break;
1539 case NEON_FCVTMS:
1540 mnemonic = "fcvtms";
1541 break;
1542 case NEON_FCVTMU:
1543 mnemonic = "fcvtmu";
1544 break;
1545 case NEON_FCVTZS:
1546 mnemonic = "fcvtzs";
1547 break;
1548 case NEON_FCVTZU:
1549 mnemonic = "fcvtzu";
1550 break;
1551 case NEON_FCVTAS:
1552 mnemonic = "fcvtas";
1553 break;
1554 case NEON_FCVTAU:
1555 mnemonic = "fcvtau";
1556 break;
1557 case NEON_FSQRT:
1558 mnemonic = "fsqrt";
1559 break;
1560 case NEON_SCVTF:
1561 mnemonic = "scvtf";
1562 break;
1563 case NEON_UCVTF:
1564 mnemonic = "ucvtf";
1565 break;
1566 case NEON_URSQRTE:
1567 mnemonic = "ursqrte";
1568 break;
1569 case NEON_URECPE:
1570 mnemonic = "urecpe";
1571 break;
1572 case NEON_FRSQRTE:
1573 mnemonic = "frsqrte";
1574 break;
1575 case NEON_FRECPE:
1576 mnemonic = "frecpe";
1577 break;
1578 case NEON_FCMGT_zero:
1579 mnemonic = "fcmgt";
1580 form = form_fcmp_zero;
1581 break;
1582 case NEON_FCMGE_zero:
1583 mnemonic = "fcmge";
1584 form = form_fcmp_zero;
1585 break;
1586 case NEON_FCMEQ_zero:
1587 mnemonic = "fcmeq";
1588 form = form_fcmp_zero;
1589 break;
1590 case NEON_FCMLE_zero:
1591 mnemonic = "fcmle";
1592 form = form_fcmp_zero;
1593 break;
1594 case NEON_FCMLT_zero:
1595 mnemonic = "fcmlt";
1596 form = form_fcmp_zero;
1597 break;
1598 default:
1599 if ((NEON_XTN_opcode <= instr->Mask(NEON2RegMiscOpcode)) &&
1600 (instr->Mask(NEON2RegMiscOpcode) <= NEON_UQXTN_opcode)) {
1601 nfd.SetFormatMap(0, nfd.IntegerFormatMap());
1602 nfd.SetFormatMap(1, nfd.LongIntegerFormatMap());
1603
1604 switch (instr->Mask(NEON2RegMiscMask)) {
1605 case NEON_XTN:
1606 mnemonic = "xtn";
1607 break;
1608 case NEON_SQXTN:
1609 mnemonic = "sqxtn";
1610 break;
1611 case NEON_UQXTN:
1612 mnemonic = "uqxtn";
1613 break;
1614 case NEON_SQXTUN:
1615 mnemonic = "sqxtun";
1616 break;
1617 case NEON_SHLL:
1618 mnemonic = "shll";
1619 nfd.SetFormatMap(0, nfd.LongIntegerFormatMap());
1620 nfd.SetFormatMap(1, nfd.IntegerFormatMap());
1621 switch (instr->NEONSize()) {
1622 case 0:
1623 form = "'Vd.%s, 'Vn.%s, #8";
1624 break;
1625 case 1:
1626 form = "'Vd.%s, 'Vn.%s, #16";
1627 break;
1628 case 2:
1629 form = "'Vd.%s, 'Vn.%s, #32";
1630 break;
1631 default:
1632 Format(instr, "unallocated", "(NEON2RegMisc)");
1633 return;
1634 }
1635 }
1636 Format(instr, nfd.Mnemonic(mnemonic), nfd.Substitute(form));
1637 return;
1638 } else {
1639 form = "(NEON2RegMisc)";
1640 }
1641 }
1642 }
1643 Format(instr, mnemonic, nfd.Substitute(form));
1644 }
1645
1646 void DisassemblingDecoder::VisitNEON3Different(Instruction *instr) {
1647 const char *mnemonic = "unimplemented";
1648 const char *form = "'Vd.%s, 'Vn.%s, 'Vm.%s";
1649
1650 NEONFormatDecoder nfd(instr);
1651 nfd.SetFormatMap(0, nfd.LongIntegerFormatMap());
1652
1653 // Ignore the Q bit. Appending a "2" suffix is handled later.
1654 switch (instr->Mask(NEON3DifferentMask) & ~NEON_Q) {
1655 case NEON_PMULL:
1656 mnemonic = "pmull";
1657 break;
1658 case NEON_SABAL:
1659 mnemonic = "sabal";
1660 break;
1661 case NEON_SABDL:
1662 mnemonic = "sabdl";
1663 break;
1664 case NEON_SADDL:
1665 mnemonic = "saddl";
1666 break;
1667 case NEON_SMLAL:
1668 mnemonic = "smlal";
1669 break;
1670 case NEON_SMLSL:
1671 mnemonic = "smlsl";
1672 break;
1673 case NEON_SMULL:
1674 mnemonic = "smull";
1675 break;
1676 case NEON_SSUBL:
1677 mnemonic = "ssubl";
1678 break;
1679 case NEON_SQDMLAL:
1680 mnemonic = "sqdmlal";
1681 break;
1682 case NEON_SQDMLSL:
1683 mnemonic = "sqdmlsl";
1684 break;
1685 case NEON_SQDMULL:
1686 mnemonic = "sqdmull";
1687 break;
1688 case NEON_UABAL:
1689 mnemonic = "uabal";
1690 break;
1691 case NEON_UABDL:
1692 mnemonic = "uabdl";
1693 break;
1694 case NEON_UADDL:
1695 mnemonic = "uaddl";
1696 break;
1697 case NEON_UMLAL:
1698 mnemonic = "umlal";
1699 break;
1700 case NEON_UMLSL:
1701 mnemonic = "umlsl";
1702 break;
1703 case NEON_UMULL:
1704 mnemonic = "umull";
1705 break;
1706 case NEON_USUBL:
1707 mnemonic = "usubl";
1708 break;
1709 case NEON_SADDW:
1710 mnemonic = "saddw";
1711 nfd.SetFormatMap(1, nfd.LongIntegerFormatMap());
1712 break;
1713 case NEON_SSUBW:
1714 mnemonic = "ssubw";
1715 nfd.SetFormatMap(1, nfd.LongIntegerFormatMap());
1716 break;
1717 case NEON_UADDW:
1718 mnemonic = "uaddw";
1719 nfd.SetFormatMap(1, nfd.LongIntegerFormatMap());
1720 break;
1721 case NEON_USUBW:
1722 mnemonic = "usubw";
1723 nfd.SetFormatMap(1, nfd.LongIntegerFormatMap());
1724 break;
1725 case NEON_ADDHN:
1726 mnemonic = "addhn";
1727 nfd.SetFormatMaps(nfd.LongIntegerFormatMap());
1728 nfd.SetFormatMap(0, nfd.IntegerFormatMap());
1729 break;
1730 case NEON_RADDHN:
1731 mnemonic = "raddhn";
1732 nfd.SetFormatMaps(nfd.LongIntegerFormatMap());
1733 nfd.SetFormatMap(0, nfd.IntegerFormatMap());
1734 break;
1735 case NEON_RSUBHN:
1736 mnemonic = "rsubhn";
1737 nfd.SetFormatMaps(nfd.LongIntegerFormatMap());
1738 nfd.SetFormatMap(0, nfd.IntegerFormatMap());
1739 break;
1740 case NEON_SUBHN:
1741 mnemonic = "subhn";
1742 nfd.SetFormatMaps(nfd.LongIntegerFormatMap());
1743 nfd.SetFormatMap(0, nfd.IntegerFormatMap());
1744 break;
1745 default:
1746 form = "(NEON3Different)";
1747 }
1748 Format(instr, nfd.Mnemonic(mnemonic), nfd.Substitute(form));
1749 }
1750
1751 void DisassemblingDecoder::VisitNEONAcrossLanes(Instruction *instr) {
1752 const char *mnemonic = "unimplemented";
1753 const char *form = "%sd, 'Vn.%s";
1754
1755 NEONFormatDecoder nfd(instr, NEONFormatDecoder::ScalarFormatMap(),
1756 NEONFormatDecoder::IntegerFormatMap());
1757
1758 if (instr->Mask(NEONAcrossLanesFPFMask) == NEONAcrossLanesFPFixed) {
1759 nfd.SetFormatMap(0, nfd.FPScalarFormatMap());
1760 nfd.SetFormatMap(1, nfd.FPFormatMap());
1761 switch (instr->Mask(NEONAcrossLanesFPMask)) {
1762 case NEON_FMAXV:
1763 mnemonic = "fmaxv";
1764 break;
1765 case NEON_FMINV:
1766 mnemonic = "fminv";
1767 break;
1768 case NEON_FMAXNMV:
1769 mnemonic = "fmaxnmv";
1770 break;
1771 case NEON_FMINNMV:
1772 mnemonic = "fminnmv";
1773 break;
1774 default:
1775 form = "(NEONAcrossLanes)";
1776 break;
1777 }
1778 } else if (instr->Mask(NEONAcrossLanesFMask) == NEONAcrossLanesFixed) {
1779 switch (instr->Mask(NEONAcrossLanesMask)) {
1780 case NEON_ADDV:
1781 mnemonic = "addv";
1782 break;
1783 case NEON_SMAXV:
1784 mnemonic = "smaxv";
1785 break;
1786 case NEON_SMINV:
1787 mnemonic = "sminv";
1788 break;
1789 case NEON_UMAXV:
1790 mnemonic = "umaxv";
1791 break;
1792 case NEON_UMINV:
1793 mnemonic = "uminv";
1794 break;
1795 case NEON_SADDLV:
1796 mnemonic = "saddlv";
1797 nfd.SetFormatMap(0, nfd.LongScalarFormatMap());
1798 break;
1799 case NEON_UADDLV:
1800 mnemonic = "uaddlv";
1801 nfd.SetFormatMap(0, nfd.LongScalarFormatMap());
1802 break;
1803 default:
1804 form = "(NEONAcrossLanes)";
1805 break;
1806 }
1807 }
1808 Format(instr, mnemonic, nfd.Substitute(form, NEONFormatDecoder::kPlaceholder,
1809 NEONFormatDecoder::kFormat));
1810 }
1811
1812 void DisassemblingDecoder::VisitNEONByIndexedElement(Instruction *instr) {
1813 const char *mnemonic = "unimplemented";
1814 bool l_instr = false;
1815 bool fp_instr = false;
1816
1817 const char *form = "'Vd.%s, 'Vn.%s, 'Ve.%s['IVByElemIndex]";
1818
1819 static const NEONFormatMap map_ta = {{23, 22}, {NF_UNDEF, NF_4S, NF_2D}};
bbudge 2017/01/31 01:41:32 magic numbers
bbudge 2017/02/08 01:39:11 OK
1820 NEONFormatDecoder nfd(instr, &map_ta, NEONFormatDecoder::IntegerFormatMap(),
1821 NEONFormatDecoder::ScalarFormatMap());
1822
1823 switch (instr->Mask(NEONByIndexedElementMask)) {
1824 case NEON_SMULL_byelement:
1825 mnemonic = "smull";
1826 l_instr = true;
1827 break;
1828 case NEON_UMULL_byelement:
1829 mnemonic = "umull";
1830 l_instr = true;
1831 break;
1832 case NEON_SMLAL_byelement:
1833 mnemonic = "smlal";
1834 l_instr = true;
1835 break;
1836 case NEON_UMLAL_byelement:
1837 mnemonic = "umlal";
1838 l_instr = true;
1839 break;
1840 case NEON_SMLSL_byelement:
1841 mnemonic = "smlsl";
1842 l_instr = true;
1843 break;
1844 case NEON_UMLSL_byelement:
1845 mnemonic = "umlsl";
1846 l_instr = true;
1847 break;
1848 case NEON_SQDMULL_byelement:
1849 mnemonic = "sqdmull";
1850 l_instr = true;
1851 break;
1852 case NEON_SQDMLAL_byelement:
1853 mnemonic = "sqdmlal";
1854 l_instr = true;
1855 break;
1856 case NEON_SQDMLSL_byelement:
1857 mnemonic = "sqdmlsl";
1858 l_instr = true;
1859 break;
1860 case NEON_MUL_byelement:
1861 mnemonic = "mul";
1862 break;
1863 case NEON_MLA_byelement:
1864 mnemonic = "mla";
1865 break;
1866 case NEON_MLS_byelement:
1867 mnemonic = "mls";
1868 break;
1869 case NEON_SQDMULH_byelement:
1870 mnemonic = "sqdmulh";
1871 break;
1872 case NEON_SQRDMULH_byelement:
1873 mnemonic = "sqrdmulh";
1874 break;
1875 default:
1876 switch (instr->Mask(NEONByIndexedElementFPMask)) {
1877 case NEON_FMUL_byelement:
1878 mnemonic = "fmul";
1879 fp_instr = true;
1880 break;
1881 case NEON_FMLA_byelement:
1882 mnemonic = "fmla";
1883 fp_instr = true;
1884 break;
1885 case NEON_FMLS_byelement:
1886 mnemonic = "fmls";
1887 fp_instr = true;
1888 break;
1889 case NEON_FMULX_byelement:
1890 mnemonic = "fmulx";
1891 fp_instr = true;
1892 break;
1893 }
1894 }
1895
1896 if (l_instr) {
1897 Format(instr, nfd.Mnemonic(mnemonic), nfd.Substitute(form));
1898 } else if (fp_instr) {
1899 nfd.SetFormatMap(0, nfd.FPFormatMap());
1900 Format(instr, mnemonic, nfd.Substitute(form));
1901 } else {
1902 nfd.SetFormatMap(0, nfd.IntegerFormatMap());
1903 Format(instr, mnemonic, nfd.Substitute(form));
1904 }
1905 }
1906
1907 void DisassemblingDecoder::VisitNEONCopy(Instruction *instr) {
1908 const char *mnemonic = "unimplemented";
1909 const char *form = "(NEONCopy)";
1910
1911 NEONFormatDecoder nfd(instr, NEONFormatDecoder::TriangularFormatMap(),
1912 NEONFormatDecoder::TriangularScalarFormatMap());
1913
1914 if (instr->Mask(NEONCopyInsElementMask) == NEON_INS_ELEMENT) {
1915 mnemonic = "mov";
1916 nfd.SetFormatMap(0, nfd.TriangularScalarFormatMap());
1917 form = "'Vd.%s['IVInsIndex1], 'Vn.%s['IVInsIndex2]";
1918 } else if (instr->Mask(NEONCopyInsGeneralMask) == NEON_INS_GENERAL) {
1919 mnemonic = "mov";
1920 nfd.SetFormatMap(0, nfd.TriangularScalarFormatMap());
1921 if (nfd.GetVectorFormat() == kFormatD) {
1922 form = "'Vd.%s['IVInsIndex1], 'Xn";
1923 } else {
1924 form = "'Vd.%s['IVInsIndex1], 'Wn";
1925 }
1926 } else if (instr->Mask(NEONCopyUmovMask) == NEON_UMOV) {
1927 if (instr->Mask(NEON_Q) || ((instr->ImmNEON5() & 7) == 4)) {
1928 mnemonic = "mov";
1929 } else {
1930 mnemonic = "umov";
1931 }
1932 nfd.SetFormatMap(0, nfd.TriangularScalarFormatMap());
1933 if (nfd.GetVectorFormat() == kFormatD) {
1934 form = "'Xd, 'Vn.%s['IVInsIndex1]";
1935 } else {
1936 form = "'Wd, 'Vn.%s['IVInsIndex1]";
1937 }
1938 } else if (instr->Mask(NEONCopySmovMask) == NEON_SMOV) {
1939 mnemonic = "smov";
1940 nfd.SetFormatMap(0, nfd.TriangularScalarFormatMap());
1941 form = "'Rdq, 'Vn.%s['IVInsIndex1]";
1942 } else if (instr->Mask(NEONCopyDupElementMask) == NEON_DUP_ELEMENT) {
1943 mnemonic = "dup";
1944 form = "'Vd.%s, 'Vn.%s['IVInsIndex1]";
1945 } else if (instr->Mask(NEONCopyDupGeneralMask) == NEON_DUP_GENERAL) {
1946 mnemonic = "dup";
1947 if (nfd.GetVectorFormat() == kFormat2D) {
1948 form = "'Vd.%s, 'Xn";
1949 } else {
1950 form = "'Vd.%s, 'Wn";
1951 }
1952 }
1953 Format(instr, mnemonic, nfd.Substitute(form));
1954 }
1955
1956 void DisassemblingDecoder::VisitNEONExtract(Instruction *instr) {
1957 const char *mnemonic = "unimplemented";
1958 const char *form = "(NEONExtract)";
1959 NEONFormatDecoder nfd(instr, NEONFormatDecoder::LogicalFormatMap());
1960 if (instr->Mask(NEONExtractMask) == NEON_EXT) {
1961 mnemonic = "ext";
1962 form = "'Vd.%s, 'Vn.%s, 'Vm.%s, 'IVExtract";
1963 }
1964 Format(instr, mnemonic, nfd.Substitute(form));
1965 }
1966
1967 void DisassemblingDecoder::VisitNEONLoadStoreMultiStruct(Instruction *instr) {
1968 const char *mnemonic = NULL;
1969 const char *form = NULL;
1970 const char *form_1v = "{'Vt.%1$s}, ['Xns]";
1971 const char *form_2v = "{'Vt.%1$s, 'Vt2.%1$s}, ['Xns]";
1972 const char *form_3v = "{'Vt.%1$s, 'Vt2.%1$s, 'Vt3.%1$s}, ['Xns]";
1973 const char *form_4v = "{'Vt.%1$s, 'Vt2.%1$s, 'Vt3.%1$s, 'Vt4.%1$s}, ['Xns]";
1974 NEONFormatDecoder nfd(instr, NEONFormatDecoder::LoadStoreFormatMap());
1975
1976 switch (instr->Mask(NEONLoadStoreMultiStructMask)) {
1977 case NEON_LD1_1v:
1978 mnemonic = "ld1";
1979 form = form_1v;
1980 break;
1981 case NEON_LD1_2v:
1982 mnemonic = "ld1";
1983 form = form_2v;
1984 break;
1985 case NEON_LD1_3v:
1986 mnemonic = "ld1";
1987 form = form_3v;
1988 break;
1989 case NEON_LD1_4v:
1990 mnemonic = "ld1";
1991 form = form_4v;
1992 break;
1993 case NEON_LD2:
1994 mnemonic = "ld2";
1995 form = form_2v;
1996 break;
1997 case NEON_LD3:
1998 mnemonic = "ld3";
1999 form = form_3v;
2000 break;
2001 case NEON_LD4:
2002 mnemonic = "ld4";
2003 form = form_4v;
2004 break;
2005 case NEON_ST1_1v:
2006 mnemonic = "st1";
2007 form = form_1v;
2008 break;
2009 case NEON_ST1_2v:
2010 mnemonic = "st1";
2011 form = form_2v;
2012 break;
2013 case NEON_ST1_3v:
2014 mnemonic = "st1";
2015 form = form_3v;
2016 break;
2017 case NEON_ST1_4v:
2018 mnemonic = "st1";
2019 form = form_4v;
2020 break;
2021 case NEON_ST2:
2022 mnemonic = "st2";
2023 form = form_2v;
2024 break;
2025 case NEON_ST3:
2026 mnemonic = "st3";
2027 form = form_3v;
2028 break;
2029 case NEON_ST4:
2030 mnemonic = "st4";
2031 form = form_4v;
2032 break;
2033 default:
2034 break;
2035 }
2036
2037 // Work out unallocated encodings.
2038 bool allocated = (mnemonic != NULL);
2039 switch (instr->Mask(NEONLoadStoreMultiStructMask)) {
2040 case NEON_LD2:
2041 case NEON_LD3:
2042 case NEON_LD4:
2043 case NEON_ST2:
2044 case NEON_ST3:
2045 case NEON_ST4:
2046 // LD[2-4] and ST[2-4] cannot use .1d format.
2047 allocated = (instr->NEONQ() != 0) || (instr->NEONLSSize() != 3);
2048 break;
2049 default:
2050 break;
2051 }
2052 if (allocated) {
2053 DCHECK_NOT_NULL(mnemonic);
2054 DCHECK_NOT_NULL(form);
2055 } else {
2056 mnemonic = "unallocated";
2057 form = "(NEONLoadStoreMultiStruct)";
2058 }
2059
2060 Format(instr, mnemonic, nfd.Substitute(form));
2061 }
2062
2063 void DisassemblingDecoder::VisitNEONLoadStoreMultiStructPostIndex(
2064 Instruction *instr) {
2065 const char *mnemonic = NULL;
2066 const char *form = NULL;
2067 const char *form_1v = "{'Vt.%1$s}, ['Xns], 'Xmr1";
2068 const char *form_2v = "{'Vt.%1$s, 'Vt2.%1$s}, ['Xns], 'Xmr2";
2069 const char *form_3v = "{'Vt.%1$s, 'Vt2.%1$s, 'Vt3.%1$s}, ['Xns], 'Xmr3";
2070 const char *form_4v =
2071 "{'Vt.%1$s, 'Vt2.%1$s, 'Vt3.%1$s, 'Vt4.%1$s}, ['Xns], 'Xmr4";
2072 NEONFormatDecoder nfd(instr, NEONFormatDecoder::LoadStoreFormatMap());
2073
2074 switch (instr->Mask(NEONLoadStoreMultiStructPostIndexMask)) {
2075 case NEON_LD1_1v_post:
2076 mnemonic = "ld1";
2077 form = form_1v;
2078 break;
2079 case NEON_LD1_2v_post:
2080 mnemonic = "ld1";
2081 form = form_2v;
2082 break;
2083 case NEON_LD1_3v_post:
2084 mnemonic = "ld1";
2085 form = form_3v;
2086 break;
2087 case NEON_LD1_4v_post:
2088 mnemonic = "ld1";
2089 form = form_4v;
2090 break;
2091 case NEON_LD2_post:
2092 mnemonic = "ld2";
2093 form = form_2v;
2094 break;
2095 case NEON_LD3_post:
2096 mnemonic = "ld3";
2097 form = form_3v;
2098 break;
2099 case NEON_LD4_post:
2100 mnemonic = "ld4";
2101 form = form_4v;
2102 break;
2103 case NEON_ST1_1v_post:
2104 mnemonic = "st1";
2105 form = form_1v;
2106 break;
2107 case NEON_ST1_2v_post:
2108 mnemonic = "st1";
2109 form = form_2v;
2110 break;
2111 case NEON_ST1_3v_post:
2112 mnemonic = "st1";
2113 form = form_3v;
2114 break;
2115 case NEON_ST1_4v_post:
2116 mnemonic = "st1";
2117 form = form_4v;
2118 break;
2119 case NEON_ST2_post:
2120 mnemonic = "st2";
2121 form = form_2v;
2122 break;
2123 case NEON_ST3_post:
2124 mnemonic = "st3";
2125 form = form_3v;
2126 break;
2127 case NEON_ST4_post:
2128 mnemonic = "st4";
2129 form = form_4v;
2130 break;
2131 default:
2132 break;
2133 }
2134
2135 // Work out unallocated encodings.
2136 bool allocated = (mnemonic != NULL);
2137 switch (instr->Mask(NEONLoadStoreMultiStructPostIndexMask)) {
2138 case NEON_LD2_post:
2139 case NEON_LD3_post:
2140 case NEON_LD4_post:
2141 case NEON_ST2_post:
2142 case NEON_ST3_post:
2143 case NEON_ST4_post:
2144 // LD[2-4] and ST[2-4] cannot use .1d format.
2145 allocated = (instr->NEONQ() != 0) || (instr->NEONLSSize() != 3);
2146 break;
2147 default:
2148 break;
2149 }
2150 if (allocated) {
2151 DCHECK_NOT_NULL(mnemonic);
2152 DCHECK_NOT_NULL(form);
2153 } else {
2154 mnemonic = "unallocated";
2155 form = "(NEONLoadStoreMultiStructPostIndex)";
2156 }
2157
2158 Format(instr, mnemonic, nfd.Substitute(form));
2159 }
2160
2161 void DisassemblingDecoder::VisitNEONLoadStoreSingleStruct(Instruction *instr) {
2162 const char *mnemonic = NULL;
2163 const char *form = NULL;
2164
2165 const char *form_1b = "{'Vt.b}['IVLSLane0], ['Xns]";
2166 const char *form_1h = "{'Vt.h}['IVLSLane1], ['Xns]";
2167 const char *form_1s = "{'Vt.s}['IVLSLane2], ['Xns]";
2168 const char *form_1d = "{'Vt.d}['IVLSLane3], ['Xns]";
2169 NEONFormatDecoder nfd(instr, NEONFormatDecoder::LoadStoreFormatMap());
2170
2171 switch (instr->Mask(NEONLoadStoreSingleStructMask)) {
2172 case NEON_LD1_b:
2173 mnemonic = "ld1";
2174 form = form_1b;
2175 break;
2176 case NEON_LD1_h:
2177 mnemonic = "ld1";
2178 form = form_1h;
2179 break;
2180 case NEON_LD1_s:
2181 mnemonic = "ld1";
2182 static_assert((NEON_LD1_s | (1 << NEONLSSize_offset)) == NEON_LD1_d,
2183 "LSB of size distinguishes S and D registers.");
2184 form = ((instr->NEONLSSize() & 1) == 0) ? form_1s : form_1d;
2185 break;
2186 case NEON_ST1_b:
2187 mnemonic = "st1";
2188 form = form_1b;
2189 break;
2190 case NEON_ST1_h:
2191 mnemonic = "st1";
2192 form = form_1h;
2193 break;
2194 case NEON_ST1_s:
2195 mnemonic = "st1";
2196 static_assert((NEON_ST1_s | (1 << NEONLSSize_offset)) == NEON_ST1_d,
2197 "LSB of size distinguishes S and D registers.");
2198 form = ((instr->NEONLSSize() & 1) == 0) ? form_1s : form_1d;
2199 break;
2200 case NEON_LD1R:
2201 mnemonic = "ld1r";
2202 form = "{'Vt.%s}, ['Xns]";
2203 break;
2204 case NEON_LD2_b:
2205 case NEON_ST2_b:
2206 mnemonic = (instr->NEONLoad() == 1) ? "ld2" : "st2";
2207 form = "{'Vt.b, 'Vt2.b}['IVLSLane0], ['Xns]";
2208 break;
2209 case NEON_LD2_h:
2210 case NEON_ST2_h:
2211 mnemonic = (instr->NEONLoad() == 1) ? "ld2" : "st2";
2212 form = "{'Vt.h, 'Vt2.h}['IVLSLane1], ['Xns]";
2213 break;
2214 case NEON_LD2_s:
2215 case NEON_ST2_s:
2216 static_assert((NEON_ST2_s | (1 << NEONLSSize_offset)) == NEON_ST2_d,
2217 "LSB of size distinguishes S and D registers.");
2218 static_assert((NEON_LD2_s | (1 << NEONLSSize_offset)) == NEON_LD2_d,
2219 "LSB of size distinguishes S and D registers.");
2220 mnemonic = (instr->NEONLoad() == 1) ? "ld2" : "st2";
2221 if ((instr->NEONLSSize() & 1) == 0) {
2222 form = "{'Vt.s, 'Vt2.s}['IVLSLane2], ['Xns]";
2223 } else {
2224 form = "{'Vt.d, 'Vt2.d}['IVLSLane3], ['Xns]";
2225 }
2226 break;
2227 case NEON_LD2R:
2228 mnemonic = "ld2r";
2229 form = "{'Vt.%s, 'Vt2.%s}, ['Xns]";
2230 break;
2231 case NEON_LD3_b:
2232 case NEON_ST3_b:
2233 mnemonic = (instr->NEONLoad() == 1) ? "ld3" : "st3";
2234 form = "{'Vt.b, 'Vt2.b, 'Vt3.b}['IVLSLane0], ['Xns]";
2235 break;
2236 case NEON_LD3_h:
2237 case NEON_ST3_h:
2238 mnemonic = (instr->NEONLoad() == 1) ? "ld3" : "st3";
2239 form = "{'Vt.h, 'Vt2.h, 'Vt3.h}['IVLSLane1], ['Xns]";
2240 break;
2241 case NEON_LD3_s:
2242 case NEON_ST3_s:
2243 mnemonic = (instr->NEONLoad() == 1) ? "ld3" : "st3";
2244 if ((instr->NEONLSSize() & 1) == 0) {
2245 form = "{'Vt.s, 'Vt2.s, 'Vt3.s}['IVLSLane2], ['Xns]";
2246 } else {
2247 form = "{'Vt.d, 'Vt2.d, 'Vt3.d}['IVLSLane3], ['Xns]";
2248 }
2249 break;
2250 case NEON_LD3R:
2251 mnemonic = "ld3r";
2252 form = "{'Vt.%s, 'Vt2.%s, 'Vt3.%s}, ['Xns]";
2253 break;
2254 case NEON_LD4_b:
2255 case NEON_ST4_b:
2256 mnemonic = (instr->NEONLoad() == 1) ? "ld4" : "st4";
2257 form = "{'Vt.b, 'Vt2.b, 'Vt3.b, 'Vt4.b}['IVLSLane0], ['Xns]";
2258 break;
2259 case NEON_LD4_h:
2260 case NEON_ST4_h:
2261 mnemonic = (instr->NEONLoad() == 1) ? "ld4" : "st4";
2262 form = "{'Vt.h, 'Vt2.h, 'Vt3.h, 'Vt4.h}['IVLSLane1], ['Xns]";
2263 break;
2264 case NEON_LD4_s:
2265 case NEON_ST4_s:
2266 static_assert((NEON_LD4_s | (1 << NEONLSSize_offset)) == NEON_LD4_d,
2267 "LSB of size distinguishes S and D registers.");
2268 static_assert((NEON_ST4_s | (1 << NEONLSSize_offset)) == NEON_ST4_d,
2269 "LSB of size distinguishes S and D registers.");
2270 mnemonic = (instr->NEONLoad() == 1) ? "ld4" : "st4";
2271 if ((instr->NEONLSSize() & 1) == 0) {
2272 form = "{'Vt.s, 'Vt2.s, 'Vt3.s, 'Vt4.s}['IVLSLane2], ['Xns]";
2273 } else {
2274 form = "{'Vt.d, 'Vt2.d, 'Vt3.d, 'Vt4.d}['IVLSLane3], ['Xns]";
2275 }
2276 break;
2277 case NEON_LD4R:
2278 mnemonic = "ld4r";
2279 form = "{'Vt.%1$s, 'Vt2.%1$s, 'Vt3.%1$s, 'Vt4.%1$s}, ['Xns]";
2280 break;
2281 default:
2282 break;
2283 }
2284
2285 // Work out unallocated encodings.
2286 bool allocated = (mnemonic != NULL);
2287 switch (instr->Mask(NEONLoadStoreSingleStructMask)) {
2288 case NEON_LD1_h:
2289 case NEON_LD2_h:
2290 case NEON_LD3_h:
2291 case NEON_LD4_h:
2292 case NEON_ST1_h:
2293 case NEON_ST2_h:
2294 case NEON_ST3_h:
2295 case NEON_ST4_h:
2296 DCHECK(allocated);
2297 allocated = ((instr->NEONLSSize() & 1) == 0);
2298 break;
2299 case NEON_LD1_s:
2300 case NEON_LD2_s:
2301 case NEON_LD3_s:
2302 case NEON_LD4_s:
2303 case NEON_ST1_s:
2304 case NEON_ST2_s:
2305 case NEON_ST3_s:
2306 case NEON_ST4_s:
2307 DCHECK(allocated);
2308 allocated = (instr->NEONLSSize() <= 1) &&
2309 ((instr->NEONLSSize() == 0) || (instr->NEONS() == 0));
2310 break;
2311 case NEON_LD1R:
2312 case NEON_LD2R:
2313 case NEON_LD3R:
2314 case NEON_LD4R:
2315 DCHECK(allocated);
2316 allocated = (instr->NEONS() == 0);
2317 break;
2318 default:
2319 break;
2320 }
2321 if (allocated) {
2322 DCHECK_NOT_NULL(mnemonic);
2323 DCHECK_NOT_NULL(form);
2324 } else {
2325 mnemonic = "unallocated";
2326 form = "(NEONLoadStoreSingleStruct)";
2327 }
2328
2329 Format(instr, mnemonic, nfd.Substitute(form));
2330 }
2331
2332 void DisassemblingDecoder::VisitNEONLoadStoreSingleStructPostIndex(
2333 Instruction *instr) {
2334 const char *mnemonic = NULL;
2335 const char *form = NULL;
2336
2337 const char *form_1b = "{'Vt.b}['IVLSLane0], ['Xns], 'Xmb1";
2338 const char *form_1h = "{'Vt.h}['IVLSLane1], ['Xns], 'Xmb2";
2339 const char *form_1s = "{'Vt.s}['IVLSLane2], ['Xns], 'Xmb4";
2340 const char *form_1d = "{'Vt.d}['IVLSLane3], ['Xns], 'Xmb8";
2341 NEONFormatDecoder nfd(instr, NEONFormatDecoder::LoadStoreFormatMap());
2342
2343 switch (instr->Mask(NEONLoadStoreSingleStructPostIndexMask)) {
2344 case NEON_LD1_b_post:
2345 mnemonic = "ld1";
2346 form = form_1b;
2347 break;
2348 case NEON_LD1_h_post:
2349 mnemonic = "ld1";
2350 form = form_1h;
2351 break;
2352 case NEON_LD1_s_post:
2353 mnemonic = "ld1";
2354 static_assert((NEON_LD1_s | (1 << NEONLSSize_offset)) == NEON_LD1_d,
2355 "LSB of size distinguishes S and D registers.");
2356 form = ((instr->NEONLSSize() & 1) == 0) ? form_1s : form_1d;
2357 break;
2358 case NEON_ST1_b_post:
2359 mnemonic = "st1";
2360 form = form_1b;
2361 break;
2362 case NEON_ST1_h_post:
2363 mnemonic = "st1";
2364 form = form_1h;
2365 break;
2366 case NEON_ST1_s_post:
2367 mnemonic = "st1";
2368 static_assert((NEON_ST1_s | (1 << NEONLSSize_offset)) == NEON_ST1_d,
2369 "LSB of size distinguishes S and D registers.");
2370 form = ((instr->NEONLSSize() & 1) == 0) ? form_1s : form_1d;
2371 break;
2372 case NEON_LD1R_post:
2373 mnemonic = "ld1r";
2374 form = "{'Vt.%s}, ['Xns], 'Xmz1";
2375 break;
2376 case NEON_LD2_b_post:
2377 case NEON_ST2_b_post:
2378 mnemonic = (instr->NEONLoad() == 1) ? "ld2" : "st2";
2379 form = "{'Vt.b, 'Vt2.b}['IVLSLane0], ['Xns], 'Xmb2";
2380 break;
2381 case NEON_ST2_h_post:
2382 case NEON_LD2_h_post:
2383 mnemonic = (instr->NEONLoad() == 1) ? "ld2" : "st2";
2384 form = "{'Vt.h, 'Vt2.h}['IVLSLane1], ['Xns], 'Xmb4";
2385 break;
2386 case NEON_LD2_s_post:
2387 case NEON_ST2_s_post:
2388 mnemonic = (instr->NEONLoad() == 1) ? "ld2" : "st2";
2389 if ((instr->NEONLSSize() & 1) == 0)
2390 form = "{'Vt.s, 'Vt2.s}['IVLSLane2], ['Xns], 'Xmb8";
2391 else
2392 form = "{'Vt.d, 'Vt2.d}['IVLSLane3], ['Xns], 'Xmb16";
2393 break;
2394 case NEON_LD2R_post:
2395 mnemonic = "ld2r";
2396 form = "{'Vt.%s, 'Vt2.%s}, ['Xns], 'Xmz2";
2397 break;
2398 case NEON_LD3_b_post:
2399 case NEON_ST3_b_post:
2400 mnemonic = (instr->NEONLoad() == 1) ? "ld3" : "st3";
2401 form = "{'Vt.b, 'Vt2.b, 'Vt3.b}['IVLSLane0], ['Xns], 'Xmb3";
2402 break;
2403 case NEON_LD3_h_post:
2404 case NEON_ST3_h_post:
2405 mnemonic = (instr->NEONLoad() == 1) ? "ld3" : "st3";
2406 form = "{'Vt.h, 'Vt2.h, 'Vt3.h}['IVLSLane1], ['Xns], 'Xmb6";
2407 break;
2408 case NEON_LD3_s_post:
2409 case NEON_ST3_s_post:
2410 mnemonic = (instr->NEONLoad() == 1) ? "ld3" : "st3";
2411 if ((instr->NEONLSSize() & 1) == 0)
2412 form = "{'Vt.s, 'Vt2.s, 'Vt3.s}['IVLSLane2], ['Xns], 'Xmb12";
2413 else
2414 form = "{'Vt.d, 'Vt2.d, 'Vt3.d}['IVLSLane3], ['Xns], 'Xmb24";
2415 break;
2416 case NEON_LD3R_post:
2417 mnemonic = "ld3r";
2418 form = "{'Vt.%s, 'Vt2.%s, 'Vt3.%s}, ['Xns], 'Xmz3";
2419 break;
2420 case NEON_LD4_b_post:
2421 case NEON_ST4_b_post:
2422 mnemonic = (instr->NEONLoad() == 1) ? "ld4" : "st4";
2423 form = "{'Vt.b, 'Vt2.b, 'Vt3.b, 'Vt4.b}['IVLSLane0], ['Xns], 'Xmb4";
2424 break;
2425 case NEON_LD4_h_post:
2426 case NEON_ST4_h_post:
2427 mnemonic = (instr->NEONLoad()) == 1 ? "ld4" : "st4";
2428 form = "{'Vt.h, 'Vt2.h, 'Vt3.h, 'Vt4.h}['IVLSLane1], ['Xns], 'Xmb8";
2429 break;
2430 case NEON_LD4_s_post:
2431 case NEON_ST4_s_post:
2432 mnemonic = (instr->NEONLoad() == 1) ? "ld4" : "st4";
2433 if ((instr->NEONLSSize() & 1) == 0)
2434 form = "{'Vt.s, 'Vt2.s, 'Vt3.s, 'Vt4.s}['IVLSLane2], ['Xns], 'Xmb16";
2435 else
2436 form = "{'Vt.d, 'Vt2.d, 'Vt3.d, 'Vt4.d}['IVLSLane3], ['Xns], 'Xmb32";
2437 break;
2438 case NEON_LD4R_post:
2439 mnemonic = "ld4r";
2440 form = "{'Vt.%1$s, 'Vt2.%1$s, 'Vt3.%1$s, 'Vt4.%1$s}, ['Xns], 'Xmz4";
2441 break;
2442 default:
2443 break;
2444 }
2445
2446 // Work out unallocated encodings.
2447 bool allocated = (mnemonic != NULL);
2448 switch (instr->Mask(NEONLoadStoreSingleStructPostIndexMask)) {
2449 case NEON_LD1_h_post:
2450 case NEON_LD2_h_post:
2451 case NEON_LD3_h_post:
2452 case NEON_LD4_h_post:
2453 case NEON_ST1_h_post:
2454 case NEON_ST2_h_post:
2455 case NEON_ST3_h_post:
2456 case NEON_ST4_h_post:
2457 DCHECK(allocated);
2458 allocated = ((instr->NEONLSSize() & 1) == 0);
2459 break;
2460 case NEON_LD1_s_post:
2461 case NEON_LD2_s_post:
2462 case NEON_LD3_s_post:
2463 case NEON_LD4_s_post:
2464 case NEON_ST1_s_post:
2465 case NEON_ST2_s_post:
2466 case NEON_ST3_s_post:
2467 case NEON_ST4_s_post:
2468 DCHECK(allocated);
2469 allocated = (instr->NEONLSSize() <= 1) &&
2470 ((instr->NEONLSSize() == 0) || (instr->NEONS() == 0));
2471 break;
2472 case NEON_LD1R_post:
2473 case NEON_LD2R_post:
2474 case NEON_LD3R_post:
2475 case NEON_LD4R_post:
2476 DCHECK(allocated);
2477 allocated = (instr->NEONS() == 0);
2478 break;
2479 default:
2480 break;
2481 }
2482 if (allocated) {
2483 DCHECK_NOT_NULL(mnemonic);
2484 DCHECK_NOT_NULL(form);
2485 } else {
2486 mnemonic = "unallocated";
2487 form = "(NEONLoadStoreSingleStructPostIndex)";
2488 }
2489
2490 Format(instr, mnemonic, nfd.Substitute(form));
2491 }
2492
2493 void DisassemblingDecoder::VisitNEONModifiedImmediate(Instruction *instr) {
2494 const char *mnemonic = "unimplemented";
2495 const char *form = "'Vt.%s, 'IVMIImm8, lsl 'IVMIShiftAmt1";
2496
2497 int cmode = instr->NEONCmode();
2498 int cmode_3 = (cmode >> 3) & 1;
2499 int cmode_2 = (cmode >> 2) & 1;
2500 int cmode_1 = (cmode >> 1) & 1;
2501 int cmode_0 = cmode & 1;
2502 int q = instr->NEONQ();
2503 int op = instr->NEONModImmOp();
2504
2505 static const NEONFormatMap map_b = {{30}, {NF_8B, NF_16B}};
2506 static const NEONFormatMap map_h = {{30}, {NF_4H, NF_8H}};
2507 static const NEONFormatMap map_s = {{30}, {NF_2S, NF_4S}};
2508 NEONFormatDecoder nfd(instr, &map_b);
2509
2510 if (cmode_3 == 0) {
2511 if (cmode_0 == 0) {
2512 mnemonic = (op == 1) ? "mvni" : "movi";
2513 } else { // cmode<0> == '1'.
2514 mnemonic = (op == 1) ? "bic" : "orr";
2515 }
2516 nfd.SetFormatMap(0, &map_s);
2517 } else { // cmode<3> == '1'.
2518 if (cmode_2 == 0) {
2519 if (cmode_0 == 0) {
2520 mnemonic = (op == 1) ? "mvni" : "movi";
2521 } else { // cmode<0> == '1'.
2522 mnemonic = (op == 1) ? "bic" : "orr";
2523 }
2524 nfd.SetFormatMap(0, &map_h);
2525 } else { // cmode<2> == '1'.
2526 if (cmode_1 == 0) {
2527 mnemonic = (op == 1) ? "mvni" : "movi";
2528 form = "'Vt.%s, 'IVMIImm8, msl 'IVMIShiftAmt2";
2529 nfd.SetFormatMap(0, &map_s);
2530 } else { // cmode<1> == '1'.
2531 if (cmode_0 == 0) {
2532 mnemonic = "movi";
2533 if (op == 0) {
2534 form = "'Vt.%s, 'IVMIImm8";
2535 } else {
2536 form = (q == 0) ? "'Dd, 'IVMIImm" : "'Vt.2d, 'IVMIImm";
2537 }
2538 } else { // cmode<0> == '1'
2539 mnemonic = "fmov";
2540 if (op == 0) {
2541 form = "'Vt.%s, 'IVMIImmFPSingle";
2542 nfd.SetFormatMap(0, &map_s);
2543 } else {
2544 if (q == 1) {
2545 form = "'Vt.2d, 'IVMIImmFPDouble";
2546 } else {
2547 mnemonic = "unallocated";
2548 form = "(NEONModifiedImmediate)";
2549 }
2550 }
2551 }
2552 }
2553 }
2554 }
2555 Format(instr, mnemonic, nfd.Substitute(form));
2556 }
2557
2558 void DisassemblingDecoder::VisitNEONPerm(Instruction *instr) {
2559 const char *mnemonic = "unimplemented";
2560 const char *form = "'Vd.%s, 'Vn.%s, 'Vm.%s";
2561 NEONFormatDecoder nfd(instr);
2562
2563 switch (instr->Mask(NEONPermMask)) {
2564 case NEON_TRN1:
2565 mnemonic = "trn1";
2566 break;
2567 case NEON_TRN2:
2568 mnemonic = "trn2";
2569 break;
2570 case NEON_UZP1:
2571 mnemonic = "uzp1";
2572 break;
2573 case NEON_UZP2:
2574 mnemonic = "uzp2";
2575 break;
2576 case NEON_ZIP1:
2577 mnemonic = "zip1";
2578 break;
2579 case NEON_ZIP2:
2580 mnemonic = "zip2";
2581 break;
2582 default:
2583 form = "(NEONPerm)";
2584 }
2585 Format(instr, mnemonic, nfd.Substitute(form));
2586 }
2587
2588 void DisassemblingDecoder::VisitNEONScalar2RegMisc(Instruction *instr) {
2589 const char *mnemonic = "unimplemented";
2590 const char *form = "%sd, %sn";
2591 const char *form_0 = "%sd, %sn, #0";
2592 const char *form_fp0 = "%sd, %sn, #0.0";
2593
2594 NEONFormatDecoder nfd(instr, NEONFormatDecoder::ScalarFormatMap());
2595
2596 if (instr->Mask(NEON2RegMiscOpcode) <= NEON_NEG_scalar_opcode) {
2597 // These instructions all use a two bit size field, except NOT and RBIT,
2598 // which use the field to encode the operation.
2599 switch (instr->Mask(NEONScalar2RegMiscMask)) {
2600 case NEON_CMGT_zero_scalar:
2601 mnemonic = "cmgt";
2602 form = form_0;
2603 break;
2604 case NEON_CMGE_zero_scalar:
2605 mnemonic = "cmge";
2606 form = form_0;
2607 break;
2608 case NEON_CMLE_zero_scalar:
2609 mnemonic = "cmle";
2610 form = form_0;
2611 break;
2612 case NEON_CMLT_zero_scalar:
2613 mnemonic = "cmlt";
2614 form = form_0;
2615 break;
2616 case NEON_CMEQ_zero_scalar:
2617 mnemonic = "cmeq";
2618 form = form_0;
2619 break;
2620 case NEON_NEG_scalar:
2621 mnemonic = "neg";
2622 break;
2623 case NEON_SQNEG_scalar:
2624 mnemonic = "sqneg";
2625 break;
2626 case NEON_ABS_scalar:
2627 mnemonic = "abs";
2628 break;
2629 case NEON_SQABS_scalar:
2630 mnemonic = "sqabs";
2631 break;
2632 case NEON_SUQADD_scalar:
2633 mnemonic = "suqadd";
2634 break;
2635 case NEON_USQADD_scalar:
2636 mnemonic = "usqadd";
2637 break;
2638 default:
2639 form = "(NEONScalar2RegMisc)";
2640 }
2641 } else {
2642 // These instructions all use a one bit size field, except SQXTUN, SQXTN
2643 // and UQXTN, which use a two bit size field.
2644 nfd.SetFormatMaps(nfd.FPScalarFormatMap());
2645 switch (instr->Mask(NEONScalar2RegMiscFPMask)) {
2646 case NEON_FRSQRTE_scalar:
2647 mnemonic = "frsqrte";
2648 break;
2649 case NEON_FRECPE_scalar:
2650 mnemonic = "frecpe";
2651 break;
2652 case NEON_SCVTF_scalar:
2653 mnemonic = "scvtf";
2654 break;
2655 case NEON_UCVTF_scalar:
2656 mnemonic = "ucvtf";
2657 break;
2658 case NEON_FCMGT_zero_scalar:
2659 mnemonic = "fcmgt";
2660 form = form_fp0;
2661 break;
2662 case NEON_FCMGE_zero_scalar:
2663 mnemonic = "fcmge";
2664 form = form_fp0;
2665 break;
2666 case NEON_FCMLE_zero_scalar:
2667 mnemonic = "fcmle";
2668 form = form_fp0;
2669 break;
2670 case NEON_FCMLT_zero_scalar:
2671 mnemonic = "fcmlt";
2672 form = form_fp0;
2673 break;
2674 case NEON_FCMEQ_zero_scalar:
2675 mnemonic = "fcmeq";
2676 form = form_fp0;
2677 break;
2678 case NEON_FRECPX_scalar:
2679 mnemonic = "frecpx";
2680 break;
2681 case NEON_FCVTNS_scalar:
2682 mnemonic = "fcvtns";
2683 break;
2684 case NEON_FCVTNU_scalar:
2685 mnemonic = "fcvtnu";
2686 break;
2687 case NEON_FCVTPS_scalar:
2688 mnemonic = "fcvtps";
2689 break;
2690 case NEON_FCVTPU_scalar:
2691 mnemonic = "fcvtpu";
2692 break;
2693 case NEON_FCVTMS_scalar:
2694 mnemonic = "fcvtms";
2695 break;
2696 case NEON_FCVTMU_scalar:
2697 mnemonic = "fcvtmu";
2698 break;
2699 case NEON_FCVTZS_scalar:
2700 mnemonic = "fcvtzs";
2701 break;
2702 case NEON_FCVTZU_scalar:
2703 mnemonic = "fcvtzu";
2704 break;
2705 case NEON_FCVTAS_scalar:
2706 mnemonic = "fcvtas";
2707 break;
2708 case NEON_FCVTAU_scalar:
2709 mnemonic = "fcvtau";
2710 break;
2711 case NEON_FCVTXN_scalar:
2712 nfd.SetFormatMap(0, nfd.LongScalarFormatMap());
2713 mnemonic = "fcvtxn";
2714 break;
2715 default:
2716 nfd.SetFormatMap(0, nfd.ScalarFormatMap());
2717 nfd.SetFormatMap(1, nfd.LongScalarFormatMap());
2718 switch (instr->Mask(NEONScalar2RegMiscMask)) {
2719 case NEON_SQXTN_scalar:
2720 mnemonic = "sqxtn";
2721 break;
2722 case NEON_UQXTN_scalar:
2723 mnemonic = "uqxtn";
2724 break;
2725 case NEON_SQXTUN_scalar:
2726 mnemonic = "sqxtun";
2727 break;
2728 default:
2729 form = "(NEONScalar2RegMisc)";
2730 }
2731 }
2732 }
2733 Format(instr, mnemonic, nfd.SubstitutePlaceholders(form));
2734 }
2735
2736 void DisassemblingDecoder::VisitNEONScalar3Diff(Instruction *instr) {
2737 const char *mnemonic = "unimplemented";
2738 const char *form = "%sd, %sn, %sm";
2739 NEONFormatDecoder nfd(instr, NEONFormatDecoder::LongScalarFormatMap(),
2740 NEONFormatDecoder::ScalarFormatMap());
2741
2742 switch (instr->Mask(NEONScalar3DiffMask)) {
2743 case NEON_SQDMLAL_scalar:
2744 mnemonic = "sqdmlal";
2745 break;
2746 case NEON_SQDMLSL_scalar:
2747 mnemonic = "sqdmlsl";
2748 break;
2749 case NEON_SQDMULL_scalar:
2750 mnemonic = "sqdmull";
2751 break;
2752 default:
2753 form = "(NEONScalar3Diff)";
2754 }
2755 Format(instr, mnemonic, nfd.SubstitutePlaceholders(form));
2756 }
2757
2758 void DisassemblingDecoder::VisitNEONScalar3Same(Instruction *instr) {
2759 const char *mnemonic = "unimplemented";
2760 const char *form = "%sd, %sn, %sm";
2761 NEONFormatDecoder nfd(instr, NEONFormatDecoder::ScalarFormatMap());
2762
2763 if (instr->Mask(NEONScalar3SameFPFMask) == NEONScalar3SameFPFixed) {
2764 nfd.SetFormatMaps(nfd.FPScalarFormatMap());
2765 switch (instr->Mask(NEONScalar3SameFPMask)) {
2766 case NEON_FACGE_scalar:
2767 mnemonic = "facge";
2768 break;
2769 case NEON_FACGT_scalar:
2770 mnemonic = "facgt";
2771 break;
2772 case NEON_FCMEQ_scalar:
2773 mnemonic = "fcmeq";
2774 break;
2775 case NEON_FCMGE_scalar:
2776 mnemonic = "fcmge";
2777 break;
2778 case NEON_FCMGT_scalar:
2779 mnemonic = "fcmgt";
2780 break;
2781 case NEON_FMULX_scalar:
2782 mnemonic = "fmulx";
2783 break;
2784 case NEON_FRECPS_scalar:
2785 mnemonic = "frecps";
2786 break;
2787 case NEON_FRSQRTS_scalar:
2788 mnemonic = "frsqrts";
2789 break;
2790 case NEON_FABD_scalar:
2791 mnemonic = "fabd";
2792 break;
2793 default:
2794 form = "(NEONScalar3Same)";
2795 }
2796 } else {
2797 switch (instr->Mask(NEONScalar3SameMask)) {
2798 case NEON_ADD_scalar:
2799 mnemonic = "add";
2800 break;
2801 case NEON_SUB_scalar:
2802 mnemonic = "sub";
2803 break;
2804 case NEON_CMEQ_scalar:
2805 mnemonic = "cmeq";
2806 break;
2807 case NEON_CMGE_scalar:
2808 mnemonic = "cmge";
2809 break;
2810 case NEON_CMGT_scalar:
2811 mnemonic = "cmgt";
2812 break;
2813 case NEON_CMHI_scalar:
2814 mnemonic = "cmhi";
2815 break;
2816 case NEON_CMHS_scalar:
2817 mnemonic = "cmhs";
2818 break;
2819 case NEON_CMTST_scalar:
2820 mnemonic = "cmtst";
2821 break;
2822 case NEON_UQADD_scalar:
2823 mnemonic = "uqadd";
2824 break;
2825 case NEON_SQADD_scalar:
2826 mnemonic = "sqadd";
2827 break;
2828 case NEON_UQSUB_scalar:
2829 mnemonic = "uqsub";
2830 break;
2831 case NEON_SQSUB_scalar:
2832 mnemonic = "sqsub";
2833 break;
2834 case NEON_USHL_scalar:
2835 mnemonic = "ushl";
2836 break;
2837 case NEON_SSHL_scalar:
2838 mnemonic = "sshl";
2839 break;
2840 case NEON_UQSHL_scalar:
2841 mnemonic = "uqshl";
2842 break;
2843 case NEON_SQSHL_scalar:
2844 mnemonic = "sqshl";
2845 break;
2846 case NEON_URSHL_scalar:
2847 mnemonic = "urshl";
2848 break;
2849 case NEON_SRSHL_scalar:
2850 mnemonic = "srshl";
2851 break;
2852 case NEON_UQRSHL_scalar:
2853 mnemonic = "uqrshl";
2854 break;
2855 case NEON_SQRSHL_scalar:
2856 mnemonic = "sqrshl";
2857 break;
2858 case NEON_SQDMULH_scalar:
2859 mnemonic = "sqdmulh";
2860 break;
2861 case NEON_SQRDMULH_scalar:
2862 mnemonic = "sqrdmulh";
2863 break;
2864 default:
2865 form = "(NEONScalar3Same)";
2866 }
2867 }
2868 Format(instr, mnemonic, nfd.SubstitutePlaceholders(form));
2869 }
2870
2871 void DisassemblingDecoder::VisitNEONScalarByIndexedElement(Instruction *instr) {
2872 const char *mnemonic = "unimplemented";
2873 const char *form = "%sd, %sn, 'Ve.%s['IVByElemIndex]";
2874 NEONFormatDecoder nfd(instr, NEONFormatDecoder::ScalarFormatMap());
2875 bool long_instr = false;
2876
2877 switch (instr->Mask(NEONScalarByIndexedElementMask)) {
2878 case NEON_SQDMULL_byelement_scalar:
2879 mnemonic = "sqdmull";
2880 long_instr = true;
2881 break;
2882 case NEON_SQDMLAL_byelement_scalar:
2883 mnemonic = "sqdmlal";
2884 long_instr = true;
2885 break;
2886 case NEON_SQDMLSL_byelement_scalar:
2887 mnemonic = "sqdmlsl";
2888 long_instr = true;
2889 break;
2890 case NEON_SQDMULH_byelement_scalar:
2891 mnemonic = "sqdmulh";
2892 break;
2893 case NEON_SQRDMULH_byelement_scalar:
2894 mnemonic = "sqrdmulh";
2895 break;
2896 default:
2897 nfd.SetFormatMap(0, nfd.FPScalarFormatMap());
2898 switch (instr->Mask(NEONScalarByIndexedElementFPMask)) {
2899 case NEON_FMUL_byelement_scalar:
2900 mnemonic = "fmul";
2901 break;
2902 case NEON_FMLA_byelement_scalar:
2903 mnemonic = "fmla";
2904 break;
2905 case NEON_FMLS_byelement_scalar:
2906 mnemonic = "fmls";
2907 break;
2908 case NEON_FMULX_byelement_scalar:
2909 mnemonic = "fmulx";
2910 break;
2911 default:
2912 form = "(NEONScalarByIndexedElement)";
2913 }
2914 }
2915
2916 if (long_instr) {
2917 nfd.SetFormatMap(0, nfd.LongScalarFormatMap());
2918 }
2919
2920 Format(instr, mnemonic,
2921 nfd.Substitute(form, nfd.kPlaceholder, nfd.kPlaceholder, nfd.kFormat));
2922 }
2923
2924 void DisassemblingDecoder::VisitNEONScalarCopy(Instruction *instr) {
2925 const char *mnemonic = "unimplemented";
2926 const char *form = "(NEONScalarCopy)";
2927
2928 NEONFormatDecoder nfd(instr, NEONFormatDecoder::TriangularScalarFormatMap());
2929
2930 if (instr->Mask(NEONScalarCopyMask) == NEON_DUP_ELEMENT_scalar) {
2931 mnemonic = "mov";
2932 form = "%sd, 'Vn.%s['IVInsIndex1]";
2933 }
2934
2935 Format(instr, mnemonic, nfd.Substitute(form, nfd.kPlaceholder, nfd.kFormat));
2936 }
2937
2938 void DisassemblingDecoder::VisitNEONScalarPairwise(Instruction *instr) {
2939 const char *mnemonic = "unimplemented";
2940 const char *form = "%sd, 'Vn.%s";
2941 NEONFormatMap map = {{22}, {NF_2S, NF_2D}};
bbudge 2017/01/31 01:41:32 magic numbers
bbudge 2017/02/08 01:39:11 OK
2942 NEONFormatDecoder nfd(instr, NEONFormatDecoder::FPScalarFormatMap(), &map);
2943
2944 switch (instr->Mask(NEONScalarPairwiseMask)) {
2945 case NEON_ADDP_scalar:
2946 mnemonic = "addp";
2947 break;
2948 case NEON_FADDP_scalar:
2949 mnemonic = "faddp";
2950 break;
2951 case NEON_FMAXP_scalar:
2952 mnemonic = "fmaxp";
2953 break;
2954 case NEON_FMAXNMP_scalar:
2955 mnemonic = "fmaxnmp";
2956 break;
2957 case NEON_FMINP_scalar:
2958 mnemonic = "fminp";
2959 break;
2960 case NEON_FMINNMP_scalar:
2961 mnemonic = "fminnmp";
2962 break;
2963 default:
2964 form = "(NEONScalarPairwise)";
2965 }
2966 Format(instr, mnemonic, nfd.Substitute(form, NEONFormatDecoder::kPlaceholder,
2967 NEONFormatDecoder::kFormat));
2968 }
2969
2970 void DisassemblingDecoder::VisitNEONScalarShiftImmediate(Instruction *instr) {
2971 const char *mnemonic = "unimplemented";
2972 const char *form = "%sd, %sn, 'Is1";
2973 const char *form_2 = "%sd, %sn, 'Is2";
2974
2975 static const NEONFormatMap map_shift = {
2976 {22, 21, 20, 19},
bbudge 2017/01/31 01:41:32 magic numbers
bbudge 2017/02/08 01:39:11 OK
2977 {NF_UNDEF, NF_B, NF_H, NF_H, NF_S, NF_S, NF_S, NF_S, NF_D, NF_D, NF_D,
2978 NF_D, NF_D, NF_D, NF_D, NF_D}};
2979 static const NEONFormatMap map_shift_narrow = {
2980 {21, 20, 19}, {NF_UNDEF, NF_H, NF_S, NF_S, NF_D, NF_D, NF_D, NF_D}};
2981 NEONFormatDecoder nfd(instr, &map_shift);
2982
2983 if (instr->ImmNEONImmh()) { // immh has to be non-zero.
2984 switch (instr->Mask(NEONScalarShiftImmediateMask)) {
2985 case NEON_FCVTZU_imm_scalar:
2986 mnemonic = "fcvtzu";
2987 break;
2988 case NEON_FCVTZS_imm_scalar:
2989 mnemonic = "fcvtzs";
2990 break;
2991 case NEON_SCVTF_imm_scalar:
2992 mnemonic = "scvtf";
2993 break;
2994 case NEON_UCVTF_imm_scalar:
2995 mnemonic = "ucvtf";
2996 break;
2997 case NEON_SRI_scalar:
2998 mnemonic = "sri";
2999 break;
3000 case NEON_SSHR_scalar:
3001 mnemonic = "sshr";
3002 break;
3003 case NEON_USHR_scalar:
3004 mnemonic = "ushr";
3005 break;
3006 case NEON_SRSHR_scalar:
3007 mnemonic = "srshr";
3008 break;
3009 case NEON_URSHR_scalar:
3010 mnemonic = "urshr";
3011 break;
3012 case NEON_SSRA_scalar:
3013 mnemonic = "ssra";
3014 break;
3015 case NEON_USRA_scalar:
3016 mnemonic = "usra";
3017 break;
3018 case NEON_SRSRA_scalar:
3019 mnemonic = "srsra";
3020 break;
3021 case NEON_URSRA_scalar:
3022 mnemonic = "ursra";
3023 break;
3024 case NEON_SHL_scalar:
3025 mnemonic = "shl";
3026 form = form_2;
3027 break;
3028 case NEON_SLI_scalar:
3029 mnemonic = "sli";
3030 form = form_2;
3031 break;
3032 case NEON_SQSHLU_scalar:
3033 mnemonic = "sqshlu";
3034 form = form_2;
3035 break;
3036 case NEON_SQSHL_imm_scalar:
3037 mnemonic = "sqshl";
3038 form = form_2;
3039 break;
3040 case NEON_UQSHL_imm_scalar:
3041 mnemonic = "uqshl";
3042 form = form_2;
3043 break;
3044 case NEON_UQSHRN_scalar:
3045 mnemonic = "uqshrn";
3046 nfd.SetFormatMap(1, &map_shift_narrow);
3047 break;
3048 case NEON_UQRSHRN_scalar:
3049 mnemonic = "uqrshrn";
3050 nfd.SetFormatMap(1, &map_shift_narrow);
3051 break;
3052 case NEON_SQSHRN_scalar:
3053 mnemonic = "sqshrn";
3054 nfd.SetFormatMap(1, &map_shift_narrow);
3055 break;
3056 case NEON_SQRSHRN_scalar:
3057 mnemonic = "sqrshrn";
3058 nfd.SetFormatMap(1, &map_shift_narrow);
3059 break;
3060 case NEON_SQSHRUN_scalar:
3061 mnemonic = "sqshrun";
3062 nfd.SetFormatMap(1, &map_shift_narrow);
3063 break;
3064 case NEON_SQRSHRUN_scalar:
3065 mnemonic = "sqrshrun";
3066 nfd.SetFormatMap(1, &map_shift_narrow);
3067 break;
3068 default:
3069 form = "(NEONScalarShiftImmediate)";
3070 }
3071 } else {
3072 form = "(NEONScalarShiftImmediate)";
3073 }
3074 Format(instr, mnemonic, nfd.SubstitutePlaceholders(form));
3075 }
3076
3077 void DisassemblingDecoder::VisitNEONShiftImmediate(Instruction *instr) {
3078 const char *mnemonic = "unimplemented";
3079 const char *form = "'Vd.%s, 'Vn.%s, 'Is1";
3080 const char *form_shift_2 = "'Vd.%s, 'Vn.%s, 'Is2";
3081 const char *form_xtl = "'Vd.%s, 'Vn.%s";
3082
3083 // 0001->8H, 001x->4S, 01xx->2D, all others undefined.
3084 static const NEONFormatMap map_shift_ta = {
3085 {22, 21, 20, 19},
bbudge 2017/01/31 01:41:32 magic numbers
bbudge 2017/02/08 01:39:11 OK
3086 {NF_UNDEF, NF_8H, NF_4S, NF_4S, NF_2D, NF_2D, NF_2D, NF_2D}};
3087
3088 // 00010->8B, 00011->16B, 001x0->4H, 001x1->8H,
3089 // 01xx0->2S, 01xx1->4S, 1xxx1->2D, all others undefined.
3090 static const NEONFormatMap map_shift_tb = {
3091 {22, 21, 20, 19, 30},
3092 {NF_UNDEF, NF_UNDEF, NF_8B, NF_16B, NF_4H, NF_8H, NF_4H, NF_8H,
3093 NF_2S, NF_4S, NF_2S, NF_4S, NF_2S, NF_4S, NF_2S, NF_4S,
3094 NF_UNDEF, NF_2D, NF_UNDEF, NF_2D, NF_UNDEF, NF_2D, NF_UNDEF, NF_2D,
3095 NF_UNDEF, NF_2D, NF_UNDEF, NF_2D, NF_UNDEF, NF_2D, NF_UNDEF, NF_2D}};
3096
3097 NEONFormatDecoder nfd(instr, &map_shift_tb);
3098
3099 if (instr->ImmNEONImmh()) { // immh has to be non-zero.
3100 switch (instr->Mask(NEONShiftImmediateMask)) {
3101 case NEON_SQSHLU:
3102 mnemonic = "sqshlu";
3103 form = form_shift_2;
3104 break;
3105 case NEON_SQSHL_imm:
3106 mnemonic = "sqshl";
3107 form = form_shift_2;
3108 break;
3109 case NEON_UQSHL_imm:
3110 mnemonic = "uqshl";
3111 form = form_shift_2;
3112 break;
3113 case NEON_SHL:
3114 mnemonic = "shl";
3115 form = form_shift_2;
3116 break;
3117 case NEON_SLI:
3118 mnemonic = "sli";
3119 form = form_shift_2;
3120 break;
3121 case NEON_SCVTF_imm:
3122 mnemonic = "scvtf";
3123 break;
3124 case NEON_UCVTF_imm:
3125 mnemonic = "ucvtf";
3126 break;
3127 case NEON_FCVTZU_imm:
3128 mnemonic = "fcvtzu";
3129 break;
3130 case NEON_FCVTZS_imm:
3131 mnemonic = "fcvtzs";
3132 break;
3133 case NEON_SRI:
3134 mnemonic = "sri";
3135 break;
3136 case NEON_SSHR:
3137 mnemonic = "sshr";
3138 break;
3139 case NEON_USHR:
3140 mnemonic = "ushr";
3141 break;
3142 case NEON_SRSHR:
3143 mnemonic = "srshr";
3144 break;
3145 case NEON_URSHR:
3146 mnemonic = "urshr";
3147 break;
3148 case NEON_SSRA:
3149 mnemonic = "ssra";
3150 break;
3151 case NEON_USRA:
3152 mnemonic = "usra";
3153 break;
3154 case NEON_SRSRA:
3155 mnemonic = "srsra";
3156 break;
3157 case NEON_URSRA:
3158 mnemonic = "ursra";
3159 break;
3160 case NEON_SHRN:
3161 mnemonic = instr->Mask(NEON_Q) ? "shrn2" : "shrn";
3162 nfd.SetFormatMap(1, &map_shift_ta);
3163 break;
3164 case NEON_RSHRN:
3165 mnemonic = instr->Mask(NEON_Q) ? "rshrn2" : "rshrn";
3166 nfd.SetFormatMap(1, &map_shift_ta);
3167 break;
3168 case NEON_UQSHRN:
3169 mnemonic = instr->Mask(NEON_Q) ? "uqshrn2" : "uqshrn";
3170 nfd.SetFormatMap(1, &map_shift_ta);
3171 break;
3172 case NEON_UQRSHRN:
3173 mnemonic = instr->Mask(NEON_Q) ? "uqrshrn2" : "uqrshrn";
3174 nfd.SetFormatMap(1, &map_shift_ta);
3175 break;
3176 case NEON_SQSHRN:
3177 mnemonic = instr->Mask(NEON_Q) ? "sqshrn2" : "sqshrn";
3178 nfd.SetFormatMap(1, &map_shift_ta);
3179 break;
3180 case NEON_SQRSHRN:
3181 mnemonic = instr->Mask(NEON_Q) ? "sqrshrn2" : "sqrshrn";
3182 nfd.SetFormatMap(1, &map_shift_ta);
3183 break;
3184 case NEON_SQSHRUN:
3185 mnemonic = instr->Mask(NEON_Q) ? "sqshrun2" : "sqshrun";
3186 nfd.SetFormatMap(1, &map_shift_ta);
3187 break;
3188 case NEON_SQRSHRUN:
3189 mnemonic = instr->Mask(NEON_Q) ? "sqrshrun2" : "sqrshrun";
3190 nfd.SetFormatMap(1, &map_shift_ta);
3191 break;
3192 case NEON_SSHLL:
3193 nfd.SetFormatMap(0, &map_shift_ta);
3194 if (instr->ImmNEONImmb() == 0 &&
3195 CountSetBits(instr->ImmNEONImmh(), 32) == 1) { // sxtl variant.
3196 form = form_xtl;
3197 mnemonic = instr->Mask(NEON_Q) ? "sxtl2" : "sxtl";
3198 } else { // sshll variant.
3199 form = form_shift_2;
3200 mnemonic = instr->Mask(NEON_Q) ? "sshll2" : "sshll";
3201 }
3202 break;
3203 case NEON_USHLL:
3204 nfd.SetFormatMap(0, &map_shift_ta);
3205 if (instr->ImmNEONImmb() == 0 &&
3206 CountSetBits(instr->ImmNEONImmh(), 32) == 1) { // uxtl variant.
3207 form = form_xtl;
3208 mnemonic = instr->Mask(NEON_Q) ? "uxtl2" : "uxtl";
3209 } else { // ushll variant.
3210 form = form_shift_2;
3211 mnemonic = instr->Mask(NEON_Q) ? "ushll2" : "ushll";
3212 }
3213 break;
3214 default:
3215 form = "(NEONShiftImmediate)";
3216 }
3217 } else {
3218 form = "(NEONShiftImmediate)";
3219 }
3220 Format(instr, mnemonic, nfd.Substitute(form));
3221 }
3222
3223 void DisassemblingDecoder::VisitNEONTable(Instruction *instr) {
3224 const char *mnemonic = "unimplemented";
3225 const char *form = "(NEONTable)";
3226 const char form_1v[] = "'Vd.%%s, {'Vn.16b}, 'Vm.%%s";
3227 const char form_2v[] = "'Vd.%%s, {'Vn.16b, v%d.16b}, 'Vm.%%s";
3228 const char form_3v[] = "'Vd.%%s, {'Vn.16b, v%d.16b, v%d.16b}, 'Vm.%%s";
3229 const char form_4v[] =
3230 "'Vd.%%s, {'Vn.16b, v%d.16b, v%d.16b, v%d.16b}, 'Vm.%%s";
3231 static const NEONFormatMap map_b = {{30}, {NF_8B, NF_16B}};
3232 NEONFormatDecoder nfd(instr, &map_b);
3233
3234 switch (instr->Mask(NEONTableMask)) {
3235 case NEON_TBL_1v:
3236 mnemonic = "tbl";
3237 form = form_1v;
3238 break;
3239 case NEON_TBL_2v:
3240 mnemonic = "tbl";
3241 form = form_2v;
3242 break;
3243 case NEON_TBL_3v:
3244 mnemonic = "tbl";
3245 form = form_3v;
3246 break;
3247 case NEON_TBL_4v:
3248 mnemonic = "tbl";
3249 form = form_4v;
3250 break;
3251 case NEON_TBX_1v:
3252 mnemonic = "tbx";
3253 form = form_1v;
3254 break;
3255 case NEON_TBX_2v:
3256 mnemonic = "tbx";
3257 form = form_2v;
3258 break;
3259 case NEON_TBX_3v:
3260 mnemonic = "tbx";
3261 form = form_3v;
3262 break;
3263 case NEON_TBX_4v:
3264 mnemonic = "tbx";
3265 form = form_4v;
3266 break;
3267 default:
3268 break;
3269 }
3270
3271 char re_form[sizeof(form_4v) + 6];
bbudge 2017/01/31 01:41:32 magic number (6)
martyn.capewell 2017/02/03 11:01:31 Done.
3272 int reg_num = instr->Rn();
3273 snprintf(re_form, sizeof(re_form), form, (reg_num + 1) % kNumberOfVRegisters,
3274 (reg_num + 2) % kNumberOfVRegisters,
3275 (reg_num + 3) % kNumberOfVRegisters);
3276
3277 Format(instr, mnemonic, nfd.Substitute(re_form));
3278 }
3279
3280 void DisassemblingDecoder::VisitUnimplemented(Instruction *instr) {
1238 Format(instr, "unimplemented", "(Unimplemented)"); 3281 Format(instr, "unimplemented", "(Unimplemented)");
1239 } 3282 }
1240 3283
1241 3284 void DisassemblingDecoder::VisitUnallocated(Instruction *instr) {
1242 void DisassemblingDecoder::VisitUnallocated(Instruction* instr) {
1243 Format(instr, "unallocated", "(Unallocated)"); 3285 Format(instr, "unallocated", "(Unallocated)");
1244 } 3286 }
1245 3287
1246 3288 void DisassemblingDecoder::ProcessOutput(Instruction * /*instr*/) {
1247 void DisassemblingDecoder::ProcessOutput(Instruction* /*instr*/) {
1248 // The base disasm does nothing more than disassembling into a buffer. 3289 // The base disasm does nothing more than disassembling into a buffer.
1249 } 3290 }
1250 3291
1251 3292 void DisassemblingDecoder::AppendRegisterNameToOutput(const Instruction *instr,
1252 void DisassemblingDecoder::Format(Instruction* instr, const char* mnemonic, 3293 const CPURegister &reg) {
1253 const char* format) { 3294 USE(instr);
3295 DCHECK(reg.IsValid());
3296 char reg_char;
3297
3298 if (reg.IsRegister()) {
3299 reg_char = reg.Is64Bits() ? 'x' : 'w';
3300 } else {
3301 DCHECK(reg.IsVRegister());
3302 switch (reg.SizeInBits()) {
3303 case kBRegSizeInBits:
3304 reg_char = 'b';
3305 break;
3306 case kHRegSizeInBits:
3307 reg_char = 'h';
3308 break;
3309 case kSRegSizeInBits:
3310 reg_char = 's';
3311 break;
3312 case kDRegSizeInBits:
3313 reg_char = 'd';
3314 break;
3315 default:
3316 DCHECK(reg.Is128Bits());
3317 reg_char = 'q';
3318 }
3319 }
3320
3321 if (reg.IsVRegister() || !(reg.Aliases(csp) || reg.Aliases(xzr))) {
3322 // Filter special registers
3323 if (reg.IsX() && (reg.code() == 27)) {
3324 AppendToOutput("cp");
3325 } else if (reg.IsX() && (reg.code() == 28)) {
3326 AppendToOutput("jssp");
3327 } else if (reg.IsX() && (reg.code() == 29)) {
3328 AppendToOutput("fp");
3329 } else if (reg.IsX() && (reg.code() == 30)) {
3330 AppendToOutput("lr");
3331 } else {
3332 // A core or scalar/vector register: [wx]0 - 30, [bhsdq]0 - 31.
3333 AppendToOutput("%c%d", reg_char, reg.code());
3334 }
3335 } else if (reg.Aliases(csp)) {
3336 // Disassemble w31/x31 as stack pointer wcsp/csp.
3337 AppendToOutput("%s", reg.Is64Bits() ? "csp" : "wcsp");
3338 } else {
3339 // Disassemble w31/x31 as zero register wzr/xzr.
3340 AppendToOutput("%czr", reg_char);
3341 }
3342 }
3343
3344 void DisassemblingDecoder::Format(Instruction *instr, const char *mnemonic,
3345 const char *format) {
1254 // TODO(mcapewel) don't think I can use the instr address here - there needs 3346 // TODO(mcapewel) don't think I can use the instr address here - there needs
1255 // to be a base address too 3347 // to be a base address too
1256 DCHECK(mnemonic != NULL); 3348 DCHECK(mnemonic != NULL);
1257 ResetOutput(); 3349 ResetOutput();
1258 Substitute(instr, mnemonic); 3350 Substitute(instr, mnemonic);
1259 if (format != NULL) { 3351 if (format != NULL) {
1260 buffer_[buffer_pos_++] = ' '; 3352 buffer_[buffer_pos_++] = ' ';
1261 Substitute(instr, format); 3353 Substitute(instr, format);
1262 } 3354 }
1263 buffer_[buffer_pos_] = 0; 3355 buffer_[buffer_pos_] = 0;
1264 ProcessOutput(instr); 3356 ProcessOutput(instr);
1265 } 3357 }
1266 3358
1267 3359 void DisassemblingDecoder::Substitute(Instruction *instr, const char *string) {
1268 void DisassemblingDecoder::Substitute(Instruction* instr, const char* string) {
1269 char chr = *string++; 3360 char chr = *string++;
1270 while (chr != '\0') { 3361 while (chr != '\0') {
1271 if (chr == '\'') { 3362 if (chr == '\'') {
1272 string += SubstituteField(instr, string); 3363 string += SubstituteField(instr, string);
1273 } else { 3364 } else {
1274 buffer_[buffer_pos_++] = chr; 3365 buffer_[buffer_pos_++] = chr;
1275 } 3366 }
1276 chr = *string++; 3367 chr = *string++;
1277 } 3368 }
1278 } 3369 }
1279 3370
1280 3371 int DisassemblingDecoder::SubstituteField(Instruction *instr,
1281 int DisassemblingDecoder::SubstituteField(Instruction* instr, 3372 const char *format) {
1282 const char* format) {
1283 switch (format[0]) { 3373 switch (format[0]) {
3374 // NB. The remaining substitution prefix characters are: GJKUZ.
1284 case 'R': // Register. X or W, selected by sf bit. 3375 case 'R': // Register. X or W, selected by sf bit.
1285 case 'F': // FP Register. S or D, selected by type field. 3376 case 'F': // FP register. S or D, selected by type field.
3377 case 'V': // Vector register, V, vector format.
1286 case 'W': 3378 case 'W':
1287 case 'X': 3379 case 'X':
3380 case 'B':
3381 case 'H':
1288 case 'S': 3382 case 'S':
1289 case 'D': return SubstituteRegisterField(instr, format); 3383 case 'D':
1290 case 'I': return SubstituteImmediateField(instr, format); 3384 case 'Q':
1291 case 'L': return SubstituteLiteralField(instr, format); 3385 return SubstituteRegisterField(instr, format);
1292 case 'H': return SubstituteShiftField(instr, format); 3386 case 'I':
1293 case 'P': return SubstitutePrefetchField(instr, format); 3387 return SubstituteImmediateField(instr, format);
1294 case 'C': return SubstituteConditionField(instr, format); 3388 case 'L':
1295 case 'E': return SubstituteExtendField(instr, format); 3389 return SubstituteLiteralField(instr, format);
1296 case 'A': return SubstitutePCRelAddressField(instr, format); 3390 case 'N':
1297 case 'B': return SubstituteBranchTargetField(instr, format); 3391 return SubstituteShiftField(instr, format);
1298 case 'O': return SubstituteLSRegOffsetField(instr, format); 3392 case 'P':
1299 case 'M': return SubstituteBarrierField(instr, format); 3393 return SubstitutePrefetchField(instr, format);
3394 case 'C':
3395 return SubstituteConditionField(instr, format);
3396 case 'E':
3397 return SubstituteExtendField(instr, format);
3398 case 'A':
3399 return SubstitutePCRelAddressField(instr, format);
3400 case 'T':
3401 return SubstituteBranchTargetField(instr, format);
3402 case 'O':
3403 return SubstituteLSRegOffsetField(instr, format);
3404 case 'M':
3405 return SubstituteBarrierField(instr, format);
1300 default: { 3406 default: {
1301 UNREACHABLE(); 3407 UNREACHABLE();
1302 return 1; 3408 return 1;
1303 } 3409 }
1304 } 3410 }
1305 } 3411 }
1306 3412
1307 3413 int DisassemblingDecoder::SubstituteRegisterField(Instruction *instr,
1308 int DisassemblingDecoder::SubstituteRegisterField(Instruction* instr, 3414 const char *format) {
1309 const char* format) { 3415 char reg_prefix = format[0];
1310 unsigned reg_num = 0; 3416 unsigned reg_num = 0;
1311 unsigned field_len = 2; 3417 unsigned field_len = 2;
3418
1312 switch (format[1]) { 3419 switch (format[1]) {
1313 case 'd': reg_num = instr->Rd(); break; 3420 case 'd':
1314 case 'n': reg_num = instr->Rn(); break; 3421 reg_num = instr->Rd();
1315 case 'm': reg_num = instr->Rm(); break; 3422 if (format[2] == 'q') {
1316 case 'a': reg_num = instr->Ra(); break; 3423 reg_prefix = instr->NEONQ() ? 'X' : 'W';
1317 case 't': {
1318 if (format[2] == '2') {
1319 reg_num = instr->Rt2();
1320 field_len = 3; 3424 field_len = 3;
3425 }
3426 break;
3427 case 'n':
3428 reg_num = instr->Rn();
3429 break;
3430 case 'm':
3431 reg_num = instr->Rm();
3432 switch (format[2]) {
3433 // Handle registers tagged with b (bytes), z (instruction), or
3434 // r (registers), used for address updates in
3435 // NEON load/store instructions.
3436 case 'r':
3437 case 'b':
3438 case 'z': {
3439 field_len = 3;
3440 char *eimm;
3441 int imm = static_cast<int>(strtol(&format[3], &eimm, 10));
3442 field_len += eimm - &format[3];
3443 if (reg_num == 31) {
3444 switch (format[2]) {
3445 case 'z':
3446 imm *= (1 << instr->NEONLSSize());
3447 break;
3448 case 'r':
3449 imm *= (instr->NEONQ() == 0) ? kDRegSize : kQRegSize;
3450 break;
3451 case 'b':
3452 break;
3453 }
3454 AppendToOutput("#%d", imm);
3455 return field_len;
3456 }
3457 break;
3458 }
3459 }
3460 break;
3461 case 'e':
3462 // This is register Rm, but using a 4-bit specifier. Used in NEON
3463 // by-element instructions.
3464 reg_num = (instr->Rm() & 0xf);
3465 break;
3466 case 'a':
3467 reg_num = instr->Ra();
3468 break;
3469 case 't':
3470 reg_num = instr->Rt();
3471 if (format[0] == 'V') {
3472 if ((format[2] >= '2') && (format[2] <= '4')) {
3473 // Handle consecutive vector register specifiers Vt2, Vt3 and Vt4.
3474 reg_num = (reg_num + format[2] - '1') % 32;
3475 field_len = 3;
3476 }
1321 } else { 3477 } else {
1322 reg_num = instr->Rt(); 3478 if (format[2] == '2') {
3479 // Handle register specifier Rt2.
3480 reg_num = instr->Rt2();
3481 field_len = 3;
3482 }
1323 } 3483 }
1324 break; 3484 break;
1325 }
1326 case 's': 3485 case 's':
1327 reg_num = instr->Rs(); 3486 reg_num = instr->Rs();
1328 break; 3487 break;
1329 default: UNREACHABLE(); 3488 default:
3489 UNREACHABLE();
1330 } 3490 }
1331 3491
1332 // Increase field length for registers tagged as stack. 3492 // Increase field length for registers tagged as stack.
1333 if (format[2] == 's') { 3493 if (format[2] == 's') {
1334 field_len = 3; 3494 field_len = 3;
1335 } 3495 }
1336 3496
1337 char reg_type; 3497 CPURegister::RegisterType reg_type;
1338 if (format[0] == 'R') { 3498 unsigned reg_size;
1339 // Register type is R: use sf bit to choose X and W. 3499
1340 reg_type = instr->SixtyFourBits() ? 'x' : 'w'; 3500 if (reg_prefix == 'R') {
1341 } else if (format[0] == 'F') { 3501 reg_prefix = instr->SixtyFourBits() ? 'X' : 'W';
1342 // Floating-point register: use type field to choose S or D. 3502 } else if (reg_prefix == 'F') {
1343 reg_type = ((instr->FPType() & 1) == 0) ? 's' : 'd'; 3503 reg_prefix = ((instr->FPType() & 1) == 0) ? 'S' : 'D';
1344 } else { 3504 }
1345 // Register type is specified. Make it lower case. 3505
1346 reg_type = format[0] + 0x20; 3506 switch (reg_prefix) {
1347 } 3507 case 'W':
1348 3508 reg_type = CPURegister::kRegister;
1349 if ((reg_num != kZeroRegCode) || (reg_type == 's') || (reg_type == 'd')) { 3509 reg_size = kWRegSizeInBits;
1350 // A normal register: w0 - w30, x0 - x30, s0 - s31, d0 - d31. 3510 break;
1351 3511 case 'X':
1352 // Filter special registers 3512 reg_type = CPURegister::kRegister;
1353 if ((reg_type == 'x') && (reg_num == 27)) { 3513 reg_size = kXRegSizeInBits;
1354 AppendToOutput("cp"); 3514 break;
1355 } else if ((reg_type == 'x') && (reg_num == 28)) { 3515 case 'B':
1356 AppendToOutput("jssp"); 3516 reg_type = CPURegister::kVRegister;
1357 } else if ((reg_type == 'x') && (reg_num == 29)) { 3517 reg_size = kBRegSizeInBits;
1358 AppendToOutput("fp"); 3518 break;
1359 } else if ((reg_type == 'x') && (reg_num == 30)) { 3519 case 'H':
1360 AppendToOutput("lr"); 3520 reg_type = CPURegister::kVRegister;
1361 } else { 3521 reg_size = kHRegSizeInBits;
1362 AppendToOutput("%c%d", reg_type, reg_num); 3522 break;
1363 } 3523 case 'S':
1364 } else if (format[2] == 's') { 3524 reg_type = CPURegister::kVRegister;
1365 // Disassemble w31/x31 as stack pointer wcsp/csp. 3525 reg_size = kSRegSizeInBits;
1366 AppendToOutput("%s", (reg_type == 'w') ? "wcsp" : "csp"); 3526 break;
1367 } else { 3527 case 'D':
1368 // Disassemble w31/x31 as zero register wzr/xzr. 3528 reg_type = CPURegister::kVRegister;
1369 AppendToOutput("%czr", reg_type); 3529 reg_size = kDRegSizeInBits;
1370 } 3530 break;
3531 case 'Q':
3532 reg_type = CPURegister::kVRegister;
3533 reg_size = kQRegSizeInBits;
3534 break;
3535 case 'V':
3536 AppendToOutput("v%d", reg_num);
3537 return field_len;
3538 default:
3539 UNREACHABLE();
3540 reg_type = CPURegister::kRegister;
3541 reg_size = kXRegSizeInBits;
3542 }
3543
3544 if ((reg_type == CPURegister::kRegister) && (reg_num == kZeroRegCode) &&
3545 (format[2] == 's')) {
3546 reg_num = kSPRegInternalCode;
3547 }
3548
3549 AppendRegisterNameToOutput(instr,
3550 CPURegister::Create(reg_num, reg_size, reg_type));
1371 3551
1372 return field_len; 3552 return field_len;
1373 } 3553 }
1374 3554
1375 3555 int DisassemblingDecoder::SubstituteImmediateField(Instruction *instr,
1376 int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr, 3556 const char *format) {
1377 const char* format) {
1378 DCHECK(format[0] == 'I'); 3557 DCHECK(format[0] == 'I');
1379 3558
1380 switch (format[1]) { 3559 switch (format[1]) {
1381 case 'M': { // IMoveImm or IMoveLSL. 3560 case 'M': { // IMoveImm or IMoveLSL.
1382 if (format[5] == 'I') { 3561 if (format[5] == 'I' || format[5] == 'N') {
1383 uint64_t imm = static_cast<uint64_t>(instr->ImmMoveWide()) 3562 uint64_t imm = static_cast<uint64_t>(instr->ImmMoveWide())
1384 << (16 * instr->ShiftMoveWide()); 3563 << (16 * instr->ShiftMoveWide());
3564 if (format[5] == 'N') imm = ~imm;
3565 if (!instr->SixtyFourBits()) imm &= UINT64_C(0xffffffff);
1385 AppendToOutput("#0x%" PRIx64, imm); 3566 AppendToOutput("#0x%" PRIx64, imm);
1386 } else { 3567 } else {
1387 DCHECK(format[5] == 'L'); 3568 DCHECK(format[5] == 'L');
1388 AppendToOutput("#0x%" PRIx32, instr->ImmMoveWide()); 3569 AppendToOutput("#0x%" PRIx64, instr->ImmMoveWide());
1389 if (instr->ShiftMoveWide() > 0) { 3570 if (instr->ShiftMoveWide() > 0) {
1390 AppendToOutput(", lsl #%d", 16 * instr->ShiftMoveWide()); 3571 AppendToOutput(", lsl #%d", 16 * instr->ShiftMoveWide());
1391 } 3572 }
1392 } 3573 }
1393 return 8; 3574 return 8;
1394 } 3575 }
1395 case 'L': { 3576 case 'L': {
1396 switch (format[2]) { 3577 switch (format[2]) {
1397 case 'L': { // ILLiteral - Immediate Load Literal. 3578 case 'L': { // ILLiteral - Immediate Load Literal.
1398 AppendToOutput("pc%+" PRId32, instr->ImmLLiteral() 3579 AppendToOutput("pc%+" PRId32, instr->ImmLLiteral()
1399 << kLoadLiteralScaleLog2); 3580 << kLoadLiteralScaleLog2);
1400 return 9; 3581 return 9;
1401 } 3582 }
1402 case 'S': { // ILS - Immediate Load/Store. 3583 case 'S': { // ILS - Immediate Load/Store.
1403 if (instr->ImmLS() != 0) { 3584 if (instr->ImmLS() != 0) {
1404 AppendToOutput(", #%" PRId32, instr->ImmLS()); 3585 AppendToOutput(", #%" PRId32, instr->ImmLS());
1405 } 3586 }
1406 return 3; 3587 return 3;
1407 } 3588 }
1408 case 'P': { // ILPx - Immediate Load/Store Pair, x = access size. 3589 case 'P': { // ILPx - Immediate Load/Store Pair, x = access size.
1409 if (instr->ImmLSPair() != 0) { 3590 if (instr->ImmLSPair() != 0) {
1410 // format[3] is the scale value. Convert to a number. 3591 // format[3] is the scale value. Convert to a number.
1411 int scale = format[3] - 0x30; 3592 int scale = 1 << (format[3] - '0');
1412 AppendToOutput(", #%" PRId32, instr->ImmLSPair() * scale); 3593 AppendToOutput(", #%" PRId32, instr->ImmLSPair() * scale);
1413 } 3594 }
1414 return 4; 3595 return 4;
1415 } 3596 }
1416 case 'U': { // ILU - Immediate Load/Store Unsigned. 3597 case 'U': { // ILU - Immediate Load/Store Unsigned.
1417 if (instr->ImmLSUnsigned() != 0) { 3598 if (instr->ImmLSUnsigned() != 0) {
1418 AppendToOutput(", #%" PRId32, instr->ImmLSUnsigned() 3599 int shift = instr->SizeLS();
1419 << instr->SizeLS()); 3600 AppendToOutput(", #%" PRId32, instr->ImmLSUnsigned() << shift);
1420 } 3601 }
1421 return 3; 3602 return 3;
1422 } 3603 }
1423 } 3604 }
1424 } 3605 }
1425 case 'C': { // ICondB - Immediate Conditional Branch. 3606 case 'C': { // ICondB - Immediate Conditional Branch.
1426 int64_t offset = instr->ImmCondBranch() << 2; 3607 int64_t offset = instr->ImmCondBranch() << 2;
1427 char sign = (offset >= 0) ? '+' : '-'; 3608 char sign = (offset >= 0) ? '+' : '-';
1428 AppendToOutput("#%c0x%" PRIx64, sign, offset); 3609 AppendToOutput("#%c0x%" PRIx64, sign, offset);
1429 return 6; 3610 return 6;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 } 3646 }
1466 case 'E': { // IExtract. 3647 case 'E': { // IExtract.
1467 AppendToOutput("#%d", instr->ImmS()); 3648 AppendToOutput("#%d", instr->ImmS());
1468 return 8; 3649 return 8;
1469 } 3650 }
1470 case 'S': { // IS - Test and branch bit. 3651 case 'S': { // IS - Test and branch bit.
1471 AppendToOutput("#%d", (instr->ImmTestBranchBit5() << 5) | 3652 AppendToOutput("#%d", (instr->ImmTestBranchBit5() << 5) |
1472 instr->ImmTestBranchBit40()); 3653 instr->ImmTestBranchBit40());
1473 return 2; 3654 return 2;
1474 } 3655 }
3656 case 's': { // Is - Shift (immediate).
3657 switch (format[2]) {
3658 case '1': { // Is1 - SSHR.
3659 int shift = 16 << HighestSetBitPosition(instr->ImmNEONImmh());
3660 shift -= instr->ImmNEONImmhImmb();
3661 AppendToOutput("#%d", shift);
3662 return 3;
3663 }
3664 case '2': { // Is2 - SLI.
3665 int shift = instr->ImmNEONImmhImmb();
3666 shift -= 8 << HighestSetBitPosition(instr->ImmNEONImmh());
3667 AppendToOutput("#%d", shift);
3668 return 3;
3669 }
3670 default: {
3671 UNIMPLEMENTED();
3672 return 0;
3673 }
3674 }
3675 }
1475 case 'D': { // IDebug - HLT and BRK instructions. 3676 case 'D': { // IDebug - HLT and BRK instructions.
1476 AppendToOutput("#0x%x", instr->ImmException()); 3677 AppendToOutput("#0x%x", instr->ImmException());
1477 return 6; 3678 return 6;
1478 } 3679 }
3680 case 'V': { // Immediate Vector.
3681 switch (format[2]) {
3682 case 'E': { // IVExtract.
3683 AppendToOutput("#%" PRId64, instr->ImmNEONExt());
3684 return 9;
3685 }
3686 case 'B': { // IVByElemIndex.
3687 int vm_index = (instr->NEONH() << 1) | instr->NEONL();
3688 if (instr->NEONSize() == 1) {
3689 vm_index = (vm_index << 1) | instr->NEONM();
3690 }
3691 AppendToOutput("%d", vm_index);
3692 return strlen("IVByElemIndex");
3693 }
3694 case 'I': { // INS element.
3695 if (strncmp(format, "IVInsIndex", strlen("IVInsIndex")) == 0) {
3696 unsigned rd_index, rn_index;
3697 unsigned imm5 = instr->ImmNEON5();
3698 unsigned imm4 = instr->ImmNEON4();
3699 int tz = CountTrailingZeros(imm5, 32);
3700 if (tz <= 3) { // Defined for 0 <= tz <= 3 only.
3701 rd_index = imm5 >> (tz + 1);
3702 rn_index = imm4 >> tz;
3703 if (strncmp(format, "IVInsIndex1", strlen("IVInsIndex1")) == 0) {
3704 AppendToOutput("%d", rd_index);
3705 return strlen("IVInsIndex1");
3706 } else if (strncmp(format, "IVInsIndex2",
3707 strlen("IVInsIndex2")) == 0) {
3708 AppendToOutput("%d", rn_index);
3709 return strlen("IVInsIndex2");
3710 }
3711 }
3712 return 0;
3713 }
3714 }
3715 case 'L': { // IVLSLane[0123] - suffix indicates access size shift.
3716 AppendToOutput("%d", instr->NEONLSIndex(format[8] - '0'));
3717 return 9;
3718 }
3719 case 'M': { // Modified Immediate cases.
3720 if (strncmp(format, "IVMIImmFPSingle", strlen("IVMIImmFPSingle")) ==
3721 0) {
3722 AppendToOutput("#0x%" PRIx32 " (%.4f)", instr->ImmNEONabcdefgh(),
3723 instr->ImmNEONFP32());
3724 return strlen("IVMIImmFPSingle");
3725 } else if (strncmp(format, "IVMIImmFPDouble",
3726 strlen("IVMIImmFPDouble")) == 0) {
3727 AppendToOutput("#0x%" PRIx32 " (%.4f)", instr->ImmNEONabcdefgh(),
3728 instr->ImmNEONFP64());
3729 return strlen("IVMIImmFPDouble");
3730 } else if (strncmp(format, "IVMIImm8", strlen("IVMIImm8")) == 0) {
3731 uint64_t imm8 = instr->ImmNEONabcdefgh();
3732 AppendToOutput("#0x%" PRIx64, imm8);
3733 return strlen("IVMIImm8");
3734 } else if (strncmp(format, "IVMIImm", strlen("IVMIImm")) == 0) {
3735 uint64_t imm8 = instr->ImmNEONabcdefgh();
3736 uint64_t imm = 0;
3737 for (int i = 0; i < 8; ++i) {
3738 if (imm8 & (1 << i)) {
3739 imm |= (UINT64_C(0xff) << (8 * i));
3740 }
3741 }
3742 AppendToOutput("#0x%" PRIx64, imm);
3743 return strlen("IVMIImm");
3744 } else if (strncmp(format, "IVMIShiftAmt1",
3745 strlen("IVMIShiftAmt1")) == 0) {
3746 int cmode = instr->NEONCmode();
3747 int shift_amount = 8 * ((cmode >> 1) & 3);
3748 AppendToOutput("#%d", shift_amount);
3749 return strlen("IVMIShiftAmt1");
3750 } else if (strncmp(format, "IVMIShiftAmt2",
3751 strlen("IVMIShiftAmt2")) == 0) {
3752 int cmode = instr->NEONCmode();
3753 int shift_amount = 8 << (cmode & 1);
3754 AppendToOutput("#%d", shift_amount);
3755 return strlen("IVMIShiftAmt2");
3756 } else {
3757 UNIMPLEMENTED();
3758 return 0;
3759 }
3760 }
3761 default: {
3762 UNIMPLEMENTED();
3763 return 0;
3764 }
3765 }
3766 }
1479 default: { 3767 default: {
3768 printf("%s", format);
1480 UNREACHABLE(); 3769 UNREACHABLE();
1481 return 0; 3770 return 0;
1482 } 3771 }
1483 } 3772 }
1484 } 3773 }
1485 3774
1486 3775
1487 int DisassemblingDecoder::SubstituteBitfieldImmediateField(Instruction* instr, 3776 int DisassemblingDecoder::SubstituteBitfieldImmediateField(Instruction* instr,
1488 const char* format) { 3777 const char* format) {
1489 DCHECK((format[0] == 'I') && (format[1] == 'B')); 3778 DCHECK((format[0] == 'I') && (format[1] == 'B'));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1534 break; 3823 break;
1535 default: UNREACHABLE(); 3824 default: UNREACHABLE();
1536 } 3825 }
1537 3826
1538 return 6; 3827 return 6;
1539 } 3828 }
1540 3829
1541 3830
1542 int DisassemblingDecoder::SubstituteShiftField(Instruction* instr, 3831 int DisassemblingDecoder::SubstituteShiftField(Instruction* instr,
1543 const char* format) { 3832 const char* format) {
1544 DCHECK(format[0] == 'H'); 3833 DCHECK_EQ(format[0], 'N');
1545 DCHECK(instr->ShiftDP() <= 0x3); 3834 DCHECK_LE(instr->ShiftDP(), 0x3);
1546 3835
1547 switch (format[1]) { 3836 switch (format[1]) {
1548 case 'D': { // HDP. 3837 case 'D': { // NDP.
1549 DCHECK(instr->ShiftDP() != ROR); 3838 DCHECK(instr->ShiftDP() != ROR);
1550 } // Fall through. 3839 } // Fall through.
1551 case 'L': { // HLo. 3840 case 'L': { // NLo.
1552 if (instr->ImmDPShift() != 0) { 3841 if (instr->ImmDPShift() != 0) {
1553 const char* shift_type[] = {"lsl", "lsr", "asr", "ror"}; 3842 const char* shift_type[] = {"lsl", "lsr", "asr", "ror"};
1554 AppendToOutput(", %s #%" PRId32, shift_type[instr->ShiftDP()], 3843 AppendToOutput(", %s #%" PRId32, shift_type[instr->ShiftDP()],
1555 instr->ImmDPShift()); 3844 instr->ImmDPShift());
1556 } 3845 }
1557 return 3; 3846 return 3;
1558 } 3847 }
1559 default: 3848 default:
1560 UNREACHABLE(); 3849 UNREACHABLE();
1561 return 0; 3850 return 0;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1600 sign = '-'; 3889 sign = '-';
1601 } 3890 }
1602 AppendToOutput("#%c0x%x (addr %p)", sign, offset, 3891 AppendToOutput("#%c0x%x (addr %p)", sign, offset,
1603 instr->InstructionAtOffset(offset, Instruction::NO_CHECK)); 3892 instr->InstructionAtOffset(offset, Instruction::NO_CHECK));
1604 return 13; 3893 return 13;
1605 } 3894 }
1606 3895
1607 3896
1608 int DisassemblingDecoder::SubstituteBranchTargetField(Instruction* instr, 3897 int DisassemblingDecoder::SubstituteBranchTargetField(Instruction* instr,
1609 const char* format) { 3898 const char* format) {
1610 DCHECK(strncmp(format, "BImm", 4) == 0); 3899 DCHECK_EQ(strncmp(format, "TImm", 4), 0);
1611 3900
1612 int64_t offset = 0; 3901 int64_t offset = 0;
1613 switch (format[5]) { 3902 switch (format[5]) {
1614 // BImmUncn - unconditional branch immediate. 3903 // TImmUncn - unconditional branch immediate.
1615 case 'n': offset = instr->ImmUncondBranch(); break; 3904 case 'n': offset = instr->ImmUncondBranch(); break;
1616 // BImmCond - conditional branch immediate. 3905 // TImmCond - conditional branch immediate.
1617 case 'o': offset = instr->ImmCondBranch(); break; 3906 case 'o': offset = instr->ImmCondBranch(); break;
1618 // BImmCmpa - compare and branch immediate. 3907 // TImmCmpa - compare and branch immediate.
1619 case 'm': offset = instr->ImmCmpBranch(); break; 3908 case 'm': offset = instr->ImmCmpBranch(); break;
1620 // BImmTest - test and branch immediate. 3909 // TImmTest - test and branch immediate.
1621 case 'e': offset = instr->ImmTestBranch(); break; 3910 case 'e': offset = instr->ImmTestBranch(); break;
1622 default: UNREACHABLE(); 3911 default: UNREACHABLE();
1623 } 3912 }
1624 offset <<= kInstructionSizeLog2; 3913 offset <<= kInstructionSizeLog2;
1625 char sign = '+'; 3914 char sign = '+';
1626 if (offset < 0) { 3915 if (offset < 0) {
1627 sign = '-'; 3916 sign = '-';
1628 } 3917 }
1629 AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, Abs(offset), 3918 AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, Abs(offset),
1630 instr->InstructionAtOffset(offset), Instruction::NO_CHECK); 3919 instr->InstructionAtOffset(offset), Instruction::NO_CHECK);
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 decoder.AppendVisitor(&disasm); 4129 decoder.AppendVisitor(&disasm);
1841 4130
1842 for (byte* pc = start; pc < end; pc += v8::internal::kInstructionSize) { 4131 for (byte* pc = start; pc < end; pc += v8::internal::kInstructionSize) {
1843 decoder.Decode(reinterpret_cast<v8::internal::Instruction*>(pc)); 4132 decoder.Decode(reinterpret_cast<v8::internal::Instruction*>(pc));
1844 } 4133 }
1845 } 4134 }
1846 4135
1847 } // namespace disasm 4136 } // namespace disasm
1848 4137
1849 #endif // V8_TARGET_ARCH_ARM64 4138 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698