| 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/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1500 if (stack_elements > 0) { | 1500 if (stack_elements > 0) { |
| 1501 AddImmediate(SP, SP, stack_elements * kWordSize); | 1501 AddImmediate(SP, SP, stack_elements * kWordSize); |
| 1502 } | 1502 } |
| 1503 } | 1503 } |
| 1504 | 1504 |
| 1505 | 1505 |
| 1506 // Uses a code sequence that can easily be decoded. | 1506 // Uses a code sequence that can easily be decoded. |
| 1507 void Assembler::LoadWordFromPoolOffset(Register rd, | 1507 void Assembler::LoadWordFromPoolOffset(Register rd, |
| 1508 int32_t offset, | 1508 int32_t offset, |
| 1509 Condition cond) { | 1509 Condition cond) { |
| 1510 ASSERT(allow_constant_pool()); |
| 1510 ASSERT(rd != PP); | 1511 ASSERT(rd != PP); |
| 1511 int32_t offset_mask = 0; | 1512 int32_t offset_mask = 0; |
| 1512 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { | 1513 if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { |
| 1513 ldr(rd, Address(PP, offset), cond); | 1514 ldr(rd, Address(PP, offset), cond); |
| 1514 } else { | 1515 } else { |
| 1515 int32_t offset_hi = offset & ~offset_mask; // signed | 1516 int32_t offset_hi = offset & ~offset_mask; // signed |
| 1516 uint32_t offset_lo = offset & offset_mask; // unsigned | 1517 uint32_t offset_lo = offset & offset_mask; // unsigned |
| 1517 // Inline a simplified version of AddImmediate(rd, PP, offset_hi). | 1518 // Inline a simplified version of AddImmediate(rd, PP, offset_hi). |
| 1518 Operand o; | 1519 Operand o; |
| 1519 if (Operand::CanHold(offset_hi, &o)) { | 1520 if (Operand::CanHold(offset_hi, &o)) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1532 Instructions::HeaderSize() - Instructions::object_pool_offset() + | 1533 Instructions::HeaderSize() - Instructions::object_pool_offset() + |
| 1533 CodeSize() + Instr::kPCReadOffset; | 1534 CodeSize() + Instr::kPCReadOffset; |
| 1534 LoadFromOffset(kWord, PP, PC, -object_pool_pc_dist); | 1535 LoadFromOffset(kWord, PP, PC, -object_pool_pc_dist); |
| 1535 } | 1536 } |
| 1536 | 1537 |
| 1537 | 1538 |
| 1538 void Assembler::LoadObject(Register rd, const Object& object, Condition cond) { | 1539 void Assembler::LoadObject(Register rd, const Object& object, Condition cond) { |
| 1539 // Smis and VM heap objects are never relocated; do not use object pool. | 1540 // Smis and VM heap objects are never relocated; do not use object pool. |
| 1540 if (object.IsSmi()) { | 1541 if (object.IsSmi()) { |
| 1541 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); | 1542 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); |
| 1542 } else if (object.InVMHeap()) { | 1543 } else if (object.InVMHeap() || !allow_constant_pool()) { |
| 1543 // Make sure that class CallPattern is able to decode this load immediate. | 1544 // Make sure that class CallPattern is able to decode this load immediate. |
| 1544 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); | 1545 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); |
| 1545 LoadImmediate(rd, object_raw, cond); | 1546 LoadImmediate(rd, object_raw, cond); |
| 1546 } else { | 1547 } else { |
| 1547 // Make sure that class CallPattern is able to decode this load from the | 1548 // Make sure that class CallPattern is able to decode this load from the |
| 1548 // object pool. | 1549 // object pool. |
| 1549 const int32_t offset = | 1550 const int32_t offset = |
| 1550 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; | 1551 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; |
| 1551 LoadWordFromPoolOffset(rd, offset, cond); | 1552 LoadWordFromPoolOffset(rd, offset, cond); |
| 1552 } | 1553 } |
| (...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2719 sub(rd, rn, Operand(IP), cond); | 2720 sub(rd, rn, Operand(IP), cond); |
| 2720 } else { | 2721 } else { |
| 2721 LoadDecodableImmediate(IP, value, cond); | 2722 LoadDecodableImmediate(IP, value, cond); |
| 2722 add(rd, rn, Operand(IP), cond); | 2723 add(rd, rn, Operand(IP), cond); |
| 2723 } | 2724 } |
| 2724 } | 2725 } |
| 2725 } | 2726 } |
| 2726 | 2727 |
| 2727 | 2728 |
| 2728 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, | 2729 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, |
| 2729 Condition cond) { | 2730 Condition cond) { |
| 2730 Operand o; | 2731 Operand o; |
| 2731 if (Operand::CanHold(value, &o)) { | 2732 if (Operand::CanHold(value, &o)) { |
| 2732 // Handles value == kMinInt32. | 2733 // Handles value == kMinInt32. |
| 2733 adds(rd, rn, o, cond); | 2734 adds(rd, rn, o, cond); |
| 2734 } else if (Operand::CanHold(-value, &o)) { | 2735 } else if (Operand::CanHold(-value, &o)) { |
| 2735 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. | 2736 ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. |
| 2736 subs(rd, rn, o, cond); | 2737 subs(rd, rn, o, cond); |
| 2737 } else { | 2738 } else { |
| 2738 ASSERT(rn != IP); | 2739 ASSERT(rn != IP); |
| 2739 if (Operand::CanHold(~value, &o)) { | 2740 if (Operand::CanHold(~value, &o)) { |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3375 | 3376 |
| 3376 | 3377 |
| 3377 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3378 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3378 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3379 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 3379 return fpu_reg_names[reg]; | 3380 return fpu_reg_names[reg]; |
| 3380 } | 3381 } |
| 3381 | 3382 |
| 3382 } // namespace dart | 3383 } // namespace dart |
| 3383 | 3384 |
| 3384 #endif // defined TARGET_ARCH_ARM | 3385 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |