Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: runtime/vm/assembler_arm.h

Issue 12321149: Implements shifted offset register addressing mode for arm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/assembler_arm.cc » ('j') | runtime/vm/assembler_arm_test.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_arm.cc » ('j') | runtime/vm/assembler_arm_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698