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/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 808 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
809 VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); | 809 VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); |
810 } | 810 } |
811 | 811 |
812 | 812 |
813 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 813 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
814 UNREACHABLE(); | 814 UNREACHABLE(); |
815 } | 815 } |
816 | 816 |
817 | 817 |
818 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { | 818 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler, |
| 819 CallMode call_mode) { |
819 IA32OperandGenerator g(this); | 820 IA32OperandGenerator g(this); |
820 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | 821 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
821 | 822 |
822 FrameStateDescriptor* frame_state_descriptor = NULL; | 823 FrameStateDescriptor* frame_state_descriptor = NULL; |
823 | 824 |
824 if (descriptor->NeedsFrameState()) { | 825 if (descriptor->NeedsFrameState()) { |
825 frame_state_descriptor = | 826 frame_state_descriptor = |
826 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); | 827 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); |
827 } | 828 } |
828 | 829 |
(...skipping 13 matching lines...) Expand all Loading... |
842 } | 843 } |
843 | 844 |
844 // Pass label of exception handler block. | 845 // Pass label of exception handler block. |
845 CallDescriptor::Flags flags = descriptor->flags(); | 846 CallDescriptor::Flags flags = descriptor->flags(); |
846 if (handler != nullptr) { | 847 if (handler != nullptr) { |
847 flags |= CallDescriptor::kHasExceptionHandler; | 848 flags |= CallDescriptor::kHasExceptionHandler; |
848 buffer.instruction_args.push_back(g.Label(handler)); | 849 buffer.instruction_args.push_back(g.Label(handler)); |
849 } | 850 } |
850 | 851 |
851 // Select the appropriate opcode based on the call type. | 852 // Select the appropriate opcode based on the call type. |
| 853 bool is_tail_call = call_mode == TAIL_CALL; |
852 InstructionCode opcode; | 854 InstructionCode opcode; |
853 switch (descriptor->kind()) { | 855 switch (descriptor->kind()) { |
854 case CallDescriptor::kCallCodeObject: { | 856 case CallDescriptor::kCallCodeObject: { |
855 opcode = kArchCallCodeObject; | 857 opcode = is_tail_call ? kArchTailCallCodeObject : kArchCallCodeObject; |
856 break; | 858 break; |
857 } | 859 } |
858 case CallDescriptor::kCallJSFunction: | 860 case CallDescriptor::kCallJSFunction: |
859 opcode = kArchCallJSFunction; | 861 opcode = is_tail_call ? kArchTailCallJSFunction : kArchCallJSFunction; |
860 break; | 862 break; |
861 default: | 863 default: |
862 UNREACHABLE(); | 864 UNREACHABLE(); |
863 return; | 865 return; |
864 } | 866 } |
865 opcode |= MiscField::encode(flags); | 867 opcode |= MiscField::encode(flags); |
866 | 868 |
867 // Emit the call instruction. | 869 // Emit the call instruction. |
| 870 size_t size = is_tail_call ? 0 : buffer.outputs.size(); |
868 InstructionOperand* first_output = | 871 InstructionOperand* first_output = |
869 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; | 872 size > 0 ? &buffer.outputs.front() : nullptr; |
870 Instruction* call_instr = | 873 Instruction* call_instr = |
871 Emit(opcode, buffer.outputs.size(), first_output, | 874 Emit(opcode, size, first_output, buffer.instruction_args.size(), |
872 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 875 &buffer.instruction_args.front()); |
873 call_instr->MarkAsCall(); | 876 call_instr->MarkAsCall(); |
874 } | 877 } |
875 | 878 |
876 | 879 |
877 namespace { | 880 namespace { |
878 | 881 |
879 // Shared routine for multiple compare operations. | 882 // Shared routine for multiple compare operations. |
880 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 883 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
881 InstructionOperand left, InstructionOperand right, | 884 InstructionOperand left, InstructionOperand right, |
882 FlagsContinuation* cont) { | 885 FlagsContinuation* cont) { |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 if (CpuFeatures::IsSupported(SSE4_1)) { | 1239 if (CpuFeatures::IsSupported(SSE4_1)) { |
1237 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1240 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1238 MachineOperatorBuilder::kFloat64RoundTruncate; | 1241 MachineOperatorBuilder::kFloat64RoundTruncate; |
1239 } | 1242 } |
1240 return flags; | 1243 return flags; |
1241 } | 1244 } |
1242 | 1245 |
1243 } // namespace compiler | 1246 } // namespace compiler |
1244 } // namespace internal | 1247 } // namespace internal |
1245 } // namespace v8 | 1248 } // namespace v8 |
OLD | NEW |