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