//===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implements the InstARM32 and OperandARM32 classes, primarily the
/// constructors and the dump()/emit() methods.
///
//===----------------------------------------------------------------------===//

#include "IceInstARM32.h"

#include "IceAssemblerARM32.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceInst.h"
#include "IceOperand.h"
#include "IceRegistersARM32.h"
#include "IceTargetLoweringARM32.h"

namespace Ice {
namespace ARM32 {

namespace {

// maximum number of registers allowed in vpush/vpop.
static constexpr SizeT VpushVpopMaxConsecRegs = 16;

const struct TypeARM32Attributes_ {
  const char *WidthString;    // b, h, <blank>, or d
  const char *VecWidthString; // i8, i16, i32, f32, f64
  int8_t SExtAddrOffsetBits;
  int8_t ZExtAddrOffsetBits;
} TypeARM32Attributes[] = {
#define X(tag, elementty, int_width, vec_width, sbits, ubits, rraddr, shaddr)  \
  { int_width, vec_width, sbits, ubits }                                       \
  ,
    ICETYPEARM32_TABLE
#undef X
};

const struct InstARM32ShiftAttributes_ {
  const char *EmitString;
} InstARM32ShiftAttributes[] = {
#define X(tag, emit)                                                           \
  { emit }                                                                     \
  ,
    ICEINSTARM32SHIFT_TABLE
#undef X
};

const struct InstARM32CondAttributes_ {
  CondARM32::Cond Opposite;
  const char *EmitString;
} InstARM32CondAttributes[] = {
#define X(tag, encode, opp, emit)                                              \
  { CondARM32::opp, emit }                                                     \
  ,
    ICEINSTARM32COND_TABLE
#undef X
};

} // end of anonymous namespace

const char *InstARM32::getWidthString(Type Ty) {
  return TypeARM32Attributes[Ty].WidthString;
}

const char *InstARM32::getVecWidthString(Type Ty) {
  return TypeARM32Attributes[Ty].VecWidthString;
}

const char *InstARM32Pred::predString(CondARM32::Cond Pred) {
  return InstARM32CondAttributes[Pred].EmitString;
}

void InstARM32Pred::dumpOpcodePred(Ostream &Str, const char *Opcode,
                                   Type Ty) const {
  Str << Opcode << getPredicate() << "." << Ty;
}

CondARM32::Cond InstARM32::getOppositeCondition(CondARM32::Cond Cond) {
  return InstARM32CondAttributes[Cond].Opposite;
}

void InstARM32::startNextInst(const Cfg *Func) const {
  if (auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>())
    Asm->incEmitTextSize(InstSize);
}

void InstARM32::emitUsingTextFixup(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  GlobalContext *Ctx = Func->getContext();
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  if (Ctx->getFlags().getDisableHybridAssembly() &&
      Ctx->getFlags().getSkipUnimplemented()) {
    Asm->trap();
    Asm->resetNeedsTextFixup();
    return;
  }
  std::string Buffer;
  llvm::raw_string_ostream StrBuf(Buffer);
  OstreamLocker L(Ctx);
  Ostream &OldStr = Ctx->getStrEmit();
  Ctx->setStrEmit(StrBuf);
  // Start counting instructions here, so that emit() methods don't
  // need to call this for the first instruction.
  Asm->resetEmitTextSize();
  Asm->incEmitTextSize(InstSize);
  emit(Func);
  Ctx->setStrEmit(OldStr);
  if (Ctx->getFlags().getDisableHybridAssembly()) {
    if (Ctx->getFlags().getSkipUnimplemented()) {
      Asm->trap();
    } else {
      llvm::errs() << "Can't assemble: " << StrBuf.str() << "\n";
      UnimplementedError(Ctx->getFlags());
    }
    Asm->resetNeedsTextFixup();
    return;
  }
  Asm->emitTextInst(StrBuf.str(), Asm->getEmitTextSize());
}

void InstARM32::emitIAS(const Cfg *Func) const { emitUsingTextFixup(Func); }

void InstARM32Pred::emitUnaryopGPR(const char *Opcode,
                                   const InstARM32Pred *Inst, const Cfg *Func,
                                   bool NeedsWidthSuffix) {
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 1);
  Type SrcTy = Inst->getSrc(0)->getType();
  Str << "\t" << Opcode;
  if (NeedsWidthSuffix)
    Str << getWidthString(SrcTy);
  Str << Inst->getPredicate() << "\t";
  Inst->getDest()->emit(Func);
  Str << ", ";
  Inst->getSrc(0)->emit(Func);
}

void InstARM32Pred::emitUnaryopFP(const char *Opcode, const InstARM32Pred *Inst,
                                  const Cfg *Func) {
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 1);
  Type SrcTy = Inst->getSrc(0)->getType();
  Str << "\t" << Opcode << Inst->getPredicate() << getVecWidthString(SrcTy)
      << "\t";
  Inst->getDest()->emit(Func);
  Str << ", ";
  Inst->getSrc(0)->emit(Func);
}

void InstARM32Pred::emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst,
                                const Cfg *Func) {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 2);
  Variable *Dest = Inst->getDest();
  assert(Dest == Inst->getSrc(0));
  Str << "\t" << Opcode << Inst->getPredicate() << "\t";
  Dest->emit(Func);
  Str << ", ";
  Inst->getSrc(1)->emit(Func);
}

void InstARM32Pred::emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst,
                                  const Cfg *Func, bool SetFlags) {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 2);
  Str << "\t" << Opcode << (SetFlags ? "s" : "") << Inst->getPredicate()
      << "\t";
  Inst->getDest()->emit(Func);
  Str << ", ";
  Inst->getSrc(0)->emit(Func);
  Str << ", ";
  Inst->getSrc(1)->emit(Func);
}

void InstARM32::emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst,
                                const Cfg *Func) {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 2);
  Str << "\t" << Opcode << getVecWidthString(Inst->getDest()->getType())
      << "\t";
  Inst->getDest()->emit(Func);
  Str << ", ";
  Inst->getSrc(0)->emit(Func);
  Str << ", ";
  Inst->getSrc(1)->emit(Func);
}

void InstARM32::emitFourAddrFP(const char *Opcode, const InstARM32 *Inst,
                               const Cfg *Func) {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 3);
  assert(Inst->getSrc(0) == Inst->getDest());
  Str << "\t" << Opcode << getVecWidthString(Inst->getDest()->getType())
      << "\t";
  Inst->getDest()->emit(Func);
  Str << ", ";
  Inst->getSrc(1)->emit(Func);
  Str << ", ";
  Inst->getSrc(2)->emit(Func);
}

void InstARM32Pred::emitFourAddr(const char *Opcode, const InstARM32Pred *Inst,
                                 const Cfg *Func) {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 3);
  Str << "\t" << Opcode << Inst->getPredicate() << "\t";
  Inst->getDest()->emit(Func);
  Str << ", ";
  Inst->getSrc(0)->emit(Func);
  Str << ", ";
  Inst->getSrc(1)->emit(Func);
  Str << ", ";
  Inst->getSrc(2)->emit(Func);
}

template <InstARM32::InstKindARM32 K>
void InstARM32FourAddrGPR<K>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <InstARM32::InstKindARM32 K>
void InstARM32FourAddrFP<K>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <InstARM32::InstKindARM32 K>
void InstARM32ThreeAddrFP<K>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <> void InstARM32Mla::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 3);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->mla(getDest(), getSrc(0), getSrc(1), getSrc(2), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Mls::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 3);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->mls(getDest(), getSrc(0), getSrc(1), getSrc(2), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Pred::emitCmpLike(const char *Opcode, const InstARM32Pred *Inst,
                                const Cfg *Func) {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(Inst->getSrcSize() == 2);
  Str << "\t" << Opcode << Inst->getPredicate() << "\t";
  Inst->getSrc(0)->emit(Func);
  Str << ", ";
  Inst->getSrc(1)->emit(Func);
}

OperandARM32Mem::OperandARM32Mem(Cfg * /* Func */, Type Ty, Variable *Base,
                                 ConstantInteger32 *ImmOffset, AddrMode Mode)
    : OperandARM32(kMem, Ty), Base(Base), ImmOffset(ImmOffset), Index(nullptr),
      ShiftOp(kNoShift), ShiftAmt(0), Mode(Mode) {
  // The Neg modes are only needed for Reg +/- Reg.
  assert(!isNegAddrMode());
  NumVars = 1;
  Vars = &this->Base;
}

OperandARM32Mem::OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base,
                                 Variable *Index, ShiftKind ShiftOp,
                                 uint16_t ShiftAmt, AddrMode Mode)
    : OperandARM32(kMem, Ty), Base(Base), ImmOffset(0), Index(Index),
      ShiftOp(ShiftOp), ShiftAmt(ShiftAmt), Mode(Mode) {
  if (Index->isRematerializable()) {
    llvm::report_fatal_error("Rematerializable Index Register is not allowed.");
  }
  NumVars = 2;
  Vars = Func->allocateArrayOf<Variable *>(2);
  Vars[0] = Base;
  Vars[1] = Index;
}

OperandARM32ShAmtImm::OperandARM32ShAmtImm(ConstantInteger32 *SA)
    : OperandARM32(kShAmtImm, IceType_i8), ShAmt(SA) {}

bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) {
  int32_t Bits = SignExt ? TypeARM32Attributes[Ty].SExtAddrOffsetBits
                         : TypeARM32Attributes[Ty].ZExtAddrOffsetBits;
  if (Bits == 0)
    return Offset == 0;
  // Note that encodings for offsets are sign-magnitude for ARM, so we check
  // with IsAbsoluteUint().
  // Scalar fp, and vector types require an offset that is aligned to a multiple
  // of 4.
  if (isScalarFloatingType(Ty) || isVectorType(Ty))
    return Utils::IsAligned(Offset, 4) && Utils::IsAbsoluteUint(Bits, Offset);
  return Utils::IsAbsoluteUint(Bits, Offset);
}

OperandARM32FlexImm::OperandARM32FlexImm(Cfg * /* Func */, Type Ty,
                                         uint32_t Imm, uint32_t RotateAmt)
    : OperandARM32Flex(kFlexImm, Ty), Imm(Imm), RotateAmt(RotateAmt) {
  NumVars = 0;
  Vars = nullptr;
}

bool OperandARM32FlexImm::canHoldImm(uint32_t Immediate, uint32_t *RotateAmt,
                                     uint32_t *Immed_8) {
  // Avoid the more expensive test for frequent small immediate values.
  if (Immediate <= 0xFF) {
    *RotateAmt = 0;
    *Immed_8 = Immediate;
    return true;
  }
  // Note that immediate must be unsigned for the test to work correctly.
  for (int Rot = 1; Rot < 16; Rot++) {
    uint32_t Imm8 = Utils::rotateLeft32(Immediate, 2 * Rot);
    if (Imm8 <= 0xFF) {
      *RotateAmt = Rot;
      *Immed_8 = Imm8;
      return true;
    }
  }
  return false;
}

OperandARM32FlexFpImm::OperandARM32FlexFpImm(Cfg * /*Func*/, Type Ty,
                                             uint32_t ModifiedImm)
    : OperandARM32Flex(kFlexFpImm, Ty), ModifiedImm(ModifiedImm) {}

bool OperandARM32FlexFpImm::canHoldImm(Operand *C, uint32_t *ModifiedImm) {
  switch (C->getType()) {
  default:
    llvm::report_fatal_error("Unhandled fp constant type.");
  case IceType_f32: {
    // We violate llvm naming conventions a bit here so that the constants are
    // named after the bit fields they represent. See "A7.5.1 Operation of
    // modified immediate constants, Floating-point" in the ARM ARM.
    static constexpr uint32_t a = 0x80000000u;
    static constexpr uint32_t B = 0x40000000;
    static constexpr uint32_t bbbbb = 0x3E000000;
    static constexpr uint32_t cdefgh = 0x01F80000;
    static constexpr uint32_t AllowedBits = a | B | bbbbb | cdefgh;
    static_assert(AllowedBits == 0xFFF80000u,
                  "Invalid mask for f32 modified immediates.");
    const float F32 = llvm::cast<ConstantFloat>(C)->getValue();
    const uint32_t I32 = Utils::bitCopy<uint32_t>(F32);
    if (I32 & ~AllowedBits) {
      // constant has disallowed bits.
      return false;
    }

    if ((I32 & bbbbb) != bbbbb && (I32 & bbbbb)) {
      // not all bbbbb bits are 0 or 1.
      return false;
    }

    if (((I32 & B) != 0) == ((I32 & bbbbb) != 0)) {
      // B ^ b = 0;
      return false;
    }

    *ModifiedImm = ((I32 & a) ? 0x80 : 0x00) | ((I32 & bbbbb) ? 0x40 : 0x00) |
                   ((I32 & cdefgh) >> 19);
    return true;
  }
  case IceType_f64: {
    static constexpr uint32_t a = 0x80000000u;
    static constexpr uint32_t B = 0x40000000;
    static constexpr uint32_t bbbbbbbb = 0x3FC00000;
    static constexpr uint32_t cdefgh = 0x003F0000;
    static constexpr uint32_t AllowedBits = a | B | bbbbbbbb | cdefgh;
    static_assert(AllowedBits == 0xFFFF0000u,
                  "Invalid mask for f64 modified immediates.");
    const double F64 = llvm::cast<ConstantDouble>(C)->getValue();
    const uint64_t I64 = Utils::bitCopy<uint64_t>(F64);
    if (I64 & 0xFFFFFFFFu) {
      // constant has disallowed bits.
      return false;
    }
    const uint32_t I32 = I64 >> 32;

    if (I32 & ~AllowedBits) {
      // constant has disallowed bits.
      return false;
    }

    if ((I32 & bbbbbbbb) != bbbbbbbb && (I32 & bbbbbbbb)) {
      // not all bbbbb bits are 0 or 1.
      return false;
    }

    if (((I32 & B) != 0) == ((I32 & bbbbbbbb) != 0)) {
      // B ^ b = 0;
      return false;
    }

    *ModifiedImm = ((I32 & a) ? 0x80 : 0x00) |
                   ((I32 & bbbbbbbb) ? 0x40 : 0x00) | ((I32 & cdefgh) >> 16);
    return true;
  }
  }
}

OperandARM32FlexFpZero::OperandARM32FlexFpZero(Cfg * /*Func*/, Type Ty)
    : OperandARM32Flex(kFlexFpZero, Ty) {}

OperandARM32FlexReg::OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg,
                                         ShiftKind ShiftOp, Operand *ShiftAmt)
    : OperandARM32Flex(kFlexReg, Ty), Reg(Reg), ShiftOp(ShiftOp),
      ShiftAmt(ShiftAmt) {
  NumVars = 1;
  auto *ShiftVar = llvm::dyn_cast_or_null<Variable>(ShiftAmt);
  if (ShiftVar)
    ++NumVars;
  Vars = Func->allocateArrayOf<Variable *>(NumVars);
  Vars[0] = Reg;
  if (ShiftVar)
    Vars[1] = ShiftVar;
}

InstARM32Br::InstARM32Br(Cfg *Func, const CfgNode *TargetTrue,
                         const CfgNode *TargetFalse,
                         const InstARM32Label *Label, CondARM32::Cond Pred)
    : InstARM32Pred(Func, InstARM32::Br, 0, nullptr, Pred),
      TargetTrue(TargetTrue), TargetFalse(TargetFalse), Label(Label) {}

bool InstARM32Br::optimizeBranch(const CfgNode *NextNode) {
  // If there is no next block, then there can be no fallthrough to optimize.
  if (NextNode == nullptr)
    return false;
  // Intra-block conditional branches can't be optimized.
  if (Label)
    return false;
  // If there is no fallthrough node, such as a non-default case label for a
  // switch instruction, then there is no opportunity to optimize.
  if (getTargetFalse() == nullptr)
    return false;

  // Unconditional branch to the next node can be removed.
  if (isUnconditionalBranch() && getTargetFalse() == NextNode) {
    assert(getTargetTrue() == nullptr);
    setDeleted();
    return true;
  }
  // If the fallthrough is to the next node, set fallthrough to nullptr to
  // indicate.
  if (getTargetFalse() == NextNode) {
    TargetFalse = nullptr;
    return true;
  }
  // If TargetTrue is the next node, and TargetFalse is not nullptr (which was
  // already tested above), then invert the branch condition, swap the targets,
  // and set new fallthrough to nullptr.
  if (getTargetTrue() == NextNode) {
    assert(Predicate != CondARM32::AL);
    setPredicate(getOppositeCondition(getPredicate()));
    TargetTrue = getTargetFalse();
    TargetFalse = nullptr;
    return true;
  }
  return false;
}

bool InstARM32Br::repointEdges(CfgNode *OldNode, CfgNode *NewNode) {
  bool Found = false;
  if (TargetFalse == OldNode) {
    TargetFalse = NewNode;
    Found = true;
  }
  if (TargetTrue == OldNode) {
    TargetTrue = NewNode;
    Found = true;
  }
  return Found;
}

template <InstARM32::InstKindARM32 K>
void InstARM32ThreeAddrGPR<K>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <> void InstARM32Adc::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->adc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Add::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->add(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  assert(!Asm->needsTextFixup());
}

template <> void InstARM32And::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->and_(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Bic::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->bic(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Eor::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->eor(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Asr::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->asr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Lsl::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->lsl(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Lsr::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->lsr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Orr::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->orr(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Mul::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->mul(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Rsb::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->rsb(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Rsc::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->rsc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Sbc::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->sbc(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Sdiv::emitIAS(const Cfg *Func) const {
  assert(!SetFlags);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->sdiv(getDest(), getSrc(0), getSrc(1), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Sub::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->sub(getDest(), getSrc(0), getSrc(1), SetFlags, getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Udiv::emitIAS(const Cfg *Func) const {
  assert(!SetFlags);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->udiv(getDest(), getSrc(0), getSrc(1), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Vadd::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  Type DestTy = Dest->getType();
  switch (DestTy) {
  default:
    llvm::report_fatal_error("Vadd not defined on type " +
                             typeIceString(DestTy));
  case IceType_v16i8:
  case IceType_v8i16:
  case IceType_v4i32:
    Asm->vaddqi(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
    break;
  case IceType_v4f32:
    Asm->vaddqf(Dest, getSrc(0), getSrc(1));
    break;
  case IceType_f32:
    Asm->vadds(Dest, getSrc(0), getSrc(1), CondARM32::AL);
    break;
  case IceType_f64:
    Asm->vaddd(Dest, getSrc(0), getSrc(1), CondARM32::AL);
    break;
  }
  assert(!Asm->needsTextFixup());
}

template <> void InstARM32Vand::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  switch (Dest->getType()) {
  default:
    llvm::report_fatal_error("Vand not defined on type " +
                             typeIceString(Dest->getType()));
  case IceType_v4i1:
  case IceType_v8i1:
  case IceType_v16i1:
  case IceType_v16i8:
  case IceType_v8i16:
  case IceType_v4i32:
    Asm->vandq(Dest, getSrc(0), getSrc(1));
  }
  assert(!Asm->needsTextFixup());
}

template <> void InstARM32Vdiv::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  switch (Dest->getType()) {
  default:
    // TODO(kschimpf) Figure if more cases are needed.
    Asm->setNeedsTextFixup();
    break;
  case IceType_f32:
    Asm->vdivs(getDest(), getSrc(0), getSrc(1), CondARM32::AL);
    break;
  case IceType_f64:
    Asm->vdivd(getDest(), getSrc(0), getSrc(1), CondARM32::AL);
    break;
  }
  assert(!Asm->needsTextFixup());
}

template <> void InstARM32Veor::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  if (isVectorType(Dest->getType())) {
    Asm->veorq(Dest, getSrc(0), getSrc(1));
    assert(!Asm->needsTextFixup());
    return;
  }
  assert(Dest->getType() == IceType_f64);
  Asm->veord(Dest, getSrc(0), getSrc(1));
  assert(!Asm->needsTextFixup());
}

template <> void InstARM32Vmla::emitIAS(const Cfg *Func) const {
  // Note: Dest == getSrc(0) for four address FP instructions.
  assert(getSrcSize() == 3);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  switch (Dest->getType()) {
  default:
    // TODO(kschimpf) Figure out how vector operations apply.
    emitUsingTextFixup(Func);
    return;
  case IceType_f32:
    Asm->vmlas(getDest(), getSrc(1), getSrc(2), CondARM32::AL);
    assert(!Asm->needsTextFixup());
    return;
  case IceType_f64:
    Asm->vmlad(getDest(), getSrc(1), getSrc(2), CondARM32::AL);
    assert(!Asm->needsTextFixup());
    return;
  }
}

template <> void InstARM32Vmls::emitIAS(const Cfg *Func) const {
  // Note: Dest == getSrc(0) for four address FP instructions.
  assert(getSrcSize() == 3);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  switch (Dest->getType()) {
  default:
    // TODO(kschimpf) Figure out how vector operations apply.
    emitUsingTextFixup(Func);
    return;
  case IceType_f32:
    Asm->vmlss(getDest(), getSrc(1), getSrc(2), CondARM32::AL);
    assert(!Asm->needsTextFixup());
    return;
  case IceType_f64:
    Asm->vmlsd(getDest(), getSrc(1), getSrc(2), CondARM32::AL);
    assert(!Asm->needsTextFixup());
    return;
  }
}

template <> void InstARM32Vorr::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  switch (Dest->getType()) {
  default:
    llvm::report_fatal_error("Vorr not defined on type " +
                             typeIceString(Dest->getType()));
  case IceType_v4i1:
  case IceType_v8i1:
  case IceType_v16i1:
  case IceType_v16i8:
  case IceType_v8i16:
  case IceType_v4i32:
    Asm->vorrq(Dest, getSrc(0), getSrc(1));
  }
  assert(!Asm->needsTextFixup());
}

template <> void InstARM32Vsub::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  Type DestTy = Dest->getType();
  switch (DestTy) {
  default:
    llvm::report_fatal_error("Vsub not defined on type " +
                             typeIceString(DestTy));
  case IceType_v16i8:
  case IceType_v8i16:
  case IceType_v4i32:
    Asm->vsubqi(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
    break;
  case IceType_v4f32:
    Asm->vsubqf(Dest, getSrc(0), getSrc(1));
    break;
  case IceType_f32:
    Asm->vsubs(getDest(), getSrc(0), getSrc(1), CondARM32::AL);
    break;
  case IceType_f64:
    Asm->vsubd(getDest(), getSrc(0), getSrc(1), CondARM32::AL);
    break;
  }
  assert(!Asm->needsTextFixup());
}

template <> void InstARM32Vmul::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  const Type DestTy = Dest->getType();
  switch (DestTy) {
  default:
    llvm::report_fatal_error("Vmul not defined on type " +
                             typeIceString(DestTy));

  case IceType_v16i8:
  case IceType_v8i16:
  case IceType_v4i32:
    Asm->vmulqi(typeElementType(DestTy), Dest, getSrc(0), getSrc(1));
    break;
  case IceType_v4f32:
    Asm->vmulqf(Dest, getSrc(0), getSrc(1));
    break;
  case IceType_f32:
    Asm->vmuls(Dest, getSrc(0), getSrc(1), CondARM32::AL);
    break;
  case IceType_f64:
    Asm->vmuld(Dest, getSrc(0), getSrc(1), CondARM32::AL);
    break;
  }
  assert(!Asm->needsTextFixup());
}

InstARM32Call::InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget)
    : InstARM32(Func, InstARM32::Call, 1, Dest) {
  HasSideEffects = true;
  addSource(CallTarget);
}

InstARM32Label::InstARM32Label(Cfg *Func, TargetARM32 *Target)
    : InstARM32(Func, InstARM32::Label, 0, nullptr),
      Number(Target->makeNextLabelNumber()) {}

IceString InstARM32Label::getName(const Cfg *Func) const {
  return ".L" + Func->getFunctionName() + "$local$__" + std::to_string(Number);
}

namespace {
// Requirements for Push/Pop:
//  1) All the Variables have the same type;
//  2) All the variables have registers assigned to them.
void validatePushOrPopRegisterListOrDie(const VarList &RegList) {
  Type PreviousTy = IceType_void;
  for (Variable *Reg : RegList) {
    if (PreviousTy != IceType_void && Reg->getType() != PreviousTy) {
      llvm::report_fatal_error("Type mismatch when popping/pushing "
                               "registers.");
    }

    if (!Reg->hasReg()) {
      llvm::report_fatal_error("Push/pop operand does not have a register "
                               "assigned to it.");
    }

    PreviousTy = Reg->getType();
  }
}
} // end of anonymous namespace

void InstARM32RegisterStackOp::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  emitUsingForm(Func, Emit_Text);
}

void InstARM32RegisterStackOp::emitIAS(const Cfg *Func) const {
  emitUsingForm(Func, Emit_Binary);
  assert(!Func->getAssembler<ARM32::AssemblerARM32>()->needsTextFixup());
}

void InstARM32RegisterStackOp::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << getDumpOpcode() << " ";
  SizeT NumRegs = getNumStackRegs();
  for (SizeT I = 0; I < NumRegs; ++I) {
    if (I > 0)
      Str << ", ";
    getStackReg(I)->dump(Func);
  }
}

void InstARM32RegisterStackOp::emitGPRsAsText(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\t" << getGPROpcode() << "\t{";
  getStackReg(0)->emit(Func);
  const SizeT NumRegs = getNumStackRegs();
  for (SizeT i = 1; i < NumRegs; ++i) {
    Str << ", ";
    getStackReg(i)->emit(Func);
  }
  Str << "}";
}

void InstARM32RegisterStackOp::emitSRegsAsText(const Cfg *Func,
                                               const Variable *BaseReg,
                                               SizeT RegCount) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\t" << getSRegOpcode() << "\t{";
  bool IsFirst = true;
  int32_t Base = BaseReg->getRegNum();
  for (SizeT i = 0; i < RegCount; ++i) {
    if (IsFirst)
      IsFirst = false;
    else
      Str << ", ";
    Str << RegARM32::getRegName(Base + i);
  }
  Str << "}";
}

namespace {

bool isAssignedConsecutiveRegisters(const Variable *Before,
                                    const Variable *After) {
  assert(Before->hasReg());
  assert(After->hasReg());
  return Before->getRegNum() + 1 == After->getRegNum();
}

} // end of anonymous namespace

void InstARM32RegisterStackOp::emitUsingForm(const Cfg *Func,
                                             const EmitForm Form) const {
  SizeT NumRegs = getNumStackRegs();
  assert(NumRegs);

  const auto *Reg = llvm::cast<Variable>(getStackReg(0));
  if (isScalarIntegerType(Reg->getType())) {
    // Pop GPR registers.
    SizeT IntegerCount = 0;
    ARM32::IValueT GPRegisters = 0;
    const Variable *LastDest = nullptr;
    for (SizeT i = 0; i < NumRegs; ++i) {
      const Variable *Var = getStackReg(i);
      assert(Var->hasReg() && "stack op only applies to registers");
      int32_t Reg = RegARM32::getEncodedGPR(Var->getRegNum());
      LastDest = Var;
      GPRegisters |= (1 << Reg);
      ++IntegerCount;
    }
    if (IntegerCount == 1) {
      emitSingleGPR(Func, Form, LastDest);
    } else {
      emitMultipleGPRs(Func, Form, GPRegisters);
    }
  } else {
    // Pop vector/floating point registers.
    const Variable *BaseReg = nullptr;
    SizeT RegCount = 0;
    for (SizeT i = 0; i < NumRegs; ++i) {
      const Variable *NextReg = getStackReg(i);
      if (BaseReg == nullptr) {
        BaseReg = NextReg;
        RegCount = 1;
      } else if (RegCount < VpushVpopMaxConsecRegs &&
                 isAssignedConsecutiveRegisters(Reg, NextReg)) {
        ++RegCount;
      } else {
        emitSRegs(Func, Form, BaseReg, RegCount);
        if (Form == Emit_Text && BuildDefs::dump()) {
          startNextInst(Func);
          Func->getContext()->getStrEmit() << "\n";
        }
        BaseReg = NextReg;
        RegCount = 1;
      }
      Reg = NextReg;
    }
    if (RegCount) {
      emitSRegs(Func, Form, BaseReg, RegCount);
    }
  }
}

InstARM32Pop::InstARM32Pop(Cfg *Func, const VarList &Dests)
    : InstARM32RegisterStackOp(Func, InstARM32::Pop, 0, nullptr), Dests(Dests) {
  // Track modifications to Dests separately via FakeDefs. Also, a pop
  // instruction affects the stack pointer and so it should not be allowed to
  // be automatically dead-code eliminated. This is automatic since we leave
  // the Dest as nullptr.
  validatePushOrPopRegisterListOrDie(Dests);
}

InstARM32Push::InstARM32Push(Cfg *Func, const VarList &Srcs)
    : InstARM32RegisterStackOp(Func, InstARM32::Push, Srcs.size(), nullptr) {
  validatePushOrPopRegisterListOrDie(Srcs);
  for (Variable *Source : Srcs) {
    addSource(Source);
  }
}

InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source)
    : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) {
  addSource(LR);
  if (Source)
    addSource(Source);
}

InstARM32Str::InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
                           CondARM32::Cond Predicate)
    : InstARM32Pred(Func, InstARM32::Str, 2, nullptr, Predicate) {
  addSource(Value);
  addSource(Mem);
}

InstARM32Strex::InstARM32Strex(Cfg *Func, Variable *Dest, Variable *Value,
                               OperandARM32Mem *Mem, CondARM32::Cond Predicate)
    : InstARM32Pred(Func, InstARM32::Strex, 2, Dest, Predicate) {
  addSource(Value);
  addSource(Mem);
}

InstARM32Trap::InstARM32Trap(Cfg *Func)
    : InstARM32(Func, InstARM32::Trap, 0, nullptr) {}

InstARM32Umull::InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi,
                               Variable *Src0, Variable *Src1,
                               CondARM32::Cond Predicate)
    : InstARM32Pred(Func, InstARM32::Umull, 2, DestLo, Predicate),
      // DestHi is expected to have a FakeDef inserted by the lowering code.
      DestHi(DestHi) {
  addSource(Src0);
  addSource(Src1);
}

InstARM32Vcvt::InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src,
                             VcvtVariant Variant, CondARM32::Cond Predicate)
    : InstARM32Pred(Func, InstARM32::Vcvt, 1, Dest, Predicate),
      Variant(Variant) {
  addSource(Src);
}

InstARM32Mov::InstARM32Mov(Cfg *Func, Variable *Dest, Operand *Src,
                           CondARM32::Cond Predicate)
    : InstARM32Pred(Func, InstARM32::Mov, 2, Dest, Predicate) {
  auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest);
  auto *Src64 = llvm::dyn_cast<Variable64On32>(Src);

  assert(Dest64 == nullptr || Src64 == nullptr);

  if (Dest64 != nullptr) {
    // this-> is needed below because there is a parameter named Dest.
    this->Dest = Dest64->getLo();
    DestHi = Dest64->getHi();
  }

  if (Src64 == nullptr) {
    addSource(Src);
  } else {
    addSource(Src64->getLo());
    addSource(Src64->getHi());
  }
}

template <InstARM32::InstKindARM32 K>
void InstARM32CmpLike<K>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <> void InstARM32Cmn::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 2);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->cmn(getSrc(0), getSrc(1), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Cmp::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 2);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->cmp(getSrc(0), getSrc(1), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Tst::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 2);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->tst(getSrc(0), getSrc(1), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

InstARM32Vcmp::InstARM32Vcmp(Cfg *Func, Variable *Src0, Operand *Src1,
                             CondARM32::Cond Predicate)
    : InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) {
  HasSideEffects = true;
  addSource(Src0);
  addSource(Src1);
}

InstARM32Vmrs::InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate)
    : InstARM32Pred(Func, InstARM32::Vmrs, 0, nullptr, Predicate) {
  HasSideEffects = true;
}

InstARM32Vabs::InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src,
                             CondARM32::Cond Predicate)
    : InstARM32Pred(Func, InstARM32::Vabs, 1, Dest, Predicate) {
  addSource(Src);
}

InstARM32Dmb::InstARM32Dmb(Cfg *Func)
    : InstARM32Pred(Func, InstARM32::Dmb, 0, nullptr, CondARM32::AL) {}

// ======================== Dump routines ======================== //

// Two-addr ops
template <> const char *InstARM32Movt::Opcode = "movt";
// Unary ops
template <> const char *InstARM32Movw::Opcode = "movw";
template <> const char *InstARM32Clz::Opcode = "clz";
template <> const char *InstARM32Mvn::Opcode = "mvn";
template <> const char *InstARM32Rbit::Opcode = "rbit";
template <> const char *InstARM32Rev::Opcode = "rev";
template <> const char *InstARM32Sxt::Opcode = "sxt"; // still requires b/h
template <> const char *InstARM32Uxt::Opcode = "uxt"; // still requires b/h
// FP
template <> const char *InstARM32Vsqrt::Opcode = "vsqrt";
// Mov-like ops
template <> const char *InstARM32Ldr::Opcode = "ldr";
template <> const char *InstARM32Ldrex::Opcode = "ldrex";
// Three-addr ops
template <> const char *InstARM32Adc::Opcode = "adc";
template <> const char *InstARM32Add::Opcode = "add";
template <> const char *InstARM32And::Opcode = "and";
template <> const char *InstARM32Asr::Opcode = "asr";
template <> const char *InstARM32Bic::Opcode = "bic";
template <> const char *InstARM32Eor::Opcode = "eor";
template <> const char *InstARM32Lsl::Opcode = "lsl";
template <> const char *InstARM32Lsr::Opcode = "lsr";
template <> const char *InstARM32Mul::Opcode = "mul";
template <> const char *InstARM32Orr::Opcode = "orr";
template <> const char *InstARM32Rsb::Opcode = "rsb";
template <> const char *InstARM32Rsc::Opcode = "rsc";
template <> const char *InstARM32Sbc::Opcode = "sbc";
template <> const char *InstARM32Sdiv::Opcode = "sdiv";
template <> const char *InstARM32Sub::Opcode = "sub";
template <> const char *InstARM32Udiv::Opcode = "udiv";
// FP
template <> const char *InstARM32Vadd::Opcode = "vadd";
template <> const char *InstARM32Vand::Opcode = "vand";
template <> const char *InstARM32Vdiv::Opcode = "vdiv";
template <> const char *InstARM32Veor::Opcode = "veor";
template <> const char *InstARM32Vmla::Opcode = "vmla";
template <> const char *InstARM32Vmls::Opcode = "vmls";
template <> const char *InstARM32Vmul::Opcode = "vmul";
template <> const char *InstARM32Vorr::Opcode = "vorr";
template <> const char *InstARM32Vsub::Opcode = "vsub";
// Four-addr ops
template <> const char *InstARM32Mla::Opcode = "mla";
template <> const char *InstARM32Mls::Opcode = "mls";
// Cmp-like ops
template <> const char *InstARM32Cmn::Opcode = "cmn";
template <> const char *InstARM32Cmp::Opcode = "cmp";
template <> const char *InstARM32Tst::Opcode = "tst";

void InstARM32::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "[ARM32] ";
  Inst::dump(Func);
}

void InstARM32Mov::emitMultiDestSingleSource(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Variable *DestLo = getDest();
  Variable *DestHi = getDestHi();
  auto *Src = llvm::cast<Variable>(getSrc(0));

  assert(DestHi->hasReg());
  assert(DestLo->hasReg());
  assert(Src->hasReg());

  Str << "\t"
         "vmov" << getPredicate() << "\t";
  DestLo->emit(Func);
  Str << ", ";
  DestHi->emit(Func);
  Str << ", ";
  Src->emit(Func);
}

void InstARM32Mov::emitSingleDestMultiSource(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Variable *Dest = getDest();
  auto *SrcLo = llvm::cast<Variable>(getSrc(0));
  auto *SrcHi = llvm::cast<Variable>(getSrc(1));

  assert(SrcHi->hasReg());
  assert(SrcLo->hasReg());
  assert(Dest->hasReg());
  assert(getSrcSize() == 2);

  Str << "\t"
         "vmov" << getPredicate() << "\t";
  Dest->emit(Func);
  Str << ", ";
  SrcLo->emit(Func);
  Str << ", ";
  SrcHi->emit(Func);
}

namespace {

bool isVariableWithoutRegister(const Operand *Op) {
  if (const auto *OpV = llvm::dyn_cast<Variable>(Op)) {
    return !OpV->hasReg();
  }
  return false;
}
bool isMemoryAccess(Operand *Op) {
  return isVariableWithoutRegister(Op) || llvm::isa<OperandARM32Mem>(Op);
}

bool isMoveBetweenCoreAndVFPRegisters(Variable *Dest, Operand *Src) {
  const Type DestTy = Dest->getType();
  const Type SrcTy = Src->getType();
  return !isVectorType(DestTy) && !isVectorType(SrcTy) &&
         (isScalarIntegerType(DestTy) == isScalarFloatingType(SrcTy));
}

} // end of anonymous namespace

void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Variable *Dest = getDest();

  if (!Dest->hasReg()) {
    llvm::report_fatal_error("mov can't store.");
  }

  Operand *Src0 = getSrc(0);
  if (isMemoryAccess(Src0)) {
    llvm::report_fatal_error("mov can't load.");
  }

  Type Ty = Dest->getType();
  const bool IsVector = isVectorType(Ty);
  const bool IsScalarFP = isScalarFloatingType(Ty);
  const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0);
  const bool IsVMove = (IsVector || IsScalarFP || CoreVFPMove);
  const char *Opcode = IsVMove ? "vmov" : "mov";
  // when vmov{c}'ing, we need to emit a width string. Otherwise, the
  // assembler might be tempted to assume we want a vector vmov{c}, and that
  // is disallowed because ARM.
  const char *WidthString = !CoreVFPMove ? getVecWidthString(Ty) : "";
  Str << "\t" << Opcode;
  if (IsVMove) {
    Str << getPredicate() << WidthString;
  } else {
    Str << WidthString << getPredicate();
  }
  Str << "\t";
  Dest->emit(Func);
  Str << ", ";
  Src0->emit(Func);
}

void InstARM32Mov::emitIASScalarVFPMove(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Operand *Src0 = getSrc(0);
  Variable *Dest = getDest();
  switch (Dest->getType()) {
  default:
    assert(false && "Do not know how to emit scalar FP move for type.");
    break;
  case IceType_f32:
    if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
      Asm->vmovss(Dest, Var, getPredicate());
      return;
    } else if (const auto *FpImm =
                   llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
      Asm->vmovs(Dest, FpImm, getPredicate());
      return;
    }
    assert(!Asm->needsTextFixup());
    return;
  case IceType_f64:
    if (const auto *Var = llvm::dyn_cast<Variable>(Src0)) {
      Asm->vmovdd(Dest, Var, getPredicate());
      return;
    } else if (const auto *FpImm =
                   llvm::dyn_cast<OperandARM32FlexFpImm>(Src0)) {
      Asm->vmovd(Dest, FpImm, getPredicate());
      return;
    }
    assert(!Asm->needsTextFixup());
    return;
  }
  // TODO(kschimpf) Handle register to register move.
  Asm->setNeedsTextFixup();
  return;
}

void InstARM32Mov::emitIASCoreVFPMove(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Operand *Src0 = getSrc(0);
  if (!llvm::isa<Variable>(Src0))
    // TODO(kschimpf) Handle moving constants into registers.
    return Asm->setNeedsTextFixup();

  // Move register to register.
  Variable *Dest = getDest();
  // TODO(kschimpf) Consider merging methods emitIAS.. methods into
  // a single case statement.
  switch (Dest->getType()) {
  default:
    // TODO(kschimpf): Fill this out more.
    return Asm->setNeedsTextFixup();
  case IceType_i1:
  case IceType_i8:
  case IceType_i16:
  case IceType_i32:
    assert(Src0->getType() == IceType_f32 && "Expected int to float move");
    Asm->vmovrs(Dest, Src0, getPredicate());
    return;
  case IceType_i64:
    assert(false && "i64 to float moves not handled here!");
    return;
  case IceType_f32:
    switch (Src0->getType()) {
    default:
      assert(false && "Expected float to int move");
      return;
    case IceType_i1:
    case IceType_i8:
    case IceType_i16:
    case IceType_i32:
      return Asm->vmovsr(Dest, Src0, getPredicate());
    }
  }
}

void InstARM32Mov::emitIASSingleDestSingleSource(const Cfg *Func) const {
  Variable *Dest = getDest();
  Operand *Src0 = getSrc(0);

  if (!Dest->hasReg()) {
    llvm::report_fatal_error("mov can't store.");
  }

  if (isMemoryAccess(Src0)) {
    llvm::report_fatal_error("mov can't load.");
  }

  if (isMoveBetweenCoreAndVFPRegisters(Dest, Src0))
    return emitIASCoreVFPMove(Func);

  const Type DestTy = Dest->getType();
  if (isScalarFloatingType(DestTy))
    return emitIASScalarVFPMove(Func);

  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  if (isVectorType(DestTy))
    return Asm->setNeedsTextFixup();

  return Asm->mov(Dest, Src0, getPredicate());
}

void InstARM32Mov::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
  if (isMultiDest()) {
    emitMultiDestSingleSource(Func);
    return;
  }

  if (isMultiSource()) {
    emitSingleDestMultiSource(Func);
    return;
  }

  emitSingleDestSingleSource(Func);
}

void InstARM32Mov::emitIAS(const Cfg *Func) const {
  // TODO(kschimpf) Flatten this to a switch statement of dest type. That is,
  // combine code of emitIASSingleDestSingleSource, emitIASCoreVFPMove,
  // emitIASScalarVFPMove, emitDoubleToI64Move, and emitI64ToDoubleMove.
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
  if (isMultiDest())
    Asm->vmovrrd(getDest(), getDestHi(), getSrc(0), getPredicate());
  else if (isMultiSource())
    Asm->vmovdrr(getDest(), getSrc(0), getSrc(1), getPredicate());
  else
    emitIASSingleDestSingleSource(Func);
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Mov::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(getSrcSize() == 1 || getSrcSize() == 2);
  Ostream &Str = Func->getContext()->getStrDump();
  Variable *Dest = getDest();
  Variable *DestHi = getDestHi();
  Dest->dump(Func);
  if (DestHi) {
    Str << ", ";
    DestHi->dump(Func);
  }

  dumpOpcodePred(Str, " = mov", getDest()->getType());
  Str << " ";

  dumpSources(Func);
}

void InstARM32Br::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\t"
         "b" << getPredicate() << "\t";
  if (Label) {
    Str << Label->getName(Func);
  } else {
    if (isUnconditionalBranch()) {
      Str << getTargetFalse()->getAsmName();
    } else {
      Str << getTargetTrue()->getAsmName();
      if (getTargetFalse()) {
        startNextInst(Func);
        Str << "\n\t"
            << "b"
            << "\t" << getTargetFalse()->getAsmName();
      }
    }
  }
}

void InstARM32Br::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  if (Label) {
    Asm->b(Asm->getOrCreateLocalLabel(Label->getNumber()), getPredicate());
  } else if (isUnconditionalBranch()) {
    Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()),
           getPredicate());
  } else {
    Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()),
           getPredicate());
    if (const CfgNode *False = getTargetFalse())
      Asm->b(Asm->getOrCreateCfgNodeLabel(False->getIndex()), CondARM32::AL);
  }
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Br::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "br ";

  if (getPredicate() == CondARM32::AL) {
    Str << "label %"
        << (Label ? Label->getName(Func) : getTargetFalse()->getName());
    return;
  }

  if (Label) {
    Str << getPredicate() << ", label %" << Label->getName(Func);
  } else {
    Str << getPredicate() << ", label %" << getTargetTrue()->getName();
    if (getTargetFalse()) {
      Str << ", label %" << getTargetFalse()->getName();
    }
  }
}

void InstARM32Call::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 1);
  if (llvm::isa<ConstantInteger32>(getCallTarget())) {
    // This shouldn't happen (typically have to copy the full 32-bits to a
    // register and do an indirect jump).
    llvm::report_fatal_error("ARM32Call to ConstantInteger32");
  } else if (const auto *CallTarget =
                 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
    // Calls only have 24-bits, but the linker should insert veneers to extend
    // the range if needed.
    Str << "\t"
           "bl"
           "\t";
    CallTarget->emitWithoutPrefix(Func->getTarget());
  } else {
    Str << "\t"
           "blx"
           "\t";
    getCallTarget()->emit(Func);
  }
}

void InstARM32Call::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  if (llvm::isa<ConstantInteger32>(getCallTarget())) {
    // This shouldn't happen (typically have to copy the full 32-bits to a
    // register and do an indirect jump).
    llvm::report_fatal_error("ARM32Call to ConstantInteger32");
  } else if (const auto *CallTarget =
                 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
    // Calls only have 24-bits, but the linker should insert veneers to extend
    // the range if needed.
    Asm->bl(CallTarget);
  } else {
    Asm->blx(getCallTarget());
  }
  if (Asm->needsTextFixup())
    return emitUsingTextFixup(Func);
}

void InstARM32Call::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  if (getDest()) {
    dumpDest(Func);
    Str << " = ";
  }
  Str << "call ";
  getCallTarget()->dump(Func);
}

void InstARM32Label::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  // A label is not really an instruction. Hence, we need to fix the
  // emitted text size.
  if (auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>())
    Asm->decEmitTextSize(InstSize);
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << getName(Func) << ":";
}

void InstARM32Label::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->bindLocalLabel(Func, this, Number);
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Label::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << getName(Func) << ":";
}

template <InstARM32::InstKindARM32 K>
void InstARM32LoadBase<K>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <> void InstARM32Ldr::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 1);
  assert(getDest()->hasReg());
  Variable *Dest = getDest();
  Type Ty = Dest->getType();
  const bool IsVector = isVectorType(Ty);
  const bool IsScalarFloat = isScalarFloatingType(Ty);
  const char *ActualOpcode =
      IsVector ? "vld1" : (IsScalarFloat ? "vldr" : "ldr");
  const char *VectorMarker = IsVector ? ".64" : "";
  const char *WidthString = IsVector ? "" : getWidthString(Ty);
  Str << "\t" << ActualOpcode;
  const bool IsVInst = IsVector || IsScalarFloat;
  if (IsVInst) {
    Str << getPredicate() << WidthString;
  } else {
    Str << WidthString << getPredicate();
  }
  Str << VectorMarker << "\t";
  getDest()->emit(Func);
  Str << ", ";
  getSrc(0)->emit(Func);
}

template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  Variable *Dest = getDest();
  const Type DestTy = Dest->getType();
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  if (isScalarFloatingType(DestTy)) {
    switch (DestTy) {
    default:
      // TODO(kschimpf) Does this happen?
      Asm->setNeedsTextFixup();
      break;
    case IceType_f32:
      Asm->vldrs(Dest, getSrc(0), getPredicate(), Func->getTarget());
      break;
    case IceType_f64:
      Asm->vldrd(Dest, getSrc(0), getPredicate(), Func->getTarget());
      break;
    }
  } else if (isVectorType(DestTy))
    // TODO(kschimpf) Handle case.
    Asm->setNeedsTextFixup();
  else
    Asm->ldr(Dest, getSrc(0), getPredicate(), Func->getTarget());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Ldrex::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 1);
  assert(getDest()->hasReg());
  Variable *Dest = getDest();
  Type DestTy = Dest->getType();
  assert(isScalarIntegerType(DestTy));
  const char *WidthString = getWidthString(DestTy);
  Str << "\t" << Opcode << WidthString << getPredicate() << "\t";
  getDest()->emit(Func);
  Str << ", ";
  getSrc(0)->emit(Func);
}

template <> void InstARM32Ldrex::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  assert(getDest()->hasReg());
  Variable *Dest = getDest();
  assert(isScalarIntegerType(Dest->getType()));
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->ldrex(Dest, getSrc(0), getPredicate(), Func->getTarget());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <InstARM32::InstKindARM32 K>
void InstARM32TwoAddrGPR<K>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <InstARM32::InstKindARM32 K, bool Nws>
void InstARM32UnaryopGPR<K, Nws>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <> void InstARM32Rbit::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->rbit(getDest(), getSrc(0), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Rev::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->rev(getDest(), getSrc(0), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Movw::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 1);
  Str << "\t" << Opcode << getPredicate() << "\t";
  getDest()->emit(Func);
  Str << ", ";
  auto *Src0 = llvm::cast<Constant>(getSrc(0));
  if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) {
    Str << "#:lower16:";
    CR->emitWithoutPrefix(Func->getTarget());
  } else {
    Src0->emit(Func);
  }
}

template <> void InstARM32Movw::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->movw(getDest(), getSrc(0), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Movt::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 2);
  Variable *Dest = getDest();
  auto *Src1 = llvm::cast<Constant>(getSrc(1));
  Str << "\t" << Opcode << getPredicate() << "\t";
  Dest->emit(Func);
  Str << ", ";
  if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) {
    Str << "#:upper16:";
    CR->emitWithoutPrefix(Func->getTarget());
  } else {
    Src1->emit(Func);
  }
}

template <> void InstARM32Movt::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 2);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->movt(getDest(), getSrc(1), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Clz::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->clz(getDest(), getSrc(0), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Mvn::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->mvn(getDest(), getSrc(0), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Sxt::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->sxt(getDest(), getSrc(0), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <> void InstARM32Uxt::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->uxt(getDest(), getSrc(0), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

template <InstARM32::InstKindARM32 K>
void InstARM32UnaryopFP<K>::emitIAS(const Cfg *Func) const {
  emitUsingTextFixup(Func);
}

template <> void InstARM32Vsqrt::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Operand *Dest = getDest();
  switch (Dest->getType()) {
  case IceType_f32:
    Asm->vsqrts(Dest, getSrc(0), getPredicate());
    break;
  case IceType_f64:
    Asm->vsqrtd(Dest, getSrc(0), getPredicate());
    break;
  default:
    llvm::report_fatal_error("Vsqrt of non-floating type");
  }
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

const char *InstARM32Pop::getGPROpcode() const { return "pop"; }

const char *InstARM32Pop::getSRegOpcode() const { return "vpop"; }

Variable *InstARM32Pop::getStackReg(SizeT Index) const { return Dests[Index]; }

SizeT InstARM32Pop::getNumStackRegs() const { return Dests.size(); }

void InstARM32Pop::emitSingleGPR(const Cfg *Func, const EmitForm Form,
                                 const Variable *Reg) const {
  switch (Form) {
  case Emit_Text:
    emitGPRsAsText(Func);
    return;
  case Emit_Binary:
    Func->getAssembler<ARM32::AssemblerARM32>()->pop(Reg, CondARM32::AL);
    return;
  }
}

void InstARM32Pop::emitMultipleGPRs(const Cfg *Func, const EmitForm Form,
                                    IValueT Registers) const {
  switch (Form) {
  case Emit_Text:
    emitGPRsAsText(Func);
    return;
  case Emit_Binary:
    Func->getAssembler<ARM32::AssemblerARM32>()->popList(Registers,
                                                         CondARM32::AL);
    return;
  }
}

void InstARM32Pop::emitSRegs(const Cfg *Func, const EmitForm Form,
                             const Variable *BaseReg, SizeT RegCount) const {
  switch (Form) {
  case Emit_Text:
    emitSRegsAsText(Func, BaseReg, RegCount);
    return;
  case Emit_Binary:
    Func->getAssembler<ARM32::AssemblerARM32>()->vpop(BaseReg, RegCount,
                                                      CondARM32::AL);
    return;
  }
}

const char *InstARM32Push::getGPROpcode() const { return "push"; }

const char *InstARM32Push::getSRegOpcode() const { return "vpush"; }

Variable *InstARM32Push::getStackReg(SizeT Index) const {
  return llvm::cast<Variable>(getSrc(Index));
}

SizeT InstARM32Push::getNumStackRegs() const { return getSrcSize(); }

void InstARM32Push::emitSingleGPR(const Cfg *Func, const EmitForm Form,
                                  const Variable *Reg) const {
  switch (Form) {
  case Emit_Text:
    emitGPRsAsText(Func);
    return;
  case Emit_Binary:
    Func->getAssembler<ARM32::AssemblerARM32>()->push(Reg, CondARM32::AL);
    return;
  }
}

void InstARM32Push::emitMultipleGPRs(const Cfg *Func, const EmitForm Form,
                                     IValueT Registers) const {
  switch (Form) {
  case Emit_Text:
    emitGPRsAsText(Func);
    return;
  case Emit_Binary:
    Func->getAssembler<ARM32::AssemblerARM32>()->pushList(Registers,
                                                          CondARM32::AL);
    return;
  }
}

void InstARM32Push::emitSRegs(const Cfg *Func, const EmitForm Form,
                              const Variable *BaseReg, SizeT RegCount) const {
  switch (Form) {
  case Emit_Text:
    emitSRegsAsText(Func, BaseReg, RegCount);
    return;
  case Emit_Binary:
    Func->getAssembler<ARM32::AssemblerARM32>()->vpush(BaseReg, RegCount,
                                                       CondARM32::AL);
    return;
  }
}

void InstARM32Ret::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(getSrcSize() > 0);
  auto *LR = llvm::cast<Variable>(getSrc(0));
  assert(LR->hasReg());
  assert(LR->getRegNum() == RegARM32::Reg_lr);
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "\t"
         "bx"
         "\t";
  LR->emit(Func);
}

void InstARM32Ret::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->bx(RegARM32::Encoded_Reg_lr);
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Ret::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType());
  Str << "ret." << Ty << " ";
  dumpSources(Func);
}

void InstARM32Str::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 2);
  Type Ty = getSrc(0)->getType();
  const bool IsVectorStore = isVectorType(Ty);
  const bool IsScalarFloat = isScalarFloatingType(Ty);
  const char *Opcode =
      IsVectorStore ? "vst1" : (IsScalarFloat ? "vstr" : "str");
  const char *VecEltWidthString = IsVectorStore ? ".64" : "";
  Str << "\t" << Opcode;
  const bool IsVInst = IsVectorStore || IsScalarFloat;
  if (IsVInst) {
    Str << getPredicate() << getWidthString(Ty);
  } else {
    Str << getWidthString(Ty) << getPredicate();
  }
  Str << VecEltWidthString << "\t";
  getSrc(0)->emit(Func);
  Str << ", ";
  getSrc(1)->emit(Func);
}

void InstARM32Str::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 2);
  Type Ty = getSrc(0)->getType();
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  if (isScalarFloatingType(Ty)) {
    switch (Ty) {
    default:
      // TODO(kschimpf) Does this happen?
      Asm->setNeedsTextFixup();
      break;
    case IceType_f32:
      Asm->vstrs(getSrc(0), getSrc(1), getPredicate(), Func->getTarget());
      break;
    case IceType_f64:
      Asm->vstrd(getSrc(0), getSrc(1), getPredicate(), Func->getTarget());
      break;
    }
  } else if (isVectorType(Ty))
    // TODO(kschimpf) Handle case.
    Asm->setNeedsTextFixup();
  else
    Asm->str(getSrc(0), getSrc(1), getPredicate(), Func->getTarget());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Str::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Type Ty = getSrc(0)->getType();
  dumpOpcodePred(Str, "str", Ty);
  Str << " ";
  getSrc(1)->dump(Func);
  Str << ", ";
  getSrc(0)->dump(Func);
}

void InstARM32Strex::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  assert(getSrcSize() == 2);
  Type Ty = getSrc(0)->getType();
  assert(isScalarIntegerType(Ty));
  Variable *Dest = getDest();
  Ostream &Str = Func->getContext()->getStrEmit();
  static constexpr char Opcode[] = "strex";
  const char *WidthString = getWidthString(Ty);
  Str << "\t" << Opcode << WidthString << getPredicate() << "\t";
  Dest->emit(Func);
  Str << ", ";
  emitSources(Func);
}

void InstARM32Strex::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 2);
  const Operand *Src0 = getSrc(0);
  assert(isScalarIntegerType(Src0->getType()));
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->strex(Dest, Src0, getSrc(1), getPredicate(), Func->getTarget());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Strex::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Variable *Dest = getDest();
  Dest->dump(Func);
  Str << " = ";
  Type Ty = getSrc(0)->getType();
  dumpOpcodePred(Str, "strex", Ty);
  Str << " ";
  getSrc(1)->dump(Func);
  Str << ", ";
  getSrc(0)->dump(Func);
}

void InstARM32Trap::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 0);
  // There isn't a mnemonic for the special NaCl Trap encoding, so dump
  // the raw bytes.
  Str << "\t.long 0x";
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  for (uint8_t I : Asm->getNonExecBundlePadding()) {
    Str.write_hex(I);
  }
}

void InstARM32Trap::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->trap();
  assert(!Asm->needsTextFixup());
}

void InstARM32Trap::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "trap";
}

void InstARM32Umull::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 2);
  assert(getDest()->hasReg());
  Str << "\t"
         "umull" << getPredicate() << "\t";
  getDest()->emit(Func);
  Str << ", ";
  DestHi->emit(Func);
  Str << ", ";
  getSrc(0)->emit(Func);
  Str << ", ";
  getSrc(1)->emit(Func);
}

void InstARM32Umull::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 2);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->umull(getDest(), DestHi, getSrc(0), getSrc(1), getPredicate());
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Umull::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = ";
  dumpOpcodePred(Str, "umull", getDest()->getType());
  Str << " ";
  dumpSources(Func);
}

namespace {
const char *vcvtVariantSuffix(const InstARM32Vcvt::VcvtVariant Variant) {
  switch (Variant) {
  case InstARM32Vcvt::S2si:
    return ".s32.f32";
  case InstARM32Vcvt::S2ui:
    return ".u32.f32";
  case InstARM32Vcvt::Si2s:
    return ".f32.s32";
  case InstARM32Vcvt::Ui2s:
    return ".f32.u32";
  case InstARM32Vcvt::D2si:
    return ".s32.f64";
  case InstARM32Vcvt::D2ui:
    return ".u32.f64";
  case InstARM32Vcvt::Si2d:
    return ".f64.s32";
  case InstARM32Vcvt::Ui2d:
    return ".f64.u32";
  case InstARM32Vcvt::S2d:
    return ".f64.f32";
  case InstARM32Vcvt::D2s:
    return ".f32.f64";
  }
  llvm::report_fatal_error("Invalid VcvtVariant enum.");
}
} // end of anonymous namespace

void InstARM32Vcvt::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 1);
  assert(getDest()->hasReg());
  Str << "\t"
         "vcvt" << getPredicate() << vcvtVariantSuffix(Variant) << "\t";
  getDest()->emit(Func);
  Str << ", ";
  getSrc(0)->emit(Func);
}

void InstARM32Vcvt::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  switch (Variant) {
  case S2si:
    Asm->vcvtis(getDest(), getSrc(0), getPredicate());
    break;
  case S2ui:
    Asm->vcvtus(getDest(), getSrc(0), getPredicate());
    break;
  case Si2s:
    Asm->vcvtsi(getDest(), getSrc(0), getPredicate());
    break;
  case Ui2s:
    Asm->vcvtsu(getDest(), getSrc(0), getPredicate());
    break;
  case D2si:
    Asm->vcvtid(getDest(), getSrc(0), getPredicate());
    break;
  case D2ui:
    Asm->vcvtud(getDest(), getSrc(0), getPredicate());
    break;
  case Si2d:
    Asm->vcvtdi(getDest(), getSrc(0), getPredicate());
    break;
  case Ui2d:
    Asm->vcvtdu(getDest(), getSrc(0), getPredicate());
    break;
  case S2d:
    Asm->vcvtds(getDest(), getSrc(0), getPredicate());
    break;
  case D2s:
    Asm->vcvtsd(getDest(), getSrc(0), getPredicate());
    break;
  }
  assert(!Asm->needsTextFixup());
}

void InstARM32Vcvt::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = "
      << "vcvt" << getPredicate() << vcvtVariantSuffix(Variant) << " ";
  dumpSources(Func);
}

void InstARM32Vcmp::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 2);
  Str << "\t"
         "vcmp" << getPredicate() << getVecWidthString(getSrc(0)->getType())
      << "\t";
  getSrc(0)->emit(Func);
  Str << ", ";
  getSrc(1)->emit(Func);
}

void InstARM32Vcmp::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 2);
  const Operand *Src0 = getSrc(0);
  const Type Ty = Src0->getType();
  const Operand *Src1 = getSrc(1);
  const CondARM32::Cond Cond = getPredicate();
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  if (llvm::isa<OperandARM32FlexFpZero>(Src1)) {
    switch (Ty) {
    case IceType_f32:
      Asm->vcmpsz(Src0, Cond);
      break;
    case IceType_f64:
      Asm->vcmpdz(Src0, Cond);
      break;
    default:
      llvm::report_fatal_error("Vcvt on non floating value");
    }
  } else {
    switch (Ty) {
    case IceType_f32:
      Asm->vcmps(Src0, Src1, Cond);
      break;
    case IceType_f64:
      Asm->vcmpd(Src0, Src1, Cond);
      break;
    default:
      llvm::report_fatal_error("Vcvt on non floating value");
    }
  }
  assert(!Asm->needsTextFixup());
}

void InstARM32Vcmp::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "vcmp" << getPredicate() << getVecWidthString(getSrc(0)->getType());
  dumpSources(Func);
}

void InstARM32Vmrs::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 0);
  Str << "\t"
         "vmrs" << getPredicate() << "\t"
                                     "APSR_nzcv"
                                     ", "
                                     "FPSCR";
}

void InstARM32Vmrs::emitIAS(const Cfg *Func) const {
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  Asm->vmrsAPSR_nzcv(getPredicate());
  assert(!Asm->needsTextFixup());
}

void InstARM32Vmrs::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  Str << "APSR{n,z,v,c} = vmrs" << getPredicate() << "\t"
                                                     "FPSCR{n,z,c,v}";
}

void InstARM32Vabs::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 1);
  Str << "\t"
         "vabs" << getPredicate() << getVecWidthString(getSrc(0)->getType())
      << "\t";
  getDest()->emit(Func);
  Str << ", ";
  getSrc(0)->emit(Func);
}

void InstARM32Vabs::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 1);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  const Variable *Dest = getDest();
  switch (Dest->getType()) {
  default:
    // TODO(kschimpf): Implement vector fabs.
    Asm->setNeedsTextFixup();
    break;
  case IceType_f32:
    Asm->vabss(Dest, getSrc(0), getPredicate());
    break;
  case IceType_f64:
    Asm->vabsd(Dest, getSrc(0), getPredicate());
    break;
  }
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Vabs::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrDump();
  dumpDest(Func);
  Str << " = vabs" << getPredicate() << getVecWidthString(getSrc(0)->getType());
}

void InstARM32Dmb::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(getSrcSize() == 0);
  Str << "\t"
         "dmb"
         "\t"
         "sy";
}

void InstARM32Dmb::emitIAS(const Cfg *Func) const {
  assert(getSrcSize() == 0);
  auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
  constexpr ARM32::IValueT SyOption = 0xF; // i.e. 1111
  Asm->dmb(SyOption);
  if (Asm->needsTextFixup())
    emitUsingTextFixup(Func);
}

void InstARM32Dmb::dump(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Func->getContext()->getStrDump() << "dmb\t"
                                      "sy";
}

void OperandARM32Mem::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  Str << "[";
  getBase()->emit(Func);
  switch (getAddrMode()) {
  case PostIndex:
  case NegPostIndex:
    Str << "]";
    break;
  default:
    break;
  }
  if (isRegReg()) {
    Str << ", ";
    if (isNegAddrMode()) {
      Str << "-";
    }
    getIndex()->emit(Func);
    if (getShiftOp() != kNoShift) {
      Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " #"
          << getShiftAmt();
    }
  } else {
    ConstantInteger32 *Offset = getOffset();
    if (Offset && Offset->getValue() != 0) {
      Str << ", ";
      Offset->emit(Func);
    }
  }
  switch (getAddrMode()) {
  case Offset:
  case NegOffset:
    Str << "]";
    break;
  case PreIndex:
  case NegPreIndex:
    Str << "]!";
    break;
  case PostIndex:
  case NegPostIndex:
    // Brace is already closed off.
    break;
  }
}

void OperandARM32Mem::dump(const Cfg *Func, Ostream &Str) const {
  if (!BuildDefs::dump())
    return;
  Str << "[";
  if (Func)
    getBase()->dump(Func);
  else
    getBase()->dump(Str);
  Str << ", ";
  if (isRegReg()) {
    if (isNegAddrMode()) {
      Str << "-";
    }
    if (Func)
      getIndex()->dump(Func);
    else
      getIndex()->dump(Str);
    if (getShiftOp() != kNoShift) {
      Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " #"
          << getShiftAmt();
    }
  } else {
    getOffset()->dump(Func, Str);
  }
  Str << "] AddrMode==" << getAddrMode();
}

void OperandARM32ShAmtImm::emit(const Cfg *Func) const { ShAmt->emit(Func); }

void OperandARM32ShAmtImm::dump(const Cfg *, Ostream &Str) const {
  ShAmt->dump(Str);
}

OperandARM32FlexImm *OperandARM32FlexImm::create(Cfg *Func, Type Ty,
                                                 uint32_t Imm,
                                                 uint32_t RotateAmt) {
  // The assembler wants the smallest rotation. Rotate if needed. Note: Imm is
  // an 8-bit value.
  assert(Utils::IsUint(8, Imm) &&
         "Flex immediates can only be defined on 8-bit immediates");
  while ((Imm & 0x03) == 0 && RotateAmt > 0) {
    --RotateAmt;
    Imm = Imm >> 2;
  }
  return new (Func->allocate<OperandARM32FlexImm>())
      OperandARM32FlexImm(Func, Ty, Imm, RotateAmt);
}

void OperandARM32FlexImm::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  uint32_t Imm = getImm();
  uint32_t RotateAmt = getRotateAmt();
  Str << "#" << Utils::rotateRight32(Imm, 2 * RotateAmt);
}

void OperandARM32FlexImm::dump(const Cfg * /* Func */, Ostream &Str) const {
  if (!BuildDefs::dump())
    return;
  uint32_t Imm = getImm();
  uint32_t RotateAmt = getRotateAmt();
  Str << "#(" << Imm << " ror 2*" << RotateAmt << ")";
}

namespace {
static constexpr uint32_t a = 0x80;
static constexpr uint32_t b = 0x40;
static constexpr uint32_t cdefgh = 0x3F;
static constexpr uint32_t AllowedBits = a | b | cdefgh;
static_assert(AllowedBits == 0xFF,
              "Invalid mask for f32/f64 constant rematerialization.");

// There's no loss in always returning the modified immediate as float.
// TODO(jpp): returning a double causes problems when outputting the constants
// for filetype=asm. Why?
float materializeFloatImmediate(uint32_t ModifiedImm) {
  const uint32_t Ret = ((ModifiedImm & a) ? 0x80000000 : 0) |
                       ((ModifiedImm & b) ? 0x3E000000 : 0x40000000) |
                       ((ModifiedImm & cdefgh) << 19);
  return Utils::bitCopy<float>(Ret);
}

} // end of anonymous namespace

void OperandARM32FlexFpImm::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  switch (Ty) {
  default:
    llvm::report_fatal_error("Invalid flex fp imm type.");
  case IceType_f64:
  case IceType_f32:
    Str << "#" << materializeFloatImmediate(ModifiedImm)
        << " @ Modified: " << ModifiedImm;
    break;
  }
}

void OperandARM32FlexFpImm::dump(const Cfg * /*Func*/, Ostream &Str) const {
  if (!BuildDefs::dump())
    return;
  Str << "#" << materializeFloatImmediate(ModifiedImm)
      << InstARM32::getVecWidthString(Ty);
}

void OperandARM32FlexFpZero::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  switch (Ty) {
  default:
    llvm::report_fatal_error("Invalid flex fp imm type.");
  case IceType_f64:
  case IceType_f32:
    Str << "#0.0";
  }
}

void OperandARM32FlexFpZero::dump(const Cfg * /*Func*/, Ostream &Str) const {
  if (!BuildDefs::dump())
    return;
  Str << "#0.0" << InstARM32::getVecWidthString(Ty);
}

void OperandARM32FlexReg::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  getReg()->emit(Func);
  if (getShiftOp() != kNoShift) {
    Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " ";
    getShiftAmt()->emit(Func);
  }
}

void OperandARM32FlexReg::dump(const Cfg *Func, Ostream &Str) const {
  if (!BuildDefs::dump())
    return;
  Variable *Reg = getReg();
  if (Func)
    Reg->dump(Func);
  else
    Reg->dump(Str);
  if (getShiftOp() != kNoShift) {
    Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " ";
    if (Func)
      getShiftAmt()->dump(Func);
    else
      getShiftAmt()->dump(Str);
  }
}

// Force instantition of template classes
template class InstARM32ThreeAddrGPR<InstARM32::Adc>;
template class InstARM32ThreeAddrGPR<InstARM32::Add>;
template class InstARM32ThreeAddrGPR<InstARM32::And>;
template class InstARM32ThreeAddrGPR<InstARM32::Asr>;
template class InstARM32ThreeAddrGPR<InstARM32::Bic>;
template class InstARM32ThreeAddrGPR<InstARM32::Eor>;
template class InstARM32ThreeAddrGPR<InstARM32::Lsl>;
template class InstARM32ThreeAddrGPR<InstARM32::Lsr>;
template class InstARM32ThreeAddrGPR<InstARM32::Mul>;
template class InstARM32ThreeAddrGPR<InstARM32::Orr>;
template class InstARM32ThreeAddrGPR<InstARM32::Rsb>;
template class InstARM32ThreeAddrGPR<InstARM32::Rsc>;
template class InstARM32ThreeAddrGPR<InstARM32::Sbc>;
template class InstARM32ThreeAddrGPR<InstARM32::Sdiv>;
template class InstARM32ThreeAddrGPR<InstARM32::Sub>;
template class InstARM32ThreeAddrGPR<InstARM32::Udiv>;

template class InstARM32ThreeAddrFP<InstARM32::Vadd>;
template class InstARM32ThreeAddrFP<InstARM32::Vdiv>;
template class InstARM32ThreeAddrFP<InstARM32::Veor>;
template class InstARM32FourAddrFP<InstARM32::Vmla>;
template class InstARM32FourAddrFP<InstARM32::Vmls>;
template class InstARM32ThreeAddrFP<InstARM32::Vmul>;
template class InstARM32ThreeAddrFP<InstARM32::Vsub>;

template class InstARM32LoadBase<InstARM32::Ldr>;
template class InstARM32LoadBase<InstARM32::Ldrex>;

template class InstARM32TwoAddrGPR<InstARM32::Movt>;

template class InstARM32UnaryopGPR<InstARM32::Movw, false>;
template class InstARM32UnaryopGPR<InstARM32::Clz, false>;
template class InstARM32UnaryopGPR<InstARM32::Mvn, false>;
template class InstARM32UnaryopGPR<InstARM32::Rbit, false>;
template class InstARM32UnaryopGPR<InstARM32::Rev, false>;
template class InstARM32UnaryopGPR<InstARM32::Sxt, true>;
template class InstARM32UnaryopGPR<InstARM32::Uxt, true>;
template class InstARM32UnaryopFP<InstARM32::Vsqrt>;

template class InstARM32FourAddrGPR<InstARM32::Mla>;
template class InstARM32FourAddrGPR<InstARM32::Mls>;

template class InstARM32CmpLike<InstARM32::Cmn>;
template class InstARM32CmpLike<InstARM32::Cmp>;
template class InstARM32CmpLike<InstARM32::Tst>;

} // end of namespace ARM32
} // end of namespace Ice
