| 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 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1065 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |  1065 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 
|  1066   VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); |  1066   VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero)); | 
|  1067 } |  1067 } | 
|  1068  |  1068  | 
|  1069  |  1069  | 
|  1070 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |  1070 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 
|  1071   UNREACHABLE(); |  1071   UNREACHABLE(); | 
|  1072 } |  1072 } | 
|  1073  |  1073  | 
|  1074  |  1074  | 
|  1075 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |  1075 void InstructionSelector::EmitPrepareArguments(NodeVector* arguments, | 
 |  1076                                                const CallDescriptor* descriptor, | 
 |  1077                                                Node* node) { | 
|  1076   X64OperandGenerator g(this); |  1078   X64OperandGenerator g(this); | 
|  1077   const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |  | 
|  1078  |  | 
|  1079   FrameStateDescriptor* frame_state_descriptor = nullptr; |  | 
|  1080   if (descriptor->NeedsFrameState()) { |  | 
|  1081     frame_state_descriptor = GetFrameStateDescriptor( |  | 
|  1082         node->InputAt(static_cast<int>(descriptor->InputCount()))); |  | 
|  1083   } |  | 
|  1084  |  | 
|  1085   CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |  | 
|  1086  |  | 
|  1087   // Compute InstructionOperands for inputs and outputs. |  | 
|  1088   InitializeCallBuffer(node, &buffer, true, true); |  | 
|  1089  |  1079  | 
|  1090   // Prepare for C function call. |  1080   // Prepare for C function call. | 
|  1091   if (descriptor->IsCFunctionCall()) { |  1081   if (descriptor->IsCFunctionCall()) { | 
|  1092     Emit(kArchPrepareCallCFunction | |  1082     Emit(kArchPrepareCallCFunction | | 
|  1093              MiscField::encode(static_cast<int>(descriptor->CParameterCount())), |  1083              MiscField::encode(static_cast<int>(descriptor->CParameterCount())), | 
|  1094          0, nullptr, 0, nullptr); |  1084          0, nullptr, 0, nullptr); | 
|  1095  |  1085  | 
|  1096     // Poke any stack arguments. |  1086     // Poke any stack arguments. | 
|  1097     for (size_t n = 0; n < buffer.pushed_nodes.size(); ++n) { |  1087     for (size_t n = 0; n < arguments->size(); ++n) { | 
|  1098       if (Node* input = buffer.pushed_nodes[n]) { |  1088       if (Node* input = (*arguments)[n]) { | 
|  1099         int slot = static_cast<int>(n); |  1089         int slot = static_cast<int>(n); | 
|  1100         InstructionOperand value = g.CanBeImmediate(input) |  1090         InstructionOperand value = g.CanBeImmediate(input) | 
|  1101                                        ? g.UseImmediate(input) |  1091                                        ? g.UseImmediate(input) | 
|  1102                                        : g.UseRegister(input); |  1092                                        : g.UseRegister(input); | 
|  1103         Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value); |  1093         Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value); | 
|  1104       } |  1094       } | 
|  1105     } |  1095     } | 
|  1106   } else { |  1096   } else { | 
|  1107     // Push any stack arguments. |  1097     // Push any stack arguments. | 
|  1108     for (Node* input : base::Reversed(buffer.pushed_nodes)) { |  1098     for (Node* input : base::Reversed(*arguments)) { | 
|  1109       // TODO(titzer): X64Push cannot handle stack->stack double moves |  1099       // TODO(titzer): X64Push cannot handle stack->stack double moves | 
|  1110       // because there is no way to encode fixed double slots. |  1100       // because there is no way to encode fixed double slots. | 
|  1111       InstructionOperand value = |  1101       InstructionOperand value = | 
|  1112           g.CanBeImmediate(input) |  1102           g.CanBeImmediate(input) | 
|  1113               ? g.UseImmediate(input) |  1103               ? g.UseImmediate(input) | 
|  1114               : IsSupported(ATOM) || |  1104               : IsSupported(ATOM) || | 
|  1115                         sequence()->IsFloat(GetVirtualRegister(input)) |  1105                         sequence()->IsFloat(GetVirtualRegister(input)) | 
|  1116                     ? g.UseRegister(input) |  1106                     ? g.UseRegister(input) | 
|  1117                     : g.Use(input); |  1107                     : g.Use(input); | 
|  1118       Emit(kX64Push, g.NoOutput(), value); |  1108       Emit(kX64Push, g.NoOutput(), value); | 
|  1119     } |  1109     } | 
|  1120   } |  1110   } | 
|  1121  |  | 
|  1122   // Pass label of exception handler block. |  | 
|  1123   CallDescriptor::Flags flags = descriptor->flags(); |  | 
|  1124   if (handler) { |  | 
|  1125     DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); |  | 
|  1126     IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); |  | 
|  1127     if (hint == IfExceptionHint::kLocallyCaught) { |  | 
|  1128       flags |= CallDescriptor::kHasLocalCatchHandler; |  | 
|  1129     } |  | 
|  1130     flags |= CallDescriptor::kHasExceptionHandler; |  | 
|  1131     buffer.instruction_args.push_back(g.Label(handler)); |  | 
|  1132   } |  | 
|  1133  |  | 
|  1134   // Select the appropriate opcode based on the call type. |  | 
|  1135   InstructionCode opcode = kArchNop; |  | 
|  1136   switch (descriptor->kind()) { |  | 
|  1137     case CallDescriptor::kCallAddress: |  | 
|  1138       opcode = |  | 
|  1139           kArchCallCFunction | |  | 
|  1140           MiscField::encode(static_cast<int>(descriptor->CParameterCount())); |  | 
|  1141       break; |  | 
|  1142     case CallDescriptor::kCallCodeObject: |  | 
|  1143       opcode = kArchCallCodeObject | MiscField::encode(flags); |  | 
|  1144       break; |  | 
|  1145     case CallDescriptor::kCallJSFunction: |  | 
|  1146       opcode = kArchCallJSFunction | MiscField::encode(flags); |  | 
|  1147       break; |  | 
|  1148     case CallDescriptor::kLazyBailout: |  | 
|  1149       opcode = kArchLazyBailout | MiscField::encode(flags); |  | 
|  1150       break; |  | 
|  1151   } |  | 
|  1152  |  | 
|  1153   // Emit the call instruction. |  | 
|  1154   size_t const output_count = buffer.outputs.size(); |  | 
|  1155   auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |  | 
|  1156   Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |  | 
|  1157        &buffer.instruction_args.front())->MarkAsCall(); |  | 
|  1158 } |  1111 } | 
|  1159  |  1112  | 
|  1160  |  1113  | 
|  1161 void InstructionSelector::VisitTailCall(Node* node) { |  1114 void InstructionSelector::VisitTailCall(Node* node) { | 
|  1162   X64OperandGenerator g(this); |  1115   X64OperandGenerator g(this); | 
|  1163   CallDescriptor const* descriptor = OpParameter<CallDescriptor const*>(node); |  1116   CallDescriptor const* descriptor = OpParameter<CallDescriptor const*>(node); | 
|  1164   DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); |  1117   DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); | 
|  1165   DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite); |  1118   DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite); | 
|  1166   DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall); |  1119   DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall); | 
|  1167  |  1120  | 
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1724   if (CpuFeatures::IsSupported(SSE4_1)) { |  1677   if (CpuFeatures::IsSupported(SSE4_1)) { | 
|  1725     flags |= MachineOperatorBuilder::kFloat64RoundDown | |  1678     flags |= MachineOperatorBuilder::kFloat64RoundDown | | 
|  1726              MachineOperatorBuilder::kFloat64RoundTruncate; |  1679              MachineOperatorBuilder::kFloat64RoundTruncate; | 
|  1727   } |  1680   } | 
|  1728   return flags; |  1681   return flags; | 
|  1729 } |  1682 } | 
|  1730  |  1683  | 
|  1731 }  // namespace compiler |  1684 }  // namespace compiler | 
|  1732 }  // namespace internal |  1685 }  // namespace internal | 
|  1733 }  // namespace v8 |  1686 }  // namespace v8 | 
| OLD | NEW |