| 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/ppc/macro-assembler-ppc.h" | 11 #include "src/ppc/macro-assembler-ppc.h" |
| 11 #include "src/scopes.h" | 12 #include "src/scopes.h" |
| 12 | 13 |
| 13 namespace v8 { | 14 namespace v8 { |
| 14 namespace internal { | 15 namespace internal { |
| 15 namespace compiler { | 16 namespace compiler { |
| 16 | 17 |
| 17 #define __ masm()-> | 18 #define __ masm()-> |
| 18 | 19 |
| 19 | 20 |
| (...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 case kPPC_Push: | 975 case kPPC_Push: |
| 975 if (instr->InputAt(0)->IsDoubleRegister()) { | 976 if (instr->InputAt(0)->IsDoubleRegister()) { |
| 976 __ stfdu(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize)); | 977 __ stfdu(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize)); |
| 977 } else { | 978 } else { |
| 978 __ Push(i.InputRegister(0)); | 979 __ Push(i.InputRegister(0)); |
| 979 } | 980 } |
| 980 DCHECK_EQ(LeaveRC, i.OutputRCBit()); | 981 DCHECK_EQ(LeaveRC, i.OutputRCBit()); |
| 981 break; | 982 break; |
| 982 case kPPC_PushFrame: { | 983 case kPPC_PushFrame: { |
| 983 int num_slots = i.InputInt32(1); | 984 int num_slots = i.InputInt32(1); |
| 984 __ StorePU(i.InputRegister(0), MemOperand(sp, -num_slots * kPointerSize)); | 985 if (instr->InputAt(0)->IsDoubleRegister()) { |
| 986 __ stfdu(i.InputDoubleRegister(0), |
| 987 MemOperand(sp, -num_slots * kPointerSize)); |
| 988 } else { |
| 989 __ StorePU(i.InputRegister(0), |
| 990 MemOperand(sp, -num_slots * kPointerSize)); |
| 991 } |
| 985 break; | 992 break; |
| 986 } | 993 } |
| 987 case kPPC_StoreToStackSlot: { | 994 case kPPC_StoreToStackSlot: { |
| 988 int slot = i.InputInt32(1); | 995 int slot = i.InputInt32(1); |
| 989 if (instr->InputAt(0)->IsDoubleRegister()) { | 996 if (instr->InputAt(0)->IsDoubleRegister()) { |
| 990 __ stfd(i.InputDoubleRegister(0), MemOperand(sp, slot * kPointerSize)); | 997 __ stfd(i.InputDoubleRegister(0), MemOperand(sp, slot * kPointerSize)); |
| 991 } else { | 998 } else { |
| 992 __ StoreP(i.InputRegister(0), MemOperand(sp, slot * kPointerSize)); | 999 __ StoreP(i.InputRegister(0), MemOperand(sp, slot * kPointerSize)); |
| 993 } | 1000 } |
| 994 break; | 1001 break; |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 void CodeGenerator::AssembleDeoptimizerCall( | 1298 void CodeGenerator::AssembleDeoptimizerCall( |
| 1292 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1299 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
| 1293 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1300 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
| 1294 isolate(), deoptimization_id, bailout_type); | 1301 isolate(), deoptimization_id, bailout_type); |
| 1295 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1302 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
| 1296 } | 1303 } |
| 1297 | 1304 |
| 1298 | 1305 |
| 1299 void CodeGenerator::AssemblePrologue() { | 1306 void CodeGenerator::AssemblePrologue() { |
| 1300 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1307 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1301 int stack_slots = frame()->GetSpillSlotCount(); | 1308 |
| 1302 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 1309 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
| 1303 __ function_descriptor(); | 1310 __ function_descriptor(); |
| 1304 RegList frame_saves = 0; | |
| 1305 __ mflr(r0); | 1311 __ mflr(r0); |
| 1306 if (FLAG_enable_embedded_constant_pool) { | 1312 if (FLAG_enable_embedded_constant_pool) { |
| 1307 __ Push(r0, fp, kConstantPoolRegister); | 1313 __ Push(r0, fp, kConstantPoolRegister); |
| 1308 // Adjust FP to point to saved FP. | 1314 // Adjust FP to point to saved FP. |
| 1309 __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); | 1315 __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); |
| 1310 frame_saves |= kConstantPoolRegister.bit(); | |
| 1311 } else { | 1316 } else { |
| 1312 __ Push(r0, fp); | 1317 __ Push(r0, fp); |
| 1313 __ mr(fp, sp); | 1318 __ mr(fp, sp); |
| 1314 } | 1319 } |
| 1315 | |
| 1316 // Save callee-saved registers. | |
| 1317 const RegList saves = descriptor->CalleeSavedRegisters() & ~frame_saves; | |
| 1318 __ MultiPush(saves); | |
| 1319 // register save area does not include the fp. | |
| 1320 DCHECK(kNumCalleeSaved - 1 == | |
| 1321 base::bits::CountPopulation32(saves | frame_saves)); | |
| 1322 int register_save_area_size = (kNumCalleeSaved - 1) * kPointerSize; | |
| 1323 | |
| 1324 // Save callee-saved Double registers. | |
| 1325 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); | |
| 1326 __ MultiPushDoubles(double_saves); | |
| 1327 DCHECK(kNumCalleeSavedDoubles == | |
| 1328 base::bits::CountPopulation32(double_saves)); | |
| 1329 register_save_area_size += kNumCalleeSavedDoubles * kDoubleSize; | |
| 1330 | |
| 1331 frame()->SetRegisterSaveAreaSize(register_save_area_size); | |
| 1332 } else if (descriptor->IsJSFunctionCall()) { | 1320 } else if (descriptor->IsJSFunctionCall()) { |
| 1333 CompilationInfo* info = this->info(); | 1321 CompilationInfo* info = this->info(); |
| 1334 __ Prologue(info->IsCodePreAgingActive()); | 1322 __ Prologue(info->IsCodePreAgingActive()); |
| 1335 frame()->SetRegisterSaveAreaSize( | |
| 1336 StandardFrameConstants::kFixedFrameSizeFromFp); | |
| 1337 } else if (needs_frame_) { | 1323 } else if (needs_frame_) { |
| 1338 __ StubPrologue(); | 1324 __ StubPrologue(); |
| 1339 frame()->SetRegisterSaveAreaSize( | 1325 } else { |
| 1340 StandardFrameConstants::kFixedFrameSizeFromFp); | 1326 frame()->SetElidedFrameSizeInSlots(0); |
| 1341 } | 1327 } |
| 1342 | 1328 |
| 1329 int stack_shrink_slots = frame()->GetSpillSlotCount(); |
| 1343 if (info()->is_osr()) { | 1330 if (info()->is_osr()) { |
| 1344 // TurboFan OSR-compiled functions cannot be entered directly. | 1331 // TurboFan OSR-compiled functions cannot be entered directly. |
| 1345 __ Abort(kShouldNotDirectlyEnterOsrFunction); | 1332 __ Abort(kShouldNotDirectlyEnterOsrFunction); |
| 1346 | 1333 |
| 1347 // Unoptimized code jumps directly to this entrypoint while the unoptimized | 1334 // Unoptimized code jumps directly to this entrypoint while the unoptimized |
| 1348 // frame is still on the stack. Optimized code uses OSR values directly from | 1335 // frame is still on the stack. Optimized code uses OSR values directly from |
| 1349 // the unoptimized frame. Thus, all that needs to be done is to allocate the | 1336 // the unoptimized frame. Thus, all that needs to be done is to allocate the |
| 1350 // remaining stack slots. | 1337 // remaining stack slots. |
| 1351 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); | 1338 if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); |
| 1352 osr_pc_offset_ = __ pc_offset(); | 1339 osr_pc_offset_ = __ pc_offset(); |
| 1353 // TODO(titzer): cannot address target function == local #-1 | 1340 // TODO(titzer): cannot address target function == local #-1 |
| 1354 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1341 __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1355 DCHECK(stack_slots >= frame()->GetOsrStackSlotCount()); | 1342 stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); |
| 1356 stack_slots -= frame()->GetOsrStackSlotCount(); | |
| 1357 } | 1343 } |
| 1358 | 1344 |
| 1359 if (stack_slots > 0) { | 1345 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
| 1360 __ Add(sp, sp, -stack_slots * kPointerSize, r0); | 1346 if (double_saves != 0) { |
| 1347 stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots(); |
| 1348 } |
| 1349 if (stack_shrink_slots > 0) { |
| 1350 __ Add(sp, sp, -stack_shrink_slots * kPointerSize, r0); |
| 1351 } |
| 1352 |
| 1353 // Save callee-saved Double registers. |
| 1354 if (double_saves != 0) { |
| 1355 __ MultiPushDoubles(double_saves); |
| 1356 DCHECK(kNumCalleeSavedDoubles == |
| 1357 base::bits::CountPopulation32(double_saves)); |
| 1358 frame()->AllocateSavedCalleeRegisterSlots(kNumCalleeSavedDoubles * |
| 1359 (kDoubleSize / kPointerSize)); |
| 1360 } |
| 1361 |
| 1362 // Save callee-saved registers. |
| 1363 const RegList saves = |
| 1364 FLAG_enable_embedded_constant_pool |
| 1365 ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() |
| 1366 : descriptor->CalleeSavedRegisters(); |
| 1367 if (saves != 0) { |
| 1368 __ MultiPush(saves); |
| 1369 // register save area does not include the fp or constant pool pointer. |
| 1370 const int num_saves = |
| 1371 kNumCalleeSaved - 1 - (FLAG_enable_embedded_constant_pool ? 1 : 0); |
| 1372 DCHECK(num_saves == base::bits::CountPopulation32(saves)); |
| 1373 frame()->AllocateSavedCalleeRegisterSlots(num_saves); |
| 1361 } | 1374 } |
| 1362 } | 1375 } |
| 1363 | 1376 |
| 1364 | 1377 |
| 1365 void CodeGenerator::AssembleReturn() { | 1378 void CodeGenerator::AssembleReturn() { |
| 1366 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1379 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 1367 int stack_slots = frame()->GetSpillSlotCount(); | |
| 1368 int pop_count = static_cast<int>(descriptor->StackParameterCount()); | 1380 int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
| 1381 |
| 1382 // Restore registers. |
| 1383 const RegList saves = |
| 1384 FLAG_enable_embedded_constant_pool |
| 1385 ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() |
| 1386 : descriptor->CalleeSavedRegisters(); |
| 1387 if (saves != 0) { |
| 1388 __ MultiPop(saves); |
| 1389 } |
| 1390 |
| 1391 // Restore double registers. |
| 1392 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); |
| 1393 if (double_saves != 0) { |
| 1394 __ MultiPopDoubles(double_saves); |
| 1395 } |
| 1396 |
| 1369 if (descriptor->kind() == CallDescriptor::kCallAddress) { | 1397 if (descriptor->kind() == CallDescriptor::kCallAddress) { |
| 1370 if (frame()->GetRegisterSaveAreaSize() > 0) { | 1398 __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize); |
| 1371 // Remove this frame's spill slots first. | |
| 1372 if (stack_slots > 0) { | |
| 1373 __ Add(sp, sp, stack_slots * kPointerSize, r0); | |
| 1374 } | |
| 1375 // Restore double registers. | |
| 1376 const RegList double_saves = descriptor->CalleeSavedFPRegisters(); | |
| 1377 __ MultiPopDoubles(double_saves); | |
| 1378 | |
| 1379 // Restore registers. | |
| 1380 RegList frame_saves = 0; | |
| 1381 if (FLAG_enable_embedded_constant_pool) { | |
| 1382 frame_saves |= kConstantPoolRegister.bit(); | |
| 1383 } | |
| 1384 const RegList saves = descriptor->CalleeSavedRegisters() & ~frame_saves; | |
| 1385 __ MultiPop(saves); | |
| 1386 } | |
| 1387 } else if (descriptor->IsJSFunctionCall() || needs_frame_) { | 1399 } else if (descriptor->IsJSFunctionCall() || needs_frame_) { |
| 1388 // Canonicalize JSFunction return sites for now. | 1400 // Canonicalize JSFunction return sites for now. |
| 1389 if (return_label_.is_bound()) { | 1401 if (return_label_.is_bound()) { |
| 1390 __ b(&return_label_); | 1402 __ b(&return_label_); |
| 1391 return; | 1403 return; |
| 1392 } else { | 1404 } else { |
| 1393 __ bind(&return_label_); | 1405 __ bind(&return_label_); |
| 1406 __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize); |
| 1394 } | 1407 } |
| 1408 } else { |
| 1409 __ Drop(pop_count); |
| 1395 } | 1410 } |
| 1396 __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize); | |
| 1397 __ Ret(); | 1411 __ Ret(); |
| 1398 } | 1412 } |
| 1399 | 1413 |
| 1400 | 1414 |
| 1401 void CodeGenerator::AssembleMove(InstructionOperand* source, | 1415 void CodeGenerator::AssembleMove(InstructionOperand* source, |
| 1402 InstructionOperand* destination) { | 1416 InstructionOperand* destination) { |
| 1403 PPCOperandConverter g(this, NULL); | 1417 PPCOperandConverter g(this, NULL); |
| 1404 // Dispatch on the source and destination operand kinds. Not all | 1418 // Dispatch on the source and destination operand kinds. Not all |
| 1405 // combinations are possible. | 1419 // combinations are possible. |
| 1406 if (source->IsRegister()) { | 1420 if (source->IsRegister()) { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 } | 1610 } |
| 1597 } | 1611 } |
| 1598 } | 1612 } |
| 1599 } | 1613 } |
| 1600 | 1614 |
| 1601 #undef __ | 1615 #undef __ |
| 1602 | 1616 |
| 1603 } // namespace compiler | 1617 } // namespace compiler |
| 1604 } // namespace internal | 1618 } // namespace internal |
| 1605 } // namespace v8 | 1619 } // namespace v8 |
| OLD | NEW |