| 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 |