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 // Note on Mips implementation: | 7 // Note on Mips implementation: |
8 // | 8 // |
9 // The result_register() for mips is the 'v0' register, which is defined | 9 // The result_register() for mips is the 'v0' register, which is defined |
10 // by the ABI to contain function return values. However, the first | 10 // by the ABI to contain function return values. However, the first |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 int32_t sp_delta = arg_count * kPointerSize; | 451 int32_t sp_delta = arg_count * kPointerSize; |
452 SetReturnPosition(literal()); | 452 SetReturnPosition(literal()); |
453 masm_->mov(sp, fp); | 453 masm_->mov(sp, fp); |
454 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); | 454 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); |
455 masm_->Daddu(sp, sp, Operand(sp_delta)); | 455 masm_->Daddu(sp, sp, Operand(sp_delta)); |
456 masm_->Jump(ra); | 456 masm_->Jump(ra); |
457 } | 457 } |
458 } | 458 } |
459 } | 459 } |
460 | 460 |
| 461 void FullCodeGenerator::RestoreContext() { |
| 462 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 463 } |
461 | 464 |
462 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 465 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
463 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 466 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
464 codegen()->GetVar(result_register(), var); | 467 codegen()->GetVar(result_register(), var); |
465 codegen()->PushOperand(result_register()); | 468 codegen()->PushOperand(result_register()); |
466 } | 469 } |
467 | 470 |
468 | 471 |
469 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 472 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
470 } | 473 } |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1410 __ ld(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1408 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); | 1411 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); |
1409 __ li(a1, Operand(constant_properties)); | 1412 __ li(a1, Operand(constant_properties)); |
1410 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags()))); | 1413 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags()))); |
1411 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1414 if (MustCreateObjectLiteralWithRuntime(expr)) { |
1412 __ Push(a3, a2, a1, a0); | 1415 __ Push(a3, a2, a1, a0); |
1413 __ CallRuntime(Runtime::kCreateObjectLiteral); | 1416 __ CallRuntime(Runtime::kCreateObjectLiteral); |
1414 } else { | 1417 } else { |
1415 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1418 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
1416 __ CallStub(&stub); | 1419 __ CallStub(&stub); |
1417 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1420 RestoreContext(); |
1418 } | 1421 } |
1419 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1422 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
1420 | 1423 |
1421 // If result_saved is true the result is on top of the stack. If | 1424 // If result_saved is true the result is on top of the stack. If |
1422 // result_saved is false the result is in v0. | 1425 // result_saved is false the result is in v0. |
1423 bool result_saved = false; | 1426 bool result_saved = false; |
1424 | 1427 |
1425 AccessorTable accessor_table(zone()); | 1428 AccessorTable accessor_table(zone()); |
1426 int property_index = 0; | 1429 int property_index = 0; |
1427 for (; property_index < expr->properties()->length(); property_index++) { | 1430 for (; property_index < expr->properties()->length(); property_index++) { |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); | 1856 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); |
1854 __ sd(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); | 1857 __ sd(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); |
1855 __ sd(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); | 1858 __ sd(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); |
1856 __ mov(a1, cp); | 1859 __ mov(a1, cp); |
1857 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, | 1860 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, |
1858 kRAHasBeenSaved, kDontSaveFPRegs); | 1861 kRAHasBeenSaved, kDontSaveFPRegs); |
1859 __ Daddu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1862 __ Daddu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
1860 __ Branch(&post_runtime, eq, sp, Operand(a1)); | 1863 __ Branch(&post_runtime, eq, sp, Operand(a1)); |
1861 __ push(v0); // generator object | 1864 __ push(v0); // generator object |
1862 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1865 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1863 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1866 RestoreContext(); |
1864 __ bind(&post_runtime); | 1867 __ bind(&post_runtime); |
1865 PopOperand(result_register()); | 1868 PopOperand(result_register()); |
1866 EmitReturnSequence(); | 1869 EmitReturnSequence(); |
1867 | 1870 |
1868 __ bind(&resume); | 1871 __ bind(&resume); |
1869 context()->Plug(result_register()); | 1872 context()->Plug(result_register()); |
1870 } | 1873 } |
1871 | 1874 |
1872 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { | 1875 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
1873 OperandStackDepthIncrement(2); | 1876 OperandStackDepthIncrement(2); |
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2524 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) | 2527 CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode()) |
2525 .code(); | 2528 .code(); |
2526 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2529 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); |
2527 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2530 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2528 // Don't assign a type feedback id to the IC, since type feedback is provided | 2531 // Don't assign a type feedback id to the IC, since type feedback is provided |
2529 // by the vector above. | 2532 // by the vector above. |
2530 CallIC(ic); | 2533 CallIC(ic); |
2531 OperandStackDepthDecrement(arg_count + 1); | 2534 OperandStackDepthDecrement(arg_count + 1); |
2532 | 2535 |
2533 RecordJSReturnSite(expr); | 2536 RecordJSReturnSite(expr); |
2534 // Restore context register. | 2537 RestoreContext(); |
2535 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2536 context()->DropAndPlug(1, v0); | 2538 context()->DropAndPlug(1, v0); |
2537 } | 2539 } |
2538 | 2540 |
2539 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { | 2541 void FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) { |
2540 int arg_count = expr->arguments()->length(); | 2542 int arg_count = expr->arguments()->length(); |
2541 // a6: copy of the first argument or undefined if it doesn't exist. | 2543 // a6: copy of the first argument or undefined if it doesn't exist. |
2542 if (arg_count > 0) { | 2544 if (arg_count > 0) { |
2543 __ ld(a6, MemOperand(sp, arg_count * kPointerSize)); | 2545 __ ld(a6, MemOperand(sp, arg_count * kPointerSize)); |
2544 } else { | 2546 } else { |
2545 __ LoadRoot(a6, Heap::kUndefinedValueRootIndex); | 2547 __ LoadRoot(a6, Heap::kUndefinedValueRootIndex); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2631 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 2633 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
2632 // Record source position for debugger. | 2634 // Record source position for debugger. |
2633 SetCallPosition(expr); | 2635 SetCallPosition(expr); |
2634 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2636 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2635 __ li(a0, Operand(arg_count)); | 2637 __ li(a0, Operand(arg_count)); |
2636 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2638 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2637 expr->tail_call_mode()), | 2639 expr->tail_call_mode()), |
2638 RelocInfo::CODE_TARGET); | 2640 RelocInfo::CODE_TARGET); |
2639 OperandStackDepthDecrement(arg_count + 1); | 2641 OperandStackDepthDecrement(arg_count + 1); |
2640 RecordJSReturnSite(expr); | 2642 RecordJSReturnSite(expr); |
2641 // Restore context register. | 2643 RestoreContext(); |
2642 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2643 context()->DropAndPlug(1, v0); | 2644 context()->DropAndPlug(1, v0); |
2644 } | 2645 } |
2645 | 2646 |
2646 | 2647 |
2647 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2648 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
2648 Comment cmnt(masm_, "[ CallNew"); | 2649 Comment cmnt(masm_, "[ CallNew"); |
2649 // According to ECMA-262, section 11.2.2, page 44, the function | 2650 // According to ECMA-262, section 11.2.2, page 44, the function |
2650 // expression in new calls must be evaluated before the | 2651 // expression in new calls must be evaluated before the |
2651 // arguments. | 2652 // arguments. |
2652 | 2653 |
(...skipping 19 matching lines...) Expand all Loading... |
2672 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); | 2673 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); |
2673 | 2674 |
2674 // Record call targets in unoptimized code. | 2675 // Record call targets in unoptimized code. |
2675 __ EmitLoadTypeFeedbackVector(a2); | 2676 __ EmitLoadTypeFeedbackVector(a2); |
2676 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); | 2677 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); |
2677 | 2678 |
2678 CallConstructStub stub(isolate()); | 2679 CallConstructStub stub(isolate()); |
2679 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 2680 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
2680 OperandStackDepthDecrement(arg_count + 1); | 2681 OperandStackDepthDecrement(arg_count + 1); |
2681 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2682 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2682 // Restore context register. | 2683 RestoreContext(); |
2683 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2684 context()->Plug(v0); | 2684 context()->Plug(v0); |
2685 } | 2685 } |
2686 | 2686 |
2687 | 2687 |
2688 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { | 2688 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { |
2689 SuperCallReference* super_call_ref = | 2689 SuperCallReference* super_call_ref = |
2690 expr->expression()->AsSuperCallReference(); | 2690 expr->expression()->AsSuperCallReference(); |
2691 DCHECK_NOT_NULL(super_call_ref); | 2691 DCHECK_NOT_NULL(super_call_ref); |
2692 | 2692 |
2693 // Push the super constructor target on the stack (may be null, | 2693 // Push the super constructor target on the stack (may be null, |
(...skipping 22 matching lines...) Expand all Loading... |
2716 __ mov(a3, result_register()); | 2716 __ mov(a3, result_register()); |
2717 | 2717 |
2718 // Load function and argument count into a1 and a0. | 2718 // Load function and argument count into a1 and a0. |
2719 __ li(a0, Operand(arg_count)); | 2719 __ li(a0, Operand(arg_count)); |
2720 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); | 2720 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); |
2721 | 2721 |
2722 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2722 __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2723 OperandStackDepthDecrement(arg_count + 1); | 2723 OperandStackDepthDecrement(arg_count + 1); |
2724 | 2724 |
2725 RecordJSReturnSite(expr); | 2725 RecordJSReturnSite(expr); |
2726 | 2726 RestoreContext(); |
2727 // Restore context register. | |
2728 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2729 context()->Plug(v0); | 2727 context()->Plug(v0); |
2730 } | 2728 } |
2731 | 2729 |
2732 | 2730 |
2733 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2731 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
2734 ZoneList<Expression*>* args = expr->arguments(); | 2732 ZoneList<Expression*>* args = expr->arguments(); |
2735 DCHECK(args->length() == 1); | 2733 DCHECK(args->length() == 1); |
2736 | 2734 |
2737 VisitForAccumulatorValue(args->at(0)); | 2735 VisitForAccumulatorValue(args->at(0)); |
2738 | 2736 |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3130 VisitForStackValue(arg); | 3128 VisitForStackValue(arg); |
3131 } | 3129 } |
3132 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); | 3130 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); |
3133 // Move target to a1. | 3131 // Move target to a1. |
3134 int const argc = args->length() - 2; | 3132 int const argc = args->length() - 2; |
3135 __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize)); | 3133 __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize)); |
3136 // Call the target. | 3134 // Call the target. |
3137 __ li(a0, Operand(argc)); | 3135 __ li(a0, Operand(argc)); |
3138 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 3136 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
3139 OperandStackDepthDecrement(argc + 1); | 3137 OperandStackDepthDecrement(argc + 1); |
3140 // Restore context register. | 3138 RestoreContext(); |
3141 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
3142 // Discard the function left on TOS. | 3139 // Discard the function left on TOS. |
3143 context()->DropAndPlug(1, v0); | 3140 context()->DropAndPlug(1, v0); |
3144 } | 3141 } |
3145 | 3142 |
3146 | 3143 |
3147 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { | 3144 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
3148 ZoneList<Expression*>* args = expr->arguments(); | 3145 ZoneList<Expression*>* args = expr->arguments(); |
3149 VisitForAccumulatorValue(args->at(0)); | 3146 VisitForAccumulatorValue(args->at(0)); |
3150 | 3147 |
3151 Label materialize_true, materialize_false; | 3148 Label materialize_true, materialize_false; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3248 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3245 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3249 ZoneList<Expression*>* args = expr->arguments(); | 3246 ZoneList<Expression*>* args = expr->arguments(); |
3250 int arg_count = args->length(); | 3247 int arg_count = args->length(); |
3251 | 3248 |
3252 SetCallPosition(expr); | 3249 SetCallPosition(expr); |
3253 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3250 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
3254 __ li(a0, Operand(arg_count)); | 3251 __ li(a0, Operand(arg_count)); |
3255 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), | 3252 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined), |
3256 RelocInfo::CODE_TARGET); | 3253 RelocInfo::CODE_TARGET); |
3257 OperandStackDepthDecrement(arg_count + 1); | 3254 OperandStackDepthDecrement(arg_count + 1); |
3258 | 3255 RestoreContext(); |
3259 // Restore context register. | |
3260 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
3261 } | 3256 } |
3262 | 3257 |
3263 | 3258 |
3264 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3259 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
3265 switch (expr->op()) { | 3260 switch (expr->op()) { |
3266 case Token::DELETE: { | 3261 case Token::DELETE: { |
3267 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 3262 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
3268 Property* property = expr->expression()->AsProperty(); | 3263 Property* property = expr->expression()->AsProperty(); |
3269 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 3264 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
3270 | 3265 |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3718 Label* fall_through = NULL; | 3713 Label* fall_through = NULL; |
3719 context()->PrepareTest(&materialize_true, &materialize_false, | 3714 context()->PrepareTest(&materialize_true, &materialize_false, |
3720 &if_true, &if_false, &fall_through); | 3715 &if_true, &if_false, &fall_through); |
3721 | 3716 |
3722 Token::Value op = expr->op(); | 3717 Token::Value op = expr->op(); |
3723 VisitForStackValue(expr->left()); | 3718 VisitForStackValue(expr->left()); |
3724 switch (op) { | 3719 switch (op) { |
3725 case Token::IN: | 3720 case Token::IN: |
3726 VisitForStackValue(expr->right()); | 3721 VisitForStackValue(expr->right()); |
3727 SetExpressionPosition(expr); | 3722 SetExpressionPosition(expr); |
3728 CallRuntimeWithOperands(Runtime::kHasProperty); | 3723 EmitHasProperty(); |
3729 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3724 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3730 __ LoadRoot(a4, Heap::kTrueValueRootIndex); | 3725 __ LoadRoot(a4, Heap::kTrueValueRootIndex); |
3731 Split(eq, v0, Operand(a4), if_true, if_false, fall_through); | 3726 Split(eq, v0, Operand(a4), if_true, if_false, fall_through); |
3732 break; | 3727 break; |
3733 | 3728 |
3734 case Token::INSTANCEOF: { | 3729 case Token::INSTANCEOF: { |
3735 VisitForAccumulatorValue(expr->right()); | 3730 VisitForAccumulatorValue(expr->right()); |
3736 SetExpressionPosition(expr); | 3731 SetExpressionPosition(expr); |
3737 __ mov(a0, result_register()); | 3732 __ mov(a0, result_register()); |
3738 PopOperand(a1); | 3733 PopOperand(a1); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3992 reinterpret_cast<uint64_t>( | 3987 reinterpret_cast<uint64_t>( |
3993 isolate->builtins()->OnStackReplacement()->entry())); | 3988 isolate->builtins()->OnStackReplacement()->entry())); |
3994 return ON_STACK_REPLACEMENT; | 3989 return ON_STACK_REPLACEMENT; |
3995 } | 3990 } |
3996 | 3991 |
3997 | 3992 |
3998 } // namespace internal | 3993 } // namespace internal |
3999 } // namespace v8 | 3994 } // namespace v8 |
4000 | 3995 |
4001 #endif // V8_TARGET_ARCH_MIPS64 | 3996 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |