| 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 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 i.InputRegister##width(1)); \ | 441 i.InputRegister##width(1)); \ |
| 442 } else { \ | 442 } else { \ |
| 443 uint32_t imm = \ | 443 uint32_t imm = \ |
| 444 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \ | 444 static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \ |
| 445 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ | 445 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ |
| 446 imm % (width)); \ | 446 imm % (width)); \ |
| 447 } \ | 447 } \ |
| 448 } while (0) | 448 } while (0) |
| 449 | 449 |
| 450 | 450 |
| 451 void CodeGenerator::AssembleDeconstructActivationRecord() { | 451 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
| 452 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 452 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 453 int stack_slots = frame()->GetSpillSlotCount(); | 453 int stack_slots = frame()->GetSpillSlotCount(); |
| 454 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | 454 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { |
| 455 __ Mov(jssp, fp); | 455 __ Mov(jssp, fp); |
| 456 __ Pop(fp, lr); | 456 __ Pop(fp, lr); |
| 457 } | 457 } |
| 458 if (stack_param_delta < 0) { |
| 459 int offset = -stack_param_delta * kPointerSize; |
| 460 __ Add(jssp, jssp, Operand(offset)); |
| 461 } |
| 458 } | 462 } |
| 459 | 463 |
| 460 | 464 |
| 461 // Assembles an instruction after register allocation, producing machine code. | 465 // Assembles an instruction after register allocation, producing machine code. |
| 462 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 466 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 463 Arm64OperandConverter i(this, instr); | 467 Arm64OperandConverter i(this, instr); |
| 464 InstructionCode opcode = instr->opcode(); | 468 InstructionCode opcode = instr->opcode(); |
| 465 switch (ArchOpcodeField::decode(opcode)) { | 469 switch (ArchOpcodeField::decode(opcode)) { |
| 466 case kArchCallCodeObject: { | 470 case kArchCallCodeObject: { |
| 467 EnsureSpaceForLazyDeopt(); | 471 EnsureSpaceForLazyDeopt(); |
| 468 if (instr->InputAt(0)->IsImmediate()) { | 472 if (instr->InputAt(0)->IsImmediate()) { |
| 469 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 473 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
| 470 RelocInfo::CODE_TARGET); | 474 RelocInfo::CODE_TARGET); |
| 471 } else { | 475 } else { |
| 472 Register target = i.InputRegister(0); | 476 Register target = i.InputRegister(0); |
| 473 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); | 477 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); |
| 474 __ Call(target); | 478 __ Call(target); |
| 475 } | 479 } |
| 476 RecordCallPosition(instr); | 480 RecordCallPosition(instr); |
| 477 break; | 481 break; |
| 478 } | 482 } |
| 479 case kArchTailCallCodeObject: { | 483 case kArchTailCallCodeObject: { |
| 480 AssembleDeconstructActivationRecord(); | 484 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
| 485 AssembleDeconstructActivationRecord(stack_param_delta); |
| 481 if (instr->InputAt(0)->IsImmediate()) { | 486 if (instr->InputAt(0)->IsImmediate()) { |
| 482 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), | 487 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), |
| 483 RelocInfo::CODE_TARGET); | 488 RelocInfo::CODE_TARGET); |
| 484 } else { | 489 } else { |
| 485 Register target = i.InputRegister(0); | 490 Register target = i.InputRegister(0); |
| 486 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); | 491 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); |
| 487 __ Jump(target); | 492 __ Jump(target); |
| 488 } | 493 } |
| 489 break; | 494 break; |
| 490 } | 495 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 507 case kArchTailCallJSFunction: { | 512 case kArchTailCallJSFunction: { |
| 508 Register func = i.InputRegister(0); | 513 Register func = i.InputRegister(0); |
| 509 if (FLAG_debug_code) { | 514 if (FLAG_debug_code) { |
| 510 // Check the function's context matches the context argument. | 515 // Check the function's context matches the context argument. |
| 511 UseScratchRegisterScope scope(masm()); | 516 UseScratchRegisterScope scope(masm()); |
| 512 Register temp = scope.AcquireX(); | 517 Register temp = scope.AcquireX(); |
| 513 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); | 518 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); |
| 514 __ cmp(cp, temp); | 519 __ cmp(cp, temp); |
| 515 __ Assert(eq, kWrongFunctionContext); | 520 __ Assert(eq, kWrongFunctionContext); |
| 516 } | 521 } |
| 517 AssembleDeconstructActivationRecord(); | 522 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
| 523 AssembleDeconstructActivationRecord(stack_param_delta); |
| 518 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 524 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); |
| 519 __ Jump(x10); | 525 __ Jump(x10); |
| 520 break; | 526 break; |
| 521 } | 527 } |
| 522 case kArchLazyBailout: { | 528 case kArchLazyBailout: { |
| 523 EnsureSpaceForLazyDeopt(); | 529 EnsureSpaceForLazyDeopt(); |
| 524 RecordCallPosition(instr); | 530 RecordCallPosition(instr); |
| 525 break; | 531 break; |
| 526 } | 532 } |
| 527 case kArchPrepareCallCFunction: | 533 case kArchPrepareCallCFunction: |
| (...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1505 padding_size -= kInstructionSize; | 1511 padding_size -= kInstructionSize; |
| 1506 } | 1512 } |
| 1507 } | 1513 } |
| 1508 } | 1514 } |
| 1509 | 1515 |
| 1510 #undef __ | 1516 #undef __ |
| 1511 | 1517 |
| 1512 } // namespace compiler | 1518 } // namespace compiler |
| 1513 } // namespace internal | 1519 } // namespace internal |
| 1514 } // namespace v8 | 1520 } // namespace v8 |
| OLD | NEW |