OLD | NEW |
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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 709 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
710 VisitRR(this, kMips64Float64RoundTruncate, node); | 710 VisitRR(this, kMips64Float64RoundTruncate, node); |
711 } | 711 } |
712 | 712 |
713 | 713 |
714 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 714 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
715 UNREACHABLE(); | 715 UNREACHABLE(); |
716 } | 716 } |
717 | 717 |
718 | 718 |
719 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { | 719 void InstructionSelector::EmitPrepareArguments(NodeVector* arguments, |
| 720 const CallDescriptor* descriptor, |
| 721 Node* node) { |
720 Mips64OperandGenerator g(this); | 722 Mips64OperandGenerator g(this); |
721 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | |
722 | |
723 FrameStateDescriptor* frame_state_descriptor = nullptr; | |
724 if (descriptor->NeedsFrameState()) { | |
725 frame_state_descriptor = GetFrameStateDescriptor( | |
726 node->InputAt(static_cast<int>(descriptor->InputCount()))); | |
727 } | |
728 | |
729 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | |
730 | |
731 // Compute InstructionOperands for inputs and outputs. | |
732 InitializeCallBuffer(node, &buffer, true, true); | |
733 | 723 |
734 // Prepare for C function call. | 724 // Prepare for C function call. |
735 if (descriptor->IsCFunctionCall()) { | 725 if (descriptor->IsCFunctionCall()) { |
736 Emit(kArchPrepareCallCFunction | | 726 Emit(kArchPrepareCallCFunction | |
737 MiscField::encode(static_cast<int>(descriptor->CParameterCount())), | 727 MiscField::encode(static_cast<int>(descriptor->CParameterCount())), |
738 0, nullptr, 0, nullptr); | 728 0, nullptr, 0, nullptr); |
739 | 729 |
740 // Poke any stack arguments. | 730 // Poke any stack arguments. |
741 int slot = kCArgSlotCount; | 731 int slot = kCArgSlotCount; |
742 for (Node* input : buffer.pushed_nodes) { | 732 for (Node* input : (*arguments)) { |
743 Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input), | 733 Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input), |
744 g.TempImmediate(slot << kPointerSizeLog2)); | 734 g.TempImmediate(slot << kPointerSizeLog2)); |
745 ++slot; | 735 ++slot; |
746 } | 736 } |
747 } else { | 737 } else { |
748 int push_count = static_cast<int>(descriptor->StackParameterCount()); | 738 int push_count = static_cast<int>(descriptor->StackParameterCount()); |
749 if (push_count > 0) { | 739 if (push_count > 0) { |
750 Emit(kMips64StackClaim, g.NoOutput(), | 740 Emit(kMips64StackClaim, g.NoOutput(), |
751 g.TempImmediate(push_count << kPointerSizeLog2)); | 741 g.TempImmediate(push_count << kPointerSizeLog2)); |
752 } | 742 } |
753 for (size_t n = 0; n < buffer.pushed_nodes.size(); ++n) { | 743 for (size_t n = 0; n < arguments->size(); ++n) { |
754 if (Node* input = buffer.pushed_nodes[n]) { | 744 if (Node* input = (*arguments)[n]) { |
755 Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input), | 745 Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input), |
756 g.TempImmediate(static_cast<int>(n << kPointerSizeLog2))); | 746 g.TempImmediate(static_cast<int>(n << kPointerSizeLog2))); |
757 } | 747 } |
758 } | 748 } |
759 } | 749 } |
760 | |
761 // Pass label of exception handler block. | |
762 CallDescriptor::Flags flags = descriptor->flags(); | |
763 if (handler) { | |
764 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); | |
765 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); | |
766 if (hint == IfExceptionHint::kLocallyCaught) { | |
767 flags |= CallDescriptor::kHasLocalCatchHandler; | |
768 } | |
769 flags |= CallDescriptor::kHasExceptionHandler; | |
770 buffer.instruction_args.push_back(g.Label(handler)); | |
771 } | |
772 | |
773 // Select the appropriate opcode based on the call type. | |
774 InstructionCode opcode = kArchNop; | |
775 switch (descriptor->kind()) { | |
776 case CallDescriptor::kCallAddress: | |
777 opcode = | |
778 kArchCallCFunction | | |
779 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); | |
780 break; | |
781 case CallDescriptor::kCallCodeObject: | |
782 opcode = kArchCallCodeObject | MiscField::encode(flags); | |
783 break; | |
784 case CallDescriptor::kCallJSFunction: | |
785 opcode = kArchCallJSFunction | MiscField::encode(flags); | |
786 break; | |
787 case CallDescriptor::kLazyBailout: | |
788 opcode = kArchLazyBailout | MiscField::encode(flags); | |
789 break; | |
790 } | |
791 opcode |= MiscField::encode(flags); | |
792 | |
793 // Emit the call instruction. | |
794 size_t const output_count = buffer.outputs.size(); | |
795 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | |
796 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | |
797 &buffer.instruction_args.front())->MarkAsCall(); | |
798 } | 750 } |
799 | 751 |
800 | 752 |
801 void InstructionSelector::VisitTailCall(Node* node) { | 753 void InstructionSelector::VisitTailCall(Node* node) { |
802 Mips64OperandGenerator g(this); | 754 Mips64OperandGenerator g(this); |
803 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | 755 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
804 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); | 756 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); |
805 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite); | 757 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite); |
806 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall); | 758 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall); |
807 | 759 |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1418 // static | 1370 // static |
1419 MachineOperatorBuilder::Flags | 1371 MachineOperatorBuilder::Flags |
1420 InstructionSelector::SupportedMachineOperatorFlags() { | 1372 InstructionSelector::SupportedMachineOperatorFlags() { |
1421 return MachineOperatorBuilder::kFloat64RoundDown | | 1373 return MachineOperatorBuilder::kFloat64RoundDown | |
1422 MachineOperatorBuilder::kFloat64RoundTruncate; | 1374 MachineOperatorBuilder::kFloat64RoundTruncate; |
1423 } | 1375 } |
1424 | 1376 |
1425 } // namespace compiler | 1377 } // namespace compiler |
1426 } // namespace internal | 1378 } // namespace internal |
1427 } // namespace v8 | 1379 } // namespace v8 |
OLD | NEW |