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 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 if (descriptor->NeedsFrameState()) { | 807 if (descriptor->NeedsFrameState()) { |
808 frame_state_descriptor = | 808 frame_state_descriptor = |
809 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); | 809 GetFrameStateDescriptor(node->InputAt(descriptor->InputCount())); |
810 } | 810 } |
811 | 811 |
812 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 812 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
813 | 813 |
814 // Compute InstructionOperands for inputs and outputs. | 814 // Compute InstructionOperands for inputs and outputs. |
815 InitializeCallBuffer(node, &buffer, true, true); | 815 InitializeCallBuffer(node, &buffer, true, true); |
816 | 816 |
817 // Push any stack arguments. | 817 // Prepare for C function call. |
818 for (Node* node : base::Reversed(buffer.pushed_nodes)) { | 818 if (descriptor->IsCFunctionCall()) { |
819 // TODO(titzer): handle pushing double parameters. | 819 InstructionOperand temps[] = {g.TempRegister()}; |
820 InstructionOperand value = | 820 size_t const temp_count = arraysize(temps); |
821 g.CanBeImmediate(node) | 821 Emit(kArchPrepareCallCFunction | |
822 ? g.UseImmediate(node) | 822 MiscField::encode(static_cast<int>(descriptor->CParameterCount())), |
823 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); | 823 0, nullptr, 0, nullptr, temp_count, temps); |
824 Emit(kX87Push, g.NoOutput(), value); | 824 |
| 825 // Poke any stack arguments. |
| 826 for (size_t n = 0; n < buffer.pushed_nodes.size(); ++n) { |
| 827 if (Node* node = buffer.pushed_nodes[n]) { |
| 828 int const slot = static_cast<int>(n); |
| 829 InstructionOperand value = |
| 830 g.CanBeImmediate(node) ? g.UseImmediate(node) : g.UseRegister(node); |
| 831 Emit(kX87Poke | MiscField::encode(slot), g.NoOutput(), value); |
| 832 } |
| 833 } |
| 834 } else { |
| 835 // Push any stack arguments. |
| 836 for (Node* node : base::Reversed(buffer.pushed_nodes)) { |
| 837 // TODO(titzer): handle pushing double parameters. |
| 838 InstructionOperand value = |
| 839 g.CanBeImmediate(node) |
| 840 ? g.UseImmediate(node) |
| 841 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); |
| 842 Emit(kX87Push, g.NoOutput(), value); |
| 843 } |
825 } | 844 } |
826 | 845 |
827 // Pass label of exception handler block. | 846 // Pass label of exception handler block. |
828 CallDescriptor::Flags flags = descriptor->flags(); | 847 CallDescriptor::Flags flags = descriptor->flags(); |
829 if (handler) { | 848 if (handler) { |
830 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); | 849 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); |
831 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); | 850 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); |
832 if (hint == IfExceptionHint::kLocallyCaught) { | 851 if (hint == IfExceptionHint::kLocallyCaught) { |
833 flags |= CallDescriptor::kHasLocalCatchHandler; | 852 flags |= CallDescriptor::kHasLocalCatchHandler; |
834 } | 853 } |
835 flags |= CallDescriptor::kHasExceptionHandler; | 854 flags |= CallDescriptor::kHasExceptionHandler; |
836 buffer.instruction_args.push_back(g.Label(handler)); | 855 buffer.instruction_args.push_back(g.Label(handler)); |
837 } | 856 } |
838 | 857 |
839 // Select the appropriate opcode based on the call type. | 858 // Select the appropriate opcode based on the call type. |
840 InstructionCode opcode; | 859 InstructionCode opcode; |
841 switch (descriptor->kind()) { | 860 switch (descriptor->kind()) { |
842 case CallDescriptor::kCallCodeObject: { | 861 case CallDescriptor::kCallAddress: |
843 opcode = kArchCallCodeObject; | 862 opcode = |
| 863 kArchCallCFunction | |
| 864 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); |
844 break; | 865 break; |
845 } | 866 case CallDescriptor::kCallCodeObject: |
| 867 opcode = kArchCallCodeObject | MiscField::encode(flags); |
| 868 break; |
846 case CallDescriptor::kCallJSFunction: | 869 case CallDescriptor::kCallJSFunction: |
847 opcode = kArchCallJSFunction; | 870 opcode = kArchCallJSFunction | MiscField::encode(flags); |
848 break; | 871 break; |
849 default: | 872 default: |
850 UNREACHABLE(); | 873 UNREACHABLE(); |
851 return; | 874 return; |
852 } | 875 } |
853 opcode |= MiscField::encode(flags); | |
854 | 876 |
855 // Emit the call instruction. | 877 // Emit the call instruction. |
856 size_t const output_count = buffer.outputs.size(); | 878 size_t const output_count = buffer.outputs.size(); |
857 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | 879 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |
858 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | 880 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
859 &buffer.instruction_args.front())->MarkAsCall(); | 881 &buffer.instruction_args.front())->MarkAsCall(); |
860 } | 882 } |
861 | 883 |
862 | 884 |
863 void InstructionSelector::VisitTailCall(Node* node) { | 885 void InstructionSelector::VisitTailCall(Node* node) { |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 MachineOperatorBuilder::kFloat32Min | | 1332 MachineOperatorBuilder::kFloat32Min | |
1311 MachineOperatorBuilder::kFloat64Max | | 1333 MachineOperatorBuilder::kFloat64Max | |
1312 MachineOperatorBuilder::kFloat64Min | | 1334 MachineOperatorBuilder::kFloat64Min | |
1313 MachineOperatorBuilder::kWord32ShiftIsSafe; | 1335 MachineOperatorBuilder::kWord32ShiftIsSafe; |
1314 return flags; | 1336 return flags; |
1315 } | 1337 } |
1316 | 1338 |
1317 } // namespace compiler | 1339 } // namespace compiler |
1318 } // namespace internal | 1340 } // namespace internal |
1319 } // namespace v8 | 1341 } // namespace v8 |
OLD | NEW |