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

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

Issue 300513002: Generate better ARM code for indexed loads and stores. (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
« runtime/vm/assembler_arm.cc ('K') | « runtime/vm/assembler_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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 return kUnboxedFloat32x4; 1131 return kUnboxedFloat32x4;
1132 case kTypedDataFloat64x2ArrayCid: 1132 case kTypedDataFloat64x2ArrayCid:
1133 return kUnboxedFloat64x2; 1133 return kUnboxedFloat64x2;
1134 default: 1134 default:
1135 UNREACHABLE(); 1135 UNREACHABLE();
1136 return kTagged; 1136 return kTagged;
1137 } 1137 }
1138 } 1138 }
1139 1139
1140 1140
1141 static bool CanBeImmediateIndex(Value* value,
1142 intptr_t cid,
1143 bool is_external,
1144 bool is_load) {
1145 ConstantInstr* constant = value->definition()->AsConstant();
1146 if ((constant == NULL) || !Assembler::IsSafeSmi(constant->value())) {
1147 return false;
1148 }
1149 const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
1150 const intptr_t scale = Instance::ElementSizeFor(cid);
1151 const int64_t offset = index * scale +
1152 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
1153 if (!Utils::IsAbsoluteUint(12, offset)) {
1154 return false;
1155 }
1156 int32_t offset_mask = 0;
1157 if (is_load) {
1158 return Address::CanHoldLoadOffset(Address::OperandSizeFor(cid),
1159 offset,
1160 &offset_mask);
1161 } else {
1162 return Address::CanHoldStoreOffset(Address::OperandSizeFor(cid),
1163 offset,
1164 &offset_mask);
1165 }
1166 }
1167
1168
1141 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Isolate* isolate, 1169 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Isolate* isolate,
1142 bool opt) const { 1170 bool opt) const {
1143 const intptr_t kNumInputs = 2; 1171 const intptr_t kNumInputs = 2;
1144 const intptr_t kNumTemps = 0; 1172 const intptr_t kNumTemps = 0;
1145 LocationSummary* locs = new(isolate) LocationSummary( 1173 LocationSummary* locs = new(isolate) LocationSummary(
1146 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1174 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1147 locs->set_in(0, Location::RequiresRegister()); 1175 locs->set_in(0, Location::RequiresRegister());
1148 // The smi index is either untagged (element size == 1), or it is left smi 1176 if (CanBeImmediateIndex(index(), class_id(), IsExternal(), true /*load*/)) {
1149 // tagged (for all element sizes > 1). 1177 // CanBeImmediateIndex must return false for unsafe smis.
1150 // TODO(regis): Revisit and see if the index can be immediate. 1178 locs->set_in(1, Location::Constant(index()->BoundConstant()));
1151 if (index_scale() == 2 && IsExternal()) { 1179 } else {
1152 locs->set_in(1, Location::RequiresRegister()); 1180 locs->set_in(1, Location::RequiresRegister());
1153 } else {
1154 locs->set_in(1, Location::WritableRegister());
1155 } 1181 }
1156 if ((representation() == kUnboxedDouble) || 1182 if ((representation() == kUnboxedDouble) ||
1157 (representation() == kUnboxedFloat32x4) || 1183 (representation() == kUnboxedFloat32x4) ||
1158 (representation() == kUnboxedInt32x4) || 1184 (representation() == kUnboxedInt32x4) ||
1159 (representation() == kUnboxedFloat64x2)) { 1185 (representation() == kUnboxedFloat64x2)) {
1160 if (class_id() == kTypedDataFloat32ArrayCid) { 1186 if (class_id() == kTypedDataFloat32ArrayCid) {
1161 // Need register <= Q7 for float operations. 1187 // Need register <= Q7 for float operations.
1162 // TODO(fschneider): Add a register policy to specify a subset of 1188 // TODO(fschneider): Add a register policy to specify a subset of
1163 // registers. 1189 // registers.
1164 locs->set_out(0, Location::FpuRegisterLocation(Q7)); 1190 locs->set_out(0, Location::FpuRegisterLocation(Q7));
1165 } else { 1191 } else {
1166 locs->set_out(0, Location::RequiresFpuRegister()); 1192 locs->set_out(0, Location::RequiresFpuRegister());
1167 } 1193 }
1168 } else if (representation() == kUnboxedMint) { 1194 } else if (representation() == kUnboxedMint) {
1169 locs->set_out(0, Location::Pair(Location::RequiresRegister(), 1195 locs->set_out(0, Location::Pair(Location::RequiresRegister(),
1170 Location::RequiresRegister())); 1196 Location::RequiresRegister()));
1171 } else { 1197 } else {
1172 ASSERT(representation() == kTagged); 1198 ASSERT(representation() == kTagged);
1173 locs->set_out(0, Location::RequiresRegister()); 1199 locs->set_out(0, Location::RequiresRegister());
1174 } 1200 }
1175 return locs; 1201 return locs;
1176 } 1202 }
1177 1203
1178 1204
1205 static Address ElementAddressForIntIndex(bool is_external,
1206 intptr_t cid,
1207 intptr_t index_scale,
1208 Register array,
1209 intptr_t index) {
1210 const int64_t offset = static_cast<int64_t>(index) * index_scale +
1211 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
1212 ASSERT(Utils::IsInt(32, offset));
1213 return Address(array, static_cast<int32_t>(offset));
1214 }
1215
1216
1217 static Address ElementAddressForRegIndex(Assembler* assembler,
1218 bool is_load,
1219 bool is_external,
1220 intptr_t cid,
1221 intptr_t index_scale,
1222 Register array,
1223 Register index) {
1224 // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
1225 const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
1226 int32_t offset =
1227 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
1228 const OperandSize size = Address::OperandSizeFor(cid);
1229 const Register base = is_load ? IP : index;
zra 2014/05/23 20:03:24 Maybe assert that array and index can't be IP.
regis 2014/05/23 20:21:35 Registers array and index are defined by the regis
1230 if ((offset != 0) ||
1231 (size == kSWord) || (size == kDWord) || (size == kRegList)) {
1232 if (shift < 0) {
1233 ASSERT(shift == -1);
1234 assembler->add(base, array, ShifterOperand(index, ASR, 1));
1235 } else {
1236 assembler->add(base, array, ShifterOperand(index, LSL, shift));
1237 }
1238 } else {
1239 if (shift < 0) {
1240 ASSERT(shift == -1);
1241 return Address(array, index, ASR, 1);
1242 } else {
1243 return Address(array, index, LSL, shift);
1244 }
1245 }
1246 int32_t offset_mask = 0;
1247 if ((is_load && !Address::CanHoldLoadOffset(size,
1248 offset,
1249 &offset_mask)) ||
1250 (!is_load && !Address::CanHoldStoreOffset(size,
1251 offset,
1252 &offset_mask))) {
1253 assembler->AddImmediate(base, offset & ~offset_mask);
1254 offset = offset & offset_mask;
1255 }
1256 return Address(base, offset);
1257 }
1258
1259
1179 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1260 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1261 Register array = locs()->in(0).reg();
zra 2014/05/23 20:03:24 const
regis 2014/05/23 20:21:35 Done.
1262 Location index = locs()->in(1);
1263
1264 Address element_address(kNoRegister, 0);
1265 element_address = index.IsRegister()
1266 ? ElementAddressForRegIndex(compiler->assembler(),
1267 true, // Load.
1268 IsExternal(), class_id(), index_scale(),
1269 array, index.reg())
1270 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(),
1271 array, Smi::Cast(index.constant()).Value());
1272 // Warning: element_address may use register IP as base.
1273
1180 if ((representation() == kUnboxedDouble) || 1274 if ((representation() == kUnboxedDouble) ||
1181 (representation() == kUnboxedFloat32x4) || 1275 (representation() == kUnboxedFloat32x4) ||
1182 (representation() == kUnboxedInt32x4) || 1276 (representation() == kUnboxedInt32x4) ||
1183 (representation() == kUnboxedFloat64x2)) { 1277 (representation() == kUnboxedFloat64x2)) {
1184 const Register array = locs()->in(0).reg();
1185 const Register idx = locs()->in(1).reg();
1186 switch (index_scale()) {
1187 case 1:
1188 __ add(idx, array, ShifterOperand(idx, ASR, kSmiTagSize));
1189 break;
1190 case 4:
1191 __ add(idx, array, ShifterOperand(idx, LSL, 1));
1192 break;
1193 case 8:
1194 __ add(idx, array, ShifterOperand(idx, LSL, 2));
1195 break;
1196 case 16:
1197 __ add(idx, array, ShifterOperand(idx, LSL, 3));
1198 break;
1199 default:
1200 // Case 2 is not reachable: We don't have unboxed 16-bit sized loads.
1201 UNREACHABLE();
1202 }
1203 if (!IsExternal()) {
1204 ASSERT(this->array()->definition()->representation() == kTagged);
1205 __ AddImmediate(idx,
1206 Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
1207 }
1208 Address element_address(idx);
1209 const QRegister result = locs()->out(0).fpu_reg(); 1278 const QRegister result = locs()->out(0).fpu_reg();
1210 const DRegister dresult0 = EvenDRegisterOf(result); 1279 const DRegister dresult0 = EvenDRegisterOf(result);
1211 switch (class_id()) { 1280 switch (class_id()) {
1212 case kTypedDataFloat32ArrayCid: 1281 case kTypedDataFloat32ArrayCid:
1213 // Load single precision float. 1282 // Load single precision float.
1214 // vldrs does not support indexed addressing. 1283 // vldrs does not support indexed addressing.
1215 __ vldrs(EvenSRegisterOf(dresult0), element_address); 1284 __ vldrs(EvenSRegisterOf(dresult0), element_address);
1216 break; 1285 break;
1217 case kTypedDataFloat64ArrayCid: 1286 case kTypedDataFloat64ArrayCid:
1218 // vldrd does not support indexed addressing. 1287 // vldrd does not support indexed addressing.
1219 __ vldrd(dresult0, element_address); 1288 __ vldrd(dresult0, element_address);
1220 break; 1289 break;
1221 case kTypedDataFloat64x2ArrayCid: 1290 case kTypedDataFloat64x2ArrayCid:
1222 case kTypedDataInt32x4ArrayCid: 1291 case kTypedDataInt32x4ArrayCid:
1223 case kTypedDataFloat32x4ArrayCid: 1292 case kTypedDataFloat32x4ArrayCid:
1224 __ vldmd(IA, idx, dresult0, 2); 1293 ASSERT(element_address.Equals(Address(IP)));
1294 __ vldmd(IA, IP, dresult0, 2);
1225 break; 1295 break;
1226 default: 1296 default:
1227 UNREACHABLE(); 1297 UNREACHABLE();
1228 } 1298 }
1229 return; 1299 return;
1230 } 1300 }
1231 1301
1232 const Register array = locs()->in(0).reg();
1233 Location index = locs()->in(1);
1234 ASSERT(index.IsRegister()); // TODO(regis): Revisit.
1235 Address element_address(kNoRegister, 0);
1236 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
1237 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
1238 // index is expected to be untagged before accessing.
1239 ASSERT(kSmiTagShift == 1);
1240 const intptr_t offset = IsExternal()
1241 ? 0
1242 : Instance::DataOffsetFor(class_id()) - kHeapObjectTag;
1243 switch (index_scale()) {
1244 case 1: {
1245 __ add(index.reg(), array, ShifterOperand(index.reg(), ASR, kSmiTagSize));
1246 element_address = Address(index.reg(), offset);
1247 break;
1248 }
1249 case 2: {
1250 // No scaling needed, since index is a smi.
1251 if (!IsExternal()) {
1252 __ AddImmediate(index.reg(), index.reg(),
1253 Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
1254 element_address = Address(array, index.reg(), LSL, 0);
1255 } else {
1256 element_address = Address(array, index.reg(), LSL, 0);
1257 }
1258 break;
1259 }
1260 case 4: {
1261 __ add(index.reg(), array, ShifterOperand(index.reg(), LSL, 1));
1262 element_address = Address(index.reg(), offset);
1263 break;
1264 }
1265 // Cases 8 and 16 are only for unboxed values and are handled above.
1266 default:
1267 UNREACHABLE();
1268 }
1269
1270 if (representation() == kUnboxedMint) { 1302 if (representation() == kUnboxedMint) {
1271 ASSERT(locs()->out(0).IsPairLocation()); 1303 ASSERT(locs()->out(0).IsPairLocation());
1272 PairLocation* result_pair = locs()->out(0).AsPairLocation(); 1304 PairLocation* result_pair = locs()->out(0).AsPairLocation();
1273 Register result1 = result_pair->At(0).reg(); 1305 Register result1 = result_pair->At(0).reg();
zra 2014/05/23 20:03:24 const
regis 2014/05/23 20:21:35 Done.
1274 Register result2 = result_pair->At(1).reg(); 1306 Register result2 = result_pair->At(1).reg();
zra 2014/05/23 20:03:24 const
regis 2014/05/23 20:21:35 Done.
1275 switch (class_id()) { 1307 switch (class_id()) {
1276 case kTypedDataInt32ArrayCid: 1308 case kTypedDataInt32ArrayCid:
1277 // Load low word. 1309 // Load low word.
1278 __ ldr(result1, element_address); 1310 __ ldr(result1, element_address);
1279 // Sign extend into high word. 1311 // Sign extend into high word.
1280 __ SignFill(result2, result1); 1312 __ SignFill(result2, result1);
1281 break; 1313 break;
1282 case kTypedDataUint32ArrayCid: 1314 case kTypedDataUint32ArrayCid:
1283 // Load low word. 1315 // Load low word.
1284 __ ldr(result1, element_address); 1316 __ ldr(result1, element_address);
1285 // Zero high word. 1317 // Zero high word.
1286 __ eor(result2, result2, ShifterOperand(result2)); 1318 __ eor(result2, result2, ShifterOperand(result2));
1287 break; 1319 break;
1288 default: 1320 default:
1289 UNREACHABLE(); 1321 UNREACHABLE();
1290 break; 1322 break;
1291 } 1323 }
1292 return; 1324 return;
1293 } 1325 }
1294 1326
1295 ASSERT(representation() == kTagged); 1327 ASSERT(representation() == kTagged);
1296 1328
1297 Register result = locs()->out(0).reg(); 1329 Register result = locs()->out(0).reg();
1298 switch (class_id()) { 1330 switch (class_id()) {
1299 case kTypedDataInt8ArrayCid: 1331 case kTypedDataInt8ArrayCid:
1300 ASSERT(index_scale() == 1); 1332 ASSERT(index_scale() == 1);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 } 1415 }
1384 1416
1385 1417
1386 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Isolate* isolate, 1418 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Isolate* isolate,
1387 bool opt) const { 1419 bool opt) const {
1388 const intptr_t kNumInputs = 3; 1420 const intptr_t kNumInputs = 3;
1389 const intptr_t kNumTemps = 0; 1421 const intptr_t kNumTemps = 0;
1390 LocationSummary* locs = new(isolate) LocationSummary( 1422 LocationSummary* locs = new(isolate) LocationSummary(
1391 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1423 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1392 locs->set_in(0, Location::RequiresRegister()); 1424 locs->set_in(0, Location::RequiresRegister());
1393 // The smi index is either untagged (element size == 1), or it is left smi 1425 if (CanBeImmediateIndex(index(), class_id(), IsExternal(), false /*store*/)) {
1394 // tagged (for all element sizes > 1). 1426 // CanBeImmediateIndex must return false for unsafe smis.
1395 // TODO(regis): Revisit and see if the index can be immediate. 1427 locs->set_in(1, Location::Constant(index()->BoundConstant()));
1396 locs->set_in(1, Location::WritableRegister()); 1428 } else {
1429 locs->set_in(1, Location::WritableRegister());
1430 }
1397 switch (class_id()) { 1431 switch (class_id()) {
1398 case kArrayCid: 1432 case kArrayCid:
1399 locs->set_in(2, ShouldEmitStoreBarrier() 1433 locs->set_in(2, ShouldEmitStoreBarrier()
1400 ? Location::WritableRegister() 1434 ? Location::WritableRegister()
1401 : Location::RegisterOrConstant(value())); 1435 : Location::RegisterOrConstant(value()));
1402 break; 1436 break;
1403 case kExternalTypedDataUint8ArrayCid: 1437 case kExternalTypedDataUint8ArrayCid:
1404 case kExternalTypedDataUint8ClampedArrayCid: 1438 case kExternalTypedDataUint8ClampedArrayCid:
1405 case kTypedDataInt8ArrayCid: 1439 case kTypedDataInt8ArrayCid:
1406 case kTypedDataUint8ArrayCid: 1440 case kTypedDataUint8ArrayCid:
(...skipping 28 matching lines...) Expand all
1435 break; 1469 break;
1436 default: 1470 default:
1437 UNREACHABLE(); 1471 UNREACHABLE();
1438 return NULL; 1472 return NULL;
1439 } 1473 }
1440 return locs; 1474 return locs;
1441 } 1475 }
1442 1476
1443 1477
1444 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1478 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1445 if ((class_id() == kTypedDataFloat32ArrayCid) || 1479 Register array = locs()->in(0).reg();
zra 2014/05/23 20:03:24 const
regis 2014/05/23 20:21:35 Done.
1446 (class_id() == kTypedDataFloat64ArrayCid) ||
1447 (class_id() == kTypedDataFloat32x4ArrayCid) ||
1448 (class_id() == kTypedDataFloat64x2ArrayCid) ||
1449 (class_id() == kTypedDataInt32x4ArrayCid)) {
1450 const Register array = locs()->in(0).reg();
1451 const Register idx = locs()->in(1).reg();
1452 Location value = locs()->in(2);
1453 switch (index_scale()) {
1454 case 1:
1455 __ add(idx, array, ShifterOperand(idx, ASR, kSmiTagSize));
1456 break;
1457 case 4:
1458 __ add(idx, array, ShifterOperand(idx, LSL, 1));
1459 break;
1460 case 8:
1461 __ add(idx, array, ShifterOperand(idx, LSL, 2));
1462 break;
1463 case 16:
1464 __ add(idx, array, ShifterOperand(idx, LSL, 3));
1465 break;
1466 default:
1467 // Case 2 is not reachable: We don't have unboxed 16-bit sized loads.
1468 UNREACHABLE();
1469 }
1470 if (!IsExternal()) {
1471 ASSERT(this->array()->definition()->representation() == kTagged);
1472 __ AddImmediate(idx,
1473 Instance::DataOffsetFor(class_id()) - kHeapObjectTag);
1474 }
1475 switch (class_id()) {
1476 case kTypedDataFloat32ArrayCid: {
1477 const SRegister value_reg =
1478 EvenSRegisterOf(EvenDRegisterOf(value.fpu_reg()));
1479 __ StoreSToOffset(value_reg, idx, 0);
1480 break;
1481 }
1482 case kTypedDataFloat64ArrayCid: {
1483 const DRegister value_reg = EvenDRegisterOf(value.fpu_reg());
1484 __ StoreDToOffset(value_reg, idx, 0);
1485 break;
1486 }
1487 case kTypedDataFloat64x2ArrayCid:
1488 case kTypedDataInt32x4ArrayCid:
1489 case kTypedDataFloat32x4ArrayCid: {
1490 const DRegister value_reg = EvenDRegisterOf(value.fpu_reg());
1491 __ vstmd(IA, idx, value_reg, 2);
1492 break;
1493 }
1494 default:
1495 UNREACHABLE();
1496 }
1497 return;
1498 }
1499
1500 const Register array = locs()->in(0).reg();
1501 Location index = locs()->in(1); 1480 Location index = locs()->in(1);
1502 1481
1503 Address element_address(kNoRegister, 0); 1482 Address element_address(kNoRegister, 0);
1504 ASSERT(index.IsRegister()); // TODO(regis): Revisit. 1483 element_address = index.IsRegister()
1505 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays 1484 ? ElementAddressForRegIndex(compiler->assembler(),
1506 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the 1485 false, // Store.
1507 // index is expected to be untagged before accessing. 1486 IsExternal(), class_id(), index_scale(),
1508 ASSERT(kSmiTagShift == 1); 1487 array, index.reg())
1509 const intptr_t offset = IsExternal() 1488 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(),
1510 ? 0 1489 array, Smi::Cast(index.constant()).Value());
1511 : Instance::DataOffsetFor(class_id()) - kHeapObjectTag;
1512 switch (index_scale()) {
1513 case 1: {
1514 __ add(index.reg(), array, ShifterOperand(index.reg(), ASR, kSmiTagSize));
1515 element_address = Address(index.reg(), offset);
1516 break;
1517 }
1518 case 2: {
1519 // No scaling needed, since index is a smi.
1520 if (!IsExternal()) {
1521 __ AddImmediate(index.reg(), index.reg(), offset);
1522 element_address = Address(array, index.reg(), LSL, 0);
1523 } else {
1524 element_address = Address(array, index.reg(), LSL, 0);
1525 }
1526 break;
1527 }
1528 case 4: {
1529 __ add(index.reg(), array, ShifterOperand(index.reg(), LSL, 1));
1530 element_address = Address(index.reg(), offset);
1531 break;
1532 }
1533 // Cases 8 and 16 are only for unboxed values and are handled above.
1534 default:
1535 UNREACHABLE();
1536 }
1537 1490
1538 switch (class_id()) { 1491 switch (class_id()) {
1539 case kArrayCid: 1492 case kArrayCid:
1540 if (ShouldEmitStoreBarrier()) { 1493 if (ShouldEmitStoreBarrier()) {
1541 const Register value = locs()->in(2).reg(); 1494 const Register value = locs()->in(2).reg();
1542 __ StoreIntoObject(array, element_address, value); 1495 __ StoreIntoObject(array, element_address, value);
1543 } else if (locs()->in(2).IsConstant()) { 1496 } else if (locs()->in(2).IsConstant()) {
1544 const Object& constant = locs()->in(2).constant(); 1497 const Object& constant = locs()->in(2).constant();
1545 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1498 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1546 } else { 1499 } else {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 __ SmiUntag(value); 1558 __ SmiUntag(value);
1606 __ str(value, element_address); 1559 __ str(value, element_address);
1607 } else { 1560 } else {
1608 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); 1561 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint);
1609 PairLocation* value_pair = locs()->in(2).AsPairLocation(); 1562 PairLocation* value_pair = locs()->in(2).AsPairLocation();
1610 Register value1 = value_pair->At(0).reg(); 1563 Register value1 = value_pair->At(0).reg();
1611 __ str(value1, element_address); 1564 __ str(value1, element_address);
1612 } 1565 }
1613 break; 1566 break;
1614 } 1567 }
1568 case kTypedDataFloat32ArrayCid: {
1569 const SRegister value_reg =
1570 EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg()));
1571 __ vstrs(value_reg, element_address);
1572 break;
1573 }
1574 case kTypedDataFloat64ArrayCid: {
1575 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg());
1576 __ vstrd(value_reg, element_address);
1577 break;
1578 }
1579 case kTypedDataFloat64x2ArrayCid:
1580 case kTypedDataInt32x4ArrayCid:
1581 case kTypedDataFloat32x4ArrayCid: {
1582 ASSERT(element_address.Equals(Address(index.reg())));
1583 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg());
1584 __ vstmd(IA, index.reg(), value_reg, 2);
1585 break;
1586 }
1615 default: 1587 default:
1616 UNREACHABLE(); 1588 UNREACHABLE();
1617 } 1589 }
1618 } 1590 }
1619 1591
1620 1592
1621 LocationSummary* GuardFieldInstr::MakeLocationSummary(Isolate* isolate, 1593 LocationSummary* GuardFieldInstr::MakeLocationSummary(Isolate* isolate,
1622 bool opt) const { 1594 bool opt) const {
1623 const intptr_t kNumInputs = 1; 1595 const intptr_t kNumInputs = 1;
1624 LocationSummary* summary = new(isolate) LocationSummary( 1596 LocationSummary* summary = new(isolate) LocationSummary(
(...skipping 4813 matching lines...) Expand 10 before | Expand all | Expand 10 after
6438 compiler->GenerateCall(token_pos(), 6410 compiler->GenerateCall(token_pos(),
6439 &label, 6411 &label,
6440 PcDescriptors::kOther, 6412 PcDescriptors::kOther,
6441 locs()); 6413 locs());
6442 __ Drop(ArgumentCount()); // Discard arguments. 6414 __ Drop(ArgumentCount()); // Discard arguments.
6443 } 6415 }
6444 6416
6445 } // namespace dart 6417 } // namespace dart
6446 6418
6447 #endif // defined TARGET_ARCH_ARM 6419 #endif // defined TARGET_ARCH_ARM
OLDNEW
« runtime/vm/assembler_arm.cc ('K') | « runtime/vm/assembler_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698