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 #include "vm/globals.h" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 | 577 |
578 void Assembler::LoadDImmediate(VRegister vd, double immd) { | 578 void Assembler::LoadDImmediate(VRegister vd, double immd) { |
579 if (!fmovdi(vd, immd)) { | 579 if (!fmovdi(vd, immd)) { |
580 int64_t imm = bit_cast<int64_t, double>(immd); | 580 int64_t imm = bit_cast<int64_t, double>(immd); |
581 LoadImmediate(TMP, imm); | 581 LoadImmediate(TMP, imm); |
582 fmovdr(vd, TMP); | 582 fmovdr(vd, TMP); |
583 } | 583 } |
584 } | 584 } |
585 | 585 |
586 | 586 |
| 587 void Assembler::Branch(const ExternalLabel* label) { |
| 588 LoadExternalLabel(TMP, label); |
| 589 br(TMP); |
| 590 } |
| 591 |
| 592 |
587 void Assembler::Branch(const StubEntry& stub_entry) { | 593 void Assembler::Branch(const StubEntry& stub_entry) { |
588 const ExternalLabel label(stub_entry.EntryPoint()); | 594 const ExternalLabel label(stub_entry.EntryPoint()); |
589 Branch(&label); | 595 Branch(&label); |
590 } | 596 } |
591 | 597 |
592 | 598 |
| 599 void Assembler::BranchPatchable(const ExternalLabel* label) { |
| 600 // TODO(zra): Use LoadExternalLabelFixed if possible. |
| 601 LoadImmediateFixed(TMP, label->address()); |
| 602 br(TMP); |
| 603 } |
| 604 |
593 void Assembler::BranchPatchable(const StubEntry& stub_entry) { | 605 void Assembler::BranchPatchable(const StubEntry& stub_entry) { |
594 const ExternalLabel label(stub_entry.EntryPoint()); | 606 const ExternalLabel label(stub_entry.EntryPoint()); |
595 BranchPatchable(&label); | 607 BranchPatchable(&label); |
596 } | 608 } |
597 | 609 |
598 | 610 |
| 611 void Assembler::BranchLink(const ExternalLabel* label) { |
| 612 LoadExternalLabel(TMP, label); |
| 613 blr(TMP); |
| 614 } |
| 615 |
| 616 |
599 void Assembler::BranchLink(const StubEntry& stub_entry) { | 617 void Assembler::BranchLink(const StubEntry& stub_entry) { |
600 const ExternalLabel label(stub_entry.EntryPoint()); | 618 const ExternalLabel label(stub_entry.EntryPoint()); |
601 BranchLink(&label); | 619 BranchLink(&label); |
602 } | 620 } |
603 | 621 |
604 | 622 |
| 623 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { |
| 624 LoadExternalLabelFixed(TMP, label, kPatchable); |
| 625 blr(TMP); |
| 626 } |
| 627 |
| 628 |
605 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) { | 629 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) { |
606 const ExternalLabel label(stub_entry.EntryPoint()); | 630 const ExternalLabel label(stub_entry.EntryPoint()); |
607 BranchLinkPatchable(&label); | 631 BranchLinkPatchable(&label); |
608 } | 632 } |
609 | 633 |
610 | 634 |
611 void Assembler::AddImmediate(Register dest, Register rn, int64_t imm) { | 635 void Assembler::AddImmediate(Register dest, Register rn, int64_t imm) { |
612 Operand op; | 636 Operand op; |
613 if (imm == 0) { | 637 if (imm == 0) { |
614 if (dest != rn) { | 638 if (dest != rn) { |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 void Assembler::LeaveDartFrame() { | 1161 void Assembler::LeaveDartFrame() { |
1138 set_constant_pool_allowed(false); | 1162 set_constant_pool_allowed(false); |
1139 // Restore and untag PP. | 1163 // Restore and untag PP. |
1140 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); | 1164 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); |
1141 sub(PP, PP, Operand(kHeapObjectTag)); | 1165 sub(PP, PP, Operand(kHeapObjectTag)); |
1142 LeaveFrame(); | 1166 LeaveFrame(); |
1143 } | 1167 } |
1144 | 1168 |
1145 | 1169 |
1146 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) { | 1170 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) { |
1147 EnterFrame(0); | 1171 EnterStubFrame(); |
1148 | 1172 |
1149 // Store fpu registers with the lowest register number at the lowest | 1173 // Store fpu registers with the lowest register number at the lowest |
1150 // address. | 1174 // address. |
1151 for (int i = kNumberOfVRegisters - 1; i >= 0; i--) { | 1175 for (int i = kNumberOfVRegisters - 1; i >= 0; i--) { |
1152 if ((i >= kAbiFirstPreservedFpuReg) && (i <= kAbiLastPreservedFpuReg)) { | 1176 if ((i >= kAbiFirstPreservedFpuReg) && (i <= kAbiLastPreservedFpuReg)) { |
1153 // TODO(zra): When SIMD is added, we must also preserve the top | 1177 // TODO(zra): When SIMD is added, we must also preserve the top |
1154 // 64-bits of the callee-saved registers. | 1178 // 64-bits of the callee-saved registers. |
1155 continue; | 1179 continue; |
1156 } | 1180 } |
1157 // TODO(zra): Save the whole V register. | 1181 // TODO(zra): Save the whole V register. |
1158 VRegister reg = static_cast<VRegister>(i); | 1182 VRegister reg = static_cast<VRegister>(i); |
1159 PushDouble(reg); | 1183 PushDouble(reg); |
1160 } | 1184 } |
1161 | 1185 |
1162 for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) { | 1186 for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) { |
1163 const Register reg = static_cast<Register>(i); | 1187 const Register reg = static_cast<Register>(i); |
1164 Push(reg); | 1188 Push(reg); |
1165 } | 1189 } |
1166 | 1190 |
1167 ReserveAlignedFrameSpace(frame_size); | 1191 ReserveAlignedFrameSpace(frame_size); |
1168 } | 1192 } |
1169 | 1193 |
1170 | 1194 |
1171 void Assembler::LeaveCallRuntimeFrame() { | 1195 void Assembler::LeaveCallRuntimeFrame() { |
1172 // SP might have been modified to reserve space for arguments | 1196 // SP might have been modified to reserve space for arguments |
1173 // and ensure proper alignment of the stack frame. | 1197 // and ensure proper alignment of the stack frame. |
1174 // We need to restore it before restoring registers. | 1198 // We need to restore it before restoring registers. |
1175 const intptr_t kPushedRegistersSize = | 1199 const intptr_t kPushedRegistersSize = |
1176 kDartVolatileCpuRegCount * kWordSize + | 1200 kDartVolatileCpuRegCount * kWordSize + |
1177 kDartVolatileFpuRegCount * kWordSize; | 1201 kDartVolatileFpuRegCount * kWordSize + |
| 1202 2 * kWordSize; // PP and pc marker from EnterStubFrame. |
1178 AddImmediate(SP, FP, -kPushedRegistersSize); | 1203 AddImmediate(SP, FP, -kPushedRegistersSize); |
1179 for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) { | 1204 for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) { |
1180 const Register reg = static_cast<Register>(i); | 1205 const Register reg = static_cast<Register>(i); |
1181 Pop(reg); | 1206 Pop(reg); |
1182 } | 1207 } |
1183 | 1208 |
1184 for (int i = 0; i < kNumberOfVRegisters; i++) { | 1209 for (int i = 0; i < kNumberOfVRegisters; i++) { |
1185 if ((i >= kAbiFirstPreservedFpuReg) && (i <= kAbiLastPreservedFpuReg)) { | 1210 if ((i >= kAbiFirstPreservedFpuReg) && (i <= kAbiLastPreservedFpuReg)) { |
1186 // TODO(zra): When SIMD is added, we must also restore the top | 1211 // TODO(zra): When SIMD is added, we must also restore the top |
1187 // 64-bits of the callee-saved registers. | 1212 // 64-bits of the callee-saved registers. |
1188 continue; | 1213 continue; |
1189 } | 1214 } |
1190 // TODO(zra): Restore the whole V register. | 1215 // TODO(zra): Restore the whole V register. |
1191 VRegister reg = static_cast<VRegister>(i); | 1216 VRegister reg = static_cast<VRegister>(i); |
1192 PopDouble(reg); | 1217 PopDouble(reg); |
1193 } | 1218 } |
1194 | 1219 |
1195 PopPair(LR, FP); | 1220 LeaveStubFrame(); |
1196 } | 1221 } |
1197 | 1222 |
1198 | 1223 |
1199 void Assembler::CallRuntime(const RuntimeEntry& entry, | 1224 void Assembler::CallRuntime(const RuntimeEntry& entry, |
1200 intptr_t argument_count) { | 1225 intptr_t argument_count) { |
1201 entry.Call(this, argument_count); | 1226 entry.Call(this, argument_count); |
1202 } | 1227 } |
1203 | 1228 |
1204 | 1229 |
1205 void Assembler::EnterStubFrame() { | 1230 void Assembler::EnterStubFrame() { |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1443 add(base, array, Operand(index, LSL, shift)); | 1468 add(base, array, Operand(index, LSL, shift)); |
1444 } | 1469 } |
1445 const OperandSize size = Address::OperandSizeFor(cid); | 1470 const OperandSize size = Address::OperandSizeFor(cid); |
1446 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1471 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
1447 return Address(base, offset, Address::Offset, size); | 1472 return Address(base, offset, Address::Offset, size); |
1448 } | 1473 } |
1449 | 1474 |
1450 } // namespace dart | 1475 } // namespace dart |
1451 | 1476 |
1452 #endif // defined TARGET_ARCH_ARM64 | 1477 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |