| OLD | NEW |
| 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 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 } | 553 } |
| 554 } | 554 } |
| 555 void str(Register rt, Address a, OperandSize sz = kDoubleWord) { | 555 void str(Register rt, Address a, OperandSize sz = kDoubleWord) { |
| 556 EmitLoadStoreReg(STR, rt, a, sz); | 556 EmitLoadStoreReg(STR, rt, a, sz); |
| 557 } | 557 } |
| 558 | 558 |
| 559 // Conditional select. | 559 // Conditional select. |
| 560 void csel(Register rd, Register rn, Register rm, Condition cond) { | 560 void csel(Register rd, Register rn, Register rm, Condition cond) { |
| 561 EmitCoditionalSelect(CSEL, rd, rn, rm, cond, kDoubleWord); | 561 EmitCoditionalSelect(CSEL, rd, rn, rm, cond, kDoubleWord); |
| 562 } | 562 } |
| 563 void csinc(Register rd, Register rn, Register rm, Condition cond) { |
| 564 EmitCoditionalSelect(CSINC, rd, rn, rm, cond, kDoubleWord); |
| 565 } |
| 566 void cinc(Register rd, Register rn, Condition cond) { |
| 567 csinc(rd, rn, rn, InvertCondition(cond)); |
| 568 } |
| 569 void cset(Register rd, Condition cond) { |
| 570 csinc(rd, ZR, ZR, InvertCondition(cond)); |
| 571 } |
| 563 | 572 |
| 564 // Comparison. | 573 // Comparison. |
| 565 // rn cmp o. | 574 // rn cmp o. |
| 566 // For add and sub, to use SP for rn, o must be of type Operand::Extend. | 575 // For add and sub, to use SP for rn, o must be of type Operand::Extend. |
| 567 // For an unmodified rm in this case, use Operand(rm, UXTX, 0); | 576 // For an unmodified rm in this case, use Operand(rm, UXTX, 0); |
| 568 void cmp(Register rn, Operand o) { | 577 void cmp(Register rn, Operand o) { |
| 569 subs(ZR, rn, o); | 578 subs(ZR, rn, o); |
| 570 } | 579 } |
| 571 // rn cmp -o. | 580 // rn cmp -o. |
| 572 void cmn(Register rn, Operand o) { | 581 void cmn(Register rn, Operand o) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 const uint8_t bit30 = (imm64 >> 48) & 0xf; | 625 const uint8_t bit30 = (imm64 >> 48) & 0xf; |
| 617 const uint8_t imm8 = (bit7 << 7) | (bit6 << 6) | (bit54 << 4) | bit30; | 626 const uint8_t imm8 = (bit7 << 7) | (bit6 << 6) | (bit54 << 4) | bit30; |
| 618 const int64_t expimm8 = Instr::VFPExpandImm(imm8); | 627 const int64_t expimm8 = Instr::VFPExpandImm(imm8); |
| 619 if (imm64 != expimm8) { | 628 if (imm64 != expimm8) { |
| 620 return false; | 629 return false; |
| 621 } | 630 } |
| 622 EmitFPImm(FMOVDI, vd, imm8); | 631 EmitFPImm(FMOVDI, vd, imm8); |
| 623 return true; | 632 return true; |
| 624 } | 633 } |
| 625 void fmovdr(VRegister vd, Register rn) { | 634 void fmovdr(VRegister vd, Register rn) { |
| 626 EmitFPIntCvtOp(FMOVDR, static_cast<Register>(vd), rn); | 635 ASSERT(rn != R31); |
| 636 ASSERT(rn != SP); |
| 637 const Register crn = ConcreteRegister(rn); |
| 638 EmitFPIntCvtOp(FMOVDR, static_cast<Register>(vd), crn); |
| 627 } | 639 } |
| 628 void fmovrd(Register rd, VRegister vn) { | 640 void fmovrd(Register rd, VRegister vn) { |
| 629 EmitFPIntCvtOp(FMOVRD, rd, static_cast<Register>(vn)); | 641 ASSERT(rd != R31); |
| 642 ASSERT(rd != SP); |
| 643 const Register crd = ConcreteRegister(rd); |
| 644 EmitFPIntCvtOp(FMOVRD, crd, static_cast<Register>(vn)); |
| 645 } |
| 646 void scvtfd(VRegister vd, Register rn) { |
| 647 ASSERT(rn != R31); |
| 648 ASSERT(rn != SP); |
| 649 const Register crn = ConcreteRegister(rn); |
| 650 EmitFPIntCvtOp(SCVTFD, static_cast<Register>(vd), crn); |
| 651 } |
| 652 void fcvtzds(Register rd, VRegister vn) { |
| 653 ASSERT(rd != R31); |
| 654 ASSERT(rd != SP); |
| 655 const Register crd = ConcreteRegister(rd); |
| 656 EmitFPIntCvtOp(FCVTZDS, crd, static_cast<Register>(vn)); |
| 630 } | 657 } |
| 631 void fmovdd(VRegister vd, VRegister vn) { | 658 void fmovdd(VRegister vd, VRegister vn) { |
| 632 EmitFPOneSourceOp(FMOVDD, vd, vn); | 659 EmitFPOneSourceOp(FMOVDD, vd, vn); |
| 633 } | 660 } |
| 634 | |
| 635 void fldrd(VRegister vt, Address a) { | 661 void fldrd(VRegister vt, Address a) { |
| 636 ASSERT(a.type() != Address::PCOffset); | 662 ASSERT(a.type() != Address::PCOffset); |
| 637 EmitLoadStoreReg(FLDR, static_cast<Register>(vt), a, kDoubleWord); | 663 EmitLoadStoreReg(FLDR, static_cast<Register>(vt), a, kDoubleWord); |
| 638 } | 664 } |
| 639 void fstrd(VRegister vt, Address a) { | 665 void fstrd(VRegister vt, Address a) { |
| 640 ASSERT(a.type() != Address::PCOffset); | 666 ASSERT(a.type() != Address::PCOffset); |
| 641 EmitLoadStoreReg(FSTR, static_cast<Register>(vt), a, kDoubleWord); | 667 EmitLoadStoreReg(FSTR, static_cast<Register>(vt), a, kDoubleWord); |
| 642 } | 668 } |
| 669 void fcmpd(VRegister vn, VRegister vm) { |
| 670 EmitFPCompareOp(FCMPD, vn, vm); |
| 671 } |
| 672 void fcmpzd(VRegister vn) { |
| 673 EmitFPCompareOp(FCMPZD, vn, V0); |
| 674 } |
| 675 void fmuld(VRegister vd, VRegister vn, VRegister vm) { |
| 676 EmitFPTwoSourceOp(FMULD, vd, vn, vm); |
| 677 } |
| 678 void fdivd(VRegister vd, VRegister vn, VRegister vm) { |
| 679 EmitFPTwoSourceOp(FDIVD, vd, vn, vm); |
| 680 } |
| 681 void faddd(VRegister vd, VRegister vn, VRegister vm) { |
| 682 EmitFPTwoSourceOp(FADDD, vd, vn, vm); |
| 683 } |
| 684 void fsubd(VRegister vd, VRegister vn, VRegister vm) { |
| 685 EmitFPTwoSourceOp(FSUBD, vd, vn, vm); |
| 686 } |
| 643 | 687 |
| 644 // Aliases. | 688 // Aliases. |
| 645 void mov(Register rd, Register rn) { | 689 void mov(Register rd, Register rn) { |
| 646 if ((rd == SP) || (rn == SP)) { | 690 if ((rd == SP) || (rn == SP)) { |
| 647 add(rd, rn, Operand(0)); | 691 add(rd, rn, Operand(0)); |
| 648 } else { | 692 } else { |
| 649 orr(rd, ZR, Operand(rn)); | 693 orr(rd, ZR, Operand(rn)); |
| 650 } | 694 } |
| 651 } | 695 } |
| 652 void mvn(Register rd, Register rm) { | 696 void mvn(Register rd, Register rm) { |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1195 void EmitFPIntCvtOp(FPIntCvtOp op, Register rd, Register rn) { | 1239 void EmitFPIntCvtOp(FPIntCvtOp op, Register rd, Register rn) { |
| 1196 const int32_t encoding = | 1240 const int32_t encoding = |
| 1197 op | | 1241 op | |
| 1198 (static_cast<int32_t>(rd) << kRdShift) | | 1242 (static_cast<int32_t>(rd) << kRdShift) | |
| 1199 (static_cast<int32_t>(rn) << kRnShift); | 1243 (static_cast<int32_t>(rn) << kRnShift); |
| 1200 Emit(encoding); | 1244 Emit(encoding); |
| 1201 } | 1245 } |
| 1202 | 1246 |
| 1203 void EmitFPOneSourceOp(FPOneSourceOp op, VRegister vd, VRegister vn) { | 1247 void EmitFPOneSourceOp(FPOneSourceOp op, VRegister vd, VRegister vn) { |
| 1204 const int32_t encoding = | 1248 const int32_t encoding = |
| 1205 op | | 1249 op | |
| 1206 (static_cast<int32_t>(vd) << kVdShift) | | 1250 (static_cast<int32_t>(vd) << kVdShift) | |
| 1207 (static_cast<int32_t>(vn) << kVnShift); | 1251 (static_cast<int32_t>(vn) << kVnShift); |
| 1252 Emit(encoding); |
| 1253 } |
| 1254 |
| 1255 void EmitFPTwoSourceOp(FPTwoSourceOp op, |
| 1256 VRegister vd, VRegister vn, VRegister vm) { |
| 1257 const int32_t encoding = |
| 1258 op | |
| 1259 (static_cast<int32_t>(vd) << kVdShift) | |
| 1260 (static_cast<int32_t>(vn) << kVnShift) | |
| 1261 (static_cast<int32_t>(vm) << kVmShift); |
| 1262 Emit(encoding); |
| 1263 } |
| 1264 |
| 1265 void EmitFPCompareOp(FPCompareOp op, VRegister vn, VRegister vm) { |
| 1266 const int32_t encoding = |
| 1267 op | |
| 1268 (static_cast<int32_t>(vn) << kVnShift) | |
| 1269 (static_cast<int32_t>(vm) << kVmShift); |
| 1208 Emit(encoding); | 1270 Emit(encoding); |
| 1209 } | 1271 } |
| 1210 | 1272 |
| 1211 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); | 1273 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); |
| 1212 | 1274 |
| 1213 // Shorter filtering sequence that assumes that value is not a smi. | 1275 // Shorter filtering sequence that assumes that value is not a smi. |
| 1214 void StoreIntoObjectFilterNoSmi(Register object, | 1276 void StoreIntoObjectFilterNoSmi(Register object, |
| 1215 Register value, | 1277 Register value, |
| 1216 Label* no_update); | 1278 Label* no_update); |
| 1217 | 1279 |
| 1218 DISALLOW_ALLOCATION(); | 1280 DISALLOW_ALLOCATION(); |
| 1219 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1281 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1220 }; | 1282 }; |
| 1221 | 1283 |
| 1222 } // namespace dart | 1284 } // namespace dart |
| 1223 | 1285 |
| 1224 #endif // VM_ASSEMBLER_ARM64_H_ | 1286 #endif // VM_ASSEMBLER_ARM64_H_ |
| OLD | NEW |