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 |