| 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 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 movt(rd, value_high); | 1255 movt(rd, value_high); |
| 1256 } | 1256 } |
| 1257 add(rd, PP, ShifterOperand(LR)); | 1257 add(rd, PP, ShifterOperand(LR)); |
| 1258 } | 1258 } |
| 1259 ldr(rd, Address(rd, offset_lo)); | 1259 ldr(rd, Address(rd, offset_lo)); |
| 1260 } | 1260 } |
| 1261 } | 1261 } |
| 1262 | 1262 |
| 1263 | 1263 |
| 1264 void Assembler::LoadObject(Register rd, const Object& object) { | 1264 void Assembler::LoadObject(Register rd, const Object& object) { |
| 1265 // Since objects in the VM heap are never relocated, test instead | 1265 // Smi's and VM heap objects are never relocated; do not use object pool. |
| 1266 // if (object.IsSmi() || object.InVMHeap()) { | 1266 if (object.IsSmi()) { |
| 1267 // and modify the decoding code in CallPattern to understand movt, movw. | |
| 1268 if (object.IsNull() || | |
| 1269 object.IsSmi() || | |
| 1270 (object.raw() == Bool::True().raw()) || | |
| 1271 (object.raw() == Bool::False().raw())) { | |
| 1272 // This object is never relocated; do not use object pool. | |
| 1273 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); | 1267 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); |
| 1274 return; | 1268 } else if (object.InVMHeap()) { |
| 1269 // Make sure that class CallPattern is able to decode this load immediate. |
| 1270 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); |
| 1271 movw(rd, Utils::Low16Bits(object_raw)); |
| 1272 const uint16_t value_high = Utils::High16Bits(object_raw); |
| 1273 if (value_high != 0) { |
| 1274 movt(rd, value_high); |
| 1275 } |
| 1276 } else { |
| 1277 // Make sure that class CallPattern is able to decode this load from the |
| 1278 // object pool. |
| 1279 const int32_t offset = |
| 1280 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; |
| 1281 LoadWordFromPoolOffset(rd, offset); |
| 1275 } | 1282 } |
| 1276 const int32_t offset = | |
| 1277 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; | |
| 1278 LoadWordFromPoolOffset(rd, offset); | |
| 1279 } | 1283 } |
| 1280 | 1284 |
| 1281 | 1285 |
| 1282 void Assembler::PushObject(const Object& object) { | 1286 void Assembler::PushObject(const Object& object) { |
| 1283 LoadObject(IP, object); | 1287 LoadObject(IP, object); |
| 1284 Push(IP); | 1288 Push(IP); |
| 1285 } | 1289 } |
| 1286 | 1290 |
| 1287 | 1291 |
| 1288 void Assembler::CompareObject(Register rn, const Object& object) { | 1292 void Assembler::CompareObject(Register rn, const Object& object) { |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 | 1480 |
| 1477 | 1481 |
| 1478 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { | 1482 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { |
| 1479 ShifterOperand shifter_op; | 1483 ShifterOperand shifter_op; |
| 1480 if (ShifterOperand::CanHold(value, &shifter_op)) { | 1484 if (ShifterOperand::CanHold(value, &shifter_op)) { |
| 1481 mov(rd, shifter_op, cond); | 1485 mov(rd, shifter_op, cond); |
| 1482 } else if (ShifterOperand::CanHold(~value, &shifter_op)) { | 1486 } else if (ShifterOperand::CanHold(~value, &shifter_op)) { |
| 1483 mvn(rd, shifter_op, cond); | 1487 mvn(rd, shifter_op, cond); |
| 1484 } else { | 1488 } else { |
| 1485 movw(rd, Utils::Low16Bits(value), cond); | 1489 movw(rd, Utils::Low16Bits(value), cond); |
| 1486 uint16_t value_high = Utils::High16Bits(value); | 1490 const uint16_t value_high = Utils::High16Bits(value); |
| 1487 if (value_high != 0) { | 1491 if (value_high != 0) { |
| 1488 movt(rd, value_high, cond); | 1492 movt(rd, value_high, cond); |
| 1489 } | 1493 } |
| 1490 } | 1494 } |
| 1491 } | 1495 } |
| 1492 | 1496 |
| 1493 | 1497 |
| 1494 void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) { | 1498 void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) { |
| 1495 if (!vmovs(sd, value, cond)) { | 1499 if (!vmovs(sd, value, cond)) { |
| 1496 LoadImmediate(IP, bit_cast<int32_t, float>(value), cond); | 1500 LoadImmediate(IP, bit_cast<int32_t, float>(value), cond); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1670 } else { | 1674 } else { |
| 1671 ASSERT(rn != IP); | 1675 ASSERT(rn != IP); |
| 1672 if (ShifterOperand::CanHold(~value, &shifter_op)) { | 1676 if (ShifterOperand::CanHold(~value, &shifter_op)) { |
| 1673 mvn(IP, shifter_op, cond); | 1677 mvn(IP, shifter_op, cond); |
| 1674 add(rd, rn, ShifterOperand(IP), cond); | 1678 add(rd, rn, ShifterOperand(IP), cond); |
| 1675 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { | 1679 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { |
| 1676 mvn(IP, shifter_op, cond); | 1680 mvn(IP, shifter_op, cond); |
| 1677 sub(rd, rn, ShifterOperand(IP), cond); | 1681 sub(rd, rn, ShifterOperand(IP), cond); |
| 1678 } else { | 1682 } else { |
| 1679 movw(IP, Utils::Low16Bits(value), cond); | 1683 movw(IP, Utils::Low16Bits(value), cond); |
| 1680 uint16_t value_high = Utils::High16Bits(value); | 1684 const uint16_t value_high = Utils::High16Bits(value); |
| 1681 if (value_high != 0) { | 1685 if (value_high != 0) { |
| 1682 movt(IP, value_high, cond); | 1686 movt(IP, value_high, cond); |
| 1683 } | 1687 } |
| 1684 add(rd, rn, ShifterOperand(IP), cond); | 1688 add(rd, rn, ShifterOperand(IP), cond); |
| 1685 } | 1689 } |
| 1686 } | 1690 } |
| 1687 } | 1691 } |
| 1688 | 1692 |
| 1689 | 1693 |
| 1690 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, | 1694 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, |
| 1691 Condition cond) { | 1695 Condition cond) { |
| 1692 ShifterOperand shifter_op; | 1696 ShifterOperand shifter_op; |
| 1693 if (ShifterOperand::CanHold(value, &shifter_op)) { | 1697 if (ShifterOperand::CanHold(value, &shifter_op)) { |
| 1694 adds(rd, rn, shifter_op, cond); | 1698 adds(rd, rn, shifter_op, cond); |
| 1695 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { | 1699 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { |
| 1696 subs(rd, rn, shifter_op, cond); | 1700 subs(rd, rn, shifter_op, cond); |
| 1697 } else { | 1701 } else { |
| 1698 ASSERT(rn != IP); | 1702 ASSERT(rn != IP); |
| 1699 if (ShifterOperand::CanHold(~value, &shifter_op)) { | 1703 if (ShifterOperand::CanHold(~value, &shifter_op)) { |
| 1700 mvn(IP, shifter_op, cond); | 1704 mvn(IP, shifter_op, cond); |
| 1701 adds(rd, rn, ShifterOperand(IP), cond); | 1705 adds(rd, rn, ShifterOperand(IP), cond); |
| 1702 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { | 1706 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { |
| 1703 mvn(IP, shifter_op, cond); | 1707 mvn(IP, shifter_op, cond); |
| 1704 subs(rd, rn, ShifterOperand(IP), cond); | 1708 subs(rd, rn, ShifterOperand(IP), cond); |
| 1705 } else { | 1709 } else { |
| 1706 movw(IP, Utils::Low16Bits(value), cond); | 1710 movw(IP, Utils::Low16Bits(value), cond); |
| 1707 uint16_t value_high = Utils::High16Bits(value); | 1711 const uint16_t value_high = Utils::High16Bits(value); |
| 1708 if (value_high != 0) { | 1712 if (value_high != 0) { |
| 1709 movt(IP, value_high, cond); | 1713 movt(IP, value_high, cond); |
| 1710 } | 1714 } |
| 1711 adds(rd, rn, ShifterOperand(IP), cond); | 1715 adds(rd, rn, ShifterOperand(IP), cond); |
| 1712 } | 1716 } |
| 1713 } | 1717 } |
| 1714 } | 1718 } |
| 1715 | 1719 |
| 1716 | 1720 |
| 1717 void Assembler::AddImmediateWithCarry(Register rd, Register rn, int32_t value, | 1721 void Assembler::AddImmediateWithCarry(Register rd, Register rn, int32_t value, |
| 1718 Condition cond) { | 1722 Condition cond) { |
| 1719 ShifterOperand shifter_op; | 1723 ShifterOperand shifter_op; |
| 1720 if (ShifterOperand::CanHold(value, &shifter_op)) { | 1724 if (ShifterOperand::CanHold(value, &shifter_op)) { |
| 1721 adc(rd, rn, shifter_op, cond); | 1725 adc(rd, rn, shifter_op, cond); |
| 1722 } else if (ShifterOperand::CanHold(-value - 1, &shifter_op)) { | 1726 } else if (ShifterOperand::CanHold(-value - 1, &shifter_op)) { |
| 1723 sbc(rd, rn, shifter_op, cond); | 1727 sbc(rd, rn, shifter_op, cond); |
| 1724 } else { | 1728 } else { |
| 1725 ASSERT(rn != IP); | 1729 ASSERT(rn != IP); |
| 1726 if (ShifterOperand::CanHold(~value, &shifter_op)) { | 1730 if (ShifterOperand::CanHold(~value, &shifter_op)) { |
| 1727 mvn(IP, shifter_op, cond); | 1731 mvn(IP, shifter_op, cond); |
| 1728 adc(rd, rn, ShifterOperand(IP), cond); | 1732 adc(rd, rn, ShifterOperand(IP), cond); |
| 1729 } else if (ShifterOperand::CanHold(~(-value - 1), &shifter_op)) { | 1733 } else if (ShifterOperand::CanHold(~(-value - 1), &shifter_op)) { |
| 1730 mvn(IP, shifter_op, cond); | 1734 mvn(IP, shifter_op, cond); |
| 1731 sbc(rd, rn, ShifterOperand(IP), cond); | 1735 sbc(rd, rn, ShifterOperand(IP), cond); |
| 1732 } else { | 1736 } else { |
| 1733 movw(IP, Utils::Low16Bits(value), cond); | 1737 movw(IP, Utils::Low16Bits(value), cond); |
| 1734 uint16_t value_high = Utils::High16Bits(value); | 1738 const uint16_t value_high = Utils::High16Bits(value); |
| 1735 if (value_high != 0) { | 1739 if (value_high != 0) { |
| 1736 movt(IP, value_high, cond); | 1740 movt(IP, value_high, cond); |
| 1737 } | 1741 } |
| 1738 adc(rd, rn, ShifterOperand(IP), cond); | 1742 adc(rd, rn, ShifterOperand(IP), cond); |
| 1739 } | 1743 } |
| 1740 } | 1744 } |
| 1741 } | 1745 } |
| 1742 | 1746 |
| 1743 | 1747 |
| 1744 void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) { | 1748 void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1927 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); | 1931 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); |
| 1928 } | 1932 } |
| 1929 | 1933 |
| 1930 | 1934 |
| 1931 int32_t Assembler::AddObject(const Object& obj) { | 1935 int32_t Assembler::AddObject(const Object& obj) { |
| 1932 ASSERT(obj.IsNotTemporaryScopedHandle()); | 1936 ASSERT(obj.IsNotTemporaryScopedHandle()); |
| 1933 ASSERT(obj.IsOld()); | 1937 ASSERT(obj.IsOld()); |
| 1934 if (object_pool_.IsNull()) { | 1938 if (object_pool_.IsNull()) { |
| 1935 // The object pool cannot be used in the vm isolate. | 1939 // The object pool cannot be used in the vm isolate. |
| 1936 ASSERT(Isolate::Current() != Dart::vm_isolate()); | 1940 ASSERT(Isolate::Current() != Dart::vm_isolate()); |
| 1937 object_pool_ = GrowableObjectArray::New(); | 1941 object_pool_ = GrowableObjectArray::New(Heap::kOld); |
| 1938 } | 1942 } |
| 1939 for (int i = 0; i < object_pool_.Length(); i++) { | 1943 for (int i = 0; i < object_pool_.Length(); i++) { |
| 1940 if (object_pool_.At(i) == obj.raw()) { | 1944 if (object_pool_.At(i) == obj.raw()) { |
| 1941 return i; | 1945 return i; |
| 1942 } | 1946 } |
| 1943 } | 1947 } |
| 1944 object_pool_.Add(obj); | 1948 object_pool_.Add(obj, Heap::kOld); |
| 1945 return object_pool_.Length() - 1; | 1949 return object_pool_.Length() - 1; |
| 1946 } | 1950 } |
| 1947 | 1951 |
| 1948 | 1952 |
| 1949 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) { | 1953 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) { |
| 1950 if (object_pool_.IsNull()) { | 1954 if (object_pool_.IsNull()) { |
| 1951 // The object pool cannot be used in the vm isolate. | 1955 // The object pool cannot be used in the vm isolate. |
| 1952 ASSERT(Isolate::Current() != Dart::vm_isolate()); | 1956 ASSERT(Isolate::Current() != Dart::vm_isolate()); |
| 1953 object_pool_ = GrowableObjectArray::New(); | 1957 object_pool_ = GrowableObjectArray::New(Heap::kOld); |
| 1954 } | 1958 } |
| 1955 const word address = label->address(); | 1959 const word address = label->address(); |
| 1956 ASSERT(Utils::IsAligned(address, 4)); | 1960 ASSERT(Utils::IsAligned(address, 4)); |
| 1957 // The address is stored in the object array as a RawSmi. | 1961 // The address is stored in the object array as a RawSmi. |
| 1958 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift)); | 1962 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift)); |
| 1959 // Do not reuse an existing entry, since each reference may be patched | 1963 // Do not reuse an existing entry, since each reference may be patched |
| 1960 // independently. | 1964 // independently. |
| 1961 object_pool_.Add(smi); | 1965 object_pool_.Add(smi, Heap::kOld); |
| 1962 return object_pool_.Length() - 1; | 1966 return object_pool_.Length() - 1; |
| 1963 } | 1967 } |
| 1964 | 1968 |
| 1965 } // namespace dart | 1969 } // namespace dart |
| 1966 | 1970 |
| 1967 #endif // defined TARGET_ARCH_ARM | 1971 #endif // defined TARGET_ARCH_ARM |
| 1968 | 1972 |
| OLD | NEW |