| 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 |