Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64_H_ | 5 #ifndef VM_ASSEMBLER_ARM64_H_ |
| 6 #define VM_ASSEMBLER_ARM64_H_ | 6 #define VM_ASSEMBLER_ARM64_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_arm64.h directly; use assembler.h instead. | 9 #error Do not include assembler_arm64.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 } | 62 } |
| 63 | 63 |
| 64 friend class Assembler; | 64 friend class Assembler; |
| 65 DISALLOW_COPY_AND_ASSIGN(Label); | 65 DISALLOW_COPY_AND_ASSIGN(Label); |
| 66 }; | 66 }; |
| 67 | 67 |
| 68 | 68 |
| 69 class Address : public ValueObject { | 69 class Address : public ValueObject { |
| 70 public: | 70 public: |
| 71 Address(const Address& other) | 71 Address(const Address& other) |
| 72 : ValueObject(), encoding_(other.encoding_) { | 72 : ValueObject(), |
| 73 encoding_(other.encoding_), | |
| 74 type_(other.type_), | |
| 75 base_(other.base_) { | |
| 73 } | 76 } |
| 74 | 77 |
| 75 Address& operator=(const Address& other) { | 78 Address& operator=(const Address& other) { |
| 76 encoding_ = other.encoding_; | 79 encoding_ = other.encoding_; |
| 80 type_ = other.type_; | |
| 81 base_ = other.base_; | |
| 77 return *this; | 82 return *this; |
| 78 } | 83 } |
| 79 | 84 |
| 80 Address(Register rn, int32_t offset = 0) { | 85 enum AddressType { |
| 81 ASSERT(Utils::IsAbsoluteUint(12, offset)); | 86 Offset, |
| 82 encoding_ = -1; | 87 PreIndex, |
| 88 PostIndex, | |
| 89 Reg, | |
| 90 }; | |
| 91 | |
| 92 // Offset is in bytes. We translate to number of operands for the larger | |
| 93 // unsigned imm12 case based on the OperandSize. For the smaller signed | |
| 94 // imm9 case, the offset is the number of bytes, but is unscaled. | |
|
regis
2014/04/07 23:38:19
I do not understand "We translate to number of ope
zra
2014/04/08 15:14:13
Tried to clarify. Also added an assert.
| |
| 95 Address(Register rn, int32_t offset = 0, AddressType at = Offset, | |
| 96 OperandSize sz = kDoubleWord) { | |
| 97 ASSERT((rn != R31) && (rn != ZR)); | |
| 98 const Register crn = ConcreteRegister(rn); | |
| 99 const int32_t scale = Log2OperandSizeBytes(sz); | |
| 100 if (Utils::IsUint(12 + scale, offset) && (at == Offset)) { | |
| 101 encoding_ = | |
| 102 B24 | | |
| 103 ((offset >> scale) << kImm12Shift) | | |
| 104 (static_cast<int32_t>(crn) << kRnShift); | |
| 105 } else { | |
| 106 ASSERT(Utils::IsInt(9, offset)); | |
| 107 ASSERT((at == PreIndex) || (at == PostIndex)); | |
| 108 int32_t idx = (at == PostIndex) ? B10 : (B11 | B10); | |
| 109 encoding_ = | |
| 110 idx | | |
| 111 ((offset & 0x1ff) << kImm9Shift) | | |
| 112 (static_cast<int32_t>(crn) << kRnShift); | |
| 113 } | |
| 114 type_ = at; | |
| 115 base_ = crn; | |
| 116 } | |
| 117 | |
| 118 // TODO(zra): Write CanHoldOffset(int32_t off, AddressType, OperandSize). | |
| 119 // TODO(zra): Write constructor for PC-relative load address. | |
| 120 | |
| 121 // Base register rn with offset rm. rm is sign-extended according to ext. | |
| 122 // If ext is UXTX, rm may be optionally scaled by the | |
| 123 // Log2OperandSize (specified by the instruction). | |
| 124 Address(Register rn, Register rm, Extend ext = UXTX, bool scaled = false) { | |
| 125 ASSERT((rn != R31) && (rn != ZR)); | |
| 126 ASSERT((rm != R31) && (rm != SP)); | |
| 127 ASSERT(!scaled || (ext == UXTX)); // Can only scale when ext = UXTX. | |
| 128 ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX)); | |
| 129 const Register crn = ConcreteRegister(rn); | |
| 130 const Register crm = ConcreteRegister(rm); | |
| 131 const int32_t s = scaled ? B12 : 0; | |
| 132 encoding_ = | |
| 133 B21 | B11 | s | | |
| 134 (static_cast<int32_t>(crn) << kRnShift) | | |
| 135 (static_cast<int32_t>(crm) << kRmShift) | | |
| 136 (static_cast<int32_t>(ext) << kExtendTypeShift); | |
| 137 type_ = Reg; | |
| 138 base_ = crn; | |
| 83 } | 139 } |
| 84 | 140 |
| 85 private: | 141 private: |
| 86 uint32_t encoding() const { return encoding_; } | 142 uint32_t encoding() const { return encoding_; } |
| 143 AddressType type() const { return type_; } | |
| 144 Register base() const { return base_; } | |
| 87 | 145 |
| 88 uint32_t encoding_; | 146 uint32_t encoding_; |
| 147 AddressType type_; | |
| 148 Register base_; | |
| 89 | 149 |
| 90 friend class Assembler; | 150 friend class Assembler; |
| 91 }; | 151 }; |
| 92 | 152 |
| 93 | 153 |
| 94 class FieldAddress : public Address { | 154 class FieldAddress : public Address { |
| 95 public: | 155 public: |
| 96 FieldAddress(Register base, int32_t disp) | 156 FieldAddress(Register base, int32_t disp) |
| 97 : Address(base, disp - kHeapObjectTag) { } | 157 : Address(base, disp - kHeapObjectTag) { } |
| 98 | 158 |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 ASSERT(rd != SP); | 341 ASSERT(rd != SP); |
| 282 const Register crd = ConcreteRegister(rd); | 342 const Register crd = ConcreteRegister(rd); |
| 283 EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord); | 343 EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord); |
| 284 } | 344 } |
| 285 void movz(Register rd, int32_t imm, int32_t hw_idx) { | 345 void movz(Register rd, int32_t imm, int32_t hw_idx) { |
| 286 ASSERT(rd != SP); | 346 ASSERT(rd != SP); |
| 287 const Register crd = ConcreteRegister(rd); | 347 const Register crd = ConcreteRegister(rd); |
| 288 EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord); | 348 EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord); |
| 289 } | 349 } |
| 290 | 350 |
| 351 // Loads and Stores. | |
| 352 void ldr(Register rt, Address a) { | |
| 353 // If we are doing pre-/post-indexing, and the base and result registers | |
| 354 // are the same, then the result of the load will be clobbered by the | |
| 355 // writeback, which is unlikely to be useful. | |
| 356 ASSERT(((a.type() != Address::PreIndex) && | |
| 357 (a.type() != Address::PostIndex)) || | |
| 358 (rt != a.base())); | |
| 359 EmitLoadStoreReg(LDR, rt, a, kDoubleWord); | |
| 360 } | |
| 361 void str(Register rt, Address a) { | |
| 362 EmitLoadStoreReg(STR, rt, a, kDoubleWord); | |
| 363 } | |
| 291 | 364 |
| 292 // Function return. | 365 // Function return. |
| 293 void ret(Register rn = R30) { | 366 void ret(Register rn = R30) { |
| 294 EmitUnconditionalBranchRegOp(RET, rn); | 367 EmitUnconditionalBranchRegOp(RET, rn); |
| 295 } | 368 } |
| 296 | 369 |
| 297 private: | 370 private: |
| 298 AssemblerBuffer buffer_; // Contains position independent code. | 371 AssemblerBuffer buffer_; // Contains position independent code. |
| 299 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. | 372 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
| 300 int32_t prologue_offset_; | 373 int32_t prologue_offset_; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 ASSERT((sz == kDoubleWord) || (sz == kWord)); | 449 ASSERT((sz == kDoubleWord) || (sz == kWord)); |
| 377 const int32_t size = (sz == kDoubleWord) ? B31 : 0; | 450 const int32_t size = (sz == kDoubleWord) ? B31 : 0; |
| 378 const int32_t encoding = | 451 const int32_t encoding = |
| 379 op | size | | 452 op | size | |
| 380 (static_cast<int32_t>(rd) << kRdShift) | | 453 (static_cast<int32_t>(rd) << kRdShift) | |
| 381 (hw_idx << kHWShift) | | 454 (hw_idx << kHWShift) | |
| 382 (imm << kImm16Shift); | 455 (imm << kImm16Shift); |
| 383 Emit(encoding); | 456 Emit(encoding); |
| 384 } | 457 } |
| 385 | 458 |
| 459 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, | |
| 460 OperandSize sz) { | |
| 461 const int32_t size = Log2OperandSizeBytes(sz); | |
| 462 const int32_t encoding = | |
| 463 op | (size << kSzShift) | | |
| 464 (static_cast<int32_t>(rt) << kRtShift) | | |
| 465 a.encoding(); | |
| 466 Emit(encoding); | |
| 467 } | |
| 468 | |
| 386 DISALLOW_ALLOCATION(); | 469 DISALLOW_ALLOCATION(); |
| 387 DISALLOW_COPY_AND_ASSIGN(Assembler); | 470 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 388 }; | 471 }; |
| 389 | 472 |
| 390 } // namespace dart | 473 } // namespace dart |
| 391 | 474 |
| 392 #endif // VM_ASSEMBLER_ARM64_H_ | 475 #endif // VM_ASSEMBLER_ARM64_H_ |
| OLD | NEW |