| 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/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/arm64/macro-assembler-arm64.h" | 8 #include "src/arm64/macro-assembler-arm64.h" |
| 9 #include "src/compiler/code-generator-impl.h" | 9 #include "src/compiler/code-generator-impl.h" |
| 10 #include "src/compiler/gap-resolver.h" | 10 #include "src/compiler/gap-resolver.h" |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 uint32_t imm = \ | 452 uint32_t imm = \ |
| 453 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \ | 453 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \ |
| 454 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ | 454 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ |
| 455 imm % (width)); \ | 455 imm % (width)); \ |
| 456 } \ | 456 } \ |
| 457 } while (0) | 457 } while (0) |
| 458 | 458 |
| 459 | 459 |
| 460 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 460 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
| 461 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 461 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 462 int stack_slots = frame()->GetSpillSlotCount(); | 462 int spill_slots = frame()->GetSpillSlotCount(); |
| 463 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | 463 bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; |
| 464 __ Mov(jssp, fp); | 464 if (has_frame) { |
| 465 if (stack_param_delta != 0) { |
| 466 int total_discarded_slots = frame()->GetTotalFrameSlotCount(); |
| 467 // Leave the PC and saved frame pointer on the stack. |
| 468 total_discarded_slots -= |
| 469 StandardFrameConstants::kFixedFrameSizeFromFp / kPointerSize; |
| 470 // Discard only slots that won't be used by new parameters. |
| 471 total_discarded_slots -= stack_param_delta; |
| 472 if (total_discarded_slots > 0) { |
| 473 __ Add(jssp, jssp, Operand(total_discarded_slots * kPointerSize)); |
| 474 } |
| 475 } else { |
| 476 __ Mov(jssp, fp); |
| 477 } |
| 465 __ Pop(fp, lr); | 478 __ Pop(fp, lr); |
| 466 } | 479 } |
| 467 if (stack_param_delta < 0) { | |
| 468 int offset = -stack_param_delta * kPointerSize; | |
| 469 __ Add(jssp, jssp, Operand(offset)); | |
| 470 } | |
| 471 } | 480 } |
| 472 | 481 |
| 482 |
| 483 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
| 484 if (stack_param_delta > 0) { |
| 485 int total_discarded_slots = frame()->GetTotalFrameSlotCount(); |
| 486 // Leave the PC and saved frame pointer on the stack. |
| 487 total_discarded_slots -= |
| 488 StandardFrameConstants::kFixedFrameSizeFromFp / kPointerSize; |
| 489 // Discard only slots that won't be used by new parameters. |
| 490 total_discarded_slots -= stack_param_delta; |
| 491 if (total_discarded_slots < 0) { |
| 492 __ Sub(jssp, jssp, Operand(-total_discarded_slots * kPointerSize)); |
| 493 } |
| 494 } |
| 495 } |
| 496 |
| 473 | 497 |
| 474 // Assembles an instruction after register allocation, producing machine code. | 498 // Assembles an instruction after register allocation, producing machine code. |
| 475 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 499 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 476 Arm64OperandConverter i(this, instr); | 500 Arm64OperandConverter i(this, instr); |
| 477 InstructionCode opcode = instr->opcode(); | 501 InstructionCode opcode = instr->opcode(); |
| 478 switch (ArchOpcodeField::decode(opcode)) { | 502 switch (ArchOpcodeField::decode(opcode)) { |
| 479 case kArchCallCodeObject: { | 503 case kArchCallCodeObject: { |
| 480 EnsureSpaceForLazyDeopt(); | 504 EnsureSpaceForLazyDeopt(); |
| 481 if (instr->InputAt(0)->IsImmediate()) { | 505 if (instr->InputAt(0)->IsImmediate()) { |
| 482 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 506 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 EnsureSpaceForLazyDeopt(); | 566 EnsureSpaceForLazyDeopt(); |
| 543 RecordCallPosition(instr); | 567 RecordCallPosition(instr); |
| 544 break; | 568 break; |
| 545 } | 569 } |
| 546 case kArchPrepareCallCFunction: | 570 case kArchPrepareCallCFunction: |
| 547 // We don't need kArchPrepareCallCFunction on arm64 as the instruction | 571 // We don't need kArchPrepareCallCFunction on arm64 as the instruction |
| 548 // selector already perform a Claim to reserve space on the stack and | 572 // selector already perform a Claim to reserve space on the stack and |
| 549 // guarantee correct alignment of stack pointer. | 573 // guarantee correct alignment of stack pointer. |
| 550 UNREACHABLE(); | 574 UNREACHABLE(); |
| 551 break; | 575 break; |
| 576 case kArchPrepareTailCall: |
| 577 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); |
| 578 break; |
| 552 case kArchCallCFunction: { | 579 case kArchCallCFunction: { |
| 553 int const num_parameters = MiscField::decode(instr->opcode()); | 580 int const num_parameters = MiscField::decode(instr->opcode()); |
| 554 if (instr->InputAt(0)->IsImmediate()) { | 581 if (instr->InputAt(0)->IsImmediate()) { |
| 555 ExternalReference ref = i.InputExternalReference(0); | 582 ExternalReference ref = i.InputExternalReference(0); |
| 556 __ CallCFunction(ref, num_parameters, 0); | 583 __ CallCFunction(ref, num_parameters, 0); |
| 557 } else { | 584 } else { |
| 558 Register func = i.InputRegister(0); | 585 Register func = i.InputRegister(0); |
| 559 __ CallCFunction(func, num_parameters, 0); | 586 __ CallCFunction(func, num_parameters, 0); |
| 560 } | 587 } |
| 561 // CallCFunction only supports register arguments so we never need to call | 588 // CallCFunction only supports register arguments so we never need to call |
| (...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 padding_size -= kInstructionSize; | 1556 padding_size -= kInstructionSize; |
| 1530 } | 1557 } |
| 1531 } | 1558 } |
| 1532 } | 1559 } |
| 1533 | 1560 |
| 1534 #undef __ | 1561 #undef __ |
| 1535 | 1562 |
| 1536 } // namespace compiler | 1563 } // namespace compiler |
| 1537 } // namespace internal | 1564 } // namespace internal |
| 1538 } // namespace v8 | 1565 } // namespace v8 |
| OLD | NEW |