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 RUNTIME_VM_ASSEMBLER_ARM_H_ | 5 #ifndef RUNTIME_VM_ASSEMBLER_ARM_H_ |
6 #define RUNTIME_VM_ASSEMBLER_ARM_H_ | 6 #define RUNTIME_VM_ASSEMBLER_ARM_H_ |
7 | 7 |
8 #ifndef RUNTIME_VM_ASSEMBLER_H_ | 8 #ifndef RUNTIME_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 |
11 | 11 |
12 #include "platform/assert.h" | 12 #include "platform/assert.h" |
13 #include "platform/utils.h" | 13 #include "platform/utils.h" |
14 #include "vm/constants_arm.h" | 14 #include "vm/constants_arm.h" |
15 #include "vm/cpu.h" | 15 #include "vm/cpu.h" |
16 #include "vm/hash_map.h" | 16 #include "vm/hash_map.h" |
17 #include "vm/object.h" | 17 #include "vm/object.h" |
18 #include "vm/simulator.h" | 18 #include "vm/simulator.h" |
19 | 19 |
20 namespace dart { | 20 namespace dart { |
21 | 21 |
22 // Forward declarations. | 22 // Forward declarations. |
23 class RuntimeEntry; | 23 class RuntimeEntry; |
24 class StubEntry; | 24 class StubEntry; |
25 | 25 |
26 | |
27 // Instruction encoding bits. | 26 // Instruction encoding bits. |
28 enum { | 27 enum { |
29 H = 1 << 5, // halfword (or byte) | 28 H = 1 << 5, // halfword (or byte) |
30 L = 1 << 20, // load (or store) | 29 L = 1 << 20, // load (or store) |
31 S = 1 << 20, // set condition code (or leave unchanged) | 30 S = 1 << 20, // set condition code (or leave unchanged) |
32 W = 1 << 21, // writeback base register (or leave unchanged) | 31 W = 1 << 21, // writeback base register (or leave unchanged) |
33 A = 1 << 21, // accumulate in multiply instruction (or not) | 32 A = 1 << 21, // accumulate in multiply instruction (or not) |
34 B = 1 << 22, // unsigned byte (or word) | 33 B = 1 << 22, // unsigned byte (or word) |
35 D = 1 << 22, // high/lo bit of start of s/d register range | 34 D = 1 << 22, // high/lo bit of start of s/d register range |
36 N = 1 << 22, // long (or short) | 35 N = 1 << 22, // long (or short) |
(...skipping 21 matching lines...) Expand all Loading... |
58 B20 = 1 << 20, | 57 B20 = 1 << 20, |
59 B21 = 1 << 21, | 58 B21 = 1 << 21, |
60 B22 = 1 << 22, | 59 B22 = 1 << 22, |
61 B23 = 1 << 23, | 60 B23 = 1 << 23, |
62 B24 = 1 << 24, | 61 B24 = 1 << 24, |
63 B25 = 1 << 25, | 62 B25 = 1 << 25, |
64 B26 = 1 << 26, | 63 B26 = 1 << 26, |
65 B27 = 1 << 27, | 64 B27 = 1 << 27, |
66 }; | 65 }; |
67 | 66 |
68 | |
69 class Label : public ValueObject { | 67 class Label : public ValueObject { |
70 public: | 68 public: |
71 Label() : position_(0) {} | 69 Label() : position_(0) {} |
72 | 70 |
73 ~Label() { | 71 ~Label() { |
74 // Assert if label is being destroyed with unresolved branches pending. | 72 // Assert if label is being destroyed with unresolved branches pending. |
75 ASSERT(!IsLinked()); | 73 ASSERT(!IsLinked()); |
76 } | 74 } |
77 | 75 |
78 // Returns the position for bound and linked labels. Cannot be used | 76 // Returns the position for bound and linked labels. Cannot be used |
(...skipping 21 matching lines...) Expand all Loading... |
100 void LinkTo(intptr_t position) { | 98 void LinkTo(intptr_t position) { |
101 ASSERT(!IsBound()); | 99 ASSERT(!IsBound()); |
102 position_ = position + kWordSize; | 100 position_ = position + kWordSize; |
103 ASSERT(IsLinked()); | 101 ASSERT(IsLinked()); |
104 } | 102 } |
105 | 103 |
106 friend class Assembler; | 104 friend class Assembler; |
107 DISALLOW_COPY_AND_ASSIGN(Label); | 105 DISALLOW_COPY_AND_ASSIGN(Label); |
108 }; | 106 }; |
109 | 107 |
110 | |
111 // Encodes Addressing Mode 1 - Data-processing operands. | 108 // Encodes Addressing Mode 1 - Data-processing operands. |
112 class Operand : public ValueObject { | 109 class Operand : public ValueObject { |
113 public: | 110 public: |
114 // Data-processing operands - Uninitialized. | 111 // Data-processing operands - Uninitialized. |
115 Operand() : type_(-1), encoding_(-1) {} | 112 Operand() : type_(-1), encoding_(-1) {} |
116 | 113 |
117 // Data-processing operands - Copy constructor. | 114 // Data-processing operands - Copy constructor. |
118 Operand(const Operand& other) | 115 Operand(const Operand& other) |
119 : ValueObject(), type_(other.type_), encoding_(other.encoding_) {} | 116 : ValueObject(), type_(other.type_), encoding_(other.encoding_) {} |
120 | 117 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 return encoding_; | 191 return encoding_; |
195 } | 192 } |
196 | 193 |
197 uint32_t type_; // Encodes the type field (bits 27-25) in the instruction. | 194 uint32_t type_; // Encodes the type field (bits 27-25) in the instruction. |
198 uint32_t encoding_; | 195 uint32_t encoding_; |
199 | 196 |
200 friend class Assembler; | 197 friend class Assembler; |
201 friend class Address; | 198 friend class Address; |
202 }; | 199 }; |
203 | 200 |
204 | |
205 enum OperandSize { | 201 enum OperandSize { |
206 kByte, | 202 kByte, |
207 kUnsignedByte, | 203 kUnsignedByte, |
208 kHalfword, | 204 kHalfword, |
209 kUnsignedHalfword, | 205 kUnsignedHalfword, |
210 kWord, | 206 kWord, |
211 kUnsignedWord, | 207 kUnsignedWord, |
212 kWordPair, | 208 kWordPair, |
213 kSWord, | 209 kSWord, |
214 kDWord, | 210 kDWord, |
215 kRegList, | 211 kRegList, |
216 }; | 212 }; |
217 | 213 |
218 | |
219 // Load/store multiple addressing mode. | 214 // Load/store multiple addressing mode. |
220 enum BlockAddressMode { | 215 enum BlockAddressMode { |
221 // bit encoding P U W | 216 // bit encoding P U W |
222 DA = (0 | 0 | 0) << 21, // decrement after | 217 DA = (0 | 0 | 0) << 21, // decrement after |
223 IA = (0 | 4 | 0) << 21, // increment after | 218 IA = (0 | 4 | 0) << 21, // increment after |
224 DB = (8 | 0 | 0) << 21, // decrement before | 219 DB = (8 | 0 | 0) << 21, // decrement before |
225 IB = (8 | 4 | 0) << 21, // increment before | 220 IB = (8 | 4 | 0) << 21, // increment before |
226 DA_W = (0 | 0 | 1) << 21, // decrement after with writeback to base | 221 DA_W = (0 | 0 | 1) << 21, // decrement after with writeback to base |
227 IA_W = (0 | 4 | 1) << 21, // increment after with writeback to base | 222 IA_W = (0 | 4 | 1) << 21, // increment after with writeback to base |
228 DB_W = (8 | 0 | 1) << 21, // decrement before with writeback to base | 223 DB_W = (8 | 0 | 1) << 21, // decrement before with writeback to base |
229 IB_W = (8 | 4 | 1) << 21 // increment before with writeback to base | 224 IB_W = (8 | 4 | 1) << 21 // increment before with writeback to base |
230 }; | 225 }; |
231 | 226 |
232 | |
233 class Address : public ValueObject { | 227 class Address : public ValueObject { |
234 public: | 228 public: |
235 enum OffsetKind { | 229 enum OffsetKind { |
236 Immediate, | 230 Immediate, |
237 IndexRegister, | 231 IndexRegister, |
238 ScaledIndexRegister, | 232 ScaledIndexRegister, |
239 }; | 233 }; |
240 | 234 |
241 // Memory operand addressing mode | 235 // Memory operand addressing mode |
242 enum Mode { | 236 enum Mode { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 | 330 |
337 OffsetKind kind() const { return kind_; } | 331 OffsetKind kind() const { return kind_; } |
338 | 332 |
339 uint32_t encoding_; | 333 uint32_t encoding_; |
340 | 334 |
341 OffsetKind kind_; | 335 OffsetKind kind_; |
342 | 336 |
343 friend class Assembler; | 337 friend class Assembler; |
344 }; | 338 }; |
345 | 339 |
346 | |
347 class FieldAddress : public Address { | 340 class FieldAddress : public Address { |
348 public: | 341 public: |
349 FieldAddress(Register base, int32_t disp) | 342 FieldAddress(Register base, int32_t disp) |
350 : Address(base, disp - kHeapObjectTag) {} | 343 : Address(base, disp - kHeapObjectTag) {} |
351 | 344 |
352 // This addressing mode does not exist. | 345 // This addressing mode does not exist. |
353 FieldAddress(Register base, Register r); | 346 FieldAddress(Register base, Register r); |
354 | 347 |
355 FieldAddress(const FieldAddress& other) : Address(other) {} | 348 FieldAddress(const FieldAddress& other) : Address(other) {} |
356 | 349 |
357 FieldAddress& operator=(const FieldAddress& other) { | 350 FieldAddress& operator=(const FieldAddress& other) { |
358 Address::operator=(other); | 351 Address::operator=(other); |
359 return *this; | 352 return *this; |
360 } | 353 } |
361 }; | 354 }; |
362 | 355 |
363 | |
364 class Assembler : public ValueObject { | 356 class Assembler : public ValueObject { |
365 public: | 357 public: |
366 explicit Assembler(bool use_far_branches = false) | 358 explicit Assembler(bool use_far_branches = false) |
367 : buffer_(), | 359 : buffer_(), |
368 prologue_offset_(-1), | 360 prologue_offset_(-1), |
369 has_single_entry_point_(true), | 361 has_single_entry_point_(true), |
370 use_far_branches_(use_far_branches), | 362 use_far_branches_(use_far_branches), |
371 comments_(), | 363 comments_(), |
372 constant_pool_allowed_(false) {} | 364 constant_pool_allowed_(false) {} |
373 | 365 |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 int32_t value, | 738 int32_t value, |
747 Condition cond = AL); | 739 Condition cond = AL); |
748 void AndImmediate(Register rd, Register rs, int32_t imm, Condition cond = AL); | 740 void AndImmediate(Register rd, Register rs, int32_t imm, Condition cond = AL); |
749 | 741 |
750 // Test rn and immediate. May clobber IP. | 742 // Test rn and immediate. May clobber IP. |
751 void TestImmediate(Register rn, int32_t imm, Condition cond = AL); | 743 void TestImmediate(Register rn, int32_t imm, Condition cond = AL); |
752 | 744 |
753 // Compare rn with signed immediate value. May clobber IP. | 745 // Compare rn with signed immediate value. May clobber IP. |
754 void CompareImmediate(Register rn, int32_t value, Condition cond = AL); | 746 void CompareImmediate(Register rn, int32_t value, Condition cond = AL); |
755 | 747 |
756 | |
757 // Signed integer division of left by right. Checks to see if integer | 748 // Signed integer division of left by right. Checks to see if integer |
758 // division is supported. If not, uses the FPU for division with | 749 // division is supported. If not, uses the FPU for division with |
759 // temporary registers tmpl and tmpr. tmpl and tmpr must be different | 750 // temporary registers tmpl and tmpr. tmpl and tmpr must be different |
760 // registers. | 751 // registers. |
761 void IntegerDivide(Register result, | 752 void IntegerDivide(Register result, |
762 Register left, | 753 Register left, |
763 Register right, | 754 Register right, |
764 DRegister tmpl, | 755 DRegister tmpl, |
765 DRegister tmpr); | 756 DRegister tmpr); |
766 | 757 |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1256 Register value, | 1247 Register value, |
1257 Label* no_update); | 1248 Label* no_update); |
1258 | 1249 |
1259 DISALLOW_ALLOCATION(); | 1250 DISALLOW_ALLOCATION(); |
1260 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1251 DISALLOW_COPY_AND_ASSIGN(Assembler); |
1261 }; | 1252 }; |
1262 | 1253 |
1263 } // namespace dart | 1254 } // namespace dart |
1264 | 1255 |
1265 #endif // RUNTIME_VM_ASSEMBLER_ARM_H_ | 1256 #endif // RUNTIME_VM_ASSEMBLER_ARM_H_ |
OLD | NEW |