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

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

Issue 2452453002: Support unaligned integer loads on ARM and MIPS. (Closed)
Patch Set: . Created 4 years, 1 month 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
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/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 } 1036 }
1037 return Address::CanHoldOffset(static_cast<int32_t>(offset), 1037 return Address::CanHoldOffset(static_cast<int32_t>(offset),
1038 Address::Offset, 1038 Address::Offset,
1039 Address::OperandSizeFor(cid)); 1039 Address::OperandSizeFor(cid));
1040 } 1040 }
1041 1041
1042 1042
1043 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone, 1043 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
1044 bool opt) const { 1044 bool opt) const {
1045 const intptr_t kNumInputs = 2; 1045 const intptr_t kNumInputs = 2;
1046 const intptr_t kNumTemps = 0; 1046 const intptr_t kNumTemps = aligned() ? 0 : 1;
1047 LocationSummary* locs = new(zone) LocationSummary( 1047 LocationSummary* locs = new(zone) LocationSummary(
1048 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1048 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1049 locs->set_in(0, Location::RequiresRegister()); 1049 locs->set_in(0, Location::RequiresRegister());
1050 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) { 1050 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) {
1051 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 1051 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
1052 } else { 1052 } else {
1053 locs->set_in(1, Location::RequiresRegister()); 1053 locs->set_in(1, Location::RequiresRegister());
1054 } 1054 }
1055 if ((representation() == kUnboxedDouble) || 1055 if ((representation() == kUnboxedDouble) ||
1056 (representation() == kUnboxedFloat32x4) || 1056 (representation() == kUnboxedFloat32x4) ||
1057 (representation() == kUnboxedInt32x4) || 1057 (representation() == kUnboxedInt32x4) ||
1058 (representation() == kUnboxedFloat64x2)) { 1058 (representation() == kUnboxedFloat64x2)) {
1059 locs->set_out(0, Location::RequiresFpuRegister()); 1059 locs->set_out(0, Location::RequiresFpuRegister());
1060 } else { 1060 } else {
1061 locs->set_out(0, Location::RequiresRegister()); 1061 locs->set_out(0, Location::RequiresRegister());
1062 } 1062 }
1063 if (!aligned()) {
1064 locs->set_temp(0, Location::RequiresRegister());
1065 }
1063 return locs; 1066 return locs;
1064 } 1067 }
1065 1068
1066 1069
1067 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1070 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1068 // The array register points to the backing store for external arrays. 1071 // The array register points to the backing store for external arrays.
1069 const Register array = locs()->in(0).reg(); 1072 const Register array = locs()->in(0).reg();
1070 const Location index = locs()->in(1); 1073 const Location index = locs()->in(1);
1074 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg();
1071 1075
1072 Address element_address = index.IsRegister() 1076 Address element_address(TMP);
zra 2016/10/26 06:59:41 ditto
1073 ? __ ElementAddressForRegIndex(true, // Load. 1077 if (aligned()) {
1074 IsExternal(), class_id(), index_scale(), 1078 element_address = index.IsRegister()
1075 array, index.reg()) 1079 ? __ ElementAddressForRegIndex(true, // Load.
1076 : __ ElementAddressForIntIndex( 1080 IsExternal(), class_id(), index_scale(),
1077 IsExternal(), class_id(), index_scale(), 1081 array, index.reg())
1078 array, Smi::Cast(index.constant()).Value()); 1082 : __ ElementAddressForIntIndex(
1079 // Warning: element_address may use register TMP as base. 1083 IsExternal(), class_id(), index_scale(),
1084 array, Smi::Cast(index.constant()).Value());
1085 // Warning: element_address may use register TMP as base.
1086 } else {
1087 if (index.IsRegister()) {
1088 __ LoadElementAddressForRegIndex(address,
1089 true, // Load.
1090 IsExternal(), class_id(), index_scale(),
1091 array, index.reg());
1092 } else {
1093 __ LoadElementAddressForIntIndex(address,
1094 IsExternal(), class_id(), index_scale(),
1095 array,
1096 Smi::Cast(index.constant()).Value());
1097 }
1098 }
1080 1099
1081 if ((representation() == kUnboxedDouble) || 1100 if ((representation() == kUnboxedDouble) ||
1082 (representation() == kUnboxedFloat32x4) || 1101 (representation() == kUnboxedFloat32x4) ||
1083 (representation() == kUnboxedInt32x4) || 1102 (representation() == kUnboxedInt32x4) ||
1084 (representation() == kUnboxedFloat64x2)) { 1103 (representation() == kUnboxedFloat64x2)) {
1085 const VRegister result = locs()->out(0).fpu_reg(); 1104 const VRegister result = locs()->out(0).fpu_reg();
1086 switch (class_id()) { 1105 switch (class_id()) {
1106 ASSERT(aligned());
1087 case kTypedDataFloat32ArrayCid: 1107 case kTypedDataFloat32ArrayCid:
1088 // Load single precision float. 1108 // Load single precision float.
1089 __ fldrs(result, element_address); 1109 __ fldrs(result, element_address);
1090 break; 1110 break;
1091 case kTypedDataFloat64ArrayCid: 1111 case kTypedDataFloat64ArrayCid:
1092 // Load double precision float. 1112 // Load double precision float.
1093 __ fldrd(result, element_address); 1113 __ fldrd(result, element_address);
1094 break; 1114 break;
1095 case kTypedDataFloat64x2ArrayCid: 1115 case kTypedDataFloat64x2ArrayCid:
1096 case kTypedDataInt32x4ArrayCid: 1116 case kTypedDataInt32x4ArrayCid:
1097 case kTypedDataFloat32x4ArrayCid: 1117 case kTypedDataFloat32x4ArrayCid:
1098 __ fldrq(result, element_address); 1118 __ fldrq(result, element_address);
1099 break; 1119 break;
1100 default: 1120 default:
1101 UNREACHABLE(); 1121 UNREACHABLE();
1102 } 1122 }
1103 return; 1123 return;
1104 } 1124 }
1105 1125
1106 if ((representation() == kUnboxedInt32) || 1126 if ((representation() == kUnboxedInt32) ||
1107 (representation() == kUnboxedUint32)) { 1127 (representation() == kUnboxedUint32)) {
1108 const Register result = locs()->out(0).reg(); 1128 const Register result = locs()->out(0).reg();
1109 switch (class_id()) { 1129 switch (class_id()) {
1110 case kTypedDataInt32ArrayCid: 1130 case kTypedDataInt32ArrayCid:
1111 ASSERT(representation() == kUnboxedInt32); 1131 ASSERT(representation() == kUnboxedInt32);
1112 __ ldr(result, element_address, kWord); 1132 if (aligned()) {
1133 __ ldr(result, element_address, kWord);
1134 } else {
1135 __ LoadUnaligned(result, address, TMP, kWord);
1136 }
1113 break; 1137 break;
1114 case kTypedDataUint32ArrayCid: 1138 case kTypedDataUint32ArrayCid:
1115 ASSERT(representation() == kUnboxedUint32); 1139 ASSERT(representation() == kUnboxedUint32);
1116 __ ldr(result, element_address, kUnsignedWord); 1140 if (aligned()) {
1141 __ ldr(result, element_address, kUnsignedWord);
1142 } else {
1143 __ LoadUnaligned(result, address, TMP, kUnsignedWord);
1144 }
1117 break; 1145 break;
1118 default: 1146 default:
1119 UNREACHABLE(); 1147 UNREACHABLE();
1120 } 1148 }
1121 return; 1149 return;
1122 } 1150 }
1123 1151
1124 ASSERT(representation() == kTagged); 1152 ASSERT(representation() == kTagged);
1125 const Register result = locs()->out(0).reg(); 1153 const Register result = locs()->out(0).reg();
1126 switch (class_id()) { 1154 switch (class_id()) {
1127 case kTypedDataInt8ArrayCid: 1155 case kTypedDataInt8ArrayCid:
1128 ASSERT(index_scale() == 1); 1156 ASSERT(index_scale() == 1);
1129 __ ldr(result, element_address, kByte); 1157 __ ldr(result, element_address, kByte);
1130 __ SmiTag(result); 1158 __ SmiTag(result);
1131 break; 1159 break;
1132 case kTypedDataUint8ArrayCid: 1160 case kTypedDataUint8ArrayCid:
1133 case kTypedDataUint8ClampedArrayCid: 1161 case kTypedDataUint8ClampedArrayCid:
1134 case kExternalTypedDataUint8ArrayCid: 1162 case kExternalTypedDataUint8ArrayCid:
1135 case kExternalTypedDataUint8ClampedArrayCid: 1163 case kExternalTypedDataUint8ClampedArrayCid:
1136 case kOneByteStringCid: 1164 case kOneByteStringCid:
1137 case kExternalOneByteStringCid: 1165 case kExternalOneByteStringCid:
1138 ASSERT(index_scale() == 1); 1166 ASSERT(index_scale() == 1);
1139 __ ldr(result, element_address, kUnsignedByte); 1167 __ ldr(result, element_address, kUnsignedByte);
1140 __ SmiTag(result); 1168 __ SmiTag(result);
1141 break; 1169 break;
1142 case kTypedDataInt16ArrayCid: 1170 case kTypedDataInt16ArrayCid:
1143 __ ldr(result, element_address, kHalfword); 1171 if (aligned()) {
1172 __ ldr(result, element_address, kHalfword);
1173 } else {
1174 __ LoadUnaligned(result, address, TMP, kHalfword);
1175 }
1144 __ SmiTag(result); 1176 __ SmiTag(result);
1145 break; 1177 break;
1146 case kTypedDataUint16ArrayCid: 1178 case kTypedDataUint16ArrayCid:
1147 case kTwoByteStringCid: 1179 case kTwoByteStringCid:
1148 case kExternalTwoByteStringCid: 1180 case kExternalTwoByteStringCid:
1149 __ ldr(result, element_address, kUnsignedHalfword); 1181 if (aligned()) {
1182 __ ldr(result, element_address, kUnsignedHalfword);
1183 } else {
1184 __ LoadUnaligned(result, address, TMP, kUnsignedHalfword);
1185 }
1150 __ SmiTag(result); 1186 __ SmiTag(result);
1151 break; 1187 break;
1152 default: 1188 default:
1153 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1189 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1190 ASSERT(aligned());
1154 __ ldr(result, element_address); 1191 __ ldr(result, element_address);
1155 break; 1192 break;
1156 } 1193 }
1157 } 1194 }
1158 1195
1159 1196
1160 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone, 1197 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Zone* zone,
1161 bool opt) const { 1198 bool opt) const {
1162 const intptr_t kNumInputs = 2; 1199 const intptr_t kNumInputs = 2;
1163 const intptr_t kNumTemps = 0; 1200 const intptr_t kNumTemps = 0;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 default: 1277 default:
1241 UNREACHABLE(); 1278 UNREACHABLE();
1242 return kTagged; 1279 return kTagged;
1243 } 1280 }
1244 } 1281 }
1245 1282
1246 1283
1247 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone, 1284 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
1248 bool opt) const { 1285 bool opt) const {
1249 const intptr_t kNumInputs = 3; 1286 const intptr_t kNumInputs = 3;
1250 const intptr_t kNumTemps = 0; 1287 const intptr_t kNumTemps = aligned() ? 0 : 2;
1251 LocationSummary* locs = new(zone) LocationSummary( 1288 LocationSummary* locs = new(zone) LocationSummary(
1252 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1289 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1253 locs->set_in(0, Location::RequiresRegister()); 1290 locs->set_in(0, Location::RequiresRegister());
1254 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) { 1291 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) {
1255 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 1292 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
1256 } else { 1293 } else {
1257 locs->set_in(1, Location::WritableRegister()); 1294 locs->set_in(1, Location::WritableRegister());
1258 } 1295 }
1259 switch (class_id()) { 1296 switch (class_id()) {
1260 case kArrayCid: 1297 case kArrayCid:
(...skipping 19 matching lines...) Expand all
1280 break; 1317 break;
1281 case kTypedDataInt32x4ArrayCid: 1318 case kTypedDataInt32x4ArrayCid:
1282 case kTypedDataFloat32x4ArrayCid: 1319 case kTypedDataFloat32x4ArrayCid:
1283 case kTypedDataFloat64x2ArrayCid: 1320 case kTypedDataFloat64x2ArrayCid:
1284 locs->set_in(2, Location::RequiresFpuRegister()); 1321 locs->set_in(2, Location::RequiresFpuRegister());
1285 break; 1322 break;
1286 default: 1323 default:
1287 UNREACHABLE(); 1324 UNREACHABLE();
1288 return NULL; 1325 return NULL;
1289 } 1326 }
1327 if (!aligned()) {
1328 locs->set_temp(0, Location::RequiresRegister());
1329 locs->set_temp(1, Location::RequiresRegister());
1330 }
1290 return locs; 1331 return locs;
1291 } 1332 }
1292 1333
1293 1334
1294 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1335 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1295 // The array register points to the backing store for external arrays. 1336 // The array register points to the backing store for external arrays.
1296 const Register array = locs()->in(0).reg(); 1337 const Register array = locs()->in(0).reg();
1297 const Location index = locs()->in(1); 1338 const Location index = locs()->in(1);
1339 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg();
1340 const Register scratch = aligned() ? kNoRegister : locs()->temp(1).reg();
1298 1341
1299 Address element_address = index.IsRegister() 1342 Address element_address(TMP);
zra 2016/10/26 06:59:41 ditto
1343 if (aligned()) {
1344 element_address = index.IsRegister()
1300 ? __ ElementAddressForRegIndex(false, // Store. 1345 ? __ ElementAddressForRegIndex(false, // Store.
1301 IsExternal(), class_id(), index_scale(), 1346 IsExternal(), class_id(), index_scale(),
1302 array, index.reg()) 1347 array, index.reg())
1303 : __ ElementAddressForIntIndex( 1348 : __ ElementAddressForIntIndex(
1304 IsExternal(), class_id(), index_scale(), 1349 IsExternal(), class_id(), index_scale(),
1305 array, Smi::Cast(index.constant()).Value()); 1350 array, Smi::Cast(index.constant()).Value());
1351 } else {
1352 if (index.IsRegister()) {
1353 __ LoadElementAddressForRegIndex(address,
1354 false, // Store.
1355 IsExternal(), class_id(), index_scale(),
1356 array, index.reg());
1357 } else {
1358 __ LoadElementAddressForIntIndex(address,
1359 IsExternal(), class_id(), index_scale(),
1360 array,
1361 Smi::Cast(index.constant()).Value());
1362 }
1363 }
1306 1364
1307 switch (class_id()) { 1365 switch (class_id()) {
1308 case kArrayCid: 1366 case kArrayCid:
1367 ASSERT(aligned());
1309 if (ShouldEmitStoreBarrier()) { 1368 if (ShouldEmitStoreBarrier()) {
1310 const Register value = locs()->in(2).reg(); 1369 const Register value = locs()->in(2).reg();
1311 __ StoreIntoObject(array, element_address, value); 1370 __ StoreIntoObject(array, element_address, value);
1312 } else if (locs()->in(2).IsConstant()) { 1371 } else if (locs()->in(2).IsConstant()) {
1313 const Object& constant = locs()->in(2).constant(); 1372 const Object& constant = locs()->in(2).constant();
1314 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1373 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1315 } else { 1374 } else {
1316 const Register value = locs()->in(2).reg(); 1375 const Register value = locs()->in(2).reg();
1317 __ StoreIntoObjectNoBarrier(array, element_address, value); 1376 __ StoreIntoObjectNoBarrier(array, element_address, value);
1318 } 1377 }
1319 break; 1378 break;
1320 case kTypedDataInt8ArrayCid: 1379 case kTypedDataInt8ArrayCid:
1321 case kTypedDataUint8ArrayCid: 1380 case kTypedDataUint8ArrayCid:
1322 case kExternalTypedDataUint8ArrayCid: 1381 case kExternalTypedDataUint8ArrayCid:
1323 case kOneByteStringCid: { 1382 case kOneByteStringCid: {
1383 ASSERT(aligned());
1324 if (locs()->in(2).IsConstant()) { 1384 if (locs()->in(2).IsConstant()) {
1325 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1385 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1326 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value())); 1386 __ LoadImmediate(TMP, static_cast<int8_t>(constant.Value()));
1327 __ str(TMP, element_address, kUnsignedByte); 1387 __ str(TMP, element_address, kUnsignedByte);
1328 } else { 1388 } else {
1329 const Register value = locs()->in(2).reg(); 1389 const Register value = locs()->in(2).reg();
1330 __ SmiUntag(TMP, value); 1390 __ SmiUntag(TMP, value);
1331 __ str(TMP, element_address, kUnsignedByte); 1391 __ str(TMP, element_address, kUnsignedByte);
1332 } 1392 }
1333 break; 1393 break;
1334 } 1394 }
1335 case kTypedDataUint8ClampedArrayCid: 1395 case kTypedDataUint8ClampedArrayCid:
1336 case kExternalTypedDataUint8ClampedArrayCid: { 1396 case kExternalTypedDataUint8ClampedArrayCid: {
1397 ASSERT(aligned());
1337 if (locs()->in(2).IsConstant()) { 1398 if (locs()->in(2).IsConstant()) {
1338 const Smi& constant = Smi::Cast(locs()->in(2).constant()); 1399 const Smi& constant = Smi::Cast(locs()->in(2).constant());
1339 intptr_t value = constant.Value(); 1400 intptr_t value = constant.Value();
1340 // Clamp to 0x0 or 0xFF respectively. 1401 // Clamp to 0x0 or 0xFF respectively.
1341 if (value > 0xFF) { 1402 if (value > 0xFF) {
1342 value = 0xFF; 1403 value = 0xFF;
1343 } else if (value < 0) { 1404 } else if (value < 0) {
1344 value = 0; 1405 value = 0;
1345 } 1406 }
1346 __ LoadImmediate(TMP, static_cast<int8_t>(value)); 1407 __ LoadImmediate(TMP, static_cast<int8_t>(value));
1347 __ str(TMP, element_address, kUnsignedByte); 1408 __ str(TMP, element_address, kUnsignedByte);
1348 } else { 1409 } else {
1349 const Register value = locs()->in(2).reg(); 1410 const Register value = locs()->in(2).reg();
1350 __ CompareImmediate(value, 0x1FE); // Smi value and smi 0xFF. 1411 __ CompareImmediate(value, 0x1FE); // Smi value and smi 0xFF.
1351 // Clamp to 0x00 or 0xFF respectively. 1412 // Clamp to 0x00 or 0xFF respectively.
1352 __ csetm(TMP, GT); // TMP = value > 0x1FE ? -1 : 0. 1413 __ csetm(TMP, GT); // TMP = value > 0x1FE ? -1 : 0.
1353 __ csel(TMP, value, TMP, LS); // TMP = value in range ? value : TMP. 1414 __ csel(TMP, value, TMP, LS); // TMP = value in range ? value : TMP.
1354 __ SmiUntag(TMP); 1415 __ SmiUntag(TMP);
1355 __ str(TMP, element_address, kUnsignedByte); 1416 __ str(TMP, element_address, kUnsignedByte);
1356 } 1417 }
1357 break; 1418 break;
1358 } 1419 }
1359 case kTypedDataInt16ArrayCid: 1420 case kTypedDataInt16ArrayCid:
1360 case kTypedDataUint16ArrayCid: { 1421 case kTypedDataUint16ArrayCid: {
1361 const Register value = locs()->in(2).reg(); 1422 const Register value = locs()->in(2).reg();
1362 __ SmiUntag(TMP, value); 1423 __ SmiUntag(TMP, value);
1363 __ str(TMP, element_address, kUnsignedHalfword); 1424 if (aligned()) {
1425 __ str(TMP, element_address, kUnsignedHalfword);
1426 } else {
1427 __ StoreUnaligned(TMP, address, scratch, kUnsignedHalfword);
1428 }
1364 break; 1429 break;
1365 } 1430 }
1366 case kTypedDataInt32ArrayCid: 1431 case kTypedDataInt32ArrayCid:
1367 case kTypedDataUint32ArrayCid: { 1432 case kTypedDataUint32ArrayCid: {
1368 const Register value = locs()->in(2).reg(); 1433 const Register value = locs()->in(2).reg();
1369 __ str(value, element_address, kUnsignedWord); 1434 if (aligned()) {
1435 __ str(value, element_address, kUnsignedWord);
1436 } else {
1437 __ StoreUnaligned(value, address, scratch, kUnsignedWord);
1438 }
1370 break; 1439 break;
1371 } 1440 }
1372 case kTypedDataFloat32ArrayCid: { 1441 case kTypedDataFloat32ArrayCid: {
1442 ASSERT(aligned());
1373 const VRegister value_reg = locs()->in(2).fpu_reg(); 1443 const VRegister value_reg = locs()->in(2).fpu_reg();
1374 __ fstrs(value_reg, element_address); 1444 __ fstrs(value_reg, element_address);
1375 break; 1445 break;
1376 } 1446 }
1377 case kTypedDataFloat64ArrayCid: { 1447 case kTypedDataFloat64ArrayCid: {
1448 ASSERT(aligned());
1378 const VRegister value_reg = locs()->in(2).fpu_reg(); 1449 const VRegister value_reg = locs()->in(2).fpu_reg();
1379 __ fstrd(value_reg, element_address); 1450 __ fstrd(value_reg, element_address);
1380 break; 1451 break;
1381 } 1452 }
1382 case kTypedDataFloat64x2ArrayCid: 1453 case kTypedDataFloat64x2ArrayCid:
1383 case kTypedDataInt32x4ArrayCid: 1454 case kTypedDataInt32x4ArrayCid:
1384 case kTypedDataFloat32x4ArrayCid: { 1455 case kTypedDataFloat32x4ArrayCid: {
1456 ASSERT(aligned());
1385 const VRegister value_reg = locs()->in(2).fpu_reg(); 1457 const VRegister value_reg = locs()->in(2).fpu_reg();
1386 __ fstrq(value_reg, element_address); 1458 __ fstrq(value_reg, element_address);
1387 break; 1459 break;
1388 } 1460 }
1389 default: 1461 default:
1390 UNREACHABLE(); 1462 UNREACHABLE();
1391 } 1463 }
1392 } 1464 }
1393 1465
1394 1466
(...skipping 4420 matching lines...) Expand 10 before | Expand all | Expand 10 after
5815 1, 5887 1,
5816 locs()); 5888 locs());
5817 __ Drop(1); 5889 __ Drop(1);
5818 __ Pop(result); 5890 __ Pop(result);
5819 } 5891 }
5820 5892
5821 5893
5822 } // namespace dart 5894 } // namespace dart
5823 5895
5824 #endif // defined TARGET_ARCH_ARM64 5896 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698