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