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

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

Issue 2940883008: [arm, arm64] Implemented unaligned scalar float access. (Closed)
Patch Set: piecewise float64 Created 3 years, 6 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
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1
2 // 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
3 // 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
4 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
5 4
6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
7 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
8 7
9 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
10 9
11 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 return true; 1231 return true;
1233 } 1232 }
1234 1233
1235 return false; 1234 return false;
1236 } 1235 }
1237 1236
1238 1237
1239 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone, 1238 LocationSummary* LoadIndexedInstr::MakeLocationSummary(Zone* zone,
1240 bool opt) const { 1239 bool opt) const {
1241 const intptr_t kNumInputs = 2; 1240 const intptr_t kNumInputs = 2;
1242 const intptr_t kNumTemps = aligned() ? 0 : 1; 1241 intptr_t kNumTemps = 0;
1242 if (!aligned()) {
1243 kNumTemps += 1;
1244 if (representation() == kUnboxedDouble) {
1245 kNumTemps += 1;
1246 }
1247 }
1243 LocationSummary* locs = new (zone) 1248 LocationSummary* locs = new (zone)
1244 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1249 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1245 locs->set_in(0, Location::RequiresRegister()); 1250 locs->set_in(0, Location::RequiresRegister());
1246 bool needs_base = false; 1251 bool needs_base = false;
1247 if (CanBeImmediateIndex(index(), class_id(), IsExternal(), 1252 if (CanBeImmediateIndex(index(), class_id(), IsExternal(),
1248 true, // Load. 1253 true, // Load.
1249 &needs_base)) { 1254 &needs_base)) {
1250 // CanBeImmediateIndex must return false for unsafe smis. 1255 // CanBeImmediateIndex must return false for unsafe smis.
1251 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 1256 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
1252 } else { 1257 } else {
(...skipping 16 matching lines...) Expand all
1269 locs->set_out(0, Location::RequiresRegister()); 1274 locs->set_out(0, Location::RequiresRegister());
1270 } else if (representation() == kUnboxedInt32) { 1275 } else if (representation() == kUnboxedInt32) {
1271 ASSERT(class_id() == kTypedDataInt32ArrayCid); 1276 ASSERT(class_id() == kTypedDataInt32ArrayCid);
1272 locs->set_out(0, Location::RequiresRegister()); 1277 locs->set_out(0, Location::RequiresRegister());
1273 } else { 1278 } else {
1274 ASSERT(representation() == kTagged); 1279 ASSERT(representation() == kTagged);
1275 locs->set_out(0, Location::RequiresRegister()); 1280 locs->set_out(0, Location::RequiresRegister());
1276 } 1281 }
1277 if (!aligned()) { 1282 if (!aligned()) {
1278 locs->set_temp(0, Location::RequiresRegister()); 1283 locs->set_temp(0, Location::RequiresRegister());
1284 if (representation() == kUnboxedDouble) {
1285 locs->set_temp(1, Location::RequiresRegister());
1286 }
1279 } 1287 }
1280 return locs; 1288 return locs;
1281 } 1289 }
1282 1290
1283 1291
1284 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1292 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1285 // The array register points to the backing store for external arrays. 1293 // The array register points to the backing store for external arrays.
1286 const Register array = locs()->in(0).reg(); 1294 const Register array = locs()->in(0).reg();
1287 const Location index = locs()->in(1); 1295 const Location index = locs()->in(1);
1288 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg(); 1296 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg();
(...skipping 29 matching lines...) Expand all
1318 if ((representation() == kUnboxedDouble) || 1326 if ((representation() == kUnboxedDouble) ||
1319 (representation() == kUnboxedFloat32x4) || 1327 (representation() == kUnboxedFloat32x4) ||
1320 (representation() == kUnboxedInt32x4) || 1328 (representation() == kUnboxedInt32x4) ||
1321 (representation() == kUnboxedFloat64x2)) { 1329 (representation() == kUnboxedFloat64x2)) {
1322 const QRegister result = locs()->out(0).fpu_reg(); 1330 const QRegister result = locs()->out(0).fpu_reg();
1323 const DRegister dresult0 = EvenDRegisterOf(result); 1331 const DRegister dresult0 = EvenDRegisterOf(result);
1324 switch (class_id()) { 1332 switch (class_id()) {
1325 case kTypedDataFloat32ArrayCid: 1333 case kTypedDataFloat32ArrayCid:
1326 // Load single precision float. 1334 // Load single precision float.
1327 // vldrs does not support indexed addressing. 1335 // vldrs does not support indexed addressing.
1328 __ vldrs(EvenSRegisterOf(dresult0), element_address); 1336 if (aligned()) {
1337 __ vldrs(EvenSRegisterOf(dresult0), element_address);
1338 } else {
1339 const Register value = locs()->temp(1).reg();
1340 __ LoadWordUnaligned(value, address, TMP);
1341 __ vmovsr(EvenSRegisterOf(dresult0), value);
1342 }
1329 break; 1343 break;
1330 case kTypedDataFloat64ArrayCid: 1344 case kTypedDataFloat64ArrayCid:
1331 // vldrd does not support indexed addressing. 1345 // vldrd does not support indexed addressing.
1332 __ vldrd(dresult0, element_address); 1346 if (aligned()) {
1347 __ vldrd(dresult0, element_address);
1348 } else {
1349 const Register value = locs()->temp(1).reg();
1350 __ LoadWordUnaligned(value, address, TMP);
1351 __ vmovsr(EvenSRegisterOf(dresult0), value);
1352 __ AddImmediate(address, address, 4);
1353 __ LoadWordUnaligned(value, address, TMP);
1354 __ vmovsr(OddSRegisterOf(dresult0), value);
1355 }
1333 break; 1356 break;
1334 case kTypedDataFloat64x2ArrayCid: 1357 case kTypedDataFloat64x2ArrayCid:
1335 case kTypedDataInt32x4ArrayCid: 1358 case kTypedDataInt32x4ArrayCid:
1336 case kTypedDataFloat32x4ArrayCid: 1359 case kTypedDataFloat32x4ArrayCid:
1337 ASSERT(element_address.Equals(Address(IP))); 1360 ASSERT(element_address.Equals(Address(IP)));
1361 ASSERT(aligned());
1338 __ vldmd(IA, IP, dresult0, 2); 1362 __ vldmd(IA, IP, dresult0, 2);
1339 break; 1363 break;
1340 default: 1364 default:
1341 UNREACHABLE(); 1365 UNREACHABLE();
1342 } 1366 }
1343 return; 1367 return;
1344 } 1368 }
1345 1369
1346 if ((representation() == kUnboxedUint32) || 1370 if ((representation() == kUnboxedUint32) ||
1347 (representation() == kUnboxedInt32)) { 1371 (representation() == kUnboxedInt32)) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 } 1476 }
1453 } 1477 }
1454 1478
1455 1479
1456 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone, 1480 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
1457 bool opt) const { 1481 bool opt) const {
1458 const intptr_t kNumInputs = 3; 1482 const intptr_t kNumInputs = 3;
1459 LocationSummary* locs; 1483 LocationSummary* locs;
1460 1484
1461 bool needs_base = false; 1485 bool needs_base = false;
1486 intptr_t kNumTemps = 0;
1462 if (CanBeImmediateIndex(index(), class_id(), IsExternal(), 1487 if (CanBeImmediateIndex(index(), class_id(), IsExternal(),
1463 false, // Store. 1488 false, // Store.
1464 &needs_base)) { 1489 &needs_base)) {
1465 const intptr_t kNumTemps = aligned() ? (needs_base ? 1 : 0) : 2; 1490 if (!aligned()) {
1491 kNumTemps += 2;
1492 } else if (needs_base) {
1493 kNumTemps += 1;
1494 }
1495
1466 locs = new (zone) 1496 locs = new (zone)
1467 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1497 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1468 1498
1469 // CanBeImmediateIndex must return false for unsafe smis. 1499 // CanBeImmediateIndex must return false for unsafe smis.
1470 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 1500 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
1471 if (needs_base) { 1501 } else {
1472 locs->set_temp(0, Location::RequiresRegister()); 1502 if (!aligned()) {
1503 kNumTemps += 2;
1473 } 1504 }
1474 if (!aligned()) { 1505
1475 locs->set_temp(0, Location::RequiresRegister());
1476 locs->set_temp(1, Location::RequiresRegister());
1477 }
1478 } else {
1479 const intptr_t kNumTemps = aligned() ? 0 : 2;
1480 locs = new (zone) 1506 locs = new (zone)
1481 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1507 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1482 1508
1483 locs->set_in(1, Location::WritableRegister()); 1509 locs->set_in(1, Location::WritableRegister());
1484 if (!aligned()) {
1485 locs->set_temp(0, Location::RequiresRegister());
1486 locs->set_temp(1, Location::RequiresRegister());
1487 }
1488 } 1510 }
1489 locs->set_in(0, Location::RequiresRegister()); 1511 locs->set_in(0, Location::RequiresRegister());
1512 for (intptr_t i = 0; i < kNumTemps; i++) {
1513 locs->set_temp(i, Location::RequiresRegister());
1514 }
1490 1515
1491 switch (class_id()) { 1516 switch (class_id()) {
1492 case kArrayCid: 1517 case kArrayCid:
1493 locs->set_in(2, ShouldEmitStoreBarrier() 1518 locs->set_in(2, ShouldEmitStoreBarrier()
1494 ? Location::WritableRegister() 1519 ? Location::WritableRegister()
1495 : Location::RegisterOrConstant(value())); 1520 : Location::RegisterOrConstant(value()));
1496 break; 1521 break;
1497 case kExternalTypedDataUint8ArrayCid: 1522 case kExternalTypedDataUint8ArrayCid:
1498 case kExternalTypedDataUint8ClampedArrayCid: 1523 case kExternalTypedDataUint8ClampedArrayCid:
1499 case kTypedDataInt8ArrayCid: 1524 case kTypedDataInt8ArrayCid:
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 if (aligned()) { 1654 if (aligned()) {
1630 __ str(value, element_address); 1655 __ str(value, element_address);
1631 } else { 1656 } else {
1632 __ StoreWordUnaligned(value, temp, temp2); 1657 __ StoreWordUnaligned(value, temp, temp2);
1633 } 1658 }
1634 break; 1659 break;
1635 } 1660 }
1636 case kTypedDataFloat32ArrayCid: { 1661 case kTypedDataFloat32ArrayCid: {
1637 const SRegister value_reg = 1662 const SRegister value_reg =
1638 EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg())); 1663 EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg()));
1639 __ vstrs(value_reg, element_address); 1664 if (aligned()) {
1665 __ vstrs(value_reg, element_address);
1666 } else {
1667 const Register address = temp;
1668 const Register value = temp2;
1669 __ vmovrs(value, value_reg);
1670 __ StoreWordUnaligned(value, address, TMP);
1671 }
1640 break; 1672 break;
1641 } 1673 }
1642 case kTypedDataFloat64ArrayCid: { 1674 case kTypedDataFloat64ArrayCid: {
1643 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg()); 1675 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg());
1644 __ vstrd(value_reg, element_address); 1676 if (aligned()) {
1677 __ vstrd(value_reg, element_address);
1678 } else {
1679 const Register address = temp;
1680 const Register value = temp2;
1681 __ vmovrs(value, EvenSRegisterOf(value_reg));
1682 __ StoreWordUnaligned(value, address, TMP);
1683 __ AddImmediate(address, address, 4);
1684 __ vmovrs(value, OddSRegisterOf(value_reg));
1685 __ StoreWordUnaligned(value, address, TMP);
1686 }
1645 break; 1687 break;
1646 } 1688 }
1647 case kTypedDataFloat64x2ArrayCid: 1689 case kTypedDataFloat64x2ArrayCid:
1648 case kTypedDataInt32x4ArrayCid: 1690 case kTypedDataInt32x4ArrayCid:
1649 case kTypedDataFloat32x4ArrayCid: { 1691 case kTypedDataFloat32x4ArrayCid: {
1650 ASSERT(element_address.Equals(Address(index.reg()))); 1692 ASSERT(element_address.Equals(Address(index.reg())));
1693 ASSERT(aligned());
1651 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg()); 1694 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg());
1652 __ vstmd(IA, index.reg(), value_reg, 2); 1695 __ vstmd(IA, index.reg(), value_reg, 2);
1653 break; 1696 break;
1654 } 1697 }
1655 default: 1698 default:
1656 UNREACHABLE(); 1699 UNREACHABLE();
1657 } 1700 }
1658 } 1701 }
1659 1702
1660 1703
(...skipping 5598 matching lines...) Expand 10 before | Expand all | Expand 10 after
7259 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), 7302 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(),
7260 kGrowRegExpStackRuntimeEntry, 1, locs()); 7303 kGrowRegExpStackRuntimeEntry, 1, locs());
7261 __ Drop(1); 7304 __ Drop(1);
7262 __ Pop(result); 7305 __ Pop(result);
7263 } 7306 }
7264 7307
7265 7308
7266 } // namespace dart 7309 } // namespace dart
7267 7310
7268 #endif // defined TARGET_ARCH_ARM 7311 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698