| 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" | 5 #include "vm/globals.h" |
| 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/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 // R1 : arguments descriptor array. | 523 // R1 : arguments descriptor array. |
| 524 // R2 : arguments array. | 524 // R2 : arguments array. |
| 525 // R3 : new context containing the current isolate pointer. | 525 // R3 : new context containing the current isolate pointer. |
| 526 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 526 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 527 __ Comment("InvokeDartCodeStub"); | 527 __ Comment("InvokeDartCodeStub"); |
| 528 __ EnterFrame(0); | 528 __ EnterFrame(0); |
| 529 | 529 |
| 530 // The new context, saved vm tag, the top exit frame, and the old context. | 530 // The new context, saved vm tag, the top exit frame, and the old context. |
| 531 // const intptr_t kPreservedContextSlots = 4; | 531 // const intptr_t kPreservedContextSlots = 4; |
| 532 const intptr_t kNewContextOffsetFromFp = | 532 const intptr_t kNewContextOffsetFromFp = |
| 533 -(1 + kAbiPreservedCpuRegCount) * kWordSize; | 533 -(1 + kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount) * kWordSize; |
| 534 // const intptr_t kPreservedRegSpace = | 534 // const intptr_t kPreservedRegSpace = |
| 535 // kWordSize * (kAbiPreservedCpuRegCount + kPreservedContextSlots); | 535 // kWordSize * (kAbiPreservedCpuRegCount + kPreservedContextSlots); |
| 536 | 536 |
| 537 // Save the callee-saved registers. | 537 // Save the callee-saved registers. |
| 538 for (int i = R19; i <= R28; i++) { | 538 for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) { |
| 539 const Register r = static_cast<Register>(i); | 539 const Register r = static_cast<Register>(i); |
| 540 // We use str instead of the Push macro because we will be pushing the PP | 540 // We use str instead of the Push macro because we will be pushing the PP |
| 541 // register when it is not holding a pool-pointer since we are coming from | 541 // register when it is not holding a pool-pointer since we are coming from |
| 542 // C++ code. | 542 // C++ code. |
| 543 __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex)); | 543 __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex)); |
| 544 } | 544 } |
| 545 | 545 |
| 546 // TODO(zra): Save the bottom 64-bits of callee-saved floating point | 546 // Save the bottom 64-bits of callee-saved V registers. |
| 547 // registers. | 547 for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) { |
| 548 const VRegister r = static_cast<VRegister>(i); |
| 549 __ PushDouble(r); |
| 550 } |
| 548 | 551 |
| 549 // Push new context. | 552 // Push new context. |
| 550 __ Push(R3); | 553 __ Push(R3); |
| 551 | 554 |
| 552 // We now load the pool pointer(PP) as we are about to invoke dart code and we | 555 // We now load the pool pointer(PP) as we are about to invoke dart code and we |
| 553 // could potentially invoke some intrinsic functions which need the PP to be | 556 // could potentially invoke some intrinsic functions which need the PP to be |
| 554 // set up. | 557 // set up. |
| 555 __ LoadPoolPointer(PP); | 558 __ LoadPoolPointer(PP); |
| 556 | 559 |
| 557 // The new Context structure contains a pointer to the current Isolate | 560 // The new Context structure contains a pointer to the current Isolate |
| 558 // structure. Cache the Context pointer in the CTX register so that it is | 561 // structure. Cache the Context pointer in the CTX register so that it is |
| 559 // available in generated code and calls to Isolate::Current() need not be | 562 // available in generated code and calls to Isolate::Current() need not be |
| 560 // done. The assumption is that this register will never be clobbered by | 563 // done. The assumption is that this register will never be clobbered by |
| 561 // compiled or runtime stub code. | 564 // compiled or runtime stub code. |
| 562 | 565 |
| 563 // Cache the new Context pointer into CTX while executing Dart code. | 566 // Cache the new Context pointer into CTX while executing Dart code. |
| 564 __ LoadFromOffset(CTX, R3, VMHandles::kOffsetOfRawPtrInHandle); | 567 __ LoadFromOffset(CTX, R3, VMHandles::kOffsetOfRawPtrInHandle); |
| 565 | 568 |
| 566 // Load Isolate pointer from Context structure into temporary register R4. | 569 // Load Isolate pointer from Context structure into temporary register R4. |
| 567 __ LoadFieldFromOffset(R5, CTX, Context::isolate_offset()); | 570 __ LoadFieldFromOffset(R5, CTX, Context::isolate_offset()); |
| 568 | 571 |
| 569 // Save the current VMTag on the stack. | 572 // Save the current VMTag on the stack. |
| 570 ASSERT(kSavedVMTagSlotFromEntryFp == -12); | 573 ASSERT(kSavedVMTagSlotFromEntryFp == -20); |
| 571 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset()); | 574 __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset()); |
| 572 __ Push(R4); | 575 __ Push(R4); |
| 573 | 576 |
| 574 // Mark that the isolate is executing Dart code. | 577 // Mark that the isolate is executing Dart code. |
| 575 __ LoadImmediate(R6, VMTag::kScriptTagId, PP); | 578 __ LoadImmediate(R6, VMTag::kScriptTagId, PP); |
| 576 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset()); | 579 __ StoreToOffset(R6, R5, Isolate::vm_tag_offset()); |
| 577 | 580 |
| 578 // Save the top exit frame info. Use R6 as a temporary register. | 581 // Save the top exit frame info. Use R6 as a temporary register. |
| 579 // StackFrameIterator reads the top exit frame info saved in this frame. | 582 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 580 __ LoadFromOffset(R6, R5, Isolate::top_exit_frame_info_offset()); | 583 __ LoadFromOffset(R6, R5, Isolate::top_exit_frame_info_offset()); |
| 581 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset()); | 584 __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset()); |
| 582 | 585 |
| 583 // Save the old Context pointer. Use R4 as a temporary register. | 586 // Save the old Context pointer. Use R4 as a temporary register. |
| 584 // Note that VisitObjectPointers will find this saved Context pointer during | 587 // Note that VisitObjectPointers will find this saved Context pointer during |
| 585 // GC marking, since it traverses any information between SP and | 588 // GC marking, since it traverses any information between SP and |
| 586 // FP - kExitLinkSlotFromEntryFp. | 589 // FP - kExitLinkSlotFromEntryFp. |
| 587 // EntryFrame::SavedContext reads the context saved in this frame. | 590 // EntryFrame::SavedContext reads the context saved in this frame. |
| 588 __ LoadFromOffset(R4, R5, Isolate::top_context_offset()); | 591 __ LoadFromOffset(R4, R5, Isolate::top_context_offset()); |
| 589 | 592 |
| 590 // The constants kSavedContextSlotFromEntryFp and | 593 // The constants kSavedContextSlotFromEntryFp and |
| 591 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 594 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
| 592 ASSERT(kExitLinkSlotFromEntryFp == -13); | 595 ASSERT(kExitLinkSlotFromEntryFp == -21); |
| 593 ASSERT(kSavedContextSlotFromEntryFp == -14); | 596 ASSERT(kSavedContextSlotFromEntryFp == -22); |
| 594 __ Push(R6); | 597 __ Push(R6); |
| 595 __ Push(R4); | 598 __ Push(R4); |
| 596 | 599 |
| 597 // Load arguments descriptor array into R4, which is passed to Dart code. | 600 // Load arguments descriptor array into R4, which is passed to Dart code. |
| 598 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle); | 601 __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle); |
| 599 | 602 |
| 600 // Load number of arguments into S5. | 603 // Load number of arguments into S5. |
| 601 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset()); | 604 __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset()); |
| 602 __ SmiUntag(R5); | 605 __ SmiUntag(R5); |
| 603 | 606 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 // Restore the saved top exit frame info back into the Isolate structure. | 646 // Restore the saved top exit frame info back into the Isolate structure. |
| 644 // Uses R6 as a temporary register for this. | 647 // Uses R6 as a temporary register for this. |
| 645 __ Pop(R4); | 648 __ Pop(R4); |
| 646 __ Pop(R6); | 649 __ Pop(R6); |
| 647 __ StoreToOffset(R4, CTX, Isolate::top_context_offset()); | 650 __ StoreToOffset(R4, CTX, Isolate::top_context_offset()); |
| 648 __ StoreToOffset(R6, CTX, Isolate::top_exit_frame_info_offset()); | 651 __ StoreToOffset(R6, CTX, Isolate::top_exit_frame_info_offset()); |
| 649 | 652 |
| 650 __ Pop(R3); | 653 __ Pop(R3); |
| 651 __ Pop(R4); | 654 __ Pop(R4); |
| 652 | 655 |
| 656 // Restore the bottom 64-bits of callee-saved V registers. |
| 657 for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) { |
| 658 const VRegister r = static_cast<VRegister>(i); |
| 659 __ PushDouble(r); |
| 660 } |
| 661 |
| 653 // Restore C++ ABI callee-saved registers. | 662 // Restore C++ ABI callee-saved registers. |
| 654 for (int i = R28; i >= R19; i--) { | 663 for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) { |
| 655 Register r = static_cast<Register>(i); | 664 Register r = static_cast<Register>(i); |
| 656 // We use ldr instead of the Pop macro because we will be popping the PP | 665 // We use ldr instead of the Pop macro because we will be popping the PP |
| 657 // register when it is not holding a pool-pointer since we are returning to | 666 // register when it is not holding a pool-pointer since we are returning to |
| 658 // C++ code. | 667 // C++ code. |
| 659 __ ldr(r, Address(SP, 1 * kWordSize, Address::PostIndex)); | 668 __ ldr(r, Address(SP, 1 * kWordSize, Address::PostIndex)); |
| 660 } | 669 } |
| 661 | 670 |
| 662 // TODO(zra): Restore callee-saved fpu registers. | |
| 663 | |
| 664 // Restore the frame pointer and return. | 671 // Restore the frame pointer and return. |
| 665 __ LeaveFrame(); | 672 __ LeaveFrame(); |
| 666 __ ret(); | 673 __ ret(); |
| 667 } | 674 } |
| 668 | 675 |
| 669 | 676 |
| 670 // Called for inline allocation of contexts. | 677 // Called for inline allocation of contexts. |
| 671 // Input: | 678 // Input: |
| 672 // R1: number of context variables. | 679 // R1: number of context variables. |
| 673 // Output: | 680 // Output: |
| (...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1586 | 1593 |
| 1587 | 1594 |
| 1588 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( | 1595 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( |
| 1589 Assembler* assembler) { | 1596 Assembler* assembler) { |
| 1590 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub"); | 1597 __ Stop("GenerateOptimizedIdenticalWithNumberCheckStub"); |
| 1591 } | 1598 } |
| 1592 | 1599 |
| 1593 } // namespace dart | 1600 } // namespace dart |
| 1594 | 1601 |
| 1595 #endif // defined TARGET_ARCH_ARM64 | 1602 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |