Chromium Code Reviews| 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) : Address(base) { | |
| 291 UNREACHABLE(); | |
|
Florian Schneider
2014/09/26 12:36:58
Remove definition and just leave declaration here
zra
2014/09/26 17:11:35
Done.
| |
| 292 } | |
| 293 | |
| 282 FieldAddress(const FieldAddress& other) : Address(other) { } | 294 FieldAddress(const FieldAddress& other) : Address(other) { } |
| 283 | 295 |
| 284 FieldAddress& operator=(const FieldAddress& other) { | 296 FieldAddress& operator=(const FieldAddress& other) { |
| 285 Address::operator=(other); | 297 Address::operator=(other); |
| 286 return *this; | 298 return *this; |
| 287 } | 299 } |
| 288 }; | 300 }; |
| 289 | 301 |
| 290 | 302 |
| 291 class Assembler : public ValueObject { | 303 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); | 401 void movs(Register rd, Operand o, Condition cond = AL); |
| 390 | 402 |
| 391 void bic(Register rd, Register rn, Operand o, Condition cond = AL); | 403 void bic(Register rd, Register rn, Operand o, Condition cond = AL); |
| 392 void bics(Register rd, Register rn, Operand o, Condition cond = AL); | 404 void bics(Register rd, Register rn, Operand o, Condition cond = AL); |
| 393 | 405 |
| 394 void mvn(Register rd, Operand o, Condition cond = AL); | 406 void mvn(Register rd, Operand o, Condition cond = AL); |
| 395 void mvns(Register rd, Operand o, Condition cond = AL); | 407 void mvns(Register rd, Operand o, Condition cond = AL); |
| 396 | 408 |
| 397 // Miscellaneous data-processing instructions. | 409 // Miscellaneous data-processing instructions. |
| 398 void clz(Register rd, Register rm, Condition cond = AL); | 410 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 | 411 |
| 402 // Multiply instructions. | 412 // Multiply instructions. |
| 403 void mul(Register rd, Register rn, Register rm, Condition cond = AL); | 413 void mul(Register rd, Register rn, Register rm, Condition cond = AL); |
| 404 void muls(Register rd, Register rn, Register rm, Condition cond = AL); | 414 void muls(Register rd, Register rn, Register rm, Condition cond = AL); |
| 405 void mla(Register rd, Register rn, Register rm, Register ra, | 415 void mla(Register rd, Register rn, Register rm, Register ra, |
| 406 Condition cond = AL); | 416 Condition cond = AL); |
| 407 void mls(Register rd, Register rn, Register rm, Register ra, | 417 void mls(Register rd, Register rn, Register rm, Register ra, |
| 408 Condition cond = AL); | 418 Condition cond = AL); |
| 409 void smull(Register rd_lo, Register rd_hi, Register rn, Register rm, | 419 void smull(Register rd_lo, Register rd_hi, Register rn, Register rm, |
| 410 Condition cond = AL); | 420 Condition cond = AL); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 707 void Push(Register rd, Condition cond = AL); | 717 void Push(Register rd, Condition cond = AL); |
| 708 void Pop(Register rd, Condition cond = AL); | 718 void Pop(Register rd, Condition cond = AL); |
| 709 | 719 |
| 710 void PushList(RegList regs, Condition cond = AL); | 720 void PushList(RegList regs, Condition cond = AL); |
| 711 void PopList(RegList regs, Condition cond = AL); | 721 void PopList(RegList regs, Condition cond = AL); |
| 712 | 722 |
| 713 void MoveRegister(Register rd, Register rm, Condition cond = AL); | 723 void MoveRegister(Register rd, Register rm, Condition cond = AL); |
| 714 | 724 |
| 715 // Convenience shift instructions. Use mov instruction with shifter operand | 725 // Convenience shift instructions. Use mov instruction with shifter operand |
| 716 // for variants setting the status flags. | 726 // for variants setting the status flags. |
| 717 void Lsl(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 727 void Lsl(Register rd, Register rm, const Operand& shift_imm, |
| 728 Condition cond = AL); | |
| 718 void Lsl(Register rd, Register rm, Register rs, Condition cond = AL); | 729 void Lsl(Register rd, Register rm, Register rs, Condition cond = AL); |
| 719 void Lsr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 730 void Lsr(Register rd, Register rm, const Operand& shift_imm, |
| 731 Condition cond = AL); | |
| 720 void Lsr(Register rd, Register rm, Register rs, Condition cond = AL); | 732 void Lsr(Register rd, Register rm, Register rs, Condition cond = AL); |
| 721 void Asr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 733 void Asr(Register rd, Register rm, const Operand& shift_imm, |
| 734 Condition cond = AL); | |
| 722 void Asr(Register rd, Register rm, Register rs, Condition cond = AL); | 735 void Asr(Register rd, Register rm, Register rs, Condition cond = AL); |
| 723 void Asrs(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 736 void Asrs(Register rd, Register rm, const Operand& shift_imm, |
| 724 void Ror(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL); | 737 Condition cond = AL); |
| 738 void Ror(Register rd, Register rm, const Operand& shift_imm, | |
| 739 Condition cond = AL); | |
| 725 void Ror(Register rd, Register rm, Register rs, Condition cond = AL); | 740 void Ror(Register rd, Register rm, Register rs, Condition cond = AL); |
| 726 void Rrx(Register rd, Register rm, Condition cond = AL); | 741 void Rrx(Register rd, Register rm, Condition cond = AL); |
| 727 | 742 |
| 728 // Fill rd with the sign of rm. | 743 // Fill rd with the sign of rm. |
| 729 void SignFill(Register rd, Register rm, Condition cond = AL); | 744 void SignFill(Register rd, Register rm, Condition cond = AL); |
| 730 | 745 |
| 731 void Vreciprocalqs(QRegister qd, QRegister qm); | 746 void Vreciprocalqs(QRegister qd, QRegister qm); |
| 732 void VreciprocalSqrtqs(QRegister qd, QRegister qm); | 747 void VreciprocalSqrtqs(QRegister qd, QRegister qm); |
| 733 // If qm must be preserved, then provide a (non-QTMP) temporary. | 748 // If qm must be preserved, then provide a (non-QTMP) temporary. |
| 734 void Vsqrtqs(QRegister qd, QRegister qm, QRegister temp); | 749 void Vsqrtqs(QRegister qd, QRegister qm, QRegister temp); |
| 735 void Vdivqs(QRegister qd, QRegister qn, QRegister qm); | 750 void Vdivqs(QRegister qd, QRegister qn, QRegister qm); |
| 736 | 751 |
| 737 void SmiTag(Register reg, Condition cond = AL) { | 752 void SmiTag(Register reg, Condition cond = AL) { |
| 738 Lsl(reg, reg, kSmiTagSize, cond); | 753 Lsl(reg, reg, Operand(kSmiTagSize), cond); |
| 739 } | 754 } |
| 740 | 755 |
| 741 void SmiTag(Register dst, Register src, Condition cond = AL) { | 756 void SmiTag(Register dst, Register src, Condition cond = AL) { |
| 742 Lsl(dst, src, kSmiTagSize, cond); | 757 Lsl(dst, src, Operand(kSmiTagSize), cond); |
| 743 } | 758 } |
| 744 | 759 |
| 745 void SmiUntag(Register reg, Condition cond = AL) { | 760 void SmiUntag(Register reg, Condition cond = AL) { |
| 746 Asr(reg, reg, kSmiTagSize, cond); | 761 Asr(reg, reg, Operand(kSmiTagSize), cond); |
| 747 } | 762 } |
| 748 | 763 |
| 749 void SmiUntag(Register dst, Register src, Condition cond = AL) { | 764 void SmiUntag(Register dst, Register src, Condition cond = AL) { |
| 750 Asr(dst, src, kSmiTagSize, cond); | 765 Asr(dst, src, Operand(kSmiTagSize), cond); |
| 751 } | 766 } |
| 752 | 767 |
| 753 // Untag the value in the register assuming it is a smi. | 768 // Untag the value in the register assuming it is a smi. |
| 754 // Untagging shifts tag bit into the carry flag - if carry is clear | 769 // Untagging shifts tag bit into the carry flag - if carry is clear |
| 755 // assumption was correct. In this case jump to the is_smi label. | 770 // assumption was correct. In this case jump to the is_smi label. |
| 756 // Otherwise fall-through. | 771 // Otherwise fall-through. |
| 757 void SmiUntag(Register dst, Register src, Label* is_smi) { | 772 void SmiUntag(Register dst, Register src, Label* is_smi) { |
| 758 ASSERT(kSmiTagSize == 1); | 773 ASSERT(kSmiTagSize == 1); |
| 759 Asrs(dst, src, kSmiTagSize); | 774 Asrs(dst, src, Operand(kSmiTagSize)); |
| 760 b(is_smi, CC); | 775 b(is_smi, CC); |
| 761 } | 776 } |
| 762 | 777 |
| 763 // Function frame setup and tear down. | 778 // Function frame setup and tear down. |
| 764 void EnterFrame(RegList regs, intptr_t frame_space); | 779 void EnterFrame(RegList regs, intptr_t frame_space); |
| 765 void LeaveFrame(RegList regs); | 780 void LeaveFrame(RegList regs); |
| 766 void Ret(); | 781 void Ret(); |
| 767 void ReserveAlignedFrameSpace(intptr_t frame_space); | 782 void ReserveAlignedFrameSpace(intptr_t frame_space); |
| 768 | 783 |
| 769 // Create a frame for calling into runtime that preserves all volatile | 784 // Create a frame for calling into runtime that preserves all volatile |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 853 allow_constant_pool_ = b; | 868 allow_constant_pool_ = b; |
| 854 } | 869 } |
| 855 | 870 |
| 856 private: | 871 private: |
| 857 AssemblerBuffer buffer_; // Contains position independent code. | 872 AssemblerBuffer buffer_; // Contains position independent code. |
| 858 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. | 873 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
| 859 int32_t prologue_offset_; | 874 int32_t prologue_offset_; |
| 860 | 875 |
| 861 bool use_far_branches_; | 876 bool use_far_branches_; |
| 862 | 877 |
| 878 // If you are thinking of using one or both of these instructions directly, | |
| 879 // instead LoadImmediate should probably be used. | |
| 880 void movw(Register rd, uint16_t imm16, Condition cond = AL); | |
| 881 void movt(Register rd, uint16_t imm16, Condition cond = AL); | |
| 882 | |
| 863 int32_t AddObject(const Object& obj); | 883 int32_t AddObject(const Object& obj); |
| 864 int32_t AddExternalLabel(const ExternalLabel* label); | 884 int32_t AddExternalLabel(const ExternalLabel* label); |
| 865 | 885 |
| 866 void BindARMv6(Label* label); | 886 void BindARMv6(Label* label); |
| 867 void BindARMv7(Label* label); | 887 void BindARMv7(Label* label); |
| 868 | 888 |
| 869 class CodeComment : public ZoneAllocated { | 889 class CodeComment : public ZoneAllocated { |
| 870 public: | 890 public: |
| 871 CodeComment(intptr_t pc_offset, const String& comment) | 891 CodeComment(intptr_t pc_offset, const String& comment) |
| 872 : pc_offset_(pc_offset), comment_(comment) { } | 892 : pc_offset_(pc_offset), comment_(comment) { } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 993 Register value, | 1013 Register value, |
| 994 Label* no_update); | 1014 Label* no_update); |
| 995 | 1015 |
| 996 DISALLOW_ALLOCATION(); | 1016 DISALLOW_ALLOCATION(); |
| 997 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1017 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 998 }; | 1018 }; |
| 999 | 1019 |
| 1000 } // namespace dart | 1020 } // namespace dart |
| 1001 | 1021 |
| 1002 #endif // VM_ASSEMBLER_ARM_H_ | 1022 #endif // VM_ASSEMBLER_ARM_H_ |
| OLD | NEW |