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 |