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 |