Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 150063004: Support reusable boxes for Float32x4 fields (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after
1574 __ b(fail, NE); 1574 __ b(fail, NE);
1575 } else { 1575 } else {
1576 UNREACHABLE(); 1576 UNREACHABLE();
1577 } 1577 }
1578 } 1578 }
1579 } 1579 }
1580 __ Bind(&ok); 1580 __ Bind(&ok);
1581 } 1581 }
1582 1582
1583 1583
1584 bool Field::IsUnboxedField() const {
Florian Schneider 2014/02/06 12:38:49 Maybe this should still be in object.cc? In this c
srdjan 2014/02/06 16:55:31 I do not like architecture dependent code in share
Cutch 2014/02/06 23:15:38 Done.
1585 bool valid_class = (guarded_cid() == kDoubleCid) ||
1586 (guarded_cid() == kFloat32x4Cid);
1587 return is_unboxing_candidate() && !is_final() && !is_nullable() &&
1588 valid_class;
1589 }
1590
1591
1584 class StoreInstanceFieldSlowPath : public SlowPathCode { 1592 class StoreInstanceFieldSlowPath : public SlowPathCode {
1585 public: 1593 public:
1586 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, 1594 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction)
1587 const Class& cls) 1595 : instruction_(instruction) { }
1588 : instruction_(instruction), cls_(cls) { }
1589 1596
1590 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1597 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1591 __ Comment("StoreInstanceFieldSlowPath"); 1598 __ Comment("StoreInstanceFieldSlowPath");
1592 __ Bind(entry_label()); 1599 {
1593 const Code& stub = 1600 __ Bind(double_entry_label());
1594 Code::Handle(StubCode::GetAllocationStubForClass(cls_));
1595 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint());
1596 1601
1597 LocationSummary* locs = instruction_->locs(); 1602 const Class& cls = compiler->double_class();
1598 locs->live_registers()->Remove(locs->out()); 1603 const Code& stub =
1604 Code::Handle(StubCode::GetAllocationStubForClass(cls));
1605 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1599 1606
1600 compiler->SaveLiveRegisters(locs); 1607 LocationSummary* locs = instruction_->locs();
1601 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1608 locs->live_registers()->Remove(locs->out());
1602 &label,
1603 PcDescriptors::kOther,
1604 locs);
1605 __ MoveRegister(locs->temp(0).reg(), R0);
1606 compiler->RestoreLiveRegisters(locs);
1607 1609
1608 __ b(exit_label()); 1610 compiler->SaveLiveRegisters(locs);
1611 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1612 &label,
1613 PcDescriptors::kOther,
1614 locs);
1615 __ MoveRegister(locs->temp(0).reg(), R0);
1616 compiler->RestoreLiveRegisters(locs);
1617
1618 __ b(double_exit_label());
1619 }
1620
1621 {
1622 __ Bind(float32x4_entry_label());
1623
1624 const Class& cls = compiler->float32x4_class();
1625 const Code& stub =
1626 Code::Handle(StubCode::GetAllocationStubForClass(cls));
1627 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1628
1629 LocationSummary* locs = instruction_->locs();
1630 locs->live_registers()->Remove(locs->out());
Florian Schneider 2014/02/06 12:38:49 locs->live_registers is already modified in the sa
Cutch 2014/02/06 23:15:38 Done.
1631
1632 compiler->SaveLiveRegisters(locs);
1633 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1634 &label,
1635 PcDescriptors::kOther,
1636 locs);
1637 __ MoveRegister(locs->temp(0).reg(), R0);
1638 compiler->RestoreLiveRegisters(locs);
1639
1640 __ b(float32x4_exit_label());
1641 }
1609 } 1642 }
1610 1643
1644 Label* double_entry_label() {
1645 // Use default SlowPathCode label for double.
1646 return entry_label();
1647 }
1648 Label* double_exit_label() {
1649 // Use default SlowPathCode label for double.
1650 return exit_label();
1651 }
1652
1653 Label* float32x4_entry_label() { return &float32x4_entry_label_; }
1654 Label* float32x4_exit_label() { return &float32x4_exit_label_; }
1655
1611 private: 1656 private:
1657 Label float32x4_entry_label_;
1658 Label float32x4_exit_label_;
1612 StoreInstanceFieldInstr* instruction_; 1659 StoreInstanceFieldInstr* instruction_;
1613 const Class& cls_;
1614 }; 1660 };
1615 1661
1616 1662
1617 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { 1663 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const {
1618 const intptr_t kNumInputs = 2; 1664 const intptr_t kNumInputs = 2;
1619 const intptr_t kNumTemps = 0; 1665 const intptr_t kNumTemps = 0;
1620 LocationSummary* summary = 1666 LocationSummary* summary =
1621 new LocationSummary(kNumInputs, kNumTemps, 1667 new LocationSummary(kNumInputs, kNumTemps,
1622 (field().guarded_cid() == kIllegalCid) || (is_initialization_) 1668 (field().guarded_cid() == kIllegalCid) || (is_initialization_)
1623 ? LocationSummary::kCallOnSlowPath 1669 ? LocationSummary::kCallOnSlowPath
(...skipping 21 matching lines...) Expand all
1645 } 1691 }
1646 1692
1647 1693
1648 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1694 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1649 Label skip_store; 1695 Label skip_store;
1650 1696
1651 Register instance_reg = locs()->in(0).reg(); 1697 Register instance_reg = locs()->in(0).reg();
1652 1698
1653 if (IsUnboxedStore() && compiler->is_optimizing()) { 1699 if (IsUnboxedStore() && compiler->is_optimizing()) {
1654 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg()); 1700 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg());
1701 DRegister value_odd = OddDRegisterOf(locs()->in(1).fpu_reg());
1655 Register temp = locs()->temp(0).reg(); 1702 Register temp = locs()->temp(0).reg();
1656 Register temp2 = locs()->temp(1).reg(); 1703 Register temp2 = locs()->temp(1).reg();
1657 const intptr_t cid = field().UnboxedFieldCid(); 1704 const intptr_t cid = field().UnboxedFieldCid();
1658 1705
1659 if (is_initialization_) { 1706 if (is_initialization_) {
1707 StoreInstanceFieldSlowPath* slow_path =
1708 new StoreInstanceFieldSlowPath(this);
1709 compiler->AddSlowPathCode(slow_path);
1710
1660 const Class* cls = NULL; 1711 const Class* cls = NULL;
1712 Label* entry_label = NULL;
1713 Label* exit_label = NULL;
1661 switch (cid) { 1714 switch (cid) {
1662 case kDoubleCid: 1715 case kDoubleCid:
1663 cls = &compiler->double_class(); 1716 cls = &compiler->double_class();
1717 entry_label = slow_path->double_entry_label();
1718 exit_label = slow_path->double_exit_label();
1664 break; 1719 break;
1665 // TODO(johnmccutchan): Add kFloat32x4Cid here. 1720 case kFloat32x4Cid:
1721 cls = &compiler->float32x4_class();
1722 entry_label = slow_path->float32x4_entry_label();
1723 exit_label = slow_path->float32x4_exit_label();
1724 break;
1666 default: 1725 default:
1667 UNREACHABLE(); 1726 UNREACHABLE();
1668 } 1727 }
1669 StoreInstanceFieldSlowPath* slow_path = 1728
1670 new StoreInstanceFieldSlowPath(this, *cls);
1671 compiler->AddSlowPathCode(slow_path);
1672 __ TryAllocate(*cls, 1729 __ TryAllocate(*cls,
1673 slow_path->entry_label(), 1730 entry_label,
1674 temp, 1731 temp,
1675 temp2); 1732 temp2);
1676 __ Bind(slow_path->exit_label()); 1733 __ Bind(exit_label);
1677 __ MoveRegister(temp2, temp); 1734 __ MoveRegister(temp2, temp);
1678 __ StoreIntoObject(instance_reg, 1735 __ StoreIntoObject(instance_reg,
1679 FieldAddress(instance_reg, field().Offset()), 1736 FieldAddress(instance_reg, field().Offset()),
1680 temp2); 1737 temp2);
1681 } else { 1738 } else {
1682 __ ldr(temp, FieldAddress(instance_reg, field().Offset())); 1739 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1683 } 1740 }
1684 switch (cid) { 1741 switch (cid) {
1685 case kDoubleCid: 1742 case kDoubleCid:
1686 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); 1743 __ Comment("UnboxedDoubleStoreInstanceFieldInstr");
1687 // TODO(johnmccutchan): Add kFloat32x4Cid here. 1744 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag);
1688 break; 1745 break;
1746 case kFloat32x4Cid:
1747 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr");
1748 __ StoreDToOffset(value, temp,
1749 Float32x4::value_offset() - kHeapObjectTag);
1750 __ StoreDToOffset(value_odd, temp,
1751 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
1752 break;
1689 default: 1753 default:
1690 UNREACHABLE(); 1754 UNREACHABLE();
1691 } 1755 }
1692 1756
1693 return; 1757 return;
1694 } 1758 }
1695 1759
1696 if (IsPotentialUnboxedStore()) { 1760 if (IsPotentialUnboxedStore()) {
1697 Register value_reg = locs()->in(1).reg(); 1761 Register value_reg = locs()->in(1).reg();
1698 Register temp = locs()->temp(0).reg(); 1762 Register temp = locs()->temp(0).reg();
1699 Register temp2 = locs()->temp(1).reg(); 1763 Register temp2 = locs()->temp(1).reg();
1700 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); 1764 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg());
1765 DRegister fpu_temp_odd = OddDRegisterOf(locs()->temp(2).fpu_reg());
1701 1766
1702 Label store_pointer; 1767 Label store_pointer;
1703 Label copy_double;
1704 Label store_double; 1768 Label store_double;
1769 Label store_float32x4;
1705 1770
1706 __ LoadObject(temp, Field::ZoneHandle(field().raw())); 1771 __ LoadObject(temp, Field::ZoneHandle(field().raw()));
1707 1772
1708 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); 1773 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset()));
1709 __ CompareImmediate(temp2, kNullCid); 1774 __ CompareImmediate(temp2, kNullCid);
1710 __ b(&store_pointer, EQ); 1775 __ b(&store_pointer, EQ);
1711 1776
1712 __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset())); 1777 __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset()));
1713 __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit)); 1778 __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit));
1714 __ b(&store_pointer, EQ); 1779 __ b(&store_pointer, EQ);
1715 1780
1716 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); 1781 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset()));
1717 __ CompareImmediate(temp2, kDoubleCid); 1782 __ CompareImmediate(temp2, kDoubleCid);
1718 __ b(&store_double, EQ); 1783 __ b(&store_double, EQ);
1719 1784
1785 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset()));
1786 __ CompareImmediate(temp2, kFloat32x4Cid);
1787 __ b(&store_float32x4, EQ);
1788
1720 // Fall through. 1789 // Fall through.
1721 __ b(&store_pointer); 1790 __ b(&store_pointer);
1722 1791
1723 __ Bind(&store_double);
1724
1725 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1726 __ CompareImmediate(temp,
1727 reinterpret_cast<intptr_t>(Object::null()));
1728 __ b(&copy_double, NE);
1729
1730 StoreInstanceFieldSlowPath* slow_path = 1792 StoreInstanceFieldSlowPath* slow_path =
1731 new StoreInstanceFieldSlowPath(this, compiler->double_class()); 1793 new StoreInstanceFieldSlowPath(this);
1732 compiler->AddSlowPathCode(slow_path); 1794 compiler->AddSlowPathCode(slow_path);
1733 1795
1734 if (!compiler->is_optimizing()) { 1796 {
1735 locs()->live_registers()->Add(locs()->in(0)); 1797 __ Bind(&store_double);
1736 locs()->live_registers()->Add(locs()->in(1)); 1798 Label copy_double;
1799
1800 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1801 __ CompareImmediate(temp,
1802 reinterpret_cast<intptr_t>(Object::null()));
1803 __ b(&copy_double, NE);
1804
1805 if (!compiler->is_optimizing()) {
1806 locs()->live_registers()->Add(locs()->in(0));
1807 locs()->live_registers()->Add(locs()->in(1));
1808 }
1809
1810 __ TryAllocate(compiler->double_class(),
1811 slow_path->double_entry_label(),
1812 temp,
1813 temp2);
1814 __ Bind(slow_path->double_exit_label());
1815 __ MoveRegister(temp2, temp);
1816 __ StoreIntoObject(instance_reg,
1817 FieldAddress(instance_reg, field().Offset()),
1818 temp2);
1819 __ Bind(&copy_double);
1820 __ LoadDFromOffset(fpu_temp,
1821 value_reg,
1822 Double::value_offset() - kHeapObjectTag);
1823 __ StoreDToOffset(fpu_temp,
1824 temp,
1825 Double::value_offset() - kHeapObjectTag);
1826 __ b(&skip_store);
1737 } 1827 }
1738 1828
1739 __ TryAllocate(compiler->double_class(), 1829 {
1740 slow_path->entry_label(), 1830 __ Bind(&store_float32x4);
1741 temp, 1831 Label copy_float32x4;
1742 temp2); 1832
1743 __ Bind(slow_path->exit_label()); 1833 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1744 __ MoveRegister(temp2, temp); 1834 __ CompareImmediate(temp,
1745 __ StoreIntoObject(instance_reg, 1835 reinterpret_cast<intptr_t>(Object::null()));
1746 FieldAddress(instance_reg, field().Offset()), 1836 __ b(&copy_float32x4, NE);
1747 temp2); 1837
1748 __ Bind(&copy_double); 1838 if (!compiler->is_optimizing()) {
1749 __ LoadDFromOffset(fpu_temp, 1839 locs()->live_registers()->Add(locs()->in(0));
Florian Schneider 2014/02/06 12:38:49 locs() is already modified in the same way above,
Cutch 2014/02/06 23:15:38 Done.
1750 value_reg, 1840 locs()->live_registers()->Add(locs()->in(1));
1751 Double::value_offset() - kHeapObjectTag); 1841 }
1752 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); 1842
1753 __ b(&skip_store); 1843 __ TryAllocate(compiler->float32x4_class(),
1844 slow_path->float32x4_entry_label(),
1845 temp,
1846 temp2);
1847 __ Bind(slow_path->float32x4_exit_label());
1848 __ MoveRegister(temp2, temp);
1849 __ StoreIntoObject(instance_reg,
1850 FieldAddress(instance_reg, field().Offset()),
1851 temp2);
1852 __ Bind(&copy_float32x4);
1853 __ LoadDFromOffset(fpu_temp, value_reg,
1854 Float32x4::value_offset() - kHeapObjectTag);
1855 __ LoadDFromOffset(fpu_temp_odd, value_reg,
1856 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
1857 __ StoreDToOffset(fpu_temp, temp,
1858 Float32x4::value_offset() - kHeapObjectTag);
1859 __ StoreDToOffset(fpu_temp_odd, temp,
1860 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
1861 __ b(&skip_store);
1862 }
1863
1754 __ Bind(&store_pointer); 1864 __ Bind(&store_pointer);
1755 } 1865 }
1756 1866
1757 if (ShouldEmitStoreBarrier()) { 1867 if (ShouldEmitStoreBarrier()) {
1758 Register value_reg = locs()->in(1).reg(); 1868 Register value_reg = locs()->in(1).reg();
1759 __ StoreIntoObject(instance_reg, 1869 __ StoreIntoObject(instance_reg,
1760 FieldAddress(instance_reg, field().Offset()), 1870 FieldAddress(instance_reg, field().Offset()),
1761 value_reg, 1871 value_reg,
1762 CanValueBeSmi()); 1872 CanValueBeSmi());
1763 } else { 1873 } else {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1887 deopt_id(), 1997 deopt_id(),
1888 kAllocateObjectWithBoundsCheckRuntimeEntry, 1998 kAllocateObjectWithBoundsCheckRuntimeEntry,
1889 3, 1999 3,
1890 locs()); 2000 locs());
1891 __ Drop(3); 2001 __ Drop(3);
1892 ASSERT(locs()->out().reg() == R0); 2002 ASSERT(locs()->out().reg() == R0);
1893 __ Pop(R0); // Pop new instance. 2003 __ Pop(R0); // Pop new instance.
1894 } 2004 }
1895 2005
1896 2006
1897 class BoxDoubleSlowPath : public SlowPathCode { 2007 class LoadFieldSlowPath : public SlowPathCode {
1898 public: 2008 public:
1899 explicit BoxDoubleSlowPath(Instruction* instruction) 2009 explicit LoadFieldSlowPath(Instruction* instruction)
1900 : instruction_(instruction) { } 2010 : instruction_(instruction) { }
1901 2011
1902 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2012 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1903 __ Comment("BoxDoubleSlowPath"); 2013 __ Comment("LoadFieldSlowPath");
1904 __ Bind(entry_label()); 2014 {
1905 const Class& double_class = compiler->double_class(); 2015 __ Bind(double_entry_label());
1906 const Code& stub = 2016 const Class& double_class = compiler->double_class();
1907 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2017 const Code& stub =
1908 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2018 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2019 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1909 2020
1910 LocationSummary* locs = instruction_->locs(); 2021 LocationSummary* locs = instruction_->locs();
1911 locs->live_registers()->Remove(locs->out()); 2022 locs->live_registers()->Remove(locs->out());
1912 2023
1913 compiler->SaveLiveRegisters(locs); 2024 compiler->SaveLiveRegisters(locs);
1914 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 2025 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1915 &label, 2026 &label,
1916 PcDescriptors::kOther, 2027 PcDescriptors::kOther,
1917 locs); 2028 locs);
1918 __ MoveRegister(locs->out().reg(), R0); 2029 __ MoveRegister(locs->out().reg(), R0);
1919 compiler->RestoreLiveRegisters(locs); 2030 compiler->RestoreLiveRegisters(locs);
1920 2031
1921 __ b(exit_label()); 2032 __ b(double_exit_label());
2033 }
2034 {
2035 __ Bind(float32x4_entry_label());
2036 const Class& float32x4_class = compiler->float32x4_class();
2037 const Code& stub =
2038 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class));
2039 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint());
2040
2041 LocationSummary* locs = instruction_->locs();
2042 locs->live_registers()->Remove(locs->out());
2043
2044 compiler->SaveLiveRegisters(locs);
2045 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2046 &label,
2047 PcDescriptors::kOther,
2048 locs);
2049 __ MoveRegister(locs->out().reg(), R0);
2050 compiler->RestoreLiveRegisters(locs);
2051
2052 __ b(float32x4_exit_label());
2053 }
1922 } 2054 }
1923 2055
2056 Label* double_entry_label() {
2057 // Use default SlowPathCode label for double.
2058 return entry_label();
2059 }
2060 Label* double_exit_label() {
2061 // Use default SlowPathCode label for double.
2062 return exit_label();
2063 }
2064
2065 Label* float32x4_entry_label() { return &float32x4_entry_label_; }
2066 Label* float32x4_exit_label() { return &float32x4_exit_label_; }
2067
1924 private: 2068 private:
2069 Label float32x4_entry_label_;
2070 Label float32x4_exit_label_;
1925 Instruction* instruction_; 2071 Instruction* instruction_;
1926 }; 2072 };
1927 2073
1928 2074
1929 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 2075 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
1930 const intptr_t kNumInputs = 1; 2076 const intptr_t kNumInputs = 1;
1931 const intptr_t kNumTemps = 0; 2077 const intptr_t kNumTemps = 0;
1932 LocationSummary* locs = 2078 LocationSummary* locs =
1933 new LocationSummary( 2079 new LocationSummary(
1934 kNumInputs, kNumTemps, 2080 kNumInputs, kNumTemps,
(...skipping 12 matching lines...) Expand all
1947 } 2093 }
1948 locs->set_out(Location::RequiresRegister()); 2094 locs->set_out(Location::RequiresRegister());
1949 return locs; 2095 return locs;
1950 } 2096 }
1951 2097
1952 2098
1953 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2099 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1954 Register instance_reg = locs()->in(0).reg(); 2100 Register instance_reg = locs()->in(0).reg();
1955 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2101 if (IsUnboxedLoad() && compiler->is_optimizing()) {
1956 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 2102 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
2103 DRegister result_odd = OddDRegisterOf(locs()->out().fpu_reg());
1957 Register temp = locs()->temp(0).reg(); 2104 Register temp = locs()->temp(0).reg();
1958 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); 2105 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
1959 intptr_t cid = field()->UnboxedFieldCid(); 2106 intptr_t cid = field()->UnboxedFieldCid();
1960 switch (cid) { 2107 switch (cid) {
1961 case kDoubleCid: 2108 case kDoubleCid:
2109 __ Comment("UnboxedDoubleLoadFieldInstr");
1962 __ LoadDFromOffset(result, temp, 2110 __ LoadDFromOffset(result, temp,
1963 Double::value_offset() - kHeapObjectTag); 2111 Double::value_offset() - kHeapObjectTag);
1964 break; 2112 break;
1965 // TODO(johnmccutchan): Add Float32x4 path here. 2113 case kFloat32x4Cid:
2114 __ Comment("UnboxedFloat32x4LoadFieldInstr");
2115 __ LoadDFromOffset(result, temp,
2116 Float32x4::value_offset() - kHeapObjectTag);
2117 __ LoadDFromOffset(result_odd, temp,
2118 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2119 break;
1966 default: 2120 default:
1967 UNREACHABLE(); 2121 UNREACHABLE();
1968 } 2122 }
1969 return; 2123 return;
1970 } 2124 }
1971 2125
1972 Label done; 2126 Label done;
1973 Register result_reg = locs()->out().reg(); 2127 Register result_reg = locs()->out().reg();
1974 if (IsPotentialUnboxedLoad()) { 2128 if (IsPotentialUnboxedLoad()) {
1975 Register temp = locs()->temp(1).reg(); 2129 Register temp = locs()->temp(1).reg();
1976 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); 2130 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg());
2131 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg());
2132
2133 LoadFieldSlowPath* slow_path = new LoadFieldSlowPath(this);
2134 compiler->AddSlowPathCode(slow_path);
1977 2135
1978 Label load_pointer; 2136 Label load_pointer;
1979 Label load_double; 2137 Label load_double;
2138 Label load_float32x4;
1980 2139
1981 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); 2140 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()));
1982 2141
1983 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); 2142 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset());
1984 FieldAddress field_nullability_operand(result_reg, 2143 FieldAddress field_nullability_operand(result_reg,
1985 Field::is_nullable_offset()); 2144 Field::is_nullable_offset());
1986 2145
1987 __ ldr(temp, field_nullability_operand); 2146 __ ldr(temp, field_nullability_operand);
1988 __ CompareImmediate(temp, kNullCid); 2147 __ CompareImmediate(temp, kNullCid);
1989 __ b(&load_pointer, EQ); 2148 __ b(&load_pointer, EQ);
1990 2149
1991 __ ldr(temp, field_cid_operand); 2150 __ ldr(temp, field_cid_operand);
1992 __ CompareImmediate(temp, kDoubleCid); 2151 __ CompareImmediate(temp, kDoubleCid);
1993 __ b(&load_double, EQ); 2152 __ b(&load_double, EQ);
1994 2153
2154 __ ldr(temp, field_cid_operand);
2155 __ CompareImmediate(temp, kFloat32x4Cid);
2156 __ b(&load_float32x4, EQ);
2157
1995 // Fall through. 2158 // Fall through.
1996 __ b(&load_pointer); 2159 __ b(&load_pointer);
1997 2160
1998 __ Bind(&load_double); 2161 {
2162 __ Bind(&load_double);
1999 2163
2000 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2164 if (!compiler->is_optimizing()) {
2001 compiler->AddSlowPathCode(slow_path); 2165 locs()->live_registers()->Add(locs()->in(0));
2166 }
2002 2167
2003 if (!compiler->is_optimizing()) { 2168 __ TryAllocate(compiler->double_class(),
2004 locs()->live_registers()->Add(locs()->in(0)); 2169 slow_path->double_entry_label(),
2170 result_reg,
2171 temp);
2172 __ Bind(slow_path->double_exit_label());
2173 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
2174 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag);
2175 __ StoreDToOffset(value,
2176 result_reg,
2177 Double::value_offset() - kHeapObjectTag);
2178 __ b(&done);
2005 } 2179 }
2006 2180
2007 __ TryAllocate(compiler->double_class(), 2181 {
2008 slow_path->entry_label(), 2182 __ Bind(&load_float32x4);
2009 result_reg,
2010 temp);
2011 __ Bind(slow_path->exit_label());
2012 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
2013 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag);
2014 __ StoreDToOffset(value,
2015 result_reg,
2016 Double::value_offset() - kHeapObjectTag);
2017 __ b(&done);
2018 2183
2019 // TODO(johnmccutchan): Add Float32x4 path here. 2184 if (!compiler->is_optimizing()) {
2185 locs()->live_registers()->Add(locs()->in(0));
2186 }
2187
2188 __ TryAllocate(compiler->float32x4_class(),
2189 slow_path->float32x4_entry_label(),
2190 result_reg,
2191 temp);
2192 __ Bind(slow_path->float32x4_exit_label());
2193 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
2194 __ LoadDFromOffset(value, temp,
2195 Float32x4::value_offset() - kHeapObjectTag);
2196 __ LoadDFromOffset(value_odd, temp,
2197 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2198 __ StoreDToOffset(value, result_reg,
2199 Float32x4::value_offset() - kHeapObjectTag);
2200 __ StoreDToOffset(value_odd, result_reg,
2201 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2202 __ b(&done);
2203 }
2020 2204
2021 __ Bind(&load_pointer); 2205 __ Bind(&load_pointer);
2022 } 2206 }
2023 __ LoadFromOffset(kWord, result_reg, 2207 __ LoadFromOffset(kWord, result_reg,
2024 instance_reg, offset_in_bytes() - kHeapObjectTag); 2208 instance_reg, offset_in_bytes() - kHeapObjectTag);
2025 __ Bind(&done); 2209 __ Bind(&done);
2026 } 2210 }
2027 2211
2028 2212
2029 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2213 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 } else if (right_cid == kSmiCid) { 3001 } else if (right_cid == kSmiCid) {
2818 __ tst(left, ShifterOperand(kSmiTagMask)); 3002 __ tst(left, ShifterOperand(kSmiTagMask));
2819 } else { 3003 } else {
2820 __ orr(IP, left, ShifterOperand(right)); 3004 __ orr(IP, left, ShifterOperand(right));
2821 __ tst(IP, ShifterOperand(kSmiTagMask)); 3005 __ tst(IP, ShifterOperand(kSmiTagMask));
2822 } 3006 }
2823 __ b(deopt, EQ); 3007 __ b(deopt, EQ);
2824 } 3008 }
2825 3009
2826 3010
3011 class BoxDoubleSlowPath : public SlowPathCode {
3012 public:
3013 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction)
3014 : instruction_(instruction) { }
3015
3016 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
3017 __ Comment("BoxDoubleSlowPath");
3018 __ Bind(entry_label());
3019 const Class& double_class = compiler->double_class();
3020 const Code& stub =
3021 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
3022 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
3023
3024 LocationSummary* locs = instruction_->locs();
3025 locs->live_registers()->Remove(locs->out());
3026
3027 compiler->SaveLiveRegisters(locs);
3028 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
3029 &label,
3030 PcDescriptors::kOther,
3031 locs);
3032 __ MoveRegister(locs->out().reg(), R0);
3033 compiler->RestoreLiveRegisters(locs);
3034
3035 __ b(exit_label());
3036 }
3037
3038 private:
3039 BoxDoubleInstr* instruction_;
3040 };
3041
3042
2827 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { 3043 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
2828 const intptr_t kNumInputs = 1; 3044 const intptr_t kNumInputs = 1;
2829 const intptr_t kNumTemps = 1; 3045 const intptr_t kNumTemps = 1;
2830 LocationSummary* summary = 3046 LocationSummary* summary =
2831 new LocationSummary(kNumInputs, 3047 new LocationSummary(kNumInputs,
2832 kNumTemps, 3048 kNumTemps,
2833 LocationSummary::kCallOnSlowPath); 3049 LocationSummary::kCallOnSlowPath);
2834 summary->set_in(0, Location::RequiresFpuRegister()); 3050 summary->set_in(0, Location::RequiresFpuRegister());
2835 summary->set_temp(0, Location::RequiresRegister()); 3051 summary->set_temp(0, Location::RequiresRegister());
2836 summary->set_out(Location::RequiresRegister()); 3052 summary->set_out(Location::RequiresRegister());
(...skipping 2050 matching lines...) Expand 10 before | Expand all | Expand 10 after
4887 compiler->GenerateCall(token_pos(), 5103 compiler->GenerateCall(token_pos(),
4888 &label, 5104 &label,
4889 PcDescriptors::kOther, 5105 PcDescriptors::kOther,
4890 locs()); 5106 locs());
4891 __ Drop(2); // Discard type arguments and receiver. 5107 __ Drop(2); // Discard type arguments and receiver.
4892 } 5108 }
4893 5109
4894 } // namespace dart 5110 } // namespace dart
4895 5111
4896 #endif // defined TARGET_ARCH_ARM 5112 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698