| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1655 LoadValueCid(compiler, value_cid_reg, value_reg); | 1655 LoadValueCid(compiler, value_cid_reg, value_reg); |
| 1656 | 1656 |
| 1657 Label skip_length_check; | 1657 Label skip_length_check; |
| 1658 | 1658 |
| 1659 __ lw(CMPRES1, field_cid_operand); | 1659 __ lw(CMPRES1, field_cid_operand); |
| 1660 __ bne(value_cid_reg, CMPRES1, &skip_length_check); | 1660 __ bne(value_cid_reg, CMPRES1, &skip_length_check); |
| 1661 if (field_has_length) { | 1661 if (field_has_length) { |
| 1662 // Field guard may have remembered list length, check it. | 1662 // Field guard may have remembered list length, check it. |
| 1663 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1663 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { |
| 1664 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); | 1664 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); |
| 1665 __ LoadImmediate(CMPRES1, field_length); | 1665 __ LoadImmediate(CMPRES1, Smi::RawValue(field_length)); |
| 1666 __ subu(CMPRES1, TMP, CMPRES1); | 1666 __ subu(CMPRES1, TMP, CMPRES1); |
| 1667 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1667 } else if (RawObject::IsTypedDataClassId(field_cid)) { |
| 1668 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); | 1668 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); |
| 1669 __ LoadImmediate(CMPRES1, field_length); | 1669 __ LoadImmediate(CMPRES1, Smi::RawValue(field_length)); |
| 1670 __ subu(CMPRES1, TMP, CMPRES1); | 1670 __ subu(CMPRES1, TMP, CMPRES1); |
| 1671 } else { | 1671 } else { |
| 1672 ASSERT(field_cid == kIllegalCid); | 1672 ASSERT(field_cid == kIllegalCid); |
| 1673 __ LoadImmediate(CMPRES1, 0x1); | 1673 Label check_array, local_exit, local_fail; |
| 1674 __ BranchEqual(value_cid_reg, kNullCid, &local_fail); |
| 1675 // Check for typed data array. |
| 1676 __ BranchSignedGreater(value_cid_reg, kTypedDataFloat32x4ArrayCid, |
| 1677 &local_fail); |
| 1678 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid, |
| 1679 &check_array); |
| 1680 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); |
| 1681 __ lw(CMPRES1, field_length_operand); |
| 1682 __ subu(CMPRES1, TMP, CMPRES1); |
| 1683 __ b(&local_exit); |
| 1684 // Check for regular array. |
| 1685 __ Bind(&check_array); |
| 1686 __ BranchSignedGreater(value_cid_reg, kImmutableArrayCid, |
| 1687 &local_fail); |
| 1688 __ BranchSignedLess(value_cid_reg, kArrayCid, &local_fail); |
| 1689 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); |
| 1690 __ lw(CMPRES1, field_length_operand); |
| 1691 __ subu(CMPRES1, TMP, CMPRES1); |
| 1692 __ b(&local_exit); |
| 1693 |
| 1694 __ Bind(&local_fail); |
| 1695 // TODO(regis): TMP1 may conflict. Revisit. |
| 1696 __ LoadImmediate(TMP1, Smi::RawValue(Field::kNoFixedLength)); |
| 1697 __ sw(TMP1, field_length_operand); |
| 1698 |
| 1699 __ Bind(&local_exit); |
| 1674 } | 1700 } |
| 1675 __ bne(CMPRES1, ZR, fail); | 1701 __ bne(CMPRES1, ZR, fail); |
| 1676 } | 1702 } |
| 1677 __ Bind(&skip_length_check); | 1703 __ Bind(&skip_length_check); |
| 1678 __ lw(TMP1, field_nullability_operand); | 1704 __ lw(TMP1, field_nullability_operand); |
| 1679 __ subu(CMPRES, value_cid_reg, TMP1); | 1705 __ subu(CMPRES, value_cid_reg, TMP1); |
| 1680 } else if (value_cid == kNullCid) { | 1706 } else if (value_cid == kNullCid) { |
| 1681 // TODO(regis): TMP1 may conflict. Revisit. | 1707 // TODO(regis): TMP1 may conflict. Revisit. |
| 1682 __ lw(TMP1, field_nullability_operand); | 1708 __ lw(TMP1, field_nullability_operand); |
| 1683 __ LoadImmediate(CMPRES, value_cid); | 1709 __ LoadImmediate(CMPRES, value_cid); |
| 1684 __ subu(CMPRES, TMP1, CMPRES); | 1710 __ subu(CMPRES, TMP1, CMPRES); |
| 1685 } else { | 1711 } else { |
| 1686 Label skip_length_check; | 1712 Label skip_length_check; |
| 1687 // TODO(regis): TMP1 may conflict. Revisit. | 1713 // TODO(regis): TMP1 may conflict. Revisit. |
| 1688 __ lw(TMP1, field_cid_operand); | 1714 __ lw(TMP1, field_cid_operand); |
| 1689 __ LoadImmediate(CMPRES, value_cid); | 1715 __ LoadImmediate(CMPRES, value_cid); |
| 1690 __ subu(CMPRES, TMP1, CMPRES); | 1716 __ subu(CMPRES, TMP1, CMPRES); |
| 1691 __ bne(CMPRES, ZR, &skip_length_check); | 1717 __ bne(CMPRES, ZR, &skip_length_check); |
| 1692 // Insert length check. | 1718 // Insert length check. |
| 1693 if (field_has_length) { | 1719 if (field_has_length) { |
| 1694 if (value_cid_reg == kNoRegister) { | 1720 if (value_cid_reg == kNoRegister) { |
| 1695 ASSERT(!compiler->is_optimizing()); | 1721 ASSERT(!compiler->is_optimizing()); |
| 1696 value_cid_reg = A1; | 1722 value_cid_reg = A1; |
| 1697 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); | 1723 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); |
| 1698 } | 1724 } |
| 1699 ASSERT(value_cid_reg != kNoRegister); | 1725 ASSERT(value_cid_reg != kNoRegister); |
| 1700 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1726 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { |
| 1701 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); | 1727 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); |
| 1702 __ LoadImmediate(CMPRES, field_length); | 1728 __ LoadImmediate(CMPRES, Smi::RawValue(field_length)); |
| 1703 __ subu(CMPRES, TMP, CMPRES); | 1729 __ subu(CMPRES, TMP, CMPRES); |
| 1704 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1730 } else if (RawObject::IsTypedDataClassId(value_cid)) { |
| 1705 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); | 1731 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); |
| 1706 __ LoadImmediate(CMPRES, field_length); | 1732 __ LoadImmediate(CMPRES, Smi::RawValue(field_length)); |
| 1707 __ subu(CMPRES, TMP, CMPRES); | 1733 __ subu(CMPRES, TMP, CMPRES); |
| 1708 } else { | 1734 } else { |
| 1709 ASSERT(field_cid == kIllegalCid); | 1735 ASSERT(field_cid == kIllegalCid); |
| 1710 __ LoadImmediate(CMPRES, 0x1); | |
| 1711 } | 1736 } |
| 1737 __ bne(CMPRES, ZR, fail); |
| 1712 } | 1738 } |
| 1713 __ Bind(&skip_length_check); | 1739 __ Bind(&skip_length_check); |
| 1714 } | 1740 } |
| 1715 __ beq(CMPRES, ZR, &ok); | 1741 __ beq(CMPRES, ZR, &ok); |
| 1716 | 1742 |
| 1717 __ lw(CMPRES1, field_cid_operand); | 1743 __ lw(CMPRES1, field_cid_operand); |
| 1718 __ BranchNotEqual(CMPRES1, kIllegalCid, fail); | 1744 __ BranchNotEqual(CMPRES1, kIllegalCid, fail); |
| 1719 | 1745 |
| 1720 if (value_cid == kDynamicCid) { | 1746 if (value_cid == kDynamicCid) { |
| 1721 __ sw(value_cid_reg, field_cid_operand); | 1747 __ sw(value_cid_reg, field_cid_operand); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1739 &local_fail); | 1765 &local_fail); |
| 1740 __ BranchSignedLess(value_cid_reg, kArrayCid, &local_fail); | 1766 __ BranchSignedLess(value_cid_reg, kArrayCid, &local_fail); |
| 1741 // Destroy value_cid_reg (safe because we are finished with it). | 1767 // Destroy value_cid_reg (safe because we are finished with it). |
| 1742 __ lw(value_cid_reg, | 1768 __ lw(value_cid_reg, |
| 1743 FieldAddress(value_reg, Array::length_offset())); | 1769 FieldAddress(value_reg, Array::length_offset())); |
| 1744 __ sw(value_cid_reg, field_length_operand); | 1770 __ sw(value_cid_reg, field_length_operand); |
| 1745 __ b(&local_exit); // Updated field length from regular array. | 1771 __ b(&local_exit); // Updated field length from regular array. |
| 1746 | 1772 |
| 1747 __ Bind(&local_fail); | 1773 __ Bind(&local_fail); |
| 1748 // TODO(regis): TMP1 may conflict. Revisit. | 1774 // TODO(regis): TMP1 may conflict. Revisit. |
| 1749 __ LoadImmediate(TMP1, Field::kNoFixedLength); | 1775 __ LoadImmediate(TMP1, Smi::RawValue(Field::kNoFixedLength)); |
| 1750 __ sw(TMP1, field_length_operand); | 1776 __ sw(TMP1, field_length_operand); |
| 1751 | 1777 |
| 1752 __ Bind(&local_exit); | 1778 __ Bind(&local_exit); |
| 1753 } | 1779 } |
| 1754 } else { | 1780 } else { |
| 1755 if (value_cid_reg == kNoRegister) { | 1781 if (value_cid_reg == kNoRegister) { |
| 1756 ASSERT(!compiler->is_optimizing()); | 1782 ASSERT(!compiler->is_optimizing()); |
| 1757 value_cid_reg = A1; | 1783 value_cid_reg = A1; |
| 1758 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); | 1784 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); |
| 1759 } | 1785 } |
| 1760 ASSERT(value_cid_reg != kNoRegister); | 1786 ASSERT(value_cid_reg != kNoRegister); |
| 1761 ASSERT(field_reg != kNoRegister); | 1787 ASSERT(field_reg != kNoRegister); |
| 1762 __ LoadImmediate(TMP1, value_cid); | 1788 __ LoadImmediate(TMP1, value_cid); |
| 1763 __ sw(TMP1, field_cid_operand); | 1789 __ sw(TMP1, field_cid_operand); |
| 1764 __ sw(TMP1, field_nullability_operand); | 1790 __ sw(TMP1, field_nullability_operand); |
| 1765 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { | 1791 if (field_has_length) { |
| 1766 // Destroy value_cid_reg (safe because we are finished with it). | 1792 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { |
| 1767 __ lw(value_cid_reg, | 1793 // Destroy value_cid_reg (safe because we are finished with it). |
| 1768 FieldAddress(value_reg, Array::length_offset())); | 1794 __ lw(value_cid_reg, |
| 1769 __ sw(value_cid_reg, field_length_operand); | 1795 FieldAddress(value_reg, Array::length_offset())); |
| 1770 } else if (RawObject::IsTypedDataClassId(value_cid)) { | 1796 __ sw(value_cid_reg, field_length_operand); |
| 1771 // Destroy value_cid_reg (safe because we are finished with it). | 1797 } else if (RawObject::IsTypedDataClassId(value_cid)) { |
| 1772 __ lw(value_cid_reg, | 1798 // Destroy value_cid_reg (safe because we are finished with it). |
| 1773 FieldAddress(value_reg, TypedData::length_offset())); | 1799 __ lw(value_cid_reg, |
| 1774 __ sw(value_cid_reg, field_length_operand); | 1800 FieldAddress(value_reg, TypedData::length_offset())); |
| 1775 } else { | 1801 __ sw(value_cid_reg, field_length_operand); |
| 1776 // Destroy value_cid_reg (safe because we are finished with it). | 1802 } else { |
| 1777 __ LoadImmediate(value_cid_reg, Field::kNoFixedLength); | 1803 // Destroy value_cid_reg (safe because we are finished with it). |
| 1778 __ sw(value_cid_reg, field_length_operand); | 1804 __ LoadImmediate(value_cid_reg, Smi::RawValue(Field::kNoFixedLength)); |
| 1805 __ sw(value_cid_reg, field_length_operand); |
| 1806 } |
| 1779 } | 1807 } |
| 1780 } | 1808 } |
| 1781 | |
| 1782 if (!ok_is_fall_through) { | 1809 if (!ok_is_fall_through) { |
| 1783 __ b(&ok); | 1810 __ b(&ok); |
| 1784 } | 1811 } |
| 1785 } else { | 1812 } else { |
| 1786 if (field_reg != kNoRegister) { | 1813 if (field_reg != kNoRegister) { |
| 1787 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); | 1814 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); |
| 1788 } | 1815 } |
| 1789 if (value_cid == kDynamicCid) { | 1816 if (value_cid == kDynamicCid) { |
| 1790 // Field's guarded class id is fixed by value's class id is not known. | 1817 // Field's guarded class id is fixed by value's class id is not known. |
| 1791 __ andi(CMPRES, value_reg, Immediate(kSmiTagMask)); | 1818 __ andi(CMPRES, value_reg, Immediate(kSmiTagMask)); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1839 ASSERT(value_cid_reg != kNoRegister); | 1866 ASSERT(value_cid_reg != kNoRegister); |
| 1840 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1867 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { |
| 1841 // Destroy value_cid_reg (safe because we are finished with it). | 1868 // Destroy value_cid_reg (safe because we are finished with it). |
| 1842 __ lw(value_cid_reg, | 1869 __ lw(value_cid_reg, |
| 1843 FieldAddress(value_reg, Array::length_offset())); | 1870 FieldAddress(value_reg, Array::length_offset())); |
| 1844 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1871 } else if (RawObject::IsTypedDataClassId(field_cid)) { |
| 1845 // Destroy value_cid_reg (safe because we are finished with it). | 1872 // Destroy value_cid_reg (safe because we are finished with it). |
| 1846 __ lw(value_cid_reg, | 1873 __ lw(value_cid_reg, |
| 1847 FieldAddress(value_reg, TypedData::length_offset())); | 1874 FieldAddress(value_reg, TypedData::length_offset())); |
| 1848 } | 1875 } |
| 1849 __ LoadImmediate(TMP1, field_length); | 1876 __ LoadImmediate(TMP1, Smi::RawValue(field_length)); |
| 1850 __ subu(CMPRES, value_cid_reg, TMP1); | 1877 __ subu(CMPRES, value_cid_reg, TMP1); |
| 1851 if (ok_is_fall_through) { | 1878 if (ok_is_fall_through) { |
| 1852 __ bne(CMPRES, ZR, fail); | 1879 __ bne(CMPRES, ZR, fail); |
| 1853 } | 1880 } |
| 1854 } else { | 1881 } else { |
| 1855 // Nothing to emit. | 1882 // Nothing to emit. |
| 1856 ASSERT(!compiler->is_optimizing()); | 1883 ASSERT(!compiler->is_optimizing()); |
| 1857 return; | 1884 return; |
| 1858 } | 1885 } |
| 1859 } | 1886 } |
| (...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4127 compiler->GenerateCall(token_pos(), | 4154 compiler->GenerateCall(token_pos(), |
| 4128 &label, | 4155 &label, |
| 4129 PcDescriptors::kOther, | 4156 PcDescriptors::kOther, |
| 4130 locs()); | 4157 locs()); |
| 4131 __ Drop(2); // Discard type arguments and receiver. | 4158 __ Drop(2); // Discard type arguments and receiver. |
| 4132 } | 4159 } |
| 4133 | 4160 |
| 4134 } // namespace dart | 4161 } // namespace dart |
| 4135 | 4162 |
| 4136 #endif // defined TARGET_ARCH_MIPS | 4163 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |