Chromium Code Reviews| 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 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 435 void subs(Register rd, Register rn, Operand o) { | 435 void subs(Register rd, Register rn, Operand o) { |
| 436 AddSubHelper(kDoubleWord, true, true, rd, rn, o); | 436 AddSubHelper(kDoubleWord, true, true, rd, rn, o); |
| 437 } | 437 } |
| 438 | 438 |
| 439 // PC relative immediate add. imm is in bytes. | 439 // PC relative immediate add. imm is in bytes. |
| 440 void adr(Register rd, int64_t imm) { | 440 void adr(Register rd, int64_t imm) { |
| 441 EmitPCRelOp(ADR, rd, imm); | 441 EmitPCRelOp(ADR, rd, imm); |
| 442 } | 442 } |
| 443 | 443 |
| 444 // Logical immediate operations. | 444 // Logical immediate operations. |
| 445 // TODO(zra): Add macros that check IsImmLogical, and fall back on a longer | |
| 446 // sequence on failure. | |
| 447 void andi(Register rd, Register rn, uint64_t imm) { | 445 void andi(Register rd, Register rn, uint64_t imm) { |
| 448 Operand imm_op; | 446 Operand imm_op; |
| 449 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); | 447 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); |
| 450 ASSERT(immok); | 448 ASSERT(immok); |
| 451 EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord); | 449 EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord); |
| 452 } | 450 } |
| 453 void orri(Register rd, Register rn, uint64_t imm) { | 451 void orri(Register rd, Register rn, uint64_t imm) { |
| 454 Operand imm_op; | 452 Operand imm_op; |
| 455 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); | 453 const bool immok = Operand::IsImmLogical(imm, kXRegSizeInBits, &imm_op); |
| 456 ASSERT(immok); | 454 ASSERT(immok); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 727 EmitFPTwoSourceOp(FDIVD, vd, vn, vm); | 725 EmitFPTwoSourceOp(FDIVD, vd, vn, vm); |
| 728 } | 726 } |
| 729 void faddd(VRegister vd, VRegister vn, VRegister vm) { | 727 void faddd(VRegister vd, VRegister vn, VRegister vm) { |
| 730 EmitFPTwoSourceOp(FADDD, vd, vn, vm); | 728 EmitFPTwoSourceOp(FADDD, vd, vn, vm); |
| 731 } | 729 } |
| 732 void fsubd(VRegister vd, VRegister vn, VRegister vm) { | 730 void fsubd(VRegister vd, VRegister vn, VRegister vm) { |
| 733 EmitFPTwoSourceOp(FSUBD, vd, vn, vm); | 731 EmitFPTwoSourceOp(FSUBD, vd, vn, vm); |
| 734 } | 732 } |
| 735 | 733 |
| 736 // SIMD operations. | 734 // SIMD operations. |
| 735 void vand(VRegister vd, VRegister vn, VRegister vm) { | |
| 736 EmitSIMDThreeSameOp(VAND, vd, vn, vm); | |
| 737 } | |
| 738 void vorr(VRegister vd, VRegister vn, VRegister vm) { | |
| 739 EmitSIMDThreeSameOp(VORR, vd, vn, vm); | |
| 740 } | |
| 741 void veor(VRegister vd, VRegister vn, VRegister vm) { | |
| 742 EmitSIMDThreeSameOp(VEOR, vd, vn, vm); | |
| 743 } | |
| 744 void vaddw(VRegister vd, VRegister vn, VRegister vm) { | |
| 745 EmitSIMDThreeSameOp(VADDW, vd, vn, vm); | |
| 746 } | |
| 747 void vaddx(VRegister vd, VRegister vn, VRegister vm) { | |
| 748 EmitSIMDThreeSameOp(VADDX, vd, vn, vm); | |
| 749 } | |
| 750 void vsubw(VRegister vd, VRegister vn, VRegister vm) { | |
| 751 EmitSIMDThreeSameOp(VSUBW, vd, vn, vm); | |
| 752 } | |
| 753 void vsubx(VRegister vd, VRegister vn, VRegister vm) { | |
| 754 EmitSIMDThreeSameOp(VSUBX, vd, vn, vm); | |
| 755 } | |
| 737 void vadds(VRegister vd, VRegister vn, VRegister vm) { | 756 void vadds(VRegister vd, VRegister vn, VRegister vm) { |
| 738 EmitSIMDThreeSameOp(VADDS, vd, vn, vm); | 757 EmitSIMDThreeSameOp(VADDS, vd, vn, vm); |
| 739 } | 758 } |
| 740 void vaddd(VRegister vd, VRegister vn, VRegister vm) { | 759 void vaddd(VRegister vd, VRegister vn, VRegister vm) { |
| 741 EmitSIMDThreeSameOp(VADDD, vd, vn, vm); | 760 EmitSIMDThreeSameOp(VADDD, vd, vn, vm); |
| 742 } | 761 } |
| 743 void vsubs(VRegister vd, VRegister vn, VRegister vm) { | 762 void vsubs(VRegister vd, VRegister vn, VRegister vm) { |
| 744 EmitSIMDThreeSameOp(VSUBS, vd, vn, vm); | 763 EmitSIMDThreeSameOp(VSUBS, vd, vn, vm); |
| 745 } | 764 } |
| 746 void vsubd(VRegister vd, VRegister vn, VRegister vm) { | 765 void vsubd(VRegister vd, VRegister vn, VRegister vm) { |
| 747 EmitSIMDThreeSameOp(VSUBD, vd, vn, vm); | 766 EmitSIMDThreeSameOp(VSUBD, vd, vn, vm); |
| 748 } | 767 } |
| 749 void vmuls(VRegister vd, VRegister vn, VRegister vm) { | 768 void vmuls(VRegister vd, VRegister vn, VRegister vm) { |
| 750 EmitSIMDThreeSameOp(VMULS, vd, vn, vm); | 769 EmitSIMDThreeSameOp(VMULS, vd, vn, vm); |
| 751 } | 770 } |
| 752 void vmuld(VRegister vd, VRegister vn, VRegister vm) { | 771 void vmuld(VRegister vd, VRegister vn, VRegister vm) { |
| 753 EmitSIMDThreeSameOp(VMULD, vd, vn, vm); | 772 EmitSIMDThreeSameOp(VMULD, vd, vn, vm); |
| 754 } | 773 } |
| 755 void vdivs(VRegister vd, VRegister vn, VRegister vm) { | 774 void vdivs(VRegister vd, VRegister vn, VRegister vm) { |
| 756 EmitSIMDThreeSameOp(VDIVS, vd, vn, vm); | 775 EmitSIMDThreeSameOp(VDIVS, vd, vn, vm); |
| 757 } | 776 } |
| 758 void vdivd(VRegister vd, VRegister vn, VRegister vm) { | 777 void vdivd(VRegister vd, VRegister vn, VRegister vm) { |
| 759 EmitSIMDThreeSameOp(VDIVD, vd, vn, vm); | 778 EmitSIMDThreeSameOp(VDIVD, vd, vn, vm); |
| 760 } | 779 } |
| 780 void vnot(VRegister vd, VRegister vn) { | |
| 781 EmitSIMDTwoRegOp(VNOT, vd, vn); | |
| 782 } | |
| 783 void vabss(VRegister vd, VRegister vn) { | |
| 784 EmitSIMDTwoRegOp(VABSS, vd, vn); | |
| 785 } | |
| 786 void vabsd(VRegister vd, VRegister vn) { | |
| 787 EmitSIMDTwoRegOp(VABSD, vd, vn); | |
| 788 } | |
| 789 void vnegs(VRegister vd, VRegister vn) { | |
| 790 EmitSIMDTwoRegOp(VNEGS, vd, vn); | |
| 791 } | |
| 792 void vnegd(VRegister vd, VRegister vn) { | |
| 793 EmitSIMDTwoRegOp(VNEGD, vd, vn); | |
| 794 } | |
| 795 void vdupw(VRegister vd, Register rn) { | |
| 796 const VRegister vn = static_cast<VRegister>(rn); | |
| 797 EmitSIMDCopyOp(VDUPI, vd, vn, kWord, 0, 0); | |
| 798 } | |
| 799 void vdupx(VRegister vd, Register rn) { | |
| 800 const VRegister vn = static_cast<VRegister>(rn); | |
| 801 EmitSIMDCopyOp(VDUPI, vd, vn, kDoubleWord, 0, 0); | |
| 802 } | |
| 761 void vdups(VRegister vd, VRegister vn, int32_t idx) { | 803 void vdups(VRegister vd, VRegister vn, int32_t idx) { |
| 762 EmitSIMDCopyOp(VDUP, vd, vn, kSWord, 0, idx); | 804 EmitSIMDCopyOp(VDUP, vd, vn, kSWord, 0, idx); |
| 763 } | 805 } |
| 764 void vdupd(VRegister vd, VRegister vn, int32_t idx) { | 806 void vdupd(VRegister vd, VRegister vn, int32_t idx) { |
| 765 EmitSIMDCopyOp(VDUP, vd, vn, kDWord, 0, idx); | 807 EmitSIMDCopyOp(VDUP, vd, vn, kDWord, 0, idx); |
| 766 } | 808 } |
| 809 void vinsw(VRegister vd, int32_t didx, Register rn) { | |
| 810 const VRegister vn = static_cast<VRegister>(rn); | |
| 811 EmitSIMDCopyOp(VINSI, vd, vn, kWord, 0, didx); | |
| 812 } | |
| 813 void vinsx(VRegister vd, int32_t didx, Register rn) { | |
| 814 const VRegister vn = static_cast<VRegister>(rn); | |
| 815 EmitSIMDCopyOp(VINSI, vd, vn, kDoubleWord, 0, didx); | |
| 816 } | |
| 767 void vinss(VRegister vd, int32_t didx, VRegister vn, int32_t sidx) { | 817 void vinss(VRegister vd, int32_t didx, VRegister vn, int32_t sidx) { |
| 768 EmitSIMDCopyOp(VINS, vd, vn, kSWord, sidx, didx); | 818 EmitSIMDCopyOp(VINS, vd, vn, kSWord, sidx, didx); |
| 769 } | 819 } |
| 770 void vinsd(VRegister vd, int32_t didx, VRegister vn, int32_t sidx) { | 820 void vinsd(VRegister vd, int32_t didx, VRegister vn, int32_t sidx) { |
| 771 EmitSIMDCopyOp(VINS, vd, vn, kDWord, sidx, didx); | 821 EmitSIMDCopyOp(VINS, vd, vn, kDWord, sidx, didx); |
| 772 } | 822 } |
| 823 void vmovrs(Register rd, VRegister vn, int32_t sidx) { | |
| 824 const VRegister vd = static_cast<VRegister>(rd); | |
| 825 EmitSIMDCopyOp(VMOVW, vd, vn, kWord, 0, sidx); | |
| 826 } | |
| 827 void vmovrd(Register rd, VRegister vn, int32_t sidx) { | |
| 828 const VRegister vd = static_cast<VRegister>(rd); | |
| 829 EmitSIMDCopyOp(VMOVX, vd, vn, kDoubleWord, 0, sidx); | |
| 830 } | |
| 773 | 831 |
| 774 // Aliases. | 832 // Aliases. |
| 775 void mov(Register rd, Register rn) { | 833 void mov(Register rd, Register rn) { |
| 776 if ((rd == SP) || (rn == SP)) { | 834 if ((rd == SP) || (rn == SP)) { |
| 777 add(rd, rn, Operand(0)); | 835 add(rd, rn, Operand(0)); |
| 778 } else { | 836 } else { |
| 779 orr(rd, ZR, Operand(rn)); | 837 orr(rd, ZR, Operand(rn)); |
| 780 } | 838 } |
| 781 } | 839 } |
| 840 void vmov(VRegister vd, VRegister vn) { | |
| 841 vorr(vd, vn, vn); | |
| 842 } | |
| 782 void mvn(Register rd, Register rm) { | 843 void mvn(Register rd, Register rm) { |
| 783 orn(rd, ZR, Operand(rm)); | 844 orn(rd, ZR, Operand(rm)); |
| 784 } | 845 } |
| 785 void neg(Register rd, Register rm) { | 846 void neg(Register rd, Register rm) { |
| 786 sub(rd, ZR, Operand(rm)); | 847 sub(rd, ZR, Operand(rm)); |
| 787 } | 848 } |
| 788 void negs(Register rd, Register rm) { | 849 void negs(Register rd, Register rm) { |
| 789 subs(rd, ZR, Operand(rm)); | 850 subs(rd, ZR, Operand(rm)); |
| 790 } | 851 } |
| 791 void mul(Register rd, Register rn, Register rm) { | 852 void mul(Register rd, Register rn, Register rm) { |
| 792 madd(rd, rn, rm, ZR); | 853 madd(rd, rn, rm, ZR); |
| 793 } | 854 } |
| 794 void Push(Register reg) { | 855 void Push(Register reg) { |
| 795 ASSERT(reg != PP); // Only push PP with TagAndPushPP(). | 856 ASSERT(reg != PP); // Only push PP with TagAndPushPP(). |
| 796 str(reg, Address(SP, -1 * kWordSize, Address::PreIndex)); | 857 str(reg, Address(SP, -1 * kWordSize, Address::PreIndex)); |
| 797 } | 858 } |
| 798 void Pop(Register reg) { | 859 void Pop(Register reg) { |
| 799 ASSERT(reg != PP); // Only pop PP with PopAndUntagPP(). | 860 ASSERT(reg != PP); // Only pop PP with PopAndUntagPP(). |
| 800 ldr(reg, Address(SP, 1 * kWordSize, Address::PostIndex)); | 861 ldr(reg, Address(SP, 1 * kWordSize, Address::PostIndex)); |
| 801 } | 862 } |
| 863 void PushFloat(VRegister reg) { | |
| 864 const int sword_bytes = 1 << Log2OperandSizeBytes(kSWord); | |
| 865 fstrs(reg, Address(SP, -1 * sword_bytes, Address::PreIndex)); | |
|
regis
2014/05/23 19:50:24
Use kFloatSize
zra
2014/05/23 20:12:58
Done.
| |
| 866 } | |
| 802 void PushDouble(VRegister reg) { | 867 void PushDouble(VRegister reg) { |
| 803 fstrd(reg, Address(SP, -1 * kWordSize, Address::PreIndex)); | 868 const int dword_bytes = 1 << Log2OperandSizeBytes(kDWord); |
| 869 fstrd(reg, Address(SP, -1 * dword_bytes, Address::PreIndex)); | |
|
regis
2014/05/23 19:50:24
Use kDoubleSize
zra
2014/05/23 20:12:58
Done.
| |
| 870 } | |
| 871 void PushQuad(VRegister reg) { | |
| 872 const int qword_bytes = 1 << Log2OperandSizeBytes(kQWord); | |
| 873 fstrq(reg, Address(SP, -1 * qword_bytes, Address::PreIndex)); | |
|
regis
2014/05/23 19:50:24
Define a kQuadSize in globals.h
zra
2014/05/23 20:12:58
Done.
| |
| 874 } | |
| 875 void PopFloat(VRegister reg) { | |
| 876 const int sword_bytes = 1 << Log2OperandSizeBytes(kSWord); | |
| 877 fldrs(reg, Address(SP, 1 * sword_bytes, Address::PostIndex)); | |
|
regis
2014/05/23 19:50:24
ditto
zra
2014/05/23 20:12:58
Done.
| |
| 804 } | 878 } |
| 805 void PopDouble(VRegister reg) { | 879 void PopDouble(VRegister reg) { |
| 806 fldrd(reg, Address(SP, 1 * kWordSize, Address::PostIndex)); | 880 const int dword_bytes = 1 << Log2OperandSizeBytes(kDWord); |
| 881 fldrd(reg, Address(SP, 1 * dword_bytes, Address::PostIndex)); | |
|
regis
2014/05/23 19:50:24
ditto
zra
2014/05/23 20:12:58
Done.
| |
| 882 } | |
| 883 void PopQuad(VRegister reg) { | |
| 884 const int qword_bytes = 1 << Log2OperandSizeBytes(kQWord); | |
| 885 fldrq(reg, Address(SP, 1 * qword_bytes, Address::PostIndex)); | |
|
regis
2014/05/23 19:50:24
ditto
zra
2014/05/23 20:12:58
Done.
| |
| 807 } | 886 } |
| 808 void TagAndPushPP() { | 887 void TagAndPushPP() { |
| 809 // Add the heap object tag back to PP before putting it on the stack. | 888 // Add the heap object tag back to PP before putting it on the stack. |
| 810 add(TMP, PP, Operand(kHeapObjectTag)); | 889 add(TMP, PP, Operand(kHeapObjectTag)); |
| 811 str(TMP, Address(SP, -1 * kWordSize, Address::PreIndex)); | 890 str(TMP, Address(SP, -1 * kWordSize, Address::PreIndex)); |
| 812 } | 891 } |
| 813 void PopAndUntagPP() { | 892 void PopAndUntagPP() { |
| 814 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex)); | 893 ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex)); |
| 815 sub(PP, PP, Operand(kHeapObjectTag)); | 894 sub(PP, PP, Operand(kHeapObjectTag)); |
| 816 } | 895 } |
| (...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1457 const int32_t imm4 = (idx4 << shift) & 0xf; | 1536 const int32_t imm4 = (idx4 << shift) & 0xf; |
| 1458 const int32_t encoding = | 1537 const int32_t encoding = |
| 1459 op | | 1538 op | |
| 1460 (imm5 << kImm5Shift) | | 1539 (imm5 << kImm5Shift) | |
| 1461 (imm4 << kImm4Shift) | | 1540 (imm4 << kImm4Shift) | |
| 1462 (static_cast<int32_t>(vd) << kVdShift) | | 1541 (static_cast<int32_t>(vd) << kVdShift) | |
| 1463 (static_cast<int32_t>(vn) << kVnShift); | 1542 (static_cast<int32_t>(vn) << kVnShift); |
| 1464 Emit(encoding); | 1543 Emit(encoding); |
| 1465 } | 1544 } |
| 1466 | 1545 |
| 1546 void EmitSIMDTwoRegOp(SIMDTwoRegOp op, VRegister vd, VRegister vn) { | |
| 1547 const int32_t encoding = | |
| 1548 op | | |
| 1549 (static_cast<int32_t>(vd) << kVdShift) | | |
| 1550 (static_cast<int32_t>(vn) << kVnShift); | |
| 1551 Emit(encoding); | |
| 1552 } | |
| 1553 | |
| 1467 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); | 1554 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); |
| 1468 | 1555 |
| 1469 // Shorter filtering sequence that assumes that value is not a smi. | 1556 // Shorter filtering sequence that assumes that value is not a smi. |
| 1470 void StoreIntoObjectFilterNoSmi(Register object, | 1557 void StoreIntoObjectFilterNoSmi(Register object, |
| 1471 Register value, | 1558 Register value, |
| 1472 Label* no_update); | 1559 Label* no_update); |
| 1473 | 1560 |
| 1474 DISALLOW_ALLOCATION(); | 1561 DISALLOW_ALLOCATION(); |
| 1475 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1562 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1476 }; | 1563 }; |
| 1477 | 1564 |
| 1478 } // namespace dart | 1565 } // namespace dart |
| 1479 | 1566 |
| 1480 #endif // VM_ASSEMBLER_ARM64_H_ | 1567 #endif // VM_ASSEMBLER_ARM64_H_ |
| OLD | NEW |