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 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 641 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
642 VisitRR(this, kMips64Float64RoundTruncate, node); | 642 VisitRR(this, kMips64Float64RoundTruncate, node); |
643 } | 643 } |
644 | 644 |
645 | 645 |
646 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 646 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
647 UNREACHABLE(); | 647 UNREACHABLE(); |
648 } | 648 } |
649 | 649 |
650 | 650 |
651 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { | 651 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler, |
| 652 CallMode call_mode) { |
652 Mips64OperandGenerator g(this); | 653 Mips64OperandGenerator g(this); |
653 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | 654 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
654 | 655 |
655 FrameStateDescriptor* frame_state_descriptor = NULL; | 656 FrameStateDescriptor* frame_state_descriptor = NULL; |
656 if (descriptor->NeedsFrameState()) { | 657 if (descriptor->NeedsFrameState()) { |
657 frame_state_descriptor = | 658 frame_state_descriptor = |
658 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); | 659 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); |
659 } | 660 } |
660 | 661 |
661 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 662 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
(...skipping 14 matching lines...) Expand all Loading... |
676 } | 677 } |
677 | 678 |
678 // Pass label of exception handler block. | 679 // Pass label of exception handler block. |
679 CallDescriptor::Flags flags = descriptor->flags(); | 680 CallDescriptor::Flags flags = descriptor->flags(); |
680 if (handler != nullptr) { | 681 if (handler != nullptr) { |
681 flags |= CallDescriptor::kHasExceptionHandler; | 682 flags |= CallDescriptor::kHasExceptionHandler; |
682 buffer.instruction_args.push_back(g.Label(handler)); | 683 buffer.instruction_args.push_back(g.Label(handler)); |
683 } | 684 } |
684 | 685 |
685 // Select the appropriate opcode based on the call type. | 686 // Select the appropriate opcode based on the call type. |
| 687 bool is_tail_call = call_mode == TAIL_CALL; |
686 InstructionCode opcode; | 688 InstructionCode opcode; |
687 switch (descriptor->kind()) { | 689 switch (descriptor->kind()) { |
688 case CallDescriptor::kCallCodeObject: { | 690 case CallDescriptor::kCallCodeObject: { |
689 opcode = kArchCallCodeObject; | 691 opcode = is_tail_call ? kArchTailCallCodeObject : kArchCallCodeObject; |
690 break; | 692 break; |
691 } | 693 } |
692 case CallDescriptor::kCallJSFunction: | 694 case CallDescriptor::kCallJSFunction: |
693 opcode = kArchCallJSFunction; | 695 opcode = is_tail_call ? kArchTailCallJSFunction : kArchCallJSFunction; |
694 break; | 696 break; |
695 default: | 697 default: |
696 UNREACHABLE(); | 698 UNREACHABLE(); |
697 return; | 699 return; |
698 } | 700 } |
699 opcode |= MiscField::encode(flags); | 701 opcode |= MiscField::encode(flags); |
700 | 702 |
701 // Emit the call instruction. | 703 // Emit the call instruction. |
| 704 size_t size = is_tail_call ? 0 : buffer.outputs.size(); |
| 705 InstructionOperand* first_output = |
| 706 size > 0 ? &buffer.outputs.front() : nullptr; |
702 Instruction* call_instr = | 707 Instruction* call_instr = |
703 Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(), | 708 Emit(opcode, size, first_output, buffer.instruction_args.size(), |
704 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 709 &buffer.instruction_args.front()); |
705 | |
706 call_instr->MarkAsCall(); | 710 call_instr->MarkAsCall(); |
707 } | 711 } |
708 | 712 |
709 | 713 |
710 void InstructionSelector::VisitCheckedLoad(Node* node) { | 714 void InstructionSelector::VisitCheckedLoad(Node* node) { |
711 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 715 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
712 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | 716 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
713 Mips64OperandGenerator g(this); | 717 Mips64OperandGenerator g(this); |
714 Node* const buffer = node->InputAt(0); | 718 Node* const buffer = node->InputAt(0); |
715 Node* const offset = node->InputAt(1); | 719 Node* const offset = node->InputAt(1); |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 InstructionSelector::SupportedMachineOperatorFlags() { | 1192 InstructionSelector::SupportedMachineOperatorFlags() { |
1189 return MachineOperatorBuilder::kFloat32Abs | | 1193 return MachineOperatorBuilder::kFloat32Abs | |
1190 MachineOperatorBuilder::kFloat64Abs | | 1194 MachineOperatorBuilder::kFloat64Abs | |
1191 MachineOperatorBuilder::kFloat64RoundDown | | 1195 MachineOperatorBuilder::kFloat64RoundDown | |
1192 MachineOperatorBuilder::kFloat64RoundTruncate; | 1196 MachineOperatorBuilder::kFloat64RoundTruncate; |
1193 } | 1197 } |
1194 | 1198 |
1195 } // namespace compiler | 1199 } // namespace compiler |
1196 } // namespace internal | 1200 } // namespace internal |
1197 } // namespace v8 | 1201 } // namespace v8 |
OLD | NEW |