Index: src/compiler/arm64/instruction-selector-arm64.cc |
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc |
index 5bb40cee4464c4b40d3bbe7cefcee3a1d641a353..7bac111f7d1341d9efad84d620e5c4401e2742eb 100644 |
--- a/src/compiler/arm64/instruction-selector-arm64.cc |
+++ b/src/compiler/arm64/instruction-selector-arm64.cc |
@@ -1416,26 +1416,13 @@ void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
} |
-void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
+void InstructionSelector::EmitPrepareArguments(NodeVector* arguments, |
+ const CallDescriptor* descriptor, |
+ Node* node) { |
Arm64OperandGenerator g(this); |
- const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
- |
- FrameStateDescriptor* frame_state_descriptor = nullptr; |
- if (descriptor->NeedsFrameState()) { |
- frame_state_descriptor = GetFrameStateDescriptor( |
- node->InputAt(static_cast<int>(descriptor->InputCount()))); |
- } |
- |
- CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
- |
- // Compute InstructionOperands for inputs and outputs. |
- // TODO(turbofan): on ARM64 it's probably better to use the code object in a |
- // register if there are multiple uses of it. Improve constant pool and the |
- // heuristics in the register allocator for where to emit constants. |
- InitializeCallBuffer(node, &buffer, true, true); |
// Push the arguments to the stack. |
- int aligned_push_count = static_cast<int>(buffer.pushed_nodes.size()); |
+ int aligned_push_count = static_cast<int>(arguments->size()); |
bool pushed_count_uneven = aligned_push_count & 1; |
// TODO(dcarney): claim and poke probably take small immediates, |
// loop here or whatever. |
@@ -1450,56 +1437,17 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
int slot = aligned_push_count - 1; |
// Emit the uneven pushes. |
if (pushed_count_uneven) { |
- Node* input = buffer.pushed_nodes[slot]; |
+ Node* input = (*arguments)[slot]; |
Emit(kArm64Poke, g.NoOutput(), g.UseRegister(input), |
g.TempImmediate(slot)); |
slot--; |
} |
// Now all pushes can be done in pairs. |
for (; slot >= 0; slot -= 2) { |
- Emit(kArm64PokePair, g.NoOutput(), |
- g.UseRegister(buffer.pushed_nodes[slot]), |
- g.UseRegister(buffer.pushed_nodes[slot - 1]), |
- g.TempImmediate(slot)); |
- } |
- } |
- |
- // Pass label of exception handler block. |
- CallDescriptor::Flags flags = descriptor->flags(); |
- if (handler != nullptr) { |
- DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode()); |
- IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front()); |
- if (hint == IfExceptionHint::kLocallyCaught) { |
- flags |= CallDescriptor::kHasLocalCatchHandler; |
+ Emit(kArm64PokePair, g.NoOutput(), g.UseRegister((*arguments)[slot]), |
+ g.UseRegister((*arguments)[slot - 1]), g.TempImmediate(slot)); |
} |
- flags |= CallDescriptor::kHasExceptionHandler; |
- buffer.instruction_args.push_back(g.Label(handler)); |
- } |
- |
- // Select the appropriate opcode based on the call type. |
- InstructionCode opcode = kArchNop; |
- switch (descriptor->kind()) { |
- case CallDescriptor::kCallAddress: |
- opcode = |
- kArchCallCFunction | |
- MiscField::encode(static_cast<int>(descriptor->CParameterCount())); |
- break; |
- case CallDescriptor::kCallCodeObject: |
- opcode = kArchCallCodeObject | MiscField::encode(flags); |
- break; |
- case CallDescriptor::kCallJSFunction: |
- opcode = kArchCallJSFunction | MiscField::encode(flags); |
- break; |
- case CallDescriptor::kLazyBailout: |
- opcode = kArchLazyBailout | MiscField::encode(flags); |
- break; |
} |
- |
- // Emit the call instruction. |
- size_t const output_count = buffer.outputs.size(); |
- auto* outputs = output_count ? &buffer.outputs.front() : nullptr; |
- Emit(opcode, output_count, outputs, buffer.instruction_args.size(), |
- &buffer.instruction_args.front())->MarkAsCall(); |
} |