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

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
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 : Address(base) {
278 UNREACHABLE();
279 }
280
249 FieldAddress(const FieldAddress& other) : Address(other) { } 281 FieldAddress(const FieldAddress& other) : Address(other) { }
250 282
251 FieldAddress& operator=(const FieldAddress& other) { 283 FieldAddress& operator=(const FieldAddress& other) {
252 Address::operator=(other); 284 Address::operator=(other);
253 return *this; 285 return *this;
254 } 286 }
255 }; 287 };
256 288
257 289
258 class Operand : public ValueObject { 290 class Operand : public ValueObject {
(...skipping 30 matching lines...) Expand all
289 ASSERT(Utils::IsUint(6, imm)); 321 ASSERT(Utils::IsUint(6, imm));
290 ASSERT((rm != R31) && (rm != CSP)); 322 ASSERT((rm != R31) && (rm != CSP));
291 const Register crm = ConcreteRegister(rm); 323 const Register crm = ConcreteRegister(rm);
292 encoding_ = 324 encoding_ =
293 (imm << kImm6Shift) | 325 (imm << kImm6Shift) |
294 (static_cast<int32_t>(crm) << kRmShift) | 326 (static_cast<int32_t>(crm) << kRmShift) |
295 (static_cast<int32_t>(shift) << kShiftTypeShift); 327 (static_cast<int32_t>(shift) << kShiftTypeShift);
296 type_ = Shifted; 328 type_ = Shifted;
297 } 329 }
298 330
331 // This operand type does not exist.
332 Operand(Register rm, Shift shift, Register r);
333
299 Operand(Register rm, Extend extend, int32_t imm) { 334 Operand(Register rm, Extend extend, int32_t imm) {
300 ASSERT(Utils::IsUint(3, imm)); 335 ASSERT(Utils::IsUint(3, imm));
301 ASSERT((rm != R31) && (rm != CSP)); 336 ASSERT((rm != R31) && (rm != CSP));
302 const Register crm = ConcreteRegister(rm); 337 const Register crm = ConcreteRegister(rm);
303 encoding_ = 338 encoding_ =
304 B21 | 339 B21 |
305 (static_cast<int32_t>(crm) << kRmShift) | 340 (static_cast<int32_t>(crm) << kRmShift) |
306 (static_cast<int32_t>(extend) << kExtendTypeShift) | 341 (static_cast<int32_t>(extend) << kExtendTypeShift) |
307 ((imm & 0x7) << kImm3Shift); 342 ((imm & 0x7) << kImm3Shift);
308 type_ = Extended; 343 type_ = Extended;
309 } 344 }
310 345
346 // This operand type does not exist.
347 Operand(Register rm, Extend extend, Register r);
348
311 explicit Operand(int32_t imm) { 349 explicit Operand(int32_t imm) {
312 if (Utils::IsUint(12, imm)) { 350 if (Utils::IsUint(12, imm)) {
313 encoding_ = imm << kImm12Shift; 351 encoding_ = imm << kImm12Shift;
314 } else { 352 } else {
315 // imm only has bits in [12, 24) set. 353 // imm only has bits in [12, 24) set.
316 ASSERT(((imm & 0xfff) == 0) && (Utils::IsUint(12, imm >> 12))); 354 ASSERT(((imm & 0xfff) == 0) && (Utils::IsUint(12, imm >> 12)));
317 encoding_ = B22 | ((imm >> 12) << kImm12Shift); 355 encoding_ = B22 | ((imm >> 12) << kImm12Shift);
318 } 356 }
319 type_ = Immediate; 357 type_ = Immediate;
320 } 358 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 static const char* FpuRegisterName(FpuRegister reg); 479 static const char* FpuRegisterName(FpuRegister reg);
442 480
443 void SetPrologueOffset() { 481 void SetPrologueOffset() {
444 if (prologue_offset_ == -1) { 482 if (prologue_offset_ == -1) {
445 prologue_offset_ = CodeSize(); 483 prologue_offset_ = CodeSize();
446 } 484 }
447 } 485 }
448 486
449 void ReserveAlignedFrameSpace(intptr_t frame_space); 487 void ReserveAlignedFrameSpace(intptr_t frame_space);
450 488
451 // TODO(zra): Make sure this is right.
452 // Instruction pattern from entrypoint is used in Dart frame prologs 489 // 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 490 // 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. 491 // RawInstruction object corresponding to the code running in the frame.
455 static const intptr_t kEntryPointToPcMarkerOffset = 0; 492 static const intptr_t kEntryPointToPcMarkerOffset = 0;
456 static intptr_t EntryPointToPcMarkerOffset() { 493 static intptr_t EntryPointToPcMarkerOffset() {
457 return kEntryPointToPcMarkerOffset; 494 return kEntryPointToPcMarkerOffset;
458 } 495 }
459 496
460 // Emit data (e.g encoded instruction or immediate) in instruction stream. 497 // Emit data (e.g encoded instruction or immediate) in instruction stream.
461 void Emit(int32_t value); 498 void Emit(int32_t value);
(...skipping 16 matching lines...) Expand all
478 AddSubHelper(kWord, false, false, rd, rn, o); 515 AddSubHelper(kWord, false, false, rd, rn, o);
479 } 516 }
480 void sub(Register rd, Register rn, Operand o) { 517 void sub(Register rd, Register rn, Operand o) {
481 AddSubHelper(kDoubleWord, false, true, rd, rn, o); 518 AddSubHelper(kDoubleWord, false, true, rd, rn, o);
482 } 519 }
483 void subs(Register rd, Register rn, Operand o) { 520 void subs(Register rd, Register rn, Operand o) {
484 AddSubHelper(kDoubleWord, true, true, rd, rn, o); 521 AddSubHelper(kDoubleWord, true, true, rd, rn, o);
485 } 522 }
486 523
487 // PC relative immediate add. imm is in bytes. 524 // PC relative immediate add. imm is in bytes.
488 void adr(Register rd, int64_t imm) { 525 void adr(Register rd, const Immediate& imm) {
489 EmitPCRelOp(ADR, rd, imm); 526 EmitPCRelOp(ADR, rd, imm);
490 } 527 }
491 528
492 // Logical immediate operations. 529 // Logical immediate operations.
493 void andi(Register rd, Register rn, uint64_t imm) { 530 void andi(Register rd, Register rn, const Immediate& imm) {
494 Operand imm_op; 531 Operand imm_op;
495 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); 532 const bool immok =
533 Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
496 ASSERT(immok); 534 ASSERT(immok);
497 EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord); 535 EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord);
498 } 536 }
499 void orri(Register rd, Register rn, uint64_t imm) { 537 void orri(Register rd, Register rn, const Immediate& imm) {
500 Operand imm_op; 538 Operand imm_op;
501 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); 539 const bool immok =
540 Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
502 ASSERT(immok); 541 ASSERT(immok);
503 EmitLogicalImmOp(ORRI, rd, rn, imm_op, kDoubleWord); 542 EmitLogicalImmOp(ORRI, rd, rn, imm_op, kDoubleWord);
504 } 543 }
505 void eori(Register rd, Register rn, uint64_t imm) { 544 void eori(Register rd, Register rn, const Immediate& imm) {
506 Operand imm_op; 545 Operand imm_op;
507 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); 546 const bool immok =
547 Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
508 ASSERT(immok); 548 ASSERT(immok);
509 EmitLogicalImmOp(EORI, rd, rn, imm_op, kDoubleWord); 549 EmitLogicalImmOp(EORI, rd, rn, imm_op, kDoubleWord);
510 } 550 }
511 void andis(Register rd, Register rn, uint64_t imm) { 551 void andis(Register rd, Register rn, const Immediate& imm) {
512 Operand imm_op; 552 Operand imm_op;
513 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); 553 const bool immok =
554 Operand::IsImmLogical(imm.value(), kXRegSizeInBits, &imm_op);
514 ASSERT(immok); 555 ASSERT(immok);
515 EmitLogicalImmOp(ANDIS, rd, rn, imm_op, kDoubleWord); 556 EmitLogicalImmOp(ANDIS, rd, rn, imm_op, kDoubleWord);
516 } 557 }
517 558
518 // Logical (shifted) register operations. 559 // Logical (shifted) register operations.
519 void and_(Register rd, Register rn, Operand o) { 560 void and_(Register rd, Register rn, Operand o) {
520 EmitLogicalShiftOp(AND, rd, rn, o, kDoubleWord); 561 EmitLogicalShiftOp(AND, rd, rn, o, kDoubleWord);
521 } 562 }
522 void andw_(Register rd, Register rn, Operand o) { 563 void andw_(Register rd, Register rn, Operand o) {
523 EmitLogicalShiftOp(AND, rd, rn, o, kWord); 564 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); 608 EmitMiscDP3Source(MADD, rd, rn, rm, ra, kDoubleWord);
568 } 609 }
569 void msub(Register rd, Register rn, Register rm, Register ra) { 610 void msub(Register rd, Register rn, Register rm, Register ra) {
570 EmitMiscDP3Source(MSUB, rd, rn, rm, ra, kDoubleWord); 611 EmitMiscDP3Source(MSUB, rd, rn, rm, ra, kDoubleWord);
571 } 612 }
572 void smulh(Register rd, Register rn, Register rm) { 613 void smulh(Register rd, Register rn, Register rm) {
573 EmitMiscDP3Source(SMULH, rd, rn, rm, R0, kDoubleWord); 614 EmitMiscDP3Source(SMULH, rd, rn, rm, R0, kDoubleWord);
574 } 615 }
575 616
576 // Move wide immediate. 617 // Move wide immediate.
577 void movk(Register rd, uint16_t imm, int hw_idx) { 618 void movk(Register rd, const Immediate& imm, int hw_idx) {
578 ASSERT(rd != CSP); 619 ASSERT(rd != CSP);
579 const Register crd = ConcreteRegister(rd); 620 const Register crd = ConcreteRegister(rd);
580 EmitMoveWideOp(MOVK, crd, imm, hw_idx, kDoubleWord); 621 EmitMoveWideOp(MOVK, crd, imm, hw_idx, kDoubleWord);
581 } 622 }
582 void movn(Register rd, uint16_t imm, int hw_idx) { 623 void movn(Register rd, const Immediate& imm, int hw_idx) {
583 ASSERT(rd != CSP); 624 ASSERT(rd != CSP);
584 const Register crd = ConcreteRegister(rd); 625 const Register crd = ConcreteRegister(rd);
585 EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord); 626 EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord);
586 } 627 }
587 void movz(Register rd, uint16_t imm, int hw_idx) { 628 void movz(Register rd, const Immediate& imm, int hw_idx) {
588 ASSERT(rd != CSP); 629 ASSERT(rd != CSP);
589 const Register crd = ConcreteRegister(rd); 630 const Register crd = ConcreteRegister(rd);
590 EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord); 631 EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord);
591 } 632 }
592 633
593 // Loads and Stores. 634 // Loads and Stores.
594 void ldr(Register rt, Address a, OperandSize sz = kDoubleWord) { 635 void ldr(Register rt, Address a, OperandSize sz = kDoubleWord) {
595 if (a.type() == Address::PCOffset) { 636 if (a.type() == Address::PCOffset) {
596 ASSERT(sz == kDoubleWord); 637 ASSERT(sz == kDoubleWord);
597 EmitLoadRegLiteral(LDRpc, rt, a, sz); 638 EmitLoadRegLiteral(LDRpc, rt, a, sz);
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 add(TMP, PP, Operand(kHeapObjectTag)); 1032 add(TMP, PP, Operand(kHeapObjectTag));
992 str(TMP, Address(SP, -1 * kWordSize, Address::PreIndex)); 1033 str(TMP, Address(SP, -1 * kWordSize, Address::PreIndex));
993 } 1034 }
994 void PopAndUntagPP() { 1035 void PopAndUntagPP() {
995 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex)); 1036 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex));
996 sub(PP, PP, Operand(kHeapObjectTag)); 1037 sub(PP, PP, Operand(kHeapObjectTag));
997 } 1038 }
998 void tst(Register rn, Operand o) { 1039 void tst(Register rn, Operand o) {
999 ands(ZR, rn, o); 1040 ands(ZR, rn, o);
1000 } 1041 }
1001 void tsti(Register rn, uint64_t imm) { 1042 void tsti(Register rn, const Immediate& imm) {
1002 andis(ZR, rn, imm); 1043 andis(ZR, rn, imm);
1003 } 1044 }
1004 1045
1005 void LslImmediate(Register rd, Register rn, int shift) { 1046 void LslImmediate(Register rd, Register rn, int shift) {
1006 add(rd, ZR, Operand(rn, LSL, shift)); 1047 add(rd, ZR, Operand(rn, LSL, shift));
1007 } 1048 }
1008 void LsrImmediate(Register rd, Register rn, int shift) { 1049 void LsrImmediate(Register rd, Register rn, int shift) {
1009 add(rd, ZR, Operand(rn, LSR, shift)); 1050 add(rd, ZR, Operand(rn, LSR, shift));
1010 } 1051 }
1011 void AsrImmediate(Register rd, Register rn, int shift) { 1052 void AsrImmediate(Register rd, Register rn, int shift) {
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 op | (static_cast<int32_t>(crn) << kRnShift); 1554 op | (static_cast<int32_t>(crn) << kRnShift);
1514 Emit(encoding); 1555 Emit(encoding);
1515 } 1556 }
1516 1557
1517 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) { 1558 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) {
1518 const int32_t encoding = 1559 const int32_t encoding =
1519 op | (static_cast<int32_t>(imm) << kImm16Shift); 1560 op | (static_cast<int32_t>(imm) << kImm16Shift);
1520 Emit(encoding); 1561 Emit(encoding);
1521 } 1562 }
1522 1563
1523 void EmitMoveWideOp(MoveWideOp op, Register rd, uint16_t imm, int hw_idx, 1564 void EmitMoveWideOp(MoveWideOp op, Register rd, const Immediate& imm,
1524 OperandSize sz) { 1565 int hw_idx, OperandSize sz) {
1525 ASSERT((hw_idx >= 0) && (hw_idx <= 3)); 1566 ASSERT((hw_idx >= 0) && (hw_idx <= 3));
1526 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1567 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1527 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1568 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1528 const int32_t encoding = 1569 const int32_t encoding =
1529 op | size | 1570 op | size |
1530 (static_cast<int32_t>(rd) << kRdShift) | 1571 (static_cast<int32_t>(rd) << kRdShift) |
1531 (static_cast<int32_t>(hw_idx) << kHWShift) | 1572 (static_cast<int32_t>(hw_idx) << kHWShift) |
1532 (static_cast<int32_t>(imm) << kImm16Shift); 1573 (static_cast<int32_t>(imm.value() & 0xffff) << kImm16Shift);
1533 Emit(encoding); 1574 Emit(encoding);
1534 } 1575 }
1535 1576
1536 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, 1577 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a,
1537 OperandSize sz) { 1578 OperandSize sz) {
1538 const Register crt = ConcreteRegister(rt); 1579 const Register crt = ConcreteRegister(rt);
1539 const int32_t size = Log2OperandSizeBytes(sz); 1580 const int32_t size = Log2OperandSizeBytes(sz);
1540 const int32_t encoding = 1581 const int32_t encoding =
1541 op | ((size & 0x3) << kSzShift) | 1582 op | ((size & 0x3) << kSzShift) |
1542 (static_cast<int32_t>(crt) << kRtShift) | 1583 (static_cast<int32_t>(crt) << kRtShift) |
1543 a.encoding(); 1584 a.encoding();
1544 Emit(encoding); 1585 Emit(encoding);
1545 } 1586 }
1546 1587
1547 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, 1588 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a,
1548 OperandSize sz) { 1589 OperandSize sz) {
1549 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1590 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1550 ASSERT((rt != CSP) && (rt != R31)); 1591 ASSERT((rt != CSP) && (rt != R31));
1551 const Register crt = ConcreteRegister(rt); 1592 const Register crt = ConcreteRegister(rt);
1552 const int32_t size = (sz == kDoubleWord) ? B30 : 0; 1593 const int32_t size = (sz == kDoubleWord) ? B30 : 0;
1553 const int32_t encoding = 1594 const int32_t encoding =
1554 op | size | 1595 op | size |
1555 (static_cast<int32_t>(crt) << kRtShift) | 1596 (static_cast<int32_t>(crt) << kRtShift) |
1556 a.encoding(); 1597 a.encoding();
1557 Emit(encoding); 1598 Emit(encoding);
1558 } 1599 }
1559 1600
1560 void EmitPCRelOp(PCRelOp op, Register rd, int64_t imm) { 1601 void EmitPCRelOp(PCRelOp op, Register rd, const Immediate& imm) {
1561 ASSERT(Utils::IsInt(21, imm)); 1602 ASSERT(Utils::IsInt(21, imm.value()));
1562 ASSERT((rd != R31) && (rd != CSP)); 1603 ASSERT((rd != R31) && (rd != CSP));
1563 const Register crd = ConcreteRegister(rd); 1604 const Register crd = ConcreteRegister(rd);
1564 const int32_t loimm = (imm & 0x3) << 29; 1605 const int32_t loimm = (imm.value() & 0x3) << 29;
1565 const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask; 1606 const int32_t hiimm = ((imm.value() >> 2) << kImm19Shift) & kImm19Mask;
1566 const int32_t encoding = 1607 const int32_t encoding =
1567 op | loimm | hiimm | 1608 op | loimm | hiimm |
1568 (static_cast<int32_t>(crd) << kRdShift); 1609 (static_cast<int32_t>(crd) << kRdShift);
1569 Emit(encoding); 1610 Emit(encoding);
1570 } 1611 }
1571 1612
1572 void EmitMiscDP2Source(MiscDP2SourceOp op, 1613 void EmitMiscDP2Source(MiscDP2SourceOp op,
1573 Register rd, Register rn, Register rm, 1614 Register rd, Register rn, Register rm,
1574 OperandSize sz) { 1615 OperandSize sz) {
1575 ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP)); 1616 ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP));
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 Register value, 1745 Register value,
1705 Label* no_update); 1746 Label* no_update);
1706 1747
1707 DISALLOW_ALLOCATION(); 1748 DISALLOW_ALLOCATION();
1708 DISALLOW_COPY_AND_ASSIGN(Assembler); 1749 DISALLOW_COPY_AND_ASSIGN(Assembler);
1709 }; 1750 };
1710 1751
1711 } // namespace dart 1752 } // namespace dart
1712 1753
1713 #endif // VM_ASSEMBLER_ARM64_H_ 1754 #endif // VM_ASSEMBLER_ARM64_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698