| 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/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 namespace compiler { | 10 namespace compiler { |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 Node* right = node->InputAt(1); | 589 Node* right = node->InputAt(1); |
| 590 VisitCompare(this, kArm64Float64Cmp, g.UseDoubleRegister(left), | 590 VisitCompare(this, kArm64Float64Cmp, g.UseDoubleRegister(left), |
| 591 g.UseDoubleRegister(right), cont); | 591 g.UseDoubleRegister(right), cont); |
| 592 } | 592 } |
| 593 | 593 |
| 594 | 594 |
| 595 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 595 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, |
| 596 BasicBlock* deoptimization) { | 596 BasicBlock* deoptimization) { |
| 597 Arm64OperandGenerator g(this); | 597 Arm64OperandGenerator g(this); |
| 598 CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call); | 598 CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call); |
| 599 CallBuffer buffer(zone(), descriptor); // TODO(turbofan): temp zone here? | 599 |
| 600 FrameStateDescriptor* frame_state_descriptor = NULL; |
| 601 if (descriptor->NeedsFrameState()) { |
| 602 frame_state_descriptor = |
| 603 GetFrameStateDescriptor(call->InputAt(descriptor->InputCount())); |
| 604 } |
| 605 |
| 606 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
| 600 | 607 |
| 601 // Compute InstructionOperands for inputs and outputs. | 608 // Compute InstructionOperands for inputs and outputs. |
| 602 // TODO(turbofan): on ARM64 it's probably better to use the code object in a | 609 // TODO(turbofan): on ARM64 it's probably better to use the code object in a |
| 603 // register if there are multiple uses of it. Improve constant pool and the | 610 // register if there are multiple uses of it. Improve constant pool and the |
| 604 // heuristics in the register allocator for where to emit constants. | 611 // heuristics in the register allocator for where to emit constants. |
| 605 InitializeCallBuffer(call, &buffer, true, false, continuation, | 612 InitializeCallBuffer(call, &buffer, true, false, continuation, |
| 606 deoptimization); | 613 deoptimization); |
| 607 | 614 |
| 608 // Push the arguments to the stack. | 615 // Push the arguments to the stack. |
| 609 bool is_c_frame = descriptor->kind() == CallDescriptor::kCallAddress; | 616 bool is_c_frame = descriptor->kind() == CallDescriptor::kCallAddress; |
| 610 bool pushed_count_uneven = buffer.pushed_count & 1; | 617 bool pushed_count_uneven = buffer.pushed_nodes.size() & 1; |
| 611 int aligned_push_count = buffer.pushed_count; | 618 int aligned_push_count = buffer.pushed_nodes.size(); |
| 612 if (is_c_frame && pushed_count_uneven) { | 619 if (is_c_frame && pushed_count_uneven) { |
| 613 aligned_push_count++; | 620 aligned_push_count++; |
| 614 } | 621 } |
| 615 // TODO(dcarney): claim and poke probably take small immediates, | 622 // TODO(dcarney): claim and poke probably take small immediates, |
| 616 // loop here or whatever. | 623 // loop here or whatever. |
| 617 // Bump the stack pointer(s). | 624 // Bump the stack pointer(s). |
| 618 if (aligned_push_count > 0) { | 625 if (aligned_push_count > 0) { |
| 619 // TODO(dcarney): it would be better to bump the csp here only | 626 // TODO(dcarney): it would be better to bump the csp here only |
| 620 // and emit paired stores with increment for non c frames. | 627 // and emit paired stores with increment for non c frames. |
| 621 Emit(kArm64Claim | MiscField::encode(aligned_push_count), NULL); | 628 Emit(kArm64Claim | MiscField::encode(aligned_push_count), NULL); |
| 622 } | 629 } |
| 623 // Move arguments to the stack. | 630 // Move arguments to the stack. |
| 624 { | 631 { |
| 625 int slot = buffer.pushed_count - 1; | 632 int slot = buffer.pushed_nodes.size() - 1; |
| 626 // Emit the uneven pushes. | 633 // Emit the uneven pushes. |
| 627 if (pushed_count_uneven) { | 634 if (pushed_count_uneven) { |
| 628 Node* input = buffer.pushed_nodes[slot]; | 635 Node* input = buffer.pushed_nodes[slot]; |
| 629 ArchOpcode opcode = is_c_frame ? kArm64PokePairZero : kArm64Poke; | 636 ArchOpcode opcode = is_c_frame ? kArm64PokePairZero : kArm64Poke; |
| 630 Emit(opcode | MiscField::encode(slot), NULL, g.UseRegister(input)); | 637 Emit(opcode | MiscField::encode(slot), NULL, g.UseRegister(input)); |
| 631 slot--; | 638 slot--; |
| 632 } | 639 } |
| 633 // Now all pushes can be done in pairs. | 640 // Now all pushes can be done in pairs. |
| 634 for (; slot >= 0; slot -= 2) { | 641 for (; slot >= 0; slot -= 2) { |
| 635 Emit(kArm64PokePair | MiscField::encode(slot), NULL, | 642 Emit(kArm64PokePair | MiscField::encode(slot), NULL, |
| 636 g.UseRegister(buffer.pushed_nodes[slot]), | 643 g.UseRegister(buffer.pushed_nodes[slot]), |
| 637 g.UseRegister(buffer.pushed_nodes[slot - 1])); | 644 g.UseRegister(buffer.pushed_nodes[slot - 1])); |
| 638 } | 645 } |
| 639 } | 646 } |
| 640 | 647 |
| 641 // Select the appropriate opcode based on the call type. | 648 // Select the appropriate opcode based on the call type. |
| 642 InstructionCode opcode; | 649 InstructionCode opcode; |
| 643 switch (descriptor->kind()) { | 650 switch (descriptor->kind()) { |
| 644 case CallDescriptor::kCallCodeObject: { | 651 case CallDescriptor::kCallCodeObject: { |
| 645 bool lazy_deopt = descriptor->CanLazilyDeoptimize(); | 652 opcode = kArm64CallCodeObject; |
| 646 opcode = kArm64CallCodeObject | MiscField::encode(lazy_deopt ? 1 : 0); | |
| 647 break; | 653 break; |
| 648 } | 654 } |
| 649 case CallDescriptor::kCallAddress: | 655 case CallDescriptor::kCallAddress: |
| 650 opcode = kArm64CallAddress; | 656 opcode = kArm64CallAddress; |
| 651 break; | 657 break; |
| 652 case CallDescriptor::kCallJSFunction: | 658 case CallDescriptor::kCallJSFunction: |
| 653 opcode = kArm64CallJSFunction; | 659 opcode = kArm64CallJSFunction; |
| 654 break; | 660 break; |
| 655 default: | 661 default: |
| 656 UNREACHABLE(); | 662 UNREACHABLE(); |
| 657 return; | 663 return; |
| 658 } | 664 } |
| 665 opcode |= MiscField::encode(descriptor->deoptimization_support()); |
| 659 | 666 |
| 660 // Emit the call instruction. | 667 // Emit the call instruction. |
| 661 Instruction* call_instr = | 668 Instruction* call_instr = |
| 662 Emit(opcode, buffer.output_count, buffer.outputs, | 669 Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(), |
| 663 buffer.fixed_and_control_count(), buffer.fixed_and_control_args); | 670 buffer.instruction_args.size(), &buffer.instruction_args.front()); |
| 664 | 671 |
| 665 call_instr->MarkAsCall(); | 672 call_instr->MarkAsCall(); |
| 666 if (deoptimization != NULL) { | 673 if (deoptimization != NULL) { |
| 667 DCHECK(continuation != NULL); | 674 DCHECK(continuation != NULL); |
| 668 call_instr->MarkAsControl(); | 675 call_instr->MarkAsControl(); |
| 669 } | 676 } |
| 670 | 677 |
| 671 // Caller clean up of stack for C-style calls. | 678 // Caller clean up of stack for C-style calls. |
| 672 if (is_c_frame && aligned_push_count > 0) { | 679 if (is_c_frame && aligned_push_count > 0) { |
| 673 DCHECK(deoptimization == NULL && continuation == NULL); | 680 DCHECK(deoptimization == NULL && continuation == NULL); |
| 674 Emit(kArm64Drop | MiscField::encode(aligned_push_count), NULL); | 681 Emit(kArm64Drop | MiscField::encode(aligned_push_count), NULL); |
| 675 } | 682 } |
| 676 } | 683 } |
| 677 | 684 |
| 678 } // namespace compiler | 685 } // namespace compiler |
| 679 } // namespace internal | 686 } // namespace internal |
| 680 } // namespace v8 | 687 } // namespace v8 |
| OLD | NEW |