| 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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 if (a.type() == Address::PCOffset) { | 542 if (a.type() == Address::PCOffset) { |
| 543 ASSERT(sz == kDoubleWord); | 543 ASSERT(sz == kDoubleWord); |
| 544 EmitLoadRegLiteral(LDRpc, rt, a, sz); | 544 EmitLoadRegLiteral(LDRpc, rt, a, sz); |
| 545 } else { | 545 } else { |
| 546 // If we are doing pre-/post-indexing, and the base and result registers | 546 // If we are doing pre-/post-indexing, and the base and result registers |
| 547 // are the same, then the result of the load will be clobbered by the | 547 // are the same, then the result of the load will be clobbered by the |
| 548 // writeback, which is unlikely to be useful. | 548 // writeback, which is unlikely to be useful. |
| 549 ASSERT(((a.type() != Address::PreIndex) && | 549 ASSERT(((a.type() != Address::PreIndex) && |
| 550 (a.type() != Address::PostIndex)) || | 550 (a.type() != Address::PostIndex)) || |
| 551 (rt != a.base())); | 551 (rt != a.base())); |
| 552 EmitLoadStoreReg(LDR, rt, a, sz); | 552 if (IsSignedOperand(sz)) { |
| 553 EmitLoadStoreReg(LDRS, rt, a, sz); |
| 554 } else { |
| 555 EmitLoadStoreReg(LDR, rt, a, sz); |
| 556 } |
| 553 } | 557 } |
| 554 } | 558 } |
| 555 void str(Register rt, Address a, OperandSize sz = kDoubleWord) { | 559 void str(Register rt, Address a, OperandSize sz = kDoubleWord) { |
| 556 EmitLoadStoreReg(STR, rt, a, sz); | 560 EmitLoadStoreReg(STR, rt, a, sz); |
| 557 } | 561 } |
| 558 | 562 |
| 559 // Conditional select. | 563 // Conditional select. |
| 560 void csel(Register rd, Register rn, Register rm, Condition cond) { | 564 void csel(Register rd, Register rn, Register rm, Condition cond) { |
| 561 EmitCoditionalSelect(CSEL, rd, rn, rm, cond, kDoubleWord); | 565 EmitCoditionalSelect(CSEL, rd, rn, rm, cond, kDoubleWord); |
| 562 } | 566 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 } | 664 } |
| 661 void fabsd(VRegister vd, VRegister vn) { | 665 void fabsd(VRegister vd, VRegister vn) { |
| 662 EmitFPOneSourceOp(FABSD, vd, vn); | 666 EmitFPOneSourceOp(FABSD, vd, vn); |
| 663 } | 667 } |
| 664 void fnegd(VRegister vd, VRegister vn) { | 668 void fnegd(VRegister vd, VRegister vn) { |
| 665 EmitFPOneSourceOp(FNEGD, vd, vn); | 669 EmitFPOneSourceOp(FNEGD, vd, vn); |
| 666 } | 670 } |
| 667 void fsqrtd(VRegister vd, VRegister vn) { | 671 void fsqrtd(VRegister vd, VRegister vn) { |
| 668 EmitFPOneSourceOp(FSQRTD, vd, vn); | 672 EmitFPOneSourceOp(FSQRTD, vd, vn); |
| 669 } | 673 } |
| 674 void fcvtsd(VRegister vd, VRegister vn) { |
| 675 EmitFPOneSourceOp(FCVTSD, vd, vn); |
| 676 } |
| 677 void fcvtds(VRegister vd, VRegister vn) { |
| 678 EmitFPOneSourceOp(FCVTDS, vd, vn); |
| 679 } |
| 680 void fldrq(VRegister vt, Address a) { |
| 681 ASSERT(a.type() != Address::PCOffset); |
| 682 EmitLoadStoreReg(FLDRQ, static_cast<Register>(vt), a, kByte); |
| 683 } |
| 684 void fstrq(VRegister vt, Address a) { |
| 685 ASSERT(a.type() != Address::PCOffset); |
| 686 EmitLoadStoreReg(FSTRQ, static_cast<Register>(vt), a, kByte); |
| 687 } |
| 670 void fldrd(VRegister vt, Address a) { | 688 void fldrd(VRegister vt, Address a) { |
| 671 ASSERT(a.type() != Address::PCOffset); | 689 ASSERT(a.type() != Address::PCOffset); |
| 672 EmitLoadStoreReg(FLDR, static_cast<Register>(vt), a, kDoubleWord); | 690 EmitLoadStoreReg(FLDR, static_cast<Register>(vt), a, kDWord); |
| 673 } | 691 } |
| 674 void fstrd(VRegister vt, Address a) { | 692 void fstrd(VRegister vt, Address a) { |
| 675 ASSERT(a.type() != Address::PCOffset); | 693 ASSERT(a.type() != Address::PCOffset); |
| 676 EmitLoadStoreReg(FSTR, static_cast<Register>(vt), a, kDoubleWord); | 694 EmitLoadStoreReg(FSTR, static_cast<Register>(vt), a, kDWord); |
| 695 } |
| 696 void fldrs(VRegister vt, Address a) { |
| 697 ASSERT(a.type() != Address::PCOffset); |
| 698 EmitLoadStoreReg(FLDR, static_cast<Register>(vt), a, kSWord); |
| 699 } |
| 700 void fstrs(VRegister vt, Address a) { |
| 701 ASSERT(a.type() != Address::PCOffset); |
| 702 EmitLoadStoreReg(FSTR, static_cast<Register>(vt), a, kSWord); |
| 677 } | 703 } |
| 678 void fcmpd(VRegister vn, VRegister vm) { | 704 void fcmpd(VRegister vn, VRegister vm) { |
| 679 EmitFPCompareOp(FCMPD, vn, vm); | 705 EmitFPCompareOp(FCMPD, vn, vm); |
| 680 } | 706 } |
| 681 void fcmpzd(VRegister vn) { | 707 void fcmpdz(VRegister vn) { |
| 682 EmitFPCompareOp(FCMPZD, vn, V0); | 708 EmitFPCompareOp(FCMPZD, vn, V0); |
| 683 } | 709 } |
| 684 void fmuld(VRegister vd, VRegister vn, VRegister vm) { | 710 void fmuld(VRegister vd, VRegister vn, VRegister vm) { |
| 685 EmitFPTwoSourceOp(FMULD, vd, vn, vm); | 711 EmitFPTwoSourceOp(FMULD, vd, vn, vm); |
| 686 } | 712 } |
| 687 void fdivd(VRegister vd, VRegister vn, VRegister vm) { | 713 void fdivd(VRegister vd, VRegister vn, VRegister vm) { |
| 688 EmitFPTwoSourceOp(FDIVD, vd, vn, vm); | 714 EmitFPTwoSourceOp(FDIVD, vd, vn, vm); |
| 689 } | 715 } |
| 690 void faddd(VRegister vd, VRegister vn, VRegister vm) { | 716 void faddd(VRegister vd, VRegister vn, VRegister vm) { |
| 691 EmitFPTwoSourceOp(FADDD, vd, vn, vm); | 717 EmitFPTwoSourceOp(FADDD, vd, vn, vm); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 void AddImmediate(Register dest, Register rn, int64_t imm, Register pp); | 826 void AddImmediate(Register dest, Register rn, int64_t imm, Register pp); |
| 801 void AddImmediateSetFlags( | 827 void AddImmediateSetFlags( |
| 802 Register dest, Register rn, int64_t imm, Register pp); | 828 Register dest, Register rn, int64_t imm, Register pp); |
| 803 void AndImmediate(Register rd, Register rn, int64_t imm, Register pp); | 829 void AndImmediate(Register rd, Register rn, int64_t imm, Register pp); |
| 804 void OrImmediate(Register rd, Register rn, int64_t imm, Register pp); | 830 void OrImmediate(Register rd, Register rn, int64_t imm, Register pp); |
| 805 void XorImmediate(Register rd, Register rn, int64_t imm, Register pp); | 831 void XorImmediate(Register rd, Register rn, int64_t imm, Register pp); |
| 806 void TestImmediate(Register rn, int64_t imm, Register pp); | 832 void TestImmediate(Register rn, int64_t imm, Register pp); |
| 807 void CompareImmediate(Register rn, int64_t imm, Register pp); | 833 void CompareImmediate(Register rn, int64_t imm, Register pp); |
| 808 | 834 |
| 809 void LoadFromOffset(Register dest, Register base, int32_t offset, | 835 void LoadFromOffset(Register dest, Register base, int32_t offset, |
| 810 OperandSize sz = kDoubleWord); | 836 Register pp, OperandSize sz = kDoubleWord); |
| 811 void LoadFieldFromOffset(Register dest, Register base, int32_t offset) { | 837 void LoadFieldFromOffset( |
| 812 LoadFromOffset(dest, base, offset - kHeapObjectTag); | 838 Register dest, Register base, int32_t offset, Register pp) { |
| 839 LoadFromOffset(dest, base, offset - kHeapObjectTag, pp); |
| 813 } | 840 } |
| 814 void LoadDFromOffset(VRegister dest, Register base, int32_t offset); | 841 void LoadDFromOffset( |
| 815 void LoadDFieldFromOffset(VRegister dest, Register base, int32_t offset) { | 842 VRegister dest, Register base, int32_t offset, Register pp); |
| 816 LoadDFromOffset(dest, base, offset - kHeapObjectTag); | 843 void LoadDFieldFromOffset( |
| 844 VRegister dest, Register base, int32_t offset, Register pp) { |
| 845 LoadDFromOffset(dest, base, offset - kHeapObjectTag, pp); |
| 846 } |
| 847 void LoadQFromOffset( |
| 848 VRegister dest, Register base, int32_t offset, Register pp); |
| 849 void LoadQFieldFromOffset( |
| 850 VRegister dest, Register base, int32_t offset, Register pp) { |
| 851 LoadQFromOffset(dest, base, offset - kHeapObjectTag, pp); |
| 817 } | 852 } |
| 818 | 853 |
| 819 void StoreToOffset(Register src, Register base, int32_t offset, | 854 void StoreToOffset(Register src, Register base, int32_t offset, |
| 820 OperandSize sz = kDoubleWord); | 855 Register pp, OperandSize sz = kDoubleWord); |
| 821 void StoreFieldToOffset(Register src, Register base, int32_t offset) { | 856 void StoreFieldToOffset( |
| 822 StoreToOffset(src, base, offset - kHeapObjectTag); | 857 Register src, Register base, int32_t offset, Register pp) { |
| 858 StoreToOffset(src, base, offset - kHeapObjectTag, pp); |
| 823 } | 859 } |
| 824 void StoreDToOffset(VRegister src, Register base, int32_t offset); | 860 void StoreDToOffset( |
| 825 void StoreDFieldToOffset(VRegister src, Register base, int32_t offset) { | 861 VRegister src, Register base, int32_t offset, Register pp); |
| 826 StoreDToOffset(src, base, offset - kHeapObjectTag); | 862 void StoreDFieldToOffset( |
| 863 VRegister src, Register base, int32_t offset, Register pp) { |
| 864 StoreDToOffset(src, base, offset - kHeapObjectTag, pp); |
| 865 } |
| 866 void StoreQToOffset( |
| 867 VRegister src, Register base, int32_t offset, Register pp); |
| 868 void StoreQFieldToOffset( |
| 869 VRegister src, Register base, int32_t offset, Register pp) { |
| 870 StoreQToOffset(src, base, offset - kHeapObjectTag, pp); |
| 827 } | 871 } |
| 828 | 872 |
| 829 // Storing into an object. | 873 // Storing into an object. |
| 830 void StoreIntoObject(Register object, | 874 void StoreIntoObject(Register object, |
| 831 const Address& dest, | 875 const Address& dest, |
| 832 Register value, | 876 Register value, |
| 833 bool can_value_be_smi = true); | 877 bool can_value_be_smi = true); |
| 878 void StoreIntoObjectOffset(Register object, |
| 879 int32_t offset, |
| 880 Register value, |
| 881 Register pp, |
| 882 bool can_value_be_smi = true); |
| 834 void StoreIntoObjectNoBarrier(Register object, | 883 void StoreIntoObjectNoBarrier(Register object, |
| 835 const Address& dest, | 884 const Address& dest, |
| 836 Register value); | 885 Register value); |
| 886 void StoreIntoObjectOffsetNoBarrier(Register object, |
| 887 int32_t offset, |
| 888 Register value, |
| 889 Register pp); |
| 837 void StoreIntoObjectNoBarrier(Register object, | 890 void StoreIntoObjectNoBarrier(Register object, |
| 838 const Address& dest, | 891 const Address& dest, |
| 839 const Object& value); | 892 const Object& value); |
| 893 void StoreIntoObjectOffsetNoBarrier(Register object, |
| 894 int32_t offset, |
| 895 const Object& value, |
| 896 Register pp); |
| 840 | 897 |
| 841 // Object pool, loading from pool, etc. | 898 // Object pool, loading from pool, etc. |
| 842 void LoadPoolPointer(Register pp); | 899 void LoadPoolPointer(Register pp); |
| 843 | 900 |
| 844 // Index of constant pool entries pointing to debugger stubs. | 901 // Index of constant pool entries pointing to debugger stubs. |
| 845 static const int kBreakpointRuntimeCPIndex = 5; | 902 static const int kBreakpointRuntimeCPIndex = 5; |
| 846 | 903 |
| 847 enum Patchability { | 904 enum Patchability { |
| 848 kPatchable, | 905 kPatchable, |
| 849 kNotPatchable, | 906 kNotPatchable, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 863 void LoadImmediateFixed(Register reg, int64_t imm); | 920 void LoadImmediateFixed(Register reg, int64_t imm); |
| 864 void LoadImmediate(Register reg, int64_t imm, Register pp); | 921 void LoadImmediate(Register reg, int64_t imm, Register pp); |
| 865 void LoadDImmediate(VRegister reg, double immd, Register pp); | 922 void LoadDImmediate(VRegister reg, double immd, Register pp); |
| 866 | 923 |
| 867 void PushObject(const Object& object, Register pp) { | 924 void PushObject(const Object& object, Register pp) { |
| 868 LoadObject(TMP, object, pp); | 925 LoadObject(TMP, object, pp); |
| 869 Push(TMP); | 926 Push(TMP); |
| 870 } | 927 } |
| 871 void CompareObject(Register reg, const Object& object, Register pp); | 928 void CompareObject(Register reg, const Object& object, Register pp); |
| 872 | 929 |
| 873 void LoadClassId(Register result, Register object); | 930 void LoadClassId(Register result, Register object, Register pp); |
| 874 void LoadClassById(Register result, Register class_id); | 931 void LoadClassById(Register result, Register class_id, Register pp); |
| 875 void LoadClass(Register result, Register object); | 932 void LoadClass(Register result, Register object, Register pp); |
| 876 void CompareClassId(Register object, intptr_t class_id); | 933 void CompareClassId(Register object, intptr_t class_id, Register pp); |
| 877 | 934 |
| 878 void EnterFrame(intptr_t frame_size); | 935 void EnterFrame(intptr_t frame_size); |
| 879 void LeaveFrame(); | 936 void LeaveFrame(); |
| 880 | 937 |
| 881 void EnterDartFrame(intptr_t frame_size); | 938 void EnterDartFrame(intptr_t frame_size); |
| 882 void EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp); | 939 void EnterDartFrameWithInfo(intptr_t frame_size, Register new_pp); |
| 883 void EnterOsrFrame(intptr_t extra_size, Register new_pp); | 940 void EnterOsrFrame(intptr_t extra_size, Register new_pp); |
| 884 void LeaveDartFrame(); | 941 void LeaveDartFrame(); |
| 885 | 942 |
| 886 void EnterCallRuntimeFrame(intptr_t frame_size); | 943 void EnterCallRuntimeFrame(intptr_t frame_size); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 (static_cast<int32_t>(hw_idx) << kHWShift) | | 1202 (static_cast<int32_t>(hw_idx) << kHWShift) | |
| 1146 (static_cast<int32_t>(imm) << kImm16Shift); | 1203 (static_cast<int32_t>(imm) << kImm16Shift); |
| 1147 Emit(encoding); | 1204 Emit(encoding); |
| 1148 } | 1205 } |
| 1149 | 1206 |
| 1150 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, | 1207 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, |
| 1151 OperandSize sz) { | 1208 OperandSize sz) { |
| 1152 const Register crt = ConcreteRegister(rt); | 1209 const Register crt = ConcreteRegister(rt); |
| 1153 const int32_t size = Log2OperandSizeBytes(sz); | 1210 const int32_t size = Log2OperandSizeBytes(sz); |
| 1154 const int32_t encoding = | 1211 const int32_t encoding = |
| 1155 op | (size << kSzShift) | | 1212 op | ((size & 0x3) << kSzShift) | |
| 1156 (static_cast<int32_t>(crt) << kRtShift) | | 1213 (static_cast<int32_t>(crt) << kRtShift) | |
| 1157 a.encoding(); | 1214 a.encoding(); |
| 1158 Emit(encoding); | 1215 Emit(encoding); |
| 1159 } | 1216 } |
| 1160 | 1217 |
| 1161 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, | 1218 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, |
| 1162 OperandSize sz) { | 1219 OperandSize sz) { |
| 1163 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); | 1220 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); |
| 1164 ASSERT((rt != SP) && (rt != R31)); | 1221 ASSERT((rt != SP) && (rt != R31)); |
| 1165 const Register crt = ConcreteRegister(rt); | 1222 const Register crt = ConcreteRegister(rt); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 Register value, | 1343 Register value, |
| 1287 Label* no_update); | 1344 Label* no_update); |
| 1288 | 1345 |
| 1289 DISALLOW_ALLOCATION(); | 1346 DISALLOW_ALLOCATION(); |
| 1290 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1347 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1291 }; | 1348 }; |
| 1292 | 1349 |
| 1293 } // namespace dart | 1350 } // namespace dart |
| 1294 | 1351 |
| 1295 #endif // VM_ASSEMBLER_ARM64_H_ | 1352 #endif // VM_ASSEMBLER_ARM64_H_ |
| OLD | NEW |