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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 1572 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 __ j(NOT_EQUAL, fail); 1583 __ j(NOT_EQUAL, fail);
1584 } else { 1584 } else {
1585 UNREACHABLE(); 1585 UNREACHABLE();
1586 } 1586 }
1587 } 1587 }
1588 } 1588 }
1589 __ Bind(&ok); 1589 __ Bind(&ok);
1590 } 1590 }
1591 1591
1592 1592
1593 bool Field::IsUnboxedField() const {
1594 bool valid_class = (guarded_cid() == kDoubleCid) ||
1595 (guarded_cid() == kFloat32x4Cid);
1596 return is_unboxing_candidate() && !is_final() && !is_nullable() &&
1597 valid_class;
1598 }
1599
1600
1593 class StoreInstanceFieldSlowPath : public SlowPathCode { 1601 class StoreInstanceFieldSlowPath : public SlowPathCode {
1594 public: 1602 public:
1595 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, 1603 explicit StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction)
1596 const Class& cls) 1604 : instruction_(instruction) { }
1597 : instruction_(instruction), cls_(cls) { }
1598 1605
1599 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1606 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1600 __ Comment("StoreInstanceFieldSlowPath"); 1607 __ Comment("StoreInstanceFieldSlowPath");
1601 __ Bind(entry_label()); 1608 {
1602 const Code& stub = 1609 __ Bind(double_entry_label());
1603 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); 1610 const Class& cls = compiler->double_class();
1604 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); 1611 const Code& stub =
1612 Code::Handle(StubCode::GetAllocationStubForClass(cls));
1613 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1605 1614
1606 LocationSummary* locs = instruction_->locs(); 1615 LocationSummary* locs = instruction_->locs();
1607 locs->live_registers()->Remove(locs->out()); 1616 locs->live_registers()->Remove(locs->out());
1608 1617 compiler->SaveLiveRegisters(locs);
1609 compiler->SaveLiveRegisters(locs); 1618 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1610 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1619 &label,
1611 &label, 1620 PcDescriptors::kOther,
1612 PcDescriptors::kOther, 1621 locs);
1613 locs); 1622 __ MoveRegister(locs->temp(0).reg(), EAX);
1614 __ MoveRegister(locs->temp(0).reg(), EAX); 1623 compiler->RestoreLiveRegisters(locs);
1615 compiler->RestoreLiveRegisters(locs); 1624 __ jmp(double_exit_label());
1616 1625 }
1617 __ jmp(exit_label()); 1626 {
1627 __ Bind(float32x4_entry_label());
1628 const Class& cls = compiler->float32x4_class();
1629 const Code& stub =
1630 Code::Handle(StubCode::GetAllocationStubForClass(cls));
1631 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
1632 LocationSummary* locs = instruction_->locs();
1633 locs->live_registers()->Remove(locs->out());
1634 compiler->SaveLiveRegisters(locs);
1635 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1636 &label,
1637 PcDescriptors::kOther,
1638 locs);
1639 __ MoveRegister(locs->temp(0).reg(), EAX);
1640 compiler->RestoreLiveRegisters(locs);
1641 __ jmp(float32x4_exit_label());
1642 }
1618 } 1643 }
1619 1644
1645 Label* double_entry_label() {
1646 // Use default SlowPathCode label for double.
1647 return entry_label();
1648 }
1649 Label* double_exit_label() {
1650 // Use default SlowPathCode label for double.
1651 return exit_label();
1652 }
1653
1654 Label* float32x4_entry_label() { return &float32x4_entry_label_; }
1655 Label* float32x4_exit_label() { return &float32x4_exit_label_; }
1656
1620 private: 1657 private:
1658 Label float32x4_entry_label_;
1659 Label float32x4_exit_label_;
1621 StoreInstanceFieldInstr* instruction_; 1660 StoreInstanceFieldInstr* instruction_;
1622 const Class& cls_;
1623 }; 1661 };
1624 1662
1625 1663
1626 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const { 1664 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary(bool opt) const {
1627 const intptr_t kNumInputs = 2; 1665 const intptr_t kNumInputs = 2;
1628 const intptr_t kNumTemps = 0; 1666 const intptr_t kNumTemps = 0;
1629 LocationSummary* summary = 1667 LocationSummary* summary =
1630 new LocationSummary(kNumInputs, kNumTemps, 1668 new LocationSummary(kNumInputs, kNumTemps,
1631 (field().guarded_cid() == kIllegalCid) || (is_initialization_) 1669 (field().guarded_cid() == kIllegalCid) || (is_initialization_)
1632 ? LocationSummary::kCallOnSlowPath 1670 ? LocationSummary::kCallOnSlowPath
(...skipping 26 matching lines...) Expand all
1659 1697
1660 Register instance_reg = locs()->in(0).reg(); 1698 Register instance_reg = locs()->in(0).reg();
1661 1699
1662 if (IsUnboxedStore() && compiler->is_optimizing()) { 1700 if (IsUnboxedStore() && compiler->is_optimizing()) {
1663 XmmRegister value = locs()->in(1).fpu_reg(); 1701 XmmRegister value = locs()->in(1).fpu_reg();
1664 Register temp = locs()->temp(0).reg(); 1702 Register temp = locs()->temp(0).reg();
1665 Register temp2 = locs()->temp(1).reg(); 1703 Register temp2 = locs()->temp(1).reg();
1666 const intptr_t cid = field().UnboxedFieldCid(); 1704 const intptr_t cid = field().UnboxedFieldCid();
1667 1705
1668 if (is_initialization_) { 1706 if (is_initialization_) {
1707 StoreInstanceFieldSlowPath* slow_path =
1708 new StoreInstanceFieldSlowPath(this);
1709 compiler->AddSlowPathCode(slow_path);
1710
1669 const Class* cls = NULL; 1711 const Class* cls = NULL;
1712 Label* entry_label = NULL;
1713 Label* exit_label = NULL;
1670 switch (cid) { 1714 switch (cid) {
1671 case kDoubleCid: 1715 case kDoubleCid:
1672 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();
1673 break; 1719 break;
1674 // 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;
1675 default: 1725 default:
1676 UNREACHABLE(); 1726 UNREACHABLE();
1677 } 1727 }
1678 StoreInstanceFieldSlowPath* slow_path =
1679 new StoreInstanceFieldSlowPath(this, *cls);
1680 compiler->AddSlowPathCode(slow_path);
1681 1728
1682 __ TryAllocate(*cls, 1729 __ TryAllocate(*cls,
1683 slow_path->entry_label(), 1730 entry_label,
1684 Assembler::kFarJump, 1731 Assembler::kFarJump,
1685 temp, 1732 temp,
1686 temp2); 1733 temp2);
1687 __ Bind(slow_path->exit_label()); 1734 __ Bind(exit_label);
1688 __ movl(temp2, temp); 1735 __ movl(temp2, temp);
1689 __ StoreIntoObject(instance_reg, 1736 __ StoreIntoObject(instance_reg,
1690 FieldAddress(instance_reg, field().Offset()), 1737 FieldAddress(instance_reg, field().Offset()),
1691 temp2); 1738 temp2);
1692 } else { 1739 } else {
1693 __ movl(temp, FieldAddress(instance_reg, field().Offset())); 1740 __ movl(temp, FieldAddress(instance_reg, field().Offset()));
1694 } 1741 }
1695 switch (cid) { 1742 switch (cid) {
1696 case kDoubleCid: 1743 case kDoubleCid:
1697 __ movsd(FieldAddress(temp, Double::value_offset()), value); 1744 __ Comment("UnboxedDoubleStoreInstanceFieldInstr");
1698 // TODO(johnmccutchan): Add kFloat32x4Cid here. 1745 __ movsd(FieldAddress(temp, Double::value_offset()), value);
1746 break;
1747 case kFloat32x4Cid:
1748 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr");
1749 __ movups(FieldAddress(temp, Float32x4::value_offset()), value);
1699 break; 1750 break;
1700 default: 1751 default:
1701 UNREACHABLE(); 1752 UNREACHABLE();
1702 } 1753 }
1703 return; 1754 return;
1704 } 1755 }
1705 1756
1706 if (IsPotentialUnboxedStore()) { 1757 if (IsPotentialUnboxedStore()) {
1707 Register value_reg = locs()->in(1).reg(); 1758 Register value_reg = locs()->in(1).reg();
1708 Register temp = locs()->temp(0).reg(); 1759 Register temp = locs()->temp(0).reg();
1709 Register temp2 = locs()->temp(1).reg(); 1760 Register temp2 = locs()->temp(1).reg();
1710 FpuRegister fpu_temp = locs()->temp(2).fpu_reg(); 1761 FpuRegister fpu_temp = locs()->temp(2).fpu_reg();
1711 1762
1712 Label store_pointer; 1763 Label store_pointer;
1713 Label copy_double;
1714 Label store_double; 1764 Label store_double;
1765 Label store_float32x4;
1715 1766
1716 __ LoadObject(temp, Field::ZoneHandle(field().raw())); 1767 __ LoadObject(temp, Field::ZoneHandle(field().raw()));
1717 1768
1718 __ cmpl(FieldAddress(temp, Field::is_nullable_offset()), 1769 __ cmpl(FieldAddress(temp, Field::is_nullable_offset()),
1719 Immediate(kNullCid)); 1770 Immediate(kNullCid));
1720 __ j(EQUAL, &store_pointer); 1771 __ j(EQUAL, &store_pointer);
1721 1772
1722 __ movzxb(temp2, FieldAddress(temp, Field::kind_bits_offset())); 1773 __ movzxb(temp2, FieldAddress(temp, Field::kind_bits_offset()));
1723 __ testl(temp2, Immediate(1 << Field::kUnboxingCandidateBit)); 1774 __ testl(temp2, Immediate(1 << Field::kUnboxingCandidateBit));
1724 __ j(ZERO, &store_pointer); 1775 __ j(ZERO, &store_pointer);
1725 1776
1726 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()), 1777 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()),
1727 Immediate(kDoubleCid)); 1778 Immediate(kDoubleCid));
1728 __ j(EQUAL, &store_double); 1779 __ j(EQUAL, &store_double);
1729 1780
1781 __ cmpl(FieldAddress(temp, Field::guarded_cid_offset()),
1782 Immediate(kFloat32x4Cid));
1783 __ j(EQUAL, &store_float32x4);
1784
1730 // Fall through. 1785 // Fall through.
1731 __ jmp(&store_pointer); 1786 __ jmp(&store_pointer);
1732 1787
1733 __ Bind(&store_double);
1734
1735 const Immediate& raw_null =
1736 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1737 __ movl(temp, FieldAddress(instance_reg, field().Offset()));
1738 __ cmpl(temp, raw_null);
1739 __ j(NOT_EQUAL, &copy_double);
1740
1741 StoreInstanceFieldSlowPath* slow_path = 1788 StoreInstanceFieldSlowPath* slow_path =
1742 new StoreInstanceFieldSlowPath(this, compiler->double_class()); 1789 new StoreInstanceFieldSlowPath(this);
1743 compiler->AddSlowPathCode(slow_path); 1790 compiler->AddSlowPathCode(slow_path);
1744 1791
1745 if (!compiler->is_optimizing()) { 1792 {
1746 locs()->live_registers()->Add(locs()->in(0)); 1793 __ Bind(&store_double);
1747 locs()->live_registers()->Add(locs()->in(1)); 1794 Label copy_double;
1795
1796 const Immediate& raw_null =
1797 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1798 __ movl(temp, FieldAddress(instance_reg, field().Offset()));
1799 __ cmpl(temp, raw_null);
1800 __ j(NOT_EQUAL, &copy_double);
1801
1802 if (!compiler->is_optimizing()) {
1803 locs()->live_registers()->Add(locs()->in(0));
1804 locs()->live_registers()->Add(locs()->in(1));
1805 }
1806
1807 __ TryAllocate(compiler->double_class(),
1808 slow_path->double_entry_label(),
1809 Assembler::kFarJump,
1810 temp,
1811 temp2);
1812 __ Bind(slow_path->double_exit_label());
1813 __ movl(temp2, temp);
1814 __ StoreIntoObject(instance_reg,
1815 FieldAddress(instance_reg, field().Offset()),
1816 temp2);
1817
1818 __ Bind(&copy_double);
1819 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset()));
1820 __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp);
1821 __ jmp(&skip_store);
1748 } 1822 }
1749 1823
1750 __ TryAllocate(compiler->double_class(), 1824 {
1751 slow_path->entry_label(), 1825 __ Bind(&store_float32x4);
1752 Assembler::kFarJump, 1826 Label copy_float32x4;
1753 temp,
1754 temp2);
1755 __ Bind(slow_path->exit_label());
1756 __ movl(temp2, temp);
1757 __ StoreIntoObject(instance_reg,
1758 FieldAddress(instance_reg, field().Offset()),
1759 temp2);
1760 1827
1761 __ Bind(&copy_double); 1828 const Immediate& raw_null =
1762 __ movsd(fpu_temp, FieldAddress(value_reg, Double::value_offset())); 1829 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1763 __ movsd(FieldAddress(temp, Double::value_offset()), fpu_temp); 1830 __ movl(temp, FieldAddress(instance_reg, field().Offset()));
1764 __ jmp(&skip_store); 1831 __ cmpl(temp, raw_null);
1832 __ j(NOT_EQUAL, &copy_float32x4);
1833
1834 if (!compiler->is_optimizing()) {
1835 locs()->live_registers()->Add(locs()->in(0));
1836 locs()->live_registers()->Add(locs()->in(1));
1837 }
1838
1839 __ TryAllocate(compiler->float32x4_class(),
1840 slow_path->float32x4_entry_label(),
1841 Assembler::kFarJump,
1842 temp,
1843 temp2);
1844 __ Bind(slow_path->float32x4_exit_label());
1845 __ movl(temp2, temp);
1846 __ StoreIntoObject(instance_reg,
1847 FieldAddress(instance_reg, field().Offset()),
1848 temp2);
1849
1850 __ Bind(&copy_float32x4);
1851 __ movups(fpu_temp, FieldAddress(value_reg, Float32x4::value_offset()));
1852 __ movups(FieldAddress(temp, Float32x4::value_offset()), fpu_temp);
1853 __ jmp(&skip_store);
1854 }
1765 __ Bind(&store_pointer); 1855 __ Bind(&store_pointer);
1766 } 1856 }
1767 1857
1768 if (ShouldEmitStoreBarrier()) { 1858 if (ShouldEmitStoreBarrier()) {
1769 Register value_reg = locs()->in(1).reg(); 1859 Register value_reg = locs()->in(1).reg();
1770 __ StoreIntoObject(instance_reg, 1860 __ StoreIntoObject(instance_reg,
1771 FieldAddress(instance_reg, field().Offset()), 1861 FieldAddress(instance_reg, field().Offset()),
1772 value_reg, 1862 value_reg,
1773 CanValueBeSmi()); 1863 CanValueBeSmi());
1774 } else { 1864 } else {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 deopt_id(), 1989 deopt_id(),
1900 kAllocateObjectWithBoundsCheckRuntimeEntry, 1990 kAllocateObjectWithBoundsCheckRuntimeEntry,
1901 3, 1991 3,
1902 locs()); 1992 locs());
1903 __ Drop(3); 1993 __ Drop(3);
1904 ASSERT(locs()->out().reg() == EAX); 1994 ASSERT(locs()->out().reg() == EAX);
1905 __ popl(EAX); // Pop new instance. 1995 __ popl(EAX); // Pop new instance.
1906 } 1996 }
1907 1997
1908 1998
1909 class BoxDoubleSlowPath : public SlowPathCode { 1999 class LoadFieldSlowPath : public SlowPathCode {
1910 public: 2000 public:
1911 explicit BoxDoubleSlowPath(Instruction* instruction) 2001 explicit LoadFieldSlowPath(Instruction* instruction)
1912 : instruction_(instruction) { } 2002 : instruction_(instruction) { }
1913 2003
1914 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 2004 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1915 __ Comment("BoxDoubleSlowPath"); 2005 __ Comment("LoadFieldSlowPath");
1916 __ Bind(entry_label()); 2006 {
1917 const Class& double_class = compiler->double_class(); 2007 __ Bind(double_entry_label());
1918 const Code& stub = 2008 const Class& double_class = compiler->double_class();
1919 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2009 const Code& stub =
1920 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2010 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2011 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1921 2012
1922 LocationSummary* locs = instruction_->locs(); 2013 LocationSummary* locs = instruction_->locs();
1923 locs->live_registers()->Remove(locs->out()); 2014 locs->live_registers()->Remove(locs->out());
1924 2015
1925 compiler->SaveLiveRegisters(locs); 2016 compiler->SaveLiveRegisters(locs);
1926 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 2017 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1927 &label, 2018 &label,
1928 PcDescriptors::kOther, 2019 PcDescriptors::kOther,
1929 locs); 2020 locs);
1930 __ MoveRegister(locs->out().reg(), EAX); 2021 __ MoveRegister(locs->out().reg(), EAX);
1931 compiler->RestoreLiveRegisters(locs); 2022 compiler->RestoreLiveRegisters(locs);
1932 2023
1933 __ jmp(exit_label()); 2024 __ jmp(double_exit_label());
2025 }
2026 {
2027 __ Bind(float32x4_entry_label());
2028 const Class& float32x4_class = compiler->float32x4_class();
2029 const Code& stub =
2030 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class));
2031 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint());
2032
2033 LocationSummary* locs = instruction_->locs();
2034 locs->live_registers()->Remove(locs->out());
2035
2036 compiler->SaveLiveRegisters(locs);
2037 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2038 &label,
2039 PcDescriptors::kOther,
2040 locs);
2041 __ MoveRegister(locs->out().reg(), EAX);
2042 compiler->RestoreLiveRegisters(locs);
2043
2044 __ jmp(float32x4_exit_label());
2045 }
1934 } 2046 }
1935 2047
2048 Label* double_entry_label() {
2049 // Use default SlowPathCode label for double.
2050 return entry_label();
2051 }
2052 Label* double_exit_label() {
2053 // Use default SlowPathCode label for double.
2054 return exit_label();
2055 }
2056
2057 Label* float32x4_entry_label() { return &float32x4_entry_label_; }
2058 Label* float32x4_exit_label() { return &float32x4_exit_label_; }
2059
1936 private: 2060 private:
2061 Label float32x4_entry_label_;
2062 Label float32x4_exit_label_;
1937 Instruction* instruction_; 2063 Instruction* instruction_;
1938 }; 2064 };
1939 2065
1940 2066
1941 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 2067 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
1942 const intptr_t kNumInputs = 1; 2068 const intptr_t kNumInputs = 1;
1943 const intptr_t kNumTemps = 0; 2069 const intptr_t kNumTemps = 0;
1944 LocationSummary* locs = 2070 LocationSummary* locs =
1945 new LocationSummary( 2071 new LocationSummary(
1946 kNumInputs, kNumTemps, 2072 kNumInputs, kNumTemps,
(...skipping 17 matching lines...) Expand all
1964 2090
1965 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2091 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1966 Register instance_reg = locs()->in(0).reg(); 2092 Register instance_reg = locs()->in(0).reg();
1967 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2093 if (IsUnboxedLoad() && compiler->is_optimizing()) {
1968 XmmRegister result = locs()->out().fpu_reg(); 2094 XmmRegister result = locs()->out().fpu_reg();
1969 Register temp = locs()->temp(0).reg(); 2095 Register temp = locs()->temp(0).reg();
1970 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes())); 2096 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes()));
1971 const intptr_t cid = field()->UnboxedFieldCid(); 2097 const intptr_t cid = field()->UnboxedFieldCid();
1972 switch (cid) { 2098 switch (cid) {
1973 case kDoubleCid: 2099 case kDoubleCid:
2100 __ Comment("UnboxedDoubleLoadFieldInstr");
1974 __ movsd(result, FieldAddress(temp, Double::value_offset())); 2101 __ movsd(result, FieldAddress(temp, Double::value_offset()));
1975 break; 2102 break;
1976 // TODO(johnmccutchan): Add Float32x4 path here. 2103 case kFloat32x4Cid:
2104 __ Comment("UnboxedFloat32x4LoadFieldInstr");
2105 __ movups(result, FieldAddress(temp, Float32x4::value_offset()));
2106 break;
1977 default: 2107 default:
1978 UNREACHABLE(); 2108 UNREACHABLE();
1979 } 2109 }
1980 return; 2110 return;
1981 } 2111 }
1982 2112
1983 Label done; 2113 Label done;
1984 Register result = locs()->out().reg(); 2114 Register result = locs()->out().reg();
1985 if (IsPotentialUnboxedLoad()) { 2115 if (IsPotentialUnboxedLoad()) {
1986 Register temp = locs()->temp(1).reg(); 2116 Register temp = locs()->temp(1).reg();
1987 XmmRegister value = locs()->temp(0).fpu_reg(); 2117 XmmRegister value = locs()->temp(0).fpu_reg();
2118 LoadFieldSlowPath* slow_path = new LoadFieldSlowPath(this);
2119 compiler->AddSlowPathCode(slow_path);
1988 2120
1989 Label load_pointer; 2121 Label load_pointer;
1990 Label load_double; 2122 Label load_double;
2123 Label load_float32x4;
2124
1991 __ LoadObject(result, Field::ZoneHandle(field()->raw())); 2125 __ LoadObject(result, Field::ZoneHandle(field()->raw()));
1992 2126
1993 FieldAddress field_cid_operand(result, Field::guarded_cid_offset()); 2127 FieldAddress field_cid_operand(result, Field::guarded_cid_offset());
1994 FieldAddress field_nullability_operand(result, Field::is_nullable_offset()); 2128 FieldAddress field_nullability_operand(result, Field::is_nullable_offset());
1995 2129
1996 __ cmpl(field_nullability_operand, Immediate(kNullCid)); 2130 __ cmpl(field_nullability_operand, Immediate(kNullCid));
1997 __ j(EQUAL, &load_pointer); 2131 __ j(EQUAL, &load_pointer);
1998 2132
1999 __ cmpl(field_cid_operand, Immediate(kDoubleCid)); 2133 __ cmpl(field_cid_operand, Immediate(kDoubleCid));
2000 __ j(EQUAL, &load_double); 2134 __ j(EQUAL, &load_double);
2001 2135
2136 __ cmpl(field_cid_operand, Immediate(kFloat32x4Cid));
2137 __ j(EQUAL, &load_float32x4);
2138
2002 // Fall through. 2139 // Fall through.
2003 __ jmp(&load_pointer); 2140 __ jmp(&load_pointer);
2004 2141
2005 __ Bind(&load_double); 2142 {
2006 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 2143 __ Bind(&load_double);
2007 compiler->AddSlowPathCode(slow_path);
2008 2144
2009 if (!compiler->is_optimizing()) { 2145 if (!compiler->is_optimizing()) {
2010 locs()->live_registers()->Add(locs()->in(0)); 2146 locs()->live_registers()->Add(locs()->in(0));
2147 }
2148
2149 __ TryAllocate(compiler->double_class(),
2150 slow_path->double_entry_label(),
2151 Assembler::kFarJump,
2152 result,
2153 temp);
2154 __ Bind(slow_path->double_exit_label());
2155 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes()));
2156 __ movsd(value, FieldAddress(temp, Double::value_offset()));
2157 __ movsd(FieldAddress(result, Double::value_offset()), value);
2158 __ jmp(&done);
2011 } 2159 }
2012 2160
2013 __ TryAllocate(compiler->double_class(), 2161 {
2014 slow_path->entry_label(), 2162 __ Bind(&load_float32x4);
2015 Assembler::kFarJump,
2016 result,
2017 temp);
2018 __ Bind(slow_path->exit_label());
2019 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes()));
2020 __ movsd(value, FieldAddress(temp, Double::value_offset()));
2021 __ movsd(FieldAddress(result, Double::value_offset()), value);
2022 __ jmp(&done);
2023 2163
2024 // TODO(johnmccutchan): Add Float32x4 path here. 2164 if (!compiler->is_optimizing()) {
2165 locs()->live_registers()->Add(locs()->in(0));
2166 }
2167
2168 __ TryAllocate(compiler->float32x4_class(),
2169 slow_path->float32x4_entry_label(),
2170 Assembler::kFarJump,
2171 result,
2172 temp);
2173 __ Bind(slow_path->float32x4_exit_label());
2174 __ movl(temp, FieldAddress(instance_reg, offset_in_bytes()));
2175 __ movups(value, FieldAddress(temp, Float32x4::value_offset()));
2176 __ movups(FieldAddress(result, Float32x4::value_offset()), value);
2177 __ jmp(&done);
2178 }
2025 2179
2026 __ Bind(&load_pointer); 2180 __ Bind(&load_pointer);
2027 } 2181 }
2028 __ movl(result, FieldAddress(instance_reg, offset_in_bytes())); 2182 __ movl(result, FieldAddress(instance_reg, offset_in_bytes()));
2029 __ Bind(&done); 2183 __ Bind(&done);
2030 } 2184 }
2031 2185
2032 2186
2033 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2187 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
2034 const intptr_t kNumInputs = 1; 2188 const intptr_t kNumInputs = 1;
(...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after
2870 } else { 3024 } else {
2871 Register temp = locs()->temp(0).reg(); 3025 Register temp = locs()->temp(0).reg();
2872 __ movl(temp, left); 3026 __ movl(temp, left);
2873 __ orl(temp, right); 3027 __ orl(temp, right);
2874 __ testl(temp, Immediate(kSmiTagMask)); 3028 __ testl(temp, Immediate(kSmiTagMask));
2875 } 3029 }
2876 __ j(ZERO, deopt); 3030 __ j(ZERO, deopt);
2877 } 3031 }
2878 3032
2879 3033
3034 class BoxDoubleSlowPath : public SlowPathCode {
3035 public:
3036 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction)
3037 : instruction_(instruction) { }
3038
3039 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
3040 __ Comment("BoxDoubleSlowPath");
3041 __ Bind(entry_label());
3042 const Class& double_class = compiler->double_class();
3043 const Code& stub =
3044 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
3045 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
3046
3047 LocationSummary* locs = instruction_->locs();
3048 locs->live_registers()->Remove(locs->out());
3049
3050 compiler->SaveLiveRegisters(locs);
3051 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
3052 &label,
3053 PcDescriptors::kOther,
3054 locs);
3055 __ MoveRegister(locs->out().reg(), EAX);
3056 compiler->RestoreLiveRegisters(locs);
3057
3058 __ jmp(exit_label());
3059 }
3060
3061 private:
3062 BoxDoubleInstr* instruction_;
3063 };
3064
3065
2880 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const { 3066 LocationSummary* BoxDoubleInstr::MakeLocationSummary(bool opt) const {
2881 const intptr_t kNumInputs = 1; 3067 const intptr_t kNumInputs = 1;
2882 const intptr_t kNumTemps = 0; 3068 const intptr_t kNumTemps = 0;
2883 LocationSummary* summary = 3069 LocationSummary* summary =
2884 new LocationSummary(kNumInputs, 3070 new LocationSummary(kNumInputs,
2885 kNumTemps, 3071 kNumTemps,
2886 LocationSummary::kCallOnSlowPath); 3072 LocationSummary::kCallOnSlowPath);
2887 summary->set_in(0, Location::RequiresFpuRegister()); 3073 summary->set_in(0, Location::RequiresFpuRegister());
2888 summary->set_out(Location::RequiresRegister()); 3074 summary->set_out(Location::RequiresRegister());
2889 return summary; 3075 return summary;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2946 __ jmp(&done); 3132 __ jmp(&done);
2947 __ Bind(&is_smi); 3133 __ Bind(&is_smi);
2948 __ movl(temp, value); 3134 __ movl(temp, value);
2949 __ SmiUntag(temp); 3135 __ SmiUntag(temp);
2950 __ cvtsi2sd(result, temp); 3136 __ cvtsi2sd(result, temp);
2951 __ Bind(&done); 3137 __ Bind(&done);
2952 } 3138 }
2953 } 3139 }
2954 3140
2955 3141
2956 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const {
2957 const intptr_t kNumInputs = 1;
2958 const intptr_t kNumTemps = 0;
2959 LocationSummary* summary =
2960 new LocationSummary(kNumInputs,
2961 kNumTemps,
2962 LocationSummary::kCallOnSlowPath);
2963 summary->set_in(0, Location::RequiresFpuRegister());
2964 summary->set_out(Location::RequiresRegister());
2965 return summary;
2966 }
2967
2968
2969 class BoxFloat32x4SlowPath : public SlowPathCode { 3142 class BoxFloat32x4SlowPath : public SlowPathCode {
2970 public: 3143 public:
2971 explicit BoxFloat32x4SlowPath(BoxFloat32x4Instr* instruction) 3144 explicit BoxFloat32x4SlowPath(BoxFloat32x4Instr* instruction)
2972 : instruction_(instruction) { } 3145 : instruction_(instruction) { }
2973 3146
2974 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 3147 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2975 __ Comment("BoxFloat32x4SlowPath"); 3148 __ Comment("BoxFloat32x4SlowPath");
2976 __ Bind(entry_label()); 3149 __ Bind(entry_label());
2977 const Class& float32x4_class = compiler->float32x4_class(); 3150 const Class& float32x4_class = compiler->float32x4_class();
2978 const Code& stub = 3151 const Code& stub =
(...skipping 12 matching lines...) Expand all
2991 compiler->RestoreLiveRegisters(locs); 3164 compiler->RestoreLiveRegisters(locs);
2992 3165
2993 __ jmp(exit_label()); 3166 __ jmp(exit_label());
2994 } 3167 }
2995 3168
2996 private: 3169 private:
2997 BoxFloat32x4Instr* instruction_; 3170 BoxFloat32x4Instr* instruction_;
2998 }; 3171 };
2999 3172
3000 3173
3174 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(bool opt) const {
3175 const intptr_t kNumInputs = 1;
3176 const intptr_t kNumTemps = 0;
3177 LocationSummary* summary =
3178 new LocationSummary(kNumInputs,
3179 kNumTemps,
3180 LocationSummary::kCallOnSlowPath);
3181 summary->set_in(0, Location::RequiresFpuRegister());
3182 summary->set_out(Location::RequiresRegister());
3183 return summary;
3184 }
3185
3186
3001 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3187 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3002 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); 3188 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this);
3003 compiler->AddSlowPathCode(slow_path); 3189 compiler->AddSlowPathCode(slow_path);
3004 3190
3005 Register out_reg = locs()->out().reg(); 3191 Register out_reg = locs()->out().reg();
3006 XmmRegister value = locs()->in(0).fpu_reg(); 3192 XmmRegister value = locs()->in(0).fpu_reg();
3007 3193
3008 __ TryAllocate(compiler->float32x4_class(), 3194 __ TryAllocate(compiler->float32x4_class(),
3009 slow_path->entry_label(), 3195 slow_path->entry_label(),
3010 Assembler::kFarJump, 3196 Assembler::kFarJump,
(...skipping 2270 matching lines...) Expand 10 before | Expand all | Expand 10 after
5281 PcDescriptors::kOther, 5467 PcDescriptors::kOther,
5282 locs()); 5468 locs());
5283 __ Drop(2); // Discard type arguments and receiver. 5469 __ Drop(2); // Discard type arguments and receiver.
5284 } 5470 }
5285 5471
5286 } // namespace dart 5472 } // namespace dart
5287 5473
5288 #undef __ 5474 #undef __
5289 5475
5290 #endif // defined TARGET_ARCH_IA32 5476 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698