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

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
« no previous file with comments | « 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 ASSERT(array != IP);
1230 ASSERT(index != IP);
1231 const Register base = is_load ? IP : index;
1232 if ((offset != 0) ||
1233 (size == kSWord) || (size == kDWord) || (size == kRegList)) {
1234 if (shift < 0) {
1235 ASSERT(shift == -1);
1236 assembler->add(base, array, ShifterOperand(index, ASR, 1));
1237 } else {
1238 assembler->add(base, array, ShifterOperand(index, LSL, shift));
1239 }
1240 } else {
1241 if (shift < 0) {
1242 ASSERT(shift == -1);
1243 return Address(array, index, ASR, 1);
1244 } else {
1245 return Address(array, index, LSL, shift);
1246 }
1247 }
1248 int32_t offset_mask = 0;
1249 if ((is_load && !Address::CanHoldLoadOffset(size,
1250 offset,
1251 &offset_mask)) ||
1252 (!is_load && !Address::CanHoldStoreOffset(size,
1253 offset,
1254 &offset_mask))) {
1255 assembler->AddImmediate(base, offset & ~offset_mask);
1256 offset = offset & offset_mask;
1257 }
1258 return Address(base, offset);
1259 }
1260
1261
1179 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1262 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1263 const Register array = locs()->in(0).reg();
1264 const Location index = locs()->in(1);
1265
1266 Address element_address(kNoRegister, 0);
1267 element_address = index.IsRegister()
1268 ? ElementAddressForRegIndex(compiler->assembler(),
1269 true, // Load.
1270 IsExternal(), class_id(), index_scale(),
1271 array, index.reg())
1272 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(),
1273 array, Smi::Cast(index.constant()).Value());
1274 // Warning: element_address may use register IP as base.
1275
1180 if ((representation() == kUnboxedDouble) || 1276 if ((representation() == kUnboxedDouble) ||
1181 (representation() == kUnboxedFloat32x4) || 1277 (representation() == kUnboxedFloat32x4) ||
1182 (representation() == kUnboxedInt32x4) || 1278 (representation() == kUnboxedInt32x4) ||
1183 (representation() == kUnboxedFloat64x2)) { 1279 (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(); 1280 const QRegister result = locs()->out(0).fpu_reg();
1210 const DRegister dresult0 = EvenDRegisterOf(result); 1281 const DRegister dresult0 = EvenDRegisterOf(result);
1211 switch (class_id()) { 1282 switch (class_id()) {
1212 case kTypedDataFloat32ArrayCid: 1283 case kTypedDataFloat32ArrayCid:
1213 // Load single precision float. 1284 // Load single precision float.
1214 // vldrs does not support indexed addressing. 1285 // vldrs does not support indexed addressing.
1215 __ vldrs(EvenSRegisterOf(dresult0), element_address); 1286 __ vldrs(EvenSRegisterOf(dresult0), element_address);
1216 break; 1287 break;
1217 case kTypedDataFloat64ArrayCid: 1288 case kTypedDataFloat64ArrayCid:
1218 // vldrd does not support indexed addressing. 1289 // vldrd does not support indexed addressing.
1219 __ vldrd(dresult0, element_address); 1290 __ vldrd(dresult0, element_address);
1220 break; 1291 break;
1221 case kTypedDataFloat64x2ArrayCid: 1292 case kTypedDataFloat64x2ArrayCid:
1222 case kTypedDataInt32x4ArrayCid: 1293 case kTypedDataInt32x4ArrayCid:
1223 case kTypedDataFloat32x4ArrayCid: 1294 case kTypedDataFloat32x4ArrayCid:
1224 __ vldmd(IA, idx, dresult0, 2); 1295 ASSERT(element_address.Equals(Address(IP)));
1296 __ vldmd(IA, IP, dresult0, 2);
1225 break; 1297 break;
1226 default: 1298 default:
1227 UNREACHABLE(); 1299 UNREACHABLE();
1228 } 1300 }
1229 return; 1301 return;
1230 } 1302 }
1231 1303
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) { 1304 if (representation() == kUnboxedMint) {
1271 ASSERT(locs()->out(0).IsPairLocation()); 1305 ASSERT(locs()->out(0).IsPairLocation());
1272 PairLocation* result_pair = locs()->out(0).AsPairLocation(); 1306 PairLocation* result_pair = locs()->out(0).AsPairLocation();
1273 Register result1 = result_pair->At(0).reg(); 1307 const Register result1 = result_pair->At(0).reg();
1274 Register result2 = result_pair->At(1).reg(); 1308 const Register result2 = result_pair->At(1).reg();
1275 switch (class_id()) { 1309 switch (class_id()) {
1276 case kTypedDataInt32ArrayCid: 1310 case kTypedDataInt32ArrayCid:
1277 // Load low word. 1311 // Load low word.
1278 __ ldr(result1, element_address); 1312 __ ldr(result1, element_address);
1279 // Sign extend into high word. 1313 // Sign extend into high word.
1280 __ SignFill(result2, result1); 1314 __ SignFill(result2, result1);
1281 break; 1315 break;
1282 case kTypedDataUint32ArrayCid: 1316 case kTypedDataUint32ArrayCid:
1283 // Load low word. 1317 // Load low word.
1284 __ ldr(result1, element_address); 1318 __ ldr(result1, element_address);
1285 // Zero high word. 1319 // Zero high word.
1286 __ eor(result2, result2, ShifterOperand(result2)); 1320 __ eor(result2, result2, ShifterOperand(result2));
1287 break; 1321 break;
1288 default: 1322 default:
1289 UNREACHABLE(); 1323 UNREACHABLE();
1290 break; 1324 break;
1291 } 1325 }
1292 return; 1326 return;
1293 } 1327 }
1294 1328
1295 ASSERT(representation() == kTagged); 1329 ASSERT(representation() == kTagged);
1296 1330
1297 Register result = locs()->out(0).reg(); 1331 Register result = locs()->out(0).reg();
1298 switch (class_id()) { 1332 switch (class_id()) {
1299 case kTypedDataInt8ArrayCid: 1333 case kTypedDataInt8ArrayCid:
1300 ASSERT(index_scale() == 1); 1334 ASSERT(index_scale() == 1);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 } 1417 }
1384 1418
1385 1419
1386 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Isolate* isolate, 1420 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Isolate* isolate,
1387 bool opt) const { 1421 bool opt) const {
1388 const intptr_t kNumInputs = 3; 1422 const intptr_t kNumInputs = 3;
1389 const intptr_t kNumTemps = 0; 1423 const intptr_t kNumTemps = 0;
1390 LocationSummary* locs = new(isolate) LocationSummary( 1424 LocationSummary* locs = new(isolate) LocationSummary(
1391 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1425 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1392 locs->set_in(0, Location::RequiresRegister()); 1426 locs->set_in(0, Location::RequiresRegister());
1393 // The smi index is either untagged (element size == 1), or it is left smi 1427 if (CanBeImmediateIndex(index(), class_id(), IsExternal(), false /*store*/)) {
1394 // tagged (for all element sizes > 1). 1428 // CanBeImmediateIndex must return false for unsafe smis.
1395 // TODO(regis): Revisit and see if the index can be immediate. 1429 locs->set_in(1, Location::Constant(index()->BoundConstant()));
1396 locs->set_in(1, Location::WritableRegister()); 1430 } else {
1431 locs->set_in(1, Location::WritableRegister());
1432 }
1397 switch (class_id()) { 1433 switch (class_id()) {
1398 case kArrayCid: 1434 case kArrayCid:
1399 locs->set_in(2, ShouldEmitStoreBarrier() 1435 locs->set_in(2, ShouldEmitStoreBarrier()
1400 ? Location::WritableRegister() 1436 ? Location::WritableRegister()
1401 : Location::RegisterOrConstant(value())); 1437 : Location::RegisterOrConstant(value()));
1402 break; 1438 break;
1403 case kExternalTypedDataUint8ArrayCid: 1439 case kExternalTypedDataUint8ArrayCid:
1404 case kExternalTypedDataUint8ClampedArrayCid: 1440 case kExternalTypedDataUint8ClampedArrayCid:
1405 case kTypedDataInt8ArrayCid: 1441 case kTypedDataInt8ArrayCid:
1406 case kTypedDataUint8ArrayCid: 1442 case kTypedDataUint8ArrayCid:
(...skipping 28 matching lines...) Expand all
1435 break; 1471 break;
1436 default: 1472 default:
1437 UNREACHABLE(); 1473 UNREACHABLE();
1438 return NULL; 1474 return NULL;
1439 } 1475 }
1440 return locs; 1476 return locs;
1441 } 1477 }
1442 1478
1443 1479
1444 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1480 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1445 if ((class_id() == kTypedDataFloat32ArrayCid) ||
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(); 1481 const Register array = locs()->in(0).reg();
1501 Location index = locs()->in(1); 1482 Location index = locs()->in(1);
1502 1483
1503 Address element_address(kNoRegister, 0); 1484 Address element_address(kNoRegister, 0);
1504 ASSERT(index.IsRegister()); // TODO(regis): Revisit. 1485 element_address = index.IsRegister()
1505 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays 1486 ? ElementAddressForRegIndex(compiler->assembler(),
1506 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the 1487 false, // Store.
1507 // index is expected to be untagged before accessing. 1488 IsExternal(), class_id(), index_scale(),
1508 ASSERT(kSmiTagShift == 1); 1489 array, index.reg())
1509 const intptr_t offset = IsExternal() 1490 : ElementAddressForIntIndex(IsExternal(), class_id(), index_scale(),
1510 ? 0 1491 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 1492
1538 switch (class_id()) { 1493 switch (class_id()) {
1539 case kArrayCid: 1494 case kArrayCid:
1540 if (ShouldEmitStoreBarrier()) { 1495 if (ShouldEmitStoreBarrier()) {
1541 const Register value = locs()->in(2).reg(); 1496 const Register value = locs()->in(2).reg();
1542 __ StoreIntoObject(array, element_address, value); 1497 __ StoreIntoObject(array, element_address, value);
1543 } else if (locs()->in(2).IsConstant()) { 1498 } else if (locs()->in(2).IsConstant()) {
1544 const Object& constant = locs()->in(2).constant(); 1499 const Object& constant = locs()->in(2).constant();
1545 __ StoreIntoObjectNoBarrier(array, element_address, constant); 1500 __ StoreIntoObjectNoBarrier(array, element_address, constant);
1546 } else { 1501 } else {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 __ SmiUntag(value); 1560 __ SmiUntag(value);
1606 __ str(value, element_address); 1561 __ str(value, element_address);
1607 } else { 1562 } else {
1608 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); 1563 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint);
1609 PairLocation* value_pair = locs()->in(2).AsPairLocation(); 1564 PairLocation* value_pair = locs()->in(2).AsPairLocation();
1610 Register value1 = value_pair->At(0).reg(); 1565 Register value1 = value_pair->At(0).reg();
1611 __ str(value1, element_address); 1566 __ str(value1, element_address);
1612 } 1567 }
1613 break; 1568 break;
1614 } 1569 }
1570 case kTypedDataFloat32ArrayCid: {
1571 const SRegister value_reg =
1572 EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg()));
1573 __ vstrs(value_reg, element_address);
1574 break;
1575 }
1576 case kTypedDataFloat64ArrayCid: {
1577 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg());
1578 __ vstrd(value_reg, element_address);
1579 break;
1580 }
1581 case kTypedDataFloat64x2ArrayCid:
1582 case kTypedDataInt32x4ArrayCid:
1583 case kTypedDataFloat32x4ArrayCid: {
1584 ASSERT(element_address.Equals(Address(index.reg())));
1585 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg());
1586 __ vstmd(IA, index.reg(), value_reg, 2);
1587 break;
1588 }
1615 default: 1589 default:
1616 UNREACHABLE(); 1590 UNREACHABLE();
1617 } 1591 }
1618 } 1592 }
1619 1593
1620 1594
1621 LocationSummary* GuardFieldInstr::MakeLocationSummary(Isolate* isolate, 1595 LocationSummary* GuardFieldInstr::MakeLocationSummary(Isolate* isolate,
1622 bool opt) const { 1596 bool opt) const {
1623 const intptr_t kNumInputs = 1; 1597 const intptr_t kNumInputs = 1;
1624 LocationSummary* summary = new(isolate) LocationSummary( 1598 LocationSummary* summary = new(isolate) LocationSummary(
(...skipping 4813 matching lines...) Expand 10 before | Expand all | Expand 10 after
6438 compiler->GenerateCall(token_pos(), 6412 compiler->GenerateCall(token_pos(),
6439 &label, 6413 &label,
6440 PcDescriptors::kOther, 6414 PcDescriptors::kOther,
6441 locs()); 6415 locs());
6442 __ Drop(ArgumentCount()); // Discard arguments. 6416 __ Drop(ArgumentCount()); // Discard arguments.
6443 } 6417 }
6444 6418
6445 } // namespace dart 6419 } // namespace dart
6446 6420
6447 #endif // defined TARGET_ARCH_ARM 6421 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698