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

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

Powered by Google App Engine
This is Rietveld 408576698