| 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 #ifndef VM_ASSEMBLER_ARM_H_ | 5 #ifndef VM_ASSEMBLER_ARM_H_ |
| 6 #define VM_ASSEMBLER_ARM_H_ | 6 #define VM_ASSEMBLER_ARM_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_arm.h directly; use assembler.h instead. | 9 #error Do not include assembler_arm.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 ASSERT(Utils::IsAbsoluteUint(12, offset)); | 224 ASSERT(Utils::IsAbsoluteUint(12, offset)); |
| 225 kind_ = Immediate; | 225 kind_ = Immediate; |
| 226 if (offset < 0) { | 226 if (offset < 0) { |
| 227 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign. | 227 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign. |
| 228 } else { | 228 } else { |
| 229 encoding_ = am | offset; | 229 encoding_ = am | offset; |
| 230 } | 230 } |
| 231 encoding_ |= static_cast<uint32_t>(rn) << kRnShift; | 231 encoding_ |= static_cast<uint32_t>(rn) << kRnShift; |
| 232 } | 232 } |
| 233 | 233 |
| 234 // There is no register offset mode unless Mode is Offset, in which case the |
| 235 // shifted register case below should be used. |
| 236 Address(Register rn, Register r, Mode am); |
| 237 |
| 234 Address(Register rn, Register rm, | 238 Address(Register rn, Register rm, |
| 235 Shift shift = LSL, uint32_t shift_imm = 0, Mode am = Offset) { | 239 Shift shift = LSL, uint32_t shift_imm = 0, Mode am = Offset) { |
| 236 Operand o(rm, shift, shift_imm); | 240 Operand o(rm, shift, shift_imm); |
| 237 | 241 |
| 238 if ((shift == LSL) && (shift_imm == 0)) { | 242 if ((shift == LSL) && (shift_imm == 0)) { |
| 239 kind_ = IndexRegister; | 243 kind_ = IndexRegister; |
| 240 } else { | 244 } else { |
| 241 kind_ = ScaledIndexRegister; | 245 kind_ = ScaledIndexRegister; |
| 242 } | 246 } |
| 243 encoding_ = o.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift); | 247 encoding_ = o.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift); |
| 244 } | 248 } |
| 245 | 249 |
| 250 // There is no shifted register mode with a register shift. |
| 251 Address(Register rn, Register rm, Shift shift, Register r, Mode am = Offset); |
| 252 |
| 246 static OperandSize OperandSizeFor(intptr_t cid); | 253 static OperandSize OperandSizeFor(intptr_t cid); |
| 247 | 254 |
| 248 static bool CanHoldLoadOffset(OperandSize size, | 255 static bool CanHoldLoadOffset(OperandSize size, |
| 249 int32_t offset, | 256 int32_t offset, |
| 250 int32_t* offset_mask); | 257 int32_t* offset_mask); |
| 251 static bool CanHoldStoreOffset(OperandSize size, | 258 static bool CanHoldStoreOffset(OperandSize size, |
| 252 int32_t offset, | 259 int32_t offset, |
| 253 int32_t* offset_mask); | 260 int32_t* offset_mask); |
| 254 static bool CanHoldImmediateOffset(bool is_load, | 261 static bool CanHoldImmediateOffset(bool is_load, |
| 255 intptr_t cid, | 262 intptr_t cid, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 272 | 279 |
| 273 friend class Assembler; | 280 friend class Assembler; |
| 274 }; | 281 }; |
| 275 | 282 |
| 276 | 283 |
| 277 class FieldAddress : public Address { | 284 class FieldAddress : public Address { |
| 278 public: | 285 public: |
| 279 FieldAddress(Register base, int32_t disp) | 286 FieldAddress(Register base, int32_t disp) |
| 280 : Address(base, disp - kHeapObjectTag) { } | 287 : Address(base, disp - kHeapObjectTag) { } |
| 281 | 288 |
| 289 // This addressing mode does not exist. |
| 290 FieldAddress(Register base, Register r); |
| 291 |
| 282 FieldAddress(const FieldAddress& other) : Address(other) { } | 292 FieldAddress(const FieldAddress& other) : Address(other) { } |
| 283 | 293 |
| 284 FieldAddress& operator=(const FieldAddress& other) { | 294 FieldAddress& operator=(const FieldAddress& other) { |
| 285 Address::operator=(other); | 295 Address::operator=(other); |
| 286 return *this; | 296 return *this; |
| 287 } | 297 } |
| 288 }; | 298 }; |
| 289 | 299 |
| 290 | 300 |
| 291 class Assembler : public ValueObject { | 301 class Assembler : public ValueObject { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 void movs(Register rd, Operand o, Condition cond = AL); | 399 void movs(Register rd, Operand o, Condition cond = AL); |
| 390 | 400 |
| 391 void bic(Register rd, Register rn, Operand o, Condition cond = AL); | 401 void bic(Register rd, Register rn, Operand o, Condition cond = AL); |
| 392 void bics(Register rd, Register rn, Operand o, Condition cond = AL); | 402 void bics(Register rd, Register rn, Operand o, Condition cond = AL); |
| 393 | 403 |
| 394 void mvn(Register rd, Operand o, Condition cond = AL); | 404 void mvn(Register rd, Operand o, Condition cond = AL); |
| 395 void mvns(Register rd, Operand o, Condition cond = AL); | 405 void mvns(Register rd, Operand o, Condition cond = AL); |
| 396 | 406 |
| 397 // Miscellaneous data-processing instructions. | 407 // Miscellaneous data-processing instructions. |
| 398 void clz(Register rd, Register rm, Condition cond = AL); | 408 void clz(Register rd, Register rm, Condition cond = AL); |
| 399 void movw(Register rd, uint16_t imm16, Condition cond = AL); | |
| 400 void movt(Register rd, uint16_t imm16, Condition cond = AL); | |
| 401 | 409 |
| 402 // Multiply instructions. | 410 // Multiply instructions. |
| 403 void mul(Register rd, Register rn, Register rm, Condition cond = AL); | 411 void mul(Register rd, Register rn, Register rm, Condition cond = AL); |
| 404 void muls(Register rd, Register rn, Register rm, Condition cond = AL); | 412 void muls(Register rd, Register rn, Register rm, Condition cond = AL); |
| 405 void mla(Register rd, Register rn, Register rm, Register ra, | 413 void mla(Register rd, Register rn, Register rm, Register ra, |
| 406 Condition cond = AL); | 414 Condition cond = AL); |
| 407 void mls(Register rd, Register rn, Register rm, Register ra, | 415 void mls(Register rd, Register rn, Register rm, Register ra, |
| 408 Condition cond = AL); | 416 Condition cond = AL); |
| 409 void smull(Register rd_lo, Register rd_hi, Register rn, Register rm, | 417 void smull(Register rd_lo, Register rd_hi, Register rn, Register rm, |
| 410 Condition cond = AL); | 418 Condition cond = AL); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 void Push(Register rd, Condition cond = AL); | 718 void Push(Register rd, Condition cond = AL); |
| 711 void Pop(Register rd, Condition cond = AL); | 719 void Pop(Register rd, Condition cond = AL); |
| 712 | 720 |
| 713 void PushList(RegList regs, Condition cond = AL); | 721 void PushList(RegList regs, Condition cond = AL); |
| 714 void PopList(RegList regs, Condition cond = AL); | 722 void PopList(RegList regs, Condition cond = AL); |
| 715 | 723 |
| 716 void MoveRegister(Register rd, Register rm, Condition cond = AL); | 724 void MoveRegister(Register rd, Register rm, Condition cond = AL); |
| 717 | 725 |
| 718 // Convenience shift instructions. Use mov instruction with shifter operand | 726 // Convenience shift instructions. Use mov instruction with shifter operand |
| 719 // for variants setting the status flags. | 727 // for variants setting the status flags. |
| 720 void Lsl(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 728 void Lsl(Register rd, Register rm, const Operand& shift_imm, |
| 729 Condition cond = AL); |
| 721 void Lsl(Register rd, Register rm, Register rs, Condition cond = AL); | 730 void Lsl(Register rd, Register rm, Register rs, Condition cond = AL); |
| 722 void Lsr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 731 void Lsr(Register rd, Register rm, const Operand& shift_imm, |
| 732 Condition cond = AL); |
| 723 void Lsr(Register rd, Register rm, Register rs, Condition cond = AL); | 733 void Lsr(Register rd, Register rm, Register rs, Condition cond = AL); |
| 724 void Asr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 734 void Asr(Register rd, Register rm, const Operand& shift_imm, |
| 735 Condition cond = AL); |
| 725 void Asr(Register rd, Register rm, Register rs, Condition cond = AL); | 736 void Asr(Register rd, Register rm, Register rs, Condition cond = AL); |
| 726 void Asrs(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 737 void Asrs(Register rd, Register rm, const Operand& shift_imm, |
| 727 void Ror(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 738 Condition cond = AL); |
| 739 void Ror(Register rd, Register rm, const Operand& shift_imm, |
| 740 Condition cond = AL); |
| 728 void Ror(Register rd, Register rm, Register rs, Condition cond = AL); | 741 void Ror(Register rd, Register rm, Register rs, Condition cond = AL); |
| 729 void Rrx(Register rd, Register rm, Condition cond = AL); | 742 void Rrx(Register rd, Register rm, Condition cond = AL); |
| 730 | 743 |
| 731 // Fill rd with the sign of rm. | 744 // Fill rd with the sign of rm. |
| 732 void SignFill(Register rd, Register rm, Condition cond = AL); | 745 void SignFill(Register rd, Register rm, Condition cond = AL); |
| 733 | 746 |
| 734 void Vreciprocalqs(QRegister qd, QRegister qm); | 747 void Vreciprocalqs(QRegister qd, QRegister qm); |
| 735 void VreciprocalSqrtqs(QRegister qd, QRegister qm); | 748 void VreciprocalSqrtqs(QRegister qd, QRegister qm); |
| 736 // If qm must be preserved, then provide a (non-QTMP) temporary. | 749 // If qm must be preserved, then provide a (non-QTMP) temporary. |
| 737 void Vsqrtqs(QRegister qd, QRegister qm, QRegister temp); | 750 void Vsqrtqs(QRegister qd, QRegister qm, QRegister temp); |
| 738 void Vdivqs(QRegister qd, QRegister qn, QRegister qm); | 751 void Vdivqs(QRegister qd, QRegister qn, QRegister qm); |
| 739 | 752 |
| 740 void SmiTag(Register reg, Condition cond = AL) { | 753 void SmiTag(Register reg, Condition cond = AL) { |
| 741 Lsl(reg, reg, kSmiTagSize, cond); | 754 Lsl(reg, reg, Operand(kSmiTagSize), cond); |
| 742 } | 755 } |
| 743 | 756 |
| 744 void SmiTag(Register dst, Register src, Condition cond = AL) { | 757 void SmiTag(Register dst, Register src, Condition cond = AL) { |
| 745 Lsl(dst, src, kSmiTagSize, cond); | 758 Lsl(dst, src, Operand(kSmiTagSize), cond); |
| 746 } | 759 } |
| 747 | 760 |
| 748 void SmiUntag(Register reg, Condition cond = AL) { | 761 void SmiUntag(Register reg, Condition cond = AL) { |
| 749 Asr(reg, reg, kSmiTagSize, cond); | 762 Asr(reg, reg, Operand(kSmiTagSize), cond); |
| 750 } | 763 } |
| 751 | 764 |
| 752 void SmiUntag(Register dst, Register src, Condition cond = AL) { | 765 void SmiUntag(Register dst, Register src, Condition cond = AL) { |
| 753 Asr(dst, src, kSmiTagSize, cond); | 766 Asr(dst, src, Operand(kSmiTagSize), cond); |
| 754 } | 767 } |
| 755 | 768 |
| 756 // Untag the value in the register assuming it is a smi. | 769 // Untag the value in the register assuming it is a smi. |
| 757 // Untagging shifts tag bit into the carry flag - if carry is clear | 770 // Untagging shifts tag bit into the carry flag - if carry is clear |
| 758 // assumption was correct. In this case jump to the is_smi label. | 771 // assumption was correct. In this case jump to the is_smi label. |
| 759 // Otherwise fall-through. | 772 // Otherwise fall-through. |
| 760 void SmiUntag(Register dst, Register src, Label* is_smi) { | 773 void SmiUntag(Register dst, Register src, Label* is_smi) { |
| 761 ASSERT(kSmiTagSize == 1); | 774 ASSERT(kSmiTagSize == 1); |
| 762 Asrs(dst, src, kSmiTagSize); | 775 Asrs(dst, src, Operand(kSmiTagSize)); |
| 763 b(is_smi, CC); | 776 b(is_smi, CC); |
| 764 } | 777 } |
| 765 | 778 |
| 766 // Function frame setup and tear down. | 779 // Function frame setup and tear down. |
| 767 void EnterFrame(RegList regs, intptr_t frame_space); | 780 void EnterFrame(RegList regs, intptr_t frame_space); |
| 768 void LeaveFrame(RegList regs); | 781 void LeaveFrame(RegList regs); |
| 769 void Ret(); | 782 void Ret(); |
| 770 void ReserveAlignedFrameSpace(intptr_t frame_space); | 783 void ReserveAlignedFrameSpace(intptr_t frame_space); |
| 771 | 784 |
| 772 // Create a frame for calling into runtime that preserves all volatile | 785 // Create a frame for calling into runtime that preserves all volatile |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 allow_constant_pool_ = b; | 876 allow_constant_pool_ = b; |
| 864 } | 877 } |
| 865 | 878 |
| 866 private: | 879 private: |
| 867 AssemblerBuffer buffer_; // Contains position independent code. | 880 AssemblerBuffer buffer_; // Contains position independent code. |
| 868 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. | 881 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
| 869 int32_t prologue_offset_; | 882 int32_t prologue_offset_; |
| 870 | 883 |
| 871 bool use_far_branches_; | 884 bool use_far_branches_; |
| 872 | 885 |
| 886 // If you are thinking of using one or both of these instructions directly, |
| 887 // instead LoadImmediate should probably be used. |
| 888 void movw(Register rd, uint16_t imm16, Condition cond = AL); |
| 889 void movt(Register rd, uint16_t imm16, Condition cond = AL); |
| 890 |
| 873 int32_t AddObject(const Object& obj); | 891 int32_t AddObject(const Object& obj); |
| 874 int32_t AddExternalLabel(const ExternalLabel* label); | 892 int32_t AddExternalLabel(const ExternalLabel* label); |
| 875 | 893 |
| 876 void BindARMv6(Label* label); | 894 void BindARMv6(Label* label); |
| 877 void BindARMv7(Label* label); | 895 void BindARMv7(Label* label); |
| 878 | 896 |
| 879 class CodeComment : public ZoneAllocated { | 897 class CodeComment : public ZoneAllocated { |
| 880 public: | 898 public: |
| 881 CodeComment(intptr_t pc_offset, const String& comment) | 899 CodeComment(intptr_t pc_offset, const String& comment) |
| 882 : pc_offset_(pc_offset), comment_(comment) { } | 900 : pc_offset_(pc_offset), comment_(comment) { } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 Register value, | 1021 Register value, |
| 1004 Label* no_update); | 1022 Label* no_update); |
| 1005 | 1023 |
| 1006 DISALLOW_ALLOCATION(); | 1024 DISALLOW_ALLOCATION(); |
| 1007 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1025 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1008 }; | 1026 }; |
| 1009 | 1027 |
| 1010 } // namespace dart | 1028 } // namespace dart |
| 1011 | 1029 |
| 1012 #endif // VM_ASSEMBLER_ARM_H_ | 1030 #endif // VM_ASSEMBLER_ARM_H_ |
| OLD | NEW |