OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/scopes.h" | 10 #include "src/scopes.h" |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | 525 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); |
526 __ Assert(equal, kWrongFunctionContext); | 526 __ Assert(equal, kWrongFunctionContext); |
527 } | 527 } |
528 __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 528 __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
529 AddSafepointAndDeopt(instr); | 529 AddSafepointAndDeopt(instr); |
530 break; | 530 break; |
531 } | 531 } |
532 case kArchJmp: | 532 case kArchJmp: |
533 AssembleArchJump(i.InputRpo(0)); | 533 AssembleArchJump(i.InputRpo(0)); |
534 break; | 534 break; |
535 case kArchSwitch: | 535 case kArchLookupSwitch: |
536 AssembleArchSwitch(instr); | 536 AssembleArchLookupSwitch(instr); |
| 537 break; |
| 538 case kArchTableSwitch: |
| 539 AssembleArchTableSwitch(instr); |
537 break; | 540 break; |
538 case kArchNop: | 541 case kArchNop: |
539 // don't emit code for nops. | 542 // don't emit code for nops. |
540 break; | 543 break; |
541 case kArchRet: | 544 case kArchRet: |
542 AssembleReturn(); | 545 AssembleReturn(); |
543 break; | 546 break; |
544 case kArchStackPointer: | 547 case kArchStackPointer: |
545 __ movq(i.OutputRegister(), rsp); | 548 __ movq(i.OutputRegister(), rsp); |
546 break; | 549 break; |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 } | 1066 } |
1064 if (!branch->fallthru) __ jmp(flabel, flabel_distance); | 1067 if (!branch->fallthru) __ jmp(flabel, flabel_distance); |
1065 } | 1068 } |
1066 | 1069 |
1067 | 1070 |
1068 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 1071 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { |
1069 if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target)); | 1072 if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target)); |
1070 } | 1073 } |
1071 | 1074 |
1072 | 1075 |
1073 void CodeGenerator::AssembleArchSwitch(Instruction* instr) { | |
1074 X64OperandConverter i(this, instr); | |
1075 size_t const label_count = instr->InputCount() - 1; | |
1076 Label** labels = zone()->NewArray<Label*>(label_count); | |
1077 for (size_t index = 0; index < label_count; ++index) { | |
1078 labels[index] = GetLabel(i.InputRpo(static_cast<int>(index + 1))); | |
1079 } | |
1080 Label* const table = AddJumpTable(labels, label_count); | |
1081 __ leaq(kScratchRegister, Operand(table)); | |
1082 __ jmp(Operand(kScratchRegister, i.InputRegister(0), times_8, 0)); | |
1083 } | |
1084 | |
1085 | |
1086 // Assembles boolean materializations after this instruction. | 1076 // Assembles boolean materializations after this instruction. |
1087 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 1077 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
1088 FlagsCondition condition) { | 1078 FlagsCondition condition) { |
1089 X64OperandConverter i(this, instr); | 1079 X64OperandConverter i(this, instr); |
1090 Label done; | 1080 Label done; |
1091 | 1081 |
1092 // Materialize a full 64-bit 1 or 0 value. The result register is always the | 1082 // Materialize a full 64-bit 1 or 0 value. The result register is always the |
1093 // last output of the instruction. | 1083 // last output of the instruction. |
1094 Label check; | 1084 Label check; |
1095 DCHECK_NE(0, static_cast<int>(instr->OutputCount())); | 1085 DCHECK_NE(0, static_cast<int>(instr->OutputCount())); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 cc = no_overflow; | 1133 cc = no_overflow; |
1144 break; | 1134 break; |
1145 } | 1135 } |
1146 __ bind(&check); | 1136 __ bind(&check); |
1147 __ setcc(cc, reg); | 1137 __ setcc(cc, reg); |
1148 __ movzxbl(reg, reg); | 1138 __ movzxbl(reg, reg); |
1149 __ bind(&done); | 1139 __ bind(&done); |
1150 } | 1140 } |
1151 | 1141 |
1152 | 1142 |
| 1143 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { |
| 1144 X64OperandConverter i(this, instr); |
| 1145 Register input = i.InputRegister(0); |
| 1146 for (size_t index = 2; index < instr->InputCount(); index += 2) { |
| 1147 __ cmpl(input, Immediate(i.InputInt32(static_cast<int>(index + 0)))); |
| 1148 __ j(equal, GetLabel(i.InputRpo(static_cast<int>(index + 1)))); |
| 1149 } |
| 1150 AssembleArchJump(i.InputRpo(1)); |
| 1151 } |
| 1152 |
| 1153 |
| 1154 void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { |
| 1155 X64OperandConverter i(this, instr); |
| 1156 Register input = i.InputRegister(0); |
| 1157 int32_t const case_count = static_cast<int32_t>(instr->InputCount() - 2); |
| 1158 Label** cases = zone()->NewArray<Label*>(case_count); |
| 1159 for (int32_t index = 0; index < case_count; ++index) { |
| 1160 cases[index] = GetLabel(i.InputRpo(index + 2)); |
| 1161 } |
| 1162 Label* const table = AddJumpTable(cases, case_count); |
| 1163 __ cmpl(input, Immediate(case_count)); |
| 1164 __ j(above_equal, GetLabel(i.InputRpo(1))); |
| 1165 __ leaq(kScratchRegister, Operand(table)); |
| 1166 __ jmp(Operand(kScratchRegister, input, times_8, 0)); |
| 1167 } |
| 1168 |
| 1169 |
1153 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 1170 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
1154 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1171 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
1155 isolate(), deoptimization_id, Deoptimizer::LAZY); | 1172 isolate(), deoptimization_id, Deoptimizer::LAZY); |
1156 __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1173 __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
1157 } | 1174 } |
1158 | 1175 |
1159 | 1176 |
1160 void CodeGenerator::AssemblePrologue() { | 1177 void CodeGenerator::AssemblePrologue() { |
1161 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1178 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1162 int stack_slots = frame()->GetSpillSlotCount(); | 1179 int stack_slots = frame()->GetSpillSlotCount(); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 } | 1437 } |
1421 } | 1438 } |
1422 MarkLazyDeoptSite(); | 1439 MarkLazyDeoptSite(); |
1423 } | 1440 } |
1424 | 1441 |
1425 #undef __ | 1442 #undef __ |
1426 | 1443 |
1427 } // namespace internal | 1444 } // namespace internal |
1428 } // namespace compiler | 1445 } // namespace compiler |
1429 } // namespace v8 | 1446 } // namespace v8 |
OLD | NEW |