OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 // ----------------------------------- | 731 // ----------------------------------- |
732 | 732 |
733 const Runtime::Function* function = Runtime::FunctionForId(fid); | 733 const Runtime::Function* function = Runtime::FunctionForId(fid); |
734 DCHECK_EQ(1, function->result_size); | 734 DCHECK_EQ(1, function->result_size); |
735 if (function->nargs >= 0) { | 735 if (function->nargs >= 0) { |
736 Set(rax, function->nargs); | 736 Set(rax, function->nargs); |
737 } | 737 } |
738 JumpToExternalReference(ExternalReference(fid, isolate())); | 738 JumpToExternalReference(ExternalReference(fid, isolate())); |
739 } | 739 } |
740 | 740 |
741 | 741 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, |
742 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { | 742 bool builtin_exit_frame) { |
743 // Set the entry point and jump to the C entry runtime stub. | 743 // Set the entry point and jump to the C entry runtime stub. |
744 LoadAddress(rbx, ext); | 744 LoadAddress(rbx, ext); |
745 CEntryStub ces(isolate(), 1); | 745 CEntryStub ces(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, |
| 746 builtin_exit_frame); |
746 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); | 747 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); |
747 } | 748 } |
748 | 749 |
749 | |
750 #define REG(Name) \ | 750 #define REG(Name) \ |
751 { Register::kCode_##Name } | 751 { Register::kCode_##Name } |
752 | 752 |
753 static const Register saved_regs[] = { | 753 static const Register saved_regs[] = { |
754 REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), | 754 REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), |
755 REG(r9), REG(r10), REG(r11) | 755 REG(r9), REG(r10), REG(r11) |
756 }; | 756 }; |
757 | 757 |
758 #undef REG | 758 #undef REG |
759 | 759 |
(...skipping 3669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4429 if (emit_debug_code()) { | 4429 if (emit_debug_code()) { |
4430 Move(kScratchRegister, Smi::FromInt(type)); | 4430 Move(kScratchRegister, Smi::FromInt(type)); |
4431 cmpp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset), | 4431 cmpp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset), |
4432 kScratchRegister); | 4432 kScratchRegister); |
4433 Check(equal, kStackFrameTypesMustMatch); | 4433 Check(equal, kStackFrameTypesMustMatch); |
4434 } | 4434 } |
4435 movp(rsp, rbp); | 4435 movp(rsp, rbp); |
4436 popq(rbp); | 4436 popq(rbp); |
4437 } | 4437 } |
4438 | 4438 |
| 4439 void MacroAssembler::EnterExitFramePrologue(bool save_rax, |
| 4440 StackFrame::Type frame_type) { |
| 4441 DCHECK(frame_type == StackFrame::EXIT || |
| 4442 frame_type == StackFrame::BUILTIN_EXIT); |
4439 | 4443 |
4440 void MacroAssembler::EnterExitFramePrologue(bool save_rax) { | |
4441 // Set up the frame structure on the stack. | 4444 // Set up the frame structure on the stack. |
4442 // All constants are relative to the frame pointer of the exit frame. | 4445 // All constants are relative to the frame pointer of the exit frame. |
4443 DCHECK_EQ(kFPOnStackSize + kPCOnStackSize, | 4446 DCHECK_EQ(kFPOnStackSize + kPCOnStackSize, |
4444 ExitFrameConstants::kCallerSPDisplacement); | 4447 ExitFrameConstants::kCallerSPDisplacement); |
4445 DCHECK_EQ(kFPOnStackSize, ExitFrameConstants::kCallerPCOffset); | 4448 DCHECK_EQ(kFPOnStackSize, ExitFrameConstants::kCallerPCOffset); |
4446 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); | 4449 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
4447 pushq(rbp); | 4450 pushq(rbp); |
4448 movp(rbp, rsp); | 4451 movp(rbp, rsp); |
4449 | 4452 |
4450 // Reserve room for entry stack pointer and push the code object. | 4453 // Reserve room for entry stack pointer and push the code object. |
4451 Push(Smi::FromInt(StackFrame::EXIT)); | 4454 Push(Smi::FromInt(frame_type)); |
4452 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); | 4455 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); |
4453 Push(Immediate(0)); // Saved entry sp, patched before call. | 4456 Push(Immediate(0)); // Saved entry sp, patched before call. |
4454 Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); | 4457 Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
4455 Push(kScratchRegister); // Accessed from EditFrame::code_slot. | 4458 Push(kScratchRegister); // Accessed from EditFrame::code_slot. |
4456 | 4459 |
4457 // Save the frame pointer and the context in top. | 4460 // Save the frame pointer and the context in top. |
4458 if (save_rax) { | 4461 if (save_rax) { |
4459 movp(r14, rax); // Backup rax in callee-save register. | 4462 movp(r14, rax); // Backup rax in callee-save register. |
4460 } | 4463 } |
4461 | 4464 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4493 if (kFrameAlignment > 0) { | 4496 if (kFrameAlignment > 0) { |
4494 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); | 4497 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); |
4495 DCHECK(is_int8(kFrameAlignment)); | 4498 DCHECK(is_int8(kFrameAlignment)); |
4496 andp(rsp, Immediate(-kFrameAlignment)); | 4499 andp(rsp, Immediate(-kFrameAlignment)); |
4497 } | 4500 } |
4498 | 4501 |
4499 // Patch the saved entry sp. | 4502 // Patch the saved entry sp. |
4500 movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); | 4503 movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); |
4501 } | 4504 } |
4502 | 4505 |
4503 | 4506 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles, |
4504 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { | 4507 StackFrame::Type frame_type) { |
4505 EnterExitFramePrologue(true); | 4508 EnterExitFramePrologue(true, frame_type); |
4506 | 4509 |
4507 // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, | 4510 // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, |
4508 // so it must be retained across the C-call. | 4511 // so it must be retained across the C-call. |
4509 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 4512 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
4510 leap(r15, Operand(rbp, r14, times_pointer_size, offset)); | 4513 leap(r15, Operand(rbp, r14, times_pointer_size, offset)); |
4511 | 4514 |
4512 EnterExitFrameEpilogue(arg_stack_space, save_doubles); | 4515 EnterExitFrameEpilogue(arg_stack_space, save_doubles); |
4513 } | 4516 } |
4514 | 4517 |
4515 | 4518 |
4516 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { | 4519 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { |
4517 EnterExitFramePrologue(false); | 4520 EnterExitFramePrologue(false, StackFrame::EXIT); |
4518 EnterExitFrameEpilogue(arg_stack_space, false); | 4521 EnterExitFrameEpilogue(arg_stack_space, false); |
4519 } | 4522 } |
4520 | 4523 |
4521 | 4524 |
4522 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { | 4525 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { |
4523 // Registers: | 4526 // Registers: |
4524 // r15 : argv | 4527 // r15 : argv |
4525 if (save_doubles) { | 4528 if (save_doubles) { |
4526 int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; | 4529 int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; |
4527 const RegisterConfiguration* config = | 4530 const RegisterConfiguration* config = |
(...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5715 movl(rax, dividend); | 5718 movl(rax, dividend); |
5716 shrl(rax, Immediate(31)); | 5719 shrl(rax, Immediate(31)); |
5717 addl(rdx, rax); | 5720 addl(rdx, rax); |
5718 } | 5721 } |
5719 | 5722 |
5720 | 5723 |
5721 } // namespace internal | 5724 } // namespace internal |
5722 } // namespace v8 | 5725 } // namespace v8 |
5723 | 5726 |
5724 #endif // V8_TARGET_ARCH_X64 | 5727 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |