| 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 |