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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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
« no previous file with comments | « runtime/vm/assembler.cc ('k') | runtime/vm/assembler_arm.cc » ('j') | no next file with comments »
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 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 26
27 // Instruction encoding bits. 27 // Instruction encoding bits.
28 enum { 28 enum {
29 H = 1 << 5, // halfword (or byte) 29 H = 1 << 5, // halfword (or byte)
30 L = 1 << 20, // load (or store) 30 L = 1 << 20, // load (or store)
31 S = 1 << 20, // set condition code (or leave unchanged) 31 S = 1 << 20, // set condition code (or leave unchanged)
32 W = 1 << 21, // writeback base register (or leave unchanged) 32 W = 1 << 21, // writeback base register (or leave unchanged)
33 A = 1 << 21, // accumulate in multiply instruction (or not) 33 A = 1 << 21, // accumulate in multiply instruction (or not)
34 B = 1 << 22, // unsigned byte (or word) 34 B = 1 << 22, // unsigned byte (or word)
35 D = 1 << 22, // high/lo bit of start of s/d register range 35 D = 1 << 22, // high/lo bit of start of s/d register range
36 N = 1 << 22, // long (or short) 36 N = 1 << 22, // long (or short)
37 U = 1 << 23, // positive (or negative) offset/index 37 U = 1 << 23, // positive (or negative) offset/index
38 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) 38 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing)
39 I = 1 << 25, // immediate shifter operand (or not) 39 I = 1 << 25, // immediate shifter operand (or not)
40 40
41 B0 = 1, 41 B0 = 1,
42 B1 = 1 << 1, 42 B1 = 1 << 1,
43 B2 = 1 << 2, 43 B2 = 1 << 2,
44 B3 = 1 << 3, 44 B3 = 1 << 3,
45 B4 = 1 << 4, 45 B4 = 1 << 4,
46 B5 = 1 << 5, 46 B5 = 1 << 5,
47 B6 = 1 << 6, 47 B6 = 1 << 6,
48 B7 = 1 << 7, 48 B7 = 1 << 7,
49 B8 = 1 << 8, 49 B8 = 1 << 8,
(...skipping 11 matching lines...) Expand all
61 B23 = 1 << 23, 61 B23 = 1 << 23,
62 B24 = 1 << 24, 62 B24 = 1 << 24,
63 B25 = 1 << 25, 63 B25 = 1 << 25,
64 B26 = 1 << 26, 64 B26 = 1 << 26,
65 B27 = 1 << 27, 65 B27 = 1 << 27,
66 }; 66 };
67 67
68 68
69 class Label : public ValueObject { 69 class Label : public ValueObject {
70 public: 70 public:
71 Label() : position_(0) { } 71 Label() : position_(0) {}
72 72
73 ~Label() { 73 ~Label() {
74 // Assert if label is being destroyed with unresolved branches pending. 74 // Assert if label is being destroyed with unresolved branches pending.
75 ASSERT(!IsLinked()); 75 ASSERT(!IsLinked());
76 } 76 }
77 77
78 // Returns the position for bound and linked labels. Cannot be used 78 // Returns the position for bound and linked labels. Cannot be used
79 // for unused labels. 79 // for unused labels.
80 intptr_t Position() const { 80 intptr_t Position() const {
81 ASSERT(!IsUnused()); 81 ASSERT(!IsUnused());
82 return IsBound() ? -position_ - kWordSize : position_ - kWordSize; 82 return IsBound() ? -position_ - kWordSize : position_ - kWordSize;
83 } 83 }
84 84
85 bool IsBound() const { return position_ < 0; } 85 bool IsBound() const { return position_ < 0; }
86 bool IsUnused() const { return position_ == 0; } 86 bool IsUnused() const { return position_ == 0; }
87 bool IsLinked() const { return position_ > 0; } 87 bool IsLinked() const { return position_ > 0; }
88 88
89 private: 89 private:
90 intptr_t position_; 90 intptr_t position_;
91 91
92 void Reinitialize() { 92 void Reinitialize() { position_ = 0; }
93 position_ = 0;
94 }
95 93
96 void BindTo(intptr_t position) { 94 void BindTo(intptr_t position) {
97 ASSERT(!IsBound()); 95 ASSERT(!IsBound());
98 position_ = -position - kWordSize; 96 position_ = -position - kWordSize;
99 ASSERT(IsBound()); 97 ASSERT(IsBound());
100 } 98 }
101 99
102 void LinkTo(intptr_t position) { 100 void LinkTo(intptr_t position) {
103 ASSERT(!IsBound()); 101 ASSERT(!IsBound());
104 position_ = position + kWordSize; 102 position_ = position + kWordSize;
105 ASSERT(IsLinked()); 103 ASSERT(IsLinked());
106 } 104 }
107 105
108 friend class Assembler; 106 friend class Assembler;
109 DISALLOW_COPY_AND_ASSIGN(Label); 107 DISALLOW_COPY_AND_ASSIGN(Label);
110 }; 108 };
111 109
112 110
113 // Encodes Addressing Mode 1 - Data-processing operands. 111 // Encodes Addressing Mode 1 - Data-processing operands.
114 class Operand : public ValueObject { 112 class Operand : public ValueObject {
115 public: 113 public:
116 // Data-processing operands - Uninitialized. 114 // Data-processing operands - Uninitialized.
117 Operand() : type_(-1), encoding_(-1) { } 115 Operand() : type_(-1), encoding_(-1) {}
118 116
119 // Data-processing operands - Copy constructor. 117 // Data-processing operands - Copy constructor.
120 Operand(const Operand& other) 118 Operand(const Operand& other)
121 : ValueObject(), type_(other.type_), encoding_(other.encoding_) { } 119 : ValueObject(), type_(other.type_), encoding_(other.encoding_) {}
122 120
123 // Data-processing operands - Assignment operator. 121 // Data-processing operands - Assignment operator.
124 Operand& operator=(const Operand& other) { 122 Operand& operator=(const Operand& other) {
125 type_ = other.type_; 123 type_ = other.type_;
126 encoding_ = other.encoding_; 124 encoding_ = other.encoding_;
127 return *this; 125 return *this;
128 } 126 }
129 127
130 // Data-processing operands - Immediate. 128 // Data-processing operands - Immediate.
131 explicit Operand(uint32_t immediate) { 129 explicit Operand(uint32_t immediate) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 164
167 static bool CanHold(uint32_t immediate, Operand* o) { 165 static bool CanHold(uint32_t immediate, Operand* o) {
168 // Avoid the more expensive test for frequent small immediate values. 166 // Avoid the more expensive test for frequent small immediate values.
169 if (immediate < (1 << kImmed8Bits)) { 167 if (immediate < (1 << kImmed8Bits)) {
170 o->type_ = 1; 168 o->type_ = 1;
171 o->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift); 169 o->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift);
172 return true; 170 return true;
173 } 171 }
174 // Note that immediate must be unsigned for the test to work correctly. 172 // Note that immediate must be unsigned for the test to work correctly.
175 for (int rot = 0; rot < 16; rot++) { 173 for (int rot = 0; rot < 16; rot++) {
176 uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot)); 174 uint32_t imm8 = (immediate << 2 * rot) | (immediate >> (32 - 2 * rot));
177 if (imm8 < (1 << kImmed8Bits)) { 175 if (imm8 < (1 << kImmed8Bits)) {
178 o->type_ = 1; 176 o->type_ = 1;
179 o->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift); 177 o->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift);
180 return true; 178 return true;
181 } 179 }
182 } 180 }
183 return false; 181 return false;
184 } 182 }
185 183
186 private: 184 private:
(...skipping 27 matching lines...) Expand all
214 kWordPair, 212 kWordPair,
215 kSWord, 213 kSWord,
216 kDWord, 214 kDWord,
217 kRegList, 215 kRegList,
218 }; 216 };
219 217
220 218
221 // Load/store multiple addressing mode. 219 // Load/store multiple addressing mode.
222 enum BlockAddressMode { 220 enum BlockAddressMode {
223 // bit encoding P U W 221 // bit encoding P U W
224 DA = (0|0|0) << 21, // decrement after 222 DA = (0 | 0 | 0) << 21, // decrement after
225 IA = (0|4|0) << 21, // increment after 223 IA = (0 | 4 | 0) << 21, // increment after
226 DB = (8|0|0) << 21, // decrement before 224 DB = (8 | 0 | 0) << 21, // decrement before
227 IB = (8|4|0) << 21, // increment before 225 IB = (8 | 4 | 0) << 21, // increment before
228 DA_W = (0|0|1) << 21, // decrement after with writeback to base 226 DA_W = (0 | 0 | 1) << 21, // decrement after with writeback to base
229 IA_W = (0|4|1) << 21, // increment after with writeback to base 227 IA_W = (0 | 4 | 1) << 21, // increment after with writeback to base
230 DB_W = (8|0|1) << 21, // decrement before with writeback to base 228 DB_W = (8 | 0 | 1) << 21, // decrement before with writeback to base
231 IB_W = (8|4|1) << 21 // increment before with writeback to base 229 IB_W = (8 | 4 | 1) << 21 // increment before with writeback to base
232 }; 230 };
233 231
234 232
235 class Address : public ValueObject { 233 class Address : public ValueObject {
236 public: 234 public:
237 enum OffsetKind { 235 enum OffsetKind {
238 Immediate, 236 Immediate,
239 IndexRegister, 237 IndexRegister,
240 ScaledIndexRegister, 238 ScaledIndexRegister,
241 }; 239 };
242 240
243 // Memory operand addressing mode 241 // Memory operand addressing mode
244 enum Mode { 242 enum Mode {
245 kModeMask = (8|4|1) << 21, 243 kModeMask = (8 | 4 | 1) << 21,
246 // bit encoding P U W 244 // bit encoding P U W
247 Offset = (8|4|0) << 21, // offset (w/o writeback to base) 245 Offset = (8 | 4 | 0) << 21, // offset (w/o writeback to base)
248 PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback 246 PreIndex = (8 | 4 | 1) << 21, // pre-indexed addressing with writeback
249 PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback 247 PostIndex = (0 | 4 | 0) << 21, // post-indexed addressing with writeback
250 NegOffset = (8|0|0) << 21, // negative offset (w/o writeback to base) 248 NegOffset = (8 | 0 | 0) << 21, // negative offset (w/o writeback to base)
251 NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback 249 NegPreIndex = (8 | 0 | 1) << 21, // negative pre-indexed with writeback
252 NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback 250 NegPostIndex = (0 | 0 | 0) << 21 // negative post-indexed with writeback
253 }; 251 };
254 252
255 Address(const Address& other) 253 Address(const Address& other)
256 : ValueObject(), encoding_(other.encoding_), kind_(other.kind_) { 254 : ValueObject(), encoding_(other.encoding_), kind_(other.kind_) {}
257 }
258 255
259 Address& operator=(const Address& other) { 256 Address& operator=(const Address& other) {
260 encoding_ = other.encoding_; 257 encoding_ = other.encoding_;
261 kind_ = other.kind_; 258 kind_ = other.kind_;
262 return *this; 259 return *this;
263 } 260 }
264 261
265 bool Equals(const Address& other) const { 262 bool Equals(const Address& other) const {
266 return (encoding_ == other.encoding_) && (kind_ == other.kind_); 263 return (encoding_ == other.encoding_) && (kind_ == other.kind_);
267 } 264 }
268 265
269 explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) { 266 explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) {
270 ASSERT(Utils::IsAbsoluteUint(12, offset)); 267 ASSERT(Utils::IsAbsoluteUint(12, offset));
271 kind_ = Immediate; 268 kind_ = Immediate;
272 if (offset < 0) { 269 if (offset < 0) {
273 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign. 270 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign.
274 } else { 271 } else {
275 encoding_ = am | offset; 272 encoding_ = am | offset;
276 } 273 }
277 encoding_ |= static_cast<uint32_t>(rn) << kRnShift; 274 encoding_ |= static_cast<uint32_t>(rn) << kRnShift;
278 } 275 }
279 276
280 // There is no register offset mode unless Mode is Offset, in which case the 277 // There is no register offset mode unless Mode is Offset, in which case the
281 // shifted register case below should be used. 278 // shifted register case below should be used.
282 Address(Register rn, Register r, Mode am); 279 Address(Register rn, Register r, Mode am);
283 280
284 Address(Register rn, Register rm, 281 Address(Register rn,
285 Shift shift = LSL, uint32_t shift_imm = 0, Mode am = Offset) { 282 Register rm,
283 Shift shift = LSL,
284 uint32_t shift_imm = 0,
285 Mode am = Offset) {
286 Operand o(rm, shift, shift_imm); 286 Operand o(rm, shift, shift_imm);
287 287
288 if ((shift == LSL) && (shift_imm == 0)) { 288 if ((shift == LSL) && (shift_imm == 0)) {
289 kind_ = IndexRegister; 289 kind_ = IndexRegister;
290 } else { 290 } else {
291 kind_ = ScaledIndexRegister; 291 kind_ = ScaledIndexRegister;
292 } 292 }
293 encoding_ = o.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift); 293 encoding_ = o.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift);
294 } 294 }
295 295
(...skipping 11 matching lines...) Expand all
307 static bool CanHoldImmediateOffset(bool is_load, 307 static bool CanHoldImmediateOffset(bool is_load,
308 intptr_t cid, 308 intptr_t cid,
309 int64_t offset); 309 int64_t offset);
310 310
311 private: 311 private:
312 Register rn() const { 312 Register rn() const {
313 return Instr::At(reinterpret_cast<uword>(&encoding_))->RnField(); 313 return Instr::At(reinterpret_cast<uword>(&encoding_))->RnField();
314 } 314 }
315 315
316 Register rm() const { 316 Register rm() const {
317 return ((kind() == IndexRegister) || (kind() == ScaledIndexRegister)) ? 317 return ((kind() == IndexRegister) || (kind() == ScaledIndexRegister))
318 Instr::At(reinterpret_cast<uword>(&encoding_))->RmField() : 318 ? Instr::At(reinterpret_cast<uword>(&encoding_))->RmField()
319 kNoRegister; 319 : kNoRegister;
320 } 320 }
321 321
322 Mode mode() const { return static_cast<Mode>(encoding() & kModeMask); } 322 Mode mode() const { return static_cast<Mode>(encoding() & kModeMask); }
323 323
324 bool has_writeback() const { 324 bool has_writeback() const {
325 return (mode() == PreIndex) || (mode() == PostIndex) || 325 return (mode() == PreIndex) || (mode() == PostIndex) ||
326 (mode() == NegPreIndex) || (mode() == NegPostIndex); 326 (mode() == NegPreIndex) || (mode() == NegPostIndex);
327 } 327 }
328 328
329 uint32_t encoding() const { return encoding_; } 329 uint32_t encoding() const { return encoding_; }
(...skipping 10 matching lines...) Expand all
340 340
341 OffsetKind kind_; 341 OffsetKind kind_;
342 342
343 friend class Assembler; 343 friend class Assembler;
344 }; 344 };
345 345
346 346
347 class FieldAddress : public Address { 347 class FieldAddress : public Address {
348 public: 348 public:
349 FieldAddress(Register base, int32_t disp) 349 FieldAddress(Register base, int32_t disp)
350 : Address(base, disp - kHeapObjectTag) { } 350 : Address(base, disp - kHeapObjectTag) {}
351 351
352 // This addressing mode does not exist. 352 // This addressing mode does not exist.
353 FieldAddress(Register base, Register r); 353 FieldAddress(Register base, Register r);
354 354
355 FieldAddress(const FieldAddress& other) : Address(other) { } 355 FieldAddress(const FieldAddress& other) : Address(other) {}
356 356
357 FieldAddress& operator=(const FieldAddress& other) { 357 FieldAddress& operator=(const FieldAddress& other) {
358 Address::operator=(other); 358 Address::operator=(other);
359 return *this; 359 return *this;
360 } 360 }
361 }; 361 };
362 362
363 363
364 class Assembler : public ValueObject { 364 class Assembler : public ValueObject {
365 public: 365 public:
366 explicit Assembler(bool use_far_branches = false) 366 explicit Assembler(bool use_far_branches = false)
367 : buffer_(), 367 : buffer_(),
368 prologue_offset_(-1), 368 prologue_offset_(-1),
369 has_single_entry_point_(true), 369 has_single_entry_point_(true),
370 use_far_branches_(use_far_branches), 370 use_far_branches_(use_far_branches),
371 comments_(), 371 comments_(),
372 constant_pool_allowed_(false) { 372 constant_pool_allowed_(false) {}
373 }
374 373
375 ~Assembler() { } 374 ~Assembler() {}
376 375
377 void PopRegister(Register r) { Pop(r); } 376 void PopRegister(Register r) { Pop(r); }
378 377
379 void Bind(Label* label); 378 void Bind(Label* label);
380 void Jump(Label* label) { b(label); } 379 void Jump(Label* label) { b(label); }
381 380
382 // Misc. functionality 381 // Misc. functionality
383 intptr_t CodeSize() const { return buffer_.Size(); } 382 intptr_t CodeSize() const { return buffer_.Size(); }
384 intptr_t prologue_offset() const { return prologue_offset_; } 383 intptr_t prologue_offset() const { return prologue_offset_; }
385 bool has_single_entry_point() const { return has_single_entry_point_; } 384 bool has_single_entry_point() const { return has_single_entry_point_; }
(...skipping 13 matching lines...) Expand all
399 return object_pool_wrapper_.MakeObjectPool(); 398 return object_pool_wrapper_.MakeObjectPool();
400 } 399 }
401 400
402 bool use_far_branches() const { 401 bool use_far_branches() const {
403 return FLAG_use_far_branches || use_far_branches_; 402 return FLAG_use_far_branches || use_far_branches_;
404 } 403 }
405 404
406 #if defined(TESTING) || defined(DEBUG) 405 #if defined(TESTING) || defined(DEBUG)
407 // Used in unit tests and to ensure predictable verification code size in 406 // Used in unit tests and to ensure predictable verification code size in
408 // FlowGraphCompiler::EmitEdgeCounter. 407 // FlowGraphCompiler::EmitEdgeCounter.
409 void set_use_far_branches(bool b) { 408 void set_use_far_branches(bool b) { use_far_branches_ = b; }
410 use_far_branches_ = b;
411 }
412 #endif // TESTING || DEBUG 409 #endif // TESTING || DEBUG
413 410
414 void FinalizeInstructions(const MemoryRegion& region) { 411 void FinalizeInstructions(const MemoryRegion& region) {
415 buffer_.FinalizeInstructions(region); 412 buffer_.FinalizeInstructions(region);
416 } 413 }
417 414
418 // Debugging and bringup support. 415 // Debugging and bringup support.
419 void Stop(const char* message); 416 void Stop(const char* message);
420 void Unimplemented(const char* message); 417 void Unimplemented(const char* message);
421 void Untested(const char* message); 418 void Untested(const char* message);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 473
477 void mvn(Register rd, Operand o, Condition cond = AL); 474 void mvn(Register rd, Operand o, Condition cond = AL);
478 void mvns(Register rd, Operand o, Condition cond = AL); 475 void mvns(Register rd, Operand o, Condition cond = AL);
479 476
480 // Miscellaneous data-processing instructions. 477 // Miscellaneous data-processing instructions.
481 void clz(Register rd, Register rm, Condition cond = AL); 478 void clz(Register rd, Register rm, Condition cond = AL);
482 479
483 // Multiply instructions. 480 // Multiply instructions.
484 void mul(Register rd, Register rn, Register rm, Condition cond = AL); 481 void mul(Register rd, Register rn, Register rm, Condition cond = AL);
485 void muls(Register rd, Register rn, Register rm, Condition cond = AL); 482 void muls(Register rd, Register rn, Register rm, Condition cond = AL);
486 void mla(Register rd, Register rn, Register rm, Register ra, 483 void mla(Register rd,
484 Register rn,
485 Register rm,
486 Register ra,
487 Condition cond = AL); 487 Condition cond = AL);
488 void mls(Register rd, Register rn, Register rm, Register ra, 488 void mls(Register rd,
489 Register rn,
490 Register rm,
491 Register ra,
489 Condition cond = AL); 492 Condition cond = AL);
490 void smull(Register rd_lo, Register rd_hi, Register rn, Register rm, 493 void smull(Register rd_lo,
494 Register rd_hi,
495 Register rn,
496 Register rm,
491 Condition cond = AL); 497 Condition cond = AL);
492 void umull(Register rd_lo, Register rd_hi, Register rn, Register rm, 498 void umull(Register rd_lo,
499 Register rd_hi,
500 Register rn,
501 Register rm,
493 Condition cond = AL); 502 Condition cond = AL);
494 void smlal(Register rd_lo, Register rd_hi, Register rn, Register rm, 503 void smlal(Register rd_lo,
504 Register rd_hi,
505 Register rn,
506 Register rm,
495 Condition cond = AL); 507 Condition cond = AL);
496 void umlal(Register rd_lo, Register rd_hi, Register rn, Register rm, 508 void umlal(Register rd_lo,
509 Register rd_hi,
510 Register rn,
511 Register rm,
497 Condition cond = AL); 512 Condition cond = AL);
498 513
499 // Emulation of this instruction uses IP and the condition codes. Therefore, 514 // Emulation of this instruction uses IP and the condition codes. Therefore,
500 // none of the registers can be IP, and the instruction can only be used 515 // none of the registers can be IP, and the instruction can only be used
501 // unconditionally. 516 // unconditionally.
502 void umaal(Register rd_lo, Register rd_hi, Register rn, Register rm); 517 void umaal(Register rd_lo, Register rd_hi, Register rn, Register rm);
503 518
504 // Division instructions. 519 // Division instructions.
505 void sdiv(Register rd, Register rn, Register rm, Condition cond = AL); 520 void sdiv(Register rd, Register rn, Register rm, Condition cond = AL);
506 void udiv(Register rd, Register rn, Register rm, Condition cond = AL); 521 void udiv(Register rd, Register rn, Register rm, Condition cond = AL);
507 522
508 // Load/store instructions. 523 // Load/store instructions.
509 void ldr(Register rd, Address ad, Condition cond = AL); 524 void ldr(Register rd, Address ad, Condition cond = AL);
510 void str(Register rd, Address ad, Condition cond = AL); 525 void str(Register rd, Address ad, Condition cond = AL);
511 526
512 void ldrb(Register rd, Address ad, Condition cond = AL); 527 void ldrb(Register rd, Address ad, Condition cond = AL);
513 void strb(Register rd, Address ad, Condition cond = AL); 528 void strb(Register rd, Address ad, Condition cond = AL);
514 529
515 void ldrh(Register rd, Address ad, Condition cond = AL); 530 void ldrh(Register rd, Address ad, Condition cond = AL);
516 void strh(Register rd, Address ad, Condition cond = AL); 531 void strh(Register rd, Address ad, Condition cond = AL);
517 532
518 void ldrsb(Register rd, Address ad, Condition cond = AL); 533 void ldrsb(Register rd, Address ad, Condition cond = AL);
519 void ldrsh(Register rd, Address ad, Condition cond = AL); 534 void ldrsh(Register rd, Address ad, Condition cond = AL);
520 535
521 // ldrd and strd actually support the full range of addressing modes, but 536 // ldrd and strd actually support the full range of addressing modes, but
522 // we don't use them, and we need to split them up into two instructions for 537 // we don't use them, and we need to split them up into two instructions for
523 // ARMv5TE, so we only support the base + offset mode. 538 // ARMv5TE, so we only support the base + offset mode.
524 // rd must be an even register and rd2 must be rd + 1. 539 // rd must be an even register and rd2 must be rd + 1.
525 void ldrd(Register rd, Register rd2, Register rn, int32_t offset, 540 void ldrd(Register rd,
541 Register rd2,
542 Register rn,
543 int32_t offset,
526 Condition cond = AL); 544 Condition cond = AL);
527 void strd(Register rd, Register rd2, Register rn, int32_t offset, 545 void strd(Register rd,
546 Register rd2,
547 Register rn,
548 int32_t offset,
528 Condition cond = AL); 549 Condition cond = AL);
529 550
530 void ldm(BlockAddressMode am, Register base, 551 void ldm(BlockAddressMode am,
531 RegList regs, Condition cond = AL); 552 Register base,
532 void stm(BlockAddressMode am, Register base, 553 RegList regs,
533 RegList regs, Condition cond = AL); 554 Condition cond = AL);
555 void stm(BlockAddressMode am,
556 Register base,
557 RegList regs,
558 Condition cond = AL);
534 559
535 void ldrex(Register rd, Register rn, Condition cond = AL); 560 void ldrex(Register rd, Register rn, Condition cond = AL);
536 void strex(Register rd, Register rt, Register rn, Condition cond = AL); 561 void strex(Register rd, Register rt, Register rn, Condition cond = AL);
537 562
538 // Miscellaneous instructions. 563 // Miscellaneous instructions.
539 void clrex(); 564 void clrex();
540 void nop(Condition cond = AL); 565 void nop(Condition cond = AL);
541 566
542 // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0. 567 // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
543 void bkpt(uint16_t imm16); 568 void bkpt(uint16_t imm16);
544 569
545 static int32_t BkptEncoding(uint16_t imm16) { 570 static int32_t BkptEncoding(uint16_t imm16) {
546 // bkpt requires that the cond field is AL. 571 // bkpt requires that the cond field is AL.
547 return (AL << kConditionShift) | B24 | B21 | 572 return (AL << kConditionShift) | B24 | B21 | ((imm16 >> 4) << 8) | B6 | B5 |
548 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 573 B4 | (imm16 & 0xf);
549 } 574 }
550 575
551 static uword GetBreakInstructionFiller() { 576 static uword GetBreakInstructionFiller() { return BkptEncoding(0); }
552 return BkptEncoding(0);
553 }
554 577
555 // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles). 578 // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
556 void vmovsr(SRegister sn, Register rt, Condition cond = AL); 579 void vmovsr(SRegister sn, Register rt, Condition cond = AL);
557 void vmovrs(Register rt, SRegister sn, Condition cond = AL); 580 void vmovrs(Register rt, SRegister sn, Condition cond = AL);
558 void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL); 581 void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL);
559 void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL); 582 void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL);
560 void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL); 583 void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL);
561 void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL); 584 void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL);
562 void vmovdr(DRegister dd, int i, Register rt, Condition cond = AL); 585 void vmovdr(DRegister dd, int i, Register rt, Condition cond = AL);
563 void vmovs(SRegister sd, SRegister sm, Condition cond = AL); 586 void vmovs(SRegister sd, SRegister sm, Condition cond = AL);
564 void vmovd(DRegister dd, DRegister dm, Condition cond = AL); 587 void vmovd(DRegister dd, DRegister dm, Condition cond = AL);
565 void vmovq(QRegister qd, QRegister qm); 588 void vmovq(QRegister qd, QRegister qm);
566 589
567 // Returns false if the immediate cannot be encoded. 590 // Returns false if the immediate cannot be encoded.
568 bool vmovs(SRegister sd, float s_imm, Condition cond = AL); 591 bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
569 bool vmovd(DRegister dd, double d_imm, Condition cond = AL); 592 bool vmovd(DRegister dd, double d_imm, Condition cond = AL);
570 593
571 void vldrs(SRegister sd, Address ad, Condition cond = AL); 594 void vldrs(SRegister sd, Address ad, Condition cond = AL);
572 void vstrs(SRegister sd, Address ad, Condition cond = AL); 595 void vstrs(SRegister sd, Address ad, Condition cond = AL);
573 void vldrd(DRegister dd, Address ad, Condition cond = AL); 596 void vldrd(DRegister dd, Address ad, Condition cond = AL);
574 void vstrd(DRegister dd, Address ad, Condition cond = AL); 597 void vstrd(DRegister dd, Address ad, Condition cond = AL);
575 598
576 void vldms(BlockAddressMode am, Register base, 599 void vldms(BlockAddressMode am,
577 SRegister first, SRegister last, Condition cond = AL); 600 Register base,
578 void vstms(BlockAddressMode am, Register base, 601 SRegister first,
579 SRegister first, SRegister last, Condition cond = AL); 602 SRegister last,
603 Condition cond = AL);
604 void vstms(BlockAddressMode am,
605 Register base,
606 SRegister first,
607 SRegister last,
608 Condition cond = AL);
580 609
581 void vldmd(BlockAddressMode am, Register base, 610 void vldmd(BlockAddressMode am,
582 DRegister first, intptr_t count, Condition cond = AL); 611 Register base,
583 void vstmd(BlockAddressMode am, Register base, 612 DRegister first,
584 DRegister first, intptr_t count, Condition cond = AL); 613 intptr_t count,
614 Condition cond = AL);
615 void vstmd(BlockAddressMode am,
616 Register base,
617 DRegister first,
618 intptr_t count,
619 Condition cond = AL);
585 620
586 void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL); 621 void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
587 void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL); 622 void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
588 void vaddqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm); 623 void vaddqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
589 void vaddqs(QRegister qd, QRegister qn, QRegister qm); 624 void vaddqs(QRegister qd, QRegister qn, QRegister qm);
590 void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL); 625 void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
591 void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL); 626 void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
592 void vsubqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm); 627 void vsubqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
593 void vsubqs(QRegister qd, QRegister qn, QRegister qm); 628 void vsubqs(QRegister qd, QRegister qn, QRegister qm);
594 void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL); 629 void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 // Emit a call that shares its object pool entries with other calls 722 // Emit a call that shares its object pool entries with other calls
688 // that have the same equivalence marker. 723 // that have the same equivalence marker.
689 void BranchLinkWithEquivalence(const StubEntry& stub_entry, 724 void BranchLinkWithEquivalence(const StubEntry& stub_entry,
690 const Object& equivalence); 725 const Object& equivalence);
691 726
692 // Branch and link to [base + offset]. Call sequence is never patched. 727 // Branch and link to [base + offset]. Call sequence is never patched.
693 void BranchLinkOffset(Register base, int32_t offset); 728 void BranchLinkOffset(Register base, int32_t offset);
694 729
695 // Add signed immediate value to rd. May clobber IP. 730 // Add signed immediate value to rd. May clobber IP.
696 void AddImmediate(Register rd, int32_t value, Condition cond = AL); 731 void AddImmediate(Register rd, int32_t value, Condition cond = AL);
697 void AddImmediate(Register rd, Register rn, int32_t value, 732 void AddImmediate(Register rd,
733 Register rn,
734 int32_t value,
698 Condition cond = AL); 735 Condition cond = AL);
699 void AddImmediateSetFlags(Register rd, Register rn, int32_t value, 736 void AddImmediateSetFlags(Register rd,
737 Register rn,
738 int32_t value,
700 Condition cond = AL); 739 Condition cond = AL);
701 void SubImmediateSetFlags(Register rd, Register rn, int32_t value, 740 void SubImmediateSetFlags(Register rd,
741 Register rn,
742 int32_t value,
702 Condition cond = AL); 743 Condition cond = AL);
703 void AndImmediate(Register rd, Register rs, int32_t imm, Condition cond = AL); 744 void AndImmediate(Register rd, Register rs, int32_t imm, Condition cond = AL);
704 745
705 // Test rn and immediate. May clobber IP. 746 // Test rn and immediate. May clobber IP.
706 void TestImmediate(Register rn, int32_t imm, Condition cond = AL); 747 void TestImmediate(Register rn, int32_t imm, Condition cond = AL);
707 748
708 // Compare rn with signed immediate value. May clobber IP. 749 // Compare rn with signed immediate value. May clobber IP.
709 void CompareImmediate(Register rn, int32_t value, Condition cond = AL); 750 void CompareImmediate(Register rn, int32_t value, Condition cond = AL);
710 751
711 752
712 // Signed integer division of left by right. Checks to see if integer 753 // Signed integer division of left by right. Checks to see if integer
713 // division is supported. If not, uses the FPU for division with 754 // division is supported. If not, uses the FPU for division with
714 // temporary registers tmpl and tmpr. tmpl and tmpr must be different 755 // temporary registers tmpl and tmpr. tmpl and tmpr must be different
715 // registers. 756 // registers.
716 void IntegerDivide(Register result, Register left, Register right, 757 void IntegerDivide(Register result,
717 DRegister tmpl, DRegister tmpr); 758 Register left,
759 Register right,
760 DRegister tmpl,
761 DRegister tmpr);
718 762
719 // Load and Store. 763 // Load and Store.
720 // These three do not clobber IP. 764 // These three do not clobber IP.
721 void LoadPatchableImmediate(Register rd, int32_t value, Condition cond = AL); 765 void LoadPatchableImmediate(Register rd, int32_t value, Condition cond = AL);
722 void LoadDecodableImmediate(Register rd, int32_t value, Condition cond = AL); 766 void LoadDecodableImmediate(Register rd, int32_t value, Condition cond = AL);
723 void LoadImmediate(Register rd, int32_t value, Condition cond = AL); 767 void LoadImmediate(Register rd, int32_t value, Condition cond = AL);
724 // These two may clobber IP. 768 // These two may clobber IP.
725 void LoadSImmediate(SRegister sd, float value, Condition cond = AL); 769 void LoadSImmediate(SRegister sd, float value, Condition cond = AL);
726 void LoadDImmediate(DRegister dd, double value, 770 void LoadDImmediate(DRegister dd,
727 Register scratch, Condition cond = AL); 771 double value,
772 Register scratch,
773 Condition cond = AL);
728 774
729 void MarkExceptionHandler(Label* label); 775 void MarkExceptionHandler(Label* label);
730 776
731 void Drop(intptr_t stack_elements); 777 void Drop(intptr_t stack_elements);
732 778
733 void RestoreCodePointer(); 779 void RestoreCodePointer();
734 void LoadPoolPointer(Register reg = PP); 780 void LoadPoolPointer(Register reg = PP);
735 781
736 void LoadIsolate(Register rd); 782 void LoadIsolate(Register rd);
737 783
738 void LoadObject(Register rd, const Object& object, Condition cond = AL); 784 void LoadObject(Register rd, const Object& object, Condition cond = AL);
739 void LoadUniqueObject(Register rd, const Object& object, Condition cond = AL); 785 void LoadUniqueObject(Register rd, const Object& object, Condition cond = AL);
740 void LoadFunctionFromCalleePool(Register dst, 786 void LoadFunctionFromCalleePool(Register dst,
741 const Function& function, 787 const Function& function,
742 Register new_pp); 788 Register new_pp);
743 void LoadNativeEntry(Register dst, 789 void LoadNativeEntry(Register dst,
744 const ExternalLabel* label, 790 const ExternalLabel* label,
745 Patchability patchable, 791 Patchability patchable,
746 Condition cond = AL); 792 Condition cond = AL);
747 void PushObject(const Object& object); 793 void PushObject(const Object& object);
748 void CompareObject(Register rn, const Object& object); 794 void CompareObject(Register rn, const Object& object);
749 795
750 void StoreIntoObject(Register object, // Object we are storing into. 796 void StoreIntoObject(Register object, // Object we are storing into.
751 const Address& dest, // Where we are storing into. 797 const Address& dest, // Where we are storing into.
752 Register value, // Value we are storing. 798 Register value, // Value we are storing.
753 bool can_value_be_smi = true); 799 bool can_value_be_smi = true);
754 void StoreIntoObjectOffset(Register object, 800 void StoreIntoObjectOffset(Register object,
755 int32_t offset, 801 int32_t offset,
756 Register value, 802 Register value,
757 bool can_value_be_smi = true); 803 bool can_value_be_smi = true);
758 804
759 void StoreIntoObjectNoBarrier(Register object, 805 void StoreIntoObjectNoBarrier(Register object,
760 const Address& dest, 806 const Address& dest,
761 Register value); 807 Register value);
762 void StoreIntoObjectNoBarrier(Register object, 808 void StoreIntoObjectNoBarrier(Register object,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 881
836 void LoadMultipleDFromOffset(DRegister first, 882 void LoadMultipleDFromOffset(DRegister first,
837 intptr_t count, 883 intptr_t count,
838 Register base, 884 Register base,
839 int32_t offset); 885 int32_t offset);
840 void StoreMultipleDToOffset(DRegister first, 886 void StoreMultipleDToOffset(DRegister first,
841 intptr_t count, 887 intptr_t count,
842 Register base, 888 Register base,
843 int32_t offset); 889 int32_t offset);
844 890
845 void CopyDoubleField(Register dst, Register src, 891 void CopyDoubleField(Register dst,
846 Register tmp1, Register tmp2, DRegister dtmp); 892 Register src,
847 void CopyFloat32x4Field(Register dst, Register src, 893 Register tmp1,
848 Register tmp1, Register tmp2, DRegister dtmp); 894 Register tmp2,
849 void CopyFloat64x2Field(Register dst, Register src, 895 DRegister dtmp);
850 Register tmp1, Register tmp2, DRegister dtmp); 896 void CopyFloat32x4Field(Register dst,
897 Register src,
898 Register tmp1,
899 Register tmp2,
900 DRegister dtmp);
901 void CopyFloat64x2Field(Register dst,
902 Register src,
903 Register tmp1,
904 Register tmp2,
905 DRegister dtmp);
851 906
852 void Push(Register rd, Condition cond = AL); 907 void Push(Register rd, Condition cond = AL);
853 void Pop(Register rd, Condition cond = AL); 908 void Pop(Register rd, Condition cond = AL);
854 909
855 void PushList(RegList regs, Condition cond = AL); 910 void PushList(RegList regs, Condition cond = AL);
856 void PopList(RegList regs, Condition cond = AL); 911 void PopList(RegList regs, Condition cond = AL);
857 912
858 void MoveRegister(Register rd, Register rm, Condition cond = AL); 913 void MoveRegister(Register rd, Register rm, Condition cond = AL);
859 914
860 // Convenience shift instructions. Use mov instruction with shifter operand 915 // Convenience shift instructions. Use mov instruction with shifter operand
861 // for variants setting the status flags. 916 // for variants setting the status flags.
862 void Lsl(Register rd, Register rm, const Operand& shift_imm, 917 void Lsl(Register rd,
918 Register rm,
919 const Operand& shift_imm,
863 Condition cond = AL); 920 Condition cond = AL);
864 void Lsl(Register rd, Register rm, Register rs, Condition cond = AL); 921 void Lsl(Register rd, Register rm, Register rs, Condition cond = AL);
865 void Lsr(Register rd, Register rm, const Operand& shift_imm, 922 void Lsr(Register rd,
923 Register rm,
924 const Operand& shift_imm,
866 Condition cond = AL); 925 Condition cond = AL);
867 void Lsr(Register rd, Register rm, Register rs, Condition cond = AL); 926 void Lsr(Register rd, Register rm, Register rs, Condition cond = AL);
868 void Asr(Register rd, Register rm, const Operand& shift_imm, 927 void Asr(Register rd,
928 Register rm,
929 const Operand& shift_imm,
869 Condition cond = AL); 930 Condition cond = AL);
870 void Asr(Register rd, Register rm, Register rs, Condition cond = AL); 931 void Asr(Register rd, Register rm, Register rs, Condition cond = AL);
871 void Asrs(Register rd, Register rm, const Operand& shift_imm, 932 void Asrs(Register rd,
933 Register rm,
934 const Operand& shift_imm,
872 Condition cond = AL); 935 Condition cond = AL);
873 void Ror(Register rd, Register rm, const Operand& shift_imm, 936 void Ror(Register rd,
937 Register rm,
938 const Operand& shift_imm,
874 Condition cond = AL); 939 Condition cond = AL);
875 void Ror(Register rd, Register rm, Register rs, Condition cond = AL); 940 void Ror(Register rd, Register rm, Register rs, Condition cond = AL);
876 void Rrx(Register rd, Register rm, Condition cond = AL); 941 void Rrx(Register rd, Register rm, Condition cond = AL);
877 942
878 // Fill rd with the sign of rm. 943 // Fill rd with the sign of rm.
879 void SignFill(Register rd, Register rm, Condition cond = AL); 944 void SignFill(Register rd, Register rm, Condition cond = AL);
880 945
881 void Vreciprocalqs(QRegister qd, QRegister qm); 946 void Vreciprocalqs(QRegister qd, QRegister qm);
882 void VreciprocalSqrtqs(QRegister qd, QRegister qm); 947 void VreciprocalSqrtqs(QRegister qd, QRegister qm);
883 // If qm must be preserved, then provide a (non-QTMP) temporary. 948 // If qm must be preserved, then provide a (non-QTMP) temporary.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 void EnterStubFrame(); 1012 void EnterStubFrame();
948 void LeaveStubFrame(); 1013 void LeaveStubFrame();
949 1014
950 void MonomorphicCheckedEntry(); 1015 void MonomorphicCheckedEntry();
951 1016
952 // The register into which the allocation stats table is loaded with 1017 // The register into which the allocation stats table is loaded with
953 // LoadAllocationStatsAddress should be passed to 1018 // LoadAllocationStatsAddress should be passed to
954 // IncrementAllocationStats(WithSize) as stats_addr_reg to update the 1019 // IncrementAllocationStats(WithSize) as stats_addr_reg to update the
955 // allocation stats. These are separate assembler macros so we can 1020 // allocation stats. These are separate assembler macros so we can
956 // avoid a dependent load too nearby the load of the table address. 1021 // avoid a dependent load too nearby the load of the table address.
957 void LoadAllocationStatsAddress(Register dest, 1022 void LoadAllocationStatsAddress(Register dest, intptr_t cid);
958 intptr_t cid);
959 void IncrementAllocationStats(Register stats_addr, 1023 void IncrementAllocationStats(Register stats_addr,
960 intptr_t cid, 1024 intptr_t cid,
961 Heap::Space space); 1025 Heap::Space space);
962 void IncrementAllocationStatsWithSize(Register stats_addr_reg, 1026 void IncrementAllocationStatsWithSize(Register stats_addr_reg,
963 Register size_reg, 1027 Register size_reg,
964 Heap::Space space); 1028 Heap::Space space);
965 1029
966 Address ElementAddressForIntIndex(bool is_load, 1030 Address ElementAddressForIntIndex(bool is_load,
967 bool is_external, 1031 bool is_external,
968 intptr_t cid, 1032 intptr_t cid,
(...skipping 26 matching lines...) Expand all
995 Register index); 1059 Register index);
996 1060
997 void LoadHalfWordUnaligned(Register dst, Register addr, Register tmp); 1061 void LoadHalfWordUnaligned(Register dst, Register addr, Register tmp);
998 void LoadHalfWordUnsignedUnaligned(Register dst, Register addr, Register tmp); 1062 void LoadHalfWordUnsignedUnaligned(Register dst, Register addr, Register tmp);
999 void StoreHalfWordUnaligned(Register src, Register addr, Register tmp); 1063 void StoreHalfWordUnaligned(Register src, Register addr, Register tmp);
1000 void LoadWordUnaligned(Register dst, Register addr, Register tmp); 1064 void LoadWordUnaligned(Register dst, Register addr, Register tmp);
1001 void StoreWordUnaligned(Register src, Register addr, Register tmp); 1065 void StoreWordUnaligned(Register src, Register addr, Register tmp);
1002 1066
1003 // If allocation tracing for |cid| is enabled, will jump to |trace| label, 1067 // If allocation tracing for |cid| is enabled, will jump to |trace| label,
1004 // which will allocate in the runtime where tracing occurs. 1068 // which will allocate in the runtime where tracing occurs.
1005 void MaybeTraceAllocation(intptr_t cid, 1069 void MaybeTraceAllocation(intptr_t cid, Register temp_reg, Label* trace);
1006 Register temp_reg,
1007 Label* trace);
1008 1070
1009 // Inlined allocation of an instance of class 'cls', code has no runtime 1071 // Inlined allocation of an instance of class 'cls', code has no runtime
1010 // calls. Jump to 'failure' if the instance cannot be allocated here. 1072 // calls. Jump to 'failure' if the instance cannot be allocated here.
1011 // Allocated instance is returned in 'instance_reg'. 1073 // Allocated instance is returned in 'instance_reg'.
1012 // Only the tags field of the object is initialized. 1074 // Only the tags field of the object is initialized.
1013 void TryAllocate(const Class& cls, 1075 void TryAllocate(const Class& cls,
1014 Label* failure, 1076 Label* failure,
1015 Register instance_reg, 1077 Register instance_reg,
1016 Register temp_reg); 1078 Register temp_reg);
1017 1079
1018 void TryAllocateArray(intptr_t cid, 1080 void TryAllocateArray(intptr_t cid,
1019 intptr_t instance_size, 1081 intptr_t instance_size,
1020 Label* failure, 1082 Label* failure,
1021 Register instance, 1083 Register instance,
1022 Register end_address, 1084 Register end_address,
1023 Register temp1, 1085 Register temp1,
1024 Register temp2); 1086 Register temp2);
1025 1087
1026 // Emit data (e.g encoded instruction or immediate) in instruction stream. 1088 // Emit data (e.g encoded instruction or immediate) in instruction stream.
1027 void Emit(int32_t value); 1089 void Emit(int32_t value);
1028 1090
1029 // On some other platforms, we draw a distinction between safe and unsafe 1091 // On some other platforms, we draw a distinction between safe and unsafe
1030 // smis. 1092 // smis.
1031 static bool IsSafe(const Object& object) { return true; } 1093 static bool IsSafe(const Object& object) { return true; }
1032 static bool IsSafeSmi(const Object& object) { return object.IsSmi(); } 1094 static bool IsSafeSmi(const Object& object) { return object.IsSmi(); }
1033 1095
1034 bool constant_pool_allowed() const { 1096 bool constant_pool_allowed() const { return constant_pool_allowed_; }
1035 return constant_pool_allowed_; 1097 void set_constant_pool_allowed(bool b) { constant_pool_allowed_ = b; }
1036 }
1037 void set_constant_pool_allowed(bool b) {
1038 constant_pool_allowed_ = b;
1039 }
1040 1098
1041 private: 1099 private:
1042 AssemblerBuffer buffer_; // Contains position independent code. 1100 AssemblerBuffer buffer_; // Contains position independent code.
1043 ObjectPoolWrapper object_pool_wrapper_; 1101 ObjectPoolWrapper object_pool_wrapper_;
1044 int32_t prologue_offset_; 1102 int32_t prologue_offset_;
1045 bool has_single_entry_point_; 1103 bool has_single_entry_point_;
1046 bool use_far_branches_; 1104 bool use_far_branches_;
1047 1105
1048 // If you are thinking of using one or both of these instructions directly, 1106 // If you are thinking of using one or both of these instructions directly,
1049 // instead LoadImmediate should probably be used. 1107 // instead LoadImmediate should probably be used.
1050 void movw(Register rd, uint16_t imm16, Condition cond = AL); 1108 void movw(Register rd, uint16_t imm16, Condition cond = AL);
1051 void movt(Register rd, uint16_t imm16, Condition cond = AL); 1109 void movt(Register rd, uint16_t imm16, Condition cond = AL);
1052 1110
1053 void BindARMv6(Label* label); 1111 void BindARMv6(Label* label);
1054 void BindARMv7(Label* label); 1112 void BindARMv7(Label* label);
1055 1113
1056 void LoadWordFromPoolOffset(Register rd, 1114 void LoadWordFromPoolOffset(Register rd,
1057 int32_t offset, 1115 int32_t offset,
1058 Register pp, 1116 Register pp,
1059 Condition cond); 1117 Condition cond);
1060 1118
1061 void BranchLink(const ExternalLabel* label); 1119 void BranchLink(const ExternalLabel* label);
1062 1120
1063 class CodeComment : public ZoneAllocated { 1121 class CodeComment : public ZoneAllocated {
1064 public: 1122 public:
1065 CodeComment(intptr_t pc_offset, const String& comment) 1123 CodeComment(intptr_t pc_offset, const String& comment)
1066 : pc_offset_(pc_offset), comment_(comment) { } 1124 : pc_offset_(pc_offset), comment_(comment) {}
1067 1125
1068 intptr_t pc_offset() const { return pc_offset_; } 1126 intptr_t pc_offset() const { return pc_offset_; }
1069 const String& comment() const { return comment_; } 1127 const String& comment() const { return comment_; }
1070 1128
1071 private: 1129 private:
1072 intptr_t pc_offset_; 1130 intptr_t pc_offset_;
1073 const String& comment_; 1131 const String& comment_;
1074 1132
1075 DISALLOW_COPY_AND_ASSIGN(CodeComment); 1133 DISALLOW_COPY_AND_ASSIGN(CodeComment);
1076 }; 1134 };
(...skipping 11 matching lines...) Expand all
1088 void EmitType01(Condition cond, 1146 void EmitType01(Condition cond,
1089 int type, 1147 int type,
1090 Opcode opcode, 1148 Opcode opcode,
1091 int set_cc, 1149 int set_cc,
1092 Register rn, 1150 Register rn,
1093 Register rd, 1151 Register rd,
1094 Operand o); 1152 Operand o);
1095 1153
1096 void EmitType5(Condition cond, int32_t offset, bool link); 1154 void EmitType5(Condition cond, int32_t offset, bool link);
1097 1155
1098 void EmitMemOp(Condition cond, 1156 void EmitMemOp(Condition cond, bool load, bool byte, Register rd, Address ad);
1099 bool load,
1100 bool byte,
1101 Register rd,
1102 Address ad);
1103 1157
1104 void EmitMemOpAddressMode3(Condition cond, 1158 void EmitMemOpAddressMode3(Condition cond,
1105 int32_t mode, 1159 int32_t mode,
1106 Register rd, 1160 Register rd,
1107 Address ad); 1161 Address ad);
1108 1162
1109 void EmitMultiMemOp(Condition cond, 1163 void EmitMultiMemOp(Condition cond,
1110 BlockAddressMode am, 1164 BlockAddressMode am,
1111 bool load, 1165 bool load,
1112 Register base, 1166 Register base,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 SRegister sd, 1210 SRegister sd,
1157 SRegister sn, 1211 SRegister sn,
1158 SRegister sm); 1212 SRegister sm);
1159 1213
1160 void EmitVFPddd(Condition cond, 1214 void EmitVFPddd(Condition cond,
1161 int32_t opcode, 1215 int32_t opcode,
1162 DRegister dd, 1216 DRegister dd,
1163 DRegister dn, 1217 DRegister dn,
1164 DRegister dm); 1218 DRegister dm);
1165 1219
1166 void EmitVFPsd(Condition cond, 1220 void EmitVFPsd(Condition cond, int32_t opcode, SRegister sd, DRegister dm);
1167 int32_t opcode,
1168 SRegister sd,
1169 DRegister dm);
1170 1221
1171 void EmitVFPds(Condition cond, 1222 void EmitVFPds(Condition cond, int32_t opcode, DRegister dd, SRegister sm);
1172 int32_t opcode,
1173 DRegister dd,
1174 SRegister sm);
1175 1223
1176 void EmitSIMDqqq(int32_t opcode, OperandSize sz, 1224 void EmitSIMDqqq(int32_t opcode,
1177 QRegister qd, QRegister qn, QRegister qm); 1225 OperandSize sz,
1226 QRegister qd,
1227 QRegister qn,
1228 QRegister qm);
1178 1229
1179 void EmitSIMDddd(int32_t opcode, OperandSize sz, 1230 void EmitSIMDddd(int32_t opcode,
1180 DRegister dd, DRegister dn, DRegister dm); 1231 OperandSize sz,
1232 DRegister dd,
1233 DRegister dn,
1234 DRegister dm);
1181 1235
1182 void EmitFarBranch(Condition cond, int32_t offset, bool link); 1236 void EmitFarBranch(Condition cond, int32_t offset, bool link);
1183 void EmitBranch(Condition cond, Label* label, bool link); 1237 void EmitBranch(Condition cond, Label* label, bool link);
1184 int32_t EncodeBranchOffset(int32_t offset, int32_t inst); 1238 int32_t EncodeBranchOffset(int32_t offset, int32_t inst);
1185 static int32_t DecodeBranchOffset(int32_t inst); 1239 static int32_t DecodeBranchOffset(int32_t inst);
1186 int32_t EncodeTstOffset(int32_t offset, int32_t inst); 1240 int32_t EncodeTstOffset(int32_t offset, int32_t inst);
1187 int32_t DecodeTstOffset(int32_t inst); 1241 int32_t DecodeTstOffset(int32_t inst);
1188 1242
1189 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); 1243 void StoreIntoObjectFilter(Register object, Register value, Label* no_update);
1190 1244
1191 // Shorter filtering sequence that assumes that value is not a smi. 1245 // Shorter filtering sequence that assumes that value is not a smi.
1192 void StoreIntoObjectFilterNoSmi(Register object, 1246 void StoreIntoObjectFilterNoSmi(Register object,
1193 Register value, 1247 Register value,
1194 Label* no_update); 1248 Label* no_update);
1195 1249
1196 DISALLOW_ALLOCATION(); 1250 DISALLOW_ALLOCATION();
1197 DISALLOW_COPY_AND_ASSIGN(Assembler); 1251 DISALLOW_COPY_AND_ASSIGN(Assembler);
1198 }; 1252 };
1199 1253
1200 } // namespace dart 1254 } // namespace dart
1201 1255
1202 #endif // RUNTIME_VM_ASSEMBLER_ARM_H_ 1256 #endif // RUNTIME_VM_ASSEMBLER_ARM_H_
OLDNEW
« no previous file with comments | « runtime/vm/assembler.cc ('k') | runtime/vm/assembler_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698