OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 next_address); | 548 next_address); |
549 const int kLevelOffset = Offset( | 549 const int kLevelOffset = Offset( |
550 ExternalReference::handle_scope_level_address(), | 550 ExternalReference::handle_scope_level_address(), |
551 next_address); | 551 next_address); |
552 ExternalReference scheduled_exception_address = | 552 ExternalReference scheduled_exception_address = |
553 ExternalReference::scheduled_exception_address(); | 553 ExternalReference::scheduled_exception_address(); |
554 | 554 |
555 // Allocate HandleScope in callee-save registers. | 555 // Allocate HandleScope in callee-save registers. |
556 Register prev_next_address_reg = r14; | 556 Register prev_next_address_reg = r14; |
557 Register prev_limit_reg = rbx; | 557 Register prev_limit_reg = rbx; |
558 Register base_reg = r12; | 558 Register base_reg = r15; |
559 movq(base_reg, next_address); | 559 movq(base_reg, next_address); |
560 movq(prev_next_address_reg, Operand(base_reg, kNextOffset)); | 560 movq(prev_next_address_reg, Operand(base_reg, kNextOffset)); |
561 movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); | 561 movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); |
562 addl(Operand(base_reg, kLevelOffset), Immediate(1)); | 562 addl(Operand(base_reg, kLevelOffset), Immediate(1)); |
563 // Call the api function! | 563 // Call the api function! |
564 movq(rax, | 564 movq(rax, |
565 reinterpret_cast<int64_t>(function->address()), | 565 reinterpret_cast<int64_t>(function->address()), |
566 RelocInfo::RUNTIME_ENTRY); | 566 RelocInfo::RUNTIME_ENTRY); |
567 call(rax); | 567 call(rax); |
568 | 568 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 cmpq(dst, kSmiConstantRegister); | 714 cmpq(dst, kSmiConstantRegister); |
715 if (allow_stub_calls()) { | 715 if (allow_stub_calls()) { |
716 Assert(equal, "Uninitialized kSmiConstantRegister"); | 716 Assert(equal, "Uninitialized kSmiConstantRegister"); |
717 } else { | 717 } else { |
718 NearLabel ok; | 718 NearLabel ok; |
719 j(equal, &ok); | 719 j(equal, &ok); |
720 int3(); | 720 int3(); |
721 bind(&ok); | 721 bind(&ok); |
722 } | 722 } |
723 } | 723 } |
724 if (source->value() == 0) { | 724 int value = source->value(); |
| 725 if (value == 0) { |
725 xorl(dst, dst); | 726 xorl(dst, dst); |
726 return; | 727 return; |
727 } | 728 } |
728 int value = source->value(); | |
729 bool negative = value < 0; | 729 bool negative = value < 0; |
730 unsigned int uvalue = negative ? -value : value; | 730 unsigned int uvalue = negative ? -value : value; |
731 | 731 |
732 switch (uvalue) { | 732 switch (uvalue) { |
733 case 9: | 733 case 9: |
734 lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_8, 0)); | 734 lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_8, 0)); |
735 break; | 735 break; |
736 case 8: | 736 case 8: |
737 xorl(dst, dst); | 737 xorl(dst, dst); |
738 lea(dst, Operand(dst, kSmiConstantRegister, times_8, 0)); | 738 lea(dst, Operand(dst, kSmiConstantRegister, times_8, 0)); |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 push(rcx); | 1467 push(rcx); |
1468 push(rdx); | 1468 push(rdx); |
1469 push(rbx); | 1469 push(rbx); |
1470 // Not pushing rsp or rbp. | 1470 // Not pushing rsp or rbp. |
1471 push(rsi); | 1471 push(rsi); |
1472 push(rdi); | 1472 push(rdi); |
1473 push(r8); | 1473 push(r8); |
1474 push(r9); | 1474 push(r9); |
1475 // r10 is kScratchRegister. | 1475 // r10 is kScratchRegister. |
1476 push(r11); | 1476 push(r11); |
1477 push(r12); | 1477 // r12 is kSmiConstantRegister. |
1478 // r13 is kRootRegister. | 1478 // r13 is kRootRegister. |
1479 push(r14); | 1479 push(r14); |
1480 // r15 is kSmiConstantRegister | 1480 push(r15); |
1481 STATIC_ASSERT(11 == kNumSafepointSavedRegisters); | 1481 STATIC_ASSERT(11 == kNumSafepointSavedRegisters); |
1482 // Use lea for symmetry with Popad. | 1482 // Use lea for symmetry with Popad. |
1483 int sp_delta = | 1483 int sp_delta = |
1484 (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; | 1484 (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; |
1485 lea(rsp, Operand(rsp, -sp_delta)); | 1485 lea(rsp, Operand(rsp, -sp_delta)); |
1486 } | 1486 } |
1487 | 1487 |
1488 | 1488 |
1489 void MacroAssembler::Popad() { | 1489 void MacroAssembler::Popad() { |
1490 // Popad must not change the flags, so use lea instead of addq. | 1490 // Popad must not change the flags, so use lea instead of addq. |
1491 int sp_delta = | 1491 int sp_delta = |
1492 (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; | 1492 (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; |
1493 lea(rsp, Operand(rsp, sp_delta)); | 1493 lea(rsp, Operand(rsp, sp_delta)); |
| 1494 pop(r15); |
1494 pop(r14); | 1495 pop(r14); |
1495 pop(r12); | |
1496 pop(r11); | 1496 pop(r11); |
1497 pop(r9); | 1497 pop(r9); |
1498 pop(r8); | 1498 pop(r8); |
1499 pop(rdi); | 1499 pop(rdi); |
1500 pop(rsi); | 1500 pop(rsi); |
1501 pop(rbx); | 1501 pop(rbx); |
1502 pop(rdx); | 1502 pop(rdx); |
1503 pop(rcx); | 1503 pop(rcx); |
1504 pop(rax); | 1504 pop(rax); |
1505 } | 1505 } |
1506 | 1506 |
1507 | 1507 |
1508 void MacroAssembler::Dropad() { | 1508 void MacroAssembler::Dropad() { |
1509 addq(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); | 1509 addq(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); |
1510 } | 1510 } |
1511 | 1511 |
1512 | 1512 |
1513 // Order general registers are pushed by Pushad: | 1513 // Order general registers are pushed by Pushad: |
1514 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14. | 1514 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. |
1515 int MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { | 1515 int MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { |
1516 0, | 1516 0, |
1517 1, | 1517 1, |
1518 2, | 1518 2, |
1519 3, | 1519 3, |
1520 -1, | 1520 -1, |
1521 -1, | 1521 -1, |
1522 4, | 1522 4, |
1523 5, | 1523 5, |
1524 6, | 1524 6, |
1525 7, | 1525 7, |
1526 -1, | 1526 -1, |
1527 8, | 1527 8, |
| 1528 -1, |
| 1529 -1, |
1528 9, | 1530 9, |
1529 -1, | 1531 10 |
1530 10, | |
1531 -1 | |
1532 }; | 1532 }; |
1533 | 1533 |
1534 | 1534 |
1535 void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { | 1535 void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { |
1536 movq(SafepointRegisterSlot(dst), src); | 1536 movq(SafepointRegisterSlot(dst), src); |
1537 } | 1537 } |
1538 | 1538 |
1539 | 1539 |
1540 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { | 1540 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { |
1541 movq(dst, SafepointRegisterSlot(src)); | 1541 movq(dst, SafepointRegisterSlot(src)); |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2070 } | 2070 } |
2071 | 2071 |
2072 // Patch the saved entry sp. | 2072 // Patch the saved entry sp. |
2073 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); | 2073 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); |
2074 } | 2074 } |
2075 | 2075 |
2076 | 2076 |
2077 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { | 2077 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { |
2078 EnterExitFramePrologue(true); | 2078 EnterExitFramePrologue(true); |
2079 | 2079 |
2080 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame, | 2080 // Setup argv in callee-saved register r15. It is reused in LeaveExitFrame, |
2081 // so it must be retained across the C-call. | 2081 // so it must be retained across the C-call. |
2082 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 2082 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
2083 lea(r12, Operand(rbp, r14, times_pointer_size, offset)); | 2083 lea(r15, Operand(rbp, r14, times_pointer_size, offset)); |
2084 | 2084 |
2085 EnterExitFrameEpilogue(arg_stack_space, save_doubles); | 2085 EnterExitFrameEpilogue(arg_stack_space, save_doubles); |
2086 } | 2086 } |
2087 | 2087 |
2088 | 2088 |
2089 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { | 2089 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { |
2090 EnterExitFramePrologue(false); | 2090 EnterExitFramePrologue(false); |
2091 EnterExitFrameEpilogue(arg_stack_space, false); | 2091 EnterExitFrameEpilogue(arg_stack_space, false); |
2092 } | 2092 } |
2093 | 2093 |
2094 | 2094 |
2095 void MacroAssembler::LeaveExitFrame(bool save_doubles) { | 2095 void MacroAssembler::LeaveExitFrame(bool save_doubles) { |
2096 // Registers: | 2096 // Registers: |
2097 // r12 : argv | 2097 // r15 : argv |
2098 if (save_doubles) { | 2098 if (save_doubles) { |
2099 int offset = -2 * kPointerSize; | 2099 int offset = -2 * kPointerSize; |
2100 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; i++) { | 2100 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; i++) { |
2101 XMMRegister reg = XMMRegister::FromAllocationIndex(i); | 2101 XMMRegister reg = XMMRegister::FromAllocationIndex(i); |
2102 movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); | 2102 movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); |
2103 } | 2103 } |
2104 } | 2104 } |
2105 // Get the return address from the stack and restore the frame pointer. | 2105 // Get the return address from the stack and restore the frame pointer. |
2106 movq(rcx, Operand(rbp, 1 * kPointerSize)); | 2106 movq(rcx, Operand(rbp, 1 * kPointerSize)); |
2107 movq(rbp, Operand(rbp, 0 * kPointerSize)); | 2107 movq(rbp, Operand(rbp, 0 * kPointerSize)); |
2108 | 2108 |
2109 // Drop everything up to and including the arguments and the receiver | 2109 // Drop everything up to and including the arguments and the receiver |
2110 // from the caller stack. | 2110 // from the caller stack. |
2111 lea(rsp, Operand(r12, 1 * kPointerSize)); | 2111 lea(rsp, Operand(r15, 1 * kPointerSize)); |
2112 | 2112 |
2113 // Push the return address to get ready to return. | 2113 // Push the return address to get ready to return. |
2114 push(rcx); | 2114 push(rcx); |
2115 | 2115 |
2116 LeaveExitFrameEpilogue(); | 2116 LeaveExitFrameEpilogue(); |
2117 } | 2117 } |
2118 | 2118 |
2119 | 2119 |
2120 void MacroAssembler::LeaveApiExitFrame() { | 2120 void MacroAssembler::LeaveApiExitFrame() { |
2121 movq(rsp, rbp); | 2121 movq(rsp, rbp); |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2686 CPU::FlushICache(address_, size_); | 2686 CPU::FlushICache(address_, size_); |
2687 | 2687 |
2688 // Check that the code was patched as expected. | 2688 // Check that the code was patched as expected. |
2689 ASSERT(masm_.pc_ == address_ + size_); | 2689 ASSERT(masm_.pc_ == address_ + size_); |
2690 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2690 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2691 } | 2691 } |
2692 | 2692 |
2693 } } // namespace v8::internal | 2693 } } // namespace v8::internal |
2694 | 2694 |
2695 #endif // V8_TARGET_ARCH_X64 | 2695 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |