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/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 329 __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
330 __ Call(ip); | 330 __ Call(ip); |
331 AddSafepointAndDeopt(instr); | 331 AddSafepointAndDeopt(instr); |
332 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 332 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
333 break; | 333 break; |
334 } | 334 } |
335 case kArchJmp: | 335 case kArchJmp: |
336 AssembleArchJump(i.InputRpo(0)); | 336 AssembleArchJump(i.InputRpo(0)); |
337 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 337 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
338 break; | 338 break; |
339 case kArchSwitch: | 339 case kArchLookupSwitch: |
340 AssembleArchSwitch(instr); | 340 AssembleArchLookupSwitch(instr); |
| 341 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
| 342 break; |
| 343 case kArchTableSwitch: |
| 344 AssembleArchTableSwitch(instr); |
341 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 345 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
342 break; | 346 break; |
343 case kArchNop: | 347 case kArchNop: |
344 // don't emit code for nops. | 348 // don't emit code for nops. |
345 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 349 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
346 break; | 350 break; |
347 case kArchRet: | 351 case kArchRet: |
348 AssembleReturn(); | 352 AssembleReturn(); |
349 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 353 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
350 break; | 354 break; |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 __ b(cc, tlabel); | 738 __ b(cc, tlabel); |
735 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. | 739 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. |
736 } | 740 } |
737 | 741 |
738 | 742 |
739 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 743 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { |
740 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); | 744 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); |
741 } | 745 } |
742 | 746 |
743 | 747 |
744 void CodeGenerator::AssembleArchSwitch(Instruction* instr) { | |
745 ArmOperandConverter i(this, instr); | |
746 int const kNumLabels = static_cast<int>(instr->InputCount() - 1); | |
747 __ BlockConstPoolFor(kNumLabels + 2); | |
748 __ ldr(pc, MemOperand(pc, i.InputRegister(0), LSL, 2)); | |
749 __ nop(); | |
750 for (int index = 0; index < kNumLabels; ++index) { | |
751 __ dd(GetLabel(i.InputRpo(index + 1))); | |
752 } | |
753 } | |
754 | |
755 | |
756 // Assembles boolean materializations after an instruction. | 748 // Assembles boolean materializations after an instruction. |
757 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 749 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
758 FlagsCondition condition) { | 750 FlagsCondition condition) { |
759 ArmOperandConverter i(this, instr); | 751 ArmOperandConverter i(this, instr); |
760 | 752 |
761 // Materialize a full 32-bit 1 or 0 value. The result register is always the | 753 // Materialize a full 32-bit 1 or 0 value. The result register is always the |
762 // last output of the instruction. | 754 // last output of the instruction. |
763 DCHECK_NE(0u, instr->OutputCount()); | 755 DCHECK_NE(0u, instr->OutputCount()); |
764 Register reg = i.OutputRegister(instr->OutputCount() - 1); | 756 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
765 Condition cc = FlagsConditionToCondition(condition); | 757 Condition cc = FlagsConditionToCondition(condition); |
766 __ mov(reg, Operand(0)); | 758 __ mov(reg, Operand(0)); |
767 __ mov(reg, Operand(1), LeaveCC, cc); | 759 __ mov(reg, Operand(1), LeaveCC, cc); |
768 } | 760 } |
769 | 761 |
770 | 762 |
| 763 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { |
| 764 ArmOperandConverter i(this, instr); |
| 765 Register input = i.InputRegister(0); |
| 766 for (size_t index = 2; index < instr->InputCount(); index += 2) { |
| 767 __ cmp(input, Operand(i.InputInt32(index + 0))); |
| 768 __ b(eq, GetLabel(i.InputRpo(index + 1))); |
| 769 } |
| 770 AssembleArchJump(i.InputRpo(1)); |
| 771 } |
| 772 |
| 773 |
| 774 void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { |
| 775 ArmOperandConverter i(this, instr); |
| 776 Register input = i.InputRegister(0); |
| 777 size_t const case_count = instr->InputCount() - 2; |
| 778 __ cmp(input, Operand(case_count)); |
| 779 __ BlockConstPoolFor(case_count + 2); |
| 780 __ ldr(pc, MemOperand(pc, input, LSL, 2), lo); |
| 781 __ b(GetLabel(i.InputRpo(1))); |
| 782 for (size_t index = 0; index < case_count; ++index) { |
| 783 __ dd(GetLabel(i.InputRpo(index + 2))); |
| 784 } |
| 785 } |
| 786 |
| 787 |
771 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 788 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
772 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 789 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
773 isolate(), deoptimization_id, Deoptimizer::LAZY); | 790 isolate(), deoptimization_id, Deoptimizer::LAZY); |
774 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 791 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
775 } | 792 } |
776 | 793 |
777 | 794 |
778 void CodeGenerator::AssemblePrologue() { | 795 void CodeGenerator::AssemblePrologue() { |
779 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 796 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
780 int stack_slots = frame()->GetSpillSlotCount(); | 797 int stack_slots = frame()->GetSpillSlotCount(); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 } | 1073 } |
1057 } | 1074 } |
1058 MarkLazyDeoptSite(); | 1075 MarkLazyDeoptSite(); |
1059 } | 1076 } |
1060 | 1077 |
1061 #undef __ | 1078 #undef __ |
1062 | 1079 |
1063 } // namespace compiler | 1080 } // namespace compiler |
1064 } // namespace internal | 1081 } // namespace internal |
1065 } // namespace v8 | 1082 } // namespace v8 |
OLD | NEW |