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 #if V8_TARGET_ARCH_PPC | 5 #if V8_TARGET_ARCH_PPC |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 | 1574 |
1575 // Slow-case: Handle non-smi or out-of-bounds access to arguments | 1575 // Slow-case: Handle non-smi or out-of-bounds access to arguments |
1576 // by calling the runtime system. | 1576 // by calling the runtime system. |
1577 __ bind(&slow); | 1577 __ bind(&slow); |
1578 __ push(r4); | 1578 __ push(r4); |
1579 __ TailCallRuntime(Runtime::kArguments, 1, 1); | 1579 __ TailCallRuntime(Runtime::kArguments, 1, 1); |
1580 } | 1580 } |
1581 | 1581 |
1582 | 1582 |
1583 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 1583 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |
1584 // sp[0] : number of parameters | 1584 // r4 : function |
1585 // sp[1] : receiver displacement | 1585 // r5 : number of parameters (tagged) |
1586 // sp[2] : function | 1586 // r6 : parameters pointer |
| 1587 |
| 1588 DCHECK(r4.is(ArgumentsAccessNewDescriptor::function())); |
| 1589 DCHECK(r5.is(ArgumentsAccessNewDescriptor::parameter_count())); |
| 1590 DCHECK(r6.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
1587 | 1591 |
1588 // Check if the calling frame is an arguments adaptor frame. | 1592 // Check if the calling frame is an arguments adaptor frame. |
1589 Label runtime; | 1593 Label runtime; |
1590 __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1594 __ LoadP(r7, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1591 __ LoadP(r5, MemOperand(r6, StandardFrameConstants::kContextOffset)); | 1595 __ LoadP(r3, MemOperand(r7, StandardFrameConstants::kContextOffset)); |
1592 STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu); | 1596 __ CmpSmiLiteral(r3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
1593 __ CmpSmiLiteral(r5, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | |
1594 __ bne(&runtime); | 1597 __ bne(&runtime); |
1595 | 1598 |
1596 // Patch the arguments.length and the parameters pointer in the current frame. | 1599 // Patch the arguments.length and the parameters pointer in the current frame. |
1597 __ LoadP(r5, MemOperand(r6, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1600 __ LoadP(r5, MemOperand(r7, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1598 __ StoreP(r5, MemOperand(sp, 0 * kPointerSize)); | 1601 __ SmiToPtrArrayOffset(r6, r5); |
1599 __ SmiToPtrArrayOffset(r5, r5); | 1602 __ add(r6, r6, r7); |
1600 __ add(r6, r6, r5); | |
1601 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); | 1603 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); |
1602 __ StoreP(r6, MemOperand(sp, 1 * kPointerSize)); | |
1603 | 1604 |
1604 __ bind(&runtime); | 1605 __ bind(&runtime); |
| 1606 __ Push(r4, r6, r5); |
1605 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 1607 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
1606 } | 1608 } |
1607 | 1609 |
1608 | 1610 |
1609 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 1611 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
1610 // Stack layout: | 1612 // r4 : function |
1611 // sp[0] : number of parameters (tagged) | 1613 // r5 : number of parameters (tagged) |
1612 // sp[1] : address of receiver argument | 1614 // r6 : parameters pointer |
1613 // sp[2] : function | |
1614 // Registers used over whole function: | 1615 // Registers used over whole function: |
1615 // r9 : allocated object (tagged) | 1616 // r8 : arguments count (tagged) |
1616 // r11 : mapped parameter count (tagged) | 1617 // r9 : mapped parameter count (tagged) |
1617 | 1618 |
1618 __ LoadP(r4, MemOperand(sp, 0 * kPointerSize)); | 1619 DCHECK(r4.is(ArgumentsAccessNewDescriptor::function())); |
1619 // r4 = parameter count (tagged) | 1620 DCHECK(r5.is(ArgumentsAccessNewDescriptor::parameter_count())); |
| 1621 DCHECK(r6.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
1620 | 1622 |
1621 // Check if the calling frame is an arguments adaptor frame. | 1623 // Check if the calling frame is an arguments adaptor frame. |
1622 Label runtime; | 1624 Label adaptor_frame, try_allocate, runtime; |
1623 Label adaptor_frame, try_allocate; | 1625 __ LoadP(r7, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1624 __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1626 __ LoadP(r3, MemOperand(r7, StandardFrameConstants::kContextOffset)); |
1625 __ LoadP(r5, MemOperand(r6, StandardFrameConstants::kContextOffset)); | 1627 __ CmpSmiLiteral(r3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
1626 STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu); | |
1627 __ CmpSmiLiteral(r5, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | |
1628 __ beq(&adaptor_frame); | 1628 __ beq(&adaptor_frame); |
1629 | 1629 |
1630 // No adaptor, parameter count = argument count. | 1630 // No adaptor, parameter count = argument count. |
1631 __ mr(r5, r4); | 1631 __ mr(r8, r5); |
| 1632 __ mr(r9, r5); |
1632 __ b(&try_allocate); | 1633 __ b(&try_allocate); |
1633 | 1634 |
1634 // We have an adaptor frame. Patch the parameters pointer. | 1635 // We have an adaptor frame. Patch the parameters pointer. |
1635 __ bind(&adaptor_frame); | 1636 __ bind(&adaptor_frame); |
1636 __ LoadP(r5, MemOperand(r6, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1637 __ LoadP(r8, MemOperand(r7, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1637 __ SmiToPtrArrayOffset(r7, r5); | 1638 __ SmiToPtrArrayOffset(r6, r8); |
1638 __ add(r6, r6, r7); | 1639 __ add(r6, r6, r7); |
1639 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); | 1640 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); |
1640 __ StoreP(r6, MemOperand(sp, 1 * kPointerSize)); | |
1641 | 1641 |
1642 // r4 = parameter count (tagged) | 1642 // r8 = argument count (tagged) |
1643 // r5 = argument count (tagged) | 1643 // r9 = parameter count (tagged) |
1644 // Compute the mapped parameter count = min(r4, r5) in r4. | 1644 // Compute the mapped parameter count = min(r5, r8) in r9. |
1645 __ cmp(r4, r5); | 1645 __ cmp(r5, r8); |
1646 if (CpuFeatures::IsSupported(ISELECT)) { | 1646 if (CpuFeatures::IsSupported(ISELECT)) { |
1647 __ isel(lt, r4, r4, r5); | 1647 __ isel(lt, r9, r5, r8); |
1648 } else { | 1648 } else { |
1649 Label skip; | 1649 Label skip; |
| 1650 __ mr(r9, r5); |
1650 __ blt(&skip); | 1651 __ blt(&skip); |
1651 __ mr(r4, r5); | 1652 __ mr(r9, r8); |
1652 __ bind(&skip); | 1653 __ bind(&skip); |
1653 } | 1654 } |
1654 | 1655 |
1655 __ bind(&try_allocate); | 1656 __ bind(&try_allocate); |
1656 | 1657 |
1657 // Compute the sizes of backing store, parameter map, and arguments object. | 1658 // Compute the sizes of backing store, parameter map, and arguments object. |
1658 // 1. Parameter map, has 2 extra words containing context and backing store. | 1659 // 1. Parameter map, has 2 extra words containing context and backing store. |
1659 const int kParameterMapHeaderSize = | 1660 const int kParameterMapHeaderSize = |
1660 FixedArray::kHeaderSize + 2 * kPointerSize; | 1661 FixedArray::kHeaderSize + 2 * kPointerSize; |
1661 // If there are no mapped parameters, we do not need the parameter_map. | 1662 // If there are no mapped parameters, we do not need the parameter_map. |
1662 __ CmpSmiLiteral(r4, Smi::FromInt(0), r0); | 1663 __ CmpSmiLiteral(r9, Smi::FromInt(0), r0); |
1663 if (CpuFeatures::IsSupported(ISELECT)) { | 1664 if (CpuFeatures::IsSupported(ISELECT)) { |
1664 __ SmiToPtrArrayOffset(r11, r4); | 1665 __ SmiToPtrArrayOffset(r11, r9); |
1665 __ addi(r11, r11, Operand(kParameterMapHeaderSize)); | 1666 __ addi(r11, r11, Operand(kParameterMapHeaderSize)); |
1666 __ isel(eq, r11, r0, r11); | 1667 __ isel(eq, r11, r0, r11); |
1667 } else { | 1668 } else { |
1668 Label skip2, skip3; | 1669 Label skip2, skip3; |
1669 __ bne(&skip2); | 1670 __ bne(&skip2); |
1670 __ li(r11, Operand::Zero()); | 1671 __ li(r11, Operand::Zero()); |
1671 __ b(&skip3); | 1672 __ b(&skip3); |
1672 __ bind(&skip2); | 1673 __ bind(&skip2); |
1673 __ SmiToPtrArrayOffset(r11, r4); | 1674 __ SmiToPtrArrayOffset(r11, r9); |
1674 __ addi(r11, r11, Operand(kParameterMapHeaderSize)); | 1675 __ addi(r11, r11, Operand(kParameterMapHeaderSize)); |
1675 __ bind(&skip3); | 1676 __ bind(&skip3); |
1676 } | 1677 } |
1677 | 1678 |
1678 // 2. Backing store. | 1679 // 2. Backing store. |
1679 __ SmiToPtrArrayOffset(r7, r5); | 1680 __ SmiToPtrArrayOffset(r7, r8); |
1680 __ add(r11, r11, r7); | 1681 __ add(r11, r11, r7); |
1681 __ addi(r11, r11, Operand(FixedArray::kHeaderSize)); | 1682 __ addi(r11, r11, Operand(FixedArray::kHeaderSize)); |
1682 | 1683 |
1683 // 3. Arguments object. | 1684 // 3. Arguments object. |
1684 __ addi(r11, r11, Operand(Heap::kSloppyArgumentsObjectSize)); | 1685 __ addi(r11, r11, Operand(Heap::kSloppyArgumentsObjectSize)); |
1685 | 1686 |
1686 // Do the allocation of all three objects in one go. | 1687 // Do the allocation of all three objects in one go. |
1687 __ Allocate(r11, r3, r6, r7, &runtime, TAG_OBJECT); | 1688 __ Allocate(r11, r3, r7, r11, &runtime, TAG_OBJECT); |
1688 | 1689 |
1689 // r3 = address of new object(s) (tagged) | 1690 // r3 = address of new object(s) (tagged) |
1690 // r5 = argument count (smi-tagged) | 1691 // r5 = argument count (smi-tagged) |
1691 // Get the arguments boilerplate from the current native context into r4. | 1692 // Get the arguments boilerplate from the current native context into r4. |
1692 const int kNormalOffset = | 1693 const int kNormalOffset = |
1693 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); | 1694 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX); |
1694 const int kAliasedOffset = | 1695 const int kAliasedOffset = |
1695 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); | 1696 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); |
1696 | 1697 |
1697 __ LoadP(r7, | 1698 __ LoadP(r7, |
1698 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 1699 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
1699 __ LoadP(r7, FieldMemOperand(r7, GlobalObject::kNativeContextOffset)); | 1700 __ LoadP(r7, FieldMemOperand(r7, GlobalObject::kNativeContextOffset)); |
1700 __ cmpi(r4, Operand::Zero()); | 1701 __ cmpi(r9, Operand::Zero()); |
1701 if (CpuFeatures::IsSupported(ISELECT)) { | 1702 if (CpuFeatures::IsSupported(ISELECT)) { |
1702 __ LoadP(r11, MemOperand(r7, kNormalOffset)); | 1703 __ LoadP(r11, MemOperand(r7, kNormalOffset)); |
1703 __ LoadP(r7, MemOperand(r7, kAliasedOffset)); | 1704 __ LoadP(r7, MemOperand(r7, kAliasedOffset)); |
1704 __ isel(eq, r7, r11, r7); | 1705 __ isel(eq, r7, r11, r7); |
1705 } else { | 1706 } else { |
1706 Label skip4, skip5; | 1707 Label skip4, skip5; |
1707 __ bne(&skip4); | 1708 __ bne(&skip4); |
1708 __ LoadP(r7, MemOperand(r7, kNormalOffset)); | 1709 __ LoadP(r7, MemOperand(r7, kNormalOffset)); |
1709 __ b(&skip5); | 1710 __ b(&skip5); |
1710 __ bind(&skip4); | 1711 __ bind(&skip4); |
1711 __ LoadP(r7, MemOperand(r7, kAliasedOffset)); | 1712 __ LoadP(r7, MemOperand(r7, kAliasedOffset)); |
1712 __ bind(&skip5); | 1713 __ bind(&skip5); |
1713 } | 1714 } |
1714 | 1715 |
1715 // r3 = address of new object (tagged) | 1716 // r3 = address of new object (tagged) |
1716 // r4 = mapped parameter count (tagged) | |
1717 // r5 = argument count (smi-tagged) | 1717 // r5 = argument count (smi-tagged) |
1718 // r7 = address of arguments map (tagged) | 1718 // r7 = address of arguments map (tagged) |
| 1719 // r9 = mapped parameter count (tagged) |
1719 __ StoreP(r7, FieldMemOperand(r3, JSObject::kMapOffset), r0); | 1720 __ StoreP(r7, FieldMemOperand(r3, JSObject::kMapOffset), r0); |
1720 __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex); | 1721 __ LoadRoot(r11, Heap::kEmptyFixedArrayRootIndex); |
1721 __ StoreP(r6, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); | 1722 __ StoreP(r11, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); |
1722 __ StoreP(r6, FieldMemOperand(r3, JSObject::kElementsOffset), r0); | 1723 __ StoreP(r11, FieldMemOperand(r3, JSObject::kElementsOffset), r0); |
1723 | 1724 |
1724 // Set up the callee in-object property. | 1725 // Set up the callee in-object property. |
1725 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | 1726 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); |
1726 __ LoadP(r6, MemOperand(sp, 2 * kPointerSize)); | 1727 __ AssertNotSmi(r4); |
1727 __ AssertNotSmi(r6); | |
1728 const int kCalleeOffset = | 1728 const int kCalleeOffset = |
1729 JSObject::kHeaderSize + Heap::kArgumentsCalleeIndex * kPointerSize; | 1729 JSObject::kHeaderSize + Heap::kArgumentsCalleeIndex * kPointerSize; |
1730 __ StoreP(r6, FieldMemOperand(r3, kCalleeOffset), r0); | 1730 __ StoreP(r4, FieldMemOperand(r3, kCalleeOffset), r0); |
1731 | 1731 |
1732 // Use the length (smi tagged) and set that as an in-object property too. | 1732 // Use the length (smi tagged) and set that as an in-object property too. |
1733 __ AssertSmi(r5); | 1733 __ AssertSmi(r8); |
1734 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 1734 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
1735 const int kLengthOffset = | 1735 const int kLengthOffset = |
1736 JSObject::kHeaderSize + Heap::kArgumentsLengthIndex * kPointerSize; | 1736 JSObject::kHeaderSize + Heap::kArgumentsLengthIndex * kPointerSize; |
1737 __ StoreP(r5, FieldMemOperand(r3, kLengthOffset), r0); | 1737 __ StoreP(r8, FieldMemOperand(r3, kLengthOffset), r0); |
1738 | 1738 |
1739 // Set up the elements pointer in the allocated arguments object. | 1739 // Set up the elements pointer in the allocated arguments object. |
1740 // If we allocated a parameter map, r7 will point there, otherwise | 1740 // If we allocated a parameter map, r7 will point there, otherwise |
1741 // it will point to the backing store. | 1741 // it will point to the backing store. |
1742 __ addi(r7, r3, Operand(Heap::kSloppyArgumentsObjectSize)); | 1742 __ addi(r7, r3, Operand(Heap::kSloppyArgumentsObjectSize)); |
1743 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); | 1743 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); |
1744 | 1744 |
1745 // r3 = address of new object (tagged) | 1745 // r3 = address of new object (tagged) |
1746 // r4 = mapped parameter count (tagged) | |
1747 // r5 = argument count (tagged) | 1746 // r5 = argument count (tagged) |
1748 // r7 = address of parameter map or backing store (tagged) | 1747 // r7 = address of parameter map or backing store (tagged) |
| 1748 // r9 = mapped parameter count (tagged) |
1749 // Initialize parameter map. If there are no mapped arguments, we're done. | 1749 // Initialize parameter map. If there are no mapped arguments, we're done. |
1750 Label skip_parameter_map; | 1750 Label skip_parameter_map; |
1751 __ CmpSmiLiteral(r4, Smi::FromInt(0), r0); | 1751 __ CmpSmiLiteral(r9, Smi::FromInt(0), r0); |
1752 if (CpuFeatures::IsSupported(ISELECT)) { | 1752 if (CpuFeatures::IsSupported(ISELECT)) { |
1753 __ isel(eq, r6, r7, r6); | 1753 __ isel(eq, r4, r7, r4); |
1754 __ beq(&skip_parameter_map); | 1754 __ beq(&skip_parameter_map); |
1755 } else { | 1755 } else { |
1756 Label skip6; | 1756 Label skip6; |
1757 __ bne(&skip6); | 1757 __ bne(&skip6); |
1758 // Move backing store address to r6, because it is | 1758 // Move backing store address to r4, because it is |
1759 // expected there when filling in the unmapped arguments. | 1759 // expected there when filling in the unmapped arguments. |
1760 __ mr(r6, r7); | 1760 __ mr(r4, r7); |
1761 __ b(&skip_parameter_map); | 1761 __ b(&skip_parameter_map); |
1762 __ bind(&skip6); | 1762 __ bind(&skip6); |
1763 } | 1763 } |
1764 | 1764 |
1765 __ LoadRoot(r9, Heap::kSloppyArgumentsElementsMapRootIndex); | 1765 __ LoadRoot(r8, Heap::kSloppyArgumentsElementsMapRootIndex); |
1766 __ StoreP(r9, FieldMemOperand(r7, FixedArray::kMapOffset), r0); | 1766 __ StoreP(r8, FieldMemOperand(r7, FixedArray::kMapOffset), r0); |
1767 __ AddSmiLiteral(r9, r4, Smi::FromInt(2), r0); | 1767 __ AddSmiLiteral(r8, r9, Smi::FromInt(2), r0); |
1768 __ StoreP(r9, FieldMemOperand(r7, FixedArray::kLengthOffset), r0); | 1768 __ StoreP(r8, FieldMemOperand(r7, FixedArray::kLengthOffset), r0); |
1769 __ StoreP(cp, FieldMemOperand(r7, FixedArray::kHeaderSize + 0 * kPointerSize), | 1769 __ StoreP(cp, FieldMemOperand(r7, FixedArray::kHeaderSize + 0 * kPointerSize), |
1770 r0); | 1770 r0); |
1771 __ SmiToPtrArrayOffset(r9, r4); | 1771 __ SmiToPtrArrayOffset(r8, r9); |
1772 __ add(r9, r7, r9); | 1772 __ add(r8, r8, r7); |
1773 __ addi(r9, r9, Operand(kParameterMapHeaderSize)); | 1773 __ addi(r8, r8, Operand(kParameterMapHeaderSize)); |
1774 __ StoreP(r9, FieldMemOperand(r7, FixedArray::kHeaderSize + 1 * kPointerSize), | 1774 __ StoreP(r8, FieldMemOperand(r7, FixedArray::kHeaderSize + 1 * kPointerSize), |
1775 r0); | 1775 r0); |
1776 | 1776 |
1777 // Copy the parameter slots and the holes in the arguments. | 1777 // Copy the parameter slots and the holes in the arguments. |
1778 // We need to fill in mapped_parameter_count slots. They index the context, | 1778 // We need to fill in mapped_parameter_count slots. They index the context, |
1779 // where parameters are stored in reverse order, at | 1779 // where parameters are stored in reverse order, at |
1780 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 | 1780 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 |
1781 // The mapped parameter thus need to get indices | 1781 // The mapped parameter thus need to get indices |
1782 // MIN_CONTEXT_SLOTS+parameter_count-1 .. | 1782 // MIN_CONTEXT_SLOTS+parameter_count-1 .. |
1783 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count | 1783 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count |
1784 // We loop from right to left. | 1784 // We loop from right to left. |
1785 Label parameters_loop, parameters_test; | 1785 Label parameters_loop; |
1786 __ mr(r9, r4); | 1786 __ mr(r8, r9); |
1787 __ LoadP(r11, MemOperand(sp, 0 * kPointerSize)); | 1787 __ AddSmiLiteral(r11, r5, Smi::FromInt(Context::MIN_CONTEXT_SLOTS), r0); |
1788 __ AddSmiLiteral(r11, r11, Smi::FromInt(Context::MIN_CONTEXT_SLOTS), r0); | 1788 __ sub(r11, r11, r9); |
1789 __ sub(r11, r11, r4); | 1789 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
1790 __ LoadRoot(r10, Heap::kTheHoleValueRootIndex); | 1790 __ SmiToPtrArrayOffset(r4, r8); |
1791 __ SmiToPtrArrayOffset(r6, r9); | 1791 __ add(r4, r4, r7); |
1792 __ add(r6, r7, r6); | 1792 __ addi(r4, r4, Operand(kParameterMapHeaderSize)); |
1793 __ addi(r6, r6, Operand(kParameterMapHeaderSize)); | |
1794 | 1793 |
1795 // r9 = loop variable (tagged) | 1794 // r4 = address of backing store (tagged) |
1796 // r4 = mapping index (tagged) | |
1797 // r6 = address of backing store (tagged) | |
1798 // r7 = address of parameter map (tagged) | 1795 // r7 = address of parameter map (tagged) |
1799 // r8 = temporary scratch (a.o., for address calculation) | 1796 // r8 = temporary scratch (a.o., for address calculation) |
1800 // r10 = the hole value | 1797 // r10 = temporary scratch (a.o., for address calculation) |
1801 __ b(¶meters_test); | 1798 // ip = the hole value |
| 1799 __ SmiUntag(r8); |
| 1800 __ mtctr(r8); |
| 1801 __ ShiftLeftImm(r8, r8, Operand(kPointerSizeLog2)); |
| 1802 __ add(r10, r4, r8); |
| 1803 __ add(r8, r7, r8); |
| 1804 __ addi(r10, r10, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1805 __ addi(r8, r8, Operand(kParameterMapHeaderSize - kHeapObjectTag)); |
1802 | 1806 |
1803 __ bind(¶meters_loop); | 1807 __ bind(¶meters_loop); |
1804 __ SubSmiLiteral(r9, r9, Smi::FromInt(1), r0); | 1808 __ StorePU(r11, MemOperand(r8, -kPointerSize)); |
1805 __ SmiToPtrArrayOffset(r8, r9); | 1809 __ StorePU(ip, MemOperand(r10, -kPointerSize)); |
1806 __ addi(r8, r8, Operand(kParameterMapHeaderSize - kHeapObjectTag)); | |
1807 __ StorePX(r11, MemOperand(r8, r7)); | |
1808 __ subi(r8, r8, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); | |
1809 __ StorePX(r10, MemOperand(r8, r6)); | |
1810 __ AddSmiLiteral(r11, r11, Smi::FromInt(1), r0); | 1810 __ AddSmiLiteral(r11, r11, Smi::FromInt(1), r0); |
1811 __ bind(¶meters_test); | 1811 __ bdnz(¶meters_loop); |
1812 __ CmpSmiLiteral(r9, Smi::FromInt(0), r0); | 1812 |
1813 __ bne(¶meters_loop); | 1813 // Restore r8 = argument count (tagged). |
| 1814 __ LoadP(r8, FieldMemOperand(r3, kLengthOffset)); |
1814 | 1815 |
1815 __ bind(&skip_parameter_map); | 1816 __ bind(&skip_parameter_map); |
1816 // r5 = argument count (tagged) | 1817 // r3 = address of new object (tagged) |
1817 // r6 = address of backing store (tagged) | 1818 // r4 = address of backing store (tagged) |
1818 // r8 = scratch | 1819 // r8 = argument count (tagged) |
| 1820 // r9 = mapped parameter count (tagged) |
| 1821 // r11 = scratch |
1819 // Copy arguments header and remaining slots (if there are any). | 1822 // Copy arguments header and remaining slots (if there are any). |
1820 __ LoadRoot(r8, Heap::kFixedArrayMapRootIndex); | 1823 __ LoadRoot(r11, Heap::kFixedArrayMapRootIndex); |
1821 __ StoreP(r8, FieldMemOperand(r6, FixedArray::kMapOffset), r0); | 1824 __ StoreP(r11, FieldMemOperand(r4, FixedArray::kMapOffset), r0); |
1822 __ StoreP(r5, FieldMemOperand(r6, FixedArray::kLengthOffset), r0); | 1825 __ StoreP(r8, FieldMemOperand(r4, FixedArray::kLengthOffset), r0); |
| 1826 __ sub(r11, r8, r9, LeaveOE, SetRC); |
| 1827 __ Ret(eq, cr0); |
1823 | 1828 |
1824 Label arguments_loop, arguments_test; | 1829 Label arguments_loop; |
1825 __ mr(r11, r4); | 1830 __ SmiUntag(r11); |
1826 __ LoadP(r7, MemOperand(sp, 1 * kPointerSize)); | 1831 __ mtctr(r11); |
1827 __ SmiToPtrArrayOffset(r8, r11); | 1832 |
1828 __ sub(r7, r7, r8); | 1833 __ SmiToPtrArrayOffset(r0, r9); |
1829 __ b(&arguments_test); | 1834 __ sub(r6, r6, r0); |
| 1835 __ add(r11, r4, r0); |
| 1836 __ addi(r11, r11, |
| 1837 Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); |
1830 | 1838 |
1831 __ bind(&arguments_loop); | 1839 __ bind(&arguments_loop); |
1832 __ subi(r7, r7, Operand(kPointerSize)); | 1840 __ LoadPU(r7, MemOperand(r6, -kPointerSize)); |
1833 __ LoadP(r9, MemOperand(r7, 0)); | 1841 __ StorePU(r7, MemOperand(r11, kPointerSize)); |
1834 __ SmiToPtrArrayOffset(r8, r11); | 1842 __ bdnz(&arguments_loop); |
1835 __ add(r8, r6, r8); | |
1836 __ StoreP(r9, FieldMemOperand(r8, FixedArray::kHeaderSize), r0); | |
1837 __ AddSmiLiteral(r11, r11, Smi::FromInt(1), r0); | |
1838 | 1843 |
1839 __ bind(&arguments_test); | 1844 // Return. |
1840 __ cmp(r11, r5); | |
1841 __ blt(&arguments_loop); | |
1842 | |
1843 // Return and remove the on-stack parameters. | |
1844 __ addi(sp, sp, Operand(3 * kPointerSize)); | |
1845 __ Ret(); | 1845 __ Ret(); |
1846 | 1846 |
1847 // Do the runtime call to allocate the arguments object. | 1847 // Do the runtime call to allocate the arguments object. |
1848 // r5 = argument count (tagged) | 1848 // r8 = argument count (tagged) |
1849 __ bind(&runtime); | 1849 __ bind(&runtime); |
1850 __ StoreP(r5, MemOperand(sp, 0 * kPointerSize)); // Patch argument count. | 1850 __ Push(r4, r6, r8); |
1851 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); | 1851 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
1852 } | 1852 } |
1853 | 1853 |
1854 | 1854 |
1855 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 1855 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
1856 // Return address is in lr. | 1856 // Return address is in lr. |
1857 Label slow; | 1857 Label slow; |
1858 | 1858 |
1859 Register receiver = LoadDescriptor::ReceiverRegister(); | 1859 Register receiver = LoadDescriptor::ReceiverRegister(); |
1860 Register key = LoadDescriptor::NameRegister(); | 1860 Register key = LoadDescriptor::NameRegister(); |
1861 | 1861 |
1862 // Check that the key is an array index, that is Uint32. | 1862 // Check that the key is an array index, that is Uint32. |
1863 __ TestIfPositiveSmi(key, r0); | 1863 __ TestIfPositiveSmi(key, r0); |
1864 __ bne(&slow, cr0); | 1864 __ bne(&slow, cr0); |
1865 | 1865 |
1866 // Everything is fine, call runtime. | 1866 // Everything is fine, call runtime. |
1867 __ Push(receiver, key); // Receiver, key. | 1867 __ Push(receiver, key); // Receiver, key. |
1868 | 1868 |
1869 // Perform tail call to the entry. | 1869 // Perform tail call to the entry. |
1870 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2, 1); | 1870 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2, 1); |
1871 | 1871 |
1872 __ bind(&slow); | 1872 __ bind(&slow); |
1873 PropertyAccessCompiler::TailCallBuiltin( | 1873 PropertyAccessCompiler::TailCallBuiltin( |
1874 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 1874 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); |
1875 } | 1875 } |
1876 | 1876 |
1877 | 1877 |
1878 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | 1878 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { |
1879 // sp[0] : number of parameters | 1879 // r4 : function |
1880 // sp[4] : receiver displacement | 1880 // r5 : number of parameters (tagged) |
1881 // sp[8] : function | 1881 // r6 : parameters pointer |
| 1882 |
| 1883 DCHECK(r4.is(ArgumentsAccessNewDescriptor::function())); |
| 1884 DCHECK(r5.is(ArgumentsAccessNewDescriptor::parameter_count())); |
| 1885 DCHECK(r6.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
| 1886 |
1882 // Check if the calling frame is an arguments adaptor frame. | 1887 // Check if the calling frame is an arguments adaptor frame. |
1883 Label adaptor_frame, try_allocate, runtime; | 1888 Label try_allocate, runtime; |
1884 __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1889 __ LoadP(r7, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1885 __ LoadP(r6, MemOperand(r5, StandardFrameConstants::kContextOffset)); | 1890 __ LoadP(r3, MemOperand(r7, StandardFrameConstants::kContextOffset)); |
1886 STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu); | 1891 __ CmpSmiLiteral(r3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
1887 __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | 1892 __ bne(&try_allocate); |
1888 __ beq(&adaptor_frame); | |
1889 | |
1890 // Get the length from the frame. | |
1891 __ LoadP(r4, MemOperand(sp, 0)); | |
1892 __ b(&try_allocate); | |
1893 | 1893 |
1894 // Patch the arguments.length and the parameters pointer. | 1894 // Patch the arguments.length and the parameters pointer. |
1895 __ bind(&adaptor_frame); | 1895 __ LoadP(r5, MemOperand(r7, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1896 __ LoadP(r4, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1896 __ SmiToPtrArrayOffset(r6, r5); |
1897 __ StoreP(r4, MemOperand(sp, 0)); | 1897 __ add(r6, r6, r7); |
1898 __ SmiToPtrArrayOffset(r6, r4); | |
1899 __ add(r6, r5, r6); | |
1900 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); | 1898 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); |
1901 __ StoreP(r6, MemOperand(sp, 1 * kPointerSize)); | |
1902 | 1899 |
1903 // Try the new space allocation. Start out with computing the size | 1900 // Try the new space allocation. Start out with computing the size |
1904 // of the arguments object and the elements array in words. | 1901 // of the arguments object and the elements array in words. |
1905 Label add_arguments_object; | 1902 Label add_arguments_object; |
1906 __ bind(&try_allocate); | 1903 __ bind(&try_allocate); |
1907 __ cmpi(r4, Operand::Zero()); | 1904 __ SmiUntag(r11, r5, SetRC); |
1908 __ beq(&add_arguments_object); | 1905 __ beq(&add_arguments_object, cr0); |
1909 __ SmiUntag(r4); | 1906 __ addi(r11, r11, Operand(FixedArray::kHeaderSize / kPointerSize)); |
1910 __ addi(r4, r4, Operand(FixedArray::kHeaderSize / kPointerSize)); | |
1911 __ bind(&add_arguments_object); | 1907 __ bind(&add_arguments_object); |
1912 __ addi(r4, r4, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize)); | 1908 __ addi(r11, r11, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize)); |
1913 | 1909 |
1914 // Do the allocation of both objects in one go. | 1910 // Do the allocation of both objects in one go. |
1915 __ Allocate(r4, r3, r5, r6, &runtime, | 1911 __ Allocate(r11, r3, r7, r8, &runtime, |
1916 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); | 1912 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS)); |
1917 | 1913 |
1918 // Get the arguments boilerplate from the current native context. | 1914 // Get the arguments boilerplate from the current native context. |
1919 __ LoadP(r7, | 1915 __ LoadP(r7, |
1920 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 1916 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
1921 __ LoadP(r7, FieldMemOperand(r7, GlobalObject::kNativeContextOffset)); | 1917 __ LoadP(r7, FieldMemOperand(r7, GlobalObject::kNativeContextOffset)); |
1922 __ LoadP( | 1918 __ LoadP( |
1923 r7, | 1919 r7, |
1924 MemOperand(r7, Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX))); | 1920 MemOperand(r7, Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX))); |
1925 | 1921 |
1926 __ StoreP(r7, FieldMemOperand(r3, JSObject::kMapOffset), r0); | 1922 __ StoreP(r7, FieldMemOperand(r3, JSObject::kMapOffset), r0); |
1927 __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex); | 1923 __ LoadRoot(r8, Heap::kEmptyFixedArrayRootIndex); |
1928 __ StoreP(r6, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); | 1924 __ StoreP(r8, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0); |
1929 __ StoreP(r6, FieldMemOperand(r3, JSObject::kElementsOffset), r0); | 1925 __ StoreP(r8, FieldMemOperand(r3, JSObject::kElementsOffset), r0); |
1930 | 1926 |
1931 // Get the length (smi tagged) and set that as an in-object property too. | 1927 // Get the length (smi tagged) and set that as an in-object property too. |
1932 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 1928 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
1933 __ LoadP(r4, MemOperand(sp, 0 * kPointerSize)); | 1929 __ AssertSmi(r5); |
1934 __ AssertSmi(r4); | 1930 __ StoreP(r5, |
1935 __ StoreP(r4, | |
1936 FieldMemOperand(r3, JSObject::kHeaderSize + | 1931 FieldMemOperand(r3, JSObject::kHeaderSize + |
1937 Heap::kArgumentsLengthIndex * kPointerSize), | 1932 Heap::kArgumentsLengthIndex * kPointerSize), |
1938 r0); | 1933 r0); |
1939 | 1934 |
1940 // If there are no actual arguments, we're done. | 1935 // If there are no actual arguments, we're done. |
1941 Label done; | 1936 __ SmiUntag(r9, r5, SetRC); |
1942 __ cmpi(r4, Operand::Zero()); | 1937 __ Ret(eq, cr0); |
1943 __ beq(&done); | |
1944 | |
1945 // Get the parameters pointer from the stack. | |
1946 __ LoadP(r5, MemOperand(sp, 1 * kPointerSize)); | |
1947 | 1938 |
1948 // Set up the elements pointer in the allocated arguments object and | 1939 // Set up the elements pointer in the allocated arguments object and |
1949 // initialize the header in the elements fixed array. | 1940 // initialize the header in the elements fixed array. |
1950 __ addi(r7, r3, Operand(Heap::kStrictArgumentsObjectSize)); | 1941 __ addi(r7, r3, Operand(Heap::kStrictArgumentsObjectSize)); |
1951 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); | 1942 __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0); |
1952 __ LoadRoot(r6, Heap::kFixedArrayMapRootIndex); | 1943 __ LoadRoot(r8, Heap::kFixedArrayMapRootIndex); |
1953 __ StoreP(r6, FieldMemOperand(r7, FixedArray::kMapOffset), r0); | 1944 __ StoreP(r8, FieldMemOperand(r7, FixedArray::kMapOffset), r0); |
1954 __ StoreP(r4, FieldMemOperand(r7, FixedArray::kLengthOffset), r0); | 1945 __ StoreP(r5, FieldMemOperand(r7, FixedArray::kLengthOffset), r0); |
1955 // Untag the length for the loop. | |
1956 __ SmiUntag(r4); | |
1957 | 1946 |
1958 // Copy the fixed array slots. | 1947 // Copy the fixed array slots. |
1959 Label loop; | 1948 Label loop; |
1960 // Set up r7 to point just prior to the first array slot. | 1949 // Set up r7 to point just prior to the first array slot. |
1961 __ addi(r7, r7, | 1950 __ addi(r7, r7, |
1962 Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); | 1951 Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); |
1963 __ mtctr(r4); | 1952 __ mtctr(r9); |
1964 __ bind(&loop); | 1953 __ bind(&loop); |
1965 // Pre-decrement r5 with kPointerSize on each iteration. | 1954 // Pre-decrement r6 with kPointerSize on each iteration. |
1966 // Pre-decrement in order to skip receiver. | 1955 // Pre-decrement in order to skip receiver. |
1967 __ LoadPU(r6, MemOperand(r5, -kPointerSize)); | 1956 __ LoadPU(r8, MemOperand(r6, -kPointerSize)); |
1968 // Pre-increment r7 with kPointerSize on each iteration. | 1957 // Pre-increment r7 with kPointerSize on each iteration. |
1969 __ StorePU(r6, MemOperand(r7, kPointerSize)); | 1958 __ StorePU(r8, MemOperand(r7, kPointerSize)); |
1970 __ bdnz(&loop); | 1959 __ bdnz(&loop); |
1971 | 1960 |
1972 // Return and remove the on-stack parameters. | 1961 // Return. |
1973 __ bind(&done); | |
1974 __ addi(sp, sp, Operand(3 * kPointerSize)); | |
1975 __ Ret(); | 1962 __ Ret(); |
1976 | 1963 |
1977 // Do the runtime call to allocate the arguments object. | 1964 // Do the runtime call to allocate the arguments object. |
1978 __ bind(&runtime); | 1965 __ bind(&runtime); |
| 1966 __ Push(r4, r6, r5); |
1979 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); | 1967 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); |
1980 } | 1968 } |
1981 | 1969 |
1982 | 1970 |
1983 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1971 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1984 // Just jump directly to runtime if native RegExp is not selected at compile | 1972 // Just jump directly to runtime if native RegExp is not selected at compile |
1985 // time or if regexp entry in generated code is turned off runtime switch or | 1973 // time or if regexp entry in generated code is turned off runtime switch or |
1986 // at compilation. | 1974 // at compilation. |
1987 #ifdef V8_INTERPRETED_REGEXP | 1975 #ifdef V8_INTERPRETED_REGEXP |
1988 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 1976 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
(...skipping 3859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5848 kStackUnwindSpace, NULL, | 5836 kStackUnwindSpace, NULL, |
5849 MemOperand(fp, 6 * kPointerSize), NULL); | 5837 MemOperand(fp, 6 * kPointerSize), NULL); |
5850 } | 5838 } |
5851 | 5839 |
5852 | 5840 |
5853 #undef __ | 5841 #undef __ |
5854 } // namespace internal | 5842 } // namespace internal |
5855 } // namespace v8 | 5843 } // namespace v8 |
5856 | 5844 |
5857 #endif // V8_TARGET_ARCH_PPC | 5845 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |