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

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 602603005: MIPS: Minor fixes and additions needed for Turbofan. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/mips/deoptimizer-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_MIPS 7 #if V8_TARGET_ARCH_MIPS
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 1092
1093 1093
1094 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 1094 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
1095 CEntryStub stub(isolate, 1, kDontSaveFPRegs); 1095 CEntryStub stub(isolate, 1, kDontSaveFPRegs);
1096 stub.GetCode(); 1096 stub.GetCode();
1097 } 1097 }
1098 1098
1099 1099
1100 void CEntryStub::Generate(MacroAssembler* masm) { 1100 void CEntryStub::Generate(MacroAssembler* masm) {
1101 // Called from JavaScript; parameters are on stack as if calling JS function 1101 // Called from JavaScript; parameters are on stack as if calling JS function
1102 // s0: number of arguments including receiver 1102 // a0: number of arguments including receiver
1103 // s1: size of arguments excluding receiver 1103 // a1: pointer to builtin function
1104 // s2: pointer to builtin function
1105 // fp: frame pointer (restored after C call) 1104 // fp: frame pointer (restored after C call)
1106 // sp: stack pointer (restored as callee's sp after C call) 1105 // sp: stack pointer (restored as callee's sp after C call)
1107 // cp: current context (C callee-saved) 1106 // cp: current context (C callee-saved)
1108 1107
1109 ProfileEntryHookStub::MaybeCallEntryHook(masm); 1108 ProfileEntryHookStub::MaybeCallEntryHook(masm);
1110 1109
1111 // NOTE: s0-s2 hold the arguments of this function instead of a0-a2.
1112 // The reason for this is that these arguments would need to be saved anyway
1113 // so it's faster to set them up directly.
1114 // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction.
1115
1116 // Compute the argv pointer in a callee-saved register. 1110 // Compute the argv pointer in a callee-saved register.
1111 __ sll(s1, a0, kPointerSizeLog2);
1117 __ Addu(s1, sp, s1); 1112 __ Addu(s1, sp, s1);
1113 __ Subu(s1, s1, kPointerSize);
1118 1114
1119 // Enter the exit frame that transitions from JavaScript to C++. 1115 // Enter the exit frame that transitions from JavaScript to C++.
1120 FrameScope scope(masm, StackFrame::MANUAL); 1116 FrameScope scope(masm, StackFrame::MANUAL);
1121 __ EnterExitFrame(save_doubles()); 1117 __ EnterExitFrame(save_doubles());
1122 1118
1123 // s0: number of arguments including receiver (C callee-saved) 1119 // s0: number of arguments including receiver (C callee-saved)
1124 // s1: pointer to first argument (C callee-saved) 1120 // s1: pointer to first argument (C callee-saved)
1125 // s2: pointer to builtin function (C callee-saved) 1121 // s2: pointer to builtin function (C callee-saved)
1126 1122
1127 // Prepare arguments for C routine. 1123 // Prepare arguments for C routine.
1128 // a0 = argc 1124 // a0 = argc
1129 __ mov(a0, s0); 1125 __ mov(s0, a0);
1126 __ mov(s2, a1);
1130 // a1 = argv (set in the delay slot after find_ra below). 1127 // a1 = argv (set in the delay slot after find_ra below).
1131 1128
1132 // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We 1129 // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We
1133 // also need to reserve the 4 argument slots on the stack. 1130 // also need to reserve the 4 argument slots on the stack.
1134 1131
1135 __ AssertStackIsAligned(); 1132 __ AssertStackIsAligned();
1136 1133
1137 __ li(a2, Operand(ExternalReference::isolate_address(isolate()))); 1134 __ li(a2, Operand(ExternalReference::isolate_address(isolate())));
1138 1135
1139 // To let the GC traverse the return address of the exit frames, we need to 1136 // To let the GC traverse the return address of the exit frames, we need to
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 // Expected input (depending on whether args are in registers or on the stack): 1407 // Expected input (depending on whether args are in registers or on the stack):
1411 // * object: a0 or at sp + 1 * kPointerSize. 1408 // * object: a0 or at sp + 1 * kPointerSize.
1412 // * function: a1 or at sp. 1409 // * function: a1 or at sp.
1413 // 1410 //
1414 // An inlined call site may have been generated before calling this stub. 1411 // An inlined call site may have been generated before calling this stub.
1415 // In this case the offset to the inline site to patch is passed on the stack, 1412 // In this case the offset to the inline site to patch is passed on the stack,
1416 // in the safepoint slot for register t0. 1413 // in the safepoint slot for register t0.
1417 void InstanceofStub::Generate(MacroAssembler* masm) { 1414 void InstanceofStub::Generate(MacroAssembler* masm) {
1418 // Call site inlining and patching implies arguments in registers. 1415 // Call site inlining and patching implies arguments in registers.
1419 DCHECK(HasArgsInRegisters() || !HasCallSiteInlineCheck()); 1416 DCHECK(HasArgsInRegisters() || !HasCallSiteInlineCheck());
1420 // ReturnTrueFalse is only implemented for inlined call sites.
1421 DCHECK(!ReturnTrueFalseObject() || HasCallSiteInlineCheck());
1422 1417
1423 // Fixed register usage throughout the stub: 1418 // Fixed register usage throughout the stub:
1424 const Register object = a0; // Object (lhs). 1419 const Register object = a0; // Object (lhs).
1425 Register map = a3; // Map of the object. 1420 Register map = a3; // Map of the object.
1426 const Register function = a1; // Function (rhs). 1421 const Register function = a1; // Function (rhs).
1427 const Register prototype = t0; // Prototype of the function. 1422 const Register prototype = t0; // Prototype of the function.
1428 const Register inline_site = t5; 1423 const Register inline_site = t5;
1429 const Register scratch = a2; 1424 const Register scratch = a2;
1430 1425
1431 const int32_t kDeltaToLoadBoolResult = 5 * kPointerSize; 1426 const int32_t kDeltaToLoadBoolResult = 5 * kPointerSize;
1432 1427
1433 Label slow, loop, is_instance, is_not_instance, not_js_object; 1428 Label slow, loop, is_instance, is_not_instance, not_js_object;
1434 1429
1435 if (!HasArgsInRegisters()) { 1430 if (!HasArgsInRegisters()) {
1436 __ lw(object, MemOperand(sp, 1 * kPointerSize)); 1431 __ lw(object, MemOperand(sp, 1 * kPointerSize));
1437 __ lw(function, MemOperand(sp, 0)); 1432 __ lw(function, MemOperand(sp, 0));
1438 } 1433 }
1439 1434
1440 // Check that the left hand is a JS object and load map. 1435 // Check that the left hand is a JS object and load map.
1441 __ JumpIfSmi(object, &not_js_object); 1436 __ JumpIfSmi(object, &not_js_object);
1442 __ IsObjectJSObjectType(object, map, scratch, &not_js_object); 1437 __ IsObjectJSObjectType(object, map, scratch, &not_js_object);
1443 1438
1444 // If there is a call site cache don't look in the global cache, but do the 1439 // If there is a call site cache don't look in the global cache, but do the
1445 // real lookup and update the call site cache. 1440 // real lookup and update the call site cache.
1446 if (!HasCallSiteInlineCheck()) { 1441 if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) {
1447 Label miss; 1442 Label miss;
1448 __ LoadRoot(at, Heap::kInstanceofCacheFunctionRootIndex); 1443 __ LoadRoot(at, Heap::kInstanceofCacheFunctionRootIndex);
1449 __ Branch(&miss, ne, function, Operand(at)); 1444 __ Branch(&miss, ne, function, Operand(at));
1450 __ LoadRoot(at, Heap::kInstanceofCacheMapRootIndex); 1445 __ LoadRoot(at, Heap::kInstanceofCacheMapRootIndex);
1451 __ Branch(&miss, ne, map, Operand(at)); 1446 __ Branch(&miss, ne, map, Operand(at));
1452 __ LoadRoot(v0, Heap::kInstanceofCacheAnswerRootIndex); 1447 __ LoadRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
1453 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); 1448 __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
1454 1449
1455 __ bind(&miss); 1450 __ bind(&miss);
1456 } 1451 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 __ Branch(&is_not_instance, eq, scratch, Operand(scratch2)); 1490 __ Branch(&is_not_instance, eq, scratch, Operand(scratch2));
1496 __ lw(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset)); 1491 __ lw(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset));
1497 __ lw(scratch, FieldMemOperand(scratch, Map::kPrototypeOffset)); 1492 __ lw(scratch, FieldMemOperand(scratch, Map::kPrototypeOffset));
1498 __ Branch(&loop); 1493 __ Branch(&loop);
1499 1494
1500 __ bind(&is_instance); 1495 __ bind(&is_instance);
1501 DCHECK(Smi::FromInt(0) == 0); 1496 DCHECK(Smi::FromInt(0) == 0);
1502 if (!HasCallSiteInlineCheck()) { 1497 if (!HasCallSiteInlineCheck()) {
1503 __ mov(v0, zero_reg); 1498 __ mov(v0, zero_reg);
1504 __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex); 1499 __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
1500 if (ReturnTrueFalseObject()) {
1501 __ LoadRoot(v0, Heap::kTrueValueRootIndex);
1502 }
1505 } else { 1503 } else {
1506 // Patch the call site to return true. 1504 // Patch the call site to return true.
1507 __ LoadRoot(v0, Heap::kTrueValueRootIndex); 1505 __ LoadRoot(v0, Heap::kTrueValueRootIndex);
1508 __ Addu(inline_site, inline_site, Operand(kDeltaToLoadBoolResult)); 1506 __ Addu(inline_site, inline_site, Operand(kDeltaToLoadBoolResult));
1509 // Get the boolean result location in scratch and patch it. 1507 // Get the boolean result location in scratch and patch it.
1510 __ PatchRelocatedValue(inline_site, scratch, v0); 1508 __ PatchRelocatedValue(inline_site, scratch, v0);
1511 1509
1512 if (!ReturnTrueFalseObject()) { 1510 if (!ReturnTrueFalseObject()) {
1513 DCHECK_EQ(Smi::FromInt(0), 0); 1511 DCHECK_EQ(Smi::FromInt(0), 0);
1514 __ mov(v0, zero_reg); 1512 __ mov(v0, zero_reg);
1515 } 1513 }
1516 } 1514 }
1517 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); 1515 __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
1518 1516
1519 __ bind(&is_not_instance); 1517 __ bind(&is_not_instance);
1520 if (!HasCallSiteInlineCheck()) { 1518 if (!HasCallSiteInlineCheck()) {
1521 __ li(v0, Operand(Smi::FromInt(1))); 1519 __ li(v0, Operand(Smi::FromInt(1)));
1522 __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex); 1520 __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
1521 if (ReturnTrueFalseObject()) {
1522 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
1523 }
1523 } else { 1524 } else {
1524 // Patch the call site to return false. 1525 // Patch the call site to return false.
1525 __ LoadRoot(v0, Heap::kFalseValueRootIndex); 1526 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
1526 __ Addu(inline_site, inline_site, Operand(kDeltaToLoadBoolResult)); 1527 __ Addu(inline_site, inline_site, Operand(kDeltaToLoadBoolResult));
1527 // Get the boolean result location in scratch and patch it. 1528 // Get the boolean result location in scratch and patch it.
1528 __ PatchRelocatedValue(inline_site, scratch, v0); 1529 __ PatchRelocatedValue(inline_site, scratch, v0);
1529 1530
1530 if (!ReturnTrueFalseObject()) { 1531 if (!ReturnTrueFalseObject()) {
1531 __ li(v0, Operand(Smi::FromInt(1))); 1532 __ li(v0, Operand(Smi::FromInt(1)));
1532 } 1533 }
1533 } 1534 }
1534 1535
1535 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); 1536 __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
1536 1537
1537 Label object_not_null, object_not_null_or_smi; 1538 Label object_not_null, object_not_null_or_smi;
1538 __ bind(&not_js_object); 1539 __ bind(&not_js_object);
1539 // Before null, smi and string value checks, check that the rhs is a function 1540 // Before null, smi and string value checks, check that the rhs is a function
1540 // as for a non-function rhs an exception needs to be thrown. 1541 // as for a non-function rhs an exception needs to be thrown.
1541 __ JumpIfSmi(function, &slow); 1542 __ JumpIfSmi(function, &slow);
1542 __ GetObjectType(function, scratch2, scratch); 1543 __ GetObjectType(function, scratch2, scratch);
1543 __ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE)); 1544 __ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE));
1544 1545
1545 // Null is not instance of anything. 1546 // Null is not instance of anything.
1546 __ Branch(&object_not_null, 1547 __ Branch(&object_not_null,
1547 ne, 1548 ne,
1548 scratch, 1549 scratch,
1549 Operand(isolate()->factory()->null_value())); 1550 Operand(isolate()->factory()->null_value()));
1550 __ li(v0, Operand(Smi::FromInt(1))); 1551 if (ReturnTrueFalseObject()) {
1552 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
1553 } else {
1554 __ li(v0, Operand(Smi::FromInt(1)));
1555 }
1551 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); 1556 __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
1552 1557
1553 __ bind(&object_not_null); 1558 __ bind(&object_not_null);
1554 // Smi values are not instances of anything. 1559 // Smi values are not instances of anything.
1555 __ JumpIfNotSmi(object, &object_not_null_or_smi); 1560 __ JumpIfNotSmi(object, &object_not_null_or_smi);
1556 __ li(v0, Operand(Smi::FromInt(1))); 1561 if (ReturnTrueFalseObject()) {
1562 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
1563 } else {
1564 __ li(v0, Operand(Smi::FromInt(1)));
1565 }
1557 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); 1566 __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
1558 1567
1559 __ bind(&object_not_null_or_smi); 1568 __ bind(&object_not_null_or_smi);
1560 // String values are not instances of anything. 1569 // String values are not instances of anything.
1561 __ IsObjectJSStringType(object, scratch, &slow); 1570 __ IsObjectJSStringType(object, scratch, &slow);
1562 __ li(v0, Operand(Smi::FromInt(1))); 1571 if (ReturnTrueFalseObject()) {
1572 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
1573 } else {
1574 __ li(v0, Operand(Smi::FromInt(1)));
1575 }
1563 __ DropAndRet(HasArgsInRegisters() ? 0 : 2); 1576 __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
1564 1577
1565 // Slow-case. Tail call builtin. 1578 // Slow-case. Tail call builtin.
1566 __ bind(&slow); 1579 __ bind(&slow);
1567 if (!ReturnTrueFalseObject()) { 1580 if (!ReturnTrueFalseObject()) {
1568 if (HasArgsInRegisters()) { 1581 if (HasArgsInRegisters()) {
1569 __ Push(a0, a1); 1582 __ Push(a0, a1);
1570 } 1583 }
1571 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 1584 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
1572 } else { 1585 } else {
(...skipping 3312 matching lines...) Expand 10 before | Expand all | Expand 10 after
4885 MemOperand(fp, 6 * kPointerSize), 4898 MemOperand(fp, 6 * kPointerSize),
4886 NULL); 4899 NULL);
4887 } 4900 }
4888 4901
4889 4902
4890 #undef __ 4903 #undef __
4891 4904
4892 } } // namespace v8::internal 4905 } } // namespace v8::internal
4893 4906
4894 #endif // V8_TARGET_ARCH_MIPS 4907 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/mips/deoptimizer-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698