OLD | NEW |
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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
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 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 // A0 : entrypoint of the Dart function to call. | 903 // A0 : entrypoint of the Dart function to call. |
904 // A1 : arguments descriptor array. | 904 // A1 : arguments descriptor array. |
905 // A2 : arguments array. | 905 // A2 : arguments array. |
906 // A3 : new context containing the current isolate pointer. | 906 // A3 : new context containing the current isolate pointer. |
907 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 907 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
908 // Save frame pointer coming in. | 908 // Save frame pointer coming in. |
909 __ TraceSimMsg("InvokeDartCodeStub"); | 909 __ TraceSimMsg("InvokeDartCodeStub"); |
910 __ EnterStubFrame(); | 910 __ EnterStubFrame(); |
911 | 911 |
912 // Save new context and C++ ABI callee-saved registers. | 912 // Save new context and C++ ABI callee-saved registers. |
913 const intptr_t kNewContextOffset = | |
914 -(1 + kAbiPreservedCpuRegCount) * kWordSize; | |
915 | 913 |
916 __ addiu(SP, SP, Immediate(-(3 + kAbiPreservedCpuRegCount) * kWordSize)); | 914 // The new context, the top exit frame, and the old context. |
| 915 const intptr_t kPreservedContextSlots = 3; |
| 916 const intptr_t kNewContextOffsetFromFp = |
| 917 -(1 + kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount) * kWordSize; |
| 918 const intptr_t kPreservedRegSpace = |
| 919 kWordSize * (kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount + |
| 920 kPreservedContextSlots); |
| 921 |
| 922 __ addiu(SP, SP, Immediate(-kPreservedRegSpace)); |
917 for (int i = S0; i <= S7; i++) { | 923 for (int i = S0; i <= S7; i++) { |
918 Register r = static_cast<Register>(i); | 924 Register r = static_cast<Register>(i); |
919 __ sw(r, Address(SP, (i - S0 + 3) * kWordSize)); | 925 const intptr_t slot = i - S0 + kPreservedContextSlots; |
| 926 __ sw(r, Address(SP, slot * kWordSize)); |
920 } | 927 } |
| 928 |
| 929 for (intptr_t i = kAbiFirstPreservedFpuReg; |
| 930 i <= kAbiLastPreservedFpuReg; i++) { |
| 931 FRegister r = static_cast<FRegister>(i); |
| 932 const intptr_t slot = |
| 933 kAbiPreservedCpuRegCount + kPreservedContextSlots + i - |
| 934 kAbiFirstPreservedFpuReg; |
| 935 __ swc1(r, Address(SP, slot * kWordSize)); |
| 936 } |
| 937 |
921 __ sw(A3, Address(SP, 2 * kWordSize)); | 938 __ sw(A3, Address(SP, 2 * kWordSize)); |
922 | 939 |
923 // The new Context structure contains a pointer to the current Isolate | 940 // The new Context structure contains a pointer to the current Isolate |
924 // structure. Cache the Context pointer in the CTX register so that it is | 941 // structure. Cache the Context pointer in the CTX register so that it is |
925 // available in generated code and calls to Isolate::Current() need not be | 942 // available in generated code and calls to Isolate::Current() need not be |
926 // done. The assumption is that this register will never be clobbered by | 943 // done. The assumption is that this register will never be clobbered by |
927 // compiled or runtime stub code. | 944 // compiled or runtime stub code. |
928 | 945 |
929 // Cache the new Context pointer into CTX while executing Dart code. | 946 // Cache the new Context pointer into CTX while executing Dart code. |
930 __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle)); | 947 __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle)); |
931 | 948 |
932 // Load Isolate pointer from Context structure into temporary register R8. | 949 // Load Isolate pointer from Context structure into temporary register R8. |
933 __ lw(T2, FieldAddress(CTX, Context::isolate_offset())); | 950 __ lw(T2, FieldAddress(CTX, Context::isolate_offset())); |
934 | 951 |
935 // Save the top exit frame info. Use T0 as a temporary register. | 952 // Save the top exit frame info. Use T0 as a temporary register. |
936 // StackFrameIterator reads the top exit frame info saved in this frame. | 953 // StackFrameIterator reads the top exit frame info saved in this frame. |
937 __ lw(T0, Address(T2, Isolate::top_exit_frame_info_offset())); | 954 __ lw(T0, Address(T2, Isolate::top_exit_frame_info_offset())); |
938 __ sw(ZR, Address(T2, Isolate::top_exit_frame_info_offset())); | 955 __ sw(ZR, Address(T2, Isolate::top_exit_frame_info_offset())); |
939 | 956 |
940 // Save the old Context pointer. Use T1 as a temporary register. | 957 // Save the old Context pointer. Use T1 as a temporary register. |
941 // Note that VisitObjectPointers will find this saved Context pointer during | 958 // Note that VisitObjectPointers will find this saved Context pointer during |
942 // GC marking, since it traverses any information between SP and | 959 // GC marking, since it traverses any information between SP and |
943 // FP - kExitLinkSlotFromEntryFp. | 960 // FP - kExitLinkSlotFromEntryFp. |
944 // EntryFrame::SavedContext reads the context saved in this frame. | 961 // EntryFrame::SavedContext reads the context saved in this frame. |
945 __ lw(T1, Address(T2, Isolate::top_context_offset())); | 962 __ lw(T1, Address(T2, Isolate::top_context_offset())); |
946 | 963 |
947 // The constants kSavedContextSlotFromEntryFp and | 964 // The constants kSavedContextSlotFromEntryFp and |
948 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. | 965 // kExitLinkSlotFromEntryFp must be kept in sync with the code below. |
949 ASSERT(kExitLinkSlotFromEntryFp == -10); | 966 ASSERT(kExitLinkSlotFromEntryFp == -22); |
950 ASSERT(kSavedContextSlotFromEntryFp == -11); | 967 ASSERT(kSavedContextSlotFromEntryFp == -23); |
951 __ sw(T0, Address(SP, 1 * kWordSize)); | 968 __ sw(T0, Address(SP, 1 * kWordSize)); |
952 __ sw(T1, Address(SP, 0 * kWordSize)); | 969 __ sw(T1, Address(SP, 0 * kWordSize)); |
953 | 970 |
954 // After the call, The stack pointer is restored to this location. | 971 // After the call, The stack pointer is restored to this location. |
955 // Pushed A3, S0-7, T0, T1 = 11. | 972 // Pushed A3, S0-7, F20-31, T0, T1 = 23. |
956 | 973 |
957 // Load arguments descriptor array into S4, which is passed to Dart code. | 974 // Load arguments descriptor array into S4, which is passed to Dart code. |
958 __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle)); | 975 __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle)); |
959 | 976 |
960 // Load number of arguments into S5. | 977 // Load number of arguments into S5. |
961 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | 978 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
962 __ SmiUntag(T1); | 979 __ SmiUntag(T1); |
963 | 980 |
964 // Compute address of 'arguments array' data area into A2. | 981 // Compute address of 'arguments array' data area into A2. |
965 __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); | 982 __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); |
(...skipping 12 matching lines...) Expand all Loading... |
978 __ BranchSignedLess(A1, T1, &push_arguments); | 995 __ BranchSignedLess(A1, T1, &push_arguments); |
979 __ delay_slot()->addiu(A2, A2, Immediate(kWordSize)); | 996 __ delay_slot()->addiu(A2, A2, Immediate(kWordSize)); |
980 | 997 |
981 __ Bind(&done_push_arguments); | 998 __ Bind(&done_push_arguments); |
982 | 999 |
983 // Call the Dart code entrypoint. | 1000 // Call the Dart code entrypoint. |
984 __ jalr(A0); // S4 is the arguments descriptor array. | 1001 __ jalr(A0); // S4 is the arguments descriptor array. |
985 __ TraceSimMsg("InvokeDartCodeStub return"); | 1002 __ TraceSimMsg("InvokeDartCodeStub return"); |
986 | 1003 |
987 // Read the saved new Context pointer. | 1004 // Read the saved new Context pointer. |
988 __ lw(CTX, Address(FP, kNewContextOffset)); | 1005 __ lw(CTX, Address(FP, kNewContextOffsetFromFp)); |
989 __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); | 1006 __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); |
990 | 1007 |
991 // Get rid of arguments pushed on the stack. | 1008 // Get rid of arguments pushed on the stack. |
992 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); | 1009 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); |
993 | 1010 |
994 // Load Isolate pointer from Context structure into CTX. Drop Context. | 1011 // Load Isolate pointer from Context structure into CTX. Drop Context. |
995 __ lw(CTX, FieldAddress(CTX, Context::isolate_offset())); | 1012 __ lw(CTX, FieldAddress(CTX, Context::isolate_offset())); |
996 | 1013 |
997 // Restore the saved Context pointer into the Isolate structure. | 1014 // Restore the saved Context pointer into the Isolate structure. |
998 // Uses T1 as a temporary register for this. | 1015 // Uses T1 as a temporary register for this. |
999 // Restore the saved top exit frame info back into the Isolate structure. | 1016 // Restore the saved top exit frame info back into the Isolate structure. |
1000 // Uses T0 as a temporary register for this. | 1017 // Uses T0 as a temporary register for this. |
1001 __ lw(T1, Address(SP, 0 * kWordSize)); | 1018 __ lw(T1, Address(SP, 0 * kWordSize)); |
1002 __ lw(T0, Address(SP, 1 * kWordSize)); | 1019 __ lw(T0, Address(SP, 1 * kWordSize)); |
1003 __ sw(T1, Address(CTX, Isolate::top_context_offset())); | 1020 __ sw(T1, Address(CTX, Isolate::top_context_offset())); |
1004 __ sw(T0, Address(CTX, Isolate::top_exit_frame_info_offset())); | 1021 __ sw(T0, Address(CTX, Isolate::top_exit_frame_info_offset())); |
1005 | 1022 |
1006 // Restore C++ ABI callee-saved registers. | 1023 // Restore C++ ABI callee-saved registers. |
1007 for (int i = S0; i <= S7; i++) { | 1024 for (int i = S0; i <= S7; i++) { |
1008 Register r = static_cast<Register>(i); | 1025 Register r = static_cast<Register>(i); |
1009 __ lw(r, Address(SP, (i - S0 + 3) * kWordSize)); | 1026 const intptr_t slot = i - S0 + kPreservedContextSlots; |
| 1027 __ lw(r, Address(SP, slot * kWordSize)); |
1010 } | 1028 } |
| 1029 |
| 1030 for (intptr_t i = kAbiFirstPreservedFpuReg; |
| 1031 i <= kAbiLastPreservedFpuReg; i++) { |
| 1032 FRegister r = static_cast<FRegister>(i); |
| 1033 const intptr_t slot = |
| 1034 kAbiPreservedCpuRegCount + kPreservedContextSlots + i - |
| 1035 kAbiFirstPreservedFpuReg; |
| 1036 __ lwc1(r, Address(SP, slot * kWordSize)); |
| 1037 } |
| 1038 |
1011 __ lw(A3, Address(SP, 2 * kWordSize)); | 1039 __ lw(A3, Address(SP, 2 * kWordSize)); |
1012 __ addiu(SP, SP, Immediate((3 + kAbiPreservedCpuRegCount) * kWordSize)); | 1040 __ addiu(SP, SP, Immediate(kPreservedRegSpace)); |
1013 | 1041 |
1014 // Restore the frame pointer and return. | 1042 // Restore the frame pointer and return. |
1015 __ LeaveStubFrameAndReturn(); | 1043 __ LeaveStubFrameAndReturn(); |
1016 } | 1044 } |
1017 | 1045 |
1018 | 1046 |
1019 // Called for inline allocation of contexts. | 1047 // Called for inline allocation of contexts. |
1020 // Input: | 1048 // Input: |
1021 // T1: number of context variables. | 1049 // T1: number of context variables. |
1022 // Output: | 1050 // Output: |
(...skipping 1440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2463 __ lw(left, Address(SP, 1 * kWordSize)); | 2491 __ lw(left, Address(SP, 1 * kWordSize)); |
2464 __ lw(temp2, Address(SP, 2 * kWordSize)); | 2492 __ lw(temp2, Address(SP, 2 * kWordSize)); |
2465 __ lw(temp1, Address(SP, 3 * kWordSize)); | 2493 __ lw(temp1, Address(SP, 3 * kWordSize)); |
2466 __ Ret(); | 2494 __ Ret(); |
2467 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); | 2495 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); |
2468 } | 2496 } |
2469 | 2497 |
2470 } // namespace dart | 2498 } // namespace dart |
2471 | 2499 |
2472 #endif // defined TARGET_ARCH_MIPS | 2500 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |