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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 | 102 |
| 103 // Data-processing operands - Register. | 103 // Data-processing operands - Register. |
| 104 explicit ShifterOperand(Register rm) { | 104 explicit ShifterOperand(Register rm) { |
| 105 type_ = 0; | 105 type_ = 0; |
| 106 encoding_ = static_cast<uint32_t>(rm); | 106 encoding_ = static_cast<uint32_t>(rm); |
| 107 } | 107 } |
| 108 | 108 |
| 109 // Data-processing operands - Logical shift/rotate by immediate. | 109 // Data-processing operands - Logical shift/rotate by immediate. |
| 110 ShifterOperand(Register rm, Shift shift, uint32_t shift_imm) { | 110 ShifterOperand(Register rm, Shift shift, uint32_t shift_imm) { |
| 111 ASSERT(shift_imm < (1 << kShiftImmBits)); | 111 ASSERT(shift_imm < (1 << kShiftImmBits)); |
| 112 ASSERT(!(shift == LSL && shift_imm == 0)); | |
|
regis
2013/02/26 23:39:49
You will notice that we like redundant parenthesis
| |
| 112 type_ = 0; | 113 type_ = 0; |
| 113 encoding_ = shift_imm << kShiftImmShift | | 114 encoding_ = shift_imm << kShiftImmShift | |
| 114 static_cast<uint32_t>(shift) << kShiftShift | | 115 static_cast<uint32_t>(shift) << kShiftShift | |
| 115 static_cast<uint32_t>(rm); | 116 static_cast<uint32_t>(rm); |
| 116 } | 117 } |
| 117 | 118 |
| 118 // Data-processing operands - Logical shift/rotate by register. | 119 // Data-processing operands - Logical shift/rotate by register. |
| 119 ShifterOperand(Register rm, Shift shift, Register rs) { | 120 ShifterOperand(Register rm, Shift shift, Register rs) { |
| 120 type_ = 0; | 121 type_ = 0; |
| 121 encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift | | 122 encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift | |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 152 | 153 |
| 153 uint32_t encoding() const { | 154 uint32_t encoding() const { |
| 154 ASSERT(is_valid()); | 155 ASSERT(is_valid()); |
| 155 return encoding_; | 156 return encoding_; |
| 156 } | 157 } |
| 157 | 158 |
| 158 uint32_t type_; // Encodes the type field (bits 27-25) in the instruction. | 159 uint32_t type_; // Encodes the type field (bits 27-25) in the instruction. |
| 159 uint32_t encoding_; | 160 uint32_t encoding_; |
| 160 | 161 |
| 161 friend class Assembler; | 162 friend class Assembler; |
| 163 friend class Address; | |
| 162 }; | 164 }; |
| 163 | 165 |
| 164 | 166 |
| 165 enum LoadOperandType { | 167 enum LoadOperandType { |
| 166 kLoadSignedByte, | 168 kLoadSignedByte, |
| 167 kLoadUnsignedByte, | 169 kLoadUnsignedByte, |
| 168 kLoadSignedHalfword, | 170 kLoadSignedHalfword, |
| 169 kLoadUnsignedHalfword, | 171 kLoadUnsignedHalfword, |
| 170 kLoadWord, | 172 kLoadWord, |
| 171 kLoadWordPair, | 173 kLoadWordPair, |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 193 IB = (8|4|0) << 21, // increment before | 195 IB = (8|4|0) << 21, // increment before |
| 194 DA_W = (0|0|1) << 21, // decrement after with writeback to base | 196 DA_W = (0|0|1) << 21, // decrement after with writeback to base |
| 195 IA_W = (0|4|1) << 21, // increment after with writeback to base | 197 IA_W = (0|4|1) << 21, // increment after with writeback to base |
| 196 DB_W = (8|0|1) << 21, // decrement before with writeback to base | 198 DB_W = (8|0|1) << 21, // decrement before with writeback to base |
| 197 IB_W = (8|4|1) << 21 // increment before with writeback to base | 199 IB_W = (8|4|1) << 21 // increment before with writeback to base |
| 198 }; | 200 }; |
| 199 | 201 |
| 200 | 202 |
| 201 class Address : public ValueObject { | 203 class Address : public ValueObject { |
| 202 public: | 204 public: |
| 205 enum OffsetKind { | |
| 206 Immediate, | |
| 207 ShiftedRegister, | |
| 208 }; | |
| 209 | |
| 203 // Memory operand addressing mode | 210 // Memory operand addressing mode |
| 204 enum Mode { | 211 enum Mode { |
| 205 // bit encoding P U W | 212 // bit encoding P U W |
| 206 Offset = (8|4|0) << 21, // offset (w/o writeback to base) | 213 Offset = (8|4|0) << 21, // offset (w/o writeback to base) |
| 207 PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback | 214 PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback |
| 208 PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback | 215 PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback |
| 209 NegOffset = (8|0|0) << 21, // negative offset (w/o writeback to base) | 216 NegOffset = (8|0|0) << 21, // negative offset (w/o writeback to base) |
| 210 NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback | 217 NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback |
| 211 NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback | 218 NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback |
| 212 }; | 219 }; |
| 213 | 220 |
| 214 Address(const Address& other) : ValueObject(), encoding_(other.encoding_) { } | 221 Address(const Address& other) : |
| 222 ValueObject(), encoding_(other.encoding_), kind_(other.kind_) | |
| 223 { } | |
|
regis
2013/02/26 23:39:49
The pair of braces cannot stand by themselves on a
| |
| 215 | 224 |
| 216 Address& operator=(const Address& other) { | 225 Address& operator=(const Address& other) { |
| 217 encoding_ = other.encoding_; | 226 encoding_ = other.encoding_; |
| 227 kind_ = other.kind_; | |
|
regis
2013/02/26 23:39:49
We generally do not align assignments, unless it r
| |
| 218 return *this; | 228 return *this; |
| 219 } | 229 } |
| 220 | 230 |
| 221 explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) { | 231 explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) { |
| 222 ASSERT(Utils::IsAbsoluteUint(12, offset)); | 232 ASSERT(Utils::IsAbsoluteUint(12, offset)); |
| 233 kind_ = Immediate; | |
| 223 if (offset < 0) { | 234 if (offset < 0) { |
| 224 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign. | 235 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign. |
| 225 } else { | 236 } else { |
| 226 encoding_ = am | offset; | 237 encoding_ = am | offset; |
| 227 } | 238 } |
| 228 encoding_ |= static_cast<uint32_t>(rn) << kRnShift; | 239 encoding_ |= static_cast<uint32_t>(rn) << kRnShift; |
| 229 } | 240 } |
| 230 | 241 |
| 242 explicit Address(Register rn, Register rm, Shift shift_t = LSL, | |
| 243 uint32_t shift_n = 0, Mode am = Offset) { | |
|
regis
2013/02/26 23:39:49
Instead of shift_t and shift_n, I would use the sa
| |
| 244 ShifterOperand so(rm, shift_t, shift_n); | |
| 245 | |
| 246 kind_ = ShiftedRegister; | |
|
regis
2013/02/26 23:39:49
No alignment.
| |
| 247 encoding_ = so.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift); | |
| 248 } | |
| 249 | |
| 231 static bool CanHoldLoadOffset(LoadOperandType type, int offset); | 250 static bool CanHoldLoadOffset(LoadOperandType type, int offset); |
| 232 static bool CanHoldStoreOffset(StoreOperandType type, int offset); | 251 static bool CanHoldStoreOffset(StoreOperandType type, int offset); |
| 233 | 252 |
| 234 private: | 253 private: |
| 235 uint32_t encoding() const { return encoding_; } | 254 uint32_t encoding() const { return encoding_; } |
| 236 | 255 |
| 237 // Encoding for addressing mode 3. | 256 // Encoding for addressing mode 3. |
| 238 uint32_t encoding3() const; | 257 uint32_t encoding3() const; |
| 239 | 258 |
| 240 // Encoding for vfp load/store addressing. | 259 // Encoding for vfp load/store addressing. |
| 241 uint32_t vencoding() const; | 260 uint32_t vencoding() const; |
| 242 | 261 |
| 262 enum OffsetKind kind() const { return kind_; } | |
|
regis
2013/02/26 23:39:49
We generally do not write "enum".
| |
| 263 | |
| 243 uint32_t encoding_; | 264 uint32_t encoding_; |
| 244 | 265 |
| 266 enum OffsetKind kind_; | |
|
regis
2013/02/26 23:39:49
ditto
| |
| 267 | |
| 245 friend class Assembler; | 268 friend class Assembler; |
| 246 }; | 269 }; |
| 247 | 270 |
| 248 | 271 |
| 249 class FieldAddress : public Address { | 272 class FieldAddress : public Address { |
| 250 public: | 273 public: |
| 251 FieldAddress(Register base, int32_t disp) | 274 FieldAddress(Register base, int32_t disp) |
| 252 : Address(base, disp - kHeapObjectTag) { } | 275 : Address(base, disp - kHeapObjectTag) { } |
| 253 | 276 |
| 254 FieldAddress(const FieldAddress& other) : Address(other) { } | 277 FieldAddress(const FieldAddress& other) : Address(other) { } |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 return *reg1 - *reg2; | 661 return *reg1 - *reg2; |
| 639 } | 662 } |
| 640 | 663 |
| 641 DISALLOW_ALLOCATION(); | 664 DISALLOW_ALLOCATION(); |
| 642 DISALLOW_COPY_AND_ASSIGN(Assembler); | 665 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 643 }; | 666 }; |
| 644 | 667 |
| 645 } // namespace dart | 668 } // namespace dart |
| 646 | 669 |
| 647 #endif // VM_ASSEMBLER_ARM_H_ | 670 #endif // VM_ASSEMBLER_ARM_H_ |
| OLD | NEW |