| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/disassembler.h" | 5 #include "vm/disassembler.h" |
| 6 | 6 |
| 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. | 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 8 #if defined(TARGET_ARCH_ARM64) | 8 #if defined(TARGET_ARCH_ARM64) |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 | 10 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 PrintRegister(reg, instr->RdMode()); | 258 PrintRegister(reg, instr->RdMode()); |
| 259 return 2; | 259 return 2; |
| 260 } else if (format[1] == 'm') { // 'rm: Rm register | 260 } else if (format[1] == 'm') { // 'rm: Rm register |
| 261 int reg = instr->RmField(); | 261 int reg = instr->RmField(); |
| 262 PrintRegister(reg, R31IsZR); | 262 PrintRegister(reg, R31IsZR); |
| 263 return 2; | 263 return 2; |
| 264 } else if (format[1] == 't') { // 'rt: Rt register | 264 } else if (format[1] == 't') { // 'rt: Rt register |
| 265 int reg = instr->RtField(); | 265 int reg = instr->RtField(); |
| 266 PrintRegister(reg, R31IsZR); | 266 PrintRegister(reg, R31IsZR); |
| 267 return 2; | 267 return 2; |
| 268 } else if (format[1] == 'a') { // 'ra: Ra register |
| 269 int reg = instr->RaField(); |
| 270 PrintRegister(reg, R31IsZR); |
| 271 return 2; |
| 268 } | 272 } |
| 269 UNREACHABLE(); | 273 UNREACHABLE(); |
| 270 return -1; | 274 return -1; |
| 271 } | 275 } |
| 272 | 276 |
| 273 | 277 |
| 274 // FormatOption takes a formatting string and interprets it based on | 278 // FormatOption takes a formatting string and interprets it based on |
| 275 // the current instructions. The format string points to the first | 279 // the current instructions. The format string points to the first |
| 276 // character of the option string (the option escape has already been | 280 // character of the option string (the option escape has already been |
| 277 // consumed by the caller.) FormatOption returns the number of | 281 // consumed by the caller.) FormatOption returns the number of |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 } | 497 } |
| 494 } | 498 } |
| 495 | 499 |
| 496 | 500 |
| 497 void ARM64Decoder::DecodeAddSubImm(Instr* instr) { | 501 void ARM64Decoder::DecodeAddSubImm(Instr* instr) { |
| 498 switch (instr->Bit(30)) { | 502 switch (instr->Bit(30)) { |
| 499 case 0: { | 503 case 0: { |
| 500 if ((instr->RdField() == R31) && (instr->SFField())) { | 504 if ((instr->RdField() == R31) && (instr->SFField())) { |
| 501 Format(instr, "cmni'sf 'rn, 'imm12s"); | 505 Format(instr, "cmni'sf 'rn, 'imm12s"); |
| 502 } else { | 506 } else { |
| 503 Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); | 507 if (((instr->RdField() == R31) || (instr->RnField() == R31)) && |
| 508 (instr->Imm12Field() == 0) && (instr->Bit(29) == 0)) { |
| 509 Format(instr, "mov'sf 'rd, 'rn"); |
| 510 } else { |
| 511 Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); |
| 512 } |
| 504 } | 513 } |
| 505 break; | 514 break; |
| 506 } | 515 } |
| 507 case 1: { | 516 case 1: { |
| 508 if ((instr->RdField() == R31) && (instr->SFField())) { | 517 if ((instr->RdField() == R31) && (instr->SFField())) { |
| 509 Format(instr, "cmpi'sf 'rn, 'imm12s"); | 518 Format(instr, "cmpi'sf 'rn, 'imm12s"); |
| 510 } else { | 519 } else { |
| 511 Format(instr, "subi'sf's 'rd, 'rn, 'imm12s"); | 520 Format(instr, "subi'sf's 'rd, 'rn, 'imm12s"); |
| 512 } | 521 } |
| 513 break; | 522 break; |
| 514 } | 523 } |
| 515 default: | 524 default: |
| 516 Unknown(instr); | 525 Unknown(instr); |
| 517 break; | 526 break; |
| 518 } | 527 } |
| 519 } | 528 } |
| 520 | 529 |
| 521 | 530 |
| 522 void ARM64Decoder::DecodeLogicalImm(Instr* instr) { | 531 void ARM64Decoder::DecodeLogicalImm(Instr* instr) { |
| 523 int op = instr->Bits(29, 2); | 532 int op = instr->Bits(29, 2); |
| 524 switch (op) { | 533 switch (op) { |
| 525 case 0: | 534 case 0: |
| 526 Format(instr, "andi'sf 'rd, 'rn, 'bitimm"); | 535 Format(instr, "andi'sf 'rd, 'rn, 'bitimm"); |
| 527 break; | 536 break; |
| 528 case 1: | 537 case 1: { |
| 529 Format(instr, "orri'sf 'rd, 'rn, 'bitimm"); | 538 if (instr->RnField() == R31) { |
| 539 Format(instr, "mov'sf 'rd, 'bitimm"); |
| 540 } else { |
| 541 Format(instr, "orri'sf 'rd, 'rn, 'bitimm"); |
| 542 } |
| 530 break; | 543 break; |
| 544 } |
| 531 case 2: | 545 case 2: |
| 532 Format(instr, "eori'sf 'rd, 'rn, 'bitimm"); | 546 Format(instr, "eori'sf 'rd, 'rn, 'bitimm"); |
| 533 break; | 547 break; |
| 534 case 3: | 548 case 3: |
| 535 Format(instr, "andi'sfs 'rd, 'rn, 'bitimm"); | 549 Format(instr, "andi'sfs 'rd, 'rn, 'bitimm"); |
| 536 break; | 550 break; |
| 537 default: | 551 default: |
| 538 Unknown(instr); | 552 Unknown(instr); |
| 539 break; | 553 break; |
| 540 } | 554 } |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 | 725 |
| 712 void ARM64Decoder::DecodeLogicalShift(Instr* instr) { | 726 void ARM64Decoder::DecodeLogicalShift(Instr* instr) { |
| 713 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); | 727 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); |
| 714 switch (op) { | 728 switch (op) { |
| 715 case 0: | 729 case 0: |
| 716 Format(instr, "and'sf 'rd, 'rn, 'shift_op"); | 730 Format(instr, "and'sf 'rd, 'rn, 'shift_op"); |
| 717 break; | 731 break; |
| 718 case 1: | 732 case 1: |
| 719 Format(instr, "bic'sf 'rd, 'rn, 'shift_op"); | 733 Format(instr, "bic'sf 'rd, 'rn, 'shift_op"); |
| 720 break; | 734 break; |
| 721 case 2: | 735 case 2: { |
| 722 Format(instr, "orr'sf 'rd, 'rn, 'shift_op"); | 736 if ((instr->RnField() == R31) && (instr->IsShift()) && |
| 737 (instr->Imm16Field() == 0) && (instr->ShiftTypeField() == LSL)) { |
| 738 Format(instr, "mov'sf 'rd, 'rm"); |
| 739 } else { |
| 740 Format(instr, "orr'sf 'rd, 'rn, 'shift_op"); |
| 741 } |
| 723 break; | 742 break; |
| 743 } |
| 724 case 3: | 744 case 3: |
| 725 Format(instr, "orn'sf 'rd, 'rn, 'shift_op"); | 745 Format(instr, "orn'sf 'rd, 'rn, 'shift_op"); |
| 726 break; | 746 break; |
| 727 case 4: | 747 case 4: |
| 728 Format(instr, "eor'sf 'rd, 'rn, 'shift_op"); | 748 Format(instr, "eor'sf 'rd, 'rn, 'shift_op"); |
| 729 break; | 749 break; |
| 730 case 5: | 750 case 5: |
| 731 Format(instr, "eon'sf 'rd, 'rn, 'shift_op"); | 751 Format(instr, "eon'sf 'rd, 'rn, 'shift_op"); |
| 732 break; | 752 break; |
| 733 case 6: | 753 case 6: |
| 734 Format(instr, "and'sfs 'rd, 'rn, 'shift_op"); | 754 Format(instr, "and'sfs 'rd, 'rn, 'shift_op"); |
| 735 break; | 755 break; |
| 736 case 7: | 756 case 7: |
| 737 Format(instr, "bic'sfs 'rd, 'rn, 'shift_op"); | 757 Format(instr, "bic'sfs 'rd, 'rn, 'shift_op"); |
| 738 break; | 758 break; |
| 739 default: | 759 default: |
| 740 UNREACHABLE(); | 760 UNREACHABLE(); |
| 741 break; | 761 break; |
| 742 } | 762 } |
| 743 } | 763 } |
| 744 | 764 |
| 745 | 765 |
| 766 void ARM64Decoder::DecodeMiscDP2Source(Instr* instr) { |
| 767 if (instr->Bit(29) != 0) { |
| 768 Unknown(instr); |
| 769 } |
| 770 |
| 771 const int op = instr->Bits(10, 5); |
| 772 switch (op) { |
| 773 case 2: |
| 774 Format(instr, "udiv'sf 'rd, 'rn, 'rm"); |
| 775 break; |
| 776 case 3: |
| 777 Format(instr, "sdiv'sf 'rd, 'rn, 'rm"); |
| 778 break; |
| 779 case 8: |
| 780 Format(instr, "lsl'sf 'rd, 'rn, 'rm"); |
| 781 break; |
| 782 case 9: |
| 783 Format(instr, "lsr'sf 'rd, 'rn, 'rm"); |
| 784 break; |
| 785 case 10: |
| 786 Format(instr, "asr'sf 'rd, 'rn, 'rm"); |
| 787 break; |
| 788 default: |
| 789 Unknown(instr); |
| 790 break; |
| 791 } |
| 792 } |
| 793 |
| 794 |
| 795 void ARM64Decoder::DecodeMiscDP3Source(Instr* instr) { |
| 796 if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 0) && |
| 797 (instr->Bit(15) == 0)) { |
| 798 if (instr->RaField() == R31) { |
| 799 Format(instr, "mul'sf, 'rd, 'rn, 'rm"); |
| 800 } else { |
| 801 Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra"); |
| 802 } |
| 803 } else { |
| 804 Unknown(instr); |
| 805 } |
| 806 } |
| 807 |
| 808 |
| 746 void ARM64Decoder::DecodeDPRegister(Instr* instr) { | 809 void ARM64Decoder::DecodeDPRegister(Instr* instr) { |
| 747 if (instr->IsAddSubShiftExtOp()) { | 810 if (instr->IsAddSubShiftExtOp()) { |
| 748 DecodeAddSubShiftExt(instr); | 811 DecodeAddSubShiftExt(instr); |
| 749 } else if (instr->IsLogicalShiftOp()) { | 812 } else if (instr->IsLogicalShiftOp()) { |
| 750 DecodeLogicalShift(instr); | 813 DecodeLogicalShift(instr); |
| 814 } else if (instr->IsMiscDP2SourceOp()) { |
| 815 DecodeMiscDP2Source(instr); |
| 816 } else if (instr->IsMiscDP3SourceOp()) { |
| 817 DecodeMiscDP3Source(instr); |
| 751 } else { | 818 } else { |
| 752 Unknown(instr); | 819 Unknown(instr); |
| 753 } | 820 } |
| 754 } | 821 } |
| 755 | 822 |
| 756 | 823 |
| 757 void ARM64Decoder::DecodeDPSimd1(Instr* instr) { | 824 void ARM64Decoder::DecodeDPSimd1(Instr* instr) { |
| 758 Unknown(instr); | 825 Unknown(instr); |
| 759 } | 826 } |
| 760 | 827 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 human_buffer, | 892 human_buffer, |
| 826 sizeof(human_buffer), | 893 sizeof(human_buffer), |
| 827 pc); | 894 pc); |
| 828 pc += instruction_length; | 895 pc += instruction_length; |
| 829 } | 896 } |
| 830 } | 897 } |
| 831 | 898 |
| 832 } // namespace dart | 899 } // namespace dart |
| 833 | 900 |
| 834 #endif // defined TARGET_ARCH_ARM | 901 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |