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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 if (descriptor->NeedsFrameState()) { | 1031 if (descriptor->NeedsFrameState()) { |
1032 frame_state_descriptor = GetFrameStateDescriptor( | 1032 frame_state_descriptor = GetFrameStateDescriptor( |
1033 node->InputAt(static_cast<int>(descriptor->InputCount()))); | 1033 node->InputAt(static_cast<int>(descriptor->InputCount()))); |
1034 } | 1034 } |
1035 | 1035 |
1036 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 1036 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
1037 | 1037 |
1038 // Compute InstructionOperands for inputs and outputs. | 1038 // Compute InstructionOperands for inputs and outputs. |
1039 InitializeCallBuffer(node, &buffer, true, true); | 1039 InitializeCallBuffer(node, &buffer, true, true); |
1040 | 1040 |
1041 // Push any stack arguments. | 1041 // Prepare for C function call. |
1042 for (Node* node : base::Reversed(buffer.pushed_nodes)) { | 1042 if (descriptor->IsCFunctionCall()) { |
1043 // TODO(titzer): handle pushing double parameters. | 1043 Emit(kArchPrepareCallCFunction | |
1044 InstructionOperand value = | 1044 MiscField::encode(static_cast<int>(descriptor->CParameterCount())), |
1045 g.CanBeImmediate(node) | 1045 0, nullptr, 0, nullptr); |
1046 ? g.UseImmediate(node) | 1046 |
1047 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); | 1047 // Poke any stack arguments. |
1048 Emit(kX64Push, g.NoOutput(), value); | 1048 for (size_t n = 0; n < buffer.pushed_nodes.size(); ++n) { |
| 1049 if (Node* node = buffer.pushed_nodes[n]) { |
| 1050 int const slot = static_cast<int>(n); |
| 1051 InstructionOperand value = |
| 1052 g.CanBeImmediate(node) ? g.UseImmediate(node) : g.UseRegister(node); |
| 1053 Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value); |
| 1054 } |
| 1055 } |
| 1056 } else { |
| 1057 // Push any stack arguments. |
| 1058 for (Node* node : base::Reversed(buffer.pushed_nodes)) { |
| 1059 // TODO(titzer): handle pushing double parameters. |
| 1060 InstructionOperand value = |
| 1061 g.CanBeImmediate(node) |
| 1062 ? g.UseImmediate(node) |
| 1063 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); |
| 1064 Emit(kX64Push, g.NoOutput(), value); |
| 1065 } |
1049 } | 1066 } |
1050 | 1067 |
1051 // Pass label of exception handler block. | 1068 // Pass label of exception handler block. |
1052 CallDescriptor::Flags flags = descriptor->flags(); | 1069 CallDescriptor::Flags flags = descriptor->flags(); |
1053 if (handler) { | 1070 if (handler) { |
1054 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); | 1071 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); |
1055 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); | 1072 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); |
1056 if (hint == IfExceptionHint::kLocallyCaught) { | 1073 if (hint == IfExceptionHint::kLocallyCaught) { |
1057 flags |= CallDescriptor::kHasLocalCatchHandler; | 1074 flags |= CallDescriptor::kHasLocalCatchHandler; |
1058 } | 1075 } |
1059 flags |= CallDescriptor::kHasExceptionHandler; | 1076 flags |= CallDescriptor::kHasExceptionHandler; |
1060 buffer.instruction_args.push_back(g.Label(handler)); | 1077 buffer.instruction_args.push_back(g.Label(handler)); |
1061 } | 1078 } |
1062 | 1079 |
1063 // Select the appropriate opcode based on the call type. | 1080 // Select the appropriate opcode based on the call type. |
1064 InstructionCode opcode; | 1081 InstructionCode opcode; |
1065 switch (descriptor->kind()) { | 1082 switch (descriptor->kind()) { |
| 1083 case CallDescriptor::kCallAddress: |
| 1084 opcode = |
| 1085 kArchCallCFunction | |
| 1086 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); |
| 1087 break; |
1066 case CallDescriptor::kCallCodeObject: | 1088 case CallDescriptor::kCallCodeObject: |
1067 opcode = kArchCallCodeObject; | 1089 opcode = kArchCallCodeObject | MiscField::encode(flags); |
1068 break; | 1090 break; |
1069 case CallDescriptor::kCallJSFunction: | 1091 case CallDescriptor::kCallJSFunction: |
1070 opcode = kArchCallJSFunction; | 1092 opcode = kArchCallJSFunction | MiscField::encode(flags); |
1071 break; | 1093 break; |
1072 default: | 1094 default: |
1073 UNREACHABLE(); | 1095 UNREACHABLE(); |
1074 return; | 1096 return; |
1075 } | 1097 } |
1076 opcode |= MiscField::encode(flags); | |
1077 | 1098 |
1078 // Emit the call instruction. | 1099 // Emit the call instruction. |
1079 size_t const output_count = buffer.outputs.size(); | 1100 size_t const output_count = buffer.outputs.size(); |
1080 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | 1101 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |
1081 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | 1102 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
1082 &buffer.instruction_args.front())->MarkAsCall(); | 1103 &buffer.instruction_args.front())->MarkAsCall(); |
1083 } | 1104 } |
1084 | 1105 |
1085 | 1106 |
1086 void InstructionSelector::VisitTailCall(Node* node) { | 1107 void InstructionSelector::VisitTailCall(Node* node) { |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1640 if (CpuFeatures::IsSupported(SSE4_1)) { | 1661 if (CpuFeatures::IsSupported(SSE4_1)) { |
1641 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1662 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1642 MachineOperatorBuilder::kFloat64RoundTruncate; | 1663 MachineOperatorBuilder::kFloat64RoundTruncate; |
1643 } | 1664 } |
1644 return flags; | 1665 return flags; |
1645 } | 1666 } |
1646 | 1667 |
1647 } // namespace compiler | 1668 } // namespace compiler |
1648 } // namespace internal | 1669 } // namespace internal |
1649 } // namespace v8 | 1670 } // namespace v8 |
OLD | NEW |