| OLD | NEW |
| 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" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1437 intptr_t index) const { | 1437 intptr_t index) const { |
| 1438 const int64_t offset = index * index_scale + | 1438 const int64_t offset = index * index_scale + |
| 1439 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); | 1439 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); |
| 1440 ASSERT(Utils::IsInt(32, offset)); | 1440 ASSERT(Utils::IsInt(32, offset)); |
| 1441 const OperandSize size = Address::OperandSizeFor(cid); | 1441 const OperandSize size = Address::OperandSizeFor(cid); |
| 1442 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1442 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
| 1443 return Address(array, static_cast<int32_t>(offset), Address::Offset, size); | 1443 return Address(array, static_cast<int32_t>(offset), Address::Offset, size); |
| 1444 } | 1444 } |
| 1445 | 1445 |
| 1446 | 1446 |
| 1447 void Assembler::LoadElementAddressForIntIndex(Register address, |
| 1448 bool is_external, |
| 1449 intptr_t cid, |
| 1450 intptr_t index_scale, |
| 1451 Register array, |
| 1452 intptr_t index) { |
| 1453 const int64_t offset = index * index_scale + |
| 1454 (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); |
| 1455 AddImmediate(address, array, offset); |
| 1456 } |
| 1457 |
| 1458 |
| 1447 Address Assembler::ElementAddressForRegIndex(bool is_load, | 1459 Address Assembler::ElementAddressForRegIndex(bool is_load, |
| 1448 bool is_external, | 1460 bool is_external, |
| 1449 intptr_t cid, | 1461 intptr_t cid, |
| 1450 intptr_t index_scale, | 1462 intptr_t index_scale, |
| 1451 Register array, | 1463 Register array, |
| 1452 Register index) { | 1464 Register index) { |
| 1453 // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays. | 1465 // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays. |
| 1454 const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift; | 1466 const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift; |
| 1455 const int32_t offset = | 1467 const int32_t offset = |
| 1456 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); | 1468 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); |
| 1457 ASSERT(array != TMP); | 1469 ASSERT(array != TMP); |
| 1458 ASSERT(index != TMP); | 1470 ASSERT(index != TMP); |
| 1459 const Register base = is_load ? TMP : index; | 1471 const Register base = is_load ? TMP : index; |
| 1460 if ((offset == 0) && (shift == 0)) { | 1472 if ((offset == 0) && (shift == 0)) { |
| 1461 return Address(array, index, UXTX, Address::Unscaled); | 1473 return Address(array, index, UXTX, Address::Unscaled); |
| 1462 } else if (shift < 0) { | 1474 } else if (shift < 0) { |
| 1463 ASSERT(shift == -1); | 1475 ASSERT(shift == -1); |
| 1464 add(base, array, Operand(index, ASR, 1)); | 1476 add(base, array, Operand(index, ASR, 1)); |
| 1465 } else { | 1477 } else { |
| 1466 add(base, array, Operand(index, LSL, shift)); | 1478 add(base, array, Operand(index, LSL, shift)); |
| 1467 } | 1479 } |
| 1468 const OperandSize size = Address::OperandSizeFor(cid); | 1480 const OperandSize size = Address::OperandSizeFor(cid); |
| 1469 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1481 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
| 1470 return Address(base, offset, Address::Offset, size); | 1482 return Address(base, offset, Address::Offset, size); |
| 1471 } | 1483 } |
| 1472 | 1484 |
| 1485 |
| 1486 void Assembler::LoadElementAddressForRegIndex(Register address, |
| 1487 bool is_load, |
| 1488 bool is_external, |
| 1489 intptr_t cid, |
| 1490 intptr_t index_scale, |
| 1491 Register array, |
| 1492 Register index) { |
| 1493 // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays. |
| 1494 const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift; |
| 1495 const int32_t offset = |
| 1496 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); |
| 1497 if (shift == 0) { |
| 1498 add(address, array, Operand(index)); |
| 1499 } else if (shift < 0) { |
| 1500 ASSERT(shift == -1); |
| 1501 add(address, array, Operand(index, ASR, 1)); |
| 1502 } else { |
| 1503 add(address, array, Operand(index, LSL, shift)); |
| 1504 } |
| 1505 if (offset != 0) { |
| 1506 AddImmediate(address, address, offset); |
| 1507 } |
| 1508 } |
| 1509 |
| 1510 |
| 1511 void Assembler::LoadUnaligned(Register dst, Register addr, Register tmp, |
| 1512 OperandSize sz) { |
| 1513 ASSERT(dst != addr); |
| 1514 ldr(dst, Address(addr, 0), kUnsignedByte); |
| 1515 if (sz == kHalfword) { |
| 1516 ldr(tmp, Address(addr, 1), kByte); |
| 1517 orr(dst, dst, Operand(tmp, LSL, 8)); |
| 1518 return; |
| 1519 } |
| 1520 ldr(tmp, Address(addr, 1), kUnsignedByte); |
| 1521 orr(dst, dst, Operand(tmp, LSL, 8)); |
| 1522 if (sz == kUnsignedHalfword) { |
| 1523 return; |
| 1524 } |
| 1525 ldr(tmp, Address(addr, 2), kUnsignedByte); |
| 1526 orr(dst, dst, Operand(tmp, LSL, 16)); |
| 1527 if (sz == kWord) { |
| 1528 ldr(tmp, Address(addr, 3), kByte); |
| 1529 orr(dst, dst, Operand(tmp, LSL, 24)); |
| 1530 return; |
| 1531 } |
| 1532 ldr(tmp, Address(addr, 3), kUnsignedByte); |
| 1533 orr(dst, dst, Operand(tmp, LSL, 24)); |
| 1534 if (sz == kUnsignedWord) { |
| 1535 return; |
| 1536 } |
| 1537 ldr(tmp, Address(addr, 4), kUnsignedByte); |
| 1538 orr(dst, dst, Operand(tmp, LSL, 32)); |
| 1539 ldr(tmp, Address(addr, 5), kUnsignedByte); |
| 1540 orr(dst, dst, Operand(tmp, LSL, 40)); |
| 1541 ldr(tmp, Address(addr, 6), kUnsignedByte); |
| 1542 orr(dst, dst, Operand(tmp, LSL, 48)); |
| 1543 ldr(tmp, Address(addr, 7), kUnsignedByte); |
| 1544 orr(dst, dst, Operand(tmp, LSL, 56)); |
| 1545 if (sz == kDoubleWord) { |
| 1546 return; |
| 1547 } |
| 1548 UNIMPLEMENTED(); |
| 1549 } |
| 1550 |
| 1551 |
| 1552 void Assembler::StoreUnaligned(Register src, Register addr, Register tmp, |
| 1553 OperandSize sz) { |
| 1554 str(src, Address(addr, 0), kUnsignedByte); |
| 1555 LsrImmediate(tmp, src, 8); |
| 1556 str(tmp, Address(addr, 1), kUnsignedByte); |
| 1557 if ((sz == kHalfword) || (sz == kUnsignedHalfword)) { |
| 1558 return; |
| 1559 } |
| 1560 LsrImmediate(tmp, src, 16); |
| 1561 str(tmp, Address(addr, 2), kUnsignedByte); |
| 1562 LsrImmediate(tmp, src, 24); |
| 1563 str(tmp, Address(addr, 3), kUnsignedByte); |
| 1564 if ((sz == kWord) || (sz == kUnsignedWord)) { |
| 1565 return; |
| 1566 } |
| 1567 LsrImmediate(tmp, src, 24); |
| 1568 str(tmp, Address(addr, 4), kUnsignedByte); |
| 1569 LsrImmediate(tmp, src, 32); |
| 1570 str(tmp, Address(addr, 5), kUnsignedByte); |
| 1571 LsrImmediate(tmp, src, 40); |
| 1572 str(tmp, Address(addr, 6), kUnsignedByte); |
| 1573 LsrImmediate(tmp, src, 48); |
| 1574 str(tmp, Address(addr, 7), kUnsignedByte); |
| 1575 if (sz == kDoubleWord) { |
| 1576 return; |
| 1577 } |
| 1578 UNIMPLEMENTED(); |
| 1579 } |
| 1580 |
| 1473 } // namespace dart | 1581 } // namespace dart |
| 1474 | 1582 |
| 1475 #endif // defined TARGET_ARCH_ARM64 | 1583 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |