| 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 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 __ AddImmediate(index.reg(), | 1074 __ AddImmediate(index.reg(), |
| 1075 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); | 1075 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); |
| 1076 } | 1076 } |
| 1077 element_address = Address(array, index.reg(), LSL, 0); | 1077 element_address = Address(array, index.reg(), LSL, 0); |
| 1078 | 1078 |
| 1079 if ((representation() == kUnboxedDouble) || | 1079 if ((representation() == kUnboxedDouble) || |
| 1080 (representation() == kUnboxedMint) || | 1080 (representation() == kUnboxedMint) || |
| 1081 (representation() == kUnboxedFloat32x4) || | 1081 (representation() == kUnboxedFloat32x4) || |
| 1082 (representation() == kUnboxedInt32x4) || | 1082 (representation() == kUnboxedInt32x4) || |
| 1083 (representation() == kUnboxedFloat64x2)) { | 1083 (representation() == kUnboxedFloat64x2)) { |
| 1084 QRegister result = locs()->out(0).fpu_reg(); | 1084 const QRegister result = locs()->out(0).fpu_reg(); |
| 1085 DRegister dresult0 = EvenDRegisterOf(result); | 1085 const DRegister dresult0 = EvenDRegisterOf(result); |
| 1086 DRegister dresult1 = OddDRegisterOf(result); | 1086 const Register idx = index.reg(); |
| 1087 Register idx = index.reg(); | |
| 1088 switch (class_id()) { | 1087 switch (class_id()) { |
| 1089 case kTypedDataInt32ArrayCid: | 1088 case kTypedDataInt32ArrayCid: |
| 1090 __ veorq(result, result, result); | 1089 __ veorq(result, result, result); |
| 1091 __ ldr(TMP, element_address); | 1090 __ ldr(TMP, element_address); |
| 1092 // Re-use the index register so we don't have to require a low-numbered | 1091 // Re-use the index register so we don't have to require a low-numbered |
| 1093 // Q register. | 1092 // Q register. |
| 1094 // Sign-extend into idx. | 1093 // Sign-extend into idx. |
| 1095 __ Asr(idx, TMP, 31); | 1094 __ Asr(idx, TMP, 31); |
| 1096 __ vmovdrr(dresult0, TMP, idx); | 1095 __ vmovdrr(dresult0, TMP, idx); |
| 1097 break; | 1096 break; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1113 case kTypedDataFloat64ArrayCid: | 1112 case kTypedDataFloat64ArrayCid: |
| 1114 // vldrd does not support indexed addressing. | 1113 // vldrd does not support indexed addressing. |
| 1115 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1114 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1116 element_address = Address(index.reg(), 0); | 1115 element_address = Address(index.reg(), 0); |
| 1117 __ vldrd(dresult0, element_address); | 1116 __ vldrd(dresult0, element_address); |
| 1118 break; | 1117 break; |
| 1119 case kTypedDataFloat64x2ArrayCid: | 1118 case kTypedDataFloat64x2ArrayCid: |
| 1120 case kTypedDataInt32x4ArrayCid: | 1119 case kTypedDataInt32x4ArrayCid: |
| 1121 case kTypedDataFloat32x4ArrayCid: | 1120 case kTypedDataFloat32x4ArrayCid: |
| 1122 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1121 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1123 // TODO(zra): Maybe use vldmd here. | 1122 __ vldmd(IA, index.reg(), dresult0, 2); |
| 1124 __ LoadDFromOffset(dresult0, index.reg(), 0); | |
| 1125 __ LoadDFromOffset(dresult1, index.reg(), 2 * kWordSize); | |
| 1126 break; | 1123 break; |
| 1127 } | 1124 } |
| 1128 return; | 1125 return; |
| 1129 } | 1126 } |
| 1130 | 1127 |
| 1131 Register result = locs()->out(0).reg(); | 1128 Register result = locs()->out(0).reg(); |
| 1132 switch (class_id()) { | 1129 switch (class_id()) { |
| 1133 case kTypedDataInt8ArrayCid: | 1130 case kTypedDataInt8ArrayCid: |
| 1134 ASSERT(index_scale() == 1); | 1131 ASSERT(index_scale() == 1); |
| 1135 __ ldrsb(result, element_address); | 1132 __ ldrsb(result, element_address); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 } | 1391 } |
| 1395 case kTypedDataFloat64ArrayCid: { | 1392 case kTypedDataFloat64ArrayCid: { |
| 1396 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); | 1393 DRegister in2 = EvenDRegisterOf(locs()->in(2).fpu_reg()); |
| 1397 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1394 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1398 __ StoreDToOffset(in2, index.reg(), 0); | 1395 __ StoreDToOffset(in2, index.reg(), 0); |
| 1399 break; | 1396 break; |
| 1400 } | 1397 } |
| 1401 case kTypedDataFloat64x2ArrayCid: | 1398 case kTypedDataFloat64x2ArrayCid: |
| 1402 case kTypedDataInt32x4ArrayCid: | 1399 case kTypedDataInt32x4ArrayCid: |
| 1403 case kTypedDataFloat32x4ArrayCid: { | 1400 case kTypedDataFloat32x4ArrayCid: { |
| 1404 QRegister in = locs()->in(2).fpu_reg(); | 1401 const QRegister in = locs()->in(2).fpu_reg(); |
| 1405 DRegister din0 = EvenDRegisterOf(in); | 1402 const DRegister din0 = EvenDRegisterOf(in); |
| 1406 DRegister din1 = OddDRegisterOf(in); | |
| 1407 __ add(index.reg(), index.reg(), ShifterOperand(array)); | 1403 __ add(index.reg(), index.reg(), ShifterOperand(array)); |
| 1408 __ StoreDToOffset(din0, index.reg(), 0); | 1404 __ vstmd(IA, index.reg(), din0, 2); |
| 1409 __ StoreDToOffset(din1, index.reg(), 2 * kWordSize); | |
| 1410 break; | 1405 break; |
| 1411 } | 1406 } |
| 1412 default: | 1407 default: |
| 1413 UNREACHABLE(); | 1408 UNREACHABLE(); |
| 1414 } | 1409 } |
| 1415 } | 1410 } |
| 1416 | 1411 |
| 1417 | 1412 |
| 1418 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { | 1413 LocationSummary* GuardFieldInstr::MakeLocationSummary(bool opt) const { |
| 1419 const intptr_t kNumInputs = 1; | 1414 const intptr_t kNumInputs = 1; |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1800 return summary; | 1795 return summary; |
| 1801 } | 1796 } |
| 1802 | 1797 |
| 1803 | 1798 |
| 1804 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1799 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1805 Label skip_store; | 1800 Label skip_store; |
| 1806 | 1801 |
| 1807 Register instance_reg = locs()->in(0).reg(); | 1802 Register instance_reg = locs()->in(0).reg(); |
| 1808 | 1803 |
| 1809 if (IsUnboxedStore() && compiler->is_optimizing()) { | 1804 if (IsUnboxedStore() && compiler->is_optimizing()) { |
| 1810 DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg()); | 1805 const DRegister value = EvenDRegisterOf(locs()->in(1).fpu_reg()); |
| 1811 DRegister value_odd = OddDRegisterOf(locs()->in(1).fpu_reg()); | 1806 const Register temp = locs()->temp(0).reg(); |
| 1812 Register temp = locs()->temp(0).reg(); | 1807 const Register temp2 = locs()->temp(1).reg(); |
| 1813 Register temp2 = locs()->temp(1).reg(); | |
| 1814 const intptr_t cid = field().UnboxedFieldCid(); | 1808 const intptr_t cid = field().UnboxedFieldCid(); |
| 1815 | 1809 |
| 1816 if (is_initialization_) { | 1810 if (is_initialization_) { |
| 1817 const Class* cls = NULL; | 1811 const Class* cls = NULL; |
| 1818 switch (cid) { | 1812 switch (cid) { |
| 1819 case kDoubleCid: | 1813 case kDoubleCid: |
| 1820 cls = &compiler->double_class(); | 1814 cls = &compiler->double_class(); |
| 1821 break; | 1815 break; |
| 1822 case kFloat32x4Cid: | 1816 case kFloat32x4Cid: |
| 1823 cls = &compiler->float32x4_class(); | 1817 cls = &compiler->float32x4_class(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1845 } else { | 1839 } else { |
| 1846 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1840 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
| 1847 } | 1841 } |
| 1848 switch (cid) { | 1842 switch (cid) { |
| 1849 case kDoubleCid: | 1843 case kDoubleCid: |
| 1850 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); | 1844 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); |
| 1851 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); | 1845 __ StoreDToOffset(value, temp, Double::value_offset() - kHeapObjectTag); |
| 1852 break; | 1846 break; |
| 1853 case kFloat32x4Cid: | 1847 case kFloat32x4Cid: |
| 1854 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); | 1848 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr"); |
| 1855 __ StoreDToOffset(value, temp, | 1849 __ StoreMultipleDToOffset(value, 2, temp, |
| 1856 Float32x4::value_offset() - kHeapObjectTag); | 1850 Float32x4::value_offset() - kHeapObjectTag); |
| 1857 __ StoreDToOffset(value_odd, temp, | |
| 1858 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 1859 break; | 1851 break; |
| 1860 case kFloat64x2Cid: | 1852 case kFloat64x2Cid: |
| 1861 __ Comment("UnboxedFloat64x2StoreInstanceFieldInstr"); | 1853 __ Comment("UnboxedFloat64x2StoreInstanceFieldInstr"); |
| 1862 __ StoreDToOffset(value, temp, | 1854 __ StoreMultipleDToOffset(value, 2, temp, |
| 1863 Float64x2::value_offset() - kHeapObjectTag); | 1855 Float64x2::value_offset() - kHeapObjectTag); |
| 1864 __ StoreDToOffset(value_odd, temp, | |
| 1865 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 1866 break; | 1856 break; |
| 1867 default: | 1857 default: |
| 1868 UNREACHABLE(); | 1858 UNREACHABLE(); |
| 1869 } | 1859 } |
| 1870 | 1860 |
| 1871 return; | 1861 return; |
| 1872 } | 1862 } |
| 1873 | 1863 |
| 1874 if (IsPotentialUnboxedStore()) { | 1864 if (IsPotentialUnboxedStore()) { |
| 1875 Register value_reg = locs()->in(1).reg(); | 1865 const Register value_reg = locs()->in(1).reg(); |
| 1876 Register temp = locs()->temp(0).reg(); | 1866 const Register temp = locs()->temp(0).reg(); |
| 1877 Register temp2 = locs()->temp(1).reg(); | 1867 const Register temp2 = locs()->temp(1).reg(); |
| 1878 DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); | 1868 const DRegister fpu_temp = EvenDRegisterOf(locs()->temp(2).fpu_reg()); |
| 1879 DRegister fpu_temp_odd = OddDRegisterOf(locs()->temp(2).fpu_reg()); | |
| 1880 | 1869 |
| 1881 Label store_pointer; | 1870 Label store_pointer; |
| 1882 Label store_double; | 1871 Label store_double; |
| 1883 Label store_float32x4; | 1872 Label store_float32x4; |
| 1884 Label store_float64x2; | 1873 Label store_float64x2; |
| 1885 | 1874 |
| 1886 __ LoadObject(temp, Field::ZoneHandle(field().raw())); | 1875 __ LoadObject(temp, Field::ZoneHandle(field().raw())); |
| 1887 | 1876 |
| 1888 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); | 1877 __ ldr(temp2, FieldAddress(temp, Field::is_nullable_offset())); |
| 1889 __ CompareImmediate(temp2, kNullCid); | 1878 __ CompareImmediate(temp2, kNullCid); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1959 __ TryAllocate(compiler->float32x4_class(), | 1948 __ TryAllocate(compiler->float32x4_class(), |
| 1960 slow_path->entry_label(), | 1949 slow_path->entry_label(), |
| 1961 temp, | 1950 temp, |
| 1962 temp2); | 1951 temp2); |
| 1963 __ Bind(slow_path->exit_label()); | 1952 __ Bind(slow_path->exit_label()); |
| 1964 __ MoveRegister(temp2, temp); | 1953 __ MoveRegister(temp2, temp); |
| 1965 __ StoreIntoObject(instance_reg, | 1954 __ StoreIntoObject(instance_reg, |
| 1966 FieldAddress(instance_reg, offset_in_bytes_), | 1955 FieldAddress(instance_reg, offset_in_bytes_), |
| 1967 temp2); | 1956 temp2); |
| 1968 __ Bind(©_float32x4); | 1957 __ Bind(©_float32x4); |
| 1969 // TODO(zra): Maybe use vldmd here. | 1958 __ LoadMultipleDFromOffset(fpu_temp, 2, value_reg, |
| 1970 __ LoadDFromOffset(fpu_temp, value_reg, | |
| 1971 Float32x4::value_offset() - kHeapObjectTag); | 1959 Float32x4::value_offset() - kHeapObjectTag); |
| 1972 __ LoadDFromOffset(fpu_temp_odd, value_reg, | 1960 __ StoreMultipleDToOffset(fpu_temp, 2, temp, |
| 1973 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 1974 __ StoreDToOffset(fpu_temp, temp, | |
| 1975 Float32x4::value_offset() - kHeapObjectTag); | 1961 Float32x4::value_offset() - kHeapObjectTag); |
| 1976 __ StoreDToOffset(fpu_temp_odd, temp, | |
| 1977 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 1978 __ b(&skip_store); | 1962 __ b(&skip_store); |
| 1979 } | 1963 } |
| 1980 | 1964 |
| 1981 { | 1965 { |
| 1982 __ Bind(&store_float64x2); | 1966 __ Bind(&store_float64x2); |
| 1983 Label copy_float64x2; | 1967 Label copy_float64x2; |
| 1984 StoreInstanceFieldSlowPath* slow_path = | 1968 StoreInstanceFieldSlowPath* slow_path = |
| 1985 new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); | 1969 new StoreInstanceFieldSlowPath(this, compiler->float64x2_class()); |
| 1986 compiler->AddSlowPathCode(slow_path); | 1970 compiler->AddSlowPathCode(slow_path); |
| 1987 | 1971 |
| 1988 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); | 1972 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes_)); |
| 1989 __ CompareImmediate(temp, | 1973 __ CompareImmediate(temp, |
| 1990 reinterpret_cast<intptr_t>(Object::null())); | 1974 reinterpret_cast<intptr_t>(Object::null())); |
| 1991 __ b(©_float64x2, NE); | 1975 __ b(©_float64x2, NE); |
| 1992 | 1976 |
| 1993 __ TryAllocate(compiler->float64x2_class(), | 1977 __ TryAllocate(compiler->float64x2_class(), |
| 1994 slow_path->entry_label(), | 1978 slow_path->entry_label(), |
| 1995 temp, | 1979 temp, |
| 1996 temp2); | 1980 temp2); |
| 1997 __ Bind(slow_path->exit_label()); | 1981 __ Bind(slow_path->exit_label()); |
| 1998 __ MoveRegister(temp2, temp); | 1982 __ MoveRegister(temp2, temp); |
| 1999 __ StoreIntoObject(instance_reg, | 1983 __ StoreIntoObject(instance_reg, |
| 2000 FieldAddress(instance_reg, offset_in_bytes_), | 1984 FieldAddress(instance_reg, offset_in_bytes_), |
| 2001 temp2); | 1985 temp2); |
| 2002 __ Bind(©_float64x2); | 1986 __ Bind(©_float64x2); |
| 2003 // TODO(zra): Maybe use vldmd here. | 1987 __ LoadMultipleDFromOffset(fpu_temp, 2, value_reg, |
| 2004 __ LoadDFromOffset(fpu_temp, value_reg, | |
| 2005 Float64x2::value_offset() - kHeapObjectTag); | 1988 Float64x2::value_offset() - kHeapObjectTag); |
| 2006 __ LoadDFromOffset(fpu_temp_odd, value_reg, | 1989 __ StoreMultipleDToOffset(fpu_temp, 2, temp, |
| 2007 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 2008 __ StoreDToOffset(fpu_temp, temp, | |
| 2009 Float64x2::value_offset() - kHeapObjectTag); | 1990 Float64x2::value_offset() - kHeapObjectTag); |
| 2010 __ StoreDToOffset(fpu_temp_odd, temp, | |
| 2011 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 2012 __ b(&skip_store); | 1991 __ b(&skip_store); |
| 2013 } | 1992 } |
| 2014 | 1993 |
| 2015 __ Bind(&store_pointer); | 1994 __ Bind(&store_pointer); |
| 2016 } | 1995 } |
| 2017 | 1996 |
| 2018 if (ShouldEmitStoreBarrier()) { | 1997 if (ShouldEmitStoreBarrier()) { |
| 2019 Register value_reg = locs()->in(1).reg(); | 1998 Register value_reg = locs()->in(1).reg(); |
| 2020 __ StoreIntoObject(instance_reg, | 1999 __ StoreIntoObject(instance_reg, |
| 2021 FieldAddress(instance_reg, offset_in_bytes_), | 2000 FieldAddress(instance_reg, offset_in_bytes_), |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2252 locs->AddTemp(Location::RequiresRegister()); | 2231 locs->AddTemp(Location::RequiresRegister()); |
| 2253 } | 2232 } |
| 2254 locs->set_out(0, Location::RequiresRegister()); | 2233 locs->set_out(0, Location::RequiresRegister()); |
| 2255 return locs; | 2234 return locs; |
| 2256 } | 2235 } |
| 2257 | 2236 |
| 2258 | 2237 |
| 2259 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2238 void LoadFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2260 Register instance_reg = locs()->in(0).reg(); | 2239 Register instance_reg = locs()->in(0).reg(); |
| 2261 if (IsUnboxedLoad() && compiler->is_optimizing()) { | 2240 if (IsUnboxedLoad() && compiler->is_optimizing()) { |
| 2262 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 2241 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
| 2263 DRegister result_odd = OddDRegisterOf(locs()->out(0).fpu_reg()); | 2242 const Register temp = locs()->temp(0).reg(); |
| 2264 Register temp = locs()->temp(0).reg(); | |
| 2265 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2243 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2266 intptr_t cid = field()->UnboxedFieldCid(); | 2244 const intptr_t cid = field()->UnboxedFieldCid(); |
| 2267 switch (cid) { | 2245 switch (cid) { |
| 2268 case kDoubleCid: | 2246 case kDoubleCid: |
| 2269 __ Comment("UnboxedDoubleLoadFieldInstr"); | 2247 __ Comment("UnboxedDoubleLoadFieldInstr"); |
| 2270 __ LoadDFromOffset(result, temp, | 2248 __ LoadDFromOffset(result, temp, |
| 2271 Double::value_offset() - kHeapObjectTag); | 2249 Double::value_offset() - kHeapObjectTag); |
| 2272 break; | 2250 break; |
| 2273 case kFloat32x4Cid: | 2251 case kFloat32x4Cid: |
| 2274 __ Comment("UnboxedFloat32x4LoadFieldInstr"); | 2252 __ Comment("UnboxedFloat32x4LoadFieldInstr"); |
| 2275 // TODO(zra): Maybe use vldmd here. | 2253 __ LoadMultipleDFromOffset(result, 2, temp, |
| 2276 __ LoadDFromOffset(result, temp, | |
| 2277 Float32x4::value_offset() - kHeapObjectTag); | 2254 Float32x4::value_offset() - kHeapObjectTag); |
| 2278 __ LoadDFromOffset(result_odd, temp, | |
| 2279 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 2280 break; | 2255 break; |
| 2281 case kFloat64x2Cid: | 2256 case kFloat64x2Cid: |
| 2282 __ Comment("UnboxedFloat64x2LoadFieldInstr"); | 2257 __ Comment("UnboxedFloat64x2LoadFieldInstr"); |
| 2283 // TODO(zra): Maybe use vldmd here. | 2258 __ LoadMultipleDFromOffset(result, 2, temp, |
| 2284 __ LoadDFromOffset(result, temp, | |
| 2285 Float64x2::value_offset() - kHeapObjectTag); | 2259 Float64x2::value_offset() - kHeapObjectTag); |
| 2286 __ LoadDFromOffset(result_odd, temp, | |
| 2287 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 2288 break; | 2260 break; |
| 2289 default: | 2261 default: |
| 2290 UNREACHABLE(); | 2262 UNREACHABLE(); |
| 2291 } | 2263 } |
| 2292 return; | 2264 return; |
| 2293 } | 2265 } |
| 2294 | 2266 |
| 2295 Label done; | 2267 Label done; |
| 2296 Register result_reg = locs()->out(0).reg(); | 2268 Register result_reg = locs()->out(0).reg(); |
| 2297 if (IsPotentialUnboxedLoad()) { | 2269 if (IsPotentialUnboxedLoad()) { |
| 2298 Register temp = locs()->temp(1).reg(); | 2270 const Register temp = locs()->temp(1).reg(); |
| 2299 DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); | 2271 const DRegister value = EvenDRegisterOf(locs()->temp(0).fpu_reg()); |
| 2300 DRegister value_odd = OddDRegisterOf(locs()->temp(0).fpu_reg()); | |
| 2301 | 2272 |
| 2302 Label load_pointer; | 2273 Label load_pointer; |
| 2303 Label load_double; | 2274 Label load_double; |
| 2304 Label load_float32x4; | 2275 Label load_float32x4; |
| 2305 Label load_float64x2; | 2276 Label load_float64x2; |
| 2306 | 2277 |
| 2307 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); | 2278 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw())); |
| 2308 | 2279 |
| 2309 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); | 2280 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); |
| 2310 FieldAddress field_nullability_operand(result_reg, | 2281 FieldAddress field_nullability_operand(result_reg, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2355 __ Bind(&load_float32x4); | 2326 __ Bind(&load_float32x4); |
| 2356 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | 2327 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); |
| 2357 compiler->AddSlowPathCode(slow_path); | 2328 compiler->AddSlowPathCode(slow_path); |
| 2358 | 2329 |
| 2359 __ TryAllocate(compiler->float32x4_class(), | 2330 __ TryAllocate(compiler->float32x4_class(), |
| 2360 slow_path->entry_label(), | 2331 slow_path->entry_label(), |
| 2361 result_reg, | 2332 result_reg, |
| 2362 temp); | 2333 temp); |
| 2363 __ Bind(slow_path->exit_label()); | 2334 __ Bind(slow_path->exit_label()); |
| 2364 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2335 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2365 // TODO(zra): Maybe use vldmd here. | 2336 __ LoadMultipleDFromOffset(value, 2, temp, |
| 2366 __ LoadDFromOffset(value, temp, | |
| 2367 Float32x4::value_offset() - kHeapObjectTag); | 2337 Float32x4::value_offset() - kHeapObjectTag); |
| 2368 __ LoadDFromOffset(value_odd, temp, | 2338 __ StoreMultipleDToOffset(value, 2, result_reg, |
| 2369 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 2370 __ StoreDToOffset(value, result_reg, | |
| 2371 Float32x4::value_offset() - kHeapObjectTag); | 2339 Float32x4::value_offset() - kHeapObjectTag); |
| 2372 __ StoreDToOffset(value_odd, result_reg, | |
| 2373 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 2374 __ b(&done); | 2340 __ b(&done); |
| 2375 } | 2341 } |
| 2376 | 2342 |
| 2377 { | 2343 { |
| 2378 __ Bind(&load_float64x2); | 2344 __ Bind(&load_float64x2); |
| 2379 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); | 2345 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |
| 2380 compiler->AddSlowPathCode(slow_path); | 2346 compiler->AddSlowPathCode(slow_path); |
| 2381 | 2347 |
| 2382 __ TryAllocate(compiler->float64x2_class(), | 2348 __ TryAllocate(compiler->float64x2_class(), |
| 2383 slow_path->entry_label(), | 2349 slow_path->entry_label(), |
| 2384 result_reg, | 2350 result_reg, |
| 2385 temp); | 2351 temp); |
| 2386 __ Bind(slow_path->exit_label()); | 2352 __ Bind(slow_path->exit_label()); |
| 2387 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); | 2353 __ ldr(temp, FieldAddress(instance_reg, offset_in_bytes())); |
| 2388 // TODO(zra): Maybe use vldmd here. | 2354 __ LoadMultipleDFromOffset(value, 2, temp, |
| 2389 __ LoadDFromOffset(value, temp, | |
| 2390 Float64x2::value_offset() - kHeapObjectTag); | 2355 Float64x2::value_offset() - kHeapObjectTag); |
| 2391 __ LoadDFromOffset(value_odd, temp, | 2356 __ StoreMultipleDToOffset(value, 2, result_reg, |
| 2392 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 2393 __ StoreDToOffset(value, result_reg, | |
| 2394 Float64x2::value_offset() - kHeapObjectTag); | 2357 Float64x2::value_offset() - kHeapObjectTag); |
| 2395 __ StoreDToOffset(value_odd, result_reg, | |
| 2396 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 2397 __ b(&done); | 2358 __ b(&done); |
| 2398 } | 2359 } |
| 2399 | 2360 |
| 2400 __ Bind(&load_pointer); | 2361 __ Bind(&load_pointer); |
| 2401 } | 2362 } |
| 2402 __ LoadFromOffset(kWord, result_reg, | 2363 __ LoadFromOffset(kWord, result_reg, |
| 2403 instance_reg, offset_in_bytes() - kHeapObjectTag); | 2364 instance_reg, offset_in_bytes() - kHeapObjectTag); |
| 2404 __ Bind(&done); | 2365 __ Bind(&done); |
| 2405 } | 2366 } |
| 2406 | 2367 |
| (...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3229 summary->set_temp(0, Location::RequiresRegister()); | 3190 summary->set_temp(0, Location::RequiresRegister()); |
| 3230 summary->set_out(0, Location::RequiresRegister()); | 3191 summary->set_out(0, Location::RequiresRegister()); |
| 3231 return summary; | 3192 return summary; |
| 3232 } | 3193 } |
| 3233 | 3194 |
| 3234 | 3195 |
| 3235 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3196 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3236 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); | 3197 BoxFloat32x4SlowPath* slow_path = new BoxFloat32x4SlowPath(this); |
| 3237 compiler->AddSlowPathCode(slow_path); | 3198 compiler->AddSlowPathCode(slow_path); |
| 3238 | 3199 |
| 3239 Register out_reg = locs()->out(0).reg(); | 3200 const Register out_reg = locs()->out(0).reg(); |
| 3240 QRegister value = locs()->in(0).fpu_reg(); | 3201 const QRegister value = locs()->in(0).fpu_reg(); |
| 3241 DRegister value_even = EvenDRegisterOf(value); | 3202 const DRegister dvalue0 = EvenDRegisterOf(value); |
| 3242 DRegister value_odd = OddDRegisterOf(value); | |
| 3243 | 3203 |
| 3244 __ TryAllocate(compiler->float32x4_class(), | 3204 __ TryAllocate(compiler->float32x4_class(), |
| 3245 slow_path->entry_label(), | 3205 slow_path->entry_label(), |
| 3246 out_reg, | 3206 out_reg, |
| 3247 locs()->temp(0).reg()); | 3207 locs()->temp(0).reg()); |
| 3248 __ Bind(slow_path->exit_label()); | 3208 __ Bind(slow_path->exit_label()); |
| 3249 | 3209 |
| 3250 __ StoreDToOffset(value_even, out_reg, | 3210 __ StoreMultipleDToOffset(dvalue0, 2, out_reg, |
| 3251 Float32x4::value_offset() - kHeapObjectTag); | 3211 Float32x4::value_offset() - kHeapObjectTag); |
| 3252 __ StoreDToOffset(value_odd, out_reg, | |
| 3253 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 3254 } | 3212 } |
| 3255 | 3213 |
| 3256 | 3214 |
| 3257 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { | 3215 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(bool opt) const { |
| 3258 const intptr_t value_cid = value()->Type()->ToCid(); | 3216 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3259 const intptr_t kNumInputs = 1; | 3217 const intptr_t kNumInputs = 1; |
| 3260 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; | 3218 const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1; |
| 3261 LocationSummary* summary = | 3219 LocationSummary* summary = |
| 3262 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3220 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3263 summary->set_in(0, Location::RequiresRegister()); | 3221 summary->set_in(0, Location::RequiresRegister()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3277 | 3235 |
| 3278 if (value_cid != kFloat32x4Cid) { | 3236 if (value_cid != kFloat32x4Cid) { |
| 3279 const Register temp = locs()->temp(0).reg(); | 3237 const Register temp = locs()->temp(0).reg(); |
| 3280 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3238 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3281 __ tst(value, ShifterOperand(kSmiTagMask)); | 3239 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3282 __ b(deopt, EQ); | 3240 __ b(deopt, EQ); |
| 3283 __ CompareClassId(value, kFloat32x4Cid, temp); | 3241 __ CompareClassId(value, kFloat32x4Cid, temp); |
| 3284 __ b(deopt, NE); | 3242 __ b(deopt, NE); |
| 3285 } | 3243 } |
| 3286 | 3244 |
| 3287 const DRegister result_even = EvenDRegisterOf(result); | 3245 const DRegister dresult0 = EvenDRegisterOf(result); |
| 3288 const DRegister result_odd = OddDRegisterOf(result); | 3246 __ LoadMultipleDFromOffset(dresult0, 2, value, |
| 3289 // TODO(zra): Maybe use vldmd here. | |
| 3290 __ LoadDFromOffset(result_even, value, | |
| 3291 Float32x4::value_offset() - kHeapObjectTag); | 3247 Float32x4::value_offset() - kHeapObjectTag); |
| 3292 __ LoadDFromOffset(result_odd, value, | |
| 3293 Float32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 3294 } | 3248 } |
| 3295 | 3249 |
| 3296 | 3250 |
| 3297 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { | 3251 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| 3298 const intptr_t kNumInputs = 1; | 3252 const intptr_t kNumInputs = 1; |
| 3299 const intptr_t kNumTemps = 1; | 3253 const intptr_t kNumTemps = 1; |
| 3300 LocationSummary* summary = | 3254 LocationSummary* summary = |
| 3301 new LocationSummary(kNumInputs, | 3255 new LocationSummary(kNumInputs, |
| 3302 kNumTemps, | 3256 kNumTemps, |
| 3303 LocationSummary::kCallOnSlowPath); | 3257 LocationSummary::kCallOnSlowPath); |
| 3304 summary->set_in(0, Location::RequiresFpuRegister()); | 3258 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3305 summary->set_temp(0, Location::RequiresRegister()); | 3259 summary->set_temp(0, Location::RequiresRegister()); |
| 3306 summary->set_out(0, Location::RequiresRegister()); | 3260 summary->set_out(0, Location::RequiresRegister()); |
| 3307 return summary; | 3261 return summary; |
| 3308 } | 3262 } |
| 3309 | 3263 |
| 3310 | 3264 |
| 3311 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3265 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3312 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); | 3266 BoxFloat64x2SlowPath* slow_path = new BoxFloat64x2SlowPath(this); |
| 3313 compiler->AddSlowPathCode(slow_path); | 3267 compiler->AddSlowPathCode(slow_path); |
| 3314 | 3268 |
| 3315 Register out_reg = locs()->out(0).reg(); | 3269 const Register out_reg = locs()->out(0).reg(); |
| 3316 QRegister value = locs()->in(0).fpu_reg(); | 3270 const QRegister value = locs()->in(0).fpu_reg(); |
| 3317 DRegister value_even = EvenDRegisterOf(value); | 3271 const DRegister dvalue0 = EvenDRegisterOf(value); |
| 3318 DRegister value_odd = OddDRegisterOf(value); | |
| 3319 | 3272 |
| 3320 __ TryAllocate(compiler->float64x2_class(), | 3273 __ TryAllocate(compiler->float64x2_class(), |
| 3321 slow_path->entry_label(), | 3274 slow_path->entry_label(), |
| 3322 out_reg, | 3275 out_reg, |
| 3323 locs()->temp(0).reg()); | 3276 locs()->temp(0).reg()); |
| 3324 __ Bind(slow_path->exit_label()); | 3277 __ Bind(slow_path->exit_label()); |
| 3325 | 3278 |
| 3326 __ StoreDToOffset(value_even, out_reg, | 3279 __ StoreMultipleDToOffset(dvalue0, 2, out_reg, |
| 3327 Float64x2::value_offset() - kHeapObjectTag); | 3280 Float64x2::value_offset() - kHeapObjectTag); |
| 3328 __ StoreDToOffset(value_odd, out_reg, | |
| 3329 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 3330 } | 3281 } |
| 3331 | 3282 |
| 3332 | 3283 |
| 3333 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { | 3284 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(bool opt) const { |
| 3334 const intptr_t value_cid = value()->Type()->ToCid(); | 3285 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3335 const intptr_t kNumInputs = 1; | 3286 const intptr_t kNumInputs = 1; |
| 3336 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; | 3287 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; |
| 3337 LocationSummary* summary = | 3288 LocationSummary* summary = |
| 3338 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3289 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3339 summary->set_in(0, Location::RequiresRegister()); | 3290 summary->set_in(0, Location::RequiresRegister()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3353 | 3304 |
| 3354 if (value_cid != kFloat64x2Cid) { | 3305 if (value_cid != kFloat64x2Cid) { |
| 3355 const Register temp = locs()->temp(0).reg(); | 3306 const Register temp = locs()->temp(0).reg(); |
| 3356 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3307 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3357 __ tst(value, ShifterOperand(kSmiTagMask)); | 3308 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3358 __ b(deopt, EQ); | 3309 __ b(deopt, EQ); |
| 3359 __ CompareClassId(value, kFloat64x2Cid, temp); | 3310 __ CompareClassId(value, kFloat64x2Cid, temp); |
| 3360 __ b(deopt, NE); | 3311 __ b(deopt, NE); |
| 3361 } | 3312 } |
| 3362 | 3313 |
| 3363 const DRegister result_even = EvenDRegisterOf(result); | 3314 const DRegister dresult0 = EvenDRegisterOf(result); |
| 3364 const DRegister result_odd = OddDRegisterOf(result); | 3315 __ LoadMultipleDFromOffset(dresult0, 2, value, |
| 3365 // TODO(zra): Maybe use vldmd here. | |
| 3366 __ LoadDFromOffset(result_even, value, | |
| 3367 Float64x2::value_offset() - kHeapObjectTag); | 3316 Float64x2::value_offset() - kHeapObjectTag); |
| 3368 __ LoadDFromOffset(result_odd, value, | |
| 3369 Float64x2::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 3370 } | 3317 } |
| 3371 | 3318 |
| 3372 | 3319 |
| 3373 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { | 3320 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 3374 const intptr_t kNumInputs = 1; | 3321 const intptr_t kNumInputs = 1; |
| 3375 const intptr_t kNumTemps = 1; | 3322 const intptr_t kNumTemps = 1; |
| 3376 LocationSummary* summary = | 3323 LocationSummary* summary = |
| 3377 new LocationSummary(kNumInputs, | 3324 new LocationSummary(kNumInputs, |
| 3378 kNumTemps, | 3325 kNumTemps, |
| 3379 LocationSummary::kCallOnSlowPath); | 3326 LocationSummary::kCallOnSlowPath); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3413 | 3360 |
| 3414 private: | 3361 private: |
| 3415 BoxInt32x4Instr* instruction_; | 3362 BoxInt32x4Instr* instruction_; |
| 3416 }; | 3363 }; |
| 3417 | 3364 |
| 3418 | 3365 |
| 3419 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3366 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3420 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); | 3367 BoxInt32x4SlowPath* slow_path = new BoxInt32x4SlowPath(this); |
| 3421 compiler->AddSlowPathCode(slow_path); | 3368 compiler->AddSlowPathCode(slow_path); |
| 3422 | 3369 |
| 3423 Register out_reg = locs()->out(0).reg(); | 3370 const Register out_reg = locs()->out(0).reg(); |
| 3424 QRegister value = locs()->in(0).fpu_reg(); | 3371 const QRegister value = locs()->in(0).fpu_reg(); |
| 3425 DRegister value_even = EvenDRegisterOf(value); | 3372 const DRegister dvalue0 = EvenDRegisterOf(value); |
| 3426 DRegister value_odd = OddDRegisterOf(value); | |
| 3427 | 3373 |
| 3428 __ TryAllocate(compiler->int32x4_class(), | 3374 __ TryAllocate(compiler->int32x4_class(), |
| 3429 slow_path->entry_label(), | 3375 slow_path->entry_label(), |
| 3430 out_reg, | 3376 out_reg, |
| 3431 locs()->temp(0).reg()); | 3377 locs()->temp(0).reg()); |
| 3432 __ Bind(slow_path->exit_label()); | 3378 __ Bind(slow_path->exit_label()); |
| 3433 __ StoreDToOffset(value_even, out_reg, | 3379 __ StoreMultipleDToOffset(dvalue0, 2, out_reg, |
| 3434 Int32x4::value_offset() - kHeapObjectTag); | 3380 Int32x4::value_offset() - kHeapObjectTag); |
| 3435 __ StoreDToOffset(value_odd, out_reg, | |
| 3436 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 3437 } | 3381 } |
| 3438 | 3382 |
| 3439 | 3383 |
| 3440 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { | 3384 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(bool opt) const { |
| 3441 const intptr_t value_cid = value()->Type()->ToCid(); | 3385 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3442 const intptr_t kNumInputs = 1; | 3386 const intptr_t kNumInputs = 1; |
| 3443 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; | 3387 const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1; |
| 3444 LocationSummary* summary = | 3388 LocationSummary* summary = |
| 3445 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3389 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3446 summary->set_in(0, Location::RequiresRegister()); | 3390 summary->set_in(0, Location::RequiresRegister()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3460 | 3404 |
| 3461 if (value_cid != kInt32x4Cid) { | 3405 if (value_cid != kInt32x4Cid) { |
| 3462 const Register temp = locs()->temp(0).reg(); | 3406 const Register temp = locs()->temp(0).reg(); |
| 3463 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); | 3407 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptCheckClass); |
| 3464 __ tst(value, ShifterOperand(kSmiTagMask)); | 3408 __ tst(value, ShifterOperand(kSmiTagMask)); |
| 3465 __ b(deopt, EQ); | 3409 __ b(deopt, EQ); |
| 3466 __ CompareClassId(value, kInt32x4Cid, temp); | 3410 __ CompareClassId(value, kInt32x4Cid, temp); |
| 3467 __ b(deopt, NE); | 3411 __ b(deopt, NE); |
| 3468 } | 3412 } |
| 3469 | 3413 |
| 3470 const DRegister result_even = EvenDRegisterOf(result); | 3414 const DRegister dresult0 = EvenDRegisterOf(result); |
| 3471 const DRegister result_odd = OddDRegisterOf(result); | 3415 __ LoadMultipleDFromOffset(dresult0, 2, value, |
| 3472 // TODO(zra): Maybe use vldmd here. | |
| 3473 __ LoadDFromOffset(result_even, value, | |
| 3474 Int32x4::value_offset() - kHeapObjectTag); | 3416 Int32x4::value_offset() - kHeapObjectTag); |
| 3475 __ LoadDFromOffset(result_odd, value, | |
| 3476 Int32x4::value_offset() + 2 * kWordSize - kHeapObjectTag); | |
| 3477 } | 3417 } |
| 3478 | 3418 |
| 3479 | 3419 |
| 3480 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { | 3420 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(bool opt) const { |
| 3481 const intptr_t kNumInputs = 2; | 3421 const intptr_t kNumInputs = 2; |
| 3482 const intptr_t kNumTemps = 0; | 3422 const intptr_t kNumTemps = 0; |
| 3483 LocationSummary* summary = | 3423 LocationSummary* summary = |
| 3484 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3424 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3485 summary->set_in(0, Location::RequiresFpuRegister()); | 3425 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3486 summary->set_in(1, Location::RequiresFpuRegister()); | 3426 summary->set_in(1, Location::RequiresFpuRegister()); |
| (...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4835 const intptr_t kNumTemps = 0; | 4775 const intptr_t kNumTemps = 0; |
| 4836 LocationSummary* result = | 4776 LocationSummary* result = |
| 4837 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4777 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 4838 result->set_in(0, Location::RegisterLocation(R1)); | 4778 result->set_in(0, Location::RegisterLocation(R1)); |
| 4839 result->set_out(0, Location::RegisterLocation(R0)); | 4779 result->set_out(0, Location::RegisterLocation(R0)); |
| 4840 return result; | 4780 return result; |
| 4841 } | 4781 } |
| 4842 | 4782 |
| 4843 | 4783 |
| 4844 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4784 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4845 Register result = locs()->out(0).reg(); | 4785 const Register result = locs()->out(0).reg(); |
| 4846 Register value_obj = locs()->in(0).reg(); | 4786 const Register value_obj = locs()->in(0).reg(); |
| 4847 ASSERT(result == R0); | 4787 ASSERT(result == R0); |
| 4848 ASSERT(result != value_obj); | 4788 ASSERT(result != value_obj); |
| 4849 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag); | 4789 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag); |
| 4850 | 4790 |
| 4851 Label do_call, done; | 4791 Label do_call, done; |
| 4852 // First check for NaN. Checking for minint after the conversion doesn't work | 4792 // First check for NaN. Checking for minint after the conversion doesn't work |
| 4853 // on ARM because vcvtid gives 0 for NaN. | 4793 // on ARM because vcvtid gives 0 for NaN. |
| 4854 __ vcmpd(DTMP, DTMP); | 4794 __ vcmpd(DTMP, DTMP); |
| 4855 __ vmstat(); | 4795 __ vmstat(); |
| 4856 __ b(&do_call, VS); | 4796 __ b(&do_call, VS); |
| (...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5883 compiler->GenerateCall(token_pos(), | 5823 compiler->GenerateCall(token_pos(), |
| 5884 &label, | 5824 &label, |
| 5885 PcDescriptors::kOther, | 5825 PcDescriptors::kOther, |
| 5886 locs()); | 5826 locs()); |
| 5887 __ Drop(ArgumentCount()); // Discard arguments. | 5827 __ Drop(ArgumentCount()); // Discard arguments. |
| 5888 } | 5828 } |
| 5889 | 5829 |
| 5890 } // namespace dart | 5830 } // namespace dart |
| 5891 | 5831 |
| 5892 #endif // defined TARGET_ARCH_ARM | 5832 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |