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