| 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 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 | 867 |
| 868 // The new Context structure contains a pointer to the current Isolate | 868 // The new Context structure contains a pointer to the current Isolate |
| 869 // structure. Cache the Context pointer in the CTX register so that it is | 869 // structure. Cache the Context pointer in the CTX register so that it is |
| 870 // available in generated code and calls to Isolate::Current() need not be | 870 // available in generated code and calls to Isolate::Current() need not be |
| 871 // done. The assumption is that this register will never be clobbered by | 871 // done. The assumption is that this register will never be clobbered by |
| 872 // compiled or runtime stub code. | 872 // compiled or runtime stub code. |
| 873 | 873 |
| 874 // Cache the new Context pointer into CTX while executing Dart code. | 874 // Cache the new Context pointer into CTX while executing Dart code. |
| 875 __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle)); | 875 __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle)); |
| 876 | 876 |
| 877 // Load Isolate pointer from Context structure into temporary register R8. | 877 __ LoadImmediate(T2, Isolate::CurrentAddress()); |
| 878 __ lw(T2, FieldAddress(CTX, Context::isolate_offset())); | |
| 879 | 878 |
| 880 // Save the current VMTag on the stack. | 879 // Save the current VMTag on the stack. |
| 881 ASSERT(kSavedVMTagSlotFromEntryFp == -22); | 880 ASSERT(kSavedVMTagSlotFromEntryFp == -22); |
| 882 __ lw(T1, Address(T2, Isolate::vm_tag_offset())); | 881 __ lw(T1, Address(T2, Isolate::vm_tag_offset())); |
| 883 __ sw(T1, Address(SP, 2 * kWordSize)); | 882 __ sw(T1, Address(SP, 2 * kWordSize)); |
| 884 | 883 |
| 885 // Mark that the isolate is executing Dart code. | 884 // Mark that the isolate is executing Dart code. |
| 886 __ LoadImmediate(T0, VMTag::kDartTagId); | 885 __ LoadImmediate(T0, VMTag::kDartTagId); |
| 887 __ sw(T0, Address(T2, Isolate::vm_tag_offset())); | 886 __ sw(T0, Address(T2, Isolate::vm_tag_offset())); |
| 888 | 887 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 __ jalr(A0); // S4 is the arguments descriptor array. | 939 __ jalr(A0); // S4 is the arguments descriptor array. |
| 941 __ TraceSimMsg("InvokeDartCodeStub return"); | 940 __ TraceSimMsg("InvokeDartCodeStub return"); |
| 942 | 941 |
| 943 // Read the saved new Context pointer. | 942 // Read the saved new Context pointer. |
| 944 __ lw(CTX, Address(FP, kNewContextOffsetFromFp)); | 943 __ lw(CTX, Address(FP, kNewContextOffsetFromFp)); |
| 945 __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); | 944 __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); |
| 946 | 945 |
| 947 // Get rid of arguments pushed on the stack. | 946 // Get rid of arguments pushed on the stack. |
| 948 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); | 947 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); |
| 949 | 948 |
| 950 // Load Isolate pointer from Context structure into CTX. Drop Context. | 949 // Load Isolate pointer into CTX. Drop Context. |
| 951 __ lw(CTX, FieldAddress(CTX, Context::isolate_offset())); | 950 __ LoadImmediate(CTX, Isolate::CurrentAddress()); |
| 952 | 951 |
| 953 // Restore the current VMTag from the stack. | 952 // Restore the current VMTag from the stack. |
| 954 __ lw(T1, Address(SP, 2 * kWordSize)); | 953 __ lw(T1, Address(SP, 2 * kWordSize)); |
| 955 __ sw(T1, Address(CTX, Isolate::vm_tag_offset())); | 954 __ sw(T1, Address(CTX, Isolate::vm_tag_offset())); |
| 956 | 955 |
| 957 // Restore the saved Context pointer into the Isolate structure. | 956 // Restore the saved Context pointer into the Isolate structure. |
| 958 // Uses T1 as a temporary register for this. | 957 // Uses T1 as a temporary register for this. |
| 959 // Restore the saved top exit frame info back into the Isolate structure. | 958 // Restore the saved top exit frame info back into the Isolate structure. |
| 960 // Uses T0 as a temporary register for this. | 959 // Uses T0 as a temporary register for this. |
| 961 __ lw(T1, Address(SP, 0 * kWordSize)); | 960 __ lw(T1, Address(SP, 0 * kWordSize)); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(context_class.id())); | 1053 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(context_class.id())); |
| 1055 __ or_(T2, T2, TMP); | 1054 __ or_(T2, T2, TMP); |
| 1056 __ sw(T2, FieldAddress(V0, Context::tags_offset())); | 1055 __ sw(T2, FieldAddress(V0, Context::tags_offset())); |
| 1057 | 1056 |
| 1058 // Setup up number of context variables field. | 1057 // Setup up number of context variables field. |
| 1059 // V0: new object. | 1058 // V0: new object. |
| 1060 // T1: number of context variables as integer value (not object). | 1059 // T1: number of context variables as integer value (not object). |
| 1061 __ sw(T1, FieldAddress(V0, Context::num_variables_offset())); | 1060 __ sw(T1, FieldAddress(V0, Context::num_variables_offset())); |
| 1062 | 1061 |
| 1063 // Setup isolate field. | 1062 // Setup isolate field. |
| 1064 // Load Isolate pointer from Context structure into R2. | |
| 1065 // V0: new object. | 1063 // V0: new object. |
| 1066 // T1: number of context variables. | 1064 // T1: number of context variables. |
| 1067 __ lw(T2, FieldAddress(CTX, Context::isolate_offset())); | |
| 1068 // T2: isolate, not an object. | 1065 // T2: isolate, not an object. |
| 1066 __ LoadImmediate(T2, Isolate::CurrentAddress()); |
| 1069 __ sw(T2, FieldAddress(V0, Context::isolate_offset())); | 1067 __ sw(T2, FieldAddress(V0, Context::isolate_offset())); |
| 1070 | 1068 |
| 1071 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); | 1069 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
| 1072 | 1070 |
| 1073 // Initialize the context variables. | 1071 // Initialize the context variables. |
| 1074 // V0: new object. | 1072 // V0: new object. |
| 1075 // T1: number of context variables. | 1073 // T1: number of context variables. |
| 1076 Label loop, loop_exit; | 1074 Label loop, loop_exit; |
| 1077 __ blez(T1, &loop_exit); | 1075 __ blez(T1, &loop_exit); |
| 1078 // Setup the parent field. | 1076 // Setup the parent field. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 __ lw(T1, Address(SP, 0 * kWordSize)); | 1134 __ lw(T1, Address(SP, 0 * kWordSize)); |
| 1137 __ lw(T2, Address(SP, 1 * kWordSize)); | 1135 __ lw(T2, Address(SP, 1 * kWordSize)); |
| 1138 __ lw(T3, Address(SP, 2 * kWordSize)); | 1136 __ lw(T3, Address(SP, 2 * kWordSize)); |
| 1139 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 1137 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
| 1140 __ Ret(); | 1138 __ Ret(); |
| 1141 | 1139 |
| 1142 __ Bind(&add_to_buffer); | 1140 __ Bind(&add_to_buffer); |
| 1143 __ ori(T2, T2, Immediate(1 << RawObject::kRememberedBit)); | 1141 __ ori(T2, T2, Immediate(1 << RawObject::kRememberedBit)); |
| 1144 __ sw(T2, FieldAddress(T0, Object::tags_offset())); | 1142 __ sw(T2, FieldAddress(T0, Object::tags_offset())); |
| 1145 | 1143 |
| 1146 // Load the isolate out of the context. | 1144 // Load the isolate. |
| 1147 // Spilled: T1, T2, T3. | 1145 // Spilled: T1, T2, T3. |
| 1148 // T0: Address being stored. | 1146 // T0: Address being stored. |
| 1149 __ lw(T1, FieldAddress(CTX, Context::isolate_offset())); | 1147 __ LoadImmediate(T1, Isolate::CurrentAddress()); |
| 1150 | 1148 |
| 1151 // Load the StoreBuffer block out of the isolate. Then load top_ out of the | 1149 // Load the StoreBuffer block out of the isolate. Then load top_ out of the |
| 1152 // StoreBufferBlock and add the address to the pointers_. | 1150 // StoreBufferBlock and add the address to the pointers_. |
| 1153 // T1: Isolate. | 1151 // T1: Isolate. |
| 1154 __ lw(T1, Address(T1, Isolate::store_buffer_offset())); | 1152 __ lw(T1, Address(T1, Isolate::store_buffer_offset())); |
| 1155 __ lw(T2, Address(T1, StoreBufferBlock::top_offset())); | 1153 __ lw(T2, Address(T1, StoreBufferBlock::top_offset())); |
| 1156 __ sll(T3, T2, 2); | 1154 __ sll(T3, T2, 2); |
| 1157 __ addu(T3, T1, T3); | 1155 __ addu(T3, T1, T3); |
| 1158 __ sw(T0, Address(T3, StoreBufferBlock::pointers_offset())); | 1156 __ sw(T0, Address(T3, StoreBufferBlock::pointers_offset())); |
| 1159 | 1157 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1170 __ lw(T3, Address(SP, 2 * kWordSize)); | 1168 __ lw(T3, Address(SP, 2 * kWordSize)); |
| 1171 __ beq(CMPRES1, ZR, &L); | 1169 __ beq(CMPRES1, ZR, &L); |
| 1172 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); | 1170 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); |
| 1173 __ Ret(); | 1171 __ Ret(); |
| 1174 | 1172 |
| 1175 // Handle overflow: Call the runtime leaf function. | 1173 // Handle overflow: Call the runtime leaf function. |
| 1176 __ Bind(&L); | 1174 __ Bind(&L); |
| 1177 // Setup frame, push callee-saved registers. | 1175 // Setup frame, push callee-saved registers. |
| 1178 | 1176 |
| 1179 __ EnterCallRuntimeFrame(1 * kWordSize); | 1177 __ EnterCallRuntimeFrame(1 * kWordSize); |
| 1180 __ lw(A0, FieldAddress(CTX, Context::isolate_offset())); | 1178 __ LoadImmediate(A0, Isolate::CurrentAddress()); |
| 1181 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); | 1179 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
| 1182 __ TraceSimMsg("UpdateStoreBufferStub return"); | 1180 __ TraceSimMsg("UpdateStoreBufferStub return"); |
| 1183 // Restore callee-saved registers, tear down frame. | 1181 // Restore callee-saved registers, tear down frame. |
| 1184 __ LeaveCallRuntimeFrame(); | 1182 __ LeaveCallRuntimeFrame(); |
| 1185 __ Ret(); | 1183 __ Ret(); |
| 1186 } | 1184 } |
| 1187 | 1185 |
| 1188 | 1186 |
| 1189 // Called for inline allocation of objects. | 1187 // Called for inline allocation of objects. |
| 1190 // Input parameters: | 1188 // Input parameters: |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset())); | 1488 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset())); |
| 1491 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1489 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1492 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); | 1490 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); |
| 1493 __ BranchEqual(T0, num_args, &ok); | 1491 __ BranchEqual(T0, num_args, &ok); |
| 1494 __ Stop("Incorrect stub for IC data"); | 1492 __ Stop("Incorrect stub for IC data"); |
| 1495 __ Bind(&ok); | 1493 __ Bind(&ok); |
| 1496 } | 1494 } |
| 1497 #endif // DEBUG | 1495 #endif // DEBUG |
| 1498 | 1496 |
| 1499 | 1497 |
| 1498 // Check single stepping. |
| 1500 Label stepping, done_stepping; | 1499 Label stepping, done_stepping; |
| 1501 // Check single stepping. | 1500 __ LoadImmediate(T0, Isolate::CurrentAddress()); |
| 1502 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | |
| 1503 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 1501 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
| 1504 __ BranchNotEqual(T0, 0, &stepping); | 1502 __ BranchNotEqual(T0, 0, &stepping); |
| 1505 __ Bind(&done_stepping); | 1503 __ Bind(&done_stepping); |
| 1506 | 1504 |
| 1507 if (kind != Token::kILLEGAL) { | 1505 if (kind != Token::kILLEGAL) { |
| 1508 Label not_smi_or_overflow; | 1506 Label not_smi_or_overflow; |
| 1509 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); | 1507 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); |
| 1510 __ Bind(¬_smi_or_overflow); | 1508 __ Bind(¬_smi_or_overflow); |
| 1511 } | 1509 } |
| 1512 | 1510 |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1748 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1746 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1749 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); | 1747 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); |
| 1750 __ beq(T0, ZR, &ok); | 1748 __ beq(T0, ZR, &ok); |
| 1751 __ Stop("Incorrect IC data for unoptimized static call"); | 1749 __ Stop("Incorrect IC data for unoptimized static call"); |
| 1752 __ Bind(&ok); | 1750 __ Bind(&ok); |
| 1753 } | 1751 } |
| 1754 #endif // DEBUG | 1752 #endif // DEBUG |
| 1755 | 1753 |
| 1756 // Check single stepping. | 1754 // Check single stepping. |
| 1757 Label stepping, done_stepping; | 1755 Label stepping, done_stepping; |
| 1758 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 1756 __ LoadImmediate(T0, Isolate::CurrentAddress()); |
| 1759 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 1757 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
| 1760 __ BranchNotEqual(T0, 0, &stepping); | 1758 __ BranchNotEqual(T0, 0, &stepping); |
| 1761 __ Bind(&done_stepping); | 1759 __ Bind(&done_stepping); |
| 1762 | 1760 |
| 1763 // S5: IC data object (preserved). | 1761 // S5: IC data object (preserved). |
| 1764 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); | 1762 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); |
| 1765 // T0: ic_data_array with entries: target functions and count. | 1763 // T0: ic_data_array with entries: target functions and count. |
| 1766 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); | 1764 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); |
| 1767 // T0: points directly to the first ic data array element. | 1765 // T0: points directly to the first ic data array element. |
| 1768 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; | 1766 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2229 const Register right = T0; | 2227 const Register right = T0; |
| 2230 __ lw(left, Address(SP, 1 * kWordSize)); | 2228 __ lw(left, Address(SP, 1 * kWordSize)); |
| 2231 __ lw(right, Address(SP, 0 * kWordSize)); | 2229 __ lw(right, Address(SP, 0 * kWordSize)); |
| 2232 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2230 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
| 2233 __ Ret(); | 2231 __ Ret(); |
| 2234 } | 2232 } |
| 2235 | 2233 |
| 2236 } // namespace dart | 2234 } // namespace dart |
| 2237 | 2235 |
| 2238 #endif // defined TARGET_ARCH_MIPS | 2236 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |