/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "assembler_thumb2.h"

#include "base/bit_utils.h"
#include "base/logging.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "offsets.h"
#include "thread.h"

namespace art {
namespace arm {

void Thumb2Assembler::Fixup::PrepareDependents(Thumb2Assembler* assembler) {
  // For each Fixup, it's easy to find the Fixups that it depends on as they are either
  // the following or the preceding Fixups until we find the target. However, for fixup
  // adjustment we need the reverse lookup, i.e. what Fixups depend on a given Fixup.
  // This function creates a compact representation of this relationship, where we have
  // all the dependents in a single array and Fixups reference their ranges by start
  // index and count. (Instead of having a per-fixup vector.)

  // Count the number of dependents of each Fixup.
  const FixupId end_id = assembler->fixups_.size();
  Fixup* fixups = assembler->fixups_.data();
  for (FixupId fixup_id = 0u; fixup_id != end_id; ++fixup_id) {
    uint32_t target = fixups[fixup_id].target_;
    if (target > fixups[fixup_id].location_) {
      for (FixupId id = fixup_id + 1u; id != end_id && fixups[id].location_ < target; ++id) {
        fixups[id].dependents_count_ += 1u;
      }
    } else {
      for (FixupId id = fixup_id; id != 0u && fixups[id - 1u].location_ >= target; --id) {
        fixups[id - 1u].dependents_count_ += 1u;
      }
    }
  }
  // Assign index ranges in fixup_dependents_ to individual fixups. Record the end of the
  // range in dependents_start_, we shall later decrement it as we fill in fixup_dependents_.
  uint32_t number_of_dependents = 0u;
  for (FixupId fixup_id = 0u; fixup_id != end_id; ++fixup_id) {
    number_of_dependents += fixups[fixup_id].dependents_count_;
    fixups[fixup_id].dependents_start_ = number_of_dependents;
  }
  if (number_of_dependents == 0u) {
    return;
  }
  // Create and fill in the fixup_dependents_.
  assembler->fixup_dependents_.resize(number_of_dependents);
  FixupId* dependents = assembler->fixup_dependents_.data();
  for (FixupId fixup_id = 0u; fixup_id != end_id; ++fixup_id) {
    uint32_t target = fixups[fixup_id].target_;
    if (target > fixups[fixup_id].location_) {
      for (FixupId id = fixup_id + 1u; id != end_id && fixups[id].location_ < target; ++id) {
        fixups[id].dependents_start_ -= 1u;
        dependents[fixups[id].dependents_start_] = fixup_id;
      }
    } else {
      for (FixupId id = fixup_id; id != 0u && fixups[id - 1u].location_ >= target; --id) {
        fixups[id - 1u].dependents_start_ -= 1u;
        dependents[fixups[id - 1u].dependents_start_] = fixup_id;
      }
    }
  }
}

void Thumb2Assembler::BindLabel(Label* label, uint32_t bound_pc) {
  CHECK(!label->IsBound());

  while (label->IsLinked()) {
    FixupId fixup_id = label->Position();                     // The id for linked Fixup.
    Fixup* fixup = GetFixup(fixup_id);                        // Get the Fixup at this id.
    fixup->Resolve(bound_pc);                                 // Fixup can be resolved now.
    uint32_t fixup_location = fixup->GetLocation();
    uint16_t next = buffer_.Load<uint16_t>(fixup_location);   // Get next in chain.
    buffer_.Store<int16_t>(fixup_location, 0);
    label->position_ = next;                                  // Move to next.
  }
  label->BindTo(bound_pc);
}

uint32_t Thumb2Assembler::BindLiterals() {
  // We don't add the padding here, that's done only after adjusting the Fixup sizes.
  uint32_t code_size = buffer_.Size();
  for (Literal& lit : literals_) {
    Label* label = lit.GetLabel();
    BindLabel(label, code_size);
    code_size += lit.GetSize();
  }
  return code_size;
}

void Thumb2Assembler::BindJumpTables(uint32_t code_size) {
  for (JumpTable& table : jump_tables_) {
    Label* label = table.GetLabel();
    BindLabel(label, code_size);
    code_size += table.GetSize();
  }
}

void Thumb2Assembler::AdjustFixupIfNeeded(Fixup* fixup, uint32_t* current_code_size,
                                          std::deque<FixupId>* fixups_to_recalculate) {
  uint32_t adjustment = fixup->AdjustSizeIfNeeded(*current_code_size);
  if (adjustment != 0u) {
    *current_code_size += adjustment;
    for (FixupId dependent_id : fixup->Dependents(*this)) {
      Fixup* dependent = GetFixup(dependent_id);
      dependent->IncreaseAdjustment(adjustment);
      if (buffer_.Load<int16_t>(dependent->GetLocation()) == 0) {
        buffer_.Store<int16_t>(dependent->GetLocation(), 1);
        fixups_to_recalculate->push_back(dependent_id);
      }
    }
  }
}

uint32_t Thumb2Assembler::AdjustFixups() {
  Fixup::PrepareDependents(this);
  uint32_t current_code_size = buffer_.Size();
  std::deque<FixupId> fixups_to_recalculate;
  if (kIsDebugBuild) {
    // We will use the placeholders in the buffer_ to mark whether the fixup has
    // been added to the fixups_to_recalculate. Make sure we start with zeros.
    for (Fixup& fixup : fixups_) {
      CHECK_EQ(buffer_.Load<int16_t>(fixup.GetLocation()), 0);
    }
  }
  for (Fixup& fixup : fixups_) {
    AdjustFixupIfNeeded(&fixup, &current_code_size, &fixups_to_recalculate);
  }
  while (!fixups_to_recalculate.empty()) {
    do {
      // Pop the fixup.
      FixupId fixup_id = fixups_to_recalculate.front();
      fixups_to_recalculate.pop_front();
      Fixup* fixup = GetFixup(fixup_id);
      DCHECK_NE(buffer_.Load<int16_t>(fixup->GetLocation()), 0);
      buffer_.Store<int16_t>(fixup->GetLocation(), 0);
      // See if it needs adjustment.
      AdjustFixupIfNeeded(fixup, &current_code_size, &fixups_to_recalculate);
    } while (!fixups_to_recalculate.empty());

    if ((current_code_size & 2) != 0 && (!literals_.empty() || !jump_tables_.empty())) {
      // If we need to add padding before literals, this may just push some out of range,
      // so recalculate all load literals. This makes up for the fact that we don't mark
      // load literal as a dependency of all previous Fixups even though it actually is.
      for (Fixup& fixup : fixups_) {
        if (fixup.IsLoadLiteral()) {
          AdjustFixupIfNeeded(&fixup, &current_code_size, &fixups_to_recalculate);
        }
      }
    }
  }
  if (kIsDebugBuild) {
    // Check that no fixup is marked as being in fixups_to_recalculate anymore.
    for (Fixup& fixup : fixups_) {
      CHECK_EQ(buffer_.Load<int16_t>(fixup.GetLocation()), 0);
    }
  }

  // Adjust literal pool labels for padding.
  DCHECK_ALIGNED(current_code_size, 2);
  uint32_t literals_adjustment = current_code_size + (current_code_size & 2) - buffer_.Size();
  if (literals_adjustment != 0u) {
    for (Literal& literal : literals_) {
      Label* label = literal.GetLabel();
      DCHECK(label->IsBound());
      int old_position = label->Position();
      label->Reinitialize();
      label->BindTo(old_position + literals_adjustment);
    }
    for (JumpTable& table : jump_tables_) {
      Label* label = table.GetLabel();
      DCHECK(label->IsBound());
      int old_position = label->Position();
      label->Reinitialize();
      label->BindTo(old_position + literals_adjustment);
    }
  }

  return current_code_size;
}

void Thumb2Assembler::EmitFixups(uint32_t adjusted_code_size) {
  // Move non-fixup code to its final place and emit fixups.
  // Process fixups in reverse order so that we don't repeatedly move the same data.
  size_t src_end = buffer_.Size();
  size_t dest_end = adjusted_code_size;
  buffer_.Resize(dest_end);
  DCHECK_GE(dest_end, src_end);
  for (auto i = fixups_.rbegin(), end = fixups_.rend(); i != end; ++i) {
    Fixup* fixup = &*i;
    if (fixup->GetOriginalSize() == fixup->GetSize()) {
      // The size of this Fixup didn't change. To avoid moving the data
      // in small chunks, emit the code to its original position.
      fixup->Emit(&buffer_, adjusted_code_size);
      fixup->Finalize(dest_end - src_end);
    } else {
      // Move the data between the end of the fixup and src_end to its final location.
      size_t old_fixup_location = fixup->GetLocation();
      size_t src_begin = old_fixup_location + fixup->GetOriginalSizeInBytes();
      size_t data_size = src_end - src_begin;
      size_t dest_begin  = dest_end - data_size;
      buffer_.Move(dest_begin, src_begin, data_size);
      src_end = old_fixup_location;
      dest_end = dest_begin - fixup->GetSizeInBytes();
      // Finalize the Fixup and emit the data to the new location.
      fixup->Finalize(dest_end - src_end);
      fixup->Emit(&buffer_, adjusted_code_size);
    }
  }
  CHECK_EQ(src_end, dest_end);
}

void Thumb2Assembler::EmitLiterals() {
  if (!literals_.empty()) {
    // Load literal instructions (LDR, LDRD, VLDR) require 4-byte alignment.
    // We don't support byte and half-word literals.
    uint32_t code_size = buffer_.Size();
    DCHECK_ALIGNED(code_size, 2);
    if ((code_size & 2u) != 0u) {
      Emit16(0);
    }
    for (Literal& literal : literals_) {
      AssemblerBuffer::EnsureCapacity ensured(&buffer_);
      DCHECK_EQ(static_cast<size_t>(literal.GetLabel()->Position()), buffer_.Size());
      DCHECK(literal.GetSize() == 4u || literal.GetSize() == 8u);
      for (size_t i = 0, size = literal.GetSize(); i != size; ++i) {
        buffer_.Emit<uint8_t>(literal.GetData()[i]);
      }
    }
  }
}

void Thumb2Assembler::EmitJumpTables() {
  if (!jump_tables_.empty()) {
    // Jump tables require 4 byte alignment. (We don't support byte and half-word jump tables.)
    uint32_t code_size = buffer_.Size();
    DCHECK_ALIGNED(code_size, 2);
    if ((code_size & 2u) != 0u) {
      Emit16(0);
    }
    for (JumpTable& table : jump_tables_) {
      // Bulk ensure capacity, as this may be large.
      size_t orig_size = buffer_.Size();
      buffer_.ExtendCapacity(orig_size + table.GetSize());
#ifndef NDEBUG
      buffer_.has_ensured_capacity_ = true;
#endif

      DCHECK_EQ(static_cast<size_t>(table.GetLabel()->Position()), buffer_.Size());
      int32_t anchor_position = table.GetAnchorLabel()->Position() + 4;

      for (Label* target : table.GetData()) {
        // Ensure that the label was tracked, so that it will have the right position.
        DCHECK(std::find(tracked_labels_.begin(), tracked_labels_.end(), target) !=
                   tracked_labels_.end());

        int32_t offset = target->Position() - anchor_position;
        buffer_.Emit<int32_t>(offset);
      }

#ifndef NDEBUG
      buffer_.has_ensured_capacity_ = false;
#endif
      size_t new_size = buffer_.Size();
      DCHECK_LE(new_size - orig_size, table.GetSize());
    }
  }
}

void Thumb2Assembler::PatchCFI() {
  if (cfi().NumberOfDelayedAdvancePCs() == 0u) {
    return;
  }

  typedef DebugFrameOpCodeWriterForAssembler::DelayedAdvancePC DelayedAdvancePC;
  const auto data = cfi().ReleaseStreamAndPrepareForDelayedAdvancePC();
  const std::vector<uint8_t>& old_stream = data.first;
  const std::vector<DelayedAdvancePC>& advances = data.second;

  // Refill our data buffer with patched opcodes.
  cfi().ReserveCFIStream(old_stream.size() + advances.size() + 16);
  size_t stream_pos = 0;
  for (const DelayedAdvancePC& advance : advances) {
    DCHECK_GE(advance.stream_pos, stream_pos);
    // Copy old data up to the point where advance was issued.
    cfi().AppendRawData(old_stream, stream_pos, advance.stream_pos);
    stream_pos = advance.stream_pos;
    // Insert the advance command with its final offset.
    size_t final_pc = GetAdjustedPosition(advance.pc);
    cfi().AdvancePC(final_pc);
  }
  // Copy the final segment if any.
  cfi().AppendRawData(old_stream, stream_pos, old_stream.size());
}

inline int16_t Thumb2Assembler::BEncoding16(int32_t offset, Condition cond) {
  DCHECK_ALIGNED(offset, 2);
  int16_t encoding = B15 | B14;
  if (cond != AL) {
    DCHECK(IsInt<9>(offset));
    encoding |= B12 |  (static_cast<int32_t>(cond) << 8) | ((offset >> 1) & 0xff);
  } else {
    DCHECK(IsInt<12>(offset));
    encoding |= B13 | ((offset >> 1) & 0x7ff);
  }
  return encoding;
}

inline int32_t Thumb2Assembler::BEncoding32(int32_t offset, Condition cond) {
  DCHECK_ALIGNED(offset, 2);
  int32_t s = (offset >> 31) & 1;   // Sign bit.
  int32_t encoding = B31 | B30 | B29 | B28 | B15 |
      (s << 26) |                   // Sign bit goes to bit 26.
      ((offset >> 1) & 0x7ff);      // imm11 goes to bits 0-10.
  if (cond != AL) {
    DCHECK(IsInt<21>(offset));
    // Encode cond, move imm6 from bits 12-17 to bits 16-21 and move J1 and J2.
    encoding |= (static_cast<int32_t>(cond) << 22) | ((offset & 0x3f000) << (16 - 12)) |
        ((offset & (1 << 19)) >> (19 - 13)) |   // Extract J1 from bit 19 to bit 13.
        ((offset & (1 << 18)) >> (18 - 11));    // Extract J2 from bit 18 to bit 11.
  } else {
    DCHECK(IsInt<25>(offset));
    int32_t j1 = ((offset >> 23) ^ s ^ 1) & 1;  // Calculate J1 from I1 extracted from bit 23.
    int32_t j2 = ((offset >> 22)^ s ^ 1) & 1;   // Calculate J2 from I2 extracted from bit 22.
    // Move imm10 from bits 12-21 to bits 16-25 and add J1 and J2.
    encoding |= B12 | ((offset & 0x3ff000) << (16 - 12)) |
        (j1 << 13) | (j2 << 11);
  }
  return encoding;
}

inline int16_t Thumb2Assembler::CbxzEncoding16(Register rn, int32_t offset, Condition cond) {
  DCHECK(!IsHighRegister(rn));
  DCHECK_ALIGNED(offset, 2);
  DCHECK(IsUint<7>(offset));
  DCHECK(cond == EQ || cond == NE);
  return B15 | B13 | B12 | B8 | (cond == NE ? B11 : 0) | static_cast<int32_t>(rn) |
      ((offset & 0x3e) << (3 - 1)) |    // Move imm5 from bits 1-5 to bits 3-7.
      ((offset & 0x40) << (9 - 6));     // Move i from bit 6 to bit 11
}

inline int16_t Thumb2Assembler::CmpRnImm8Encoding16(Register rn, int32_t value) {
  DCHECK(!IsHighRegister(rn));
  DCHECK(IsUint<8>(value));
  return B13 | B11 | (rn << 8) | value;
}

inline int16_t Thumb2Assembler::AddRdnRmEncoding16(Register rdn, Register rm) {
  // The high bit of rn is moved across 4-bit rm.
  return B14 | B10 | (static_cast<int32_t>(rm) << 3) |
      (static_cast<int32_t>(rdn) & 7) | ((static_cast<int32_t>(rdn) & 8) << 4);
}

inline int32_t Thumb2Assembler::MovwEncoding32(Register rd, int32_t value) {
  DCHECK(IsUint<16>(value));
  return B31 | B30 | B29 | B28 | B25 | B22 |
      (static_cast<int32_t>(rd) << 8) |
      ((value & 0xf000) << (16 - 12)) |   // Move imm4 from bits 12-15 to bits 16-19.
      ((value & 0x0800) << (26 - 11)) |   // Move i from bit 11 to bit 26.
      ((value & 0x0700) << (12 - 8)) |    // Move imm3 from bits 8-10 to bits 12-14.
      (value & 0xff);                     // Keep imm8 in bits 0-7.
}

inline int32_t Thumb2Assembler::MovtEncoding32(Register rd, int32_t value) {
  DCHECK_EQ(value & 0xffff, 0);
  int32_t movw_encoding = MovwEncoding32(rd, (value >> 16) & 0xffff);
  return movw_encoding | B25 | B23;
}

inline int32_t Thumb2Assembler::MovModImmEncoding32(Register rd, int32_t value) {
  uint32_t mod_imm = ModifiedImmediate(value);
  DCHECK_NE(mod_imm, kInvalidModifiedImmediate);
  return B31 | B30 | B29 | B28 | B22 | B19 | B18 | B17 | B16 |
      (static_cast<int32_t>(rd) << 8) | static_cast<int32_t>(mod_imm);
}

inline int16_t Thumb2Assembler::LdrLitEncoding16(Register rt, int32_t offset) {
  DCHECK(!IsHighRegister(rt));
  DCHECK_ALIGNED(offset, 4);
  DCHECK(IsUint<10>(offset));
  return B14 | B11 | (static_cast<int32_t>(rt) << 8) | (offset >> 2);
}

inline int32_t Thumb2Assembler::LdrLitEncoding32(Register rt, int32_t offset) {
  // NOTE: We don't support negative offset, i.e. U=0 (B23).
  return LdrRtRnImm12Encoding(rt, PC, offset);
}

inline int32_t Thumb2Assembler::LdrdEncoding32(Register rt, Register rt2, Register rn, int32_t offset) {
  DCHECK_ALIGNED(offset, 4);
  CHECK(IsUint<10>(offset));
  return B31 | B30 | B29 | B27 |
      B24 /* P = 1 */ | B23 /* U = 1 */ | B22 | 0 /* W = 0 */ | B20 |
      (static_cast<int32_t>(rn) << 16) | (static_cast<int32_t>(rt) << 12) |
      (static_cast<int32_t>(rt2) << 8) | (offset >> 2);
}

inline int32_t Thumb2Assembler::VldrsEncoding32(SRegister sd, Register rn, int32_t offset) {
  DCHECK_ALIGNED(offset, 4);
  CHECK(IsUint<10>(offset));
  return B31 | B30 | B29 | B27 | B26 | B24 |
      B23 /* U = 1 */ | B20 | B11 | B9 |
      (static_cast<int32_t>(rn) << 16) |
      ((static_cast<int32_t>(sd) & 0x01) << (22 - 0)) |   // Move D from bit 0 to bit 22.
      ((static_cast<int32_t>(sd) & 0x1e) << (12 - 1)) |   // Move Vd from bits 1-4 to bits 12-15.
      (offset >> 2);
}

inline int32_t Thumb2Assembler::VldrdEncoding32(DRegister dd, Register rn, int32_t offset) {
  DCHECK_ALIGNED(offset, 4);
  CHECK(IsUint<10>(offset));
  return B31 | B30 | B29 | B27 | B26 | B24 |
      B23 /* U = 1 */ | B20 | B11 | B9 | B8 |
      (rn << 16) |
      ((static_cast<int32_t>(dd) & 0x10) << (22 - 4)) |   // Move D from bit 4 to bit 22.
      ((static_cast<int32_t>(dd) & 0x0f) << (12 - 0)) |   // Move Vd from bits 0-3 to bits 12-15.
      (offset >> 2);
}

inline int16_t Thumb2Assembler::LdrRtRnImm5Encoding16(Register rt, Register rn, int32_t offset) {
  DCHECK(!IsHighRegister(rt));
  DCHECK(!IsHighRegister(rn));
  DCHECK_ALIGNED(offset, 4);
  DCHECK(IsUint<7>(offset));
  return B14 | B13 | B11 |
      (static_cast<int32_t>(rn) << 3) | static_cast<int32_t>(rt) |
      (offset << (6 - 2));                // Move imm5 from bits 2-6 to bits 6-10.
}

int32_t Thumb2Assembler::Fixup::LoadWideOrFpEncoding(Register rbase, int32_t offset) const {
  switch (type_) {
    case kLoadLiteralWide:
      return LdrdEncoding32(rn_, rt2_, rbase, offset);
    case kLoadFPLiteralSingle:
      return VldrsEncoding32(sd_, rbase, offset);
    case kLoadFPLiteralDouble:
      return VldrdEncoding32(dd_, rbase, offset);
    default:
      LOG(FATAL) << "Unexpected type: " << static_cast<int>(type_);
      UNREACHABLE();
  }
}

inline int32_t Thumb2Assembler::LdrRtRnImm12Encoding(Register rt, Register rn, int32_t offset) {
  DCHECK(IsUint<12>(offset));
  return B31 | B30 | B29 | B28 | B27 | B23 | B22 | B20 | (rn << 16) | (rt << 12) | offset;
}

inline int16_t Thumb2Assembler::AdrEncoding16(Register rd, int32_t offset) {
  DCHECK(IsUint<10>(offset));
  DCHECK(IsAligned<4>(offset));
  DCHECK(!IsHighRegister(rd));
  return B15 | B13 | (rd << 8) | (offset >> 2);
}

inline int32_t Thumb2Assembler::AdrEncoding32(Register rd, int32_t offset) {
  DCHECK(IsUint<12>(offset));
  // Bit     26: offset[11]
  // Bits 14-12: offset[10-8]
  // Bits   7-0: offset[7-0]
  int32_t immediate_mask =
      ((offset & (1 << 11)) << (26 - 11)) |
      ((offset & (7 << 8)) << (12 - 8)) |
      (offset & 0xFF);
  return B31 | B30 | B29 | B28 | B25 | B19 | B18 | B17 | B16 | (rd << 8) | immediate_mask;
}

void Thumb2Assembler::FinalizeCode() {
  ArmAssembler::FinalizeCode();
  uint32_t size_after_literals = BindLiterals();
  BindJumpTables(size_after_literals);
  uint32_t adjusted_code_size = AdjustFixups();
  EmitFixups(adjusted_code_size);
  EmitLiterals();
  FinalizeTrackedLabels();
  EmitJumpTables();
  PatchCFI();
}

bool Thumb2Assembler::ShifterOperandCanAlwaysHold(uint32_t immediate) {
  return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate;
}

bool Thumb2Assembler::ShifterOperandCanHold(Register rd ATTRIBUTE_UNUSED,
                                            Register rn ATTRIBUTE_UNUSED,
                                            Opcode opcode,
                                            uint32_t immediate,
                                            SetCc set_cc,
                                            ShifterOperand* shifter_op) {
  shifter_op->type_ = ShifterOperand::kImmediate;
  shifter_op->immed_ = immediate;
  shifter_op->is_shift_ = false;
  shifter_op->is_rotate_ = false;
  switch (opcode) {
    case ADD:
    case SUB:
      // Less than (or equal to) 12 bits can be done if we don't need to set condition codes.
      if (immediate < (1 << 12) && set_cc != kCcSet) {
        return true;
      }
      return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate;

    case MOV:
      // TODO: Support less than or equal to 12bits.
      return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate;

    case MVN:
    default:
      return ArmAssembler::ModifiedImmediate(immediate) != kInvalidModifiedImmediate;
  }
}

void Thumb2Assembler::and_(Register rd, Register rn, const ShifterOperand& so,
                           Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, AND, set_cc, rn, rd, so);
}


void Thumb2Assembler::eor(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, EOR, set_cc, rn, rd, so);
}


void Thumb2Assembler::sub(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, SUB, set_cc, rn, rd, so);
}


void Thumb2Assembler::rsb(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, RSB, set_cc, rn, rd, so);
}


void Thumb2Assembler::add(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, ADD, set_cc, rn, rd, so);
}


void Thumb2Assembler::adc(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, ADC, set_cc, rn, rd, so);
}


void Thumb2Assembler::sbc(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, SBC, set_cc, rn, rd, so);
}


void Thumb2Assembler::rsc(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, RSC, set_cc, rn, rd, so);
}


void Thumb2Assembler::tst(Register rn, const ShifterOperand& so, Condition cond) {
  CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
  EmitDataProcessing(cond, TST, kCcSet, rn, R0, so);
}


void Thumb2Assembler::teq(Register rn, const ShifterOperand& so, Condition cond) {
  CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
  EmitDataProcessing(cond, TEQ, kCcSet, rn, R0, so);
}


void Thumb2Assembler::cmp(Register rn, const ShifterOperand& so, Condition cond) {
  EmitDataProcessing(cond, CMP, kCcSet, rn, R0, so);
}


void Thumb2Assembler::cmn(Register rn, const ShifterOperand& so, Condition cond) {
  EmitDataProcessing(cond, CMN, kCcSet, rn, R0, so);
}


void Thumb2Assembler::orr(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, ORR, set_cc, rn, rd, so);
}


void Thumb2Assembler::orn(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, ORN, set_cc, rn, rd, so);
}


void Thumb2Assembler::mov(Register rd, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, MOV, set_cc, R0, rd, so);
}


void Thumb2Assembler::bic(Register rd, Register rn, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, BIC, set_cc, rn, rd, so);
}


void Thumb2Assembler::mvn(Register rd, const ShifterOperand& so,
                          Condition cond, SetCc set_cc) {
  EmitDataProcessing(cond, MVN, set_cc, R0, rd, so);
}


void Thumb2Assembler::mul(Register rd, Register rn, Register rm, Condition cond) {
  CheckCondition(cond);

  if (rd == rm && !IsHighRegister(rd) && !IsHighRegister(rn) && !force_32bit_) {
    // 16 bit.
    int16_t encoding = B14 | B9 | B8 | B6 |
        rn << 3 | rd;
    Emit16(encoding);
  } else {
    // 32 bit.
    uint32_t op1 = 0U /* 0b000 */;
    uint32_t op2 = 0U /* 0b00 */;
    int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
        op1 << 20 |
        B15 | B14 | B13 | B12 |
        op2 << 4 |
        static_cast<uint32_t>(rd) << 8 |
        static_cast<uint32_t>(rn) << 16 |
        static_cast<uint32_t>(rm);

    Emit32(encoding);
  }
}


void Thumb2Assembler::mla(Register rd, Register rn, Register rm, Register ra,
                          Condition cond) {
  CheckCondition(cond);

  uint32_t op1 = 0U /* 0b000 */;
  uint32_t op2 = 0U /* 0b00 */;
  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
      op1 << 20 |
      op2 << 4 |
      static_cast<uint32_t>(rd) << 8 |
      static_cast<uint32_t>(ra) << 12 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rm);

  Emit32(encoding);
}


void Thumb2Assembler::mls(Register rd, Register rn, Register rm, Register ra,
                          Condition cond) {
  CheckCondition(cond);

  uint32_t op1 = 0U /* 0b000 */;
  uint32_t op2 = 01 /* 0b01 */;
  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
      op1 << 20 |
      op2 << 4 |
      static_cast<uint32_t>(rd) << 8 |
      static_cast<uint32_t>(ra) << 12 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rm);

  Emit32(encoding);
}


void Thumb2Assembler::smull(Register rd_lo, Register rd_hi, Register rn,
                            Register rm, Condition cond) {
  CheckCondition(cond);

  uint32_t op1 = 0U /* 0b000; */;
  uint32_t op2 = 0U /* 0b0000 */;
  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 |
      op1 << 20 |
      op2 << 4 |
      static_cast<uint32_t>(rd_lo) << 12 |
      static_cast<uint32_t>(rd_hi) << 8 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rm);

  Emit32(encoding);
}


void Thumb2Assembler::umull(Register rd_lo, Register rd_hi, Register rn,
                            Register rm, Condition cond) {
  CheckCondition(cond);

  uint32_t op1 = 2U /* 0b010; */;
  uint32_t op2 = 0U /* 0b0000 */;
  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 |
      op1 << 20 |
      op2 << 4 |
      static_cast<uint32_t>(rd_lo) << 12 |
      static_cast<uint32_t>(rd_hi) << 8 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rm);

  Emit32(encoding);
}


void Thumb2Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) {
  CheckCondition(cond);

  uint32_t op1 = 1U  /* 0b001 */;
  uint32_t op2 = 15U /* 0b1111 */;
  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | B20 |
      op1 << 20 |
      op2 << 4 |
      0xf << 12 |
      static_cast<uint32_t>(rd) << 8 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rm);

  Emit32(encoding);
}


void Thumb2Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) {
  CheckCondition(cond);

  uint32_t op1 = 1U  /* 0b001 */;
  uint32_t op2 = 15U /* 0b1111 */;
  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | B21 | B20 |
      op1 << 20 |
      op2 << 4 |
      0xf << 12 |
      static_cast<uint32_t>(rd) << 8 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rm);

  Emit32(encoding);
}


void Thumb2Assembler::sbfx(Register rd, Register rn, uint32_t lsb, uint32_t width, Condition cond) {
  CheckCondition(cond);
  CHECK_LE(lsb, 31U);
  CHECK(1U <= width && width <= 32U) << width;
  uint32_t widthminus1 = width - 1;
  uint32_t imm2 = lsb & (B1 | B0);  // Bits 0-1 of `lsb`.
  uint32_t imm3 = (lsb & (B4 | B3 | B2)) >> 2;  // Bits 2-4 of `lsb`.

  uint32_t op = 20U /* 0b10100 */;
  int32_t encoding = B31 | B30 | B29 | B28 | B25 |
      op << 20 |
      static_cast<uint32_t>(rn) << 16 |
      imm3 << 12 |
      static_cast<uint32_t>(rd) << 8 |
      imm2 << 6 |
      widthminus1;

  Emit32(encoding);
}


void Thumb2Assembler::ubfx(Register rd, Register rn, uint32_t lsb, uint32_t width, Condition cond) {
  CheckCondition(cond);
  CHECK_LE(lsb, 31U);
  CHECK(1U <= width && width <= 32U) << width;
  uint32_t widthminus1 = width - 1;
  uint32_t imm2 = lsb & (B1 | B0);  // Bits 0-1 of `lsb`.
  uint32_t imm3 = (lsb & (B4 | B3 | B2)) >> 2;  // Bits 2-4 of `lsb`.

  uint32_t op = 28U /* 0b11100 */;
  int32_t encoding = B31 | B30 | B29 | B28 | B25 |
      op << 20 |
      static_cast<uint32_t>(rn) << 16 |
      imm3 << 12 |
      static_cast<uint32_t>(rd) << 8 |
      imm2 << 6 |
      widthminus1;

  Emit32(encoding);
}


void Thumb2Assembler::ldr(Register rd, const Address& ad, Condition cond) {
  EmitLoadStore(cond, true, false, false, false, rd, ad);
}


void Thumb2Assembler::str(Register rd, const Address& ad, Condition cond) {
  EmitLoadStore(cond, false, false, false, false, rd, ad);
}


void Thumb2Assembler::ldrb(Register rd, const Address& ad, Condition cond) {
  EmitLoadStore(cond, true, true, false, false, rd, ad);
}


void Thumb2Assembler::strb(Register rd, const Address& ad, Condition cond) {
  EmitLoadStore(cond, false, true, false, false, rd, ad);
}


void Thumb2Assembler::ldrh(Register rd, const Address& ad, Condition cond) {
  EmitLoadStore(cond, true, false, true, false, rd, ad);
}


void Thumb2Assembler::strh(Register rd, const Address& ad, Condition cond) {
  EmitLoadStore(cond, false, false, true, false, rd, ad);
}


void Thumb2Assembler::ldrsb(Register rd, const Address& ad, Condition cond) {
  EmitLoadStore(cond, true, true, false, true, rd, ad);
}


void Thumb2Assembler::ldrsh(Register rd, const Address& ad, Condition cond) {
  EmitLoadStore(cond, true, false, true, true, rd, ad);
}


void Thumb2Assembler::ldrd(Register rd, const Address& ad, Condition cond) {
  ldrd(rd, Register(rd + 1), ad, cond);
}


void Thumb2Assembler::ldrd(Register rd, Register rd2, const Address& ad, Condition cond) {
  CheckCondition(cond);
  // Encoding T1.
  // This is different from other loads.  The encoding is like ARM.
  int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 |
      static_cast<int32_t>(rd) << 12 |
      static_cast<int32_t>(rd2) << 8 |
      ad.encodingThumbLdrdStrd();
  Emit32(encoding);
}


void Thumb2Assembler::strd(Register rd, const Address& ad, Condition cond) {
  strd(rd, Register(rd + 1), ad, cond);
}


void Thumb2Assembler::strd(Register rd, Register rd2, const Address& ad, Condition cond) {
  CheckCondition(cond);
  // Encoding T1.
  // This is different from other loads.  The encoding is like ARM.
  int32_t encoding = B31 | B30 | B29 | B27 | B22 |
      static_cast<int32_t>(rd) << 12 |
      static_cast<int32_t>(rd2) << 8 |
      ad.encodingThumbLdrdStrd();
  Emit32(encoding);
}


void Thumb2Assembler::ldm(BlockAddressMode am,
                          Register base,
                          RegList regs,
                          Condition cond) {
  CHECK_NE(regs, 0u);  // Do not use ldm if there's nothing to load.
  if (IsPowerOfTwo(regs)) {
    // Thumb doesn't support one reg in the list.
    // Find the register number.
    int reg = CTZ(static_cast<uint32_t>(regs));
    CHECK_LT(reg, 16);
    CHECK(am == DB_W);      // Only writeback is supported.
    ldr(static_cast<Register>(reg), Address(base, kRegisterSize, Address::PostIndex), cond);
  } else {
    EmitMultiMemOp(cond, am, true, base, regs);
  }
}


void Thumb2Assembler::stm(BlockAddressMode am,
                          Register base,
                          RegList regs,
                          Condition cond) {
  CHECK_NE(regs, 0u);  // Do not use stm if there's nothing to store.
  if (IsPowerOfTwo(regs)) {
    // Thumb doesn't support one reg in the list.
    // Find the register number.
    int reg = CTZ(static_cast<uint32_t>(regs));
    CHECK_LT(reg, 16);
    CHECK(am == IA || am == IA_W);
    Address::Mode strmode = am == IA ? Address::PreIndex : Address::Offset;
    str(static_cast<Register>(reg), Address(base, -kRegisterSize, strmode), cond);
  } else {
    EmitMultiMemOp(cond, am, false, base, regs);
  }
}


bool Thumb2Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
  uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
  if (((imm32 & ((1 << 19) - 1)) == 0) &&
      ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
       (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
    uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
        ((imm32 >> 19) & ((1 << 6) -1));
    EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
               sd, S0, S0);
    return true;
  }
  return false;
}


bool Thumb2Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
  uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
  if (((imm64 & ((1LL << 48) - 1)) == 0) &&
      ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
       (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
    uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
        ((imm64 >> 48) & ((1 << 6) -1));
    EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
               dd, D0, D0);
    return true;
  }
  return false;
}


void Thumb2Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
}


void Thumb2Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
  EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
}


void Thumb2Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
                            Condition cond) {
  EmitVFPsss(cond, B21 | B20, sd, sn, sm);
}


void Thumb2Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
                            Condition cond) {
  EmitVFPddd(cond, B21 | B20, dd, dn, dm);
}


void Thumb2Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
                            Condition cond) {
  EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
}


void Thumb2Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
                            Condition cond) {
  EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
}


void Thumb2Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
                            Condition cond) {
  EmitVFPsss(cond, B21, sd, sn, sm);
}


void Thumb2Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
                            Condition cond) {
  EmitVFPddd(cond, B21, dd, dn, dm);
}


void Thumb2Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
                            Condition cond) {
  EmitVFPsss(cond, 0, sd, sn, sm);
}


void Thumb2Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
                            Condition cond) {
  EmitVFPddd(cond, 0, dd, dn, dm);
}


void Thumb2Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
                            Condition cond) {
  EmitVFPsss(cond, B6, sd, sn, sm);
}


void Thumb2Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
                            Condition cond) {
  EmitVFPddd(cond, B6, dd, dn, dm);
}


void Thumb2Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
                            Condition cond) {
  EmitVFPsss(cond, B23, sd, sn, sm);
}


void Thumb2Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
                            Condition cond) {
  EmitVFPddd(cond, B23, dd, dn, dm);
}


void Thumb2Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
}


void Thumb2Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
  EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
}


void Thumb2Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
}


void Thumb2Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
}


void Thumb2Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
}

void Thumb2Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
}


void Thumb2Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
  EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
}


void Thumb2Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
  EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
}


void Thumb2Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
}


void Thumb2Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
}


void Thumb2Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
}


void Thumb2Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
}


void Thumb2Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
}


void Thumb2Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
}


void Thumb2Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
}


void Thumb2Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
}


void Thumb2Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
}


void Thumb2Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
}


void Thumb2Assembler::vcmpsz(SRegister sd, Condition cond) {
  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
}


void Thumb2Assembler::vcmpdz(DRegister dd, Condition cond) {
  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
}

void Thumb2Assembler::b(Label* label, Condition cond) {
  DCHECK_EQ(next_condition_, AL);
  EmitBranch(cond, label, false, false);
}


void Thumb2Assembler::bl(Label* label, Condition cond) {
  CheckCondition(cond);
  EmitBranch(cond, label, true, false);
}


void Thumb2Assembler::blx(Label* label) {
  EmitBranch(AL, label, true, true);
}


void Thumb2Assembler::MarkExceptionHandler(Label* label) {
  EmitDataProcessing(AL, TST, kCcSet, PC, R0, ShifterOperand(0));
  Label l;
  b(&l);
  EmitBranch(AL, label, false, false);
  Bind(&l);
}


void Thumb2Assembler::Emit32(int32_t value) {
  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
  buffer_.Emit<int16_t>(value >> 16);
  buffer_.Emit<int16_t>(value & 0xffff);
}


void Thumb2Assembler::Emit16(int16_t value) {
  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
  buffer_.Emit<int16_t>(value);
}


bool Thumb2Assembler::Is32BitDataProcessing(Condition cond,
                                            Opcode opcode,
                                            SetCc set_cc,
                                            Register rn,
                                            Register rd,
                                            const ShifterOperand& so) {
  if (force_32bit_) {
    return true;
  }

  // Check special case for SP relative ADD and SUB immediate.
  if ((opcode == ADD || opcode == SUB) && rn == SP && so.IsImmediate() && set_cc != kCcSet) {
    // If the immediate is in range, use 16 bit.
    if (rd == SP) {
      if (so.GetImmediate() < (1 << 9)) {    // 9 bit immediate.
        return false;
      }
    } else if (!IsHighRegister(rd) && opcode == ADD) {
      if (so.GetImmediate() < (1 << 10)) {    // 10 bit immediate.
        return false;
      }
    }
  }

  bool can_contain_high_register =
      (opcode == CMP) ||
      (opcode == MOV && set_cc != kCcSet) ||
      ((opcode == ADD) && (rn == rd) && set_cc != kCcSet);

  if (IsHighRegister(rd) || IsHighRegister(rn)) {
    if (!can_contain_high_register) {
      return true;
    }

    // There are high register instructions available for this opcode.
    // However, there is no actual shift available, neither for ADD nor for MOV (ASR/LSR/LSL/ROR).
    if (so.IsShift() && (so.GetShift() == RRX || so.GetImmediate() != 0u)) {
      return true;
    }

    // The ADD and MOV instructions that work with high registers don't have 16-bit
    // immediate variants.
    if (so.IsImmediate()) {
      return true;
    }
  }

  if (so.IsRegister() && IsHighRegister(so.GetRegister()) && !can_contain_high_register) {
    return true;
  }

  bool rn_is_valid = true;

  // Check for single operand instructions and ADD/SUB.
  switch (opcode) {
    case CMP:
    case MOV:
    case TST:
    case MVN:
      rn_is_valid = false;      // There is no Rn for these instructions.
      break;
    case TEQ:
    case ORN:
      return true;
    case ADD:
    case SUB:
      break;
    default:
      if (so.IsRegister() && rd != rn) {
        return true;
      }
  }

  if (so.IsImmediate()) {
    if (opcode == RSB) {
      DCHECK(rn_is_valid);
      if (so.GetImmediate() != 0u) {
        return true;
      }
    } else if (rn_is_valid && rn != rd) {
      // The only thumb1 instructions with a register and an immediate are ADD and SUB
      // with a 3-bit immediate, and RSB with zero immediate.
      if (opcode == ADD || opcode == SUB) {
        if ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet) {
          return true;  // Cannot match "setflags".
        }
        if (!IsUint<3>(so.GetImmediate()) && !IsUint<3>(-so.GetImmediate())) {
          return true;
        }
      } else {
        return true;
      }
    } else {
      // ADD, SUB, CMP and MOV may be thumb1 only if the immediate is 8 bits.
      if (!(opcode == ADD || opcode == SUB || opcode == MOV || opcode == CMP)) {
        return true;
      } else if (opcode != CMP && ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet)) {
        return true;  // Cannot match "setflags" for ADD, SUB or MOV.
      } else {
        // For ADD and SUB allow also negative 8-bit immediate as we will emit the oposite opcode.
        if (!IsUint<8>(so.GetImmediate()) &&
            (opcode == MOV || opcode == CMP || !IsUint<8>(-so.GetImmediate()))) {
          return true;
        }
      }
    }
  } else {
    DCHECK(so.IsRegister());
    if (so.IsShift()) {
      // Shift operand - check if it is a MOV convertible to a 16-bit shift instruction.
      if (opcode != MOV) {
        return true;
      }
      // Check for MOV with an ROR/RRX. There is no 16-bit ROR immediate and no 16-bit RRX.
      if (so.GetShift() == ROR || so.GetShift() == RRX) {
        return true;
      }
      // 16-bit shifts set condition codes if and only if outside IT block,
      // i.e. if and only if cond == AL.
      if ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet) {
        return true;
      }
    } else {
      // Register operand without shift.
      switch (opcode) {
        case ADD:
          // The 16-bit ADD that cannot contain high registers can set condition codes
          // if and only if outside IT block, i.e. if and only if cond == AL.
          if (!can_contain_high_register &&
              ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet)) {
            return true;
          }
          break;
        case AND:
        case BIC:
        case EOR:
        case ORR:
        case MVN:
        case ADC:
        case SUB:
        case SBC:
          // These 16-bit opcodes set condition codes if and only if outside IT block,
          // i.e. if and only if cond == AL.
          if ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet) {
            return true;
          }
          break;
        case RSB:
        case RSC:
          // No 16-bit RSB/RSC Rd, Rm, Rn. It would be equivalent to SUB/SBC Rd, Rn, Rm.
          return true;
        case CMP:
        default:
          break;
      }
    }
  }

  // The instruction can be encoded in 16 bits.
  return false;
}


void Thumb2Assembler::Emit32BitDataProcessing(Condition cond ATTRIBUTE_UNUSED,
                                              Opcode opcode,
                                              SetCc set_cc,
                                              Register rn,
                                              Register rd,
                                              const ShifterOperand& so) {
  uint8_t thumb_opcode = 255U /* 0b11111111 */;
  switch (opcode) {
    case AND: thumb_opcode =  0U /* 0b0000 */; break;
    case EOR: thumb_opcode =  4U /* 0b0100 */; break;
    case SUB: thumb_opcode = 13U /* 0b1101 */; break;
    case RSB: thumb_opcode = 14U /* 0b1110 */; break;
    case ADD: thumb_opcode =  8U /* 0b1000 */; break;
    case ADC: thumb_opcode = 10U /* 0b1010 */; break;
    case SBC: thumb_opcode = 11U /* 0b1011 */; break;
    case RSC: break;
    case TST: thumb_opcode =  0U /* 0b0000 */; DCHECK(set_cc == kCcSet); rd = PC; break;
    case TEQ: thumb_opcode =  4U /* 0b0100 */; DCHECK(set_cc == kCcSet); rd = PC; break;
    case CMP: thumb_opcode = 13U /* 0b1101 */; DCHECK(set_cc == kCcSet); rd = PC; break;
    case CMN: thumb_opcode =  8U /* 0b1000 */; DCHECK(set_cc == kCcSet); rd = PC; break;
    case ORR: thumb_opcode =  2U /* 0b0010 */; break;
    case MOV: thumb_opcode =  2U /* 0b0010 */; rn = PC; break;
    case BIC: thumb_opcode =  1U /* 0b0001 */; break;
    case MVN: thumb_opcode =  3U /* 0b0011 */; rn = PC; break;
    case ORN: thumb_opcode =  3U /* 0b0011 */; break;
    default:
      break;
  }

  if (thumb_opcode == 255U /* 0b11111111 */) {
    LOG(FATAL) << "Invalid thumb2 opcode " << opcode;
    UNREACHABLE();
  }

  int32_t encoding = 0;
  if (so.IsImmediate()) {
    // Check special cases.
    if ((opcode == SUB || opcode == ADD) && (so.GetImmediate() < (1u << 12)) &&
        /* Prefer T3 encoding to T4. */ !ShifterOperandCanAlwaysHold(so.GetImmediate())) {
      if (set_cc != kCcSet) {
        if (opcode == SUB) {
          thumb_opcode = 5U;
        } else if (opcode == ADD) {
          thumb_opcode = 0U;
        }
      }
      uint32_t imm = so.GetImmediate();

      uint32_t i = (imm >> 11) & 1;
      uint32_t imm3 = (imm >> 8) & 7U /* 0b111 */;
      uint32_t imm8 = imm & 0xff;

      encoding = B31 | B30 | B29 | B28 |
          (set_cc == kCcSet ? B20 : B25) |
          thumb_opcode << 21 |
          rn << 16 |
          rd << 8 |
          i << 26 |
          imm3 << 12 |
          imm8;
    } else {
      // Modified immediate.
      uint32_t imm = ModifiedImmediate(so.encodingThumb());
      if (imm == kInvalidModifiedImmediate) {
        LOG(FATAL) << "Immediate value cannot fit in thumb2 modified immediate";
        UNREACHABLE();
      }
      encoding = B31 | B30 | B29 | B28 |
          thumb_opcode << 21 |
          (set_cc == kCcSet ? B20 : 0) |
          rn << 16 |
          rd << 8 |
          imm;
    }
  } else if (so.IsRegister()) {
    // Register (possibly shifted)
    encoding = B31 | B30 | B29 | B27 | B25 |
        thumb_opcode << 21 |
        (set_cc == kCcSet ? B20 : 0) |
        rn << 16 |
        rd << 8 |
        so.encodingThumb();
  }
  Emit32(encoding);
}


void Thumb2Assembler::Emit16BitDataProcessing(Condition cond,
                                              Opcode opcode,
                                              SetCc set_cc,
                                              Register rn,
                                              Register rd,
                                              const ShifterOperand& so) {
  if (opcode == ADD || opcode == SUB) {
    Emit16BitAddSub(cond, opcode, set_cc, rn, rd, so);
    return;
  }
  uint8_t thumb_opcode = 255U /* 0b11111111 */;
  // Thumb1.
  uint8_t dp_opcode = 1U /* 0b01 */;
  uint8_t opcode_shift = 6;
  uint8_t rd_shift = 0;
  uint8_t rn_shift = 3;
  uint8_t immediate_shift = 0;
  bool use_immediate = false;
  uint8_t immediate = 0;

  if (opcode == MOV && so.IsRegister() && so.IsShift()) {
    // Convert shifted mov operand2 into 16 bit opcodes.
    dp_opcode = 0;
    opcode_shift = 11;

    use_immediate = true;
    immediate = so.GetImmediate();
    immediate_shift = 6;

    rn = so.GetRegister();

    switch (so.GetShift()) {
    case LSL:
      DCHECK_LE(immediate, 31u);
      thumb_opcode = 0U /* 0b00 */;
      break;
    case LSR:
      DCHECK(1 <= immediate && immediate <= 32);
      immediate &= 31;  // 32 is encoded as 0.
      thumb_opcode = 1U /* 0b01 */;
      break;
    case ASR:
      DCHECK(1 <= immediate && immediate <= 32);
      immediate &= 31;  // 32 is encoded as 0.
      thumb_opcode = 2U /* 0b10 */;
      break;
    case ROR:  // No 16-bit ROR immediate.
    case RRX:  // No 16-bit RRX.
    default:
      LOG(FATAL) << "Unexpected shift: " << so.GetShift();
      UNREACHABLE();
    }
  } else {
    if (so.IsImmediate()) {
      use_immediate = true;
      immediate = so.GetImmediate();
    } else {
      CHECK(!(so.IsRegister() && so.IsShift() && so.GetSecondRegister() != kNoRegister))
          << "No register-shifted register instruction available in thumb";
      // Adjust rn and rd: only two registers will be emitted.
      switch (opcode) {
        case AND:
        case ORR:
        case EOR:
        case RSB:
        case ADC:
        case SBC:
        case BIC: {
          // Sets condition codes if and only if outside IT block,
          // check that it complies with set_cc.
          DCHECK((cond == AL) ? set_cc != kCcKeep : set_cc != kCcSet);
          if (rn == rd) {
            rn = so.GetRegister();
          } else {
            CHECK_EQ(rd, so.GetRegister());
          }
          break;
        }
        case CMP:
        case CMN: {
          CHECK_EQ(rd, 0);
          rd = rn;
          rn = so.GetRegister();
          break;
        }
        case MVN: {
          // Sets condition codes if and only if outside IT block,
          // check that it complies with set_cc.
          DCHECK((cond == AL) ? set_cc != kCcKeep : set_cc != kCcSet);
          CHECK_EQ(rn, 0);
          rn = so.GetRegister();
          break;
        }
        case TST:
        case TEQ: {
          DCHECK(set_cc == kCcSet);
          CHECK_EQ(rn, 0);
          rn = so.GetRegister();
          break;
        }
        default:
          break;
      }
    }

    switch (opcode) {
      case AND: thumb_opcode = 0U /* 0b0000 */; break;
      case ORR: thumb_opcode = 12U /* 0b1100 */; break;
      case EOR: thumb_opcode = 1U /* 0b0001 */; break;
      case RSB: thumb_opcode = 9U /* 0b1001 */; break;
      case ADC: thumb_opcode = 5U /* 0b0101 */; break;
      case SBC: thumb_opcode = 6U /* 0b0110 */; break;
      case BIC: thumb_opcode = 14U /* 0b1110 */; break;
      case TST: thumb_opcode = 8U /* 0b1000 */; CHECK(!use_immediate); break;
      case MVN: thumb_opcode = 15U /* 0b1111 */; CHECK(!use_immediate); break;
      case CMP: {
        DCHECK(set_cc == kCcSet);
        if (use_immediate) {
          // T2 encoding.
          dp_opcode = 0;
          opcode_shift = 11;
          thumb_opcode = 5U /* 0b101 */;
          rd_shift = 8;
          rn_shift = 8;
        } else if (IsHighRegister(rd) || IsHighRegister(rn)) {
          // Special cmp for high registers.
          dp_opcode = 1U /* 0b01 */;
          opcode_shift = 7;
          // Put the top bit of rd into the bottom bit of the opcode.
          thumb_opcode = 10U /* 0b0001010 */ | static_cast<uint32_t>(rd) >> 3;
          rd = static_cast<Register>(static_cast<uint32_t>(rd) & 7U /* 0b111 */);
        } else {
          thumb_opcode = 10U /* 0b1010 */;
        }

        break;
      }
      case CMN: {
        CHECK(!use_immediate);
        thumb_opcode = 11U /* 0b1011 */;
        break;
      }
      case MOV:
        dp_opcode = 0;
        if (use_immediate) {
          // T2 encoding.
          opcode_shift = 11;
          thumb_opcode = 4U /* 0b100 */;
          rd_shift = 8;
          rn_shift = 8;
        } else {
          rn = so.GetRegister();
          if (set_cc != kCcSet) {
            // Special mov for high registers.
            dp_opcode = 1U /* 0b01 */;
            opcode_shift = 7;
            // Put the top bit of rd into the bottom bit of the opcode.
            thumb_opcode = 12U /* 0b0001100 */ | static_cast<uint32_t>(rd) >> 3;
            rd = static_cast<Register>(static_cast<uint32_t>(rd) & 7U /* 0b111 */);
          } else {
            DCHECK(!IsHighRegister(rn));
            DCHECK(!IsHighRegister(rd));
            thumb_opcode = 0;
          }
        }
        break;

      case TEQ:
      case RSC:
      default:
        LOG(FATAL) << "Invalid thumb1 opcode " << opcode;
        break;
    }
  }

  if (thumb_opcode == 255U /* 0b11111111 */) {
    LOG(FATAL) << "Invalid thumb1 opcode " << opcode;
    UNREACHABLE();
  }

  int16_t encoding = dp_opcode << 14 |
      (thumb_opcode << opcode_shift) |
      rd << rd_shift |
      rn << rn_shift |
      (use_immediate ? (immediate << immediate_shift) : 0);

  Emit16(encoding);
}


// ADD and SUB are complex enough to warrant their own emitter.
void Thumb2Assembler::Emit16BitAddSub(Condition cond,
                                      Opcode opcode,
                                      SetCc set_cc,
                                      Register rn,
                                      Register rd,
                                      const ShifterOperand& so) {
  uint8_t dp_opcode = 0;
  uint8_t opcode_shift = 6;
  uint8_t rd_shift = 0;
  uint8_t rn_shift = 3;
  uint8_t immediate_shift = 0;
  bool use_immediate = false;
  uint32_t immediate = 0;  // Should be at most 10 bits but keep the full immediate for CHECKs.
  uint8_t thumb_opcode;

  if (so.IsImmediate()) {
    use_immediate = true;
    immediate = so.GetImmediate();
    if (!IsUint<10>(immediate)) {
      // Flip ADD/SUB.
      opcode = (opcode == ADD) ? SUB : ADD;
      immediate = -immediate;
      DCHECK(IsUint<10>(immediate));  // More stringent checks below.
    }
  }

  switch (opcode) {
    case ADD:
      if (so.IsRegister()) {
        Register rm = so.GetRegister();
        if (rn == rd && set_cc != kCcSet) {
          // Can use T2 encoding (allows 4 bit registers)
          dp_opcode = 1U /* 0b01 */;
          opcode_shift = 10;
          thumb_opcode = 1U /* 0b0001 */;
          // Make Rn also contain the top bit of rd.
          rn = static_cast<Register>(static_cast<uint32_t>(rm) |
                                     (static_cast<uint32_t>(rd) & 8U /* 0b1000 */) << 1);
          rd = static_cast<Register>(static_cast<uint32_t>(rd) & 7U /* 0b111 */);
        } else {
          // T1.
          DCHECK(!IsHighRegister(rd));
          DCHECK(!IsHighRegister(rn));
          DCHECK(!IsHighRegister(rm));
          // Sets condition codes if and only if outside IT block,
          // check that it complies with set_cc.
          DCHECK((cond == AL) ? set_cc != kCcKeep : set_cc != kCcSet);
          opcode_shift = 9;
          thumb_opcode = 12U /* 0b01100 */;
          immediate = static_cast<uint32_t>(so.GetRegister());
          use_immediate = true;
          immediate_shift = 6;
        }
      } else {
        // Immediate.
        if (rd == SP && rn == SP) {
          // ADD sp, sp, #imm
          dp_opcode = 2U /* 0b10 */;
          thumb_opcode = 3U /* 0b11 */;
          opcode_shift = 12;
          CHECK(IsUint<9>(immediate));
          CHECK_ALIGNED(immediate, 4);

          // Remove rd and rn from instruction by orring it with immed and clearing bits.
          rn = R0;
          rd = R0;
          rd_shift = 0;
          rn_shift = 0;
          immediate >>= 2;
        } else if (rd != SP && rn == SP) {
          // ADD rd, SP, #imm
          dp_opcode = 2U /* 0b10 */;
          thumb_opcode = 5U /* 0b101 */;
          opcode_shift = 11;
          CHECK(IsUint<10>(immediate));
          CHECK_ALIGNED(immediate, 4);

          // Remove rn from instruction.
          rn = R0;
          rn_shift = 0;
          rd_shift = 8;
          immediate >>= 2;
        } else if (rn != rd) {
          // Must use T1.
          CHECK(IsUint<3>(immediate));
          opcode_shift = 9;
          thumb_opcode = 14U /* 0b01110 */;
          immediate_shift = 6;
        } else {
          // T2 encoding.
          CHECK(IsUint<8>(immediate));
          opcode_shift = 11;
          thumb_opcode = 6U /* 0b110 */;
          rd_shift = 8;
          rn_shift = 8;
        }
      }
      break;

    case SUB:
      if (so.IsRegister()) {
        // T1.
        Register rm = so.GetRegister();
        DCHECK(!IsHighRegister(rd));
        DCHECK(!IsHighRegister(rn));
        DCHECK(!IsHighRegister(rm));
        // Sets condition codes if and only if outside IT block,
        // check that it complies with set_cc.
        DCHECK((cond == AL) ? set_cc != kCcKeep : set_cc != kCcSet);
        opcode_shift = 9;
        thumb_opcode = 13U /* 0b01101 */;
        immediate = static_cast<uint32_t>(rm);
        use_immediate = true;
        immediate_shift = 6;
      } else {
        if (rd == SP && rn == SP) {
          // SUB sp, sp, #imm
          dp_opcode = 2U /* 0b10 */;
          thumb_opcode = 0x61 /* 0b1100001 */;
          opcode_shift = 7;
          CHECK(IsUint<9>(immediate));
          CHECK_ALIGNED(immediate, 4);

          // Remove rd and rn from instruction by orring it with immed and clearing bits.
          rn = R0;
          rd = R0;
          rd_shift = 0;
          rn_shift = 0;
          immediate >>= 2;
        } else if (rn != rd) {
          // Must use T1.
          CHECK(IsUint<3>(immediate));
          opcode_shift = 9;
          thumb_opcode = 15U /* 0b01111 */;
          immediate_shift = 6;
        } else {
          // T2 encoding.
          CHECK(IsUint<8>(immediate));
          opcode_shift = 11;
          thumb_opcode = 7U /* 0b111 */;
          rd_shift = 8;
          rn_shift = 8;
        }
      }
      break;
    default:
      LOG(FATAL) << "This opcode is not an ADD or SUB: " << opcode;
      UNREACHABLE();
  }

  int16_t encoding = dp_opcode << 14 |
      (thumb_opcode << opcode_shift) |
      rd << rd_shift |
      rn << rn_shift |
      (use_immediate ? (immediate << immediate_shift) : 0);

  Emit16(encoding);
}


void Thumb2Assembler::EmitDataProcessing(Condition cond,
                                         Opcode opcode,
                                         SetCc set_cc,
                                         Register rn,
                                         Register rd,
                                         const ShifterOperand& so) {
  CHECK_NE(rd, kNoRegister);
  CheckCondition(cond);

  if (Is32BitDataProcessing(cond, opcode, set_cc, rn, rd, so)) {
    Emit32BitDataProcessing(cond, opcode, set_cc, rn, rd, so);
  } else {
    Emit16BitDataProcessing(cond, opcode, set_cc, rn, rd, so);
  }
}

void Thumb2Assembler::EmitShift(Register rd,
                                Register rm,
                                Shift shift,
                                uint8_t amount,
                                Condition cond,
                                SetCc set_cc) {
  CHECK_LT(amount, (1 << 5));
  if ((IsHighRegister(rd) || IsHighRegister(rm) || shift == ROR || shift == RRX) ||
      ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet)) {
    uint16_t opcode = 0;
    switch (shift) {
      case LSL: opcode = 0U /* 0b00 */; break;
      case LSR: opcode = 1U /* 0b01 */; break;
      case ASR: opcode = 2U /* 0b10 */; break;
      case ROR: opcode = 3U /* 0b11 */; break;
      case RRX: opcode = 3U /* 0b11 */; amount = 0; break;
      default:
        LOG(FATAL) << "Unsupported thumb2 shift opcode";
        UNREACHABLE();
    }
    // 32 bit.
    int32_t encoding = B31 | B30 | B29 | B27 | B25 | B22 |
        0xf << 16 | (set_cc == kCcSet ? B20 : 0);
    uint32_t imm3 = amount >> 2;
    uint32_t imm2 = amount & 3U /* 0b11 */;
    encoding |= imm3 << 12 | imm2 << 6 | static_cast<int16_t>(rm) |
        static_cast<int16_t>(rd) << 8 | opcode << 4;
    Emit32(encoding);
  } else {
    // 16 bit shift
    uint16_t opcode = 0;
    switch (shift) {
      case LSL: opcode = 0U /* 0b00 */; break;
      case LSR: opcode = 1U /* 0b01 */; break;
      case ASR: opcode = 2U /* 0b10 */; break;
      default:
        LOG(FATAL) << "Unsupported thumb2 shift opcode";
        UNREACHABLE();
    }
    int16_t encoding = opcode << 11 | amount << 6 | static_cast<int16_t>(rm) << 3 |
        static_cast<int16_t>(rd);
    Emit16(encoding);
  }
}

void Thumb2Assembler::EmitShift(Register rd,
                                Register rn,
                                Shift shift,
                                Register rm,
                                Condition cond,
                                SetCc set_cc) {
  CHECK_NE(shift, RRX);
  bool must_be_32bit = false;
  if (IsHighRegister(rd) || IsHighRegister(rm) || IsHighRegister(rn) || rd != rn ||
      ((cond == AL) ? set_cc == kCcKeep : set_cc == kCcSet)) {
    must_be_32bit = true;
  }

  if (must_be_32bit) {
    uint16_t opcode = 0;
     switch (shift) {
       case LSL: opcode = 0U /* 0b00 */; break;
       case LSR: opcode = 1U /* 0b01 */; break;
       case ASR: opcode = 2U /* 0b10 */; break;
       case ROR: opcode = 3U /* 0b11 */; break;
       default:
         LOG(FATAL) << "Unsupported thumb2 shift opcode";
         UNREACHABLE();
     }
     // 32 bit.
     int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 |
         0xf << 12 | (set_cc == kCcSet ? B20 : 0);
     encoding |= static_cast<int16_t>(rn) << 16 | static_cast<int16_t>(rm) |
         static_cast<int16_t>(rd) << 8 | opcode << 21;
     Emit32(encoding);
  } else {
    uint16_t opcode = 0;
    switch (shift) {
      case LSL: opcode = 2U /* 0b0010 */; break;
      case LSR: opcode = 3U /* 0b0011 */; break;
      case ASR: opcode = 4U /* 0b0100 */; break;
      case ROR: opcode = 7U /* 0b0111 */; break;
      default:
        LOG(FATAL) << "Unsupported thumb2 shift opcode";
        UNREACHABLE();
    }
    int16_t encoding = B14 | opcode << 6 | static_cast<int16_t>(rm) << 3 |
        static_cast<int16_t>(rd);
    Emit16(encoding);
  }
}

inline size_t Thumb2Assembler::Fixup::SizeInBytes(Size size) {
  switch (size) {
    case kBranch16Bit:
      return 2u;
    case kBranch32Bit:
      return 4u;

    case kCbxz16Bit:
      return 2u;
    case kCbxz32Bit:
      return 4u;
    case kCbxz48Bit:
      return 6u;

    case kLiteral1KiB:
      return 2u;
    case kLiteral4KiB:
      return 4u;
    case kLiteral64KiB:
      return 8u;
    case kLiteral1MiB:
      return 10u;
    case kLiteralFar:
      return 14u;

    case kLiteralAddr1KiB:
      return 2u;
    case kLiteralAddr4KiB:
      return 4u;
    case kLiteralAddr64KiB:
      return 6u;
    case kLiteralAddrFar:
      return 10u;

    case kLongOrFPLiteral1KiB:
      return 4u;
    case kLongOrFPLiteral256KiB:
      return 10u;
    case kLongOrFPLiteralFar:
      return 14u;
  }
  LOG(FATAL) << "Unexpected size: " << static_cast<int>(size);
  UNREACHABLE();
}

inline uint32_t Thumb2Assembler::Fixup::GetOriginalSizeInBytes() const {
  return SizeInBytes(original_size_);
}

inline uint32_t Thumb2Assembler::Fixup::GetSizeInBytes() const {
  return SizeInBytes(size_);
}

inline size_t Thumb2Assembler::Fixup::LiteralPoolPaddingSize(uint32_t current_code_size) {
  // The code size must be a multiple of 2.
  DCHECK_ALIGNED(current_code_size, 2);
  // If it isn't a multiple of 4, we need to add a 2-byte padding before the literal pool.
  return current_code_size & 2;
}

inline int32_t Thumb2Assembler::Fixup::GetOffset(uint32_t current_code_size) const {
  static constexpr int32_t int32_min = std::numeric_limits<int32_t>::min();
  static constexpr int32_t int32_max = std::numeric_limits<int32_t>::max();
  DCHECK_LE(target_, static_cast<uint32_t>(int32_max));
  DCHECK_LE(location_, static_cast<uint32_t>(int32_max));
  DCHECK_LE(adjustment_, static_cast<uint32_t>(int32_max));
  int32_t diff = static_cast<int32_t>(target_) - static_cast<int32_t>(location_);
  if (target_ > location_) {
    DCHECK_LE(adjustment_, static_cast<uint32_t>(int32_max - diff));
    diff += static_cast<int32_t>(adjustment_);
  } else {
    DCHECK_LE(int32_min + static_cast<int32_t>(adjustment_), diff);
    diff -= static_cast<int32_t>(adjustment_);
  }
  // The default PC adjustment for Thumb2 is 4 bytes.
  DCHECK_GE(diff, int32_min + 4);
  diff -= 4;
  // Add additional adjustment for instructions preceding the PC usage, padding
  // before the literal pool and rounding down the PC for literal loads.
  switch (GetSize()) {
    case kBranch16Bit:
    case kBranch32Bit:
      break;

    case kCbxz16Bit:
      break;
    case kCbxz32Bit:
    case kCbxz48Bit:
      DCHECK_GE(diff, int32_min + 2);
      diff -= 2;        // Extra CMP Rn, #0, 16-bit.
      break;

    case kLiteral1KiB:
    case kLiteral4KiB:
    case kLongOrFPLiteral1KiB:
    case kLiteralAddr1KiB:
    case kLiteralAddr4KiB:
      DCHECK(diff >= 0 || (GetSize() == kLiteral1KiB && diff == -2));
      diff += LiteralPoolPaddingSize(current_code_size);
      // Load literal instructions round down the PC+4 to a multiple of 4, so if the PC
      // isn't a multiple of 2, we need to adjust. Since we already adjusted for the target
      // being aligned, current PC alignment can be inferred from diff.
      DCHECK_ALIGNED(diff, 2);
      diff = diff + (diff & 2);
      DCHECK_GE(diff, 0);
      break;
    case kLiteral1MiB:
    case kLiteral64KiB:
    case kLongOrFPLiteral256KiB:
    case kLiteralAddr64KiB:
      DCHECK_GE(diff, 4);  // The target must be at least 4 bytes after the ADD rX, PC.
      diff -= 4;        // One extra 32-bit MOV.
      diff += LiteralPoolPaddingSize(current_code_size);
      break;
    case kLiteralFar:
    case kLongOrFPLiteralFar:
    case kLiteralAddrFar:
      DCHECK_GE(diff, 8);  // The target must be at least 4 bytes after the ADD rX, PC.
      diff -= 8;        // Extra MOVW+MOVT; both 32-bit.
      diff += LiteralPoolPaddingSize(current_code_size);
      break;
  }
  return diff;
}

inline size_t Thumb2Assembler::Fixup::IncreaseSize(Size new_size) {
  DCHECK_NE(target_, kUnresolved);
  Size old_size = size_;
  size_ = new_size;
  DCHECK_GT(SizeInBytes(new_size), SizeInBytes(old_size));
  size_t adjustment = SizeInBytes(new_size) - SizeInBytes(old_size);
  if (target_ > location_) {
    adjustment_ += adjustment;
  }
  return adjustment;
}

uint32_t Thumb2Assembler::Fixup::AdjustSizeIfNeeded(uint32_t current_code_size) {
  uint32_t old_code_size = current_code_size;
  switch (GetSize()) {
    case kBranch16Bit:
      if (IsInt(cond_ != AL ? 9 : 12, GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kBranch32Bit);
      FALLTHROUGH_INTENDED;
    case kBranch32Bit:
      // We don't support conditional branches beyond +-1MiB
      // or unconditional branches beyond +-16MiB.
      break;

    case kCbxz16Bit:
      if (IsUint<7>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kCbxz32Bit);
      FALLTHROUGH_INTENDED;
    case kCbxz32Bit:
      if (IsInt<9>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kCbxz48Bit);
      FALLTHROUGH_INTENDED;
    case kCbxz48Bit:
      // We don't support conditional branches beyond +-1MiB.
      break;

    case kLiteral1KiB:
      DCHECK(!IsHighRegister(rn_));
      if (IsUint<10>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLiteral4KiB);
      FALLTHROUGH_INTENDED;
    case kLiteral4KiB:
      if (IsUint<12>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLiteral64KiB);
      FALLTHROUGH_INTENDED;
    case kLiteral64KiB:
      // Can't handle high register which we can encounter by fall-through from kLiteral4KiB.
      if (!IsHighRegister(rn_) && IsUint<16>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLiteral1MiB);
      FALLTHROUGH_INTENDED;
    case kLiteral1MiB:
      if (IsUint<20>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLiteralFar);
      FALLTHROUGH_INTENDED;
    case kLiteralFar:
      // This encoding can reach any target.
      break;

    case kLiteralAddr1KiB:
      DCHECK(!IsHighRegister(rn_));
      if (IsUint<10>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLiteralAddr4KiB);
      FALLTHROUGH_INTENDED;
    case kLiteralAddr4KiB:
      if (IsUint<12>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLiteralAddr64KiB);
      FALLTHROUGH_INTENDED;
    case kLiteralAddr64KiB:
      if (IsUint<16>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLiteralAddrFar);
      FALLTHROUGH_INTENDED;
    case kLiteralAddrFar:
      // This encoding can reach any target.
      break;

    case kLongOrFPLiteral1KiB:
      if (IsUint<10>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLongOrFPLiteral256KiB);
      FALLTHROUGH_INTENDED;
    case kLongOrFPLiteral256KiB:
      if (IsUint<18>(GetOffset(current_code_size))) {
        break;
      }
      current_code_size += IncreaseSize(kLongOrFPLiteralFar);
      FALLTHROUGH_INTENDED;
    case kLongOrFPLiteralFar:
      // This encoding can reach any target.
      break;
  }
  return current_code_size - old_code_size;
}

void Thumb2Assembler::Fixup::Emit(AssemblerBuffer* buffer, uint32_t code_size) const {
  switch (GetSize()) {
    case kBranch16Bit: {
      DCHECK(type_ == kUnconditional || type_ == kConditional);
      DCHECK_EQ(type_ == kConditional, cond_ != AL);
      int16_t encoding = BEncoding16(GetOffset(code_size), cond_);
      buffer->Store<int16_t>(location_, encoding);
      break;
    }
    case kBranch32Bit: {
      DCHECK(type_ == kConditional || type_ == kUnconditional ||
             type_ == kUnconditionalLink || type_ == kUnconditionalLinkX);
      DCHECK_EQ(type_ == kConditional, cond_ != AL);
      int32_t encoding = BEncoding32(GetOffset(code_size), cond_);
      if (type_ == kUnconditionalLink) {
        DCHECK_NE(encoding & B12, 0);
        encoding |= B14;
      } else if (type_ == kUnconditionalLinkX) {
        DCHECK_NE(encoding & B12, 0);
        encoding ^= B14 | B12;
      }
      buffer->Store<int16_t>(location_, encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(encoding & 0xffff));
      break;
    }

    case kCbxz16Bit: {
      DCHECK(type_ == kCompareAndBranchXZero);
      int16_t encoding = CbxzEncoding16(rn_, GetOffset(code_size), cond_);
      buffer->Store<int16_t>(location_, encoding);
      break;
    }
    case kCbxz32Bit: {
      DCHECK(type_ == kCompareAndBranchXZero);
      DCHECK(cond_ == EQ || cond_ == NE);
      int16_t cmp_encoding = CmpRnImm8Encoding16(rn_, 0);
      int16_t b_encoding = BEncoding16(GetOffset(code_size), cond_);
      buffer->Store<int16_t>(location_, cmp_encoding);
      buffer->Store<int16_t>(location_ + 2, b_encoding);
      break;
    }
    case kCbxz48Bit: {
      DCHECK(type_ == kCompareAndBranchXZero);
      DCHECK(cond_ == EQ || cond_ == NE);
      int16_t cmp_encoding = CmpRnImm8Encoding16(rn_, 0);
      int32_t b_encoding = BEncoding32(GetOffset(code_size), cond_);
      buffer->Store<int16_t>(location_, cmp_encoding);
      buffer->Store<int16_t>(location_ + 2u, b_encoding >> 16);
      buffer->Store<int16_t>(location_ + 4u, static_cast<int16_t>(b_encoding & 0xffff));
      break;
    }

    case kLiteral1KiB: {
      DCHECK(type_ == kLoadLiteralNarrow);
      int16_t encoding = LdrLitEncoding16(rn_, GetOffset(code_size));
      buffer->Store<int16_t>(location_, encoding);
      break;
    }
    case kLiteral4KiB: {
      DCHECK(type_ == kLoadLiteralNarrow);
      // GetOffset() uses PC+4 but load literal uses AlignDown(PC+4, 4). Adjust offset accordingly.
      int32_t encoding = LdrLitEncoding32(rn_, GetOffset(code_size));
      buffer->Store<int16_t>(location_, encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(encoding & 0xffff));
      break;
    }
    case kLiteral64KiB: {
      DCHECK(type_ == kLoadLiteralNarrow);
      int32_t mov_encoding = MovwEncoding32(rn_, GetOffset(code_size));
      int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC);
      int16_t ldr_encoding = LdrRtRnImm5Encoding16(rn_, rn_, 0);
      buffer->Store<int16_t>(location_, mov_encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(mov_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 4u, add_pc_encoding);
      buffer->Store<int16_t>(location_ + 6u, ldr_encoding);
      break;
    }
    case kLiteral1MiB: {
      DCHECK(type_ == kLoadLiteralNarrow);
      int32_t offset = GetOffset(code_size);
      int32_t mov_encoding = MovModImmEncoding32(rn_, offset & ~0xfff);
      int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC);
      int32_t ldr_encoding = LdrRtRnImm12Encoding(rn_, rn_, offset & 0xfff);
      buffer->Store<int16_t>(location_, mov_encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(mov_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 4u, add_pc_encoding);
      buffer->Store<int16_t>(location_ + 6u, ldr_encoding >> 16);
      buffer->Store<int16_t>(location_ + 8u, static_cast<int16_t>(ldr_encoding & 0xffff));
      break;
    }
    case kLiteralFar: {
      DCHECK(type_ == kLoadLiteralNarrow);
      int32_t offset = GetOffset(code_size);
      int32_t movw_encoding = MovwEncoding32(rn_, offset & 0xffff);
      int32_t movt_encoding = MovtEncoding32(rn_, offset & ~0xffff);
      int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC);
      int32_t ldr_encoding = LdrRtRnImm12Encoding(rn_, rn_, 0);
      buffer->Store<int16_t>(location_, movw_encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(movw_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 4u, movt_encoding >> 16);
      buffer->Store<int16_t>(location_ + 6u, static_cast<int16_t>(movt_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 8u, add_pc_encoding);
      buffer->Store<int16_t>(location_ + 10u, ldr_encoding >> 16);
      buffer->Store<int16_t>(location_ + 12u, static_cast<int16_t>(ldr_encoding & 0xffff));
      break;
    }

    case kLiteralAddr1KiB: {
      DCHECK(type_ == kLoadLiteralAddr);
      int16_t encoding = AdrEncoding16(rn_, GetOffset(code_size));
      buffer->Store<int16_t>(location_, encoding);
      break;
    }
    case kLiteralAddr4KiB: {
      DCHECK(type_ == kLoadLiteralAddr);
      int32_t encoding = AdrEncoding32(rn_, GetOffset(code_size));
      buffer->Store<int16_t>(location_, encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(encoding & 0xffff));
      break;
    }
    case kLiteralAddr64KiB: {
      DCHECK(type_ == kLoadLiteralAddr);
      int32_t mov_encoding = MovwEncoding32(rn_, GetOffset(code_size));
      int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC);
      buffer->Store<int16_t>(location_, mov_encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(mov_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 4u, add_pc_encoding);
      break;
    }
    case kLiteralAddrFar: {
      DCHECK(type_ == kLoadLiteralAddr);
      int32_t offset = GetOffset(code_size);
      int32_t movw_encoding = MovwEncoding32(rn_, offset & 0xffff);
      int32_t movt_encoding = MovtEncoding32(rn_, offset & ~0xffff);
      int16_t add_pc_encoding = AddRdnRmEncoding16(rn_, PC);
      buffer->Store<int16_t>(location_, movw_encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(movw_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 4u, movt_encoding >> 16);
      buffer->Store<int16_t>(location_ + 6u, static_cast<int16_t>(movt_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 8u, add_pc_encoding);
      break;
    }

    case kLongOrFPLiteral1KiB: {
      int32_t encoding = LoadWideOrFpEncoding(PC, GetOffset(code_size));  // DCHECKs type_.
      buffer->Store<int16_t>(location_, encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(encoding & 0xffff));
      break;
    }
    case kLongOrFPLiteral256KiB: {
      int32_t offset = GetOffset(code_size);
      int32_t mov_encoding = MovModImmEncoding32(IP, offset & ~0x3ff);
      int16_t add_pc_encoding = AddRdnRmEncoding16(IP, PC);
      int32_t ldr_encoding = LoadWideOrFpEncoding(IP, offset & 0x3ff);    // DCHECKs type_.
      buffer->Store<int16_t>(location_, mov_encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(mov_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 4u, add_pc_encoding);
      buffer->Store<int16_t>(location_ + 6u, ldr_encoding >> 16);
      buffer->Store<int16_t>(location_ + 8u, static_cast<int16_t>(ldr_encoding & 0xffff));
      break;
    }
    case kLongOrFPLiteralFar: {
      int32_t offset = GetOffset(code_size);
      int32_t movw_encoding = MovwEncoding32(IP, offset & 0xffff);
      int32_t movt_encoding = MovtEncoding32(IP, offset & ~0xffff);
      int16_t add_pc_encoding = AddRdnRmEncoding16(IP, PC);
      int32_t ldr_encoding = LoadWideOrFpEncoding(IP, 0);                 // DCHECKs type_.
      buffer->Store<int16_t>(location_, movw_encoding >> 16);
      buffer->Store<int16_t>(location_ + 2u, static_cast<int16_t>(movw_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 4u, movt_encoding >> 16);
      buffer->Store<int16_t>(location_ + 6u, static_cast<int16_t>(movt_encoding & 0xffff));
      buffer->Store<int16_t>(location_ + 8u, add_pc_encoding);
      buffer->Store<int16_t>(location_ + 10u, ldr_encoding >> 16);
      buffer->Store<int16_t>(location_ + 12u, static_cast<int16_t>(ldr_encoding & 0xffff));
      break;
    }
  }
}

uint16_t Thumb2Assembler::EmitCompareAndBranch(Register rn, uint16_t prev, bool n) {
  CHECK(IsLowRegister(rn));
  uint32_t location = buffer_.Size();

  // This is always unresolved as it must be a forward branch.
  Emit16(prev);      // Previous link.
  return AddFixup(Fixup::CompareAndBranch(location, rn, n ? NE : EQ));
}


// NOTE: this only support immediate offsets, not [rx,ry].
// TODO: support [rx,ry] instructions.
void Thumb2Assembler::EmitLoadStore(Condition cond,
                                    bool load,
                                    bool byte,
                                    bool half,
                                    bool is_signed,
                                    Register rd,
                                    const Address& ad) {
  CHECK_NE(rd, kNoRegister);
  CheckCondition(cond);
  bool must_be_32bit = force_32bit_;
  if (IsHighRegister(rd)) {
    must_be_32bit = true;
  }

  Register rn = ad.GetRegister();
  if (IsHighRegister(rn) && rn != SP && rn != PC) {
    must_be_32bit = true;
  }

  if (is_signed || ad.GetOffset() < 0 || ad.GetMode() != Address::Offset) {
    must_be_32bit = true;
  }

  if (ad.IsImmediate()) {
    // Immediate offset
    int32_t offset = ad.GetOffset();

    // The 16 bit SP relative instruction can only have a 10 bit offset.
    if (rn == SP && offset >= (1 << 10)) {
      must_be_32bit = true;
    }

    if (byte) {
      // 5 bit offset, no shift.
      if (offset >= (1 << 5)) {
        must_be_32bit = true;
      }
    } else if (half) {
      // 6 bit offset, shifted by 1.
      if (offset >= (1 << 6)) {
        must_be_32bit = true;
      }
    } else {
      // 7 bit offset, shifted by 2.
      if (offset >= (1 << 7)) {
        must_be_32bit = true;
      }
    }

    if (must_be_32bit) {
      int32_t encoding = B31 | B30 | B29 | B28 | B27 |
          (load ? B20 : 0) |
          (is_signed ? B24 : 0) |
          static_cast<uint32_t>(rd) << 12 |
          ad.encodingThumb(true) |
          (byte ? 0 : half ? B21 : B22);
      Emit32(encoding);
    } else {
      // 16 bit thumb1.
      uint8_t opA = 0;
      bool sp_relative = false;

      if (byte) {
        opA = 7U /* 0b0111 */;
      } else if (half) {
        opA = 8U /* 0b1000 */;
      } else {
        if (rn == SP) {
          opA = 9U /* 0b1001 */;
          sp_relative = true;
        } else {
          opA = 6U /* 0b0110 */;
        }
      }
      int16_t encoding = opA << 12 |
          (load ? B11 : 0);

      CHECK_GE(offset, 0);
      if (sp_relative) {
        // SP relative, 10 bit offset.
        CHECK_LT(offset, (1 << 10));
        CHECK_ALIGNED(offset, 4);
        encoding |= rd << 8 | offset >> 2;
      } else {
        // No SP relative.  The offset is shifted right depending on
        // the size of the load/store.
        encoding |= static_cast<uint32_t>(rd);

        if (byte) {
          // 5 bit offset, no shift.
          CHECK_LT(offset, (1 << 5));
        } else if (half) {
          // 6 bit offset, shifted by 1.
          CHECK_LT(offset, (1 << 6));
          CHECK_ALIGNED(offset, 2);
          offset >>= 1;
        } else {
          // 7 bit offset, shifted by 2.
          CHECK_LT(offset, (1 << 7));
          CHECK_ALIGNED(offset, 4);
          offset >>= 2;
        }
        encoding |= rn << 3 | offset  << 6;
      }

      Emit16(encoding);
    }
  } else {
    // Register shift.
    if (ad.GetRegister() == PC) {
       // PC relative literal encoding.
      int32_t offset = ad.GetOffset();
      if (must_be_32bit || offset < 0 || offset >= (1 << 10) || !load) {
        int32_t up = B23;
        if (offset < 0) {
          offset = -offset;
          up = 0;
        }
        CHECK_LT(offset, (1 << 12));
        int32_t encoding = 0x1f << 27 | 0xf << 16 | B22 | (load ? B20 : 0) |
            offset | up |
            static_cast<uint32_t>(rd) << 12;
        Emit32(encoding);
      } else {
        // 16 bit literal load.
        CHECK_GE(offset, 0);
        CHECK_LT(offset, (1 << 10));
        int32_t encoding = B14 | (load ? B11 : 0) | static_cast<uint32_t>(rd) << 8 | offset >> 2;
        Emit16(encoding);
      }
    } else {
      if (ad.GetShiftCount() != 0) {
        // If there is a shift count this must be 32 bit.
        must_be_32bit = true;
      } else if (IsHighRegister(ad.GetRegisterOffset())) {
        must_be_32bit = true;
      }

      if (must_be_32bit) {
        int32_t encoding = 0x1f << 27 | (load ? B20 : 0) | static_cast<uint32_t>(rd) << 12 |
            ad.encodingThumb(true);
        if (half) {
          encoding |= B21;
        } else if (!byte) {
          encoding |= B22;
        }
        Emit32(encoding);
      } else {
        // 16 bit register offset.
        int32_t encoding = B14 | B12 | (load ? B11 : 0) | static_cast<uint32_t>(rd) |
            ad.encodingThumb(false);
        if (byte) {
          encoding |= B10;
        } else if (half) {
          encoding |= B9;
        }
        Emit16(encoding);
      }
    }
  }
}


void Thumb2Assembler::EmitMultiMemOp(Condition cond,
                                     BlockAddressMode bam,
                                     bool load,
                                     Register base,
                                     RegList regs) {
  CHECK_NE(base, kNoRegister);
  CheckCondition(cond);
  bool must_be_32bit = force_32bit_;

  if (!must_be_32bit && base == SP && bam == (load ? IA_W : DB_W) &&
      (regs & 0xff00 & ~(1 << (load ? PC : LR))) == 0) {
    // Use 16-bit PUSH/POP.
    int16_t encoding = B15 | B13 | B12 | (load ? B11 : 0) | B10 |
        ((regs & (1 << (load ? PC : LR))) != 0 ? B8 : 0) | (regs & 0x00ff);
    Emit16(encoding);
    return;
  }

  if ((regs & 0xff00) != 0) {
    must_be_32bit = true;
  }

  bool w_bit = bam == IA_W || bam == DB_W || bam == DA_W || bam == IB_W;
  // 16 bit always uses writeback.
  if (!w_bit) {
    must_be_32bit = true;
  }

  if (must_be_32bit) {
    uint32_t op = 0;
    switch (bam) {
      case IA:
      case IA_W:
        op = 1U /* 0b01 */;
        break;
      case DB:
      case DB_W:
        op = 2U /* 0b10 */;
        break;
      case DA:
      case IB:
      case DA_W:
      case IB_W:
        LOG(FATAL) << "LDM/STM mode not supported on thumb: " << bam;
        UNREACHABLE();
    }
    if (load) {
      // Cannot have SP in the list.
      CHECK_EQ((regs & (1 << SP)), 0);
    } else {
      // Cannot have PC or SP in the list.
      CHECK_EQ((regs & (1 << PC | 1 << SP)), 0);
    }
    int32_t encoding = B31 | B30 | B29 | B27 |
                    (op << 23) |
                    (load ? B20 : 0) |
                    base << 16 |
                    regs |
                    (w_bit << 21);
    Emit32(encoding);
  } else {
    int16_t encoding = B15 | B14 |
                    (load ? B11 : 0) |
                    base << 8 |
                    regs;
    Emit16(encoding);
  }
}

void Thumb2Assembler::EmitBranch(Condition cond, Label* label, bool link, bool x) {
  bool use32bit = IsForced32Bit() || !CanRelocateBranches();
  uint32_t pc = buffer_.Size();
  Fixup::Type branch_type;
  if (cond == AL) {
    if (link) {
      use32bit = true;
      if (x) {
        branch_type = Fixup::kUnconditionalLinkX;      // BLX.
      } else {
        branch_type = Fixup::kUnconditionalLink;       // BX.
      }
    } else {
      branch_type = Fixup::kUnconditional;             // B.
    }
  } else {
    branch_type = Fixup::kConditional;                 // B<cond>.
  }

  Fixup::Size size = use32bit ? Fixup::kBranch32Bit : Fixup::kBranch16Bit;
  FixupId branch_id = AddFixup(Fixup::Branch(pc, branch_type, size, cond));

  if (label->IsBound()) {
    // The branch is to a bound label which means that it's a backwards branch.
    GetFixup(branch_id)->Resolve(label->Position());
    Emit16(0);
  } else {
    // Branch target is an unbound label. Add it to a singly-linked list maintained within
    // the code with the label serving as the head.
    Emit16(static_cast<uint16_t>(label->position_));
    label->LinkTo(branch_id);
  }

  if (use32bit) {
    Emit16(0);
  }
  DCHECK_EQ(buffer_.Size() - pc, GetFixup(branch_id)->GetSizeInBytes());
}


void Thumb2Assembler::Emit32Miscellaneous(uint8_t op1,
                                          uint8_t op2,
                                          uint32_t rest_encoding) {
  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B23 |
      op1 << 20 |
      0xf << 12 |
      B7 |
      op2 << 4 |
      rest_encoding;
  Emit32(encoding);
}


void Thumb2Assembler::Emit16Miscellaneous(uint32_t rest_encoding) {
  int16_t encoding = B15 | B13 | B12 |
      rest_encoding;
  Emit16(encoding);
}

void Thumb2Assembler::clz(Register rd, Register rm, Condition cond) {
  CHECK_NE(rd, kNoRegister);
  CHECK_NE(rm, kNoRegister);
  CheckCondition(cond);
  CHECK_NE(rd, PC);
  CHECK_NE(rm, PC);
  int32_t encoding =
      static_cast<uint32_t>(rm) << 16 |
      static_cast<uint32_t>(rd) << 8 |
      static_cast<uint32_t>(rm);
  Emit32Miscellaneous(0b11, 0b00, encoding);
}


void Thumb2Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
  CheckCondition(cond);
  // Always 32 bits, encoding T3. (Other encondings are called MOV, not MOVW.)
  uint32_t imm4 = (imm16 >> 12) & 15U /* 0b1111 */;
  uint32_t i = (imm16 >> 11) & 1U /* 0b1 */;
  uint32_t imm3 = (imm16 >> 8) & 7U /* 0b111 */;
  uint32_t imm8 = imm16 & 0xff;
  int32_t encoding = B31 | B30 | B29 | B28 |
                  B25 | B22 |
                  static_cast<uint32_t>(rd) << 8 |
                  i << 26 |
                  imm4 << 16 |
                  imm3 << 12 |
                  imm8;
  Emit32(encoding);
}


void Thumb2Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
  CheckCondition(cond);
  // Always 32 bits.
  uint32_t imm4 = (imm16 >> 12) & 15U /* 0b1111 */;
  uint32_t i = (imm16 >> 11) & 1U /* 0b1 */;
  uint32_t imm3 = (imm16 >> 8) & 7U /* 0b111 */;
  uint32_t imm8 = imm16 & 0xff;
  int32_t encoding = B31 | B30 | B29 | B28 |
                  B25 | B23 | B22 |
                  static_cast<uint32_t>(rd) << 8 |
                  i << 26 |
                  imm4 << 16 |
                  imm3 << 12 |
                  imm8;
  Emit32(encoding);
}


void Thumb2Assembler::rbit(Register rd, Register rm, Condition cond) {
  CHECK_NE(rd, kNoRegister);
  CHECK_NE(rm, kNoRegister);
  CheckCondition(cond);
  CHECK_NE(rd, PC);
  CHECK_NE(rm, PC);
  CHECK_NE(rd, SP);
  CHECK_NE(rm, SP);
  int32_t encoding =
      static_cast<uint32_t>(rm) << 16 |
      static_cast<uint32_t>(rd) << 8 |
      static_cast<uint32_t>(rm);

  Emit32Miscellaneous(0b01, 0b10, encoding);
}


void Thumb2Assembler::EmitReverseBytes(Register rd, Register rm,
                                       uint32_t op) {
  CHECK_NE(rd, kNoRegister);
  CHECK_NE(rm, kNoRegister);
  CHECK_NE(rd, PC);
  CHECK_NE(rm, PC);
  CHECK_NE(rd, SP);
  CHECK_NE(rm, SP);

  if (!IsHighRegister(rd) && !IsHighRegister(rm) && !force_32bit_) {
    uint16_t t1_op = B11 | B9 | (op << 6);
    int16_t encoding = t1_op |
        static_cast<uint16_t>(rm) << 3 |
        static_cast<uint16_t>(rd);
    Emit16Miscellaneous(encoding);
  } else {
    int32_t encoding =
        static_cast<uint32_t>(rm) << 16 |
        static_cast<uint32_t>(rd) << 8 |
        static_cast<uint32_t>(rm);
    Emit32Miscellaneous(0b01, op, encoding);
  }
}


void Thumb2Assembler::rev(Register rd, Register rm, Condition cond) {
  CheckCondition(cond);
  EmitReverseBytes(rd, rm, 0b00);
}


void Thumb2Assembler::rev16(Register rd, Register rm, Condition cond) {
  CheckCondition(cond);
  EmitReverseBytes(rd, rm, 0b01);
}


void Thumb2Assembler::revsh(Register rd, Register rm, Condition cond) {
  CheckCondition(cond);
  EmitReverseBytes(rd, rm, 0b11);
}


void Thumb2Assembler::ldrex(Register rt, Register rn, uint16_t imm, Condition cond) {
  CHECK_NE(rn, kNoRegister);
  CHECK_NE(rt, kNoRegister);
  CheckCondition(cond);
  CHECK_LT(imm, (1u << 10));

  int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rt) << 12 |
      0xf << 8 |
      imm >> 2;
  Emit32(encoding);
}


void Thumb2Assembler::ldrex(Register rt, Register rn, Condition cond) {
  ldrex(rt, rn, 0, cond);
}


void Thumb2Assembler::strex(Register rd,
                            Register rt,
                            Register rn,
                            uint16_t imm,
                            Condition cond) {
  CHECK_NE(rn, kNoRegister);
  CHECK_NE(rd, kNoRegister);
  CHECK_NE(rt, kNoRegister);
  CheckCondition(cond);
  CHECK_LT(imm, (1u << 10));

  int32_t encoding = B31 | B30 | B29 | B27 | B22 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rt) << 12 |
      static_cast<uint32_t>(rd) << 8 |
      imm >> 2;
  Emit32(encoding);
}


void Thumb2Assembler::ldrexd(Register rt, Register rt2, Register rn, Condition cond) {
  CHECK_NE(rn, kNoRegister);
  CHECK_NE(rt, kNoRegister);
  CHECK_NE(rt2, kNoRegister);
  CHECK_NE(rt, rt2);
  CheckCondition(cond);

  int32_t encoding = B31 | B30 | B29 | B27 | B23 | B22 | B20 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rt) << 12 |
      static_cast<uint32_t>(rt2) << 8 |
      B6 | B5 | B4 | B3 | B2 | B1 | B0;
  Emit32(encoding);
}


void Thumb2Assembler::strex(Register rd,
                            Register rt,
                            Register rn,
                            Condition cond) {
  strex(rd, rt, rn, 0, cond);
}


void Thumb2Assembler::strexd(Register rd, Register rt, Register rt2, Register rn, Condition cond) {
  CHECK_NE(rd, kNoRegister);
  CHECK_NE(rn, kNoRegister);
  CHECK_NE(rt, kNoRegister);
  CHECK_NE(rt2, kNoRegister);
  CHECK_NE(rt, rt2);
  CHECK_NE(rd, rt);
  CHECK_NE(rd, rt2);
  CheckCondition(cond);

  int32_t encoding = B31 | B30 | B29 | B27 | B23 | B22 |
      static_cast<uint32_t>(rn) << 16 |
      static_cast<uint32_t>(rt) << 12 |
      static_cast<uint32_t>(rt2) << 8 |
      B6 | B5 | B4 |
      static_cast<uint32_t>(rd);
  Emit32(encoding);
}


void Thumb2Assembler::clrex(Condition cond) {
  CheckCondition(cond);
  int32_t encoding = B31 | B30 | B29 | B27 | B28 | B25 | B24 | B23 |
      B21 | B20 |
      0xf << 16 |
      B15 |
      0xf << 8 |
      B5 |
      0xf;
  Emit32(encoding);
}


void Thumb2Assembler::nop(Condition cond) {
  CheckCondition(cond);
  uint16_t encoding = B15 | B13 | B12 |
      B11 | B10 | B9 | B8;
  Emit16(static_cast<int16_t>(encoding));
}


void Thumb2Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
  CHECK_NE(sn, kNoSRegister);
  CHECK_NE(rt, kNoRegister);
  CHECK_NE(rt, SP);
  CHECK_NE(rt, PC);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B25 |
                     ((static_cast<int32_t>(sn) >> 1)*B16) |
                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
  Emit32(encoding);
}


void Thumb2Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
  CHECK_NE(sn, kNoSRegister);
  CHECK_NE(rt, kNoRegister);
  CHECK_NE(rt, SP);
  CHECK_NE(rt, PC);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B25 | B20 |
                     ((static_cast<int32_t>(sn) >> 1)*B16) |
                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
  Emit32(encoding);
}


void Thumb2Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
                              Condition cond) {
  CHECK_NE(sm, kNoSRegister);
  CHECK_NE(sm, S31);
  CHECK_NE(rt, kNoRegister);
  CHECK_NE(rt, SP);
  CHECK_NE(rt, PC);
  CHECK_NE(rt2, kNoRegister);
  CHECK_NE(rt2, SP);
  CHECK_NE(rt2, PC);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B22 |
                     (static_cast<int32_t>(rt2)*B16) |
                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
                     (static_cast<int32_t>(sm) >> 1);
  Emit32(encoding);
}


void Thumb2Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
                              Condition cond) {
  CHECK_NE(sm, kNoSRegister);
  CHECK_NE(sm, S31);
  CHECK_NE(rt, kNoRegister);
  CHECK_NE(rt, SP);
  CHECK_NE(rt, PC);
  CHECK_NE(rt2, kNoRegister);
  CHECK_NE(rt2, SP);
  CHECK_NE(rt2, PC);
  CHECK_NE(rt, rt2);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B22 | B20 |
                     (static_cast<int32_t>(rt2)*B16) |
                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
                     (static_cast<int32_t>(sm) >> 1);
  Emit32(encoding);
}


void Thumb2Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
                              Condition cond) {
  CHECK_NE(dm, kNoDRegister);
  CHECK_NE(rt, kNoRegister);
  CHECK_NE(rt, SP);
  CHECK_NE(rt, PC);
  CHECK_NE(rt2, kNoRegister);
  CHECK_NE(rt2, SP);
  CHECK_NE(rt2, PC);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B22 |
                     (static_cast<int32_t>(rt2)*B16) |
                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
                     (static_cast<int32_t>(dm) & 0xf);
  Emit32(encoding);
}


void Thumb2Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
                              Condition cond) {
  CHECK_NE(dm, kNoDRegister);
  CHECK_NE(rt, kNoRegister);
  CHECK_NE(rt, SP);
  CHECK_NE(rt, PC);
  CHECK_NE(rt2, kNoRegister);
  CHECK_NE(rt2, SP);
  CHECK_NE(rt2, PC);
  CHECK_NE(rt, rt2);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B22 | B20 |
                     (static_cast<int32_t>(rt2)*B16) |
                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
                     (static_cast<int32_t>(dm) & 0xf);
  Emit32(encoding);
}


void Thumb2Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) {
  const Address& addr = static_cast<const Address&>(ad);
  CHECK_NE(sd, kNoSRegister);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B24 | B20 |
                     ((static_cast<int32_t>(sd) & 1)*B22) |
                     ((static_cast<int32_t>(sd) >> 1)*B12) |
                     B11 | B9 | addr.vencoding();
  Emit32(encoding);
}


void Thumb2Assembler::vstrs(SRegister sd, const Address& ad, Condition cond) {
  const Address& addr = static_cast<const Address&>(ad);
  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
  CHECK_NE(sd, kNoSRegister);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B24 |
                     ((static_cast<int32_t>(sd) & 1)*B22) |
                     ((static_cast<int32_t>(sd) >> 1)*B12) |
                     B11 | B9 | addr.vencoding();
  Emit32(encoding);
}


void Thumb2Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) {
  const Address& addr = static_cast<const Address&>(ad);
  CHECK_NE(dd, kNoDRegister);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B24 | B20 |
                     ((static_cast<int32_t>(dd) >> 4)*B22) |
                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
                     B11 | B9 | B8 | addr.vencoding();
  Emit32(encoding);
}


void Thumb2Assembler::vstrd(DRegister dd, const Address& ad, Condition cond) {
  const Address& addr = static_cast<const Address&>(ad);
  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
  CHECK_NE(dd, kNoDRegister);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B24 |
                     ((static_cast<int32_t>(dd) >> 4)*B22) |
                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
                     B11 | B9 | B8 | addr.vencoding();
  Emit32(encoding);
}


void Thumb2Assembler::vpushs(SRegister reg, int nregs, Condition cond) {
  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond);
}


void Thumb2Assembler::vpushd(DRegister reg, int nregs, Condition cond) {
  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond);
}


void Thumb2Assembler::vpops(SRegister reg, int nregs, Condition cond) {
  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond);
}


void Thumb2Assembler::vpopd(DRegister reg, int nregs, Condition cond) {
  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond);
}


void Thumb2Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) {
  CheckCondition(cond);

  uint32_t D;
  uint32_t Vd;
  if (dbl) {
    // Encoded as D:Vd.
    D = (reg >> 4) & 1;
    Vd = reg & 15U /* 0b1111 */;
  } else {
    // Encoded as Vd:D.
    D = reg & 1;
    Vd = (reg >> 1) & 15U /* 0b1111 */;
  }
  int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 |
                    B11 | B9 |
        (dbl ? B8 : 0) |
        (push ? B24 : (B23 | B20)) |
        14U /* 0b1110 */ << 28 |
        nregs << (dbl ? 1 : 0) |
        D << 22 |
        Vd << 12;
  Emit32(encoding);
}


void Thumb2Assembler::EmitVFPsss(Condition cond, int32_t opcode,
                                 SRegister sd, SRegister sn, SRegister sm) {
  CHECK_NE(sd, kNoSRegister);
  CHECK_NE(sn, kNoSRegister);
  CHECK_NE(sm, kNoSRegister);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B25 | B11 | B9 | opcode |
                     ((static_cast<int32_t>(sd) & 1)*B22) |
                     ((static_cast<int32_t>(sn) >> 1)*B16) |
                     ((static_cast<int32_t>(sd) >> 1)*B12) |
                     ((static_cast<int32_t>(sn) & 1)*B7) |
                     ((static_cast<int32_t>(sm) & 1)*B5) |
                     (static_cast<int32_t>(sm) >> 1);
  Emit32(encoding);
}


void Thumb2Assembler::EmitVFPddd(Condition cond, int32_t opcode,
                                 DRegister dd, DRegister dn, DRegister dm) {
  CHECK_NE(dd, kNoDRegister);
  CHECK_NE(dn, kNoDRegister);
  CHECK_NE(dm, kNoDRegister);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
                     ((static_cast<int32_t>(dd) >> 4)*B22) |
                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
                     ((static_cast<int32_t>(dn) >> 4)*B7) |
                     ((static_cast<int32_t>(dm) >> 4)*B5) |
                     (static_cast<int32_t>(dm) & 0xf);
  Emit32(encoding);
}


void Thumb2Assembler::EmitVFPsd(Condition cond, int32_t opcode,
                                SRegister sd, DRegister dm) {
  CHECK_NE(sd, kNoSRegister);
  CHECK_NE(dm, kNoDRegister);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B25 | B11 | B9 | opcode |
                     ((static_cast<int32_t>(sd) & 1)*B22) |
                     ((static_cast<int32_t>(sd) >> 1)*B12) |
                     ((static_cast<int32_t>(dm) >> 4)*B5) |
                     (static_cast<int32_t>(dm) & 0xf);
  Emit32(encoding);
}


void Thumb2Assembler::EmitVFPds(Condition cond, int32_t opcode,
                                DRegister dd, SRegister sm) {
  CHECK_NE(dd, kNoDRegister);
  CHECK_NE(sm, kNoSRegister);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
                     B27 | B26 | B25 | B11 | B9 | opcode |
                     ((static_cast<int32_t>(dd) >> 4)*B22) |
                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
                     ((static_cast<int32_t>(sm) & 1)*B5) |
                     (static_cast<int32_t>(sm) >> 1);
  Emit32(encoding);
}


void Thumb2Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR.
  CHECK_NE(cond, kNoCondition);
  CheckCondition(cond);
  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
      B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
      (static_cast<int32_t>(PC)*B12) |
      B11 | B9 | B4;
  Emit32(encoding);
}


void Thumb2Assembler::svc(uint32_t imm8) {
  CHECK(IsUint<8>(imm8)) << imm8;
  int16_t encoding = B15 | B14 | B12 |
       B11 | B10 | B9 | B8 |
       imm8;
  Emit16(encoding);
}


void Thumb2Assembler::bkpt(uint16_t imm8) {
  CHECK(IsUint<8>(imm8)) << imm8;
  int16_t encoding = B15 | B13 | B12 |
      B11 | B10 | B9 |
      imm8;
  Emit16(encoding);
}

// Convert the given IT state to a mask bit given bit 0 of the first
// condition and a shift position.
static uint8_t ToItMask(ItState s, uint8_t firstcond0, uint8_t shift) {
  switch (s) {
  case kItOmitted: return 1 << shift;
  case kItThen: return firstcond0 << shift;
  case kItElse: return !firstcond0 << shift;
  }
  return 0;
}


// Set the IT condition in the given position for the given state.  This is used
// to check that conditional instructions match the preceding IT statement.
void Thumb2Assembler::SetItCondition(ItState s, Condition cond, uint8_t index) {
  switch (s) {
  case kItOmitted: it_conditions_[index] = AL; break;
  case kItThen: it_conditions_[index] = cond; break;
  case kItElse:
    it_conditions_[index] = static_cast<Condition>(static_cast<uint8_t>(cond) ^ 1);
    break;
  }
}


void Thumb2Assembler::it(Condition firstcond, ItState i1, ItState i2, ItState i3) {
  CheckCondition(AL);       // Not allowed in IT block.
  uint8_t firstcond0 = static_cast<uint8_t>(firstcond) & 1;

  // All conditions to AL.
  for (uint8_t i = 0; i < 4; ++i) {
    it_conditions_[i] = AL;
  }

  SetItCondition(kItThen, firstcond, 0);
  uint8_t mask = ToItMask(i1, firstcond0, 3);
  SetItCondition(i1, firstcond, 1);

  if (i1 != kItOmitted) {
    mask |= ToItMask(i2, firstcond0, 2);
    SetItCondition(i2, firstcond, 2);
    if (i2 != kItOmitted) {
      mask |= ToItMask(i3, firstcond0, 1);
      SetItCondition(i3, firstcond, 3);
      if (i3 != kItOmitted) {
        mask |= 1U /* 0b0001 */;
      }
    }
  }

  // Start at first condition.
  it_cond_index_ = 0;
  next_condition_ = it_conditions_[0];
  uint16_t encoding = B15 | B13 | B12 |
        B11 | B10 | B9 | B8 |
        firstcond << 4 |
        mask;
  Emit16(encoding);
}


void Thumb2Assembler::cbz(Register rn, Label* label) {
  CheckCondition(AL);
  if (label->IsBound()) {
    LOG(FATAL) << "cbz can only be used to branch forwards";
    UNREACHABLE();
  } else if (IsHighRegister(rn)) {
    LOG(FATAL) << "cbz can only be used with low registers";
    UNREACHABLE();
  } else {
    uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), false);
    label->LinkTo(branchid);
  }
}


void Thumb2Assembler::cbnz(Register rn, Label* label) {
  CheckCondition(AL);
  if (label->IsBound()) {
    LOG(FATAL) << "cbnz can only be used to branch forwards";
    UNREACHABLE();
  } else if (IsHighRegister(rn)) {
    LOG(FATAL) << "cbnz can only be used with low registers";
    UNREACHABLE();
  } else {
    uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), true);
    label->LinkTo(branchid);
  }
}


void Thumb2Assembler::blx(Register rm, Condition cond) {
  CHECK_NE(rm, kNoRegister);
  CheckCondition(cond);
  int16_t encoding = B14 | B10 | B9 | B8 | B7 | static_cast<int16_t>(rm) << 3;
  Emit16(encoding);
}


void Thumb2Assembler::bx(Register rm, Condition cond) {
  CHECK_NE(rm, kNoRegister);
  CheckCondition(cond);
  int16_t encoding = B14 | B10 | B9 | B8 | static_cast<int16_t>(rm) << 3;
  Emit16(encoding);
}


void Thumb2Assembler::Push(Register rd, Condition cond) {
  str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
}


void Thumb2Assembler::Pop(Register rd, Condition cond) {
  ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
}


void Thumb2Assembler::PushList(RegList regs, Condition cond) {
  stm(DB_W, SP, regs, cond);
}


void Thumb2Assembler::PopList(RegList regs, Condition cond) {
  ldm(IA_W, SP, regs, cond);
}


void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) {
  if (cond != AL || rd != rm) {
    mov(rd, ShifterOperand(rm), cond);
  }
}


void Thumb2Assembler::Bind(Label* label) {
  BindLabel(label, buffer_.Size());
}


void Thumb2Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
                          Condition cond, SetCc set_cc) {
  CHECK_LE(shift_imm, 31u);
  CheckCondition(cond);
  EmitShift(rd, rm, LSL, shift_imm, cond, set_cc);
}


void Thumb2Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
                          Condition cond, SetCc set_cc) {
  CHECK(1u <= shift_imm && shift_imm <= 32u);
  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
  CheckCondition(cond);
  EmitShift(rd, rm, LSR, shift_imm, cond, set_cc);
}


void Thumb2Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
                          Condition cond, SetCc set_cc) {
  CHECK(1u <= shift_imm && shift_imm <= 32u);
  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
  CheckCondition(cond);
  EmitShift(rd, rm, ASR, shift_imm, cond, set_cc);
}


void Thumb2Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
                          Condition cond, SetCc set_cc) {
  CHECK(1u <= shift_imm && shift_imm <= 31u);
  CheckCondition(cond);
  EmitShift(rd, rm, ROR, shift_imm, cond, set_cc);
}


void Thumb2Assembler::Rrx(Register rd, Register rm, Condition cond, SetCc set_cc) {
  CheckCondition(cond);
  EmitShift(rd, rm, RRX, 0, cond, set_cc);
}


void Thumb2Assembler::Lsl(Register rd, Register rm, Register rn,
                          Condition cond, SetCc set_cc) {
  CheckCondition(cond);
  EmitShift(rd, rm, LSL, rn, cond, set_cc);
}


void Thumb2Assembler::Lsr(Register rd, Register rm, Register rn,
                          Condition cond, SetCc set_cc) {
  CheckCondition(cond);
  EmitShift(rd, rm, LSR, rn, cond, set_cc);
}


void Thumb2Assembler::Asr(Register rd, Register rm, Register rn,
                          Condition cond, SetCc set_cc) {
  CheckCondition(cond);
  EmitShift(rd, rm, ASR, rn, cond, set_cc);
}


void Thumb2Assembler::Ror(Register rd, Register rm, Register rn,
                          Condition cond, SetCc set_cc) {
  CheckCondition(cond);
  EmitShift(rd, rm, ROR, rn, cond, set_cc);
}


int32_t Thumb2Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
  // The offset is off by 4 due to the way the ARM CPUs read PC.
  offset -= 4;
  offset >>= 1;

  uint32_t value = 0;
  // There are two different encodings depending on the value of bit 12.  In one case
  // intermediate values are calculated using the sign bit.
  if ((inst & B12) == B12) {
    // 25 bits of offset.
    uint32_t signbit = (offset >> 31) & 0x1;
    uint32_t i1 = (offset >> 22) & 0x1;
    uint32_t i2 = (offset >> 21) & 0x1;
    uint32_t imm10 = (offset >> 11) & 0x03ff;
    uint32_t imm11 = offset & 0x07ff;
    uint32_t j1 = (i1 ^ signbit) ? 0 : 1;
    uint32_t j2 = (i2 ^ signbit) ? 0 : 1;
    value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm10 << 16) |
                      imm11;
    // Remove the offset from the current encoding.
    inst &= ~(0x3ff << 16 | 0x7ff);
  } else {
    uint32_t signbit = (offset >> 31) & 0x1;
    uint32_t imm6 = (offset >> 11) & 0x03f;
    uint32_t imm11 = offset & 0x07ff;
    uint32_t j1 = (offset >> 19) & 1;
    uint32_t j2 = (offset >> 17) & 1;
    value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm6 << 16) |
        imm11;
    // Remove the offset from the current encoding.
    inst &= ~(0x3f << 16 | 0x7ff);
  }
  // Mask out offset bits in current instruction.
  inst &= ~(B26 | B13 | B11);
  inst |= value;
  return inst;
}


int Thumb2Assembler::DecodeBranchOffset(int32_t instr) {
  int32_t imm32;
  if ((instr & B12) == B12) {
    uint32_t S = (instr >> 26) & 1;
    uint32_t J2 = (instr >> 11) & 1;
    uint32_t J1 = (instr >> 13) & 1;
    uint32_t imm10 = (instr >> 16) & 0x3FF;
    uint32_t imm11 = instr & 0x7FF;

    uint32_t I1 = ~(J1 ^ S) & 1;
    uint32_t I2 = ~(J2 ^ S) & 1;
    imm32 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
    imm32 = (imm32 << 8) >> 8;  // sign extend 24 bit immediate.
  } else {
    uint32_t S = (instr >> 26) & 1;
    uint32_t J2 = (instr >> 11) & 1;
    uint32_t J1 = (instr >> 13) & 1;
    uint32_t imm6 = (instr >> 16) & 0x3F;
    uint32_t imm11 = instr & 0x7FF;

    imm32 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
    imm32 = (imm32 << 11) >> 11;  // sign extend 21 bit immediate.
  }
  imm32 += 4;
  return imm32;
}

uint32_t Thumb2Assembler::GetAdjustedPosition(uint32_t old_position) {
  // We can reconstruct the adjustment by going through all the fixups from the beginning
  // up to the old_position. Since we expect AdjustedPosition() to be called in a loop
  // with increasing old_position, we can use the data from last AdjustedPosition() to
  // continue where we left off and the whole loop should be O(m+n) where m is the number
  // of positions to adjust and n is the number of fixups.
  if (old_position < last_old_position_) {
    last_position_adjustment_ = 0u;
    last_old_position_ = 0u;
    last_fixup_id_ = 0u;
  }
  while (last_fixup_id_ != fixups_.size()) {
    Fixup* fixup = GetFixup(last_fixup_id_);
    if (fixup->GetLocation() >= old_position + last_position_adjustment_) {
      break;
    }
    if (fixup->GetSize() != fixup->GetOriginalSize()) {
      last_position_adjustment_ += fixup->GetSizeInBytes() - fixup->GetOriginalSizeInBytes();
    }
     ++last_fixup_id_;
  }
  last_old_position_ = old_position;
  return old_position + last_position_adjustment_;
}

Literal* Thumb2Assembler::NewLiteral(size_t size, const uint8_t* data)  {
  DCHECK(size == 4u || size == 8u) << size;
  literals_.emplace_back(size, data);
  return &literals_.back();
}

void Thumb2Assembler::LoadLiteral(Register rt, Literal* literal)  {
  DCHECK_EQ(literal->GetSize(), 4u);
  DCHECK(!literal->GetLabel()->IsBound());
  bool use32bit = IsForced32Bit() || IsHighRegister(rt);
  uint32_t location = buffer_.Size();
  Fixup::Size size = use32bit ? Fixup::kLiteral4KiB : Fixup::kLiteral1KiB;
  FixupId fixup_id = AddFixup(Fixup::LoadNarrowLiteral(location, rt, size));
  Emit16(static_cast<uint16_t>(literal->GetLabel()->position_));
  literal->GetLabel()->LinkTo(fixup_id);
  if (use32bit) {
    Emit16(0);
  }
  DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size());
}

void Thumb2Assembler::LoadLiteral(Register rt, Register rt2, Literal* literal)  {
  DCHECK_EQ(literal->GetSize(), 8u);
  DCHECK(!literal->GetLabel()->IsBound());
  uint32_t location = buffer_.Size();
  FixupId fixup_id =
      AddFixup(Fixup::LoadWideLiteral(location, rt, rt2, Fixup::kLongOrFPLiteral1KiB));
  Emit16(static_cast<uint16_t>(literal->GetLabel()->position_));
  literal->GetLabel()->LinkTo(fixup_id);
  Emit16(0);
  DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size());
}

void Thumb2Assembler::LoadLiteral(SRegister sd, Literal* literal)  {
  DCHECK_EQ(literal->GetSize(), 4u);
  DCHECK(!literal->GetLabel()->IsBound());
  uint32_t location = buffer_.Size();
  FixupId fixup_id = AddFixup(Fixup::LoadSingleLiteral(location, sd, Fixup::kLongOrFPLiteral1KiB));
  Emit16(static_cast<uint16_t>(literal->GetLabel()->position_));
  literal->GetLabel()->LinkTo(fixup_id);
  Emit16(0);
  DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size());
}

void Thumb2Assembler::LoadLiteral(DRegister dd, Literal* literal) {
  DCHECK_EQ(literal->GetSize(), 8u);
  DCHECK(!literal->GetLabel()->IsBound());
  uint32_t location = buffer_.Size();
  FixupId fixup_id = AddFixup(Fixup::LoadDoubleLiteral(location, dd, Fixup::kLongOrFPLiteral1KiB));
  Emit16(static_cast<uint16_t>(literal->GetLabel()->position_));
  literal->GetLabel()->LinkTo(fixup_id);
  Emit16(0);
  DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size());
}


void Thumb2Assembler::AddConstant(Register rd, Register rn, int32_t value,
                                  Condition cond, SetCc set_cc) {
  if (value == 0 && set_cc != kCcSet) {
    if (rd != rn) {
      mov(rd, ShifterOperand(rn), cond);
    }
    return;
  }
  // We prefer to select the shorter code sequence rather than selecting add for
  // positive values and sub for negatives ones, which would slightly improve
  // the readability of generated code for some constants.
  ShifterOperand shifter_op;
  if (ShifterOperandCanHold(rd, rn, ADD, value, set_cc, &shifter_op)) {
    add(rd, rn, shifter_op, cond, set_cc);
  } else if (ShifterOperandCanHold(rd, rn, SUB, -value, set_cc, &shifter_op)) {
    sub(rd, rn, shifter_op, cond, set_cc);
  } else {
    CHECK(rn != IP);
    // If rd != rn, use rd as temp. This alows 16-bit ADD/SUB in more situations than using IP.
    Register temp = (rd != rn) ? rd : IP;
    if (ShifterOperandCanHold(temp, kNoRegister, MVN, ~value, kCcKeep, &shifter_op)) {
      mvn(temp, shifter_op, cond, kCcKeep);
      add(rd, rn, ShifterOperand(temp), cond, set_cc);
    } else if (ShifterOperandCanHold(temp, kNoRegister, MVN, ~(-value), kCcKeep, &shifter_op)) {
      mvn(temp, shifter_op, cond, kCcKeep);
      sub(rd, rn, ShifterOperand(temp), cond, set_cc);
    } else if (High16Bits(-value) == 0) {
      movw(temp, Low16Bits(-value), cond);
      sub(rd, rn, ShifterOperand(temp), cond, set_cc);
    } else {
      movw(temp, Low16Bits(value), cond);
      uint16_t value_high = High16Bits(value);
      if (value_high != 0) {
        movt(temp, value_high, cond);
      }
      add(rd, rn, ShifterOperand(temp), cond, set_cc);
    }
  }
}

void Thumb2Assembler::CmpConstant(Register rn, int32_t value, Condition cond) {
  // We prefer to select the shorter code sequence rather than using plain cmp and cmn
  // which would slightly improve the readability of generated code for some constants.
  ShifterOperand shifter_op;
  if (ShifterOperandCanHold(kNoRegister, rn, CMP, value, kCcSet, &shifter_op)) {
    cmp(rn, shifter_op, cond);
  } else if (ShifterOperandCanHold(kNoRegister, rn, CMN, -value, kCcSet, &shifter_op)) {
    cmn(rn, shifter_op, cond);
  } else {
    CHECK(rn != IP);
    if (ShifterOperandCanHold(IP, kNoRegister, MVN, ~value, kCcKeep, &shifter_op)) {
      mvn(IP, shifter_op, cond, kCcKeep);
      cmp(rn, ShifterOperand(IP), cond);
    } else if (ShifterOperandCanHold(IP, kNoRegister, MVN, ~(-value), kCcKeep, &shifter_op)) {
      mvn(IP, shifter_op, cond, kCcKeep);
      cmn(rn, ShifterOperand(IP), cond);
    } else if (High16Bits(-value) == 0) {
      movw(IP, Low16Bits(-value), cond);
      cmn(rn, ShifterOperand(IP), cond);
    } else {
      movw(IP, Low16Bits(value), cond);
      uint16_t value_high = High16Bits(value);
      if (value_high != 0) {
        movt(IP, value_high, cond);
      }
      cmp(rn, ShifterOperand(IP), cond);
    }
  }
}

void Thumb2Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
  ShifterOperand shifter_op;
  if (ShifterOperandCanHold(rd, R0, MOV, value, &shifter_op)) {
    mov(rd, shifter_op, cond);
  } else if (ShifterOperandCanHold(rd, R0, MVN, ~value, &shifter_op)) {
    mvn(rd, shifter_op, cond);
  } else {
    movw(rd, Low16Bits(value), cond);
    uint16_t value_high = High16Bits(value);
    if (value_high != 0) {
      movt(rd, value_high, cond);
    }
  }
}

int32_t Thumb2Assembler::GetAllowedLoadOffsetBits(LoadOperandType type) {
  switch (type) {
    case kLoadSignedByte:
    case kLoadSignedHalfword:
    case kLoadUnsignedHalfword:
    case kLoadUnsignedByte:
    case kLoadWord:
      // We can encode imm12 offset.
      return 0xfffu;
    case kLoadSWord:
    case kLoadDWord:
    case kLoadWordPair:
      // We can encode imm8:'00' offset.
      return 0xff << 2;
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
}

int32_t Thumb2Assembler::GetAllowedStoreOffsetBits(StoreOperandType type) {
  switch (type) {
    case kStoreHalfword:
    case kStoreByte:
    case kStoreWord:
      // We can encode imm12 offset.
      return 0xfff;
    case kStoreSWord:
    case kStoreDWord:
    case kStoreWordPair:
      // We can encode imm8:'00' offset.
      return 0xff << 2;
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
}

bool Thumb2Assembler::CanSplitLoadStoreOffset(int32_t allowed_offset_bits,
                                              int32_t offset,
                                              /*out*/ int32_t* add_to_base,
                                              /*out*/ int32_t* offset_for_load_store) {
  int32_t other_bits = offset & ~allowed_offset_bits;
  if (ShifterOperandCanAlwaysHold(other_bits) || ShifterOperandCanAlwaysHold(-other_bits)) {
    *add_to_base = offset & ~allowed_offset_bits;
    *offset_for_load_store = offset & allowed_offset_bits;
    return true;
  }
  return false;
}

int32_t Thumb2Assembler::AdjustLoadStoreOffset(int32_t allowed_offset_bits,
                                               Register temp,
                                               Register base,
                                               int32_t offset,
                                               Condition cond) {
  DCHECK_NE(offset & ~allowed_offset_bits, 0);
  int32_t add_to_base, offset_for_load;
  if (CanSplitLoadStoreOffset(allowed_offset_bits, offset, &add_to_base, &offset_for_load)) {
    AddConstant(temp, base, add_to_base, cond, kCcKeep);
    return offset_for_load;
  } else {
    LoadImmediate(temp, offset, cond);
    add(temp, temp, ShifterOperand(base), cond, kCcKeep);
    return 0;
  }
}

// Implementation note: this method must emit at most one instruction when
// Address::CanHoldLoadOffsetThumb.
void Thumb2Assembler::LoadFromOffset(LoadOperandType type,
                                     Register reg,
                                     Register base,
                                     int32_t offset,
                                     Condition cond) {
  if (!Address::CanHoldLoadOffsetThumb(type, offset)) {
    CHECK_NE(base, IP);
    // Inlined AdjustLoadStoreOffset() allows us to pull a few more tricks.
    int32_t allowed_offset_bits = GetAllowedLoadOffsetBits(type);
    DCHECK_NE(offset & ~allowed_offset_bits, 0);
    int32_t add_to_base, offset_for_load;
    if (CanSplitLoadStoreOffset(allowed_offset_bits, offset, &add_to_base, &offset_for_load)) {
      // Use reg for the adjusted base. If it's low reg, we may end up using 16-bit load.
      AddConstant(reg, base, add_to_base, cond, kCcKeep);
      base = reg;
      offset = offset_for_load;
    } else {
      Register temp = (reg == base) ? IP : reg;
      LoadImmediate(temp, offset, cond);
      // TODO: Implement indexed load (not available for LDRD) and use it here to avoid the ADD.
      // Use reg for the adjusted base. If it's low reg, we may end up using 16-bit load.
      add(reg, reg, ShifterOperand((reg == base) ? IP : base), cond, kCcKeep);
      base = reg;
      offset = 0;
    }
  }
  DCHECK(Address::CanHoldLoadOffsetThumb(type, offset));
  switch (type) {
    case kLoadSignedByte:
      ldrsb(reg, Address(base, offset), cond);
      break;
    case kLoadUnsignedByte:
      ldrb(reg, Address(base, offset), cond);
      break;
    case kLoadSignedHalfword:
      ldrsh(reg, Address(base, offset), cond);
      break;
    case kLoadUnsignedHalfword:
      ldrh(reg, Address(base, offset), cond);
      break;
    case kLoadWord:
      ldr(reg, Address(base, offset), cond);
      break;
    case kLoadWordPair:
      ldrd(reg, Address(base, offset), cond);
      break;
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
}

// Implementation note: this method must emit at most one instruction when
// Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
void Thumb2Assembler::LoadSFromOffset(SRegister reg,
                                      Register base,
                                      int32_t offset,
                                      Condition cond) {
  if (!Address::CanHoldLoadOffsetThumb(kLoadSWord, offset)) {
    CHECK_NE(base, IP);
    offset = AdjustLoadStoreOffset(GetAllowedLoadOffsetBits(kLoadSWord), IP, base, offset, cond);
    base = IP;
  }
  DCHECK(Address::CanHoldLoadOffsetThumb(kLoadSWord, offset));
  vldrs(reg, Address(base, offset), cond);
}


// Implementation note: this method must emit at most one instruction when
// Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
void Thumb2Assembler::LoadDFromOffset(DRegister reg,
                                      Register base,
                                      int32_t offset,
                                      Condition cond) {
  if (!Address::CanHoldLoadOffsetThumb(kLoadDWord, offset)) {
    CHECK_NE(base, IP);
    offset = AdjustLoadStoreOffset(GetAllowedLoadOffsetBits(kLoadDWord), IP, base, offset, cond);
    base = IP;
  }
  DCHECK(Address::CanHoldLoadOffsetThumb(kLoadDWord, offset));
  vldrd(reg, Address(base, offset), cond);
}


// Implementation note: this method must emit at most one instruction when
// Address::CanHoldStoreOffsetThumb.
void Thumb2Assembler::StoreToOffset(StoreOperandType type,
                                    Register reg,
                                    Register base,
                                    int32_t offset,
                                    Condition cond) {
  Register tmp_reg = kNoRegister;
  if (!Address::CanHoldStoreOffsetThumb(type, offset)) {
    CHECK_NE(base, IP);
    if ((reg != IP) &&
        ((type != kStoreWordPair) || (reg + 1 != IP))) {
      tmp_reg = IP;
    } else {
      // Be careful not to use IP twice (for `reg` (or `reg` + 1 in
      // the case of a word-pair store) and `base`) to build the
      // Address object used by the store instruction(s) below.
      // Instead, save R5 on the stack (or R6 if R5 is already used by
      // `base`), use it as secondary temporary register, and restore
      // it after the store instruction has been emitted.
      tmp_reg = (base != R5) ? R5 : R6;
      Push(tmp_reg);
      if (base == SP) {
        offset += kRegisterSize;
      }
    }
    // TODO: Implement indexed store (not available for STRD), inline AdjustLoadStoreOffset()
    // and in the "unsplittable" path get rid of the "add" by using the store indexed instead.
    offset = AdjustLoadStoreOffset(GetAllowedStoreOffsetBits(type), tmp_reg, base, offset, cond);
    base = tmp_reg;
  }
  DCHECK(Address::CanHoldStoreOffsetThumb(type, offset));
  switch (type) {
    case kStoreByte:
      strb(reg, Address(base, offset), cond);
      break;
    case kStoreHalfword:
      strh(reg, Address(base, offset), cond);
      break;
    case kStoreWord:
      str(reg, Address(base, offset), cond);
      break;
    case kStoreWordPair:
      strd(reg, Address(base, offset), cond);
      break;
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
  if ((tmp_reg != kNoRegister) && (tmp_reg != IP)) {
    CHECK((tmp_reg == R5) || (tmp_reg == R6));
    Pop(tmp_reg);
  }
}


// Implementation note: this method must emit at most one instruction when
// Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreToOffset.
void Thumb2Assembler::StoreSToOffset(SRegister reg,
                                     Register base,
                                     int32_t offset,
                                     Condition cond) {
  if (!Address::CanHoldStoreOffsetThumb(kStoreSWord, offset)) {
    CHECK_NE(base, IP);
    offset = AdjustLoadStoreOffset(GetAllowedStoreOffsetBits(kStoreSWord), IP, base, offset, cond);
    base = IP;
  }
  DCHECK(Address::CanHoldStoreOffsetThumb(kStoreSWord, offset));
  vstrs(reg, Address(base, offset), cond);
}


// Implementation note: this method must emit at most one instruction when
// Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreSToOffset.
void Thumb2Assembler::StoreDToOffset(DRegister reg,
                                     Register base,
                                     int32_t offset,
                                     Condition cond) {
  if (!Address::CanHoldStoreOffsetThumb(kStoreDWord, offset)) {
    CHECK_NE(base, IP);
    offset = AdjustLoadStoreOffset(GetAllowedStoreOffsetBits(kStoreDWord), IP, base, offset, cond);
    base = IP;
  }
  DCHECK(Address::CanHoldStoreOffsetThumb(kStoreDWord, offset));
  vstrd(reg, Address(base, offset), cond);
}


void Thumb2Assembler::MemoryBarrier(ManagedRegister mscratch) {
  CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
  dmb(SY);
}


void Thumb2Assembler::dmb(DmbOptions flavor) {
  int32_t encoding = 0xf3bf8f50;  // dmb in T1 encoding.
  Emit32(encoding | flavor);
}


void Thumb2Assembler::CompareAndBranchIfZero(Register r, Label* label) {
  if (CanRelocateBranches() && IsLowRegister(r) && !label->IsBound()) {
    cbz(r, label);
  } else {
    cmp(r, ShifterOperand(0));
    b(label, EQ);
  }
}


void Thumb2Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
  if (CanRelocateBranches() && IsLowRegister(r) && !label->IsBound()) {
    cbnz(r, label);
  } else {
    cmp(r, ShifterOperand(0));
    b(label, NE);
  }
}

JumpTable* Thumb2Assembler::CreateJumpTable(std::vector<Label*>&& labels, Register base_reg) {
  jump_tables_.emplace_back(std::move(labels));
  JumpTable* table = &jump_tables_.back();
  DCHECK(!table->GetLabel()->IsBound());

  bool use32bit = IsForced32Bit() || IsHighRegister(base_reg);
  uint32_t location = buffer_.Size();
  Fixup::Size size = use32bit ? Fixup::kLiteralAddr4KiB : Fixup::kLiteralAddr1KiB;
  FixupId fixup_id = AddFixup(Fixup::LoadLiteralAddress(location, base_reg, size));
  Emit16(static_cast<uint16_t>(table->GetLabel()->position_));
  table->GetLabel()->LinkTo(fixup_id);
  if (use32bit) {
    Emit16(0);
  }
  DCHECK_EQ(location + GetFixup(fixup_id)->GetSizeInBytes(), buffer_.Size());

  return table;
}

void Thumb2Assembler::EmitJumpTableDispatch(JumpTable* jump_table, Register displacement_reg) {
  CHECK(!IsForced32Bit()) << "Forced 32-bit dispatch not implemented yet";
  // 32-bit ADD doesn't support PC as an input, so we need a two-instruction sequence:
  //   SUB ip, ip, #0
  //   ADD pc, ip, reg
  // TODO: Implement.

  // The anchor's position needs to be fixed up before we can compute offsets - so make it a tracked
  // label.
  BindTrackedLabel(jump_table->GetAnchorLabel());

  add(PC, PC, ShifterOperand(displacement_reg));
}

}  // namespace arm
}  // namespace art
