| OLD | NEW |
| 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/simulator.h" | 9 #include "vm/simulator.h" |
| 10 #include "vm/runtime_entry.h" | 10 #include "vm/runtime_entry.h" |
| (...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 if (object.IsNull() || | 1239 if (object.IsNull() || |
| 1240 object.IsSmi() || | 1240 object.IsSmi() || |
| 1241 (object.raw() == Bool::True().raw()) || | 1241 (object.raw() == Bool::True().raw()) || |
| 1242 (object.raw() == Bool::False().raw())) { | 1242 (object.raw() == Bool::False().raw())) { |
| 1243 // This object is never relocated; do not use object pool. | 1243 // This object is never relocated; do not use object pool. |
| 1244 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); | 1244 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); |
| 1245 return; | 1245 return; |
| 1246 } | 1246 } |
| 1247 const int32_t offset = | 1247 const int32_t offset = |
| 1248 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; | 1248 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; |
| 1249 int32_t offset_mask; | 1249 int32_t offset_mask = 0; |
| 1250 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) { | 1250 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) { |
| 1251 ldr(rd, Address(PP, offset)); | 1251 ldr(rd, Address(PP, offset)); |
| 1252 } else { | 1252 } else { |
| 1253 int32_t offset_hi = offset & ~offset_mask; // signed | 1253 int32_t offset_hi = offset & ~offset_mask; // signed |
| 1254 uint32_t offset_lo = offset & offset_mask; // unsigned | 1254 uint32_t offset_lo = offset & offset_mask; // unsigned |
| 1255 AddImmediate(rd, PP, offset_hi); | 1255 AddImmediate(rd, PP, offset_hi); |
| 1256 ldr(rd, Address(rd, offset_lo)); | 1256 ldr(rd, Address(rd, offset_lo)); |
| 1257 } | 1257 } |
| 1258 } | 1258 } |
| 1259 | 1259 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 } | 1402 } |
| 1403 | 1403 |
| 1404 | 1404 |
| 1405 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { | 1405 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { |
| 1406 // Make sure that class CallPattern is able to patch the label referred | 1406 // Make sure that class CallPattern is able to patch the label referred |
| 1407 // to by this code sequence. | 1407 // to by this code sequence. |
| 1408 // For added code robustness, use 'blx lr' in a patchable sequence and | 1408 // For added code robustness, use 'blx lr' in a patchable sequence and |
| 1409 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). | 1409 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). |
| 1410 const int32_t offset = | 1410 const int32_t offset = |
| 1411 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; | 1411 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; |
| 1412 int32_t offset_mask; | 1412 int32_t offset_mask = 0; |
| 1413 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) { | 1413 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) { |
| 1414 ldr(LR, Address(PP, offset)); | 1414 ldr(LR, Address(PP, offset)); |
| 1415 } else { | 1415 } else { |
| 1416 int32_t offset_hi = offset & ~offset_mask; // signed | 1416 int32_t offset_hi = offset & ~offset_mask; // signed |
| 1417 uint32_t offset_lo = offset & offset_mask; // unsigned | 1417 uint32_t offset_lo = offset & offset_mask; // unsigned |
| 1418 // Inline a simplified version of AddImmediate(LR, CP, offset_hi). | 1418 // Inline a simplified version of AddImmediate(LR, CP, offset_hi). |
| 1419 ShifterOperand shifter_op; | 1419 ShifterOperand shifter_op; |
| 1420 if (ShifterOperand::CanHold(offset_hi, &shifter_op)) { | 1420 if (ShifterOperand::CanHold(offset_hi, &shifter_op)) { |
| 1421 add(LR, PP, shifter_op); | 1421 add(LR, PP, shifter_op); |
| 1422 } else { | 1422 } else { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1437 // TODO(regis): Revisit this code sequence. | 1437 // TODO(regis): Revisit this code sequence. |
| 1438 LoadImmediate(IP, label->address()); // Target address is never patched. | 1438 LoadImmediate(IP, label->address()); // Target address is never patched. |
| 1439 str(PC, ad); | 1439 str(PC, ad); |
| 1440 blx(IP); // Use blx instruction so that the return branch prediction works. | 1440 blx(IP); // Use blx instruction so that the return branch prediction works. |
| 1441 } | 1441 } |
| 1442 | 1442 |
| 1443 | 1443 |
| 1444 void Assembler::BranchLinkOffset(Register base, int offset) { | 1444 void Assembler::BranchLinkOffset(Register base, int offset) { |
| 1445 ASSERT(base != PC); | 1445 ASSERT(base != PC); |
| 1446 ASSERT(base != IP); | 1446 ASSERT(base != IP); |
| 1447 int32_t offset_mask; | 1447 int32_t offset_mask = 0; |
| 1448 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) { | 1448 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) { |
| 1449 ldr(IP, Address(base, offset)); | 1449 ldr(IP, Address(base, offset)); |
| 1450 } else { | 1450 } else { |
| 1451 int offset_hi = offset & ~offset_mask; | 1451 int offset_hi = offset & ~offset_mask; |
| 1452 int offset_lo = offset & offset_mask; | 1452 int offset_lo = offset & offset_mask; |
| 1453 ShifterOperand offset_hi_op; | 1453 ShifterOperand offset_hi_op; |
| 1454 if (ShifterOperand::CanHold(offset_hi, &offset_hi_op)) { | 1454 if (ShifterOperand::CanHold(offset_hi, &offset_hi_op)) { |
| 1455 add(IP, base, offset_hi_op); | 1455 add(IP, base, offset_hi_op); |
| 1456 ldr(IP, Address(IP, offset_lo)); | 1456 ldr(IP, Address(IP, offset_lo)); |
| 1457 } else { | 1457 } else { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 vmovdrr(dd, IP, scratch, cond); | 1504 vmovdrr(dd, IP, scratch, cond); |
| 1505 } | 1505 } |
| 1506 } | 1506 } |
| 1507 | 1507 |
| 1508 | 1508 |
| 1509 void Assembler::LoadFromOffset(LoadOperandType type, | 1509 void Assembler::LoadFromOffset(LoadOperandType type, |
| 1510 Register reg, | 1510 Register reg, |
| 1511 Register base, | 1511 Register base, |
| 1512 int32_t offset, | 1512 int32_t offset, |
| 1513 Condition cond) { | 1513 Condition cond) { |
| 1514 int32_t offset_mask; | 1514 int32_t offset_mask = 0; |
| 1515 if (!Address::CanHoldLoadOffset(type, offset, &offset_mask)) { | 1515 if (!Address::CanHoldLoadOffset(type, offset, &offset_mask)) { |
| 1516 ASSERT(base != IP); | 1516 ASSERT(base != IP); |
| 1517 AddImmediate(IP, base, offset & ~offset_mask, cond); | 1517 AddImmediate(IP, base, offset & ~offset_mask, cond); |
| 1518 base = IP; | 1518 base = IP; |
| 1519 offset = offset & offset_mask; | 1519 offset = offset & offset_mask; |
| 1520 } | 1520 } |
| 1521 switch (type) { | 1521 switch (type) { |
| 1522 case kLoadSignedByte: | 1522 case kLoadSignedByte: |
| 1523 ldrsb(reg, Address(base, offset), cond); | 1523 ldrsb(reg, Address(base, offset), cond); |
| 1524 break; | 1524 break; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1541 UNREACHABLE(); | 1541 UNREACHABLE(); |
| 1542 } | 1542 } |
| 1543 } | 1543 } |
| 1544 | 1544 |
| 1545 | 1545 |
| 1546 void Assembler::StoreToOffset(StoreOperandType type, | 1546 void Assembler::StoreToOffset(StoreOperandType type, |
| 1547 Register reg, | 1547 Register reg, |
| 1548 Register base, | 1548 Register base, |
| 1549 int32_t offset, | 1549 int32_t offset, |
| 1550 Condition cond) { | 1550 Condition cond) { |
| 1551 int32_t offset_mask; | 1551 int32_t offset_mask = 0; |
| 1552 if (!Address::CanHoldStoreOffset(type, offset, &offset_mask)) { | 1552 if (!Address::CanHoldStoreOffset(type, offset, &offset_mask)) { |
| 1553 ASSERT(reg != IP); | 1553 ASSERT(reg != IP); |
| 1554 ASSERT(base != IP); | 1554 ASSERT(base != IP); |
| 1555 AddImmediate(IP, base, offset & ~offset_mask, cond); | 1555 AddImmediate(IP, base, offset & ~offset_mask, cond); |
| 1556 base = IP; | 1556 base = IP; |
| 1557 offset = offset & offset_mask; | 1557 offset = offset & offset_mask; |
| 1558 } | 1558 } |
| 1559 switch (type) { | 1559 switch (type) { |
| 1560 case kStoreByte: | 1560 case kStoreByte: |
| 1561 strb(reg, Address(base, offset), cond); | 1561 strb(reg, Address(base, offset), cond); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1572 default: | 1572 default: |
| 1573 UNREACHABLE(); | 1573 UNREACHABLE(); |
| 1574 } | 1574 } |
| 1575 } | 1575 } |
| 1576 | 1576 |
| 1577 | 1577 |
| 1578 void Assembler::LoadSFromOffset(SRegister reg, | 1578 void Assembler::LoadSFromOffset(SRegister reg, |
| 1579 Register base, | 1579 Register base, |
| 1580 int32_t offset, | 1580 int32_t offset, |
| 1581 Condition cond) { | 1581 Condition cond) { |
| 1582 int32_t offset_mask; | 1582 int32_t offset_mask = 0; |
| 1583 if (!Address::CanHoldLoadOffset(kLoadSWord, offset, &offset_mask)) { | 1583 if (!Address::CanHoldLoadOffset(kLoadSWord, offset, &offset_mask)) { |
| 1584 ASSERT(base != IP); | 1584 ASSERT(base != IP); |
| 1585 AddImmediate(IP, base, offset & ~offset_mask, cond); | 1585 AddImmediate(IP, base, offset & ~offset_mask, cond); |
| 1586 base = IP; | 1586 base = IP; |
| 1587 offset = offset & offset_mask; | 1587 offset = offset & offset_mask; |
| 1588 } | 1588 } |
| 1589 vldrs(reg, Address(base, offset), cond); | 1589 vldrs(reg, Address(base, offset), cond); |
| 1590 } | 1590 } |
| 1591 | 1591 |
| 1592 | 1592 |
| 1593 void Assembler::StoreSToOffset(SRegister reg, | 1593 void Assembler::StoreSToOffset(SRegister reg, |
| 1594 Register base, | 1594 Register base, |
| 1595 int32_t offset, | 1595 int32_t offset, |
| 1596 Condition cond) { | 1596 Condition cond) { |
| 1597 int32_t offset_mask; | 1597 int32_t offset_mask = 0; |
| 1598 if (!Address::CanHoldStoreOffset(kStoreSWord, offset, &offset_mask)) { | 1598 if (!Address::CanHoldStoreOffset(kStoreSWord, offset, &offset_mask)) { |
| 1599 ASSERT(base != IP); | 1599 ASSERT(base != IP); |
| 1600 AddImmediate(IP, base, offset & ~offset_mask, cond); | 1600 AddImmediate(IP, base, offset & ~offset_mask, cond); |
| 1601 base = IP; | 1601 base = IP; |
| 1602 offset = offset & offset_mask; | 1602 offset = offset & offset_mask; |
| 1603 } | 1603 } |
| 1604 vstrs(reg, Address(base, offset), cond); | 1604 vstrs(reg, Address(base, offset), cond); |
| 1605 } | 1605 } |
| 1606 | 1606 |
| 1607 | 1607 |
| 1608 void Assembler::LoadDFromOffset(DRegister reg, | 1608 void Assembler::LoadDFromOffset(DRegister reg, |
| 1609 Register base, | 1609 Register base, |
| 1610 int32_t offset, | 1610 int32_t offset, |
| 1611 Condition cond) { | 1611 Condition cond) { |
| 1612 int32_t offset_mask; | 1612 int32_t offset_mask = 0; |
| 1613 if (!Address::CanHoldLoadOffset(kLoadDWord, offset, &offset_mask)) { | 1613 if (!Address::CanHoldLoadOffset(kLoadDWord, offset, &offset_mask)) { |
| 1614 ASSERT(base != IP); | 1614 ASSERT(base != IP); |
| 1615 AddImmediate(IP, base, offset & ~offset_mask, cond); | 1615 AddImmediate(IP, base, offset & ~offset_mask, cond); |
| 1616 base = IP; | 1616 base = IP; |
| 1617 offset = offset & offset_mask; | 1617 offset = offset & offset_mask; |
| 1618 } | 1618 } |
| 1619 vldrd(reg, Address(base, offset), cond); | 1619 vldrd(reg, Address(base, offset), cond); |
| 1620 } | 1620 } |
| 1621 | 1621 |
| 1622 | 1622 |
| 1623 void Assembler::StoreDToOffset(DRegister reg, | 1623 void Assembler::StoreDToOffset(DRegister reg, |
| 1624 Register base, | 1624 Register base, |
| 1625 int32_t offset, | 1625 int32_t offset, |
| 1626 Condition cond) { | 1626 Condition cond) { |
| 1627 int32_t offset_mask; | 1627 int32_t offset_mask = 0; |
| 1628 if (!Address::CanHoldStoreOffset(kStoreDWord, offset, &offset_mask)) { | 1628 if (!Address::CanHoldStoreOffset(kStoreDWord, offset, &offset_mask)) { |
| 1629 ASSERT(base != IP); | 1629 ASSERT(base != IP); |
| 1630 AddImmediate(IP, base, offset & ~offset_mask, cond); | 1630 AddImmediate(IP, base, offset & ~offset_mask, cond); |
| 1631 base = IP; | 1631 base = IP; |
| 1632 offset = offset & offset_mask; | 1632 offset = offset & offset_mask; |
| 1633 } | 1633 } |
| 1634 vstrd(reg, Address(base, offset), cond); | 1634 vstrd(reg, Address(base, offset), cond); |
| 1635 } | 1635 } |
| 1636 | 1636 |
| 1637 | 1637 |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1946 // Do not reuse an existing entry, since each reference may be patched | 1946 // Do not reuse an existing entry, since each reference may be patched |
| 1947 // independently. | 1947 // independently. |
| 1948 object_pool_.Add(smi); | 1948 object_pool_.Add(smi); |
| 1949 return object_pool_.Length() - 1; | 1949 return object_pool_.Length() - 1; |
| 1950 } | 1950 } |
| 1951 | 1951 |
| 1952 } // namespace dart | 1952 } // namespace dart |
| 1953 | 1953 |
| 1954 #endif // defined TARGET_ARCH_ARM | 1954 #endif // defined TARGET_ARCH_ARM |
| 1955 | 1955 |
| OLD | NEW |