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 int slot = 0; |
| 1049 for (Node* node : buffer.pushed_nodes) { |
| 1050 InstructionOperand value = |
| 1051 g.CanBeImmediate(node) ? g.UseImmediate(node) : g.UseRegister(node); |
| 1052 Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value); |
| 1053 ++slot; |
| 1054 } |
| 1055 } else { |
| 1056 // Push any stack arguments. |
| 1057 for (Node* node : base::Reversed(buffer.pushed_nodes)) { |
| 1058 // TODO(titzer): handle pushing double parameters. |
| 1059 InstructionOperand value = |
| 1060 g.CanBeImmediate(node) |
| 1061 ? g.UseImmediate(node) |
| 1062 : IsSupported(ATOM) ? g.UseRegister(node) : g.Use(node); |
| 1063 Emit(kX64Push, g.NoOutput(), value); |
| 1064 } |
1049 } | 1065 } |
1050 | 1066 |
1051 // Pass label of exception handler block. | 1067 // Pass label of exception handler block. |
1052 CallDescriptor::Flags flags = descriptor->flags(); | 1068 CallDescriptor::Flags flags = descriptor->flags(); |
1053 if (handler) { | 1069 if (handler) { |
1054 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); | 1070 DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); |
1055 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); | 1071 IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); |
1056 if (hint == IfExceptionHint::kLocallyCaught) { | 1072 if (hint == IfExceptionHint::kLocallyCaught) { |
1057 flags |= CallDescriptor::kHasLocalCatchHandler; | 1073 flags |= CallDescriptor::kHasLocalCatchHandler; |
1058 } | 1074 } |
1059 flags |= CallDescriptor::kHasExceptionHandler; | 1075 flags |= CallDescriptor::kHasExceptionHandler; |
1060 buffer.instruction_args.push_back(g.Label(handler)); | 1076 buffer.instruction_args.push_back(g.Label(handler)); |
1061 } | 1077 } |
1062 | 1078 |
1063 // Select the appropriate opcode based on the call type. | 1079 // Select the appropriate opcode based on the call type. |
1064 InstructionCode opcode; | 1080 InstructionCode opcode; |
1065 switch (descriptor->kind()) { | 1081 switch (descriptor->kind()) { |
| 1082 case CallDescriptor::kCallAddress: |
| 1083 opcode = |
| 1084 kArchCallCFunction | |
| 1085 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); |
| 1086 break; |
1066 case CallDescriptor::kCallCodeObject: | 1087 case CallDescriptor::kCallCodeObject: |
1067 opcode = kArchCallCodeObject; | 1088 opcode = kArchCallCodeObject | MiscField::encode(flags); |
1068 break; | 1089 break; |
1069 case CallDescriptor::kCallJSFunction: | 1090 case CallDescriptor::kCallJSFunction: |
1070 opcode = kArchCallJSFunction; | 1091 opcode = kArchCallJSFunction | MiscField::encode(flags); |
1071 break; | 1092 break; |
1072 default: | 1093 default: |
1073 UNREACHABLE(); | 1094 UNREACHABLE(); |
1074 return; | 1095 return; |
1075 } | 1096 } |
1076 opcode |= MiscField::encode(flags); | |
1077 | 1097 |
1078 // Emit the call instruction. | 1098 // Emit the call instruction. |
1079 size_t const output_count = buffer.outputs.size(); | 1099 size_t const output_count = buffer.outputs.size(); |
1080 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | 1100 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |
1081 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | 1101 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
1082 &buffer.instruction_args.front())->MarkAsCall(); | 1102 &buffer.instruction_args.front())->MarkAsCall(); |
1083 } | 1103 } |
1084 | 1104 |
1085 | 1105 |
1086 void InstructionSelector::VisitTailCall(Node* node) { | 1106 void InstructionSelector::VisitTailCall(Node* node) { |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1640 if (CpuFeatures::IsSupported(SSE4_1)) { | 1660 if (CpuFeatures::IsSupported(SSE4_1)) { |
1641 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1661 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
1642 MachineOperatorBuilder::kFloat64RoundTruncate; | 1662 MachineOperatorBuilder::kFloat64RoundTruncate; |
1643 } | 1663 } |
1644 return flags; | 1664 return flags; |
1645 } | 1665 } |
1646 | 1666 |
1647 } // namespace compiler | 1667 } // namespace compiler |
1648 } // namespace internal | 1668 } // namespace internal |
1649 } // namespace v8 | 1669 } // namespace v8 |
OLD | NEW |