| 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 |