Chromium Code Reviews| 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/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 689 fldrd(dest, Address(base, offset, Address::Offset, kDWord)); | 689 fldrd(dest, Address(base, offset, Address::Offset, kDWord)); |
| 690 } else { | 690 } else { |
| 691 ASSERT(base != TMP2); | 691 ASSERT(base != TMP2); |
| 692 // Since offset is 32-bits, it won't be loaded from the pool. | 692 // Since offset is 32-bits, it won't be loaded from the pool. |
| 693 AddImmediate(TMP2, base, offset, kNoPP); | 693 AddImmediate(TMP2, base, offset, kNoPP); |
| 694 fldrd(dest, Address(TMP2)); | 694 fldrd(dest, Address(TMP2)); |
| 695 } | 695 } |
| 696 } | 696 } |
| 697 | 697 |
| 698 | 698 |
| 699 void Assembler::LoadQFromOffset(VRegister dest, Register base, int32_t offset) { | |
| 700 if (Address::CanHoldOffset(offset, Address::Offset, kQWord)) { | |
| 701 fldrq(dest, Address(base, offset, Address::Offset, kQWord)); | |
| 702 } else { | |
| 703 ASSERT(base != TMP2); | |
| 704 // Since offset is 32-bits, it won't be loaded from the pool. | |
|
regis
2014/05/08 17:10:05
But if it was, PP would be used and it would be OK
zra
2014/05/08 18:55:07
Changed to pass a PP or kNoPP so that lower level
| |
| 705 AddImmediate(TMP2, base, offset, kNoPP); | |
| 706 fldrq(dest, Address(TMP2)); | |
| 707 } | |
| 708 } | |
| 709 | |
| 710 | |
| 699 void Assembler::StoreToOffset( | 711 void Assembler::StoreToOffset( |
| 700 Register src, Register base, int32_t offset, OperandSize sz) { | 712 Register src, Register base, int32_t offset, OperandSize sz) { |
| 701 ASSERT(base != TMP2); | 713 ASSERT(base != TMP2); |
| 702 if (Address::CanHoldOffset(offset, Address::Offset, sz)) { | 714 if (Address::CanHoldOffset(offset, Address::Offset, sz)) { |
| 703 str(src, Address(base, offset, Address::Offset, sz), sz); | 715 str(src, Address(base, offset, Address::Offset, sz), sz); |
| 704 } else { | 716 } else { |
| 705 ASSERT(src != TMP2); | 717 ASSERT(src != TMP2); |
| 706 // Since offset is 32-bits, it won't be loaded from the pool. | 718 // Since offset is 32-bits, it won't be loaded from the pool. |
| 707 AddImmediate(TMP2, base, offset, kNoPP); | 719 AddImmediate(TMP2, base, offset, kNoPP); |
| 708 str(src, Address(TMP2), sz); | 720 str(src, Address(TMP2), sz); |
| 709 } | 721 } |
| 710 } | 722 } |
| 711 | 723 |
| 712 | 724 |
| 713 void Assembler::StoreDToOffset(VRegister src, Register base, int32_t offset) { | 725 void Assembler::StoreDToOffset(VRegister src, Register base, int32_t offset) { |
| 714 if (Address::CanHoldOffset(offset, Address::Offset, kDWord)) { | 726 if (Address::CanHoldOffset(offset, Address::Offset, kDWord)) { |
| 715 fstrd(src, Address(base, offset, Address::Offset, kDWord)); | 727 fstrd(src, Address(base, offset, Address::Offset, kDWord)); |
| 716 } else { | 728 } else { |
| 717 ASSERT(base != TMP2); | 729 ASSERT(base != TMP2); |
| 718 // Since offset is 32-bits, it won't be loaded from the pool. | 730 // Since offset is 32-bits, it won't be loaded from the pool. |
| 719 AddImmediate(TMP2, base, offset, kNoPP); | 731 AddImmediate(TMP2, base, offset, kNoPP); |
| 720 fstrd(src, Address(TMP2)); | 732 fstrd(src, Address(TMP2)); |
| 721 } | 733 } |
| 722 } | 734 } |
| 723 | 735 |
| 724 | 736 |
| 737 void Assembler::StoreQToOffset(VRegister src, Register base, int32_t offset) { | |
| 738 if (Address::CanHoldOffset(offset, Address::Offset, kQWord)) { | |
| 739 fstrq(src, Address(base, offset, Address::Offset, kQWord)); | |
| 740 } else { | |
| 741 ASSERT(base != TMP2); | |
| 742 // Since offset is 32-bits, it won't be loaded from the pool. | |
| 743 AddImmediate(TMP2, base, offset, kNoPP); | |
| 744 fstrq(src, Address(TMP2)); | |
| 745 } | |
| 746 } | |
| 747 | |
| 748 | |
| 725 // Store into object. | 749 // Store into object. |
| 726 // Preserves object and value registers. | 750 // Preserves object and value registers. |
| 727 void Assembler::StoreIntoObjectFilterNoSmi(Register object, | 751 void Assembler::StoreIntoObjectFilterNoSmi(Register object, |
| 728 Register value, | 752 Register value, |
| 729 Label* no_update) { | 753 Label* no_update) { |
| 730 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && | 754 COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && |
| 731 (kOldObjectAlignmentOffset == 0), young_alignment); | 755 (kOldObjectAlignmentOffset == 0), young_alignment); |
| 732 | 756 |
| 733 // Write-barrier triggers if the value is in the new space (has bit set) and | 757 // Write-barrier triggers if the value is in the new space (has bit set) and |
| 734 // the object is in the old space (has bit cleared). | 758 // the object is in the old space (has bit cleared). |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 747 // For the value we are only interested in the new/old bit and the tag bit. | 771 // For the value we are only interested in the new/old bit and the tag bit. |
| 748 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi. | 772 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi. |
| 749 and_(TMP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1)); | 773 and_(TMP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1)); |
| 750 // And the result with the negated space bit of the object. | 774 // And the result with the negated space bit of the object. |
| 751 bic(TMP, TMP, Operand(object)); | 775 bic(TMP, TMP, Operand(object)); |
| 752 tsti(TMP, kNewObjectAlignmentOffset); | 776 tsti(TMP, kNewObjectAlignmentOffset); |
| 753 b(no_update, EQ); | 777 b(no_update, EQ); |
| 754 } | 778 } |
| 755 | 779 |
| 756 | 780 |
| 781 void Assembler::StoreIntoObjectOffset(Register object, | |
| 782 int32_t offset, | |
| 783 Register value, | |
| 784 bool can_value_be_smi) { | |
| 785 if (Address::CanHoldOffset(offset - kHeapObjectTag)) { | |
| 786 StoreIntoObject( | |
| 787 object, FieldAddress(object, offset), value, can_value_be_smi); | |
| 788 } else { | |
| 789 AddImmediate(TMP, object, offset - kHeapObjectTag, PP); | |
|
regis
2014/05/08 17:10:05
Why don't you pass kNoPP as above, since the offse
zra
2014/05/08 18:55:07
Done.
| |
| 790 StoreIntoObject(object, Address(TMP), value, can_value_be_smi); | |
| 791 } | |
| 792 } | |
| 793 | |
| 794 | |
| 757 void Assembler::StoreIntoObject(Register object, | 795 void Assembler::StoreIntoObject(Register object, |
| 758 const Address& dest, | 796 const Address& dest, |
| 759 Register value, | 797 Register value, |
| 760 bool can_value_be_smi) { | 798 bool can_value_be_smi) { |
| 761 ASSERT(object != value); | 799 ASSERT(object != value); |
| 762 str(value, dest); | 800 str(value, dest); |
| 763 Label done; | 801 Label done; |
| 764 if (can_value_be_smi) { | 802 if (can_value_be_smi) { |
| 765 StoreIntoObjectFilter(object, value, &done); | 803 StoreIntoObjectFilter(object, value, &done); |
| 766 } else { | 804 } else { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 792 #if defined(DEBUG) | 830 #if defined(DEBUG) |
| 793 Label done; | 831 Label done; |
| 794 StoreIntoObjectFilter(object, value, &done); | 832 StoreIntoObjectFilter(object, value, &done); |
| 795 Stop("Store buffer update is required"); | 833 Stop("Store buffer update is required"); |
| 796 Bind(&done); | 834 Bind(&done); |
| 797 #endif // defined(DEBUG) | 835 #endif // defined(DEBUG) |
| 798 // No store buffer update. | 836 // No store buffer update. |
| 799 } | 837 } |
| 800 | 838 |
| 801 | 839 |
| 840 void Assembler::StoreIntoObjectOffsetNoBarrier(Register object, | |
| 841 int32_t offset, | |
| 842 Register value) { | |
| 843 if (Address::CanHoldOffset(offset - kHeapObjectTag)) { | |
| 844 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value); | |
| 845 } else { | |
| 846 AddImmediate(TMP, object, offset - kHeapObjectTag, PP); | |
|
regis
2014/05/08 17:10:05
ditto
zra
2014/05/08 18:55:07
Done.
| |
| 847 StoreIntoObjectNoBarrier(object, Address(TMP), value); | |
| 848 } | |
| 849 } | |
| 850 | |
| 851 | |
| 802 void Assembler::StoreIntoObjectNoBarrier(Register object, | 852 void Assembler::StoreIntoObjectNoBarrier(Register object, |
| 803 const Address& dest, | 853 const Address& dest, |
| 804 const Object& value) { | 854 const Object& value) { |
| 805 ASSERT(value.IsSmi() || value.InVMHeap() || | 855 ASSERT(value.IsSmi() || value.InVMHeap() || |
| 806 (value.IsOld() && value.IsNotTemporaryScopedHandle())); | 856 (value.IsOld() && value.IsNotTemporaryScopedHandle())); |
| 807 // No store buffer update. | 857 // No store buffer update. |
| 808 LoadObject(TMP, value, PP); | 858 LoadObject(TMP2, value, PP); |
| 809 str(TMP, dest); | 859 str(TMP2, dest); |
| 860 } | |
| 861 | |
| 862 | |
| 863 void Assembler::StoreIntoObjectOffsetNoBarrier(Register object, | |
| 864 int32_t offset, | |
| 865 const Object& value) { | |
| 866 if (Address::CanHoldOffset(offset - kHeapObjectTag)) { | |
| 867 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value); | |
| 868 } else { | |
| 869 AddImmediate(TMP, object, offset - kHeapObjectTag, PP); | |
|
regis
2014/05/08 17:10:05
ditto
zra
2014/05/08 18:55:07
Done.
| |
| 870 StoreIntoObjectNoBarrier(object, Address(TMP), value); | |
| 871 } | |
| 810 } | 872 } |
| 811 | 873 |
| 812 | 874 |
| 813 void Assembler::LoadClassId(Register result, Register object) { | 875 void Assembler::LoadClassId(Register result, Register object) { |
| 814 ASSERT(RawObject::kClassIdTagPos == 16); | 876 ASSERT(RawObject::kClassIdTagPos == 16); |
| 815 ASSERT(RawObject::kClassIdTagSize == 16); | 877 ASSERT(RawObject::kClassIdTagSize == 16); |
| 816 const intptr_t class_id_offset = Object::tags_offset() + | 878 const intptr_t class_id_offset = Object::tags_offset() + |
| 817 RawObject::kClassIdTagPos / kBitsPerByte; | 879 RawObject::kClassIdTagPos / kBitsPerByte; |
| 818 LoadFromOffset(result, object, class_id_offset - kHeapObjectTag, | 880 LoadFromOffset(result, object, class_id_offset - kHeapObjectTag, |
| 819 kUnsignedHalfword); | 881 kUnsignedHalfword); |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1153 LoadImmediate(TMP, tags, pp); | 1215 LoadImmediate(TMP, tags, pp); |
| 1154 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset()); | 1216 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset()); |
| 1155 } else { | 1217 } else { |
| 1156 b(failure); | 1218 b(failure); |
| 1157 } | 1219 } |
| 1158 } | 1220 } |
| 1159 | 1221 |
| 1160 } // namespace dart | 1222 } // namespace dart |
| 1161 | 1223 |
| 1162 #endif // defined TARGET_ARCH_ARM64 | 1224 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |