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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 position_ = position + kWordSize; | 58 position_ = position + kWordSize; |
59 ASSERT(IsLinked()); | 59 ASSERT(IsLinked()); |
60 } | 60 } |
61 | 61 |
62 friend class Assembler; | 62 friend class Assembler; |
63 DISALLOW_COPY_AND_ASSIGN(Label); | 63 DISALLOW_COPY_AND_ASSIGN(Label); |
64 }; | 64 }; |
65 | 65 |
66 | 66 |
67 // Encodes Addressing Mode 1 - Data-processing operands. | 67 // Encodes Addressing Mode 1 - Data-processing operands. |
68 // TODO(regis): rename ShifterOperand to Operand. | 68 class Operand : public ValueObject { |
69 class ShifterOperand : public ValueObject { | |
70 public: | 69 public: |
71 // Data-processing operands - Uninitialized. | 70 // Data-processing operands - Uninitialized. |
72 ShifterOperand() : type_(-1), encoding_(-1) { } | 71 Operand() : type_(-1), encoding_(-1) { } |
73 | 72 |
74 // Data-processing operands - Copy constructor. | 73 // Data-processing operands - Copy constructor. |
75 ShifterOperand(const ShifterOperand& other) | 74 Operand(const Operand& other) |
76 : ValueObject(), type_(other.type_), encoding_(other.encoding_) { } | 75 : ValueObject(), type_(other.type_), encoding_(other.encoding_) { } |
77 | 76 |
78 // Data-processing operands - Assignment operator. | 77 // Data-processing operands - Assignment operator. |
79 ShifterOperand& operator=(const ShifterOperand& other) { | 78 Operand& operator=(const Operand& other) { |
80 type_ = other.type_; | 79 type_ = other.type_; |
81 encoding_ = other.encoding_; | 80 encoding_ = other.encoding_; |
82 return *this; | 81 return *this; |
83 } | 82 } |
84 | 83 |
85 // Data-processing operands - Immediate. | 84 // Data-processing operands - Immediate. |
86 explicit ShifterOperand(uint32_t immediate) { | 85 explicit Operand(uint32_t immediate) { |
87 ASSERT(immediate < (1 << kImmed8Bits)); | 86 ASSERT(immediate < (1 << kImmed8Bits)); |
88 type_ = 1; | 87 type_ = 1; |
89 encoding_ = immediate; | 88 encoding_ = immediate; |
90 } | 89 } |
91 | 90 |
92 // Data-processing operands - Rotated immediate. | 91 // Data-processing operands - Rotated immediate. |
93 ShifterOperand(uint32_t rotate, uint32_t immed8) { | 92 Operand(uint32_t rotate, uint32_t immed8) { |
94 ASSERT((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits))); | 93 ASSERT((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits))); |
95 type_ = 1; | 94 type_ = 1; |
96 encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift); | 95 encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift); |
97 } | 96 } |
98 | 97 |
99 // Data-processing operands - Register. | 98 // Data-processing operands - Register. |
100 explicit ShifterOperand(Register rm) { | 99 explicit Operand(Register rm) { |
101 type_ = 0; | 100 type_ = 0; |
102 encoding_ = static_cast<uint32_t>(rm); | 101 encoding_ = static_cast<uint32_t>(rm); |
103 } | 102 } |
104 | 103 |
105 // Data-processing operands - Logical shift/rotate by immediate. | 104 // Data-processing operands - Logical shift/rotate by immediate. |
106 ShifterOperand(Register rm, Shift shift, uint32_t shift_imm) { | 105 Operand(Register rm, Shift shift, uint32_t shift_imm) { |
107 ASSERT(shift_imm < (1 << kShiftImmBits)); | 106 ASSERT(shift_imm < (1 << kShiftImmBits)); |
108 type_ = 0; | 107 type_ = 0; |
109 encoding_ = shift_imm << kShiftImmShift | | 108 encoding_ = shift_imm << kShiftImmShift | |
110 static_cast<uint32_t>(shift) << kShiftShift | | 109 static_cast<uint32_t>(shift) << kShiftShift | |
111 static_cast<uint32_t>(rm); | 110 static_cast<uint32_t>(rm); |
112 } | 111 } |
113 | 112 |
114 // Data-processing operands - Logical shift/rotate by register. | 113 // Data-processing operands - Logical shift/rotate by register. |
115 ShifterOperand(Register rm, Shift shift, Register rs) { | 114 Operand(Register rm, Shift shift, Register rs) { |
116 type_ = 0; | 115 type_ = 0; |
117 encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift | | 116 encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift | |
118 static_cast<uint32_t>(shift) << kShiftShift | (1 << 4) | | 117 static_cast<uint32_t>(shift) << kShiftShift | (1 << 4) | |
119 static_cast<uint32_t>(rm); | 118 static_cast<uint32_t>(rm); |
120 } | 119 } |
121 | 120 |
122 static bool CanHold(uint32_t immediate, ShifterOperand* shifter_op) { | 121 static bool CanHold(uint32_t immediate, Operand* o) { |
123 // Avoid the more expensive test for frequent small immediate values. | 122 // Avoid the more expensive test for frequent small immediate values. |
124 if (immediate < (1 << kImmed8Bits)) { | 123 if (immediate < (1 << kImmed8Bits)) { |
125 shifter_op->type_ = 1; | 124 o->type_ = 1; |
126 shifter_op->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift); | 125 o->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift); |
127 return true; | 126 return true; |
128 } | 127 } |
129 // Note that immediate must be unsigned for the test to work correctly. | 128 // Note that immediate must be unsigned for the test to work correctly. |
130 for (int rot = 0; rot < 16; rot++) { | 129 for (int rot = 0; rot < 16; rot++) { |
131 uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot)); | 130 uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot)); |
132 if (imm8 < (1 << kImmed8Bits)) { | 131 if (imm8 < (1 << kImmed8Bits)) { |
133 shifter_op->type_ = 1; | 132 o->type_ = 1; |
134 shifter_op->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift); | 133 o->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift); |
135 return true; | 134 return true; |
136 } | 135 } |
137 } | 136 } |
138 return false; | 137 return false; |
139 } | 138 } |
140 | 139 |
141 private: | 140 private: |
142 bool is_valid() const { return (type_ == 0) || (type_ == 1); } | 141 bool is_valid() const { return (type_ == 0) || (type_ == 1); } |
143 | 142 |
144 uint32_t type() const { | 143 uint32_t type() const { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 if (offset < 0) { | 225 if (offset < 0) { |
227 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign. | 226 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign. |
228 } else { | 227 } else { |
229 encoding_ = am | offset; | 228 encoding_ = am | offset; |
230 } | 229 } |
231 encoding_ |= static_cast<uint32_t>(rn) << kRnShift; | 230 encoding_ |= static_cast<uint32_t>(rn) << kRnShift; |
232 } | 231 } |
233 | 232 |
234 Address(Register rn, Register rm, | 233 Address(Register rn, Register rm, |
235 Shift shift = LSL, uint32_t shift_imm = 0, Mode am = Offset) { | 234 Shift shift = LSL, uint32_t shift_imm = 0, Mode am = Offset) { |
236 ShifterOperand so(rm, shift, shift_imm); | 235 Operand o(rm, shift, shift_imm); |
237 | 236 |
238 if ((shift == LSL) && (shift_imm == 0)) { | 237 if ((shift == LSL) && (shift_imm == 0)) { |
239 kind_ = IndexRegister; | 238 kind_ = IndexRegister; |
240 } else { | 239 } else { |
241 kind_ = ScaledIndexRegister; | 240 kind_ = ScaledIndexRegister; |
242 } | 241 } |
243 encoding_ = so.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift); | 242 encoding_ = o.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift); |
244 } | 243 } |
245 | 244 |
246 static OperandSize OperandSizeFor(intptr_t cid); | 245 static OperandSize OperandSizeFor(intptr_t cid); |
247 | 246 |
248 static bool CanHoldLoadOffset(OperandSize size, | 247 static bool CanHoldLoadOffset(OperandSize size, |
249 int32_t offset, | 248 int32_t offset, |
250 int32_t* offset_mask); | 249 int32_t* offset_mask); |
251 static bool CanHoldStoreOffset(OperandSize size, | 250 static bool CanHoldStoreOffset(OperandSize size, |
252 int32_t offset, | 251 int32_t offset, |
253 int32_t* offset_mask); | 252 int32_t* offset_mask); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 | 335 |
337 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); | 336 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
338 | 337 |
339 const Code::Comments& GetCodeComments() const; | 338 const Code::Comments& GetCodeComments() const; |
340 | 339 |
341 static const char* RegisterName(Register reg); | 340 static const char* RegisterName(Register reg); |
342 | 341 |
343 static const char* FpuRegisterName(FpuRegister reg); | 342 static const char* FpuRegisterName(FpuRegister reg); |
344 | 343 |
345 // Data-processing instructions. | 344 // Data-processing instructions. |
346 void and_(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 345 void and_(Register rd, Register rn, Operand o, Condition cond = AL); |
347 | 346 |
348 void eor(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 347 void eor(Register rd, Register rn, Operand o, Condition cond = AL); |
349 | 348 |
350 void sub(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 349 void sub(Register rd, Register rn, Operand o, Condition cond = AL); |
351 void subs(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 350 void subs(Register rd, Register rn, Operand o, Condition cond = AL); |
352 | 351 |
353 void rsb(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 352 void rsb(Register rd, Register rn, Operand o, Condition cond = AL); |
354 void rsbs(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 353 void rsbs(Register rd, Register rn, Operand o, Condition cond = AL); |
355 | 354 |
356 void add(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 355 void add(Register rd, Register rn, Operand o, Condition cond = AL); |
357 | 356 |
358 void adds(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 357 void adds(Register rd, Register rn, Operand o, Condition cond = AL); |
359 | 358 |
360 void adc(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 359 void adc(Register rd, Register rn, Operand o, Condition cond = AL); |
361 | 360 |
362 void adcs(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 361 void adcs(Register rd, Register rn, Operand o, Condition cond = AL); |
363 | 362 |
364 void sbc(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 363 void sbc(Register rd, Register rn, Operand o, Condition cond = AL); |
365 | 364 |
366 void sbcs(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 365 void sbcs(Register rd, Register rn, Operand o, Condition cond = AL); |
367 | 366 |
368 void rsc(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 367 void rsc(Register rd, Register rn, Operand o, Condition cond = AL); |
369 | 368 |
370 void tst(Register rn, ShifterOperand so, Condition cond = AL); | 369 void tst(Register rn, Operand o, Condition cond = AL); |
371 | 370 |
372 void teq(Register rn, ShifterOperand so, Condition cond = AL); | 371 void teq(Register rn, Operand o, Condition cond = AL); |
373 | 372 |
374 void cmp(Register rn, ShifterOperand so, Condition cond = AL); | 373 void cmp(Register rn, Operand o, Condition cond = AL); |
375 | 374 |
376 void cmn(Register rn, ShifterOperand so, Condition cond = AL); | 375 void cmn(Register rn, Operand o, Condition cond = AL); |
377 | 376 |
378 void orr(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 377 void orr(Register rd, Register rn, Operand o, Condition cond = AL); |
379 void orrs(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 378 void orrs(Register rd, Register rn, Operand o, Condition cond = AL); |
380 | 379 |
381 void mov(Register rd, ShifterOperand so, Condition cond = AL); | 380 void mov(Register rd, Operand o, Condition cond = AL); |
382 void movs(Register rd, ShifterOperand so, Condition cond = AL); | 381 void movs(Register rd, Operand o, Condition cond = AL); |
383 | 382 |
384 void bic(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 383 void bic(Register rd, Register rn, Operand o, Condition cond = AL); |
385 void bics(Register rd, Register rn, ShifterOperand so, Condition cond = AL); | 384 void bics(Register rd, Register rn, Operand o, Condition cond = AL); |
386 | 385 |
387 void mvn(Register rd, ShifterOperand so, Condition cond = AL); | 386 void mvn(Register rd, Operand o, Condition cond = AL); |
388 void mvns(Register rd, ShifterOperand so, Condition cond = AL); | 387 void mvns(Register rd, Operand o, Condition cond = AL); |
389 | 388 |
390 // Miscellaneous data-processing instructions. | 389 // Miscellaneous data-processing instructions. |
391 void clz(Register rd, Register rm, Condition cond = AL); | 390 void clz(Register rd, Register rm, Condition cond = AL); |
392 void movw(Register rd, uint16_t imm16, Condition cond = AL); | 391 void movw(Register rd, uint16_t imm16, Condition cond = AL); |
393 void movt(Register rd, uint16_t imm16, Condition cond = AL); | 392 void movt(Register rd, uint16_t imm16, Condition cond = AL); |
394 | 393 |
395 // Multiply instructions. | 394 // Multiply instructions. |
396 void mul(Register rd, Register rn, Register rm, Condition cond = AL); | 395 void mul(Register rd, Register rn, Register rm, Condition cond = AL); |
397 void muls(Register rd, Register rn, Register rm, Condition cond = AL); | 396 void muls(Register rd, Register rn, Register rm, Condition cond = AL); |
398 void mla(Register rd, Register rn, Register rm, Register ra, | 397 void mla(Register rd, Register rn, Register rm, Register ra, |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 }; | 812 }; |
814 | 813 |
815 GrowableArray<CodeComment*> comments_; | 814 GrowableArray<CodeComment*> comments_; |
816 | 815 |
817 void EmitType01(Condition cond, | 816 void EmitType01(Condition cond, |
818 int type, | 817 int type, |
819 Opcode opcode, | 818 Opcode opcode, |
820 int set_cc, | 819 int set_cc, |
821 Register rn, | 820 Register rn, |
822 Register rd, | 821 Register rd, |
823 ShifterOperand so); | 822 Operand o); |
824 | 823 |
825 void EmitType5(Condition cond, int32_t offset, bool link); | 824 void EmitType5(Condition cond, int32_t offset, bool link); |
826 | 825 |
827 void EmitMemOp(Condition cond, | 826 void EmitMemOp(Condition cond, |
828 bool load, | 827 bool load, |
829 bool byte, | 828 bool byte, |
830 Register rd, | 829 Register rd, |
831 Address ad); | 830 Address ad); |
832 | 831 |
833 void EmitMemOpAddressMode3(Condition cond, | 832 void EmitMemOpAddressMode3(Condition cond, |
834 int32_t mode, | 833 int32_t mode, |
835 Register rd, | 834 Register rd, |
836 Address ad); | 835 Address ad); |
837 | 836 |
838 void EmitMultiMemOp(Condition cond, | 837 void EmitMultiMemOp(Condition cond, |
839 BlockAddressMode am, | 838 BlockAddressMode am, |
840 bool load, | 839 bool load, |
841 Register base, | 840 Register base, |
842 RegList regs); | 841 RegList regs); |
843 | 842 |
844 void EmitShiftImmediate(Condition cond, | 843 void EmitShiftImmediate(Condition cond, |
845 Shift opcode, | 844 Shift opcode, |
846 Register rd, | 845 Register rd, |
847 Register rm, | 846 Register rm, |
848 ShifterOperand so); | 847 Operand o); |
849 | 848 |
850 void EmitShiftRegister(Condition cond, | 849 void EmitShiftRegister(Condition cond, |
851 Shift opcode, | 850 Shift opcode, |
852 Register rd, | 851 Register rd, |
853 Register rm, | 852 Register rm, |
854 ShifterOperand so); | 853 Operand o); |
855 | 854 |
856 void EmitMulOp(Condition cond, | 855 void EmitMulOp(Condition cond, |
857 int32_t opcode, | 856 int32_t opcode, |
858 Register rd, | 857 Register rd, |
859 Register rn, | 858 Register rn, |
860 Register rm, | 859 Register rm, |
861 Register rs); | 860 Register rs); |
862 | 861 |
863 void EmitDivOp(Condition cond, | 862 void EmitDivOp(Condition cond, |
864 int32_t opcode, | 863 int32_t opcode, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 Register value, | 921 Register value, |
923 Label* no_update); | 922 Label* no_update); |
924 | 923 |
925 DISALLOW_ALLOCATION(); | 924 DISALLOW_ALLOCATION(); |
926 DISALLOW_COPY_AND_ASSIGN(Assembler); | 925 DISALLOW_COPY_AND_ASSIGN(Assembler); |
927 }; | 926 }; |
928 | 927 |
929 } // namespace dart | 928 } // namespace dart |
930 | 929 |
931 #endif // VM_ASSEMBLER_ARM_H_ | 930 #endif // VM_ASSEMBLER_ARM_H_ |
OLD | NEW |