| 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 #include "src/compiler/code-generator-impl.h" | 6 #include "src/compiler/code-generator-impl.h" |
| 7 #include "src/compiler/gap-resolver.h" | 7 #include "src/compiler/gap-resolver.h" |
| 8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
| 9 #include "src/compiler/osr.h" | 9 #include "src/compiler/osr.h" |
| 10 #include "src/mips/macro-assembler-mips.h" | 10 #include "src/mips/macro-assembler-mips.h" |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 __ dmfc1(at, i.OutputDoubleRegister()); \ | 448 __ dmfc1(at, i.OutputDoubleRegister()); \ |
| 449 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ | 449 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ |
| 450 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ | 450 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ |
| 451 __ bind(ool->exit()); \ | 451 __ bind(ool->exit()); \ |
| 452 __ bind(&done); \ | 452 __ bind(&done); \ |
| 453 } while (0) | 453 } while (0) |
| 454 | 454 |
| 455 | 455 |
| 456 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 456 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
| 457 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 457 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 458 int stack_slots = frame()->GetSpillSlotCount(); | 458 int spill_slots = frame()->GetSpillSlotCount(); |
| 459 int stack_pointer_delta = 0; | 459 bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; |
| 460 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | 460 if (has_frame) { |
| 461 __ mov(sp, fp); | 461 if (stack_param_delta != 0) { |
| 462 __ ld(fp, MemOperand(sp, 0 * kPointerSize)); | 462 int total_discarded_slots = frame()->GetTotalFrameSlotCount(); |
| 463 __ ld(ra, MemOperand(sp, 1 * kPointerSize)); | 463 // Leave the PC and saved frame pointer on the stack. |
| 464 stack_pointer_delta = 2 * kPointerSize; | 464 total_discarded_slots -= |
| 465 } | 465 StandardFrameConstants::kFixedFrameSizeFromFp / kPointerSize; |
| 466 if (stack_param_delta < 0) { | 466 // Discard only slots that won't be used by new parameters. |
| 467 stack_pointer_delta += -stack_param_delta * kPointerSize; | 467 total_discarded_slots -= stack_param_delta; |
| 468 } | 468 if (total_discarded_slots > 0) { |
| 469 if (stack_pointer_delta != 0) { | 469 __ daddiu(sp, sp, total_discarded_slots * kPointerSize); |
| 470 __ daddiu(sp, sp, stack_pointer_delta); | 470 } |
| 471 } else { |
| 472 __ mov(sp, fp); |
| 473 } |
| 474 __ Pop(ra, fp); |
| 471 } | 475 } |
| 472 } | 476 } |
| 473 | 477 |
| 478 |
| 479 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
| 480 if (stack_param_delta > 0) { |
| 481 int total_discarded_slots = frame()->GetTotalFrameSlotCount(); |
| 482 // Leave the PC and saved frame pointer on the stack. |
| 483 total_discarded_slots -= |
| 484 StandardFrameConstants::kFixedFrameSizeFromFp / kPointerSize; |
| 485 // Discard only slots that won't be used by new parameters. |
| 486 total_discarded_slots -= stack_param_delta; |
| 487 if (total_discarded_slots < 0) { |
| 488 __ Dsubu(sp, sp, Operand(-total_discarded_slots * kPointerSize)); |
| 489 } |
| 490 } |
| 491 } |
| 492 |
| 474 | 493 |
| 475 // Assembles an instruction after register allocation, producing machine code. | 494 // Assembles an instruction after register allocation, producing machine code. |
| 476 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 495 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 477 MipsOperandConverter i(this, instr); | 496 MipsOperandConverter i(this, instr); |
| 478 InstructionCode opcode = instr->opcode(); | 497 InstructionCode opcode = instr->opcode(); |
| 479 | 498 |
| 480 switch (ArchOpcodeField::decode(opcode)) { | 499 switch (ArchOpcodeField::decode(opcode)) { |
| 481 case kArchCallCodeObject: { | 500 case kArchCallCodeObject: { |
| 482 EnsureSpaceForLazyDeopt(); | 501 EnsureSpaceForLazyDeopt(); |
| 483 if (instr->InputAt(0)->IsImmediate()) { | 502 if (instr->InputAt(0)->IsImmediate()) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 case kArchLazyBailout: { | 550 case kArchLazyBailout: { |
| 532 EnsureSpaceForLazyDeopt(); | 551 EnsureSpaceForLazyDeopt(); |
| 533 RecordCallPosition(instr); | 552 RecordCallPosition(instr); |
| 534 break; | 553 break; |
| 535 } | 554 } |
| 536 case kArchPrepareCallCFunction: { | 555 case kArchPrepareCallCFunction: { |
| 537 int const num_parameters = MiscField::decode(instr->opcode()); | 556 int const num_parameters = MiscField::decode(instr->opcode()); |
| 538 __ PrepareCallCFunction(num_parameters, kScratchReg); | 557 __ PrepareCallCFunction(num_parameters, kScratchReg); |
| 539 break; | 558 break; |
| 540 } | 559 } |
| 560 case kArchPrepareTailCall: |
| 561 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); |
| 562 break; |
| 541 case kArchCallCFunction: { | 563 case kArchCallCFunction: { |
| 542 int const num_parameters = MiscField::decode(instr->opcode()); | 564 int const num_parameters = MiscField::decode(instr->opcode()); |
| 543 if (instr->InputAt(0)->IsImmediate()) { | 565 if (instr->InputAt(0)->IsImmediate()) { |
| 544 ExternalReference ref = i.InputExternalReference(0); | 566 ExternalReference ref = i.InputExternalReference(0); |
| 545 __ CallCFunction(ref, num_parameters); | 567 __ CallCFunction(ref, num_parameters); |
| 546 } else { | 568 } else { |
| 547 Register func = i.InputRegister(0); | 569 Register func = i.InputRegister(0); |
| 548 __ CallCFunction(func, num_parameters); | 570 __ CallCFunction(func, num_parameters); |
| 549 } | 571 } |
| 550 break; | 572 break; |
| (...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1701 padding_size -= v8::internal::Assembler::kInstrSize; | 1723 padding_size -= v8::internal::Assembler::kInstrSize; |
| 1702 } | 1724 } |
| 1703 } | 1725 } |
| 1704 } | 1726 } |
| 1705 | 1727 |
| 1706 #undef __ | 1728 #undef __ |
| 1707 | 1729 |
| 1708 } // namespace compiler | 1730 } // namespace compiler |
| 1709 } // namespace internal | 1731 } // namespace internal |
| 1710 } // namespace v8 | 1732 } // namespace v8 |
| OLD | NEW |