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

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
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1572 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 1583
1584 class StoreInstanceFieldSlowPath : public SlowPathCode { 1584 class StoreInstanceFieldSlowPath : public SlowPathCode {
1585 public: 1585 public:
1586 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction, 1586 StoreInstanceFieldSlowPath(StoreInstanceFieldInstr* instruction,
1587 const Class& cls) 1587 const Class& cls)
1588 : instruction_(instruction), cls_(cls) { } 1588 : instruction_(instruction), cls_(cls) { }
1589 1589
1590 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1590 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1591 __ Comment("StoreInstanceFieldSlowPath"); 1591 __ Comment("StoreInstanceFieldSlowPath");
1592 __ Bind(entry_label()); 1592 __ Bind(entry_label());
1593
1593 const Code& stub = 1594 const Code& stub =
1594 Code::Handle(StubCode::GetAllocationStubForClass(cls_)); 1595 Code::Handle(StubCode::GetAllocationStubForClass(cls_));
1595 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint()); 1596 const ExternalLabel label(cls_.ToCString(), stub.EntryPoint());
1596 1597
1597 LocationSummary* locs = instruction_->locs(); 1598 LocationSummary* locs = instruction_->locs();
1598 locs->live_registers()->Remove(locs->out()); 1599 locs->live_registers()->Remove(locs->out());
1599 1600
1600 compiler->SaveLiveRegisters(locs); 1601 compiler->SaveLiveRegisters(locs);
1601 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. 1602 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
1602 &label, 1603 &label,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 } 1646 }
1646 1647
1647 1648
1648 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1649 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1649 Label skip_store; 1650 Label skip_store;
1650 1651
1651 Register instance_reg = locs()->in(0).reg(); 1652 Register instance_reg = locs()->in(0).reg();
1652 1653
1653 if (IsUnboxedStore() && compiler->is_optimizing()) { 1654 if (IsUnboxedStore() && compiler->is_optimizing()) {
1654 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg()); 1655 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg());
1656 DRegister value_odd = OddDRegisterOf(locs()->in(1).fpu_reg());
1655 Register temp = locs()->temp(0).reg(); 1657 Register temp = locs()->temp(0).reg();
1656 Register temp2 = locs()->temp(1).reg(); 1658 Register temp2 = locs()->temp(1).reg();
1657 const intptr_t cid = field().UnboxedFieldCid(); 1659 const intptr_t cid = field().UnboxedFieldCid();
1658 1660
1659 if (is_initialization_) { 1661 if (is_initialization_) {
1660 const Class* cls = NULL; 1662 const Class* cls = NULL;
1661 switch (cid) { 1663 switch (cid) {
1662 case kDoubleCid: 1664 case kDoubleCid:
1663 cls = &compiler->double_class(); 1665 cls = &compiler->double_class();
1664 break; 1666 break;
1665 // TODO(johnmccutchan): Add kFloat32x4Cid here. 1667 case kFloat32x4Cid:
1668 cls = &compiler->float32x4_class();
1669 break;
1666 default: 1670 default:
1667 UNREACHABLE(); 1671 UNREACHABLE();
1668 } 1672 }
1673
1669 StoreInstanceFieldSlowPath* slow_path = 1674 StoreInstanceFieldSlowPath* slow_path =
1670 new StoreInstanceFieldSlowPath(this, *cls); 1675 new StoreInstanceFieldSlowPath(this, *cls);
1671 compiler->AddSlowPathCode(slow_path); 1676 compiler->AddSlowPathCode(slow_path);
1677
1672 __ TryAllocate(*cls, 1678 __ TryAllocate(*cls,
1673 slow_path->entry_label(), 1679 slow_path->entry_label(),
1674 temp, 1680 temp,
1675 temp2); 1681 temp2);
1676 __ Bind(slow_path->exit_label()); 1682 __ Bind(slow_path->exit_label());
1677 __ MoveRegister(temp2, temp); 1683 __ MoveRegister(temp2, temp);
1678 __ StoreIntoObject(instance_reg, 1684 __ StoreIntoObject(instance_reg,
1679 FieldAddress(instance_reg, field().Offset()), 1685 FieldAddress(instance_reg, field().Offset()),
1680 temp2); 1686 temp2);
1681 } else { 1687 } else {
1682 __ ldr(temp, FieldAddress(instance_reg, field().Offset())); 1688 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1683 } 1689 }
1684 switch (cid) { 1690 switch (cid) {
1685 case kDoubleCid: 1691 case kDoubleCid:
1686 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); 1692 __ Comment("UnboxedDoubleStoreInstanceFieldInstr");
1687 // TODO(johnmccutchan): Add kFloat32x4Cid here. 1693 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag);
1688 break; 1694 break;
1695 case kFloat32x4Cid:
1696 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr");
1697 __ StoreDToOffset(value, temp,
1698 Float32x4::value_offset() - kHeapObjectTag);
1699 __ StoreDToOffset(value_odd, temp,
1700 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
1701 break;
1689 default: 1702 default:
1690 UNREACHABLE(); 1703 UNREACHABLE();
1691 } 1704 }
1692 1705
1693 return; 1706 return;
1694 } 1707 }
1695 1708
1696 if (IsPotentialUnboxedStore()) { 1709 if (IsPotentialUnboxedStore()) {
1697 Register value_reg = locs()->in(1).reg(); 1710 Register value_reg = locs()->in(1).reg();
1698 Register temp = locs()->temp(0).reg(); 1711 Register temp = locs()->temp(0).reg();
1699 Register temp2 = locs()->temp(1).reg(); 1712 Register temp2 = locs()->temp(1).reg();
1700 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); 1713 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg());
1714 DRegister fpu_temp_odd = OddDRegisterOf(locs()->temp(2).fpu_reg());
1701 1715
1702 Label store_pointer; 1716 Label store_pointer;
1703 Label copy_double;
1704 Label store_double; 1717 Label store_double;
1718 Label store_float32x4;
1705 1719
1706 __ LoadObject(temp, Field::ZoneHandle(field().raw())); 1720 __ LoadObject(temp, Field::ZoneHandle(field().raw()));
1707 1721
1708 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); 1722 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset()));
1709 __ CompareImmediate(temp2, kNullCid); 1723 __ CompareImmediate(temp2, kNullCid);
1710 __ b(&store_pointer, EQ); 1724 __ b(&store_pointer, EQ);
1711 1725
1712 __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset())); 1726 __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset()));
1713 __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit)); 1727 __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit));
1714 __ b(&store_pointer, EQ); 1728 __ b(&store_pointer, EQ);
1715 1729
1716 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); 1730 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset()));
1717 __ CompareImmediate(temp2, kDoubleCid); 1731 __ CompareImmediate(temp2, kDoubleCid);
1718 __ b(&store_double, EQ); 1732 __ b(&store_double, EQ);
1719 1733
1734 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset()));
1735 __ CompareImmediate(temp2, kFloat32x4Cid);
1736 __ b(&store_float32x4, EQ);
1737
1720 // Fall through. 1738 // Fall through.
1721 __ b(&store_pointer); 1739 __ b(&store_pointer);
1722 1740
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 =
1731 new StoreInstanceFieldSlowPath(this, compiler->double_class());
1732 compiler->AddSlowPathCode(slow_path);
1733
1734 if (!compiler->is_optimizing()) { 1741 if (!compiler->is_optimizing()) {
1735 locs()->live_registers()->Add(locs()->in(0)); 1742 locs()->live_registers()->Add(locs()->in(0));
1736 locs()->live_registers()->Add(locs()->in(1)); 1743 locs()->live_registers()->Add(locs()->in(1));
1737 } 1744 }
1738 1745
1739 __ TryAllocate(compiler->double_class(), 1746 {
1740 slow_path->entry_label(), 1747 __ Bind(&store_double);
1741 temp, 1748 Label copy_double;
1742 temp2); 1749 StoreInstanceFieldSlowPath* slow_path =
1743 __ Bind(slow_path->exit_label()); 1750 new StoreInstanceFieldSlowPath(this, compiler->double_class());
1744 __ MoveRegister(temp2, temp); 1751 compiler->AddSlowPathCode(slow_path);
1745 __ StoreIntoObject(instance_reg, 1752
1746 FieldAddress(instance_reg, field().Offset()), 1753 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1747 temp2); 1754 __ CompareImmediate(temp,
1748 __ Bind(&copy_double); 1755 reinterpret_cast<intptr_t>(Object::null()));
1749 __ LoadDFromOffset(fpu_temp, 1756 __ b(&copy_double, NE);
1750 value_reg, 1757
1751 Double::value_offset() - kHeapObjectTag); 1758 __ TryAllocate(compiler->double_class(),
1752 __ StoreDToOffset(fpu_temp, temp, Double::value_offset() - kHeapObjectTag); 1759 slow_path->entry_label(),
1753 __ b(&skip_store); 1760 temp,
1761 temp2);
1762 __ Bind(slow_path->exit_label());
1763 __ MoveRegister(temp2, temp);
1764 __ StoreIntoObject(instance_reg,
1765 FieldAddress(instance_reg, field().Offset()),
1766 temp2);
1767 __ Bind(&copy_double);
1768 __ LoadDFromOffset(fpu_temp,
1769 value_reg,
1770 Double::value_offset() - kHeapObjectTag);
1771 __ StoreDToOffset(fpu_temp,
1772 temp,
1773 Double::value_offset() - kHeapObjectTag);
1774 __ b(&skip_store);
1775 }
1776
1777 {
1778 __ Bind(&store_float32x4);
1779 Label copy_float32x4;
1780 StoreInstanceFieldSlowPath* slow_path =
1781 new StoreInstanceFieldSlowPath(this, compiler->float32x4_class());
1782 compiler->AddSlowPathCode(slow_path);
1783
1784 __ ldr(temp, FieldAddress(instance_reg, field().Offset()));
1785 __ CompareImmediate(temp,
1786 reinterpret_cast<intptr_t>(Object::null()));
1787 __ b(&copy_float32x4, NE);
1788
1789 __ TryAllocate(compiler->float32x4_class(),
1790 slow_path->entry_label(),
1791 temp,
1792 temp2);
1793 __ Bind(slow_path->exit_label());
1794 __ MoveRegister(temp2, temp);
1795 __ StoreIntoObject(instance_reg,
1796 FieldAddress(instance_reg, field().Offset()),
1797 temp2);
1798 __ Bind(&copy_float32x4);
1799 __ LoadDFromOffset(fpu_temp, value_reg,
1800 Float32x4::value_offset() - kHeapObjectTag);
1801 __ LoadDFromOffset(fpu_temp_odd, value_reg,
1802 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
1803 __ StoreDToOffset(fpu_temp, temp,
1804 Float32x4::value_offset() - kHeapObjectTag);
1805 __ StoreDToOffset(fpu_temp_odd, temp,
1806 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
1807 __ b(&skip_store);
1808 }
1809
1754 __ Bind(&store_pointer); 1810 __ Bind(&store_pointer);
1755 } 1811 }
1756 1812
1757 if (ShouldEmitStoreBarrier()) { 1813 if (ShouldEmitStoreBarrier()) {
1758 Register value_reg = locs()->in(1).reg(); 1814 Register value_reg = locs()->in(1).reg();
1759 __ StoreIntoObject(instance_reg, 1815 __ StoreIntoObject(instance_reg,
1760 FieldAddress(instance_reg, field().Offset()), 1816 FieldAddress(instance_reg, field().Offset()),
1761 value_reg, 1817 value_reg,
1762 CanValueBeSmi()); 1818 CanValueBeSmi());
1763 } else { 1819 } else {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 compiler->RestoreLiveRegisters(locs); 1975 compiler->RestoreLiveRegisters(locs);
1920 1976
1921 __ b(exit_label()); 1977 __ b(exit_label());
1922 } 1978 }
1923 1979
1924 private: 1980 private:
1925 Instruction* instruction_; 1981 Instruction* instruction_;
1926 }; 1982 };
1927 1983
1928 1984
1985 class BoxFloat32x4SlowPath : public SlowPathCode {
1986 public:
1987 explicit BoxFloat32x4SlowPath(Instruction* instruction)
1988 : instruction_(instruction) { }
1989
1990 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1991 __ Comment("BoxFloat32x4SlowPath");
1992 __ Bind(entry_label());
1993 const Class& float32x4_class = compiler->float32x4_class();
1994 const Code& stub =
1995 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class));
1996 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint());
1997
1998 LocationSummary* locs = instruction_->locs();
1999 locs->live_registers()->Remove(locs->out());
2000
2001 compiler->SaveLiveRegisters(locs);
2002 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2003 &label,
2004 PcDescriptors::kOther,
2005 locs);
2006 __ mov(locs->out().reg(), ShifterOperand(R0));
2007 compiler->RestoreLiveRegisters(locs);
2008
2009 __ b(exit_label());
2010 }
2011
2012 private:
2013 Instruction* instruction_;
2014 };
2015
2016
1929 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const { 2017 LocationSummary* LoadFieldInstr::MakeLocationSummary(bool opt) const {
1930 const intptr_t kNumInputs = 1; 2018 const intptr_t kNumInputs = 1;
1931 const intptr_t kNumTemps = 0; 2019 const intptr_t kNumTemps = 0;
1932 LocationSummary* locs = 2020 LocationSummary* locs =
1933 new LocationSummary( 2021 new LocationSummary(
1934 kNumInputs, kNumTemps, 2022 kNumInputs, kNumTemps,
1935 (opt && !IsPotentialUnboxedLoad()) 2023 (opt && !IsPotentialUnboxedLoad())
1936 ? LocationSummary::kNoCall 2024 ? LocationSummary::kNoCall
1937 : LocationSummary::kCallOnSlowPath); 2025 : LocationSummary::kCallOnSlowPath);
1938 2026
1939 locs->set_in(0, Location::RequiresRegister()); 2027 locs->set_in(0, Location::RequiresRegister());
1940 2028
1941 if (IsUnboxedLoad() && opt) { 2029 if (IsUnboxedLoad() && opt) {
1942 locs->AddTemp(Location::RequiresRegister()); 2030 locs->AddTemp(Location::RequiresRegister());
1943 } else if (IsPotentialUnboxedLoad()) { 2031 } else if (IsPotentialUnboxedLoad()) {
1944 locs->AddTemp(opt ? Location::RequiresFpuRegister() 2032 locs->AddTemp(opt ? Location::RequiresFpuRegister()
1945 : Location::FpuRegisterLocation(Q1)); 2033 : Location::FpuRegisterLocation(Q1));
1946 locs->AddTemp(Location::RequiresRegister()); 2034 locs->AddTemp(Location::RequiresRegister());
1947 } 2035 }
1948 locs->set_out(Location::RequiresRegister()); 2036 locs->set_out(Location::RequiresRegister());
1949 return locs; 2037 return locs;
1950 } 2038 }
1951 2039
1952 2040
1953 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2041 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1954 Register instance_reg = locs()->in(0).reg(); 2042 Register instance_reg = locs()->in(0).reg();
1955 if (IsUnboxedLoad() && compiler->is_optimizing()) { 2043 if (IsUnboxedLoad() && compiler->is_optimizing()) {
1956 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg()); 2044 DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
2045 DRegister result_odd = OddDRegisterOf(locs()->out().fpu_reg());
1957 Register temp = locs()->temp(0).reg(); 2046 Register temp = locs()->temp(0).reg();
1958 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); 2047 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
1959 intptr_t cid = field()->UnboxedFieldCid(); 2048 intptr_t cid = field()->UnboxedFieldCid();
1960 switch (cid) { 2049 switch (cid) {
1961 case kDoubleCid: 2050 case kDoubleCid:
2051 __ Comment("UnboxedDoubleLoadFieldInstr");
1962 __ LoadDFromOffset(result, temp, 2052 __ LoadDFromOffset(result, temp,
1963 Double::value_offset() - kHeapObjectTag); 2053 Double::value_offset() - kHeapObjectTag);
1964 break; 2054 break;
1965 // TODO(johnmccutchan): Add Float32x4 path here. 2055 case kFloat32x4Cid:
2056 __ Comment("UnboxedFloat32x4LoadFieldInstr");
2057 __ LoadDFromOffset(result, temp,
2058 Float32x4::value_offset() - kHeapObjectTag);
2059 __ LoadDFromOffset(result_odd, temp,
2060 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2061 break;
1966 default: 2062 default:
1967 UNREACHABLE(); 2063 UNREACHABLE();
1968 } 2064 }
1969 return; 2065 return;
1970 } 2066 }
1971 2067
1972 Label done; 2068 Label done;
1973 Register result_reg = locs()->out().reg(); 2069 Register result_reg = locs()->out().reg();
1974 if (IsPotentialUnboxedLoad()) { 2070 if (IsPotentialUnboxedLoad()) {
1975 Register temp = locs()->temp(1).reg(); 2071 Register temp = locs()->temp(1).reg();
1976 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); 2072 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg());
2073 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg());
1977 2074
1978 Label load_pointer; 2075 Label load_pointer;
1979 Label load_double; 2076 Label load_double;
2077 Label load_float32x4;
1980 2078
1981 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); 2079 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()));
1982 2080
1983 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); 2081 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset());
1984 FieldAddress field_nullability_operand(result_reg, 2082 FieldAddress field_nullability_operand(result_reg,
1985 Field::is_nullable_offset()); 2083 Field::is_nullable_offset());
1986 2084
1987 __ ldr(temp, field_nullability_operand); 2085 __ ldr(temp, field_nullability_operand);
1988 __ CompareImmediate(temp, kNullCid); 2086 __ CompareImmediate(temp, kNullCid);
1989 __ b(&load_pointer, EQ); 2087 __ b(&load_pointer, EQ);
1990 2088
1991 __ ldr(temp, field_cid_operand); 2089 __ ldr(temp, field_cid_operand);
1992 __ CompareImmediate(temp, kDoubleCid); 2090 __ CompareImmediate(temp, kDoubleCid);
1993 __ b(&load_double, EQ); 2091 __ b(&load_double, EQ);
1994 2092
2093 __ ldr(temp, field_cid_operand);
2094 __ CompareImmediate(temp, kFloat32x4Cid);
2095 __ b(&load_float32x4, EQ);
2096
1995 // Fall through. 2097 // Fall through.
1996 __ b(&load_pointer); 2098 __ b(&load_pointer);
1997 2099
1998 __ Bind(&load_double);
1999
2000 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2001 compiler->AddSlowPathCode(slow_path);
2002
2003 if (!compiler->is_optimizing()) { 2100 if (!compiler->is_optimizing()) {
2004 locs()->live_registers()->Add(locs()->in(0)); 2101 locs()->live_registers()->Add(locs()->in(0));
2005 } 2102 }
2006 2103
2007 __ TryAllocate(compiler->double_class(), 2104 {
2008 slow_path->entry_label(), 2105 __ Bind(&load_double);
2009 result_reg, 2106 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
2010 temp); 2107 compiler->AddSlowPathCode(slow_path);
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 2108
2019 // TODO(johnmccutchan): Add Float32x4 path here. 2109 __ TryAllocate(compiler->double_class(),
2110 slow_path->entry_label(),
2111 result_reg,
2112 temp);
2113 __ Bind(slow_path->exit_label());
2114 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
2115 __ LoadDFromOffset(value, temp, Double::value_offset() - kHeapObjectTag);
2116 __ StoreDToOffset(value,
2117 result_reg,
2118 Double::value_offset() - kHeapObjectTag);
2119 __ b(&done);
2120 }
2121
2122 {
2123 __ Bind(&load_float32x4);
2124 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this);
2125 compiler->AddSlowPathCode(slow_path);
2126
2127 __ TryAllocate(compiler->float32x4_class(),
2128 slow_path->entry_label(),
2129 result_reg,
2130 temp);
2131 __ Bind(slow_path->exit_label());
2132 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes()));
2133 __ LoadDFromOffset(value, temp,
2134 Float32x4::value_offset() - kHeapObjectTag);
2135 __ LoadDFromOffset(value_odd, temp,
2136 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2137 __ StoreDToOffset(value, result_reg,
2138 Float32x4::value_offset() - kHeapObjectTag);
2139 __ StoreDToOffset(value_odd, result_reg,
2140 Float32x4::value_offset() + 2*kWordSize - kHeapObjectTag);
2141 __ b(&done);
2142 }
2020 2143
2021 __ Bind(&load_pointer); 2144 __ Bind(&load_pointer);
2022 } 2145 }
2023 __ LoadFromOffset(kWord, result_reg, 2146 __ LoadFromOffset(kWord, result_reg,
2024 instance_reg, offset_in_bytes() - kHeapObjectTag); 2147 instance_reg, offset_in_bytes() - kHeapObjectTag);
2025 __ Bind(&done); 2148 __ Bind(&done);
2026 } 2149 }
2027 2150
2028 2151
2029 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { 2152 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const {
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
2909 new LocationSummary(kNumInputs, 3032 new LocationSummary(kNumInputs,
2910 kNumTemps, 3033 kNumTemps,
2911 LocationSummary::kCallOnSlowPath); 3034 LocationSummary::kCallOnSlowPath);
2912 summary->set_in(0, Location::RequiresFpuRegister()); 3035 summary->set_in(0, Location::RequiresFpuRegister());
2913 summary->set_temp(0, Location::RequiresRegister()); 3036 summary->set_temp(0, Location::RequiresRegister());
2914 summary->set_out(Location::RequiresRegister()); 3037 summary->set_out(Location::RequiresRegister());
2915 return summary; 3038 return summary;
2916 } 3039 }
2917 3040
2918 3041
2919 class BoxFloat32x4SlowPath : public SlowPathCode {
2920 public:
2921 explicit BoxFloat32x4SlowPath(BoxFloat32x4Instr* instruction)
2922 : instruction_(instruction) { }
2923
2924 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
2925 __ Comment("BoxFloat32x4SlowPath");
2926 __ Bind(entry_label());
2927 const Class& float32x4_class = compiler->float32x4_class();
2928 const Code& stub =
2929 Code::Handle(StubCode::GetAllocationStubForClass(float32x4_class));
2930 const ExternalLabel label(float32x4_class.ToCString(), stub.EntryPoint());
2931
2932 LocationSummary* locs = instruction_->locs();
2933 locs->live_registers()->Remove(locs->out());
2934
2935 compiler->SaveLiveRegisters(locs);
2936 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position.
2937 &label,
2938 PcDescriptors::kOther,
2939 locs);
2940 __ mov(locs->out().reg(), ShifterOperand(R0));
2941 compiler->RestoreLiveRegisters(locs);
2942
2943 __ b(exit_label());
2944 }
2945
2946 private:
2947 BoxFloat32x4Instr* instruction_;
2948 };
2949
2950
2951 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3042 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
2952 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); 3043 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this);
2953 compiler->AddSlowPathCode(slow_path); 3044 compiler->AddSlowPathCode(slow_path);
2954 3045
2955 Register out_reg = locs()->out().reg(); 3046 Register out_reg = locs()->out().reg();
2956 QRegister value = locs()->in(0).fpu_reg(); 3047 QRegister value = locs()->in(0).fpu_reg();
2957 DRegister value_even = EvenDRegisterOf(value); 3048 DRegister value_even = EvenDRegisterOf(value);
2958 DRegister value_odd = OddDRegisterOf(value); 3049 DRegister value_odd = OddDRegisterOf(value);
2959 3050
2960 __ TryAllocate(compiler->float32x4_class(), 3051 __ TryAllocate(compiler->float32x4_class(),
(...skipping 1926 matching lines...) Expand 10 before | Expand all | Expand 10 after
4887 compiler->GenerateCall(token_pos(), 4978 compiler->GenerateCall(token_pos(),
4888 &label, 4979 &label,
4889 PcDescriptors::kOther, 4980 PcDescriptors::kOther,
4890 locs()); 4981 locs());
4891 __ Drop(2); // Discard type arguments and receiver. 4982 __ Drop(2); // Discard type arguments and receiver.
4892 } 4983 }
4893 4984
4894 } // namespace dart 4985 } // namespace dart
4895 4986
4896 #endif // defined TARGET_ARCH_ARM 4987 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698