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

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

Issue 269343010: Adds single-precision and SIMD load/store to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 991 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 (representation() == kUnboxedFloat64x2)) { 1002 (representation() == kUnboxedFloat64x2)) {
1003 const VRegister result = locs()->out(0).fpu_reg(); 1003 const VRegister result = locs()->out(0).fpu_reg();
1004 switch (class_id()) { 1004 switch (class_id()) {
1005 case kTypedDataInt32ArrayCid: 1005 case kTypedDataInt32ArrayCid:
1006 case kTypedDataUint32ArrayCid: 1006 case kTypedDataUint32ArrayCid:
1007 // TODO(zra): Add when we have simd. 1007 // TODO(zra): Add when we have simd.
1008 UNIMPLEMENTED(); 1008 UNIMPLEMENTED();
1009 break; 1009 break;
1010 case kTypedDataFloat32ArrayCid: 1010 case kTypedDataFloat32ArrayCid:
1011 // Load single precision float. 1011 // Load single precision float.
1012 // TODO(zra): Add when we add single precision floats. 1012 __ fldrs(result, element_address);
1013 UNIMPLEMENTED();
1014 break; 1013 break;
1015 case kTypedDataFloat64ArrayCid: 1014 case kTypedDataFloat64ArrayCid:
1016 // Load double precision float. 1015 // Load double precision float.
1017 __ fldrd(result, element_address); 1016 __ fldrd(result, element_address);
1018 break; 1017 break;
1019 case kTypedDataFloat64x2ArrayCid: 1018 case kTypedDataFloat64x2ArrayCid:
1020 case kTypedDataInt32x4ArrayCid: 1019 case kTypedDataInt32x4ArrayCid:
1021 case kTypedDataFloat32x4ArrayCid: 1020 case kTypedDataFloat32x4ArrayCid:
1022 // TODO(zra): Add when we have simd. 1021 // TODO(zra): Add when we have simd.
1023 UNIMPLEMENTED(); 1022 UNIMPLEMENTED();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 // Mints are stored in Q registers. For smis, use a writable register 1133 // Mints are stored in Q registers. For smis, use a writable register
1135 // because the value must be untagged before storing. 1134 // because the value must be untagged before storing.
1136 if (value()->IsSmiValue()) { 1135 if (value()->IsSmiValue()) {
1137 locs->set_in(2, Location::WritableRegister()); 1136 locs->set_in(2, Location::WritableRegister());
1138 } else { 1137 } else {
1139 // TODO(zra): Implement when we add simd loads and stores. 1138 // TODO(zra): Implement when we add simd loads and stores.
1140 UNIMPLEMENTED(); 1139 UNIMPLEMENTED();
1141 } 1140 }
1142 break; 1141 break;
1143 case kTypedDataFloat32ArrayCid: 1142 case kTypedDataFloat32ArrayCid:
1144 // TODO(zra): Implement when we add float store.
1145 UNIMPLEMENTED();
1146 break;
1147 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants. 1143 case kTypedDataFloat64ArrayCid: // TODO(srdjan): Support Float64 constants.
1148 locs->set_in(2, Location::RequiresFpuRegister()); 1144 locs->set_in(2, Location::RequiresFpuRegister());
1149 break; 1145 break;
1150 case kTypedDataInt32x4ArrayCid: 1146 case kTypedDataInt32x4ArrayCid:
1151 case kTypedDataFloat32x4ArrayCid: 1147 case kTypedDataFloat32x4ArrayCid:
1152 case kTypedDataFloat64x2ArrayCid: 1148 case kTypedDataFloat64x2ArrayCid:
1153 // TODO(zra): Implement when we add simd loads and stores. 1149 // TODO(zra): Implement when we add simd loads and stores.
1154 UNIMPLEMENTED(); 1150 UNIMPLEMENTED();
1155 break; 1151 break;
1156 default: 1152 default:
1157 UNREACHABLE(); 1153 UNREACHABLE();
1158 return NULL; 1154 return NULL;
1159 } 1155 }
1160 return locs; 1156 return locs;
1161 } 1157 }
1162 1158
1163 1159
1164 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1160 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1165 Register array = locs()->in(0).reg(); 1161 const Register array = locs()->in(0).reg();
1166 Location index = locs()->in(1); 1162 Location index = locs()->in(1);
1167 1163
1168 Address element_address(kNoRegister, 0); 1164 Address element_address(kNoRegister, 0);
1169 ASSERT(index.IsRegister()); // TODO(regis): Revisit. 1165 ASSERT(index.IsRegister()); // TODO(regis): Revisit.
1170 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays 1166 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
1171 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the 1167 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
1172 // index is expected to be untagged before accessing. 1168 // index is expected to be untagged before accessing.
1173 ASSERT(kSmiTagShift == 1); 1169 ASSERT(kSmiTagShift == 1);
1174 switch (index_scale()) { 1170 switch (index_scale()) {
1175 case 1: { 1171 case 1: {
(...skipping 21 matching lines...) Expand all
1197 if (!IsExternal()) { 1193 if (!IsExternal()) {
1198 ASSERT(this->array()->definition()->representation() == kTagged); 1194 ASSERT(this->array()->definition()->representation() == kTagged);
1199 __ AddImmediate(index.reg(), index.reg(), 1195 __ AddImmediate(index.reg(), index.reg(),
1200 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag, PP); 1196 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag, PP);
1201 } 1197 }
1202 element_address = Address(array, index.reg(), UXTX, Address::Unscaled); 1198 element_address = Address(array, index.reg(), UXTX, Address::Unscaled);
1203 1199
1204 switch (class_id()) { 1200 switch (class_id()) {
1205 case kArrayCid: 1201 case kArrayCid:
1206 if (ShouldEmitStoreBarrier()) { 1202 if (ShouldEmitStoreBarrier()) {
1207 Register value = locs()->in(2).reg(); 1203 const Register value = locs()->in(2).reg();
1208 __ StoreIntoObject(array, element_address, value); 1204 __ StoreIntoObject(array, element_address, value);
1209 } else if (locs()->in(2).IsConstant()) { 1205 } else if (locs()->in(2).IsConstant()) {
1210 const Object& constant = locs()->in(2).constant(); 1206 const Object& constant = locs()->in(2).constant();
1211 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1207 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1212 } else { 1208 } else {
1213 Register value = locs()->in(2).reg(); 1209 const Register value = locs()->in(2).reg();
1214 __ StoreIntoObjectNoBarrier(array, element_address, value); 1210 __ StoreIntoObjectNoBarrier(array, element_address, value);
1215 } 1211 }
1216 break; 1212 break;
1217 case kTypedDataInt8ArrayCid: 1213 case kTypedDataInt8ArrayCid:
1218 case kTypedDataUint8ArrayCid: 1214 case kTypedDataUint8ArrayCid:
1219 case kExternalTypedDataUint8ArrayCid: 1215 case kExternalTypedDataUint8ArrayCid:
1220 case kOneByteStringCid: { 1216 case kOneByteStringCid: {
1221 if (locs()->in(2).IsConstant()) { 1217 if (locs()->in(2).IsConstant()) {
1222 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1218 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1223 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()), PP); 1219 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()), PP);
1224 __ str(TMP, element_address, kUnsignedByte); 1220 __ str(TMP, element_address, kUnsignedByte);
1225 } else { 1221 } else {
1226 Register value = locs()->in(2).reg(); 1222 const Register value = locs()->in(2).reg();
1227 __ SmiUntag(value); 1223 __ SmiUntag(value);
1228 __ str(value, element_address, kUnsignedByte); 1224 __ str(value, element_address, kUnsignedByte);
1229 } 1225 }
1230 break; 1226 break;
1231 } 1227 }
1232 case kTypedDataUint8ClampedArrayCid: 1228 case kTypedDataUint8ClampedArrayCid:
1233 case kExternalTypedDataUint8ClampedArrayCid: { 1229 case kExternalTypedDataUint8ClampedArrayCid: {
1234 if (locs()->in(2).IsConstant()) { 1230 if (locs()->in(2).IsConstant()) {
1235 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1231 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1236 intptr_t value = constant.Value(); 1232 intptr_t value = constant.Value();
1237 // Clamp to 0x0 or 0xFF respectively. 1233 // Clamp to 0x0 or 0xFF respectively.
1238 if (value > 0xFF) { 1234 if (value > 0xFF) {
1239 value = 0xFF; 1235 value = 0xFF;
1240 } else if (value < 0) { 1236 } else if (value < 0) {
1241 value = 0; 1237 value = 0;
1242 } 1238 }
1243 __ LoadImmediate(TMP, static_cast<int8_t>(value), PP); 1239 __ LoadImmediate(TMP, static_cast<int8_t>(value), PP);
1244 __ str(TMP, element_address, kUnsignedByte); 1240 __ str(TMP, element_address, kUnsignedByte);
1245 } else { 1241 } else {
1246 Register value = locs()->in(2).reg(); 1242 const Register value = locs()->in(2).reg();
1247 Label store_value; 1243 Label store_value;
1248 __ SmiUntag(value); 1244 __ SmiUntag(value);
1249 __ CompareImmediate(value, 0xFF, PP); 1245 __ CompareImmediate(value, 0xFF, PP);
1250 // Clamp to 0x00 or 0xFF respectively. 1246 // Clamp to 0x00 or 0xFF respectively.
1251 __ b(&store_value, LS); 1247 __ b(&store_value, LS);
1252 __ LoadImmediate(TMP, 0x00, PP); 1248 __ LoadImmediate(TMP, 0x00, PP);
1253 __ LoadImmediate(TMP2, 0xFF, PP); 1249 __ LoadImmediate(TMP2, 0xFF, PP);
1254 __ csel(value, TMP, value, LE); 1250 __ csel(value, TMP, value, LE);
1255 __ csel(value, TMP2, value, GT); 1251 __ csel(value, TMP2, value, GT);
1256 __ Bind(&store_value); 1252 __ Bind(&store_value);
1257 __ str(value, element_address, kUnsignedByte); 1253 __ str(value, element_address, kUnsignedByte);
1258 } 1254 }
1259 break; 1255 break;
1260 } 1256 }
1261 case kTypedDataInt16ArrayCid: 1257 case kTypedDataInt16ArrayCid:
1262 case kTypedDataUint16ArrayCid: { 1258 case kTypedDataUint16ArrayCid: {
1263 Register value = locs()->in(2).reg(); 1259 const Register value = locs()->in(2).reg();
1264 __ SmiUntag(value); 1260 __ SmiUntag(value);
1265 __ str(value, element_address, kUnsignedHalfword); 1261 __ str(value, element_address, kUnsignedHalfword);
1266 break; 1262 break;
1267 } 1263 }
1268 case kTypedDataInt32ArrayCid: 1264 case kTypedDataInt32ArrayCid:
1269 case kTypedDataUint32ArrayCid: { 1265 case kTypedDataUint32ArrayCid: {
1270 if (value()->IsSmiValue()) { 1266 if (value()->IsSmiValue()) {
1271 ASSERT(RequiredInputRepresentation(2) == kTagged); 1267 ASSERT(RequiredInputRepresentation(2) == kTagged);
1272 Register value = locs()->in(2).reg(); 1268 const Register value = locs()->in(2).reg();
1273 __ SmiUntag(value); 1269 __ SmiUntag(value);
1274 __ str(value, element_address); 1270 __ str(value, element_address, kUnsignedWord);
1275 } else { 1271 } else {
1276 // TODO(zra): Implement when we add simd loads and stores. 1272 // TODO(zra): Implement when we add simd loads and stores.
1277 UNIMPLEMENTED(); 1273 UNIMPLEMENTED();
1278 } 1274 }
1279 break; 1275 break;
1280 } 1276 }
1281 case kTypedDataFloat32ArrayCid: 1277 case kTypedDataFloat32ArrayCid: {
1282 // TODO(zra): Implement when we add float store. 1278 const VRegister in2 = locs()->in(2).fpu_reg();
1283 UNIMPLEMENTED(); 1279 __ add(index.reg(), index.reg(), Operand(array));
1280 __ fstrs(in2, Address(index.reg()));
1284 break; 1281 break;
1282 }
1285 case kTypedDataFloat64ArrayCid: { 1283 case kTypedDataFloat64ArrayCid: {
1286 VRegister in2 = locs()->in(2).fpu_reg(); 1284 const VRegister in2 = locs()->in(2).fpu_reg();
1287 __ add(index.reg(), index.reg(), Operand(array)); 1285 __ add(index.reg(), index.reg(), Operand(array));
1288 __ StoreDToOffset(in2, index.reg(), 0); 1286 __ StoreDToOffset(in2, index.reg(), 0);
1289 break; 1287 break;
1290 } 1288 }
1291 case kTypedDataFloat64x2ArrayCid: 1289 case kTypedDataFloat64x2ArrayCid:
1292 case kTypedDataInt32x4ArrayCid: 1290 case kTypedDataInt32x4ArrayCid:
1293 case kTypedDataFloat32x4ArrayCid: { 1291 case kTypedDataFloat32x4ArrayCid: {
1294 // TODO(zra): Implement when we add simd loads and stores. 1292 // TODO(zra): Implement when we add simd loads and stores.
1295 UNIMPLEMENTED(); 1293 UNIMPLEMENTED();
1296 break; 1294 break;
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 const Register temp = locs()->temp(0).reg(); 1710 const Register temp = locs()->temp(0).reg();
1713 const Register temp2 = locs()->temp(1).reg(); 1711 const Register temp2 = locs()->temp(1).reg();
1714 const intptr_t cid = field().UnboxedFieldCid(); 1712 const intptr_t cid = field().UnboxedFieldCid();
1715 1713
1716 if (is_initialization_) { 1714 if (is_initialization_) {
1717 const Class* cls = NULL; 1715 const Class* cls = NULL;
1718 switch (cid) { 1716 switch (cid) {
1719 case kDoubleCid: 1717 case kDoubleCid:
1720 cls = &compiler->double_class(); 1718 cls = &compiler->double_class();
1721 break; 1719 break;
1722 // TODO(zra): Implement these when we add fpu loads and stores.
1723 case kFloat32x4Cid: 1720 case kFloat32x4Cid:
1721 cls = &compiler->float32x4_class();
1722 break;
1724 case kFloat64x2Cid: 1723 case kFloat64x2Cid:
1725 UNIMPLEMENTED(); 1724 cls = &compiler->float64x2_class();
1726 break; 1725 break;
1727 default: 1726 default:
1728 UNREACHABLE(); 1727 UNREACHABLE();
1729 } 1728 }
1730 1729
1731 StoreInstanceFieldSlowPath* slow_path = 1730 StoreInstanceFieldSlowPath* slow_path =
1732 new StoreInstanceFieldSlowPath(this, *cls); 1731 new StoreInstanceFieldSlowPath(this, *cls);
1733 compiler->AddSlowPathCode(slow_path); 1732 compiler->AddSlowPathCode(slow_path);
1734 1733
1735 __ TryAllocate(*cls, 1734 __ TryAllocate(*cls,
1736 slow_path->entry_label(), 1735 slow_path->entry_label(),
1737 temp, 1736 temp,
1738 temp2, 1737 temp2,
1739 PP); 1738 PP);
1740 __ Bind(slow_path->exit_label()); 1739 __ Bind(slow_path->exit_label());
1741 __ mov(temp2, temp); 1740 __ mov(temp2, temp);
1742 __ StoreIntoObject(instance_reg, 1741 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
1743 FieldAddress(instance_reg, offset_in_bytes_),
1744 temp2);
1745 } else { 1742 } else {
1746 __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_); 1743 __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_);
1747 } 1744 }
1748 switch (cid) { 1745 switch (cid) {
1749 case kDoubleCid: 1746 case kDoubleCid:
1750 __ Comment("UnboxedDoubleStoreInstanceFieldInstr"); 1747 __ Comment("UnboxedDoubleStoreInstanceFieldInstr");
1751 __ StoreDFieldToOffset(value, temp, Double::value_offset()); 1748 __ StoreDFieldToOffset(value, temp, Double::value_offset());
1752 break; 1749 break;
1753 case kFloat32x4Cid: 1750 case kFloat32x4Cid:
1751 __ Comment("UnboxedFloat32x4StoreInstanceFieldInstr");
1752 __ StoreQFieldToOffset(value, temp, Float32x4::value_offset());
1753 break;
1754 case kFloat64x2Cid: 1754 case kFloat64x2Cid:
1755 UNIMPLEMENTED(); 1755 __ Comment("UnboxedFloat64x2StoreInstanceFieldInstr");
1756 __ StoreQFieldToOffset(value, temp, Float64x2::value_offset());
1756 break; 1757 break;
1757 default: 1758 default:
1758 UNREACHABLE(); 1759 UNREACHABLE();
1759 } 1760 }
1760 1761
1761 return; 1762 return;
1762 } 1763 }
1763 1764
1764 if (IsPotentialUnboxedStore()) { 1765 if (IsPotentialUnboxedStore()) {
1765 const Register value_reg = locs()->in(1).reg(); 1766 const Register value_reg = locs()->in(1).reg();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 __ CompareObject(temp, Object::null_object(), PP); 1815 __ CompareObject(temp, Object::null_object(), PP);
1815 __ b(&copy_double, NE); 1816 __ b(&copy_double, NE);
1816 1817
1817 __ TryAllocate(compiler->double_class(), 1818 __ TryAllocate(compiler->double_class(),
1818 slow_path->entry_label(), 1819 slow_path->entry_label(),
1819 temp, 1820 temp,
1820 temp2, 1821 temp2,
1821 PP); 1822 PP);
1822 __ Bind(slow_path->exit_label()); 1823 __ Bind(slow_path->exit_label());
1823 __ mov(temp2, temp); 1824 __ mov(temp2, temp);
1824 __ StoreIntoObject(instance_reg, 1825 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
1825 FieldAddress(instance_reg, offset_in_bytes_),
1826 temp2);
1827 __ Bind(&copy_double); 1826 __ Bind(&copy_double);
1828 __ LoadDFieldFromOffset(fpu_temp, value_reg, Double::value_offset()); 1827 __ LoadDFieldFromOffset(fpu_temp, value_reg, Double::value_offset());
1829 __ StoreDFieldToOffset(fpu_temp, temp, Double::value_offset()); 1828 __ StoreDFieldToOffset(fpu_temp, temp, Double::value_offset());
1830 __ b(&skip_store); 1829 __ b(&skip_store);
1831 } 1830 }
1832 1831
1833 // TODO(zra): Implement these when we add simd loads and stores.
1834 { 1832 {
1835 __ Bind(&store_float32x4); 1833 __ Bind(&store_float32x4);
1836 __ Stop("Float32x4 Unimplemented"); 1834 Label copy_float32x4;
1835 StoreInstanceFieldSlowPath* slow_path =
1836 new StoreInstanceFieldSlowPath(this, compiler->float32x4_class());
1837 compiler->AddSlowPathCode(slow_path);
1838
1839 __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_);
1840 __ CompareObject(temp, Object::null_object(), PP);
1841 __ b(&copy_float32x4, NE);
1842
1843 __ TryAllocate(compiler->float32x4_class(),
1844 slow_path->entry_label(),
1845 temp,
1846 temp2,
1847 PP);
1848 __ Bind(slow_path->exit_label());
1849 __ mov(temp2, temp);
1850 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
1851 __ Bind(&copy_float32x4);
1852 __ LoadQFieldFromOffset(fpu_temp, value_reg, Float32x4::value_offset());
1853 __ StoreQFieldToOffset(fpu_temp, value_reg, Float32x4::value_offset());
1854 __ b(&skip_store);
1837 } 1855 }
1838 1856
1839 { 1857 {
1840 __ Bind(&store_float64x2); 1858 __ Bind(&store_float64x2);
1841 __ Stop("Float64x2 Unimplemented"); 1859 Label copy_float64x2;
1860 StoreInstanceFieldSlowPath* slow_path =
1861 new StoreInstanceFieldSlowPath(this, compiler->float64x2_class());
1862 compiler->AddSlowPathCode(slow_path);
1863
1864 __ LoadFieldFromOffset(temp, instance_reg, offset_in_bytes_);
1865 __ CompareObject(temp, Object::null_object(), PP);
1866 __ b(&copy_float64x2, NE);
1867
1868 __ TryAllocate(compiler->float64x2_class(),
1869 slow_path->entry_label(),
1870 temp,
1871 temp2,
1872 PP);
1873 __ Bind(slow_path->exit_label());
1874 __ mov(temp2, temp);
1875 __ StoreIntoObjectOffset(instance_reg, offset_in_bytes_, temp2);
1876 __ Bind(&copy_float64x2);
1877 __ LoadQFieldFromOffset(fpu_temp, value_reg, Float64x2::value_offset());
1878 __ StoreQFieldToOffset(fpu_temp, value_reg, Float64x2::value_offset());
1879 __ b(&skip_store);
1842 } 1880 }
1843 1881
1844 __ Bind(&store_pointer); 1882 __ Bind(&store_pointer);
1845 } 1883 }
1846 1884
1847 if (ShouldEmitStoreBarrier()) { 1885 if (ShouldEmitStoreBarrier()) {
1848 Register value_reg = locs()->in(1).reg(); 1886 const Register value_reg = locs()->in(1).reg();
1849 __ StoreIntoObject(instance_reg, 1887 __ StoreIntoObjectOffset(
1850 FieldAddress(instance_reg, offset_in_bytes_), 1888 instance_reg, offset_in_bytes_, value_reg, CanValueBeSmi());
1851 value_reg,
1852 CanValueBeSmi());
1853 } else { 1889 } else {
1854 if (locs()->in(1).IsConstant()) { 1890 if (locs()->in(1).IsConstant()) {
1855 __ StoreIntoObjectNoBarrier( 1891 __ StoreIntoObjectOffsetNoBarrier(
1856 instance_reg, 1892 instance_reg,
1857 FieldAddress(instance_reg, offset_in_bytes_), 1893 offset_in_bytes_,
1858 locs()->in(1).constant()); 1894 locs()->in(1).constant());
1859 } else { 1895 } else {
1860 Register value_reg = locs()->in(1).reg(); 1896 const Register value_reg = locs()->in(1).reg();
1861 __ StoreIntoObjectNoBarrier(instance_reg, 1897 __ StoreIntoObjectOffsetNoBarrier(
1862 FieldAddress(instance_reg, offset_in_bytes_), value_reg); 1898 instance_reg,
1899 offset_in_bytes_,
1900 value_reg);
1863 } 1901 }
1864 } 1902 }
1865 __ Bind(&skip_store); 1903 __ Bind(&skip_store);
1866 } 1904 }
1867 1905
1868 1906
1869 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const { 1907 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary(bool opt) const {
1870 const intptr_t kNumInputs = 1; 1908 const intptr_t kNumInputs = 1;
1871 const intptr_t kNumTemps = 0; 1909 const intptr_t kNumTemps = 0;
1872 LocationSummary* summary = 1910 LocationSummary* summary =
(...skipping 24 matching lines...) Expand all
1897 return locs; 1935 return locs;
1898 } 1936 }
1899 1937
1900 1938
1901 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1939 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1902 Register value = locs()->in(0).reg(); 1940 Register value = locs()->in(0).reg();
1903 Register temp = locs()->temp(0).reg(); 1941 Register temp = locs()->temp(0).reg();
1904 1942
1905 __ LoadObject(temp, field(), PP); 1943 __ LoadObject(temp, field(), PP);
1906 if (this->value()->NeedsStoreBuffer()) { 1944 if (this->value()->NeedsStoreBuffer()) {
1907 __ StoreIntoObject(temp, 1945 __ StoreIntoObjectOffset(
1908 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); 1946 temp, Field::value_offset(), value, CanValueBeSmi());
1909 } else { 1947 } else {
1910 __ StoreIntoObjectNoBarrier( 1948 __ StoreIntoObjectOffsetNoBarrier(temp, Field::value_offset(), value);
1911 temp, FieldAddress(temp, Field::value_offset()), value);
1912 } 1949 }
1913 } 1950 }
1914 1951
1915 1952
1916 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const { 1953 LocationSummary* InstanceOfInstr::MakeLocationSummary(bool opt) const {
1917 const intptr_t kNumInputs = 3; 1954 const intptr_t kNumInputs = 3;
1918 const intptr_t kNumTemps = 0; 1955 const intptr_t kNumTemps = 0;
1919 LocationSummary* summary = 1956 LocationSummary* summary =
1920 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1957 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1921 summary->set_in(0, Location::RegisterLocation(R0)); 1958 summary->set_in(0, Location::RegisterLocation(R0));
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 return NULL; 3598 return NULL;
3562 } 3599 }
3563 3600
3564 3601
3565 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3602 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3566 UNIMPLEMENTED(); 3603 UNIMPLEMENTED();
3567 } 3604 }
3568 3605
3569 3606
3570 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const { 3607 LocationSummary* DoubleToFloatInstr::MakeLocationSummary(bool opt) const {
3571 UNIMPLEMENTED(); 3608 const intptr_t kNumInputs = 1;
3572 return NULL; 3609 const intptr_t kNumTemps = 0;
3610 LocationSummary* result =
3611 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3612 result->set_in(0, Location::RequiresFpuRegister());
3613 result->set_out(0, Location::RequiresFpuRegister());
3614 return result;
3573 } 3615 }
3574 3616
3575 3617
3576 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3618 void DoubleToFloatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3577 UNIMPLEMENTED(); 3619 const VRegister value = locs()->in(0).fpu_reg();
3620 const VRegister result = locs()->out(0).fpu_reg();
3621 __ fcvtsd(result, value);
3578 } 3622 }
3579 3623
3580 3624
3581 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const { 3625 LocationSummary* FloatToDoubleInstr::MakeLocationSummary(bool opt) const {
3582 UNIMPLEMENTED(); 3626 const intptr_t kNumInputs = 1;
3583 return NULL; 3627 const intptr_t kNumTemps = 0;
3628 LocationSummary* result =
3629 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3630 result->set_in(0, Location::RequiresFpuRegister());
3631 result->set_out(0, Location::RequiresFpuRegister());
3632 return result;
3584 } 3633 }
3585 3634
3586 3635
3587 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3636 void FloatToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3588 UNIMPLEMENTED(); 3637 const VRegister value = locs()->in(0).fpu_reg();
3638 const VRegister result = locs()->out(0).fpu_reg();
3639 __ fcvtds(result, value);
3589 } 3640 }
3590 3641
3591 3642
3592 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { 3643 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
3593 ASSERT((InputCount() == 1) || (InputCount() == 2)); 3644 ASSERT((InputCount() == 1) || (InputCount() == 2));
3594 const intptr_t kNumTemps = 0; 3645 const intptr_t kNumTemps = 0;
3595 LocationSummary* result = 3646 LocationSummary* result =
3596 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 3647 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3597 result->set_in(0, Location::FpuRegisterLocation(V0)); 3648 result->set_in(0, Location::FpuRegisterLocation(V0));
3598 if (InputCount() == 2) { 3649 if (InputCount() == 2) {
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
4254 compiler->GenerateCall(token_pos(), 4305 compiler->GenerateCall(token_pos(),
4255 &label, 4306 &label,
4256 PcDescriptors::kOther, 4307 PcDescriptors::kOther,
4257 locs()); 4308 locs());
4258 __ Drop(ArgumentCount()); // Discard arguments. 4309 __ Drop(ArgumentCount()); // Discard arguments.
4259 } 4310 }
4260 4311
4261 } // namespace dart 4312 } // namespace dart
4262 4313
4263 #endif // defined TARGET_ARCH_ARM64 4314 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698