| 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/base/bits.h" | 6 #include "src/base/bits.h" |
| 7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
| 8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
| 9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
| 10 | 10 |
| (...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 // Push any stack arguments. | 1133 // Push any stack arguments. |
| 1134 for (Node* input : base::Reversed(*arguments)) { | 1134 for (Node* input : base::Reversed(*arguments)) { |
| 1135 // Skip any alignment holes in pushed nodes. | 1135 // Skip any alignment holes in pushed nodes. |
| 1136 if (input == nullptr) continue; | 1136 if (input == nullptr) continue; |
| 1137 Emit(kArmPush, g.NoOutput(), g.UseRegister(input)); | 1137 Emit(kArmPush, g.NoOutput(), g.UseRegister(input)); |
| 1138 } | 1138 } |
| 1139 } | 1139 } |
| 1140 } | 1140 } |
| 1141 | 1141 |
| 1142 | 1142 |
| 1143 void InstructionSelector::VisitTailCall(Node* node) { | 1143 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } |
| 1144 ArmOperandGenerator g(this); | |
| 1145 CallDescriptor const* descriptor = OpParameter<CallDescriptor const*>(node); | |
| 1146 DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls); | |
| 1147 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite); | |
| 1148 DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall); | |
| 1149 | |
| 1150 // TODO(turbofan): Relax restriction for stack parameters. | |
| 1151 if (linkage()->GetIncomingDescriptor()->CanTailCall(node)) { | |
| 1152 CallBuffer buffer(zone(), descriptor, nullptr); | |
| 1153 | |
| 1154 // Compute InstructionOperands for inputs and outputs. | |
| 1155 // TODO(turbofan): on ARM it's probably better to use the code object in a | |
| 1156 // register if there are multiple uses of it. Improve constant pool and the | |
| 1157 // heuristics in the register allocator for where to emit constants. | |
| 1158 InitializeCallBuffer(node, &buffer, true, false); | |
| 1159 | |
| 1160 // Select the appropriate opcode based on the call type. | |
| 1161 InstructionCode opcode; | |
| 1162 switch (descriptor->kind()) { | |
| 1163 case CallDescriptor::kCallCodeObject: | |
| 1164 opcode = kArchTailCallCodeObject; | |
| 1165 break; | |
| 1166 case CallDescriptor::kCallJSFunction: | |
| 1167 opcode = kArchTailCallJSFunction; | |
| 1168 break; | |
| 1169 default: | |
| 1170 UNREACHABLE(); | |
| 1171 return; | |
| 1172 } | |
| 1173 opcode |= MiscField::encode(descriptor->flags()); | |
| 1174 | |
| 1175 // Emit the tailcall instruction. | |
| 1176 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), | |
| 1177 &buffer.instruction_args.front()); | |
| 1178 } else { | |
| 1179 FrameStateDescriptor* frame_state_descriptor = | |
| 1180 descriptor->NeedsFrameState() | |
| 1181 ? GetFrameStateDescriptor( | |
| 1182 node->InputAt(static_cast<int>(descriptor->InputCount()))) | |
| 1183 : nullptr; | |
| 1184 | |
| 1185 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | |
| 1186 | |
| 1187 // Compute InstructionOperands for inputs and outputs. | |
| 1188 // TODO(turbofan): on ARM it's probably better to use the code object in a | |
| 1189 // register if there are multiple uses of it. Improve constant pool and the | |
| 1190 // heuristics in the register allocator for where to emit constants. | |
| 1191 InitializeCallBuffer(node, &buffer, true, false); | |
| 1192 | |
| 1193 // Push any stack arguments. | |
| 1194 for (Node* input : base::Reversed(buffer.pushed_nodes)) { | |
| 1195 Emit(kArmPush, g.NoOutput(), g.UseRegister(input)); | |
| 1196 } | |
| 1197 | |
| 1198 // Select the appropriate opcode based on the call type. | |
| 1199 InstructionCode opcode; | |
| 1200 switch (descriptor->kind()) { | |
| 1201 case CallDescriptor::kCallCodeObject: { | |
| 1202 opcode = kArchCallCodeObject; | |
| 1203 break; | |
| 1204 } | |
| 1205 case CallDescriptor::kCallJSFunction: | |
| 1206 opcode = kArchCallJSFunction; | |
| 1207 break; | |
| 1208 default: | |
| 1209 UNREACHABLE(); | |
| 1210 return; | |
| 1211 } | |
| 1212 opcode |= MiscField::encode(descriptor->flags()); | |
| 1213 | |
| 1214 // Emit the call instruction. | |
| 1215 size_t const output_count = buffer.outputs.size(); | |
| 1216 auto* outputs = output_count ? &buffer.outputs.front() : nullptr; | |
| 1217 Emit(opcode, output_count, outputs, buffer.instruction_args.size(), | |
| 1218 &buffer.instruction_args.front())->MarkAsCall(); | |
| 1219 Emit(kArchRet, 0, nullptr, output_count, outputs); | |
| 1220 } | |
| 1221 } | |
| 1222 | 1144 |
| 1223 | 1145 |
| 1224 namespace { | 1146 namespace { |
| 1225 | 1147 |
| 1226 // Shared routine for multiple compare operations. | 1148 // Shared routine for multiple compare operations. |
| 1227 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1149 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1228 InstructionOperand left, InstructionOperand right, | 1150 InstructionOperand left, InstructionOperand right, |
| 1229 FlagsContinuation* cont) { | 1151 FlagsContinuation* cont) { |
| 1230 ArmOperandGenerator g(selector); | 1152 ArmOperandGenerator g(selector); |
| 1231 opcode = cont->Encode(opcode); | 1153 opcode = cont->Encode(opcode); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1616 flags |= MachineOperatorBuilder::kFloat64RoundDown | | 1538 flags |= MachineOperatorBuilder::kFloat64RoundDown | |
| 1617 MachineOperatorBuilder::kFloat64RoundTruncate | | 1539 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1618 MachineOperatorBuilder::kFloat64RoundTiesAway; | 1540 MachineOperatorBuilder::kFloat64RoundTiesAway; |
| 1619 } | 1541 } |
| 1620 return flags; | 1542 return flags; |
| 1621 } | 1543 } |
| 1622 | 1544 |
| 1623 } // namespace compiler | 1545 } // namespace compiler |
| 1624 } // namespace internal | 1546 } // namespace internal |
| 1625 } // namespace v8 | 1547 } // namespace v8 |
| OLD | NEW |