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_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 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 | 1680 |
1681 if (is_initialization_) { | 1681 if (is_initialization_) { |
1682 const Class* cls = NULL; | 1682 const Class* cls = NULL; |
1683 switch (cid) { | 1683 switch (cid) { |
1684 case kDoubleCid: | 1684 case kDoubleCid: |
1685 cls = &compiler->double_class(); | 1685 cls = &compiler->double_class(); |
1686 break; | 1686 break; |
1687 case kFloat32x4Cid: | 1687 case kFloat32x4Cid: |
1688 cls = &compiler->float32x4_class(); | 1688 cls = &compiler->float32x4_class(); |
1689 break; | 1689 break; |
| 1690 case kFloat64x2Cid: |
| 1691 cls = &compiler->float64x2_class(); |
| 1692 break; |
1690 default: | 1693 default: |
1691 UNREACHABLE(); | 1694 UNREACHABLE(); |
1692 } | 1695 } |
1693 | 1696 |
1694 StoreInstanceFieldSlowPath* slow_path = | 1697 StoreInstanceFieldSlowPath* slow_path = |
1695 new StoreInstanceFieldSlowPath(this, *cls); | 1698 new StoreInstanceFieldSlowPath(this, *cls); |
1696 compiler->AddSlowPathCode(slow_path); | 1699 compiler->AddSlowPathCode(slow_path); |
1697 | 1700 |
1698 __ TryAllocate(*cls, | 1701 __ TryAllocate(*cls, |
1699 slow_path->entry_label(), | 1702 slow_path->entry_label(), |
(...skipping 12 matching lines...) Expand all Loading... |
1712 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); | 1715 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); |
1713 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); | 1716 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
1714 break; | 1717 break; |
1715 case kFloat32x4Cid: | 1718 case kFloat32x4Cid: |
1716 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); | 1719 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); |
1717 __ StoreDToOffset(value, temp, | 1720 __ StoreDToOffset(value, temp, |
1718 Float32x4::value_offset() - kHeapObjectTag); | 1721 Float32x4::value_offset() - kHeapObjectTag); |
1719 __ StoreDToOffset(value_odd, temp, | 1722 __ StoreDToOffset(value_odd, temp, |
1720 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 1723 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
1721 break; | 1724 break; |
| 1725 case kFloat64x2Cid: |
| 1726 __ Comment("UnboxedFloat64x2StoreInstanceFieldInstr"); |
| 1727 __ StoreDToOffset(value, temp, |
| 1728 Float64x2::value_offset() - kHeapObjectTag); |
| 1729 __ StoreDToOffset(value_odd, temp, |
| 1730 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 1731 break; |
1722 default: | 1732 default: |
1723 UNREACHABLE(); | 1733 UNREACHABLE(); |
1724 } | 1734 } |
1725 | 1735 |
1726 return; | 1736 return; |
1727 } | 1737 } |
1728 | 1738 |
1729 if (IsPotentialUnboxedStore()) { | 1739 if (IsPotentialUnboxedStore()) { |
1730 Register value_reg = locs()->in(1).reg(); | 1740 Register value_reg = locs()->in(1).reg(); |
1731 Register temp = locs()->temp(0).reg(); | 1741 Register temp = locs()->temp(0).reg(); |
1732 Register temp2 = locs()->temp(1).reg(); | 1742 Register temp2 = locs()->temp(1).reg(); |
1733 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); | 1743 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); |
1734 DRegister fpu_temp_odd = OddDRegisterOf(locs()->temp(2).fpu_reg()); | 1744 DRegister fpu_temp_odd = OddDRegisterOf(locs()->temp(2).fpu_reg()); |
1735 | 1745 |
1736 Label store_pointer; | 1746 Label store_pointer; |
1737 Label store_double; | 1747 Label store_double; |
1738 Label store_float32x4; | 1748 Label store_float32x4; |
| 1749 Label store_float64x2; |
1739 | 1750 |
1740 __ LoadObject(temp, Field::ZoneHandle(field().raw())); | 1751 __ LoadObject(temp, Field::ZoneHandle(field().raw())); |
1741 | 1752 |
1742 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); | 1753 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); |
1743 __ CompareImmediate(temp2, kNullCid); | 1754 __ CompareImmediate(temp2, kNullCid); |
1744 __ b(&store_pointer, EQ); | 1755 __ b(&store_pointer, EQ); |
1745 | 1756 |
1746 __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset())); | 1757 __ ldrb(temp2, FieldAddress(temp, Field::kind_bits_offset())); |
1747 __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit)); | 1758 __ tst(temp2, ShifterOperand(1 << Field::kUnboxingCandidateBit)); |
1748 __ b(&store_pointer, EQ); | 1759 __ b(&store_pointer, EQ); |
1749 | 1760 |
1750 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); | 1761 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); |
1751 __ CompareImmediate(temp2, kDoubleCid); | 1762 __ CompareImmediate(temp2, kDoubleCid); |
1752 __ b(&store_double, EQ); | 1763 __ b(&store_double, EQ); |
1753 | 1764 |
1754 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); | 1765 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); |
1755 __ CompareImmediate(temp2, kFloat32x4Cid); | 1766 __ CompareImmediate(temp2, kFloat32x4Cid); |
1756 __ b(&store_float32x4, EQ); | 1767 __ b(&store_float32x4, EQ); |
1757 | 1768 |
| 1769 __ ldr(temp2, FieldAddress(temp, Field::guarded_cid_offset())); |
| 1770 __ CompareImmediate(temp2, kFloat64x2Cid); |
| 1771 __ b(&store_float64x2, EQ); |
| 1772 |
1758 // Fall through. | 1773 // Fall through. |
1759 __ b(&store_pointer); | 1774 __ b(&store_pointer); |
1760 | 1775 |
1761 if (!compiler->is_optimizing()) { | 1776 if (!compiler->is_optimizing()) { |
1762 locs()->live_registers()->Add(locs()->in(0)); | 1777 locs()->live_registers()->Add(locs()->in(0)); |
1763 locs()->live_registers()->Add(locs()->in(1)); | 1778 locs()->live_registers()->Add(locs()->in(1)); |
1764 } | 1779 } |
1765 | 1780 |
1766 { | 1781 { |
1767 __ Bind(&store_double); | 1782 __ Bind(&store_double); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1821 Float32x4::value_offset() - kHeapObjectTag); | 1836 Float32x4::value_offset() - kHeapObjectTag); |
1822 __ LoadDFromOffset(fpu_temp_odd, value_reg, | 1837 __ LoadDFromOffset(fpu_temp_odd, value_reg, |
1823 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 1838 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
1824 __ StoreDToOffset(fpu_temp, temp, | 1839 __ StoreDToOffset(fpu_temp, temp, |
1825 Float32x4::value_offset() - kHeapObjectTag); | 1840 Float32x4::value_offset() - kHeapObjectTag); |
1826 __ StoreDToOffset(fpu_temp_odd, temp, | 1841 __ StoreDToOffset(fpu_temp_odd, temp, |
1827 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 1842 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
1828 __ b(&skip_store); | 1843 __ b(&skip_store); |
1829 } | 1844 } |
1830 | 1845 |
| 1846 { |
| 1847 __ Bind(&store_float64x2); |
| 1848 Label copy_float64x2; |
| 1849 StoreInstanceFieldSlowPath* slow_path = |
| 1850 new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); |
| 1851 compiler->AddSlowPathCode(slow_path); |
| 1852 |
| 1853 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
| 1854 __ CompareImmediate(temp, |
| 1855 reinterpret_cast<intptr_t>(Object::null())); |
| 1856 __ b(©_float64x2, NE); |
| 1857 |
| 1858 __ TryAllocate(compiler->float64x2_class(), |
| 1859 slow_path->entry_label(), |
| 1860 temp, |
| 1861 temp2); |
| 1862 __ Bind(slow_path->exit_label()); |
| 1863 __ MoveRegister(temp2, temp); |
| 1864 __ StoreIntoObject(instance_reg, |
| 1865 FieldAddress(instance_reg, offset_in_bytes_), |
| 1866 temp2); |
| 1867 __ Bind(©_float64x2); |
| 1868 // TODO(zra): Maybe use vldmd here. |
| 1869 __ LoadDFromOffset(fpu_temp, value_reg, |
| 1870 Float64x2::value_offset() - kHeapObjectTag); |
| 1871 __ LoadDFromOffset(fpu_temp_odd, value_reg, |
| 1872 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 1873 __ StoreDToOffset(fpu_temp, temp, |
| 1874 Float64x2::value_offset() - kHeapObjectTag); |
| 1875 __ StoreDToOffset(fpu_temp_odd, temp, |
| 1876 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 1877 __ b(&skip_store); |
| 1878 } |
| 1879 |
1831 __ Bind(&store_pointer); | 1880 __ Bind(&store_pointer); |
1832 } | 1881 } |
1833 | 1882 |
1834 if (ShouldEmitStoreBarrier()) { | 1883 if (ShouldEmitStoreBarrier()) { |
1835 Register value_reg = locs()->in(1).reg(); | 1884 Register value_reg = locs()->in(1).reg(); |
1836 __ StoreIntoObject(instance_reg, | 1885 __ StoreIntoObject(instance_reg, |
1837 FieldAddress(instance_reg, offset_in_bytes_), | 1886 FieldAddress(instance_reg, offset_in_bytes_), |
1838 value_reg, | 1887 value_reg, |
1839 CanValueBeSmi()); | 1888 CanValueBeSmi()); |
1840 } else { | 1889 } else { |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2087 Double::value_offset() - kHeapObjectTag); | 2136 Double::value_offset() - kHeapObjectTag); |
2088 break; | 2137 break; |
2089 case kFloat32x4Cid: | 2138 case kFloat32x4Cid: |
2090 __ Comment("UnboxedFloat32x4LoadFieldInstr"); | 2139 __ Comment("UnboxedFloat32x4LoadFieldInstr"); |
2091 // TODO(zra): Maybe use vldmd here. | 2140 // TODO(zra): Maybe use vldmd here. |
2092 __ LoadDFromOffset(result, temp, | 2141 __ LoadDFromOffset(result, temp, |
2093 Float32x4::value_offset() - kHeapObjectTag); | 2142 Float32x4::value_offset() - kHeapObjectTag); |
2094 __ LoadDFromOffset(result_odd, temp, | 2143 __ LoadDFromOffset(result_odd, temp, |
2095 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 2144 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
2096 break; | 2145 break; |
| 2146 case kFloat64x2Cid: |
| 2147 __ Comment("UnboxedFloat64x2LoadFieldInstr"); |
| 2148 // TODO(zra): Maybe use vldmd here. |
| 2149 __ LoadDFromOffset(result, temp, |
| 2150 Float64x2::value_offset() - kHeapObjectTag); |
| 2151 __ LoadDFromOffset(result_odd, temp, |
| 2152 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 2153 break; |
2097 default: | 2154 default: |
2098 UNREACHABLE(); | 2155 UNREACHABLE(); |
2099 } | 2156 } |
2100 return; | 2157 return; |
2101 } | 2158 } |
2102 | 2159 |
2103 Label done; | 2160 Label done; |
2104 Register result_reg = locs()->out().reg(); | 2161 Register result_reg = locs()->out().reg(); |
2105 if (IsPotentialUnboxedLoad()) { | 2162 if (IsPotentialUnboxedLoad()) { |
2106 Register temp = locs()->temp(1).reg(); | 2163 Register temp = locs()->temp(1).reg(); |
2107 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); | 2164 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); |
2108 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg()); | 2165 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg()); |
2109 | 2166 |
2110 Label load_pointer; | 2167 Label load_pointer; |
2111 Label load_double; | 2168 Label load_double; |
2112 Label load_float32x4; | 2169 Label load_float32x4; |
| 2170 Label load_float64x2; |
2113 | 2171 |
2114 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); | 2172 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |
2115 | 2173 |
2116 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); | 2174 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |
2117 FieldAddress field_nullability_operand(result_reg, | 2175 FieldAddress field_nullability_operand(result_reg, |
2118 Field::is_nullable_offset()); | 2176 Field::is_nullable_offset()); |
2119 | 2177 |
2120 __ ldr(temp, field_nullability_operand); | 2178 __ ldr(temp, field_nullability_operand); |
2121 __ CompareImmediate(temp, kNullCid); | 2179 __ CompareImmediate(temp, kNullCid); |
2122 __ b(&load_pointer, EQ); | 2180 __ b(&load_pointer, EQ); |
2123 | 2181 |
2124 __ ldr(temp, field_cid_operand); | 2182 __ ldr(temp, field_cid_operand); |
2125 __ CompareImmediate(temp, kDoubleCid); | 2183 __ CompareImmediate(temp, kDoubleCid); |
2126 __ b(&load_double, EQ); | 2184 __ b(&load_double, EQ); |
2127 | 2185 |
2128 __ ldr(temp, field_cid_operand); | 2186 __ ldr(temp, field_cid_operand); |
2129 __ CompareImmediate(temp, kFloat32x4Cid); | 2187 __ CompareImmediate(temp, kFloat32x4Cid); |
2130 __ b(&load_float32x4, EQ); | 2188 __ b(&load_float32x4, EQ); |
2131 | 2189 |
| 2190 __ ldr(temp, field_cid_operand); |
| 2191 __ CompareImmediate(temp, kFloat64x2Cid); |
| 2192 __ b(&load_float64x2, EQ); |
| 2193 |
2132 // Fall through. | 2194 // Fall through. |
2133 __ b(&load_pointer); | 2195 __ b(&load_pointer); |
2134 | 2196 |
2135 if (!compiler->is_optimizing()) { | 2197 if (!compiler->is_optimizing()) { |
2136 locs()->live_registers()->Add(locs()->in(0)); | 2198 locs()->live_registers()->Add(locs()->in(0)); |
2137 } | 2199 } |
2138 | 2200 |
2139 { | 2201 { |
2140 __ Bind(&load_double); | 2202 __ Bind(&load_double); |
2141 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 2203 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
(...skipping 28 matching lines...) Expand all Loading... |
2170 Float32x4::value_offset() - kHeapObjectTag); | 2232 Float32x4::value_offset() - kHeapObjectTag); |
2171 __ LoadDFromOffset(value_odd, temp, | 2233 __ LoadDFromOffset(value_odd, temp, |
2172 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 2234 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
2173 __ StoreDToOffset(value, result_reg, | 2235 __ StoreDToOffset(value, result_reg, |
2174 Float32x4::value_offset() - kHeapObjectTag); | 2236 Float32x4::value_offset() - kHeapObjectTag); |
2175 __ StoreDToOffset(value_odd, result_reg, | 2237 __ StoreDToOffset(value_odd, result_reg, |
2176 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | 2238 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); |
2177 __ b(&done); | 2239 __ b(&done); |
2178 } | 2240 } |
2179 | 2241 |
| 2242 { |
| 2243 __ Bind(&load_float64x2); |
| 2244 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |
| 2245 compiler->AddSlowPathCode(slow_path); |
| 2246 |
| 2247 __ TryAllocate(compiler->float64x2_class(), |
| 2248 slow_path->entry_label(), |
| 2249 result_reg, |
| 2250 temp); |
| 2251 __ Bind(slow_path->exit_label()); |
| 2252 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2253 // TODO(zra): Maybe use vldmd here. |
| 2254 __ LoadDFromOffset(value, temp, |
| 2255 Float64x2::value_offset() - kHeapObjectTag); |
| 2256 __ LoadDFromOffset(value_odd, temp, |
| 2257 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 2258 __ StoreDToOffset(value, result_reg, |
| 2259 Float64x2::value_offset() - kHeapObjectTag); |
| 2260 __ StoreDToOffset(value_odd, result_reg, |
| 2261 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); |
| 2262 __ b(&done); |
| 2263 } |
| 2264 |
2180 __ Bind(&load_pointer); | 2265 __ Bind(&load_pointer); |
2181 } | 2266 } |
2182 __ LoadFromOffset(kWord, result_reg, | 2267 __ LoadFromOffset(kWord, result_reg, |
2183 instance_reg, offset_in_bytes() - kHeapObjectTag); | 2268 instance_reg, offset_in_bytes() - kHeapObjectTag); |
2184 __ Bind(&done); | 2269 __ Bind(&done); |
2185 } | 2270 } |
2186 | 2271 |
2187 | 2272 |
2188 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { | 2273 LocationSummary* InstantiateTypeInstr::MakeLocationSummary(bool opt) const { |
2189 const intptr_t kNumInputs = 1; | 2274 const intptr_t kNumInputs = 1; |
(...skipping 3162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5352 compiler->GenerateCall(token_pos(), | 5437 compiler->GenerateCall(token_pos(), |
5353 &label, | 5438 &label, |
5354 PcDescriptors::kOther, | 5439 PcDescriptors::kOther, |
5355 locs()); | 5440 locs()); |
5356 __ Drop(ArgumentCount()); // Discard arguments. | 5441 __ Drop(ArgumentCount()); // Discard arguments. |
5357 } | 5442 } |
5358 | 5443 |
5359 } // namespace dart | 5444 } // namespace dart |
5360 | 5445 |
5361 #endif // defined TARGET_ARCH_ARM | 5446 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |