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

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

Issue 593363003: Expands the use of Immediate and Operand wrappers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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 | « runtime/vm/assembler_arm.cc ('k') | runtime/vm/assembler_arm64.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) 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
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_arm64.h" 14 #include "vm/constants_arm64.h"
15 #include "vm/hash_map.h" 15 #include "vm/hash_map.h"
16 #include "vm/longjump.h" 16 #include "vm/longjump.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 24
25 class Immediate : public ValueObject {
26 public:
27 explicit Immediate(int64_t value) : value_(value) { }
28
29 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { }
30 Immediate& operator=(const Immediate& other) {
31 value_ = other.value_;
32 return *this;
33 }
34
35 private:
36 int64_t value_;
37
38 int64_t value() const { return value_; }
39
40 friend class Assembler;
41 };
42
43
25 class Label : public ValueObject { 44 class Label : public ValueObject {
26 public: 45 public:
27 Label() : position_(0) { } 46 Label() : position_(0) { }
28 47
29 ~Label() { 48 ~Label() {
30 // Assert if label is being destroyed with unresolved branches pending. 49 // Assert if label is being destroyed with unresolved branches pending.
31 ASSERT(!IsLinked()); 50 ASSERT(!IsLinked());
32 } 51 }
33 52
34 // Returns the position for bound and linked labels. Cannot be used 53 // Returns the position for bound and linked labels. Cannot be used
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 int32_t idx = (at == PostIndex) ? B10 : (B11 | B10); 138 int32_t idx = (at == PostIndex) ? B10 : (B11 | B10);
120 encoding_ = 139 encoding_ =
121 idx | 140 idx |
122 ((offset & 0x1ff) << kImm9Shift) | 141 ((offset & 0x1ff) << kImm9Shift) |
123 (static_cast<int32_t>(crn) << kRnShift); 142 (static_cast<int32_t>(crn) << kRnShift);
124 } 143 }
125 type_ = at; 144 type_ = at;
126 base_ = crn; 145 base_ = crn;
127 } 146 }
128 147
148 // This addressing mode does not exist.
149 Address(Register rn, Register offset, AddressType at,
150 OperandSize sz = kDoubleWord);
151
129 static bool CanHoldOffset(int32_t offset, AddressType at = Offset, 152 static bool CanHoldOffset(int32_t offset, AddressType at = Offset,
130 OperandSize sz = kDoubleWord) { 153 OperandSize sz = kDoubleWord) {
131 if (at == Offset) { 154 if (at == Offset) {
132 // Offset fits in 12 bit unsigned and has right alignment for sz, 155 // Offset fits in 12 bit unsigned and has right alignment for sz,
133 // or fits in 9 bit signed offset with no alignment restriction. 156 // or fits in 9 bit signed offset with no alignment restriction.
134 const int32_t scale = Log2OperandSizeBytes(sz); 157 const int32_t scale = Log2OperandSizeBytes(sz);
135 return (Utils::IsUint(12 + scale, offset) && 158 return (Utils::IsUint(12 + scale, offset) &&
136 (offset == ((offset >> scale) << scale))) || 159 (offset == ((offset >> scale) << scale))) ||
137 (Utils::IsInt(9, offset)); 160 (Utils::IsInt(9, offset));
138 } else if (at == PCOffset) { 161 } else if (at == PCOffset) {
139 return Utils::IsInt(21, offset) && 162 return Utils::IsInt(21, offset) &&
140 (offset == ((offset >> 2) << 2)); 163 (offset == ((offset >> 2) << 2));
141 } else { 164 } else {
142 ASSERT((at == PreIndex) || (at == PostIndex)); 165 ASSERT((at == PreIndex) || (at == PostIndex));
143 return Utils::IsInt(9, offset); 166 return Utils::IsInt(9, offset);
144 } 167 }
145 } 168 }
146 169
147 // PC-relative load address. 170 // PC-relative load address.
148 static Address PC(int32_t pc_off) { 171 static Address PC(int32_t pc_off) {
149 ASSERT(CanHoldOffset(pc_off, PCOffset)); 172 ASSERT(CanHoldOffset(pc_off, PCOffset));
150 Address addr; 173 Address addr;
151 addr.encoding_ = (((pc_off >> 2) << kImm19Shift) & kImm19Mask); 174 addr.encoding_ = (((pc_off >> 2) << kImm19Shift) & kImm19Mask);
152 addr.base_ = kNoRegister; 175 addr.base_ = kNoRegister;
153 addr.type_ = PCOffset; 176 addr.type_ = PCOffset;
154 return addr; 177 return addr;
155 } 178 }
156 179
180 // This addressing mode does not exist.
181 static Address PC(Register r);
182
157 enum Scaling { 183 enum Scaling {
158 Unscaled, 184 Unscaled,
159 Scaled, 185 Scaled,
160 }; 186 };
161 187
162 // Base register rn with offset rm. rm is sign-extended according to ext. 188 // Base register rn with offset rm. rm is sign-extended according to ext.
163 // If ext is UXTX, rm may be optionally scaled by the 189 // If ext is UXTX, rm may be optionally scaled by the
164 // Log2OperandSize (specified by the instruction). 190 // Log2OperandSize (specified by the instruction).
165 Address(Register rn, Register rm, 191 Address(Register rn, Register rm,
166 Extend ext = UXTX, Scaling scale = Unscaled) { 192 Extend ext = UXTX, Scaling scale = Unscaled) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 265
240 friend class Assembler; 266 friend class Assembler;
241 }; 267 };
242 268
243 269
244 class FieldAddress : public Address { 270 class FieldAddress : public Address {
245 public: 271 public:
246 FieldAddress(Register base, int32_t disp, OperandSize sz = kDoubleWord) 272 FieldAddress(Register base, int32_t disp, OperandSize sz = kDoubleWord)
247 : Address(base, disp - kHeapObjectTag, Offset, sz) { } 273 : Address(base, disp - kHeapObjectTag, Offset, sz) { }
248 274
275 // This addressing mode does not exist.
276 FieldAddress(Register base, Register disp, OperandSize sz = kDoubleWord);
277
249 FieldAddress(const FieldAddress& other) : Address(other) { } 278 FieldAddress(const FieldAddress& other) : Address(other) { }
250 279
251 FieldAddress& operator=(const FieldAddress& other) { 280 FieldAddress& operator=(const FieldAddress& other) {
252 Address::operator=(other); 281 Address::operator=(other);
253 return *this; 282 return *this;
254 } 283 }
255 }; 284 };
256 285
257 286
258 class Operand : public ValueObject { 287 class Operand : public ValueObject {
(...skipping 30 matching lines...) Expand all
289 ASSERT(Utils::IsUint(6, imm)); 318 ASSERT(Utils::IsUint(6, imm));
290 ASSERT((rm != R31) && (rm != CSP)); 319 ASSERT((rm != R31) && (rm != CSP));
291 const Register crm = ConcreteRegister(rm); 320 const Register crm = ConcreteRegister(rm);
292 encoding_ = 321 encoding_ =
293 (imm << kImm6Shift) | 322 (imm << kImm6Shift) |
294 (static_cast<int32_t>(crm) << kRmShift) | 323 (static_cast<int32_t>(crm) << kRmShift) |
295 (static_cast<int32_t>(shift) << kShiftTypeShift); 324 (static_cast<int32_t>(shift) << kShiftTypeShift);
296 type_ = Shifted; 325 type_ = Shifted;
297 } 326 }
298 327
328 // This operand type does not exist.
329 Operand(Register rm, Shift shift, Register r);
330
299 Operand(Register rm, Extend extend, int32_t imm) { 331 Operand(Register rm, Extend extend, int32_t imm) {
300 ASSERT(Utils::IsUint(3, imm)); 332 ASSERT(Utils::IsUint(3, imm));
301 ASSERT((rm != R31) && (rm != CSP)); 333 ASSERT((rm != R31) && (rm != CSP));
302 const Register crm = ConcreteRegister(rm); 334 const Register crm = ConcreteRegister(rm);
303 encoding_ = 335 encoding_ =
304 B21 | 336 B21 |
305 (static_cast<int32_t>(crm) << kRmShift) | 337 (static_cast<int32_t>(crm) << kRmShift) |
306 (static_cast<int32_t>(extend) << kExtendTypeShift) | 338 (static_cast<int32_t>(extend) << kExtendTypeShift) |
307 ((imm & 0x7) << kImm3Shift); 339 ((imm & 0x7) << kImm3Shift);
308 type_ = Extended; 340 type_ = Extended;
309 } 341 }
310 342
343 // This operand type does not exist.
344 Operand(Register rm, Extend extend, Register r);
345
311 explicit Operand(int32_t imm) { 346 explicit Operand(int32_t imm) {
312 if (Utils::IsUint(12, imm)) { 347 if (Utils::IsUint(12, imm)) {
313 encoding_ = imm << kImm12Shift; 348 encoding_ = imm << kImm12Shift;
314 } else { 349 } else {
315 // imm only has bits in [12, 24) set. 350 // imm only has bits in [12, 24) set.
316 ASSERT(((imm & 0xfff) == 0) && (Utils::IsUint(12, imm >> 12))); 351 ASSERT(((imm & 0xfff) == 0) && (Utils::IsUint(12, imm >> 12)));
317 encoding_ = B22 | ((imm >> 12) << kImm12Shift); 352 encoding_ = B22 | ((imm >> 12) << kImm12Shift);
318 } 353 }
319 type_ = Immediate; 354 type_ = Immediate;
320 } 355 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 static const char* FpuRegisterName(FpuRegister reg); 476 static const char* FpuRegisterName(FpuRegister reg);
442 477
443 void SetPrologueOffset() { 478 void SetPrologueOffset() {
444 if (prologue_offset_ == -1) { 479 if (prologue_offset_ == -1) {
445 prologue_offset_ = CodeSize(); 480 prologue_offset_ = CodeSize();
446 } 481 }
447 } 482 }
448 483
449 void ReserveAlignedFrameSpace(intptr_t frame_space); 484 void ReserveAlignedFrameSpace(intptr_t frame_space);
450 485
451 // TODO(zra): Make sure this is right.
452 // Instruction pattern from entrypoint is used in Dart frame prologs 486 // Instruction pattern from entrypoint is used in Dart frame prologs
453 // to set up the frame and save a PC which can be used to figure out the 487 // to set up the frame and save a PC which can be used to figure out the
454 // RawInstruction object corresponding to the code running in the frame. 488 // RawInstruction object corresponding to the code running in the frame.
455 static const intptr_t kEntryPointToPcMarkerOffset = 0; 489 static const intptr_t kEntryPointToPcMarkerOffset = 0;
456 static intptr_t EntryPointToPcMarkerOffset() { 490 static intptr_t EntryPointToPcMarkerOffset() {
457 return kEntryPointToPcMarkerOffset; 491 return kEntryPointToPcMarkerOffset;
458 } 492 }
459 493
460 // Emit data (e.g encoded instruction or immediate) in instruction stream. 494 // Emit data (e.g encoded instruction or immediate) in instruction stream.
461 void Emit(int32_t value); 495 void Emit(int32_t value);
(...skipping 16 matching lines...) Expand all
478 AddSubHelper(kWord, false, false, rd, rn, o); 512 AddSubHelper(kWord, false, false, rd, rn, o);
479 } 513 }
480 void sub(Register rd, Register rn, Operand o) { 514 void sub(Register rd, Register rn, Operand o) {
481 AddSubHelper(kDoubleWord, false, true, rd, rn, o); 515 AddSubHelper(kDoubleWord, false, true, rd, rn, o);
482 } 516 }
483 void subs(Register rd, Register rn, Operand o) { 517 void subs(Register rd, Register rn, Operand o) {
484 AddSubHelper(kDoubleWord, true, true, rd, rn, o); 518 AddSubHelper(kDoubleWord, true, true, rd, rn, o);
485 } 519 }
486 520
487 // PC relative immediate add. imm is in bytes. 521 // PC relative immediate add. imm is in bytes.
488 void adr(Register rd, int64_t imm) { 522 void adr(Register rd, const Immediate& imm) {
489 EmitPCRelOp(ADR, rd, imm); 523 EmitPCRelOp(ADR, rd, imm);
490 } 524 }
491 525
492 // Logical immediate operations. 526 // Logical immediate operations.
493 void andi(Register rd, Register rn, uint64_t imm) { 527 void andi(Register rd, Register rn, const Immediate& imm) {
494 Operand imm_op; 528 Operand imm_op;
495 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); 529 const bool immok =
530 Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
496 ASSERT(immok); 531 ASSERT(immok);
497 EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord); 532 EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord);
498 } 533 }
499 void orri(Register rd, Register rn, uint64_t imm) { 534 void orri(Register rd, Register rn, const Immediate& imm) {
500 Operand imm_op; 535 Operand imm_op;
501 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); 536 const bool immok =
537 Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
502 ASSERT(immok); 538 ASSERT(immok);
503 EmitLogicalImmOp(ORRI, rd, rn, imm_op, kDoubleWord); 539 EmitLogicalImmOp(ORRI, rd, rn, imm_op, kDoubleWord);
504 } 540 }
505 void eori(Register rd, Register rn, uint64_t imm) { 541 void eori(Register rd, Register rn, const Immediate& imm) {
506 Operand imm_op; 542 Operand imm_op;
507 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); 543 const bool immok =
544 Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
508 ASSERT(immok); 545 ASSERT(immok);
509 EmitLogicalImmOp(EORI, rd, rn, imm_op, kDoubleWord); 546 EmitLogicalImmOp(EORI, rd, rn, imm_op, kDoubleWord);
510 } 547 }
511 void andis(Register rd, Register rn, uint64_t imm) { 548 void andis(Register rd, Register rn, const Immediate& imm) {
512 Operand imm_op; 549 Operand imm_op;
513 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); 550 const bool immok =
551 Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
514 ASSERT(immok); 552 ASSERT(immok);
515 EmitLogicalImmOp(ANDIS, rd, rn, imm_op, kDoubleWord); 553 EmitLogicalImmOp(ANDIS, rd, rn, imm_op, kDoubleWord);
516 } 554 }
517 555
518 // Logical (shifted) register operations. 556 // Logical (shifted) register operations.
519 void and_(Register rd, Register rn, Operand o) { 557 void and_(Register rd, Register rn, Operand o) {
520 EmitLogicalShiftOp(AND, rd, rn, o, kDoubleWord); 558 EmitLogicalShiftOp(AND, rd, rn, o, kDoubleWord);
521 } 559 }
522 void andw_(Register rd, Register rn, Operand o) { 560 void andw_(Register rd, Register rn, Operand o) {
523 EmitLogicalShiftOp(AND, rd, rn, o, kWord); 561 EmitLogicalShiftOp(AND, rd, rn, o, kWord);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 EmitMiscDP3Source(MADD, rd, rn, rm, ra, kDoubleWord); 605 EmitMiscDP3Source(MADD, rd, rn, rm, ra, kDoubleWord);
568 } 606 }
569 void msub(Register rd, Register rn, Register rm, Register ra) { 607 void msub(Register rd, Register rn, Register rm, Register ra) {
570 EmitMiscDP3Source(MSUB, rd, rn, rm, ra, kDoubleWord); 608 EmitMiscDP3Source(MSUB, rd, rn, rm, ra, kDoubleWord);
571 } 609 }
572 void smulh(Register rd, Register rn, Register rm) { 610 void smulh(Register rd, Register rn, Register rm) {
573 EmitMiscDP3Source(SMULH, rd, rn, rm, R0, kDoubleWord); 611 EmitMiscDP3Source(SMULH, rd, rn, rm, R0, kDoubleWord);
574 } 612 }
575 613
576 // Move wide immediate. 614 // Move wide immediate.
577 void movk(Register rd, uint16_t imm, int hw_idx) { 615 void movk(Register rd, const Immediate& imm, int hw_idx) {
578 ASSERT(rd != CSP); 616 ASSERT(rd != CSP);
579 const Register crd = ConcreteRegister(rd); 617 const Register crd = ConcreteRegister(rd);
580 EmitMoveWideOp(MOVK, crd, imm, hw_idx, kDoubleWord); 618 EmitMoveWideOp(MOVK, crd, imm, hw_idx, kDoubleWord);
581 } 619 }
582 void movn(Register rd, uint16_t imm, int hw_idx) { 620 void movn(Register rd, const Immediate& imm, int hw_idx) {
583 ASSERT(rd != CSP); 621 ASSERT(rd != CSP);
584 const Register crd = ConcreteRegister(rd); 622 const Register crd = ConcreteRegister(rd);
585 EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord); 623 EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord);
586 } 624 }
587 void movz(Register rd, uint16_t imm, int hw_idx) { 625 void movz(Register rd, const Immediate& imm, int hw_idx) {
588 ASSERT(rd != CSP); 626 ASSERT(rd != CSP);
589 const Register crd = ConcreteRegister(rd); 627 const Register crd = ConcreteRegister(rd);
590 EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord); 628 EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord);
591 } 629 }
592 630
593 // Loads and Stores. 631 // Loads and Stores.
594 void ldr(Register rt, Address a, OperandSize sz = kDoubleWord) { 632 void ldr(Register rt, Address a, OperandSize sz = kDoubleWord) {
595 if (a.type() == Address::PCOffset) { 633 if (a.type() == Address::PCOffset) {
596 ASSERT(sz == kDoubleWord); 634 ASSERT(sz == kDoubleWord);
597 EmitLoadRegLiteral(LDRpc, rt, a, sz); 635 EmitLoadRegLiteral(LDRpc, rt, a, sz);
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 add(TMP, PP, Operand(kHeapObjectTag)); 1029 add(TMP, PP, Operand(kHeapObjectTag));
992 str(TMP, Address(SP, -1 * kWordSize, Address::PreIndex)); 1030 str(TMP, Address(SP, -1 * kWordSize, Address::PreIndex));
993 } 1031 }
994 void PopAndUntagPP() { 1032 void PopAndUntagPP() {
995 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex)); 1033 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex));
996 sub(PP, PP, Operand(kHeapObjectTag)); 1034 sub(PP, PP, Operand(kHeapObjectTag));
997 } 1035 }
998 void tst(Register rn, Operand o) { 1036 void tst(Register rn, Operand o) {
999 ands(ZR, rn, o); 1037 ands(ZR, rn, o);
1000 } 1038 }
1001 void tsti(Register rn, uint64_t imm) { 1039 void tsti(Register rn, const Immediate& imm) {
1002 andis(ZR, rn, imm); 1040 andis(ZR, rn, imm);
1003 } 1041 }
1004 1042
1005 void LslImmediate(Register rd, Register rn, int shift) { 1043 void LslImmediate(Register rd, Register rn, int shift) {
1006 add(rd, ZR, Operand(rn, LSL, shift)); 1044 add(rd, ZR, Operand(rn, LSL, shift));
1007 } 1045 }
1008 void LsrImmediate(Register rd, Register rn, int shift) { 1046 void LsrImmediate(Register rd, Register rn, int shift) {
1009 add(rd, ZR, Operand(rn, LSR, shift)); 1047 add(rd, ZR, Operand(rn, LSR, shift));
1010 } 1048 }
1011 void AsrImmediate(Register rd, Register rn, int shift) { 1049 void AsrImmediate(Register rd, Register rn, int shift) {
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 op | (static_cast<int32_t>(crn) << kRnShift); 1557 op | (static_cast<int32_t>(crn) << kRnShift);
1520 Emit(encoding); 1558 Emit(encoding);
1521 } 1559 }
1522 1560
1523 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) { 1561 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) {
1524 const int32_t encoding = 1562 const int32_t encoding =
1525 op | (static_cast<int32_t>(imm) << kImm16Shift); 1563 op | (static_cast<int32_t>(imm) << kImm16Shift);
1526 Emit(encoding); 1564 Emit(encoding);
1527 } 1565 }
1528 1566
1529 void EmitMoveWideOp(MoveWideOp op, Register rd, uint16_t imm, int hw_idx, 1567 void EmitMoveWideOp(MoveWideOp op, Register rd, const Immediate& imm,
1530 OperandSize sz) { 1568 int hw_idx, OperandSize sz) {
1531 ASSERT((hw_idx >= 0) && (hw_idx <= 3)); 1569 ASSERT((hw_idx >= 0) && (hw_idx <= 3));
1532 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1570 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1533 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1571 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1534 const int32_t encoding = 1572 const int32_t encoding =
1535 op | size | 1573 op | size |
1536 (static_cast<int32_t>(rd) << kRdShift) | 1574 (static_cast<int32_t>(rd) << kRdShift) |
1537 (static_cast<int32_t>(hw_idx) << kHWShift) | 1575 (static_cast<int32_t>(hw_idx) << kHWShift) |
1538 (static_cast<int32_t>(imm) << kImm16Shift); 1576 (static_cast<int32_t>(imm.value() & 0xffff) << kImm16Shift);
1539 Emit(encoding); 1577 Emit(encoding);
1540 } 1578 }
1541 1579
1542 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, 1580 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a,
1543 OperandSize sz) { 1581 OperandSize sz) {
1544 const Register crt = ConcreteRegister(rt); 1582 const Register crt = ConcreteRegister(rt);
1545 const int32_t size = Log2OperandSizeBytes(sz); 1583 const int32_t size = Log2OperandSizeBytes(sz);
1546 const int32_t encoding = 1584 const int32_t encoding =
1547 op | ((size & 0x3) << kSzShift) | 1585 op | ((size & 0x3) << kSzShift) |
1548 (static_cast<int32_t>(crt) << kRtShift) | 1586 (static_cast<int32_t>(crt) << kRtShift) |
1549 a.encoding(); 1587 a.encoding();
1550 Emit(encoding); 1588 Emit(encoding);
1551 } 1589 }
1552 1590
1553 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, 1591 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a,
1554 OperandSize sz) { 1592 OperandSize sz) {
1555 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1593 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1556 ASSERT((rt != CSP) && (rt != R31)); 1594 ASSERT((rt != CSP) && (rt != R31));
1557 const Register crt = ConcreteRegister(rt); 1595 const Register crt = ConcreteRegister(rt);
1558 const int32_t size = (sz == kDoubleWord) ? B30 : 0; 1596 const int32_t size = (sz == kDoubleWord) ? B30 : 0;
1559 const int32_t encoding = 1597 const int32_t encoding =
1560 op | size | 1598 op | size |
1561 (static_cast<int32_t>(crt) << kRtShift) | 1599 (static_cast<int32_t>(crt) << kRtShift) |
1562 a.encoding(); 1600 a.encoding();
1563 Emit(encoding); 1601 Emit(encoding);
1564 } 1602 }
1565 1603
1566 void EmitPCRelOp(PCRelOp op, Register rd, int64_t imm) { 1604 void EmitPCRelOp(PCRelOp op, Register rd, const Immediate& imm) {
1567 ASSERT(Utils::IsInt(21, imm)); 1605 ASSERT(Utils::IsInt(21, imm.value()));
1568 ASSERT((rd != R31) && (rd != CSP)); 1606 ASSERT((rd != R31) && (rd != CSP));
1569 const Register crd = ConcreteRegister(rd); 1607 const Register crd = ConcreteRegister(rd);
1570 const int32_t loimm = (imm & 0x3) << 29; 1608 const int32_t loimm = (imm.value() & 0x3) << 29;
1571 const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask; 1609 const int32_t hiimm = ((imm.value() >> 2) << kImm19Shift) & kImm19Mask;
1572 const int32_t encoding = 1610 const int32_t encoding =
1573 op | loimm | hiimm | 1611 op | loimm | hiimm |
1574 (static_cast<int32_t>(crd) << kRdShift); 1612 (static_cast<int32_t>(crd) << kRdShift);
1575 Emit(encoding); 1613 Emit(encoding);
1576 } 1614 }
1577 1615
1578 void EmitMiscDP2Source(MiscDP2SourceOp op, 1616 void EmitMiscDP2Source(MiscDP2SourceOp op,
1579 Register rd, Register rn, Register rm, 1617 Register rd, Register rn, Register rm,
1580 OperandSize sz) { 1618 OperandSize sz) {
1581 ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP)); 1619 ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP));
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 Register value, 1748 Register value,
1711 Label* no_update); 1749 Label* no_update);
1712 1750
1713 DISALLOW_ALLOCATION(); 1751 DISALLOW_ALLOCATION();
1714 DISALLOW_COPY_AND_ASSIGN(Assembler); 1752 DISALLOW_COPY_AND_ASSIGN(Assembler);
1715 }; 1753 };
1716 1754
1717 } // namespace dart 1755 } // namespace dart
1718 1756
1719 #endif // VM_ASSEMBLER_ARM64_H_ 1757 #endif // VM_ASSEMBLER_ARM64_H_
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.cc ('k') | runtime/vm/assembler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698