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/arm64/macro-assembler-arm64.h" | 7 #include "src/arm64/macro-assembler-arm64.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 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 __ Assert(eq, kWrongFunctionContext); | 350 __ Assert(eq, kWrongFunctionContext); |
351 } | 351 } |
352 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 352 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
353 __ Call(x10); | 353 __ Call(x10); |
354 AddSafepointAndDeopt(instr); | 354 AddSafepointAndDeopt(instr); |
355 break; | 355 break; |
356 } | 356 } |
357 case kArchJmp: | 357 case kArchJmp: |
358 AssembleArchJump(i.InputRpo(0)); | 358 AssembleArchJump(i.InputRpo(0)); |
359 break; | 359 break; |
360 case kArchSwitch: | 360 case kArchTableSwitch: |
361 AssembleArchSwitch(instr); | 361 AssembleArchTableSwitch(instr); |
| 362 break; |
| 363 case kArchLookupSwitch: |
| 364 AssembleArchLookupSwitch(instr); |
362 break; | 365 break; |
363 case kArchNop: | 366 case kArchNop: |
364 // don't emit code for nops. | 367 // don't emit code for nops. |
365 break; | 368 break; |
366 case kArchRet: | 369 case kArchRet: |
367 AssembleReturn(); | 370 AssembleReturn(); |
368 break; | 371 break; |
369 case kArchStackPointer: | 372 case kArchStackPointer: |
370 __ mov(i.OutputRegister(), masm()->StackPointer()); | 373 __ mov(i.OutputRegister(), masm()->StackPointer()); |
371 break; | 374 break; |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 } | 837 } |
835 if (!branch->fallthru) __ B(flabel); // no fallthru to flabel. | 838 if (!branch->fallthru) __ B(flabel); // no fallthru to flabel. |
836 } | 839 } |
837 | 840 |
838 | 841 |
839 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 842 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { |
840 if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target)); | 843 if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target)); |
841 } | 844 } |
842 | 845 |
843 | 846 |
844 void CodeGenerator::AssembleArchSwitch(Instruction* instr) { | |
845 Arm64OperandConverter i(this, instr); | |
846 UseScratchRegisterScope scope(masm()); | |
847 Register reg = i.InputRegister(0); | |
848 Register tmp = scope.AcquireX(); | |
849 Label table; | |
850 __ Adr(tmp, &table); | |
851 __ Add(tmp, tmp, Operand(reg, LSL, 2)); | |
852 __ Br(tmp); | |
853 __ Bind(&table); | |
854 for (size_t index = 1; index < instr->InputCount(); ++index) { | |
855 __ B(GetLabel(i.InputRpo(index))); | |
856 } | |
857 } | |
858 | |
859 | |
860 // Assemble boolean materializations after this instruction. | 847 // Assemble boolean materializations after this instruction. |
861 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 848 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
862 FlagsCondition condition) { | 849 FlagsCondition condition) { |
863 Arm64OperandConverter i(this, instr); | 850 Arm64OperandConverter i(this, instr); |
864 | 851 |
865 // Materialize a full 64-bit 1 or 0 value. The result register is always the | 852 // Materialize a full 64-bit 1 or 0 value. The result register is always the |
866 // last output of the instruction. | 853 // last output of the instruction. |
867 DCHECK_NE(0u, instr->OutputCount()); | 854 DCHECK_NE(0u, instr->OutputCount()); |
868 Register reg = i.OutputRegister(instr->OutputCount() - 1); | 855 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
869 Condition cc = FlagsConditionToCondition(condition); | 856 Condition cc = FlagsConditionToCondition(condition); |
870 __ Cset(reg, cc); | 857 __ Cset(reg, cc); |
871 } | 858 } |
872 | 859 |
873 | 860 |
| 861 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { |
| 862 Arm64OperandConverter i(this, instr); |
| 863 Register input = i.InputRegister32(0); |
| 864 for (size_t index = 2; index < instr->InputCount(); index += 2) { |
| 865 __ Cmp(input, i.InputInt32(index + 0)); |
| 866 __ B(eq, GetLabel(i.InputRpo(index + 1))); |
| 867 } |
| 868 AssembleArchJump(i.InputRpo(1)); |
| 869 } |
| 870 |
| 871 |
| 872 void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { |
| 873 Arm64OperandConverter i(this, instr); |
| 874 UseScratchRegisterScope scope(masm()); |
| 875 Register input = i.InputRegister32(0); |
| 876 Register temp = scope.AcquireX(); |
| 877 size_t const case_count = instr->InputCount() - 2; |
| 878 Label table; |
| 879 __ Cmp(input, case_count); |
| 880 __ B(hs, GetLabel(i.InputRpo(1))); |
| 881 __ Adr(temp, &table); |
| 882 __ Add(temp, temp, Operand(input, UXTW, 2)); |
| 883 __ Br(temp); |
| 884 __ StartBlockPools(); |
| 885 __ Bind(&table); |
| 886 for (size_t index = 0; index < case_count; ++index) { |
| 887 __ B(GetLabel(i.InputRpo(index + 2))); |
| 888 } |
| 889 __ EndBlockPools(); |
| 890 } |
| 891 |
| 892 |
874 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 893 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
875 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 894 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
876 isolate(), deoptimization_id, Deoptimizer::LAZY); | 895 isolate(), deoptimization_id, Deoptimizer::LAZY); |
877 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 896 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
878 } | 897 } |
879 | 898 |
880 | 899 |
881 // TODO(dcarney): increase stack slots in frame once before first use. | 900 // TODO(dcarney): increase stack slots in frame once before first use. |
882 static int AlignedStackSlots(int stack_slots) { | 901 static int AlignedStackSlots(int stack_slots) { |
883 if (stack_slots & 1) stack_slots++; | 902 if (stack_slots & 1) stack_slots++; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 } | 1153 } |
1135 } | 1154 } |
1136 MarkLazyDeoptSite(); | 1155 MarkLazyDeoptSite(); |
1137 } | 1156 } |
1138 | 1157 |
1139 #undef __ | 1158 #undef __ |
1140 | 1159 |
1141 } // namespace compiler | 1160 } // namespace compiler |
1142 } // namespace internal | 1161 } // namespace internal |
1143 } // namespace v8 | 1162 } // namespace v8 |
OLD | NEW |