| 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 fcmpzd(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 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 OperandSize sz = kDoubleWord); |
| 811 void LoadFieldFromOffset(Register dest, Register base, int32_t offset) { | 837 void LoadFieldFromOffset(Register dest, Register base, int32_t offset) { |
| 812 LoadFromOffset(dest, base, offset - kHeapObjectTag); | 838 LoadFromOffset(dest, base, offset - kHeapObjectTag); |
| 813 } | 839 } |
| 814 void LoadDFromOffset(VRegister dest, Register base, int32_t offset); | 840 void LoadDFromOffset(VRegister dest, Register base, int32_t offset); |
| 815 void LoadDFieldFromOffset(VRegister dest, Register base, int32_t offset) { | 841 void LoadDFieldFromOffset(VRegister dest, Register base, int32_t offset) { |
| 816 LoadDFromOffset(dest, base, offset - kHeapObjectTag); | 842 LoadDFromOffset(dest, base, offset - kHeapObjectTag); |
| 817 } | 843 } |
| 844 void LoadQFromOffset(VRegister dest, Register base, int32_t offset); |
| 845 void LoadQFieldFromOffset(VRegister dest, Register base, int32_t offset) { |
| 846 LoadQFromOffset(dest, base, offset - kHeapObjectTag); |
| 847 } |
| 818 | 848 |
| 819 void StoreToOffset(Register src, Register base, int32_t offset, | 849 void StoreToOffset(Register src, Register base, int32_t offset, |
| 820 OperandSize sz = kDoubleWord); | 850 OperandSize sz = kDoubleWord); |
| 821 void StoreFieldToOffset(Register src, Register base, int32_t offset) { | 851 void StoreFieldToOffset(Register src, Register base, int32_t offset) { |
| 822 StoreToOffset(src, base, offset - kHeapObjectTag); | 852 StoreToOffset(src, base, offset - kHeapObjectTag); |
| 823 } | 853 } |
| 824 void StoreDToOffset(VRegister src, Register base, int32_t offset); | 854 void StoreDToOffset(VRegister src, Register base, int32_t offset); |
| 825 void StoreDFieldToOffset(VRegister src, Register base, int32_t offset) { | 855 void StoreDFieldToOffset(VRegister src, Register base, int32_t offset) { |
| 826 StoreDToOffset(src, base, offset - kHeapObjectTag); | 856 StoreDToOffset(src, base, offset - kHeapObjectTag); |
| 827 } | 857 } |
| 858 void StoreQToOffset(VRegister src, Register base, int32_t offset); |
| 859 void StoreQFieldToOffset(VRegister src, Register base, int32_t offset) { |
| 860 StoreQToOffset(src, base, offset - kHeapObjectTag); |
| 861 } |
| 828 | 862 |
| 829 // Storing into an object. | 863 // Storing into an object. |
| 830 void StoreIntoObject(Register object, | 864 void StoreIntoObject(Register object, |
| 831 const Address& dest, | 865 const Address& dest, |
| 832 Register value, | 866 Register value, |
| 833 bool can_value_be_smi = true); | 867 bool can_value_be_smi = true); |
| 868 void StoreIntoObjectOffset(Register object, |
| 869 int32_t offset, |
| 870 Register value, |
| 871 bool can_value_be_smi = true); |
| 834 void StoreIntoObjectNoBarrier(Register object, | 872 void StoreIntoObjectNoBarrier(Register object, |
| 835 const Address& dest, | 873 const Address& dest, |
| 836 Register value); | 874 Register value); |
| 875 void StoreIntoObjectOffsetNoBarrier(Register object, |
| 876 int32_t offset, |
| 877 Register value); |
| 837 void StoreIntoObjectNoBarrier(Register object, | 878 void StoreIntoObjectNoBarrier(Register object, |
| 838 const Address& dest, | 879 const Address& dest, |
| 839 const Object& value); | 880 const Object& value); |
| 881 void StoreIntoObjectOffsetNoBarrier(Register object, |
| 882 int32_t offset, |
| 883 const Object& value); |
| 840 | 884 |
| 841 // Object pool, loading from pool, etc. | 885 // Object pool, loading from pool, etc. |
| 842 void LoadPoolPointer(Register pp); | 886 void LoadPoolPointer(Register pp); |
| 843 | 887 |
| 844 // Index of constant pool entries pointing to debugger stubs. | 888 // Index of constant pool entries pointing to debugger stubs. |
| 845 static const int kBreakpointRuntimeCPIndex = 5; | 889 static const int kBreakpointRuntimeCPIndex = 5; |
| 846 | 890 |
| 847 enum Patchability { | 891 enum Patchability { |
| 848 kPatchable, | 892 kPatchable, |
| 849 kNotPatchable, | 893 kNotPatchable, |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 (static_cast<int32_t>(hw_idx) << kHWShift) | | 1189 (static_cast<int32_t>(hw_idx) << kHWShift) | |
| 1146 (static_cast<int32_t>(imm) << kImm16Shift); | 1190 (static_cast<int32_t>(imm) << kImm16Shift); |
| 1147 Emit(encoding); | 1191 Emit(encoding); |
| 1148 } | 1192 } |
| 1149 | 1193 |
| 1150 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, | 1194 void EmitLoadStoreReg(LoadStoreRegOp op, Register rt, Address a, |
| 1151 OperandSize sz) { | 1195 OperandSize sz) { |
| 1152 const Register crt = ConcreteRegister(rt); | 1196 const Register crt = ConcreteRegister(rt); |
| 1153 const int32_t size = Log2OperandSizeBytes(sz); | 1197 const int32_t size = Log2OperandSizeBytes(sz); |
| 1154 const int32_t encoding = | 1198 const int32_t encoding = |
| 1155 op | (size << kSzShift) | | 1199 op | ((size & 0x3) << kSzShift) | |
| 1156 (static_cast<int32_t>(crt) << kRtShift) | | 1200 (static_cast<int32_t>(crt) << kRtShift) | |
| 1157 a.encoding(); | 1201 a.encoding(); |
| 1158 Emit(encoding); | 1202 Emit(encoding); |
| 1159 } | 1203 } |
| 1160 | 1204 |
| 1161 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, | 1205 void EmitLoadRegLiteral(LoadRegLiteralOp op, Register rt, Address a, |
| 1162 OperandSize sz) { | 1206 OperandSize sz) { |
| 1163 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); | 1207 ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord)); |
| 1164 ASSERT((rt != SP) && (rt != R31)); | 1208 ASSERT((rt != SP) && (rt != R31)); |
| 1165 const Register crt = ConcreteRegister(rt); | 1209 const Register crt = ConcreteRegister(rt); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 Register value, | 1330 Register value, |
| 1287 Label* no_update); | 1331 Label* no_update); |
| 1288 | 1332 |
| 1289 DISALLOW_ALLOCATION(); | 1333 DISALLOW_ALLOCATION(); |
| 1290 DISALLOW_COPY_AND_ASSIGN(Assembler); | 1334 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 1291 }; | 1335 }; |
| 1292 | 1336 |
| 1293 } // namespace dart | 1337 } // namespace dart |
| 1294 | 1338 |
| 1295 #endif // VM_ASSEMBLER_ARM64_H_ | 1339 #endif // VM_ASSEMBLER_ARM64_H_ |
| OLD | NEW |