OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_ARM. | 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
8 #if defined(TARGET_ARCH_ARM) | 8 #if defined(TARGET_ARCH_ARM) |
9 | 9 |
10 #include "platform/assert.h" | 10 #include "platform/assert.h" |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 } | 689 } |
690 break; | 690 break; |
691 } | 691 } |
692 default: { | 692 default: { |
693 Unknown(instr); // Not used. | 693 Unknown(instr); // Not used. |
694 break; | 694 break; |
695 } | 695 } |
696 } | 696 } |
697 } else if (instr->IsMultiplyOrSyncPrimitive()) { | 697 } else if (instr->IsMultiplyOrSyncPrimitive()) { |
698 if (instr->Bit(24) == 0) { | 698 if (instr->Bit(24) == 0) { |
699 if ((TargetCPUFeatures::arm_version() != ARMv7) && | |
700 (instr->Bits(21, 3) != 0)) { | |
701 // mla ... smlal only supported on armv7. | |
702 Unknown(instr); | |
703 return; | |
704 } | |
705 // multiply instructions | 699 // multiply instructions |
706 switch (instr->Bits(21, 3)) { | 700 switch (instr->Bits(21, 3)) { |
707 case 0: { | 701 case 0: { |
708 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 702 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
709 Format(instr, "mul'cond's 'rn, 'rm, 'rs"); | 703 Format(instr, "mul'cond's 'rn, 'rm, 'rs"); |
710 break; | 704 break; |
711 } | 705 } |
712 case 1: { | 706 case 1: { |
713 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. | 707 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. |
714 Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd"); | 708 Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd"); |
715 break; | 709 break; |
716 } | 710 } |
717 case 2: { | 711 case 2: { |
| 712 if (TargetCPUFeatures::arm_version() == ARMv5TE) { |
| 713 Unknown(instr); |
| 714 return; |
| 715 } |
718 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 716 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
719 Format(instr, "umaal'cond's 'rd, 'rn, 'rm, 'rs"); | 717 Format(instr, "umaal'cond's 'rd, 'rn, 'rm, 'rs"); |
720 break; | 718 break; |
721 } | 719 } |
722 case 3: { | 720 case 3: { |
| 721 if (TargetCPUFeatures::arm_version() != ARMv7) { |
| 722 Unknown(instr); |
| 723 return; |
| 724 } |
723 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. | 725 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. |
724 Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd"); | 726 Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd"); |
725 break; | 727 break; |
726 } | 728 } |
727 case 4: { | 729 case 4: { |
728 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 730 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
729 Format(instr, "umull'cond's 'rd, 'rn, 'rm, 'rs"); | 731 Format(instr, "umull'cond's 'rd, 'rn, 'rm, 'rs"); |
730 break; | 732 break; |
731 } | 733 } |
732 case 5: { | 734 case 5: { |
733 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 735 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
734 Format(instr, "umlal'cond's 'rd, 'rn, 'rm, 'rs"); | 736 Format(instr, "umlal'cond's 'rd, 'rn, 'rm, 'rs"); |
735 break; | 737 break; |
736 } | 738 } |
737 case 6: { | 739 case 6: { |
738 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 740 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
739 Format(instr, "smull'cond's 'rd, 'rn, 'rm, 'rs"); | 741 Format(instr, "smull'cond's 'rd, 'rn, 'rm, 'rs"); |
740 break; | 742 break; |
741 } | 743 } |
742 case 7: { | |
743 // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | |
744 Format(instr, "smlal'cond's 'rd, 'rn, 'rm, 'rs"); | |
745 break; | |
746 } | |
747 default: { | 744 default: { |
748 Unknown(instr); // Not used. | 745 Unknown(instr); // Not used. |
749 break; | 746 break; |
750 } | 747 } |
751 } | 748 } |
752 } else { | 749 } else { |
| 750 if (TargetCPUFeatures::arm_version() == ARMv5TE) { |
| 751 // strex and ldrex are only supported after ARMv6. |
| 752 Unknown(instr); |
| 753 return; |
| 754 } |
753 // synchronization primitives | 755 // synchronization primitives |
754 switch (instr->Bits(20, 4)) { | 756 switch (instr->Bits(20, 4)) { |
755 case 8: { | 757 case 8: { |
756 Format(instr, "strex'cond 'rd, 'rm, ['rn]"); | 758 Format(instr, "strex'cond 'rd, 'rm, ['rn]"); |
757 break; | 759 break; |
758 } | 760 } |
759 case 9: { | 761 case 9: { |
760 Format(instr, "ldrex'cond 'rd, ['rn]"); | 762 Format(instr, "ldrex'cond 'rd, ['rn]"); |
761 break; | 763 break; |
762 } | 764 } |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1463 Unknown(instr); | 1465 Unknown(instr); |
1464 } | 1466 } |
1465 } | 1467 } |
1466 } | 1468 } |
1467 | 1469 |
1468 | 1470 |
1469 void ARMDecoder::InstructionDecode(uword pc) { | 1471 void ARMDecoder::InstructionDecode(uword pc) { |
1470 Instr* instr = Instr::At(pc); | 1472 Instr* instr = Instr::At(pc); |
1471 | 1473 |
1472 if (instr->ConditionField() == kSpecialCondition) { | 1474 if (instr->ConditionField() == kSpecialCondition) { |
1473 if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) { | 1475 if ((instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) && |
| 1476 (TargetCPUFeatures::arm_version() != ARMv5TE)) { |
1474 Format(instr, "clrex"); | 1477 Format(instr, "clrex"); |
1475 } else { | 1478 } else { |
1476 if (instr->IsSIMDDataProcessing()) { | 1479 if (instr->IsSIMDDataProcessing()) { |
1477 DecodeSIMDDataProcessing(instr); | 1480 DecodeSIMDDataProcessing(instr); |
1478 } else { | 1481 } else { |
1479 Unknown(instr); | 1482 Unknown(instr); |
1480 } | 1483 } |
1481 } | 1484 } |
1482 } else { | 1485 } else { |
1483 switch (instr->TypeField()) { | 1486 switch (instr->TypeField()) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1528 int32_t instruction_bits = Instr::At(pc)->InstructionBits(); | 1531 int32_t instruction_bits = Instr::At(pc)->InstructionBits(); |
1529 OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits); | 1532 OS::SNPrint(hex_buffer, hex_size, "%08x", instruction_bits); |
1530 if (out_instr_size) { | 1533 if (out_instr_size) { |
1531 *out_instr_size = Instr::kInstrSize; | 1534 *out_instr_size = Instr::kInstrSize; |
1532 } | 1535 } |
1533 } | 1536 } |
1534 | 1537 |
1535 } // namespace dart | 1538 } // namespace dart |
1536 | 1539 |
1537 #endif // defined TARGET_ARCH_ARM | 1540 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |