| 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/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 | 9 |
| 10 #include "vm/stub_code.h" | 10 #include "vm/stub_code.h" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 // TODO(regis): Enable this flag after PrintStopMessage stub is implemented. | 14 // TODO(regis): Enable this flag after PrintStopMessage stub is implemented. |
| 15 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); | 15 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); |
| 16 | 16 |
| 17 | 17 |
| 18 // Instruction encoding bits. | 18 // Instruction encoding bits. |
| 19 enum { | 19 enum { |
| 20 H = 1 << 5, // halfword (or byte) | 20 H = 1 << 5, // halfword (or byte) |
| 21 L = 1 << 20, // load (or store) | 21 L = 1 << 20, // load (or store) |
| 22 S = 1 << 20, // set condition code (or leave unchanged) | 22 S = 1 << 20, // set condition code (or leave unchanged) |
| 23 W = 1 << 21, // writeback base register (or leave unchanged) | 23 W = 1 << 21, // writeback base register (or leave unchanged) |
| 24 A = 1 << 21, // accumulate in multiply instruction (or not) | 24 A = 1 << 21, // accumulate in multiply instruction (or not) |
| 25 B = 1 << 22, // unsigned byte (or word) | 25 B = 1 << 22, // unsigned byte (or word) |
| 26 D = 1 << 22, // high/lo bit of start of s/d register range |
| 26 N = 1 << 22, // long (or short) | 27 N = 1 << 22, // long (or short) |
| 27 U = 1 << 23, // positive (or negative) offset/index | 28 U = 1 << 23, // positive (or negative) offset/index |
| 28 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) | 29 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) |
| 29 I = 1 << 25, // immediate shifter operand (or not) | 30 I = 1 << 25, // immediate shifter operand (or not) |
| 30 | 31 |
| 31 B0 = 1, | 32 B0 = 1, |
| 32 B1 = 1 << 1, | 33 B1 = 1 << 1, |
| 33 B2 = 1 << 2, | 34 B2 = 1 << 2, |
| 34 B3 = 1 << 3, | 35 B3 = 1 << 3, |
| 35 B4 = 1 << 4, | 36 B4 = 1 << 4, |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 ASSERT(dd != kNoDRegister); | 698 ASSERT(dd != kNoDRegister); |
| 698 ASSERT(cond != kNoCondition); | 699 ASSERT(cond != kNoCondition); |
| 699 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | | 700 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 700 B27 | B26 | B24 | | 701 B27 | B26 | B24 | |
| 701 ((static_cast<int32_t>(dd) >> 4)*B22) | | 702 ((static_cast<int32_t>(dd) >> 4)*B22) | |
| 702 ((static_cast<int32_t>(dd) & 0xf)*B12) | | 703 ((static_cast<int32_t>(dd) & 0xf)*B12) | |
| 703 B11 | B9 | B8 | ad.vencoding(); | 704 B11 | B9 | B8 | ad.vencoding(); |
| 704 Emit(encoding); | 705 Emit(encoding); |
| 705 } | 706 } |
| 706 | 707 |
| 708 void Assembler::EmitMultiVSMemOp(Condition cond, |
| 709 BlockAddressMode am, |
| 710 bool load, |
| 711 Register base, |
| 712 SRegister start, |
| 713 uint32_t count) { |
| 714 ASSERT(base != kNoRegister); |
| 715 ASSERT(cond != kNoCondition); |
| 716 ASSERT(start != kNoSRegister); |
| 717 ASSERT(static_cast<int32_t>(start) + count <= kNumberOfSRegisters); |
| 718 |
| 719 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 720 B27 | B26 | B11 | B9 | |
| 721 am | |
| 722 (load ? L : 0) | |
| 723 (static_cast<int32_t>(base) << kRnShift) | |
| 724 ((static_cast<int32_t>(start) & 0x1) ? D : 0) | |
| 725 ((static_cast<int32_t>(start) >> 1) << 12) | |
| 726 count; |
| 727 Emit(encoding); |
| 728 } |
| 729 |
| 730 |
| 731 void Assembler::EmitMultiVDMemOp(Condition cond, |
| 732 BlockAddressMode am, |
| 733 bool load, |
| 734 Register base, |
| 735 DRegister start, |
| 736 int32_t count) { |
| 737 ASSERT(base != kNoRegister); |
| 738 ASSERT(cond != kNoCondition); |
| 739 ASSERT(start != kNoDRegister); |
| 740 ASSERT(static_cast<int32_t>(start) + count <= kNumberOfDRegisters); |
| 741 |
| 742 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 743 B27 | B26 | B11 | B9 | B8 | |
| 744 am | |
| 745 (load ? L : 0) | |
| 746 (static_cast<int32_t>(base) << kRnShift) | |
| 747 ((static_cast<int32_t>(start) & 0x10) ? D : 0) | |
| 748 ((static_cast<int32_t>(start) & 0xf) << 12) | |
| 749 (count << 1); |
| 750 Emit(encoding); |
| 751 } |
| 752 |
| 753 |
| 754 void Assembler::vldms(BlockAddressMode am, Register base, |
| 755 SRegister first, SRegister last, Condition cond) { |
| 756 ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); |
| 757 ASSERT(last > first); |
| 758 EmitMultiVSMemOp(cond, am, true, base, first, last - first + 1); |
| 759 } |
| 760 |
| 761 |
| 762 void Assembler::vstms(BlockAddressMode am, Register base, |
| 763 SRegister first, SRegister last, Condition cond) { |
| 764 ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); |
| 765 ASSERT(last > first); |
| 766 EmitMultiVSMemOp(cond, am, false, base, first, last - first + 1); |
| 767 } |
| 768 |
| 769 |
| 770 void Assembler::vldmd(BlockAddressMode am, Register base, |
| 771 DRegister first, DRegister last, Condition cond) { |
| 772 ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); |
| 773 ASSERT(last > first); |
| 774 EmitMultiVDMemOp(cond, am, true, base, first, last - first + 1); |
| 775 } |
| 776 |
| 777 |
| 778 void Assembler::vstmd(BlockAddressMode am, Register base, |
| 779 DRegister first, DRegister last, Condition cond) { |
| 780 ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); |
| 781 ASSERT(last > first); |
| 782 EmitMultiVDMemOp(cond, am, false, base, first, last - first + 1); |
| 783 } |
| 784 |
| 707 | 785 |
| 708 void Assembler::EmitVFPsss(Condition cond, int32_t opcode, | 786 void Assembler::EmitVFPsss(Condition cond, int32_t opcode, |
| 709 SRegister sd, SRegister sn, SRegister sm) { | 787 SRegister sd, SRegister sn, SRegister sm) { |
| 710 ASSERT(sd != kNoSRegister); | 788 ASSERT(sd != kNoSRegister); |
| 711 ASSERT(sn != kNoSRegister); | 789 ASSERT(sn != kNoSRegister); |
| 712 ASSERT(sm != kNoSRegister); | 790 ASSERT(sm != kNoSRegister); |
| 713 ASSERT(cond != kNoCondition); | 791 ASSERT(cond != kNoCondition); |
| 714 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | | 792 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 715 B27 | B26 | B25 | B11 | B9 | opcode | | 793 B27 | B26 | B25 | B11 | B9 | opcode | |
| 716 ((static_cast<int32_t>(sd) & 1)*B22) | | 794 ((static_cast<int32_t>(sd) & 1)*B22) | |
| (...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1655 // Do not reuse an existing entry, since each reference may be patched | 1733 // Do not reuse an existing entry, since each reference may be patched |
| 1656 // independently. | 1734 // independently. |
| 1657 object_pool_.Add(smi); | 1735 object_pool_.Add(smi); |
| 1658 return object_pool_.Length() - 1; | 1736 return object_pool_.Length() - 1; |
| 1659 } | 1737 } |
| 1660 | 1738 |
| 1661 } // namespace dart | 1739 } // namespace dart |
| 1662 | 1740 |
| 1663 #endif // defined TARGET_ARCH_ARM | 1741 #endif // defined TARGET_ARCH_ARM |
| 1664 | 1742 |
| OLD | NEW |