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/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 __ asm_instr(value, operand); \ | 599 __ asm_instr(value, operand); \ |
600 } else { \ | 600 } else { \ |
601 __ asm_instrx(value, operand); \ | 601 __ asm_instrx(value, operand); \ |
602 } \ | 602 } \ |
603 __ bind(&done); \ | 603 __ bind(&done); \ |
604 DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ | 604 DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ |
605 } while (0) | 605 } while (0) |
606 | 606 |
607 | 607 |
608 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 608 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
| 609 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 610 if (sp_slot_delta > 0) { |
| 611 __ Add(sp, sp, sp_slot_delta * kPointerSize, r0); |
| 612 } |
609 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 613 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
610 int stack_slots = frame()->GetSpillSlotCount(); | 614 int spill_slots = frame()->GetSpillSlotCount(); |
611 int sp_delta = | 615 bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; |
612 (stack_param_delta < 0) ? -stack_param_delta * kPointerSize : 0; | 616 if (has_frame) { |
613 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | 617 if (FLAG_enable_embedded_constant_pool) { |
614 __ LeaveFrame(StackFrame::MANUAL, sp_delta); | 618 __ Pop(r0, fp, kConstantPoolRegister); |
615 } else if (sp_delta) { | 619 } else { |
616 __ Add(sp, sp, sp_delta, r0); | 620 __ Pop(r0, fp); |
| 621 } |
| 622 __ mtlr(r0); |
617 } | 623 } |
618 } | 624 } |
619 | 625 |
| 626 |
| 627 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
| 628 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 629 if (sp_slot_delta < 0) { |
| 630 __ Add(sp, sp, sp_slot_delta * kPointerSize, r0); |
| 631 } |
| 632 } |
| 633 |
620 | 634 |
621 // Assembles an instruction after register allocation, producing machine code. | 635 // Assembles an instruction after register allocation, producing machine code. |
622 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 636 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
623 PPCOperandConverter i(this, instr); | 637 PPCOperandConverter i(this, instr); |
624 ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode()); | 638 ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode()); |
625 | 639 |
626 switch (opcode) { | 640 switch (opcode) { |
627 case kArchCallCodeObject: { | 641 case kArchCallCodeObject: { |
628 v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( | 642 v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( |
629 masm()); | 643 masm()); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 masm()); | 710 masm()); |
697 EnsureSpaceForLazyDeopt(); | 711 EnsureSpaceForLazyDeopt(); |
698 RecordCallPosition(instr); | 712 RecordCallPosition(instr); |
699 break; | 713 break; |
700 } | 714 } |
701 case kArchPrepareCallCFunction: { | 715 case kArchPrepareCallCFunction: { |
702 int const num_parameters = MiscField::decode(instr->opcode()); | 716 int const num_parameters = MiscField::decode(instr->opcode()); |
703 __ PrepareCallCFunction(num_parameters, kScratchReg); | 717 __ PrepareCallCFunction(num_parameters, kScratchReg); |
704 break; | 718 break; |
705 } | 719 } |
| 720 case kArchPrepareTailCall: |
| 721 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); |
| 722 break; |
706 case kArchCallCFunction: { | 723 case kArchCallCFunction: { |
707 int const num_parameters = MiscField::decode(instr->opcode()); | 724 int const num_parameters = MiscField::decode(instr->opcode()); |
708 if (instr->InputAt(0)->IsImmediate()) { | 725 if (instr->InputAt(0)->IsImmediate()) { |
709 ExternalReference ref = i.InputExternalReference(0); | 726 ExternalReference ref = i.InputExternalReference(0); |
710 __ CallCFunction(ref, num_parameters); | 727 __ CallCFunction(ref, num_parameters); |
711 } else { | 728 } else { |
712 Register func = i.InputRegister(0); | 729 Register func = i.InputRegister(0); |
713 __ CallCFunction(func, num_parameters); | 730 __ CallCFunction(func, num_parameters); |
714 } | 731 } |
715 break; | 732 break; |
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1735 padding_size -= v8::internal::Assembler::kInstrSize; | 1752 padding_size -= v8::internal::Assembler::kInstrSize; |
1736 } | 1753 } |
1737 } | 1754 } |
1738 } | 1755 } |
1739 | 1756 |
1740 #undef __ | 1757 #undef __ |
1741 | 1758 |
1742 } // namespace compiler | 1759 } // namespace compiler |
1743 } // namespace internal | 1760 } // namespace internal |
1744 } // namespace v8 | 1761 } // namespace v8 |
OLD | NEW |