| 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/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 DCHECK(CpuFeatures::IsSupported(SSE4_1)); | 711 DCHECK(CpuFeatures::IsSupported(SSE4_1)); |
| 712 VisitRRFloat64(this, kSSEFloat64RoundTruncate, node); | 712 VisitRRFloat64(this, kSSEFloat64RoundTruncate, node); |
| 713 } | 713 } |
| 714 | 714 |
| 715 | 715 |
| 716 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 716 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
| 717 UNREACHABLE(); | 717 UNREACHABLE(); |
| 718 } | 718 } |
| 719 | 719 |
| 720 | 720 |
| 721 void InstructionSelector::VisitCall(Node* node) { | 721 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
| 722 IA32OperandGenerator g(this); | 722 IA32OperandGenerator g(this); |
| 723 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | 723 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
| 724 | 724 |
| 725 FrameStateDescriptor* frame_state_descriptor = NULL; | 725 FrameStateDescriptor* frame_state_descriptor = NULL; |
| 726 | 726 |
| 727 if (descriptor->NeedsFrameState()) { | 727 if (descriptor->NeedsFrameState()) { |
| 728 frame_state_descriptor = | 728 frame_state_descriptor = |
| 729 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); | 729 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); |
| 730 } | 730 } |
| 731 | 731 |
| 732 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 732 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
| 733 | 733 |
| 734 // Compute InstructionOperands for inputs and outputs. | 734 // Compute InstructionOperands for inputs and outputs. |
| 735 InitializeCallBuffer(node, &buffer, true, true); | 735 InitializeCallBuffer(node, &buffer, true, true); |
| 736 | 736 |
| 737 // Push any stack arguments. | 737 // Push any stack arguments. |
| 738 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); | 738 for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); |
| 739 ++i) { | 739 ++i) { |
| 740 // TODO(titzer): handle pushing double parameters. | 740 // TODO(titzer): handle pushing double parameters. |
| 741 InstructionOperand value = | 741 InstructionOperand value = |
| 742 g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM) | 742 g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM) |
| 743 ? g.UseRegister(*i) | 743 ? g.UseRegister(*i) |
| 744 : g.Use(*i); | 744 : g.Use(*i); |
| 745 Emit(kIA32Push, g.NoOutput(), value); | 745 Emit(kIA32Push, g.NoOutput(), value); |
| 746 } | 746 } |
| 747 | 747 |
| 748 // Pass label of exception handler block. |
| 749 CallDescriptor::Flags flags = descriptor->flags(); |
| 750 if (handler != nullptr) { |
| 751 flags |= CallDescriptor::kHasExceptionHandler; |
| 752 buffer.instruction_args.push_back(g.Label(handler)); |
| 753 } |
| 754 |
| 748 // Select the appropriate opcode based on the call type. | 755 // Select the appropriate opcode based on the call type. |
| 749 InstructionCode opcode; | 756 InstructionCode opcode; |
| 750 switch (descriptor->kind()) { | 757 switch (descriptor->kind()) { |
| 751 case CallDescriptor::kCallCodeObject: { | 758 case CallDescriptor::kCallCodeObject: { |
| 752 opcode = kArchCallCodeObject; | 759 opcode = kArchCallCodeObject; |
| 753 break; | 760 break; |
| 754 } | 761 } |
| 755 case CallDescriptor::kCallJSFunction: | 762 case CallDescriptor::kCallJSFunction: |
| 756 opcode = kArchCallJSFunction; | 763 opcode = kArchCallJSFunction; |
| 757 break; | 764 break; |
| 758 default: | 765 default: |
| 759 UNREACHABLE(); | 766 UNREACHABLE(); |
| 760 return; | 767 return; |
| 761 } | 768 } |
| 762 opcode |= MiscField::encode(descriptor->flags()); | 769 opcode |= MiscField::encode(flags); |
| 763 | 770 |
| 764 // Emit the call instruction. | 771 // Emit the call instruction. |
| 765 InstructionOperand* first_output = | 772 InstructionOperand* first_output = |
| 766 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; | 773 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; |
| 767 Instruction* call_instr = | 774 Instruction* call_instr = |
| 768 Emit(opcode, buffer.outputs.size(), first_output, | 775 Emit(opcode, buffer.outputs.size(), first_output, |
| 769 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 776 buffer.instruction_args.size(), &buffer.instruction_args.front()); |
| 770 call_instr->MarkAsCall(); | 777 call_instr->MarkAsCall(); |
| 771 } | 778 } |
| 772 | 779 |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 MachineOperatorBuilder::kFloat64Ceil | | 1076 MachineOperatorBuilder::kFloat64Ceil | |
| 1070 MachineOperatorBuilder::kFloat64RoundTruncate | | 1077 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1071 MachineOperatorBuilder::kWord32ShiftIsSafe; | 1078 MachineOperatorBuilder::kWord32ShiftIsSafe; |
| 1072 } | 1079 } |
| 1073 return MachineOperatorBuilder::Flag::kNoFlags; | 1080 return MachineOperatorBuilder::Flag::kNoFlags; |
| 1074 } | 1081 } |
| 1075 | 1082 |
| 1076 } // namespace compiler | 1083 } // namespace compiler |
| 1077 } // namespace internal | 1084 } // namespace internal |
| 1078 } // namespace v8 | 1085 } // namespace v8 |
| OLD | NEW |