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

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

Issue 208423006: Use more fpu multi-load/store instructions on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 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/flow_graph_compiler_arm.cc ('k') | no next file » | 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 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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(&copy_float32x4); 1957 __ Bind(&copy_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(&copy_float64x2, NE); 1975 __ b(&copy_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(&copy_float64x2); 1986 __ Bind(&copy_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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698