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

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

Issue 2940883008: [arm, arm64] Implemented unaligned scalar float access. (Closed)
Patch Set: . 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 += 2;
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 locs->set_temp(2, Location::RequiresRegister());
1287 }
1279 } 1288 }
1280 return locs; 1289 return locs;
1281 } 1290 }
1282 1291
1283 1292
1284 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1293 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1285 // The array register points to the backing store for external arrays. 1294 // The array register points to the backing store for external arrays.
1286 const Register array = locs()->in(0).reg(); 1295 const Register array = locs()->in(0).reg();
1287 const Location index = locs()->in(1); 1296 const Location index = locs()->in(1);
1288 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg(); 1297 const Register address = aligned() ? kNoRegister : locs()->temp(0).reg();
(...skipping 29 matching lines...) Expand all
1318 if ((representation() == kUnboxedDouble) || 1327 if ((representation() == kUnboxedDouble) ||
1319 (representation() == kUnboxedFloat32x4) || 1328 (representation() == kUnboxedFloat32x4) ||
1320 (representation() == kUnboxedInt32x4) || 1329 (representation() == kUnboxedInt32x4) ||
1321 (representation() == kUnboxedFloat64x2)) { 1330 (representation() == kUnboxedFloat64x2)) {
1322 const QRegister result = locs()->out(0).fpu_reg(); 1331 const QRegister result = locs()->out(0).fpu_reg();
1323 const DRegister dresult0 = EvenDRegisterOf(result); 1332 const DRegister dresult0 = EvenDRegisterOf(result);
1324 switch (class_id()) { 1333 switch (class_id()) {
1325 case kTypedDataFloat32ArrayCid: 1334 case kTypedDataFloat32ArrayCid:
1326 // Load single precision float. 1335 // Load single precision float.
1327 // vldrs does not support indexed addressing. 1336 // vldrs does not support indexed addressing.
1328 __ vldrs(EvenSRegisterOf(dresult0), element_address); 1337 if (aligned()) {
1338 __ vldrs(EvenSRegisterOf(dresult0), element_address);
1339 } else {
1340 const Register value = locs()->temp(1).reg();
1341 __ LoadWordUnaligned(value, address, TMP);
1342 __ vmovsr(EvenSRegisterOf(dresult0), value);
1343 }
1329 break; 1344 break;
1330 case kTypedDataFloat64ArrayCid: 1345 case kTypedDataFloat64ArrayCid:
1331 // vldrd does not support indexed addressing. 1346 // vldrd does not support indexed addressing.
1332 __ vldrd(dresult0, element_address); 1347 if (aligned()) {
1348 __ vldrd(dresult0, element_address);
1349 } else {
1350 const Register value1 = locs()->temp(1).reg();
zra 2017/06/19 15:02:48 You can save a temporary register here by using vm
rmacnak 2017/06/19 17:18:32 Done.
1351 const Register value2 = locs()->temp(2).reg();
1352 __ LoadWordUnaligned(value1, address, TMP);
1353 __ AddImmediate(address, address, 4);
1354 __ LoadWordUnaligned(value2, address, TMP);
1355 __ vmovdrr(dresult0, value1, value2);
1356 }
1333 break; 1357 break;
1334 case kTypedDataFloat64x2ArrayCid: 1358 case kTypedDataFloat64x2ArrayCid:
1335 case kTypedDataInt32x4ArrayCid: 1359 case kTypedDataInt32x4ArrayCid:
1336 case kTypedDataFloat32x4ArrayCid: 1360 case kTypedDataFloat32x4ArrayCid:
1337 ASSERT(element_address.Equals(Address(IP))); 1361 ASSERT(element_address.Equals(Address(IP)));
1362 ASSERT(aligned());
1338 __ vldmd(IA, IP, dresult0, 2); 1363 __ vldmd(IA, IP, dresult0, 2);
1339 break; 1364 break;
1340 default: 1365 default:
1341 UNREACHABLE(); 1366 UNREACHABLE();
1342 } 1367 }
1343 return; 1368 return;
1344 } 1369 }
1345 1370
1346 if ((representation() == kUnboxedUint32) || 1371 if ((representation() == kUnboxedUint32) ||
1347 (representation() == kUnboxedInt32)) { 1372 (representation() == kUnboxedInt32)) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 } 1477 }
1453 } 1478 }
1454 1479
1455 1480
1456 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone, 1481 LocationSummary* StoreIndexedInstr::MakeLocationSummary(Zone* zone,
1457 bool opt) const { 1482 bool opt) const {
1458 const intptr_t kNumInputs = 3; 1483 const intptr_t kNumInputs = 3;
1459 LocationSummary* locs; 1484 LocationSummary* locs;
1460 1485
1461 bool needs_base = false; 1486 bool needs_base = false;
1487 intptr_t kNumTemps = 0;
1462 if (CanBeImmediateIndex(index(), class_id(), IsExternal(), 1488 if (CanBeImmediateIndex(index(), class_id(), IsExternal(),
1463 false, // Store. 1489 false, // Store.
1464 &needs_base)) { 1490 &needs_base)) {
1465 const intptr_t kNumTemps = aligned() ? (needs_base ? 1 : 0) : 2; 1491 if (!aligned()) {
1492 kNumTemps += 2;
1493 if (class_id() == kTypedDataFloat64ArrayCid) {
1494 kNumTemps += 1;
1495 }
1496 } else if (needs_base) {
1497 kNumTemps += 1;
1498 }
1499
1466 locs = new (zone) 1500 locs = new (zone)
1467 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1501 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1468 1502
1469 // CanBeImmediateIndex must return false for unsafe smis. 1503 // CanBeImmediateIndex must return false for unsafe smis.
1470 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); 1504 locs->set_in(1, Location::Constant(index()->definition()->AsConstant()));
1471 if (needs_base) { 1505 } else {
1472 locs->set_temp(0, Location::RequiresRegister()); 1506 if (!aligned()) {
1507 kNumTemps += 2;
1508 if (class_id() == kTypedDataFloat64ArrayCid) {
1509 kNumTemps += 1;
1510 }
1473 } 1511 }
1474 if (!aligned()) { 1512
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) 1513 locs = new (zone)
1481 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 1514 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1482 1515
1483 locs->set_in(1, Location::WritableRegister()); 1516 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 } 1517 }
1489 locs->set_in(0, Location::RequiresRegister()); 1518 locs->set_in(0, Location::RequiresRegister());
1519 for (intptr_t i = 0; i < kNumTemps; i++) {
1520 locs->set_temp(i, Location::RequiresRegister());
1521 }
1490 1522
1491 switch (class_id()) { 1523 switch (class_id()) {
1492 case kArrayCid: 1524 case kArrayCid:
1493 locs->set_in(2, ShouldEmitStoreBarrier() 1525 locs->set_in(2, ShouldEmitStoreBarrier()
1494 ? Location::WritableRegister() 1526 ? Location::WritableRegister()
1495 : Location::RegisterOrConstant(value())); 1527 : Location::RegisterOrConstant(value()));
1496 break; 1528 break;
1497 case kExternalTypedDataUint8ArrayCid: 1529 case kExternalTypedDataUint8ArrayCid:
1498 case kExternalTypedDataUint8ClampedArrayCid: 1530 case kExternalTypedDataUint8ClampedArrayCid:
1499 case kTypedDataInt8ArrayCid: 1531 case kTypedDataInt8ArrayCid:
(...skipping 25 matching lines...) Expand all
1525 1557
1526 1558
1527 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1559 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1528 // The array register points to the backing store for external arrays. 1560 // The array register points to the backing store for external arrays.
1529 const Register array = locs()->in(0).reg(); 1561 const Register array = locs()->in(0).reg();
1530 const Location index = locs()->in(1); 1562 const Location index = locs()->in(1);
1531 const Register temp = 1563 const Register temp =
1532 (locs()->temp_count() > 0) ? locs()->temp(0).reg() : kNoRegister; 1564 (locs()->temp_count() > 0) ? locs()->temp(0).reg() : kNoRegister;
1533 const Register temp2 = 1565 const Register temp2 =
1534 (locs()->temp_count() > 1) ? locs()->temp(1).reg() : kNoRegister; 1566 (locs()->temp_count() > 1) ? locs()->temp(1).reg() : kNoRegister;
1567 const Register temp3 =
1568 (locs()->temp_count() > 2) ? locs()->temp(2).reg() : kNoRegister;
1535 1569
1536 Address element_address(kNoRegister); 1570 Address element_address(kNoRegister);
1537 if (aligned()) { 1571 if (aligned()) {
1538 element_address = index.IsRegister() 1572 element_address = index.IsRegister()
1539 ? __ ElementAddressForRegIndex( 1573 ? __ ElementAddressForRegIndex(
1540 false, // Store. 1574 false, // Store.
1541 IsExternal(), class_id(), index_scale(), array, 1575 IsExternal(), class_id(), index_scale(), array,
1542 index.reg()) 1576 index.reg())
1543 : __ ElementAddressForIntIndex( 1577 : __ ElementAddressForIntIndex(
1544 false, // Store. 1578 false, // Store.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 if (aligned()) { 1663 if (aligned()) {
1630 __ str(value, element_address); 1664 __ str(value, element_address);
1631 } else { 1665 } else {
1632 __ StoreWordUnaligned(value, temp, temp2); 1666 __ StoreWordUnaligned(value, temp, temp2);
1633 } 1667 }
1634 break; 1668 break;
1635 } 1669 }
1636 case kTypedDataFloat32ArrayCid: { 1670 case kTypedDataFloat32ArrayCid: {
1637 const SRegister value_reg = 1671 const SRegister value_reg =
1638 EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg())); 1672 EvenSRegisterOf(EvenDRegisterOf(locs()->in(2).fpu_reg()));
1639 __ vstrs(value_reg, element_address); 1673 if (aligned()) {
1674 __ vstrs(value_reg, element_address);
1675 } else {
1676 const Register& address = temp;
zra 2017/06/19 15:02:48 Is & needed?
rmacnak 2017/06/19 17:18:32 No, removed.
1677 const Register& value = temp2;
1678 __ vmovrs(value, value_reg);
1679 __ StoreWordUnaligned(value, address, TMP);
1680 }
1640 break; 1681 break;
1641 } 1682 }
1642 case kTypedDataFloat64ArrayCid: { 1683 case kTypedDataFloat64ArrayCid: {
1643 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg()); 1684 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg());
1644 __ vstrd(value_reg, element_address); 1685 if (aligned()) {
1686 __ vstrd(value_reg, element_address);
1687 } else {
1688 const Register& address = temp;
1689 const Register& value1 = temp2;
1690 const Register& value2 = temp3;
1691 __ vmovrrd(value1, value2, value_reg);
zra 2017/06/19 15:02:48 Same idea here for saving a temporary by using vmo
1692 __ StoreWordUnaligned(value1, address, TMP);
1693 __ AddImmediate(address, address, 4);
1694 __ StoreWordUnaligned(value2, address, TMP);
1695 }
1645 break; 1696 break;
1646 } 1697 }
1647 case kTypedDataFloat64x2ArrayCid: 1698 case kTypedDataFloat64x2ArrayCid:
1648 case kTypedDataInt32x4ArrayCid: 1699 case kTypedDataInt32x4ArrayCid:
1649 case kTypedDataFloat32x4ArrayCid: { 1700 case kTypedDataFloat32x4ArrayCid: {
1650 ASSERT(element_address.Equals(Address(index.reg()))); 1701 ASSERT(element_address.Equals(Address(index.reg())));
1702 ASSERT(aligned());
1651 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg()); 1703 const DRegister value_reg = EvenDRegisterOf(locs()->in(2).fpu_reg());
1652 __ vstmd(IA, index.reg(), value_reg, 2); 1704 __ vstmd(IA, index.reg(), value_reg, 2);
1653 break; 1705 break;
1654 } 1706 }
1655 default: 1707 default:
1656 UNREACHABLE(); 1708 UNREACHABLE();
1657 } 1709 }
1658 } 1710 }
1659 1711
1660 1712
(...skipping 5598 matching lines...) Expand 10 before | Expand all | Expand 10 after
7259 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), 7311 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(),
7260 kGrowRegExpStackRuntimeEntry, 1, locs()); 7312 kGrowRegExpStackRuntimeEntry, 1, locs());
7261 __ Drop(1); 7313 __ Drop(1);
7262 __ Pop(result); 7314 __ Pop(result);
7263 } 7315 }
7264 7316
7265 7317
7266 } // namespace dart 7318 } // namespace dart
7267 7319
7268 #endif // defined TARGET_ARCH_ARM 7320 #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