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 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, | 741 |
742 bool builtin_exit_frame) { | 742 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { |
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, kDontSaveFPRegs, kArgvOnStack, | 745 CEntryStub ces(isolate(), 1); |
746 builtin_exit_frame); | |
747 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); | 746 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); |
748 } | 747 } |
749 | 748 |
| 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); | |
4443 | 4439 |
| 4440 void MacroAssembler::EnterExitFramePrologue(bool save_rax) { |
4444 // Set up the frame structure on the stack. | 4441 // Set up the frame structure on the stack. |
4445 // All constants are relative to the frame pointer of the exit frame. | 4442 // All constants are relative to the frame pointer of the exit frame. |
4446 DCHECK_EQ(kFPOnStackSize + kPCOnStackSize, | 4443 DCHECK_EQ(kFPOnStackSize + kPCOnStackSize, |
4447 ExitFrameConstants::kCallerSPDisplacement); | 4444 ExitFrameConstants::kCallerSPDisplacement); |
4448 DCHECK_EQ(kFPOnStackSize, ExitFrameConstants::kCallerPCOffset); | 4445 DCHECK_EQ(kFPOnStackSize, ExitFrameConstants::kCallerPCOffset); |
4449 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); | 4446 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
4450 pushq(rbp); | 4447 pushq(rbp); |
4451 movp(rbp, rsp); | 4448 movp(rbp, rsp); |
4452 | 4449 |
4453 // Reserve room for entry stack pointer and push the code object. | 4450 // Reserve room for entry stack pointer and push the code object. |
4454 Push(Smi::FromInt(frame_type)); | 4451 Push(Smi::FromInt(StackFrame::EXIT)); |
4455 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); | 4452 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); |
4456 Push(Immediate(0)); // Saved entry sp, patched before call. | 4453 Push(Immediate(0)); // Saved entry sp, patched before call. |
4457 Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); | 4454 Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); |
4458 Push(kScratchRegister); // Accessed from EditFrame::code_slot. | 4455 Push(kScratchRegister); // Accessed from EditFrame::code_slot. |
4459 | 4456 |
4460 // Save the frame pointer and the context in top. | 4457 // Save the frame pointer and the context in top. |
4461 if (save_rax) { | 4458 if (save_rax) { |
4462 movp(r14, rax); // Backup rax in callee-save register. | 4459 movp(r14, rax); // Backup rax in callee-save register. |
4463 } | 4460 } |
4464 | 4461 |
(...skipping 30 matching lines...) Expand all Loading... |
4495 if (kFrameAlignment > 0) { | 4492 if (kFrameAlignment > 0) { |
4496 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); | 4493 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); |
4497 DCHECK(is_int8(kFrameAlignment)); | 4494 DCHECK(is_int8(kFrameAlignment)); |
4498 andp(rsp, Immediate(-kFrameAlignment)); | 4495 andp(rsp, Immediate(-kFrameAlignment)); |
4499 } | 4496 } |
4500 | 4497 |
4501 // Patch the saved entry sp. | 4498 // Patch the saved entry sp. |
4502 movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); | 4499 movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); |
4503 } | 4500 } |
4504 | 4501 |
4505 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles, | 4502 |
4506 StackFrame::Type frame_type) { | 4503 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { |
4507 EnterExitFramePrologue(true, frame_type); | 4504 EnterExitFramePrologue(true); |
4508 | 4505 |
4509 // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, | 4506 // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, |
4510 // so it must be retained across the C-call. | 4507 // so it must be retained across the C-call. |
4511 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 4508 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
4512 leap(r15, Operand(rbp, r14, times_pointer_size, offset)); | 4509 leap(r15, Operand(rbp, r14, times_pointer_size, offset)); |
4513 | 4510 |
4514 EnterExitFrameEpilogue(arg_stack_space, save_doubles); | 4511 EnterExitFrameEpilogue(arg_stack_space, save_doubles); |
4515 } | 4512 } |
4516 | 4513 |
4517 | 4514 |
4518 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { | 4515 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { |
4519 EnterExitFramePrologue(false, StackFrame::EXIT); | 4516 EnterExitFramePrologue(false); |
4520 EnterExitFrameEpilogue(arg_stack_space, false); | 4517 EnterExitFrameEpilogue(arg_stack_space, false); |
4521 } | 4518 } |
4522 | 4519 |
4523 | 4520 |
4524 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { | 4521 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { |
4525 // Registers: | 4522 // Registers: |
4526 // r15 : argv | 4523 // r15 : argv |
4527 if (save_doubles) { | 4524 if (save_doubles) { |
4528 int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; | 4525 int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; |
4529 const RegisterConfiguration* config = RegisterConfiguration::Crankshaft(); | 4526 const RegisterConfiguration* config = RegisterConfiguration::Crankshaft(); |
(...skipping 1186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5716 movl(rax, dividend); | 5713 movl(rax, dividend); |
5717 shrl(rax, Immediate(31)); | 5714 shrl(rax, Immediate(31)); |
5718 addl(rdx, rax); | 5715 addl(rdx, rax); |
5719 } | 5716 } |
5720 | 5717 |
5721 | 5718 |
5722 } // namespace internal | 5719 } // namespace internal |
5723 } // namespace v8 | 5720 } // namespace v8 |
5724 | 5721 |
5725 #endif // V8_TARGET_ARCH_X64 | 5722 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |