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

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

Issue 311903004: Fixes to run "Hello, world!" on arm64 hardware. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/assembler_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
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 Unscaled, 160 Unscaled,
161 Scaled, 161 Scaled,
162 }; 162 };
163 163
164 // Base register rn with offset rm. rm is sign-extended according to ext. 164 // Base register rn with offset rm. rm is sign-extended according to ext.
165 // If ext is UXTX, rm may be optionally scaled by the 165 // If ext is UXTX, rm may be optionally scaled by the
166 // Log2OperandSize (specified by the instruction). 166 // Log2OperandSize (specified by the instruction).
167 Address(Register rn, Register rm, 167 Address(Register rn, Register rm,
168 Extend ext = UXTX, Scaling scale = Unscaled) { 168 Extend ext = UXTX, Scaling scale = Unscaled) {
169 ASSERT((rn != R31) && (rn != ZR)); 169 ASSERT((rn != R31) && (rn != ZR));
170 ASSERT((rm != R31) && (rm != SP)); 170 ASSERT((rm != R31) && (rm != CSP));
171 // Can only scale when ext = UXTX. 171 // Can only scale when ext = UXTX.
172 ASSERT((scale != Scaled) || (ext == UXTX)); 172 ASSERT((scale != Scaled) || (ext == UXTX));
173 ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX)); 173 ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX));
174 const Register crn = ConcreteRegister(rn); 174 const Register crn = ConcreteRegister(rn);
175 const Register crm = ConcreteRegister(rm); 175 const Register crm = ConcreteRegister(rm);
176 const int32_t s = (scale == Scaled) ? B12 : 0; 176 const int32_t s = (scale == Scaled) ? B12 : 0;
177 encoding_ = 177 encoding_ =
178 B21 | B11 | s | 178 B21 | B11 | s |
179 (static_cast<int32_t>(crn) << kRnShift) | 179 (static_cast<int32_t>(crn) << kRnShift) |
180 (static_cast<int32_t>(crm) << kRmShift) | 180 (static_cast<int32_t>(crm) << kRmShift) |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 Operand(const Operand& other) 274 Operand(const Operand& other)
275 : ValueObject(), encoding_(other.encoding_), type_(other.type_) { } 275 : ValueObject(), encoding_(other.encoding_), type_(other.type_) { }
276 276
277 Operand& operator=(const Operand& other) { 277 Operand& operator=(const Operand& other) {
278 type_ = other.type_; 278 type_ = other.type_;
279 encoding_ = other.encoding_; 279 encoding_ = other.encoding_;
280 return *this; 280 return *this;
281 } 281 }
282 282
283 explicit Operand(Register rm) { 283 explicit Operand(Register rm) {
284 ASSERT((rm != R31) && (rm != SP)); 284 ASSERT((rm != R31) && (rm != CSP));
285 const Register crm = ConcreteRegister(rm); 285 const Register crm = ConcreteRegister(rm);
286 encoding_ = (static_cast<int32_t>(crm) << kRmShift); 286 encoding_ = (static_cast<int32_t>(crm) << kRmShift);
287 type_ = Shifted; 287 type_ = Shifted;
288 } 288 }
289 289
290 Operand(Register rm, Shift shift, int32_t imm) { 290 Operand(Register rm, Shift shift, int32_t imm) {
291 ASSERT(Utils::IsUint(6, imm)); 291 ASSERT(Utils::IsUint(6, imm));
292 ASSERT((rm != R31) && (rm != SP)); 292 ASSERT((rm != R31) && (rm != CSP));
293 const Register crm = ConcreteRegister(rm); 293 const Register crm = ConcreteRegister(rm);
294 encoding_ = 294 encoding_ =
295 (imm << kImm6Shift) | 295 (imm << kImm6Shift) |
296 (static_cast<int32_t>(crm) << kRmShift) | 296 (static_cast<int32_t>(crm) << kRmShift) |
297 (static_cast<int32_t>(shift) << kShiftTypeShift); 297 (static_cast<int32_t>(shift) << kShiftTypeShift);
298 type_ = Shifted; 298 type_ = Shifted;
299 } 299 }
300 300
301 Operand(Register rm, Extend extend, int32_t imm) { 301 Operand(Register rm, Extend extend, int32_t imm) {
302 ASSERT(Utils::IsUint(3, imm)); 302 ASSERT(Utils::IsUint(3, imm));
303 ASSERT((rm != R31) && (rm != SP)); 303 ASSERT((rm != R31) && (rm != CSP));
304 const Register crm = ConcreteRegister(rm); 304 const Register crm = ConcreteRegister(rm);
305 encoding_ = 305 encoding_ =
306 B21 | 306 B21 |
307 (static_cast<int32_t>(crm) << kRmShift) | 307 (static_cast<int32_t>(crm) << kRmShift) |
308 (static_cast<int32_t>(extend) << kExtendTypeShift) | 308 (static_cast<int32_t>(extend) << kExtendTypeShift) |
309 ((imm & 0x7) << kImm3Shift); 309 ((imm & 0x7) << kImm3Shift);
310 type_ = Extended; 310 type_ = Extended;
311 } 311 }
312 312
313 explicit Operand(int32_t imm) { 313 explicit Operand(int32_t imm) {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 456
457 // Emit data (e.g encoded instruction or immediate) in instruction stream. 457 // Emit data (e.g encoded instruction or immediate) in instruction stream.
458 void Emit(int32_t value); 458 void Emit(int32_t value);
459 459
460 // On some other platforms, we draw a distinction between safe and unsafe 460 // On some other platforms, we draw a distinction between safe and unsafe
461 // smis. 461 // smis.
462 static bool IsSafe(const Object& object) { return true; } 462 static bool IsSafe(const Object& object) { return true; }
463 static bool IsSafeSmi(const Object& object) { return object.IsSmi(); } 463 static bool IsSafeSmi(const Object& object) { return object.IsSmi(); }
464 464
465 // Addition and subtraction. 465 // Addition and subtraction.
466 // For add and sub, to use SP for rn, o must be of type Operand::Extend. 466 // For add and sub, to use CSP for rn, o must be of type Operand::Extend.
467 // For an unmodified rm in this case, use Operand(rm, UXTX, 0); 467 // For an unmodified rm in this case, use Operand(rm, UXTX, 0);
468 void add(Register rd, Register rn, Operand o) { 468 void add(Register rd, Register rn, Operand o) {
469 AddSubHelper(kDoubleWord, false, false, rd, rn, o); 469 AddSubHelper(kDoubleWord, false, false, rd, rn, o);
470 } 470 }
471 void adds(Register rd, Register rn, Operand o) { 471 void adds(Register rd, Register rn, Operand o) {
472 AddSubHelper(kDoubleWord, true, false, rd, rn, o); 472 AddSubHelper(kDoubleWord, true, false, rd, rn, o);
473 } 473 }
474 void addw(Register rd, Register rn, Operand o) { 474 void addw(Register rd, Register rn, Operand o) {
475 AddSubHelper(kWord, false, false, rd, rn, o); 475 AddSubHelper(kWord, false, false, rd, rn, o);
476 } 476 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 } 565 }
566 void msub(Register rd, Register rn, Register rm, Register ra) { 566 void msub(Register rd, Register rn, Register rm, Register ra) {
567 EmitMiscDP3Source(MSUB, rd, rn, rm, ra, kDoubleWord); 567 EmitMiscDP3Source(MSUB, rd, rn, rm, ra, kDoubleWord);
568 } 568 }
569 void smulh(Register rd, Register rn, Register rm) { 569 void smulh(Register rd, Register rn, Register rm) {
570 EmitMiscDP3Source(SMULH, rd, rn, rm, R0, kDoubleWord); 570 EmitMiscDP3Source(SMULH, rd, rn, rm, R0, kDoubleWord);
571 } 571 }
572 572
573 // Move wide immediate. 573 // Move wide immediate.
574 void movk(Register rd, uint16_t imm, int hw_idx) { 574 void movk(Register rd, uint16_t imm, int hw_idx) {
575 ASSERT(rd != SP); 575 ASSERT(rd != CSP);
576 const Register crd = ConcreteRegister(rd); 576 const Register crd = ConcreteRegister(rd);
577 EmitMoveWideOp(MOVK, crd, imm, hw_idx, kDoubleWord); 577 EmitMoveWideOp(MOVK, crd, imm, hw_idx, kDoubleWord);
578 } 578 }
579 void movn(Register rd, uint16_t imm, int hw_idx) { 579 void movn(Register rd, uint16_t imm, int hw_idx) {
580 ASSERT(rd != SP); 580 ASSERT(rd != CSP);
581 const Register crd = ConcreteRegister(rd); 581 const Register crd = ConcreteRegister(rd);
582 EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord); 582 EmitMoveWideOp(MOVN, crd, imm, hw_idx, kDoubleWord);
583 } 583 }
584 void movz(Register rd, uint16_t imm, int hw_idx) { 584 void movz(Register rd, uint16_t imm, int hw_idx) {
585 ASSERT(rd != SP); 585 ASSERT(rd != CSP);
586 const Register crd = ConcreteRegister(rd); 586 const Register crd = ConcreteRegister(rd);
587 EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord); 587 EmitMoveWideOp(MOVZ, crd, imm, hw_idx, kDoubleWord);
588 } 588 }
589 589
590 // Loads and Stores. 590 // Loads and Stores.
591 void ldr(Register rt, Address a, OperandSize sz = kDoubleWord) { 591 void ldr(Register rt, Address a, OperandSize sz = kDoubleWord) {
592 if (a.type() == Address::PCOffset) { 592 if (a.type() == Address::PCOffset) {
593 ASSERT(sz == kDoubleWord); 593 ASSERT(sz == kDoubleWord);
594 EmitLoadRegLiteral(LDRpc, rt, a, sz); 594 EmitLoadRegLiteral(LDRpc, rt, a, sz);
595 } else { 595 } else {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 } 628 }
629 void cinv(Register rd, Register rn, Condition cond) { 629 void cinv(Register rd, Register rn, Condition cond) {
630 csinv(rd, rn, rn, InvertCondition(cond)); 630 csinv(rd, rn, rn, InvertCondition(cond));
631 } 631 }
632 void csetm(Register rd, Condition cond) { 632 void csetm(Register rd, Condition cond) {
633 csinv(rd, ZR, ZR, InvertCondition(cond)); 633 csinv(rd, ZR, ZR, InvertCondition(cond));
634 } 634 }
635 635
636 // Comparison. 636 // Comparison.
637 // rn cmp o. 637 // rn cmp o.
638 // For add and sub, to use SP for rn, o must be of type Operand::Extend. 638 // For add and sub, to use CSP for rn, o must be of type Operand::Extend.
639 // For an unmodified rm in this case, use Operand(rm, UXTX, 0); 639 // For an unmodified rm in this case, use Operand(rm, UXTX, 0);
640 void cmp(Register rn, Operand o) { 640 void cmp(Register rn, Operand o) {
641 subs(ZR, rn, o); 641 subs(ZR, rn, o);
642 } 642 }
643 // rn cmp -o. 643 // rn cmp -o.
644 void cmn(Register rn, Operand o) { 644 void cmn(Register rn, Operand o) {
645 adds(ZR, rn, o); 645 adds(ZR, rn, o);
646 } 646 }
647 647
648 void CompareRegisters(Register rn, Register rm) { 648 void CompareRegisters(Register rn, Register rm) {
649 if (rn == SP) { 649 if (rn == CSP) {
650 // UXTX 0 on a 64-bit register (rm) is a nop, but forces R31 to be 650 // UXTX 0 on a 64-bit register (rm) is a nop, but forces R31 to be
651 // interpreted as SP. 651 // interpreted as CSP.
652 cmp(SP, Operand(rm, UXTX, 0)); 652 cmp(CSP, Operand(rm, UXTX, 0));
653 } else { 653 } else {
654 cmp(rn, Operand(rm)); 654 cmp(rn, Operand(rm));
655 } 655 }
656 } 656 }
657 657
658 // Conditional branch. 658 // Conditional branch.
659 void b(Label* label, Condition cond = AL) { 659 void b(Label* label, Condition cond = AL) {
660 EmitBranch(BCOND, cond, label); 660 EmitBranch(BCOND, cond, label);
661 } 661 }
662 662
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 const uint8_t imm8 = (bit7 << 7) | (bit6 << 6) | (bit54 << 4) | bit30; 695 const uint8_t imm8 = (bit7 << 7) | (bit6 << 6) | (bit54 << 4) | bit30;
696 const int64_t expimm8 = Instr::VFPExpandImm(imm8); 696 const int64_t expimm8 = Instr::VFPExpandImm(imm8);
697 if (imm64 != expimm8) { 697 if (imm64 != expimm8) {
698 return false; 698 return false;
699 } 699 }
700 EmitFPImm(FMOVDI, vd, imm8); 700 EmitFPImm(FMOVDI, vd, imm8);
701 return true; 701 return true;
702 } 702 }
703 void fmovdr(VRegister vd, Register rn) { 703 void fmovdr(VRegister vd, Register rn) {
704 ASSERT(rn != R31); 704 ASSERT(rn != R31);
705 ASSERT(rn != SP); 705 ASSERT(rn != CSP);
706 const Register crn = ConcreteRegister(rn); 706 const Register crn = ConcreteRegister(rn);
707 EmitFPIntCvtOp(FMOVDR, static_cast<Register>(vd), crn); 707 EmitFPIntCvtOp(FMOVDR, static_cast<Register>(vd), crn);
708 } 708 }
709 void fmovrd(Register rd, VRegister vn) { 709 void fmovrd(Register rd, VRegister vn) {
710 ASSERT(rd != R31); 710 ASSERT(rd != R31);
711 ASSERT(rd != SP); 711 ASSERT(rd != CSP);
712 const Register crd = ConcreteRegister(rd); 712 const Register crd = ConcreteRegister(rd);
713 EmitFPIntCvtOp(FMOVRD, crd, static_cast<Register>(vn)); 713 EmitFPIntCvtOp(FMOVRD, crd, static_cast<Register>(vn));
714 } 714 }
715 void scvtfd(VRegister vd, Register rn) { 715 void scvtfd(VRegister vd, Register rn) {
716 ASSERT(rn != R31); 716 ASSERT(rn != R31);
717 ASSERT(rn != SP); 717 ASSERT(rn != CSP);
718 const Register crn = ConcreteRegister(rn); 718 const Register crn = ConcreteRegister(rn);
719 EmitFPIntCvtOp(SCVTFD, static_cast<Register>(vd), crn); 719 EmitFPIntCvtOp(SCVTFD, static_cast<Register>(vd), crn);
720 } 720 }
721 void fcvtzds(Register rd, VRegister vn) { 721 void fcvtzds(Register rd, VRegister vn) {
722 ASSERT(rd != R31); 722 ASSERT(rd != R31);
723 ASSERT(rd != SP); 723 ASSERT(rd != CSP);
724 const Register crd = ConcreteRegister(rd); 724 const Register crd = ConcreteRegister(rd);
725 EmitFPIntCvtOp(FCVTZDS, crd, static_cast<Register>(vn)); 725 EmitFPIntCvtOp(FCVTZDS, crd, static_cast<Register>(vn));
726 } 726 }
727 void fmovdd(VRegister vd, VRegister vn) { 727 void fmovdd(VRegister vd, VRegister vn) {
728 EmitFPOneSourceOp(FMOVDD, vd, vn); 728 EmitFPOneSourceOp(FMOVDD, vd, vn);
729 } 729 }
730 void fabsd(VRegister vd, VRegister vn) { 730 void fabsd(VRegister vd, VRegister vn) {
731 EmitFPOneSourceOp(FABSD, vd, vn); 731 EmitFPOneSourceOp(FABSD, vd, vn);
732 } 732 }
733 void fnegd(VRegister vd, VRegister vn) { 733 void fnegd(VRegister vd, VRegister vn) {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 const VRegister vd = static_cast<VRegister>(rd); 926 const VRegister vd = static_cast<VRegister>(rd);
927 EmitSIMDCopyOp(VMOVW, vd, vn, kWord, 0, sidx); 927 EmitSIMDCopyOp(VMOVW, vd, vn, kWord, 0, sidx);
928 } 928 }
929 void vmovrd(Register rd, VRegister vn, int32_t sidx) { 929 void vmovrd(Register rd, VRegister vn, int32_t sidx) {
930 const VRegister vd = static_cast<VRegister>(rd); 930 const VRegister vd = static_cast<VRegister>(rd);
931 EmitSIMDCopyOp(VMOVX, vd, vn, kDoubleWord, 0, sidx); 931 EmitSIMDCopyOp(VMOVX, vd, vn, kDoubleWord, 0, sidx);
932 } 932 }
933 933
934 // Aliases. 934 // Aliases.
935 void mov(Register rd, Register rn) { 935 void mov(Register rd, Register rn) {
936 if ((rd == SP) || (rn == SP)) { 936 if ((rd == CSP) || (rn == CSP)) {
937 add(rd, rn, Operand(0)); 937 add(rd, rn, Operand(0));
938 } else { 938 } else {
939 orr(rd, ZR, Operand(rn)); 939 orr(rd, ZR, Operand(rn));
940 } 940 }
941 } 941 }
942 void vmov(VRegister vd, VRegister vn) { 942 void vmov(VRegister vd, VRegister vn) {
943 vorr(vd, vn, vn); 943 vorr(vd, vn, vn);
944 } 944 }
945 void mvn(Register rd, Register rm) { 945 void mvn(Register rd, Register rm) {
946 orn(rd, ZR, Operand(rm)); 946 orn(rd, ZR, Operand(rm));
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 1279
1280 void AddSubHelper(OperandSize os, bool set_flags, bool subtract, 1280 void AddSubHelper(OperandSize os, bool set_flags, bool subtract,
1281 Register rd, Register rn, Operand o) { 1281 Register rd, Register rn, Operand o) {
1282 ASSERT((rd != R31) && (rn != R31)); 1282 ASSERT((rd != R31) && (rn != R31));
1283 const Register crd = ConcreteRegister(rd); 1283 const Register crd = ConcreteRegister(rd);
1284 const Register crn = ConcreteRegister(rn); 1284 const Register crn = ConcreteRegister(rn);
1285 if (o.type() == Operand::Immediate) { 1285 if (o.type() == Operand::Immediate) {
1286 ASSERT(rn != ZR); 1286 ASSERT(rn != ZR);
1287 EmitAddSubImmOp(subtract ? SUBI : ADDI, crd, crn, o, os, set_flags); 1287 EmitAddSubImmOp(subtract ? SUBI : ADDI, crd, crn, o, os, set_flags);
1288 } else if (o.type() == Operand::Shifted) { 1288 } else if (o.type() == Operand::Shifted) {
1289 ASSERT((rd != SP) && (rn != SP)); 1289 ASSERT((rd != CSP) && (rn != CSP));
1290 EmitAddSubShiftExtOp(subtract ? SUB : ADD, crd, crn, o, os, set_flags); 1290 EmitAddSubShiftExtOp(subtract ? SUB : ADD, crd, crn, o, os, set_flags);
1291 } else { 1291 } else {
1292 ASSERT(o.type() == Operand::Extended); 1292 ASSERT(o.type() == Operand::Extended);
1293 ASSERT((rd != SP) && (rn != ZR)); 1293 ASSERT((rd != CSP) && (rn != ZR));
1294 EmitAddSubShiftExtOp(subtract ? SUB : ADD, crd, crn, o, os, set_flags); 1294 EmitAddSubShiftExtOp(subtract ? SUB : ADD, crd, crn, o, os, set_flags);
1295 } 1295 }
1296 } 1296 }
1297 1297
1298 void EmitAddSubImmOp(AddSubImmOp op, Register rd, Register rn, 1298 void EmitAddSubImmOp(AddSubImmOp op, Register rd, Register rn,
1299 Operand o, OperandSize sz, bool set_flags) { 1299 Operand o, OperandSize sz, bool set_flags) {
1300 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1300 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1301 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1301 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1302 const int32_t s = set_flags ? B29 : 0; 1302 const int32_t s = set_flags ? B29 : 0;
1303 const int32_t encoding = 1303 const int32_t encoding =
1304 op | size | s | 1304 op | size | s |
1305 (static_cast<int32_t>(rd) << kRdShift) | 1305 (static_cast<int32_t>(rd) << kRdShift) |
1306 (static_cast<int32_t>(rn) << kRnShift) | 1306 (static_cast<int32_t>(rn) << kRnShift) |
1307 o.encoding(); 1307 o.encoding();
1308 Emit(encoding); 1308 Emit(encoding);
1309 } 1309 }
1310 1310
1311 void EmitLogicalImmOp(LogicalImmOp op, Register rd, Register rn, 1311 void EmitLogicalImmOp(LogicalImmOp op, Register rd, Register rn,
1312 Operand o, OperandSize sz) { 1312 Operand o, OperandSize sz) {
1313 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1313 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1314 ASSERT((rd != R31) && (rn != R31)); 1314 ASSERT((rd != R31) && (rn != R31));
1315 ASSERT(rn != SP); 1315 ASSERT(rn != CSP);
1316 ASSERT((op == ANDIS) || (rd != ZR)); // op != ANDIS => rd != ZR. 1316 ASSERT((op == ANDIS) || (rd != ZR)); // op != ANDIS => rd != ZR.
1317 ASSERT((op != ANDIS) || (rd != SP)); // op == ANDIS => rd != SP. 1317 ASSERT((op != ANDIS) || (rd != CSP)); // op == ANDIS => rd != CSP.
1318 ASSERT(o.type() == Operand::BitfieldImm); 1318 ASSERT(o.type() == Operand::BitfieldImm);
1319 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1319 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1320 const Register crd = ConcreteRegister(rd); 1320 const Register crd = ConcreteRegister(rd);
1321 const Register crn = ConcreteRegister(rn); 1321 const Register crn = ConcreteRegister(rn);
1322 const int32_t encoding = 1322 const int32_t encoding =
1323 op | size | 1323 op | size |
1324 (static_cast<int32_t>(crd) << kRdShift) | 1324 (static_cast<int32_t>(crd) << kRdShift) |
1325 (static_cast<int32_t>(crn) << kRnShift) | 1325 (static_cast<int32_t>(crn) << kRnShift) |
1326 o.encoding(); 1326 o.encoding();
1327 Emit(encoding); 1327 Emit(encoding);
1328 } 1328 }
1329 1329
1330 void EmitLogicalShiftOp(LogicalShiftOp op, 1330 void EmitLogicalShiftOp(LogicalShiftOp op,
1331 Register rd, Register rn, Operand o, OperandSize sz) { 1331 Register rd, Register rn, Operand o, OperandSize sz) {
1332 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1332 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1333 ASSERT((rd != R31) && (rn != R31)); 1333 ASSERT((rd != R31) && (rn != R31));
1334 ASSERT((rd != SP) && (rn != SP)); 1334 ASSERT((rd != CSP) && (rn != CSP));
1335 ASSERT(o.type() == Operand::Shifted); 1335 ASSERT(o.type() == Operand::Shifted);
1336 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1336 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1337 const Register crd = ConcreteRegister(rd); 1337 const Register crd = ConcreteRegister(rd);
1338 const Register crn = ConcreteRegister(rn); 1338 const Register crn = ConcreteRegister(rn);
1339 const int32_t encoding = 1339 const int32_t encoding =
1340 op | size | 1340 op | size |
1341 (static_cast<int32_t>(crd) << kRdShift) | 1341 (static_cast<int32_t>(crd) << kRdShift) |
1342 (static_cast<int32_t>(crn) << kRnShift) | 1342 (static_cast<int32_t>(crn) << kRnShift) |
1343 o.encoding(); 1343 o.encoding();
1344 Emit(encoding); 1344 Emit(encoding);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 1391
1392 int64_t DecodeImm26BranchOffset(int32_t instr) { 1392 int64_t DecodeImm26BranchOffset(int32_t instr) {
1393 const int32_t off = (((instr & kImm26Mask) >> kImm26Shift) << 6) >> 4; 1393 const int32_t off = (((instr & kImm26Mask) >> kImm26Shift) << 6) >> 4;
1394 return static_cast<int64_t>(off); 1394 return static_cast<int64_t>(off);
1395 } 1395 }
1396 1396
1397 void EmitCompareAndBranch(CompareAndBranchOp op, Register rt, int64_t imm, 1397 void EmitCompareAndBranch(CompareAndBranchOp op, Register rt, int64_t imm,
1398 OperandSize sz) { 1398 OperandSize sz) {
1399 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1399 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1400 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0)); 1400 ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0));
1401 ASSERT((rt != SP) && (rt != R31)); 1401 ASSERT((rt != CSP) && (rt != R31));
1402 const Register crt = ConcreteRegister(rt); 1402 const Register crt = ConcreteRegister(rt);
1403 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1403 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1404 const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0); 1404 const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0);
1405 const int32_t encoding = 1405 const int32_t encoding =
1406 op | size | 1406 op | size |
1407 (static_cast<int32_t>(crt) << kRtShift) | 1407 (static_cast<int32_t>(crt) << kRtShift) |
1408 encoded_offset; 1408 encoded_offset;
1409 Emit(encoding); 1409 Emit(encoding);
1410 } 1410 }
1411 1411
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 } 1456 }
1457 1457
1458 void EmitUnconditionalBranchOp(UnconditionalBranchOp op, int64_t offset) { 1458 void EmitUnconditionalBranchOp(UnconditionalBranchOp op, int64_t offset) {
1459 ASSERT(CanEncodeImm26BranchOffset(offset)); 1459 ASSERT(CanEncodeImm26BranchOffset(offset));
1460 const int32_t off = (offset >> 2) << kImm26Shift; 1460 const int32_t off = (offset >> 2) << kImm26Shift;
1461 const int32_t encoding = op | off; 1461 const int32_t encoding = op | off;
1462 Emit(encoding); 1462 Emit(encoding);
1463 } 1463 }
1464 1464
1465 void EmitUnconditionalBranchRegOp(UnconditionalBranchRegOp op, Register rn) { 1465 void EmitUnconditionalBranchRegOp(UnconditionalBranchRegOp op, Register rn) {
1466 ASSERT((rn != SP) && (rn != R31)); 1466 ASSERT((rn != CSP) && (rn != R31));
1467 const Register crn = ConcreteRegister(rn); 1467 const Register crn = ConcreteRegister(rn);
1468 const int32_t encoding = 1468 const int32_t encoding =
1469 op | (static_cast<int32_t>(crn) << kRnShift); 1469 op | (static_cast<int32_t>(crn) << kRnShift);
1470 Emit(encoding); 1470 Emit(encoding);
1471 } 1471 }
1472 1472
1473 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) { 1473 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) {
1474 const int32_t encoding = 1474 const int32_t encoding =
1475 op | (static_cast<int32_t>(imm) << kImm16Shift); 1475 op | (static_cast<int32_t>(imm) << kImm16Shift);
1476 Emit(encoding); 1476 Emit(encoding);
(...skipping 19 matching lines...) Expand all
1496 const int32_t encoding = 1496 const int32_t encoding =
1497 op | ((size & 0x3) << kSzShift) | 1497 op | ((size & 0x3) << kSzShift) |
1498 (static_cast<int32_t>(crt) << kRtShift) | 1498 (static_cast<int32_t>(crt) << kRtShift) |
1499 a.encoding(); 1499 a.encoding();
1500 Emit(encoding); 1500 Emit(encoding);
1501 } 1501 }
1502 1502
1503 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, 1503 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a,
1504 OperandSize sz) { 1504 OperandSize sz) {
1505 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1505 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1506 ASSERT((rt != SP) && (rt != R31)); 1506 ASSERT((rt != CSP) && (rt != R31));
1507 const Register crt = ConcreteRegister(rt); 1507 const Register crt = ConcreteRegister(rt);
1508 const int32_t size = (sz == kDoubleWord) ? B30 : 0; 1508 const int32_t size = (sz == kDoubleWord) ? B30 : 0;
1509 const int32_t encoding = 1509 const int32_t encoding =
1510 op | size | 1510 op | size |
1511 (static_cast<int32_t>(crt) << kRtShift) | 1511 (static_cast<int32_t>(crt) << kRtShift) |
1512 a.encoding(); 1512 a.encoding();
1513 Emit(encoding); 1513 Emit(encoding);
1514 } 1514 }
1515 1515
1516 void EmitPCRelOp(PCRelOp op, Register rd, int64_t imm) { 1516 void EmitPCRelOp(PCRelOp op, Register rd, int64_t imm) {
1517 ASSERT(Utils::IsInt(21, imm)); 1517 ASSERT(Utils::IsInt(21, imm));
1518 ASSERT((rd != R31) && (rd != SP)); 1518 ASSERT((rd != R31) && (rd != CSP));
1519 const Register crd = ConcreteRegister(rd); 1519 const Register crd = ConcreteRegister(rd);
1520 const int32_t loimm = (imm & 0x3) << 29; 1520 const int32_t loimm = (imm & 0x3) << 29;
1521 const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask; 1521 const int32_t hiimm = ((imm >> 2) << kImm19Shift) & kImm19Mask;
1522 const int32_t encoding = 1522 const int32_t encoding =
1523 op | loimm | hiimm | 1523 op | loimm | hiimm |
1524 (static_cast<int32_t>(crd) << kRdShift); 1524 (static_cast<int32_t>(crd) << kRdShift);
1525 Emit(encoding); 1525 Emit(encoding);
1526 } 1526 }
1527 1527
1528 void EmitMiscDP2Source(MiscDP2SourceOp op, 1528 void EmitMiscDP2Source(MiscDP2SourceOp op,
1529 Register rd, Register rn, Register rm, 1529 Register rd, Register rn, Register rm,
1530 OperandSize sz) { 1530 OperandSize sz) {
1531 ASSERT((rd != SP) && (rn != SP) && (rm != SP)); 1531 ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP));
1532 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1532 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1533 const Register crd = ConcreteRegister(rd); 1533 const Register crd = ConcreteRegister(rd);
1534 const Register crn = ConcreteRegister(rn); 1534 const Register crn = ConcreteRegister(rn);
1535 const Register crm = ConcreteRegister(rm); 1535 const Register crm = ConcreteRegister(rm);
1536 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1536 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1537 const int32_t encoding = 1537 const int32_t encoding =
1538 op | size | 1538 op | size |
1539 (static_cast<int32_t>(crd) << kRdShift) | 1539 (static_cast<int32_t>(crd) << kRdShift) |
1540 (static_cast<int32_t>(crn) << kRnShift) | 1540 (static_cast<int32_t>(crn) << kRnShift) |
1541 (static_cast<int32_t>(crm) << kRmShift); 1541 (static_cast<int32_t>(crm) << kRmShift);
1542 Emit(encoding); 1542 Emit(encoding);
1543 } 1543 }
1544 1544
1545 void EmitMiscDP3Source(MiscDP3SourceOp op, 1545 void EmitMiscDP3Source(MiscDP3SourceOp op,
1546 Register rd, Register rn, Register rm, Register ra, 1546 Register rd, Register rn, Register rm, Register ra,
1547 OperandSize sz) { 1547 OperandSize sz) {
1548 ASSERT((rd != SP) && (rn != SP) && (rm != SP) && (ra != SP)); 1548 ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP) && (ra != CSP));
1549 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1549 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1550 const Register crd = ConcreteRegister(rd); 1550 const Register crd = ConcreteRegister(rd);
1551 const Register crn = ConcreteRegister(rn); 1551 const Register crn = ConcreteRegister(rn);
1552 const Register crm = ConcreteRegister(rm); 1552 const Register crm = ConcreteRegister(rm);
1553 const Register cra = ConcreteRegister(ra); 1553 const Register cra = ConcreteRegister(ra);
1554 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1554 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1555 const int32_t encoding = 1555 const int32_t encoding =
1556 op | size | 1556 op | size |
1557 (static_cast<int32_t>(crd) << kRdShift) | 1557 (static_cast<int32_t>(crd) << kRdShift) |
1558 (static_cast<int32_t>(crn) << kRnShift) | 1558 (static_cast<int32_t>(crn) << kRnShift) |
1559 (static_cast<int32_t>(crm) << kRmShift) | 1559 (static_cast<int32_t>(crm) << kRmShift) |
1560 (static_cast<int32_t>(cra) << kRaShift); 1560 (static_cast<int32_t>(cra) << kRaShift);
1561 Emit(encoding); 1561 Emit(encoding);
1562 } 1562 }
1563 1563
1564 void EmitConditionalSelect(ConditionalSelectOp op, 1564 void EmitConditionalSelect(ConditionalSelectOp op,
1565 Register rd, Register rn, Register rm, 1565 Register rd, Register rn, Register rm,
1566 Condition cond, OperandSize sz) { 1566 Condition cond, OperandSize sz) {
1567 ASSERT((rd != SP) && (rn != SP) && (rm != SP)); 1567 ASSERT((rd != CSP) && (rn != CSP) && (rm != CSP));
1568 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); 1568 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
1569 const Register crd = ConcreteRegister(rd); 1569 const Register crd = ConcreteRegister(rd);
1570 const Register crn = ConcreteRegister(rn); 1570 const Register crn = ConcreteRegister(rn);
1571 const Register crm = ConcreteRegister(rm); 1571 const Register crm = ConcreteRegister(rm);
1572 const int32_t size = (sz == kDoubleWord) ? B31 : 0; 1572 const int32_t size = (sz == kDoubleWord) ? B31 : 0;
1573 const int32_t encoding = 1573 const int32_t encoding =
1574 op | size | 1574 op | size |
1575 (static_cast<int32_t>(crd) << kRdShift) | 1575 (static_cast<int32_t>(crd) << kRdShift) |
1576 (static_cast<int32_t>(crn) << kRnShift) | 1576 (static_cast<int32_t>(crn) << kRnShift) |
1577 (static_cast<int32_t>(crm) << kRmShift) | 1577 (static_cast<int32_t>(crm) << kRmShift) |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1660 Register value, 1660 Register value,
1661 Label* no_update); 1661 Label* no_update);
1662 1662
1663 DISALLOW_ALLOCATION(); 1663 DISALLOW_ALLOCATION();
1664 DISALLOW_COPY_AND_ASSIGN(Assembler); 1664 DISALLOW_COPY_AND_ASSIGN(Assembler);
1665 }; 1665 };
1666 1666
1667 } // namespace dart 1667 } // namespace dart
1668 1668
1669 #endif // VM_ASSEMBLER_ARM64_H_ 1669 #endif // VM_ASSEMBLER_ARM64_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698