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" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
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/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
11 #include "vm/runtime_entry.h" | 11 #include "vm/runtime_entry.h" |
12 #include "vm/simulator.h" | 12 #include "vm/simulator.h" |
13 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" |
14 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
15 | 15 |
16 // An extra check since we are assuming the existence of /proc/cpuinfo below. | 16 // An extra check since we are assuming the existence of /proc/cpuinfo below. |
17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) | 17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) |
18 #error ARM cross-compile only supported on Linux | 18 #error ARM cross-compile only supported on Linux |
19 #endif | 19 #endif |
20 | 20 |
21 namespace dart { | 21 namespace dart { |
22 | 22 |
| 23 DECLARE_FLAG(bool, allow_absolute_addresses); |
23 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 24 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
24 DECLARE_FLAG(bool, inline_alloc); | 25 DECLARE_FLAG(bool, inline_alloc); |
25 | 26 |
26 // Instruction encoding bits. | 27 // Instruction encoding bits. |
27 enum { | 28 enum { |
28 H = 1 << 5, // halfword (or byte) | 29 H = 1 << 5, // halfword (or byte) |
29 L = 1 << 20, // load (or store) | 30 L = 1 << 20, // load (or store) |
30 S = 1 << 20, // set condition code (or leave unchanged) | 31 S = 1 << 20, // set condition code (or leave unchanged) |
31 W = 1 << 21, // writeback base register (or leave unchanged) | 32 W = 1 << 21, // writeback base register (or leave unchanged) |
32 A = 1 << 21, // accumulate in multiply instruction (or not) | 33 A = 1 << 21, // accumulate in multiply instruction (or not) |
(...skipping 1543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 // Load common VM constants from the thread. This works also in places where | 1577 // Load common VM constants from the thread. This works also in places where |
1577 // no constant pool is set up (e.g. intrinsic code). | 1578 // no constant pool is set up (e.g. intrinsic code). |
1578 if (Thread::CanLoadFromThread(object)) { | 1579 if (Thread::CanLoadFromThread(object)) { |
1579 ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond); | 1580 ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond); |
1580 return; | 1581 return; |
1581 } | 1582 } |
1582 // Smis and VM heap objects are never relocated; do not use object pool. | 1583 // Smis and VM heap objects are never relocated; do not use object pool. |
1583 if (object.IsSmi()) { | 1584 if (object.IsSmi()) { |
1584 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); | 1585 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); |
1585 } else if (object.InVMHeap() || !constant_pool_allowed()) { | 1586 } else if (object.InVMHeap() || !constant_pool_allowed()) { |
| 1587 ASSERT(FLAG_allow_absolute_addresses); |
1586 // Make sure that class CallPattern is able to decode this load immediate. | 1588 // Make sure that class CallPattern is able to decode this load immediate. |
1587 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); | 1589 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); |
1588 LoadImmediate(rd, object_raw, cond); | 1590 LoadImmediate(rd, object_raw, cond); |
1589 } else { | 1591 } else { |
1590 // Make sure that class CallPattern is able to decode this load from the | 1592 // Make sure that class CallPattern is able to decode this load from the |
1591 // object pool. | 1593 // object pool. |
1592 const int32_t offset = ObjectPool::element_offset( | 1594 const int32_t offset = ObjectPool::element_offset( |
1593 is_unique ? object_pool_wrapper_.AddObject(object) | 1595 is_unique ? object_pool_wrapper_.AddObject(object) |
1594 : object_pool_wrapper_.FindObject(object)); | 1596 : object_pool_wrapper_.FindObject(object)); |
1595 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond); | 1597 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1770 b(&ok, EQ); | 1772 b(&ok, EQ); |
1771 Stop("Expected heap object or Smi"); | 1773 Stop("Expected heap object or Smi"); |
1772 break; | 1774 break; |
1773 case kEmptyOrSmiOrNull: | 1775 case kEmptyOrSmiOrNull: |
1774 b(&ok, EQ); // Smi is OK. | 1776 b(&ok, EQ); // Smi is OK. |
1775 // Non-smi case: Check for the special zap word or null. | 1777 // Non-smi case: Check for the special zap word or null. |
1776 // Note: Cannot use CompareImmediate, since IP may be in use. | 1778 // Note: Cannot use CompareImmediate, since IP may be in use. |
1777 LoadImmediate(temp, Heap::kZap32Bits); | 1779 LoadImmediate(temp, Heap::kZap32Bits); |
1778 cmp(old_value, Operand(temp)); | 1780 cmp(old_value, Operand(temp)); |
1779 b(&ok, EQ); | 1781 b(&ok, EQ); |
1780 LoadImmediate(temp, reinterpret_cast<uint32_t>(Object::null())); | 1782 LoadObject(temp, Object::null_object()); |
1781 cmp(old_value, Operand(temp)); | 1783 cmp(old_value, Operand(temp)); |
1782 b(&ok, EQ); | 1784 b(&ok, EQ); |
1783 Stop("Expected zapped, Smi or null"); | 1785 Stop("Expected zapped, Smi or null"); |
1784 break; | 1786 break; |
1785 default: | 1787 default: |
1786 UNREACHABLE(); | 1788 UNREACHABLE(); |
1787 } | 1789 } |
1788 Bind(&ok); | 1790 Bind(&ok); |
1789 if (VerifiedMemory::enabled()) { | 1791 if (VerifiedMemory::enabled()) { |
1790 Operand shadow_offset(GetVerifiedMemoryShadow()); | 1792 Operand shadow_offset(GetVerifiedMemoryShadow()); |
(...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3380 | 3382 |
3381 | 3383 |
3382 void Assembler::LoadAllocationStatsAddress(Register dest, | 3384 void Assembler::LoadAllocationStatsAddress(Register dest, |
3383 intptr_t cid, | 3385 intptr_t cid, |
3384 bool inline_isolate) { | 3386 bool inline_isolate) { |
3385 ASSERT(dest != kNoRegister); | 3387 ASSERT(dest != kNoRegister); |
3386 ASSERT(dest != TMP); | 3388 ASSERT(dest != TMP); |
3387 ASSERT(cid > 0); | 3389 ASSERT(cid > 0); |
3388 const intptr_t class_offset = ClassTable::ClassOffsetFor(cid); | 3390 const intptr_t class_offset = ClassTable::ClassOffsetFor(cid); |
3389 if (inline_isolate) { | 3391 if (inline_isolate) { |
| 3392 ASSERT(FLAG_allow_absolute_addresses); |
3390 ClassTable* class_table = Isolate::Current()->class_table(); | 3393 ClassTable* class_table = Isolate::Current()->class_table(); |
3391 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 3394 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
3392 if (cid < kNumPredefinedCids) { | 3395 if (cid < kNumPredefinedCids) { |
3393 LoadImmediate(dest, reinterpret_cast<uword>(*table_ptr) + class_offset); | 3396 LoadImmediate(dest, reinterpret_cast<uword>(*table_ptr) + class_offset); |
3394 } else { | 3397 } else { |
3395 LoadImmediate(dest, reinterpret_cast<uword>(table_ptr)); | 3398 LoadImmediate(dest, reinterpret_cast<uword>(table_ptr)); |
3396 ldr(dest, Address(dest, 0)); | 3399 ldr(dest, Address(dest, 0)); |
3397 AddImmediate(dest, class_offset); | 3400 AddImmediate(dest, class_offset); |
3398 } | 3401 } |
3399 } else { | 3402 } else { |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3663 | 3666 |
3664 | 3667 |
3665 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3668 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
3666 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3669 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
3667 return fpu_reg_names[reg]; | 3670 return fpu_reg_names[reg]; |
3668 } | 3671 } |
3669 | 3672 |
3670 } // namespace dart | 3673 } // namespace dart |
3671 | 3674 |
3672 #endif // defined TARGET_ARCH_ARM | 3675 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |