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

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

Issue 2123983002: PPC/s390: [turbofan]: Support using push instructions for setting up tail call parameters (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
« no previous file with comments | « src/compiler/ppc/code-generator-ppc.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 Register value = i.InputRegister(3); \ 573 Register value = i.InputRegister(3); \
574 __ CleanUInt32(offset); \ 574 __ CleanUInt32(offset); \
575 __ asm_instr(value, operand); \ 575 __ asm_instr(value, operand); \
576 __ bind(&done); \ 576 __ bind(&done); \
577 } while (0) 577 } while (0)
578 578
579 void CodeGenerator::AssembleDeconstructFrame() { 579 void CodeGenerator::AssembleDeconstructFrame() {
580 __ LeaveFrame(StackFrame::MANUAL); 580 __ LeaveFrame(StackFrame::MANUAL);
581 } 581 }
582 582
583 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { 583 void CodeGenerator::AssemblePrepareTailCall() {
584 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
585 if (sp_slot_delta > 0) {
586 __ AddP(sp, sp, Operand(sp_slot_delta * kPointerSize));
587 }
588 frame_access_state()->SetFrameAccessToDefault();
589 }
590
591 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
592 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
593 if (sp_slot_delta < 0) {
594 __ AddP(sp, sp, Operand(sp_slot_delta * kPointerSize));
595 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
596 }
597 if (frame_access_state()->has_frame()) { 584 if (frame_access_state()->has_frame()) {
598 __ RestoreFrameStateForTailCall(); 585 __ RestoreFrameStateForTailCall();
599 } 586 }
600 frame_access_state()->SetFrameAccessToSP(); 587 frame_access_state()->SetFrameAccessToSP();
601 } 588 }
602 589
603 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 590 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
604 Register scratch1, 591 Register scratch1,
605 Register scratch2, 592 Register scratch2,
606 Register scratch3) { 593 Register scratch3) {
(...skipping 11 matching lines...) Expand all
618 __ LoadP(caller_args_count_reg, 605 __ LoadP(caller_args_count_reg,
619 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 606 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
620 __ SmiUntag(caller_args_count_reg); 607 __ SmiUntag(caller_args_count_reg);
621 608
622 ParameterCount callee_args_count(args_reg); 609 ParameterCount callee_args_count(args_reg);
623 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, 610 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
624 scratch3); 611 scratch3);
625 __ bind(&done); 612 __ bind(&done);
626 } 613 }
627 614
615 namespace {
616
617 void FlushPendingPushRegisters(MacroAssembler* masm,
618 FrameAccessState* frame_access_state,
619 ZoneVector<Register>* pending_pushes) {
620 switch (pending_pushes->size()) {
621 case 0:
622 break;
623 case 1:
624 masm->Push((*pending_pushes)[0]);
625 break;
626 case 2:
627 masm->Push((*pending_pushes)[0], (*pending_pushes)[1]);
628 break;
629 case 3:
630 masm->Push((*pending_pushes)[0], (*pending_pushes)[1],
631 (*pending_pushes)[2]);
632 break;
633 default:
634 UNREACHABLE();
635 break;
636 }
637 frame_access_state->IncreaseSPDelta(pending_pushes->size());
638 pending_pushes->resize(0);
639 }
640
641 void AddPendingPushRegister(MacroAssembler* masm,
642 FrameAccessState* frame_access_state,
643 ZoneVector<Register>* pending_pushes,
644 Register reg) {
645 pending_pushes->push_back(reg);
646 if (pending_pushes->size() == 3 || reg.is(ip)) {
647 FlushPendingPushRegisters(masm, frame_access_state, pending_pushes);
648 }
649 }
650 void AdjustStackPointerForTailCall(
651 MacroAssembler* masm, FrameAccessState* state, int new_slot_above_sp,
652 ZoneVector<Register>* pending_pushes = nullptr,
653 bool allow_shrinkage = true) {
654 int current_sp_offset = state->GetSPToFPSlotCount() +
655 StandardFrameConstants::kFixedSlotCountAboveFp;
656 int stack_slot_delta = new_slot_above_sp - current_sp_offset;
657 if (stack_slot_delta > 0) {
658 if (pending_pushes != nullptr) {
659 FlushPendingPushRegisters(masm, state, pending_pushes);
660 }
661 masm->AddP(sp, sp, Operand(-stack_slot_delta * kPointerSize));
662 state->IncreaseSPDelta(stack_slot_delta);
663 } else if (allow_shrinkage && stack_slot_delta < 0) {
664 if (pending_pushes != nullptr) {
665 FlushPendingPushRegisters(masm, state, pending_pushes);
666 }
667 masm->AddP(sp, sp, Operand(-stack_slot_delta * kPointerSize));
668 state->IncreaseSPDelta(stack_slot_delta);
669 }
670 }
671
672 } // namespace
673
674 void CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr,
675 int first_unused_stack_slot) {
676 CodeGenerator::PushTypeFlags flags(kImmediatePush | kScalarPush);
677 ZoneVector<MoveOperands*> pushes(zone());
678 GetPushCompatibleMoves(instr, flags, &pushes);
679
680 if (!pushes.empty() &&
681 (LocationOperand::cast(pushes.back()->destination()).index() + 1 ==
682 first_unused_stack_slot)) {
683 S390OperandConverter g(this, instr);
684 ZoneVector<Register> pending_pushes(zone());
685 for (auto move : pushes) {
686 LocationOperand destination_location(
687 LocationOperand::cast(move->destination()));
688 InstructionOperand source(move->source());
689 AdjustStackPointerForTailCall(
690 masm(), frame_access_state(),
691 destination_location.index() - pending_pushes.size(),
692 &pending_pushes);
693 if (source.IsStackSlot()) {
694 LocationOperand source_location(LocationOperand::cast(source));
695 __ LoadP(ip, g.SlotToMemOperand(source_location.index()));
696 AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes,
697 ip);
698 } else if (source.IsRegister()) {
699 LocationOperand source_location(LocationOperand::cast(source));
700 AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes,
701 source_location.GetRegister());
702 } else if (source.IsImmediate()) {
703 AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes,
704 ip);
705 } else {
706 // Pushes of non-scalar data types is not supported.
707 UNIMPLEMENTED();
708 }
709 move->Eliminate();
710 }
711 FlushPendingPushRegisters(masm(), frame_access_state(), &pending_pushes);
712 }
713 AdjustStackPointerForTailCall(masm(), frame_access_state(),
714 first_unused_stack_slot, nullptr, false);
715 }
716
717 void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
718 int first_unused_stack_slot) {
719 AdjustStackPointerForTailCall(masm(), frame_access_state(),
720 first_unused_stack_slot);
721 }
722
628 // Assembles an instruction after register allocation, producing machine code. 723 // Assembles an instruction after register allocation, producing machine code.
629 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 724 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
630 Instruction* instr) { 725 Instruction* instr) {
631 S390OperandConverter i(this, instr); 726 S390OperandConverter i(this, instr);
632 ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode()); 727 ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode());
633 728
634 switch (opcode) { 729 switch (opcode) {
635 case kArchCallCodeObject: { 730 case kArchCallCodeObject: {
636 EnsureSpaceForLazyDeopt(); 731 EnsureSpaceForLazyDeopt();
637 if (HasRegisterInput(instr, 0)) { 732 if (HasRegisterInput(instr, 0)) {
638 __ AddP(ip, i.InputRegister(0), 733 __ AddP(ip, i.InputRegister(0),
639 Operand(Code::kHeaderSize - kHeapObjectTag)); 734 Operand(Code::kHeaderSize - kHeapObjectTag));
640 __ Call(ip); 735 __ Call(ip);
641 } else { 736 } else {
642 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 737 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
643 RelocInfo::CODE_TARGET); 738 RelocInfo::CODE_TARGET);
644 } 739 }
645 RecordCallPosition(instr); 740 RecordCallPosition(instr);
646 frame_access_state()->ClearSPDelta(); 741 frame_access_state()->ClearSPDelta();
647 break; 742 break;
648 } 743 }
649 case kArchTailCallCodeObjectFromJSFunction: 744 case kArchTailCallCodeObjectFromJSFunction:
650 case kArchTailCallCodeObject: { 745 case kArchTailCallCodeObject: {
651 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
652 AssembleDeconstructActivationRecord(stack_param_delta);
653 if (opcode == kArchTailCallCodeObjectFromJSFunction) { 746 if (opcode == kArchTailCallCodeObjectFromJSFunction) {
654 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 747 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
655 i.TempRegister(0), i.TempRegister(1), 748 i.TempRegister(0), i.TempRegister(1),
656 i.TempRegister(2)); 749 i.TempRegister(2));
657 } 750 }
658 if (HasRegisterInput(instr, 0)) { 751 if (HasRegisterInput(instr, 0)) {
659 __ AddP(ip, i.InputRegister(0), 752 __ AddP(ip, i.InputRegister(0),
660 Operand(Code::kHeaderSize - kHeapObjectTag)); 753 Operand(Code::kHeaderSize - kHeapObjectTag));
661 __ Jump(ip); 754 __ Jump(ip);
662 } else { 755 } else {
663 // We cannot use the constant pool to load the target since 756 // We cannot use the constant pool to load the target since
664 // we've already restored the caller's frame. 757 // we've already restored the caller's frame.
665 ConstantPoolUnavailableScope constant_pool_unavailable(masm()); 758 ConstantPoolUnavailableScope constant_pool_unavailable(masm());
666 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 759 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
667 RelocInfo::CODE_TARGET); 760 RelocInfo::CODE_TARGET);
668 } 761 }
669 frame_access_state()->ClearSPDelta(); 762 frame_access_state()->ClearSPDelta();
763 frame_access_state()->SetFrameAccessToDefault();
670 break; 764 break;
671 } 765 }
672 case kArchTailCallAddress: { 766 case kArchTailCallAddress: {
673 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
674 AssembleDeconstructActivationRecord(stack_param_delta);
675 CHECK(!instr->InputAt(0)->IsImmediate()); 767 CHECK(!instr->InputAt(0)->IsImmediate());
676 __ Jump(i.InputRegister(0)); 768 __ Jump(i.InputRegister(0));
677 frame_access_state()->ClearSPDelta(); 769 frame_access_state()->ClearSPDelta();
770 frame_access_state()->SetFrameAccessToDefault();
678 break; 771 break;
679 } 772 }
680 case kArchCallJSFunction: { 773 case kArchCallJSFunction: {
681 EnsureSpaceForLazyDeopt(); 774 EnsureSpaceForLazyDeopt();
682 Register func = i.InputRegister(0); 775 Register func = i.InputRegister(0);
683 if (FLAG_debug_code) { 776 if (FLAG_debug_code) {
684 // Check the function's context matches the context argument. 777 // Check the function's context matches the context argument.
685 __ LoadP(kScratchReg, 778 __ LoadP(kScratchReg,
686 FieldMemOperand(func, JSFunction::kContextOffset)); 779 FieldMemOperand(func, JSFunction::kContextOffset));
687 __ CmpP(cp, kScratchReg); 780 __ CmpP(cp, kScratchReg);
688 __ Assert(eq, kWrongFunctionContext); 781 __ Assert(eq, kWrongFunctionContext);
689 } 782 }
690 __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 783 __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
691 __ Call(ip); 784 __ Call(ip);
692 RecordCallPosition(instr); 785 RecordCallPosition(instr);
693 frame_access_state()->ClearSPDelta(); 786 frame_access_state()->ClearSPDelta();
694 break; 787 break;
695 } 788 }
696 case kArchTailCallJSFunctionFromJSFunction: 789 case kArchTailCallJSFunctionFromJSFunction:
697 case kArchTailCallJSFunction: { 790 case kArchTailCallJSFunction: {
698 Register func = i.InputRegister(0); 791 Register func = i.InputRegister(0);
699 if (FLAG_debug_code) { 792 if (FLAG_debug_code) {
700 // Check the function's context matches the context argument. 793 // Check the function's context matches the context argument.
701 __ LoadP(kScratchReg, 794 __ LoadP(kScratchReg,
702 FieldMemOperand(func, JSFunction::kContextOffset)); 795 FieldMemOperand(func, JSFunction::kContextOffset));
703 __ CmpP(cp, kScratchReg); 796 __ CmpP(cp, kScratchReg);
704 __ Assert(eq, kWrongFunctionContext); 797 __ Assert(eq, kWrongFunctionContext);
705 } 798 }
706 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
707 AssembleDeconstructActivationRecord(stack_param_delta);
708 if (opcode == kArchTailCallJSFunctionFromJSFunction) { 799 if (opcode == kArchTailCallJSFunctionFromJSFunction) {
709 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 800 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
710 i.TempRegister(0), i.TempRegister(1), 801 i.TempRegister(0), i.TempRegister(1),
711 i.TempRegister(2)); 802 i.TempRegister(2));
712 } 803 }
713 __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 804 __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
714 __ Jump(ip); 805 __ Jump(ip);
715 frame_access_state()->ClearSPDelta(); 806 frame_access_state()->ClearSPDelta();
807 frame_access_state()->SetFrameAccessToDefault();
716 break; 808 break;
717 } 809 }
718 case kArchPrepareCallCFunction: { 810 case kArchPrepareCallCFunction: {
719 int const num_parameters = MiscField::decode(instr->opcode()); 811 int const num_parameters = MiscField::decode(instr->opcode());
720 __ PrepareCallCFunction(num_parameters, kScratchReg); 812 __ PrepareCallCFunction(num_parameters, kScratchReg);
721 // Frame alignment requires using FP-relative frame addressing. 813 // Frame alignment requires using FP-relative frame addressing.
722 frame_access_state()->SetFrameAccessToFP(); 814 frame_access_state()->SetFrameAccessToFP();
723 break; 815 break;
724 } 816 }
725 case kArchPrepareTailCall: 817 case kArchPrepareTailCall:
726 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); 818 AssemblePrepareTailCall();
727 break; 819 break;
728 case kArchCallCFunction: { 820 case kArchCallCFunction: {
729 int const num_parameters = MiscField::decode(instr->opcode()); 821 int const num_parameters = MiscField::decode(instr->opcode());
730 if (instr->InputAt(0)->IsImmediate()) { 822 if (instr->InputAt(0)->IsImmediate()) {
731 ExternalReference ref = i.InputExternalReference(0); 823 ExternalReference ref = i.InputExternalReference(0);
732 __ CallCFunction(ref, num_parameters); 824 __ CallCFunction(ref, num_parameters);
733 } else { 825 } else {
734 Register func = i.InputRegister(0); 826 Register func = i.InputRegister(0);
735 __ CallCFunction(func, num_parameters); 827 __ CallCFunction(func, num_parameters);
736 } 828 }
(...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after
2255 padding_size -= 2; 2347 padding_size -= 2;
2256 } 2348 }
2257 } 2349 }
2258 } 2350 }
2259 2351
2260 #undef __ 2352 #undef __
2261 2353
2262 } // namespace compiler 2354 } // namespace compiler
2263 } // namespace internal 2355 } // namespace internal
2264 } // namespace v8 2356 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ppc/code-generator-ppc.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698