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

Side by Side Diff: src/compiler/mips64/code-generator-mips64.cc

Issue 2082263002: [turbofan]: Support using push instructions for setting up tail call parameters (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove stray test change Created 4 years, 5 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/ast/scopes.h" 5 #include "src/ast/scopes.h"
6 #include "src/compiler/code-generator.h" 6 #include "src/compiler/code-generator.h"
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/osr.h" 10 #include "src/compiler/osr.h"
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 0, 1); \ 517 0, 1); \
518 /* Move the result in the double result register. */ \ 518 /* Move the result in the double result register. */ \
519 __ MovFromFloatResult(i.OutputDoubleRegister()); \ 519 __ MovFromFloatResult(i.OutputDoubleRegister()); \
520 } while (0) 520 } while (0)
521 521
522 void CodeGenerator::AssembleDeconstructFrame() { 522 void CodeGenerator::AssembleDeconstructFrame() {
523 __ mov(sp, fp); 523 __ mov(sp, fp);
524 __ Pop(ra, fp); 524 __ Pop(ra, fp);
525 } 525 }
526 526
527 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { 527 void CodeGenerator::AssemblePrepareTailCall() {
528 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
529 if (sp_slot_delta > 0) {
530 __ daddiu(sp, sp, sp_slot_delta * kPointerSize);
531 }
532 frame_access_state()->SetFrameAccessToDefault();
533 }
534
535
536 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
537 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
538 if (sp_slot_delta < 0) {
539 __ Dsubu(sp, sp, Operand(-sp_slot_delta * kPointerSize));
540 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
541 }
542 if (frame_access_state()->has_frame()) { 528 if (frame_access_state()->has_frame()) {
543 __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); 529 __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
544 __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 530 __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
545 } 531 }
546 frame_access_state()->SetFrameAccessToSP(); 532 frame_access_state()->SetFrameAccessToSP();
547 } 533 }
548 534
549 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 535 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
550 Register scratch1, 536 Register scratch1,
551 Register scratch2, 537 Register scratch2,
(...skipping 12 matching lines...) Expand all
564 __ ld(caller_args_count_reg, 550 __ ld(caller_args_count_reg,
565 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 551 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
566 __ SmiUntag(caller_args_count_reg); 552 __ SmiUntag(caller_args_count_reg);
567 553
568 ParameterCount callee_args_count(args_reg); 554 ParameterCount callee_args_count(args_reg);
569 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, 555 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
570 scratch3); 556 scratch3);
571 __ bind(&done); 557 __ bind(&done);
572 } 558 }
573 559
560 namespace {
561 void AdjustStackPointerForGap(MacroAssembler* masm, FrameAccessState* state,
562 int new_slot_above_sp,
563 bool allow_shrinkage = true) {
564 int current_sp_offset = state->GetSPToFPSlotCount() +
565 StandardFrameConstants::kFixedSlotCountAboveFp;
566 int stack_slot_delta = new_slot_above_sp - current_sp_offset;
567 if (stack_slot_delta > 0) {
568 masm->Dsubu(sp, sp, stack_slot_delta * kPointerSize);
569 state->IncreaseSPDelta(stack_slot_delta);
570 } else if (allow_shrinkage && stack_slot_delta < 0) {
571 masm->Daddu(sp, sp, stack_slot_delta * kPointerSize);
572 state->IncreaseSPDelta(stack_slot_delta);
573 }
574 }
575 } // namespace
576
577 void CodeGenerator::AssemblePreGaps(Instruction* instr) {
578 int first_unused_stack_slot;
579 if (!GetSlotAboveSPAfterGap(instr, &first_unused_stack_slot)) return;
580 AdjustStackPointerForGap(masm(), frame_access_state(),
581 first_unused_stack_slot, false);
582 }
583
584 void CodeGenerator::AssemblePostGaps(Instruction* instr) {
585 int first_unused_stack_slot;
586 if (!GetSlotAboveSPAfterGap(instr, &first_unused_stack_slot)) return;
587 AdjustStackPointerForGap(masm(), frame_access_state(),
588 first_unused_stack_slot);
589 }
590
574 // Assembles an instruction after register allocation, producing machine code. 591 // Assembles an instruction after register allocation, producing machine code.
575 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 592 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
576 Instruction* instr) { 593 Instruction* instr) {
577 MipsOperandConverter i(this, instr); 594 MipsOperandConverter i(this, instr);
578 InstructionCode opcode = instr->opcode(); 595 InstructionCode opcode = instr->opcode();
579 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); 596 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
580 switch (arch_opcode) { 597 switch (arch_opcode) {
581 case kArchCallCodeObject: { 598 case kArchCallCodeObject: {
582 EnsureSpaceForLazyDeopt(); 599 EnsureSpaceForLazyDeopt();
583 if (instr->InputAt(0)->IsImmediate()) { 600 if (instr->InputAt(0)->IsImmediate()) {
584 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 601 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
585 RelocInfo::CODE_TARGET); 602 RelocInfo::CODE_TARGET);
586 } else { 603 } else {
587 __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); 604 __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
588 __ Call(at); 605 __ Call(at);
589 } 606 }
590 RecordCallPosition(instr); 607 RecordCallPosition(instr);
591 frame_access_state()->ClearSPDelta(); 608 frame_access_state()->ClearSPDelta();
592 break; 609 break;
593 } 610 }
594 case kArchTailCallCodeObjectFromJSFunction: 611 case kArchTailCallCodeObjectFromJSFunction:
595 case kArchTailCallCodeObject: { 612 case kArchTailCallCodeObject: {
596 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
597 AssembleDeconstructActivationRecord(stack_param_delta);
598 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) { 613 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
599 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 614 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
600 i.TempRegister(0), i.TempRegister(1), 615 i.TempRegister(0), i.TempRegister(1),
601 i.TempRegister(2)); 616 i.TempRegister(2));
602 } 617 }
603 if (instr->InputAt(0)->IsImmediate()) { 618 if (instr->InputAt(0)->IsImmediate()) {
604 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 619 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
605 RelocInfo::CODE_TARGET); 620 RelocInfo::CODE_TARGET);
606 } else { 621 } else {
607 __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); 622 __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
608 __ Jump(at); 623 __ Jump(at);
609 } 624 }
610 frame_access_state()->ClearSPDelta(); 625 frame_access_state()->ClearSPDelta();
626 frame_access_state()->SetFrameAccessToDefault();
611 break; 627 break;
612 } 628 }
613 case kArchTailCallAddress: { 629 case kArchTailCallAddress: {
614 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
615 AssembleDeconstructActivationRecord(stack_param_delta);
616 CHECK(!instr->InputAt(0)->IsImmediate()); 630 CHECK(!instr->InputAt(0)->IsImmediate());
617 __ Jump(i.InputRegister(0)); 631 __ Jump(i.InputRegister(0));
618 frame_access_state()->ClearSPDelta(); 632 frame_access_state()->ClearSPDelta();
633 frame_access_state()->SetFrameAccessToDefault();
619 break; 634 break;
620 } 635 }
621 case kArchCallJSFunction: { 636 case kArchCallJSFunction: {
622 EnsureSpaceForLazyDeopt(); 637 EnsureSpaceForLazyDeopt();
623 Register func = i.InputRegister(0); 638 Register func = i.InputRegister(0);
624 if (FLAG_debug_code) { 639 if (FLAG_debug_code) {
625 // Check the function's context matches the context argument. 640 // Check the function's context matches the context argument.
626 __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); 641 __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
627 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); 642 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
628 } 643 }
629 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 644 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
630 __ Call(at); 645 __ Call(at);
631 RecordCallPosition(instr); 646 RecordCallPosition(instr);
632 frame_access_state()->ClearSPDelta(); 647 frame_access_state()->ClearSPDelta();
633 break; 648 break;
634 } 649 }
635 case kArchTailCallJSFunctionFromJSFunction: 650 case kArchTailCallJSFunctionFromJSFunction:
636 case kArchTailCallJSFunction: { 651 case kArchTailCallJSFunction: {
637 Register func = i.InputRegister(0); 652 Register func = i.InputRegister(0);
638 if (FLAG_debug_code) { 653 if (FLAG_debug_code) {
639 // Check the function's context matches the context argument. 654 // Check the function's context matches the context argument.
640 __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); 655 __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
641 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); 656 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
642 } 657 }
643 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
644 AssembleDeconstructActivationRecord(stack_param_delta);
645 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) { 658 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) {
646 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 659 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
647 i.TempRegister(0), i.TempRegister(1), 660 i.TempRegister(0), i.TempRegister(1),
648 i.TempRegister(2)); 661 i.TempRegister(2));
649 } 662 }
650 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 663 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
651 __ Jump(at); 664 __ Jump(at);
652 frame_access_state()->ClearSPDelta(); 665 frame_access_state()->ClearSPDelta();
666 frame_access_state()->SetFrameAccessToDefault();
653 break; 667 break;
654 } 668 }
655 case kArchPrepareCallCFunction: { 669 case kArchPrepareCallCFunction: {
656 int const num_parameters = MiscField::decode(instr->opcode()); 670 int const num_parameters = MiscField::decode(instr->opcode());
657 __ PrepareCallCFunction(num_parameters, kScratchReg); 671 __ PrepareCallCFunction(num_parameters, kScratchReg);
658 // Frame alignment requires using FP-relative frame addressing. 672 // Frame alignment requires using FP-relative frame addressing.
659 frame_access_state()->SetFrameAccessToFP(); 673 frame_access_state()->SetFrameAccessToFP();
660 break; 674 break;
661 } 675 }
662 case kArchPrepareTailCall: 676 case kArchPrepareTailCall:
663 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); 677 AssemblePrepareTailCall();
664 break; 678 break;
665 case kArchCallCFunction: { 679 case kArchCallCFunction: {
666 int const num_parameters = MiscField::decode(instr->opcode()); 680 int const num_parameters = MiscField::decode(instr->opcode());
667 if (instr->InputAt(0)->IsImmediate()) { 681 if (instr->InputAt(0)->IsImmediate()) {
668 ExternalReference ref = i.InputExternalReference(0); 682 ExternalReference ref = i.InputExternalReference(0);
669 __ CallCFunction(ref, num_parameters); 683 __ CallCFunction(ref, num_parameters);
670 } else { 684 } else {
671 Register func = i.InputRegister(0); 685 Register func = i.InputRegister(0);
672 __ CallCFunction(func, num_parameters); 686 __ CallCFunction(func, num_parameters);
673 } 687 }
(...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after
2336 padding_size -= v8::internal::Assembler::kInstrSize; 2350 padding_size -= v8::internal::Assembler::kInstrSize;
2337 } 2351 }
2338 } 2352 }
2339 } 2353 }
2340 2354
2341 #undef __ 2355 #undef __
2342 2356
2343 } // namespace compiler 2357 } // namespace compiler
2344 } // namespace internal 2358 } // namespace internal
2345 } // namespace v8 2359 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698