Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: runtime/vm/stub_code_arm.cc

Issue 23549013: Preserves callee-saved FPU registers on ARM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« runtime/vm/assembler_arm.cc ('K') | « runtime/vm/stack_frame_arm.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 // LR : points to return address. 775 // LR : points to return address.
776 // R0 : entrypoint of the Dart function to call. 776 // R0 : entrypoint of the Dart function to call.
777 // R1 : arguments descriptor array. 777 // R1 : arguments descriptor array.
778 // R2 : arguments array. 778 // R2 : arguments array.
779 // R3 : new context containing the current isolate pointer. 779 // R3 : new context containing the current isolate pointer.
780 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { 780 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
781 // Save frame pointer coming in. 781 // Save frame pointer coming in.
782 __ EnterStubFrame(); 782 __ EnterStubFrame();
783 783
784 // Save new context and C++ ABI callee-saved registers. 784 // Save new context and C++ ABI callee-saved registers.
785 const intptr_t kNewContextOffset = 785 const intptr_t kNewContextOffsetFromFp =
786 -(1 + kAbiPreservedCpuRegCount) * kWordSize; 786 -(1 + kAbiPreservedCpuRegCount) * kWordSize;
787 __ PushList((1 << R3) | kAbiPreservedCpuRegs); 787 __ PushList((1 << R3) | kAbiPreservedCpuRegs);
788 788
789 const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg);
790 ASSERT(2 * kAbiPreservedFpuRegCount < 16);
791 // Save FPU registers. 2 D registers per Q register.
792 __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
793
789 // The new Context structure contains a pointer to the current Isolate 794 // The new Context structure contains a pointer to the current Isolate
790 // structure. Cache the Context pointer in the CTX register so that it is 795 // structure. Cache the Context pointer in the CTX register so that it is
791 // available in generated code and calls to Isolate::Current() need not be 796 // available in generated code and calls to Isolate::Current() need not be
792 // done. The assumption is that this register will never be clobbered by 797 // done. The assumption is that this register will never be clobbered by
793 // compiled or runtime stub code. 798 // compiled or runtime stub code.
794 799
795 // Cache the new Context pointer into CTX while executing Dart code. 800 // Cache the new Context pointer into CTX while executing Dart code.
796 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); 801 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle));
797 802
798 // Load Isolate pointer from Context structure into temporary register R8. 803 // Load Isolate pointer from Context structure into temporary register R8.
799 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); 804 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset()));
800 805
801 // Save the top exit frame info. Use R5 as a temporary register. 806 // Save the top exit frame info. Use R5 as a temporary register.
802 // StackFrameIterator reads the top exit frame info saved in this frame. 807 // StackFrameIterator reads the top exit frame info saved in this frame.
803 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset()); 808 __ LoadFromOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset());
804 __ LoadImmediate(R6, 0); 809 __ LoadImmediate(R6, 0);
805 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset()); 810 __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset());
806 811
807 // Save the old Context pointer. Use R4 as a temporary register. 812 // Save the old Context pointer. Use R4 as a temporary register.
808 // Note that VisitObjectPointers will find this saved Context pointer during 813 // Note that VisitObjectPointers will find this saved Context pointer during
809 // GC marking, since it traverses any information between SP and 814 // GC marking, since it traverses any information between SP and
810 // FP - kExitLinkSlotFromEntryFp. 815 // FP - kExitLinkSlotFromEntryFp.
811 // EntryFrame::SavedContext reads the context saved in this frame. 816 // EntryFrame::SavedContext reads the context saved in this frame.
812 __ LoadFromOffset(kWord, R4, R8, Isolate::top_context_offset()); 817 __ LoadFromOffset(kWord, R4, R8, Isolate::top_context_offset());
813 818
814 // The constants kSavedContextSlotFromEntryFp and 819 // The constants kSavedContextSlotFromEntryFp and
815 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. 820 // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
816 ASSERT(kExitLinkSlotFromEntryFp == -9); 821 ASSERT(kExitLinkSlotFromEntryFp == -25);
817 ASSERT(kSavedContextSlotFromEntryFp == -10); 822 ASSERT(kSavedContextSlotFromEntryFp == -26);
818 __ PushList((1 << R4) | (1 << R5)); 823 __ PushList((1 << R4) | (1 << R5));
819 824
820 // The stack pointer is restored after the call to this location.
821 const intptr_t kSavedContextSlotFromEntryFp = -10 * kWordSize;
822
823 // Load arguments descriptor array into R4, which is passed to Dart code. 825 // Load arguments descriptor array into R4, which is passed to Dart code.
824 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); 826 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
825 827
826 // Load number of arguments into R5. 828 // Load number of arguments into R5.
827 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 829 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
828 __ SmiUntag(R5); 830 __ SmiUntag(R5);
829 831
830 // Compute address of 'arguments array' data area into R2. 832 // Compute address of 'arguments array' data area into R2.
831 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); 833 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle));
832 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag); 834 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag);
(...skipping 10 matching lines...) Expand all
843 __ AddImmediate(R2, kWordSize); 845 __ AddImmediate(R2, kWordSize);
844 __ AddImmediate(R1, 1); 846 __ AddImmediate(R1, 1);
845 __ cmp(R1, ShifterOperand(R5)); 847 __ cmp(R1, ShifterOperand(R5));
846 __ b(&push_arguments, LT); 848 __ b(&push_arguments, LT);
847 __ Bind(&done_push_arguments); 849 __ Bind(&done_push_arguments);
848 850
849 // Call the Dart code entrypoint. 851 // Call the Dart code entrypoint.
850 __ blx(R0); // R4 is the arguments descriptor array. 852 __ blx(R0); // R4 is the arguments descriptor array.
851 853
852 // Read the saved new Context pointer. 854 // Read the saved new Context pointer.
853 __ ldr(CTX, Address(FP, kNewContextOffset)); 855 __ ldr(CTX, Address(FP, kNewContextOffsetFromFp));
854 __ ldr(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); 856 __ ldr(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle));
855 857
856 // Get rid of arguments pushed on the stack. 858 // Get rid of arguments pushed on the stack.
857 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp); 859 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize);
858 860
859 // Load Isolate pointer from Context structure into CTX. Drop Context. 861 // Load Isolate pointer from Context structure into CTX. Drop Context.
860 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset())); 862 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset()));
861 863
862 // Restore the saved Context pointer into the Isolate structure. 864 // Restore the saved Context pointer into the Isolate structure.
863 // Uses R4 as a temporary register for this. 865 // Uses R4 as a temporary register for this.
864 // Restore the saved top exit frame info back into the Isolate structure. 866 // Restore the saved top exit frame info back into the Isolate structure.
865 // Uses R5 as a temporary register for this. 867 // Uses R5 as a temporary register for this.
866 __ PopList((1 << R4) | (1 << R5)); 868 __ PopList((1 << R4) | (1 << R5));
867 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset()); 869 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset());
868 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset()); 870 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset());
869 871
870 // Restore C++ ABI callee-saved registers. 872 // Restore C++ ABI callee-saved registers.
873 // Restore FPU registers. 2 D registers per Q register.
874 __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
875 // Restore CPU registers.
871 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3. 876 __ PopList((1 << R3) | kAbiPreservedCpuRegs); // Ignore restored R3.
872 877
873 // Restore the frame pointer and return. 878 // Restore the frame pointer and return.
874 __ LeaveStubFrame(); 879 __ LeaveStubFrame();
875 __ Ret(); 880 __ Ret();
876 } 881 }
877 882
878 883
879 // Called for inline allocation of contexts. 884 // Called for inline allocation of contexts.
880 // Input: 885 // Input:
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after
2178 __ ldr(left, Address(SP, 4 * kWordSize)); 2183 __ ldr(left, Address(SP, 4 * kWordSize));
2179 __ ldr(right, Address(SP, 3 * kWordSize)); 2184 __ ldr(right, Address(SP, 3 * kWordSize));
2180 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2185 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2181 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 2186 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
2182 __ Ret(); 2187 __ Ret();
2183 } 2188 }
2184 2189
2185 } // namespace dart 2190 } // namespace dart
2186 2191
2187 #endif // defined TARGET_ARCH_ARM 2192 #endif // defined TARGET_ARCH_ARM
OLDNEW
« runtime/vm/assembler_arm.cc ('K') | « runtime/vm/stack_frame_arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698