| Index: runtime/vm/assembler_arm.cc
|
| ===================================================================
|
| --- runtime/vm/assembler_arm.cc (revision 38478)
|
| +++ runtime/vm/assembler_arm.cc (working copy)
|
| @@ -2183,6 +2183,17 @@
|
| }
|
|
|
|
|
| +bool Address::CanHoldImmediateOffset(
|
| + bool is_load, intptr_t cid, int64_t offset) {
|
| + int32_t offset_mask = 0;
|
| + if (is_load) {
|
| + return CanHoldLoadOffset(OperandSizeFor(cid), offset, &offset_mask);
|
| + } else {
|
| + return CanHoldStoreOffset(OperandSizeFor(cid), offset, &offset_mask);
|
| + }
|
| +}
|
| +
|
| +
|
| void Assembler::Push(Register rd, Condition cond) {
|
| str(rd, Address(SP, -kWordSize, Address::PreIndex), cond);
|
| }
|
| @@ -3224,6 +3235,73 @@
|
| }
|
|
|
|
|
| +Address Assembler::ElementAddressForIntIndex(bool is_load,
|
| + bool is_external,
|
| + intptr_t cid,
|
| + intptr_t index_scale,
|
| + Register array,
|
| + intptr_t index,
|
| + Register temp) {
|
| + const int64_t offset_base =
|
| + (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
|
| + const int64_t offset = offset_base +
|
| + static_cast<int64_t>(index) * index_scale;
|
| + ASSERT(Utils::IsInt(32, offset));
|
| +
|
| + if (Address::CanHoldImmediateOffset(is_load, cid, offset)) {
|
| + return Address(array, static_cast<int32_t>(offset));
|
| + } else {
|
| + ASSERT(Address::CanHoldImmediateOffset(is_load, cid, offset - offset_base));
|
| + AddImmediate(temp, array, static_cast<int32_t>(offset_base));
|
| + return Address(temp, static_cast<int32_t>(offset - offset_base));
|
| + }
|
| +}
|
| +
|
| +
|
| +Address Assembler::ElementAddressForRegIndex(bool is_load,
|
| + bool is_external,
|
| + intptr_t cid,
|
| + intptr_t index_scale,
|
| + Register array,
|
| + Register index) {
|
| + // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
|
| + const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
|
| + int32_t offset =
|
| + is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
|
| + const OperandSize size = Address::OperandSizeFor(cid);
|
| + ASSERT(array != IP);
|
| + ASSERT(index != IP);
|
| + const Register base = is_load ? IP : index;
|
| + if ((offset != 0) ||
|
| + (size == kSWord) || (size == kDWord) || (size == kRegList)) {
|
| + if (shift < 0) {
|
| + ASSERT(shift == -1);
|
| + add(base, array, Operand(index, ASR, 1));
|
| + } else {
|
| + add(base, array, Operand(index, LSL, shift));
|
| + }
|
| + } else {
|
| + if (shift < 0) {
|
| + ASSERT(shift == -1);
|
| + return Address(array, index, ASR, 1);
|
| + } else {
|
| + return Address(array, index, LSL, shift);
|
| + }
|
| + }
|
| + int32_t offset_mask = 0;
|
| + if ((is_load && !Address::CanHoldLoadOffset(size,
|
| + offset,
|
| + &offset_mask)) ||
|
| + (!is_load && !Address::CanHoldStoreOffset(size,
|
| + offset,
|
| + &offset_mask))) {
|
| + AddImmediate(base, offset & ~offset_mask);
|
| + offset = offset & offset_mask;
|
| + }
|
| + return Address(base, offset);
|
| +}
|
| +
|
| +
|
| static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
|
| "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
| "r8", "ctx", "pp", "fp", "ip", "sp", "lr", "pc",
|
|
|