| 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 |