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 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 | 617 |
618 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); | 618 CallBuffer buffer(zone(), descriptor, frame_state_descriptor); |
619 | 619 |
620 // Compute InstructionOperands for inputs and outputs. | 620 // Compute InstructionOperands for inputs and outputs. |
621 // TODO(turbofan): on ARM64 it's probably better to use the code object in a | 621 // TODO(turbofan): on ARM64 it's probably better to use the code object in a |
622 // register if there are multiple uses of it. Improve constant pool and the | 622 // register if there are multiple uses of it. Improve constant pool and the |
623 // heuristics in the register allocator for where to emit constants. | 623 // heuristics in the register allocator for where to emit constants. |
624 InitializeCallBuffer(call, &buffer, true, false); | 624 InitializeCallBuffer(call, &buffer, true, false); |
625 | 625 |
626 // Push the arguments to the stack. | 626 // Push the arguments to the stack. |
627 bool is_c_frame = descriptor->kind() == CallDescriptor::kCallAddress; | |
628 bool pushed_count_uneven = buffer.pushed_nodes.size() & 1; | 627 bool pushed_count_uneven = buffer.pushed_nodes.size() & 1; |
629 int aligned_push_count = buffer.pushed_nodes.size(); | 628 int aligned_push_count = buffer.pushed_nodes.size(); |
630 if (is_c_frame && pushed_count_uneven) { | |
631 aligned_push_count++; | |
632 } | |
633 // TODO(dcarney): claim and poke probably take small immediates, | 629 // TODO(dcarney): claim and poke probably take small immediates, |
634 // loop here or whatever. | 630 // loop here or whatever. |
635 // Bump the stack pointer(s). | 631 // Bump the stack pointer(s). |
636 if (aligned_push_count > 0) { | 632 if (aligned_push_count > 0) { |
637 // TODO(dcarney): it would be better to bump the csp here only | 633 // TODO(dcarney): it would be better to bump the csp here only |
638 // and emit paired stores with increment for non c frames. | 634 // and emit paired stores with increment for non c frames. |
639 Emit(kArm64Claim | MiscField::encode(aligned_push_count), NULL); | 635 Emit(kArm64Claim | MiscField::encode(aligned_push_count), NULL); |
640 } | 636 } |
641 // Move arguments to the stack. | 637 // Move arguments to the stack. |
642 { | 638 { |
643 int slot = buffer.pushed_nodes.size() - 1; | 639 int slot = buffer.pushed_nodes.size() - 1; |
644 // Emit the uneven pushes. | 640 // Emit the uneven pushes. |
645 if (pushed_count_uneven) { | 641 if (pushed_count_uneven) { |
646 Node* input = buffer.pushed_nodes[slot]; | 642 Node* input = buffer.pushed_nodes[slot]; |
647 ArchOpcode opcode = is_c_frame ? kArm64PokePairZero : kArm64Poke; | 643 Emit(kArm64Poke | MiscField::encode(slot), NULL, g.UseRegister(input)); |
648 Emit(opcode | MiscField::encode(slot), NULL, g.UseRegister(input)); | |
649 slot--; | 644 slot--; |
650 } | 645 } |
651 // Now all pushes can be done in pairs. | 646 // Now all pushes can be done in pairs. |
652 for (; slot >= 0; slot -= 2) { | 647 for (; slot >= 0; slot -= 2) { |
653 Emit(kArm64PokePair | MiscField::encode(slot), NULL, | 648 Emit(kArm64PokePair | MiscField::encode(slot), NULL, |
654 g.UseRegister(buffer.pushed_nodes[slot]), | 649 g.UseRegister(buffer.pushed_nodes[slot]), |
655 g.UseRegister(buffer.pushed_nodes[slot - 1])); | 650 g.UseRegister(buffer.pushed_nodes[slot - 1])); |
656 } | 651 } |
657 } | 652 } |
658 | 653 |
659 // Select the appropriate opcode based on the call type. | 654 // Select the appropriate opcode based on the call type. |
660 InstructionCode opcode; | 655 InstructionCode opcode; |
661 switch (descriptor->kind()) { | 656 switch (descriptor->kind()) { |
662 case CallDescriptor::kCallCodeObject: { | 657 case CallDescriptor::kCallCodeObject: { |
663 opcode = kArchCallCodeObject; | 658 opcode = kArchCallCodeObject; |
664 break; | 659 break; |
665 } | 660 } |
666 case CallDescriptor::kCallAddress: | |
667 opcode = kArchCallAddress; | |
668 break; | |
669 case CallDescriptor::kCallJSFunction: | 661 case CallDescriptor::kCallJSFunction: |
670 opcode = kArchCallJSFunction; | 662 opcode = kArchCallJSFunction; |
671 break; | 663 break; |
672 default: | 664 default: |
673 UNREACHABLE(); | 665 UNREACHABLE(); |
674 return; | 666 return; |
675 } | 667 } |
676 opcode |= MiscField::encode(descriptor->flags()); | 668 opcode |= MiscField::encode(descriptor->flags()); |
677 | 669 |
678 // Emit the call instruction. | 670 // Emit the call instruction. |
679 Instruction* call_instr = | 671 Instruction* call_instr = |
680 Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(), | 672 Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(), |
681 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 673 buffer.instruction_args.size(), &buffer.instruction_args.front()); |
682 | 674 |
683 call_instr->MarkAsCall(); | 675 call_instr->MarkAsCall(); |
684 if (deoptimization != NULL) { | 676 if (deoptimization != NULL) { |
685 DCHECK(continuation != NULL); | 677 DCHECK(continuation != NULL); |
686 call_instr->MarkAsControl(); | 678 call_instr->MarkAsControl(); |
687 } | 679 } |
688 | |
689 // Caller clean up of stack for C-style calls. | |
690 if (is_c_frame && aligned_push_count > 0) { | |
691 DCHECK(deoptimization == NULL && continuation == NULL); | |
692 Emit(kArchDrop | MiscField::encode(aligned_push_count), NULL); | |
693 } | |
694 } | 680 } |
695 | 681 |
696 } // namespace compiler | 682 } // namespace compiler |
697 } // namespace internal | 683 } // namespace internal |
698 } // namespace v8 | 684 } // namespace v8 |
OLD | NEW |