| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
| 6 | 6 |
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 __ Dsubu(a0, a0, Operand(1)); | 1243 __ Dsubu(a0, a0, Operand(1)); |
| 1244 __ Pop(); | 1244 __ Pop(); |
| 1245 } | 1245 } |
| 1246 | 1246 |
| 1247 // 4. Call the callable. | 1247 // 4. Call the callable. |
| 1248 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1248 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1249 } | 1249 } |
| 1250 | 1250 |
| 1251 | 1251 |
| 1252 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1252 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
| 1253 const int vectorOffset, |
| 1253 const int argumentsOffset, | 1254 const int argumentsOffset, |
| 1254 const int indexOffset, | 1255 const int indexOffset, |
| 1255 const int limitOffset) { | 1256 const int limitOffset) { |
| 1256 Label entry, loop; | 1257 Label entry, loop; |
| 1257 Register receiver = LoadDescriptor::ReceiverRegister(); | 1258 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 1258 Register key = LoadDescriptor::NameRegister(); | 1259 Register key = LoadDescriptor::NameRegister(); |
| 1259 Register slot = LoadDescriptor::SlotRegister(); | 1260 Register slot = LoadDescriptor::SlotRegister(); |
| 1260 Register vector = LoadWithVectorDescriptor::VectorRegister(); | 1261 Register vector = LoadWithVectorDescriptor::VectorRegister(); |
| 1261 | 1262 |
| 1262 __ ld(key, MemOperand(fp, indexOffset)); | 1263 __ ld(key, MemOperand(fp, indexOffset)); |
| 1263 __ Branch(&entry); | 1264 __ Branch(&entry); |
| 1264 | 1265 |
| 1265 // Load the current argument from the arguments array. | 1266 // Load the current argument from the arguments array. |
| 1266 __ bind(&loop); | 1267 __ bind(&loop); |
| 1267 __ ld(receiver, MemOperand(fp, argumentsOffset)); | 1268 __ ld(receiver, MemOperand(fp, argumentsOffset)); |
| 1268 | 1269 |
| 1269 // Use inline caching to speed up access to arguments. | 1270 // Use inline caching to speed up access to arguments. |
| 1270 Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; | 1271 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex(); |
| 1271 FeedbackVectorSpec spec(0, 1, kinds); | 1272 __ li(slot, Operand(Smi::FromInt(slot_index))); |
| 1272 Handle<TypeFeedbackVector> feedback_vector = | 1273 __ ld(vector, MemOperand(fp, vectorOffset)); |
| 1273 masm->isolate()->factory()->NewTypeFeedbackVector(&spec); | |
| 1274 int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0)); | |
| 1275 __ li(slot, Operand(Smi::FromInt(index))); | |
| 1276 __ li(vector, feedback_vector); | |
| 1277 Handle<Code> ic = | 1274 Handle<Code> ic = |
| 1278 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); | 1275 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); |
| 1279 __ Call(ic, RelocInfo::CODE_TARGET); | 1276 __ Call(ic, RelocInfo::CODE_TARGET); |
| 1280 | 1277 |
| 1281 __ push(v0); | 1278 __ push(v0); |
| 1282 | 1279 |
| 1283 // Use inline caching to access the arguments. | 1280 // Use inline caching to access the arguments. |
| 1284 __ ld(key, MemOperand(fp, indexOffset)); | 1281 __ ld(key, MemOperand(fp, indexOffset)); |
| 1285 __ Daddu(key, key, Operand(Smi::FromInt(1))); | 1282 __ Daddu(key, key, Operand(Smi::FromInt(1))); |
| 1286 __ sd(key, MemOperand(fp, indexOffset)); | 1283 __ sd(key, MemOperand(fp, indexOffset)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1300 // Used by FunctionApply and ReflectApply | 1297 // Used by FunctionApply and ReflectApply |
| 1301 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { | 1298 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { |
| 1302 const int kFormalParameters = targetIsArgument ? 3 : 2; | 1299 const int kFormalParameters = targetIsArgument ? 3 : 2; |
| 1303 const int kStackSize = kFormalParameters + 1; | 1300 const int kStackSize = kFormalParameters + 1; |
| 1304 | 1301 |
| 1305 { | 1302 { |
| 1306 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1303 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 1307 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1304 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
| 1308 const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1305 const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
| 1309 const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1306 const int kFunctionOffset = kReceiverOffset + kPointerSize; |
| 1307 const int kVectorOffset = |
| 1308 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1309 |
| 1310 // Push the vector. |
| 1311 __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1312 __ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1313 __ Push(a1); |
| 1310 | 1314 |
| 1311 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function. | 1315 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function. |
| 1312 __ ld(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array. | 1316 __ ld(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array. |
| 1313 __ Push(a0, a1); | 1317 __ Push(a0, a1); |
| 1314 | 1318 |
| 1315 // Returns (in v0) number of arguments to copy to stack as Smi. | 1319 // Returns (in v0) number of arguments to copy to stack as Smi. |
| 1316 if (targetIsArgument) { | 1320 if (targetIsArgument) { |
| 1317 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, | 1321 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
| 1318 CALL_FUNCTION); | 1322 CALL_FUNCTION); |
| 1319 } else { | 1323 } else { |
| 1320 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); | 1324 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
| 1321 } | 1325 } |
| 1322 | 1326 |
| 1323 // Returns the result in v0. | 1327 // Returns the result in v0. |
| 1324 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); | 1328 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
| 1325 | 1329 |
| 1326 // Push current limit and index. | 1330 // Push current limit and index. |
| 1327 const int kIndexOffset = | 1331 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
| 1328 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1332 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
| 1329 const int kLimitOffset = | |
| 1330 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
| 1331 __ mov(a1, zero_reg); | 1333 __ mov(a1, zero_reg); |
| 1332 __ ld(a2, MemOperand(fp, kReceiverOffset)); | 1334 __ ld(a2, MemOperand(fp, kReceiverOffset)); |
| 1333 __ Push(v0, a1, a2); // limit, initial index and receiver. | 1335 __ Push(v0, a1, a2); // limit, initial index and receiver. |
| 1334 | 1336 |
| 1335 // Copy all arguments from the array to the stack. | 1337 // Copy all arguments from the array to the stack. |
| 1336 Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, | 1338 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
| 1337 kLimitOffset); | 1339 kIndexOffset, kLimitOffset); |
| 1338 | 1340 |
| 1339 // Call the callable. | 1341 // Call the callable. |
| 1340 // TODO(bmeurer): This should be a tail call according to ES6. | 1342 // TODO(bmeurer): This should be a tail call according to ES6. |
| 1341 __ ld(a1, MemOperand(fp, kFunctionOffset)); | 1343 __ ld(a1, MemOperand(fp, kFunctionOffset)); |
| 1342 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1344 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1343 | 1345 |
| 1344 // Tear down the internal frame and remove function, receiver and args. | 1346 // Tear down the internal frame and remove function, receiver and args. |
| 1345 } | 1347 } |
| 1346 | 1348 |
| 1347 __ Ret(USE_DELAY_SLOT); | 1349 __ Ret(USE_DELAY_SLOT); |
| 1348 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot. | 1350 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot. |
| 1349 } | 1351 } |
| 1350 | 1352 |
| 1351 | 1353 |
| 1352 static void Generate_ConstructHelper(MacroAssembler* masm) { | 1354 static void Generate_ConstructHelper(MacroAssembler* masm) { |
| 1353 const int kFormalParameters = 3; | 1355 const int kFormalParameters = 3; |
| 1354 const int kStackSize = kFormalParameters + 1; | 1356 const int kStackSize = kFormalParameters + 1; |
| 1355 | 1357 |
| 1356 { | 1358 { |
| 1357 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1359 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 1358 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1360 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
| 1359 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1361 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
| 1360 const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1362 const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
| 1363 const int kVectorOffset = |
| 1364 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1365 |
| 1366 // Push the vector. |
| 1367 __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1368 __ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1369 __ Push(a1); |
| 1361 | 1370 |
| 1362 // If newTarget is not supplied, set it to constructor | 1371 // If newTarget is not supplied, set it to constructor |
| 1363 Label validate_arguments; | 1372 Label validate_arguments; |
| 1364 __ ld(a0, MemOperand(fp, kNewTargetOffset)); | 1373 __ ld(a0, MemOperand(fp, kNewTargetOffset)); |
| 1365 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 1374 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 1366 __ Branch(&validate_arguments, ne, a0, Operand(at)); | 1375 __ Branch(&validate_arguments, ne, a0, Operand(at)); |
| 1367 __ ld(a0, MemOperand(fp, kFunctionOffset)); | 1376 __ ld(a0, MemOperand(fp, kFunctionOffset)); |
| 1368 __ sd(a0, MemOperand(fp, kNewTargetOffset)); | 1377 __ sd(a0, MemOperand(fp, kNewTargetOffset)); |
| 1369 | 1378 |
| 1370 // Validate arguments | 1379 // Validate arguments |
| 1371 __ bind(&validate_arguments); | 1380 __ bind(&validate_arguments); |
| 1372 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function | 1381 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function |
| 1373 __ push(a0); | 1382 __ push(a0); |
| 1374 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1383 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array |
| 1375 __ push(a0); | 1384 __ push(a0); |
| 1376 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1385 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target |
| 1377 __ push(a0); | 1386 __ push(a0); |
| 1378 // Returns argument count in v0. | 1387 // Returns argument count in v0. |
| 1379 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, | 1388 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
| 1380 CALL_FUNCTION); | 1389 CALL_FUNCTION); |
| 1381 | 1390 |
| 1382 // Returns result in v0. | 1391 // Returns result in v0. |
| 1383 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); | 1392 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
| 1384 | 1393 |
| 1385 // Push current limit and index. | 1394 // Push current limit and index. |
| 1386 const int kIndexOffset = | 1395 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
| 1387 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1396 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
| 1388 const int kLimitOffset = | |
| 1389 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
| 1390 __ push(v0); // limit | 1397 __ push(v0); // limit |
| 1391 __ mov(a1, zero_reg); // initial index | 1398 __ mov(a1, zero_reg); // initial index |
| 1392 __ push(a1); | 1399 __ push(a1); |
| 1393 // Push the constructor function as callee. | 1400 // Push the constructor function as callee. |
| 1394 __ ld(a0, MemOperand(fp, kFunctionOffset)); | 1401 __ ld(a0, MemOperand(fp, kFunctionOffset)); |
| 1395 __ push(a0); | 1402 __ push(a0); |
| 1396 | 1403 |
| 1397 // Copy all arguments from the array to the stack. | 1404 // Copy all arguments from the array to the stack. |
| 1398 Generate_PushAppliedArguments( | 1405 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
| 1399 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1406 kIndexOffset, kLimitOffset); |
| 1400 | 1407 |
| 1401 // Use undefined feedback vector | 1408 // Use undefined feedback vector |
| 1402 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 1409 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
| 1403 __ ld(a1, MemOperand(fp, kFunctionOffset)); | 1410 __ ld(a1, MemOperand(fp, kFunctionOffset)); |
| 1404 __ ld(a4, MemOperand(fp, kNewTargetOffset)); | 1411 __ ld(a4, MemOperand(fp, kNewTargetOffset)); |
| 1405 | 1412 |
| 1406 // Call the function. | 1413 // Call the function. |
| 1407 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); | 1414 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); |
| 1408 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 1415 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 1409 | 1416 |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1797 } | 1804 } |
| 1798 } | 1805 } |
| 1799 | 1806 |
| 1800 | 1807 |
| 1801 #undef __ | 1808 #undef __ |
| 1802 | 1809 |
| 1803 } // namespace internal | 1810 } // namespace internal |
| 1804 } // namespace v8 | 1811 } // namespace v8 |
| 1805 | 1812 |
| 1806 #endif // V8_TARGET_ARCH_MIPS64 | 1813 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |