//===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
//
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Modified by the Subzero authors.
//
//===----------------------------------------------------------------------===//
//
//                        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 Assembler class for ARM32.
///
//===----------------------------------------------------------------------===//

#include "IceAssemblerARM32.h"
#include "IceCfgNode.h"
#include "IceUtils.h"

namespace {

using namespace Ice;
using namespace Ice::ARM32;

using WordType = uint32_t;
static constexpr IValueT kWordSize = sizeof(WordType);

// The following define individual bits.
static constexpr IValueT B0 = 1;
static constexpr IValueT B1 = 1 << 1;
static constexpr IValueT B2 = 1 << 2;
static constexpr IValueT B3 = 1 << 3;
static constexpr IValueT B4 = 1 << 4;
static constexpr IValueT B5 = 1 << 5;
static constexpr IValueT B6 = 1 << 6;
static constexpr IValueT B7 = 1 << 7;
static constexpr IValueT B8 = 1 << 8;
static constexpr IValueT B9 = 1 << 9;
static constexpr IValueT B10 = 1 << 10;
static constexpr IValueT B11 = 1 << 11;
static constexpr IValueT B12 = 1 << 12;
static constexpr IValueT B13 = 1 << 13;
static constexpr IValueT B14 = 1 << 14;
static constexpr IValueT B15 = 1 << 15;
static constexpr IValueT B16 = 1 << 16;
static constexpr IValueT B17 = 1 << 17;
static constexpr IValueT B18 = 1 << 18;
static constexpr IValueT B19 = 1 << 19;
static constexpr IValueT B20 = 1 << 20;
static constexpr IValueT B21 = 1 << 21;
static constexpr IValueT B22 = 1 << 22;
static constexpr IValueT B23 = 1 << 23;
static constexpr IValueT B24 = 1 << 24;
static constexpr IValueT B25 = 1 << 25;
static constexpr IValueT B26 = 1 << 26;
static constexpr IValueT B27 = 1 << 27;

// Constants used for the decoding or encoding of the individual fields of
// instructions. Based on ARM section A5.1.
static constexpr IValueT L = 1 << 20; // load (or store)
static constexpr IValueT W = 1 << 21; // writeback base register
                                      // (or leave unchanged)
static constexpr IValueT B = 1 << 22; // unsigned byte (or word)
static constexpr IValueT U = 1 << 23; // positive (or negative)
                                      // offset/index
static constexpr IValueT P = 1 << 24; // offset/pre-indexed
                                      // addressing (or
                                      // post-indexed addressing)

static constexpr IValueT kConditionShift = 28;
static constexpr IValueT kLinkShift = 24;
static constexpr IValueT kOpcodeShift = 21;
static constexpr IValueT kRdShift = 12;
static constexpr IValueT kRmShift = 0;
static constexpr IValueT kRnShift = 16;
static constexpr IValueT kRsShift = 8;
static constexpr IValueT kSShift = 20;
static constexpr IValueT kTypeShift = 25;

// Immediate instruction fields encoding.
static constexpr IValueT kImmed8Bits = 8;
static constexpr IValueT kImmed8Shift = 0;
static constexpr IValueT kRotateBits = 4;
static constexpr IValueT kRotateShift = 8;

// Shift instruction register fields encodings.
static constexpr IValueT kShiftImmShift = 7;
static constexpr IValueT kShiftImmBits = 5;
static constexpr IValueT kShiftShift = 5;
static constexpr IValueT kImmed12Bits = 12;
static constexpr IValueT kImm12Shift = 0;

// Rotation instructions (uxtb etc.).
static constexpr IValueT kRotationShift = 10;

// MemEx instructions.
static constexpr IValueT kMemExOpcodeShift = 20;

// Div instruction register field encodings.
static constexpr IValueT kDivRdShift = 16;
static constexpr IValueT kDivRmShift = 8;
static constexpr IValueT kDivRnShift = 0;

// Type of instruction encoding (bits 25-27). See ARM section A5.1
static constexpr IValueT kInstTypeDataRegister = 0;  // i.e. 000
static constexpr IValueT kInstTypeDataRegShift = 0;  // i.e. 000
static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001
static constexpr IValueT kInstTypeMemImmediate = 2;  // i.e. 010
static constexpr IValueT kInstTypeRegisterShift = 3; // i.e. 011

// Limit on number of registers in a vpush/vpop.
static constexpr SizeT VpushVpopMaxConsecRegs = 16;

// Offset modifier to current PC for next instruction.  The offset is off by 8
// due to the way the ARM CPUs read PC.
static constexpr IOffsetT kPCReadOffset = 8;

// Mask to pull out PC offset from branch (b) instruction.
static constexpr int kBranchOffsetBits = 24;
static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff;

IValueT encodeBool(bool B) { return B ? 1 : 0; }

IValueT encodeRotation(ARM32::AssemblerARM32::RotationValue Value) {
  return static_cast<IValueT>(Value);
}

IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) {
  return static_cast<IValueT>(Rn);
}

RegARM32::GPRRegister decodeGPRRegister(IValueT R) {
  return static_cast<RegARM32::GPRRegister>(R);
}

IValueT encodeCondition(CondARM32::Cond Cond) {
  return static_cast<IValueT>(Cond);
}

IValueT encodeShift(OperandARM32::ShiftKind Shift) {
  // Follows encoding in ARM section A8.4.1 "Constant shifts".
  switch (Shift) {
  case OperandARM32::kNoShift:
  case OperandARM32::LSL:
    return 0; // 0b00
  case OperandARM32::LSR:
    return 1; // 0b01
  case OperandARM32::ASR:
    return 2; // 0b10
  case OperandARM32::ROR:
  case OperandARM32::RRX:
    return 3; // 0b11
  }
  llvm::report_fatal_error("Unknown Shift value");
  return 0;
}

// Returns the bits in the corresponding masked value.
IValueT mask(IValueT Value, IValueT Shift, IValueT Bits) {
  return (Value >> Shift) & ((1 << Bits) - 1);
}

// Extract out a Bit in Value.
bool isBitSet(IValueT Bit, IValueT Value) { return (Value & Bit) == Bit; }

// Returns the GPR register at given Shift in Value.
RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) {
  return decodeGPRRegister((Value >> Shift) & 0xF);
}

IValueT getEncodedGPRegNum(const Variable *Var) {
  assert(Var->hasReg());
  const auto Reg = Var->getRegNum();
  return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg)
                                        : RegARM32::getEncodedGPR(Reg);
}

IValueT getEncodedSRegNum(const Variable *Var) {
  assert(Var->hasReg());
  return RegARM32::getEncodedSReg(Var->getRegNum());
}

IValueT getEncodedDRegNum(const Variable *Var) {
  return RegARM32::getEncodedDReg(Var->getRegNum());
}

IValueT getEncodedQRegNum(const Variable *Var) {
  return RegARM32::getEncodedQReg(Var->getRegNum());
}

IValueT mapQRegToDReg(IValueT EncodedQReg) {
  IValueT DReg = EncodedQReg << 1;
  assert(DReg < RegARM32::getNumDRegs());
  return DReg;
}

IValueT mapQRegToSReg(IValueT EncodedQReg) {
  IValueT SReg = EncodedQReg << 2;
  assert(SReg < RegARM32::getNumSRegs());
  return SReg;
}

IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; }

IValueT getXXXXInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY >> 1; }

IValueT getYInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX >> 4; }

IValueT getXXXXInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX & 0x0f; }

// Defines layouts of an operand representing a (register) memory address,
// possibly modified by an immediate value.
enum EncodedImmAddress {
  // Address modified by a rotated immediate 8-bit value.
  RotatedImm8Address,

  // Alternate encoding for RotatedImm8Address, where the offset is divided by 4
  // before encoding.
  RotatedImm8Div4Address,

  // Address modified by an immediate 12-bit value.
  Imm12Address,

  // Alternate encoding 3, for an address modified by a rotated immediate 8-bit
  // value.
  RotatedImm8Enc3Address,

  // Encoding where no immediate offset is used.
  NoImmOffsetAddress
};

// The way an operand is encoded into a sequence of bits in functions
// encodeOperand and encodeAddress below.
enum EncodedOperand {
  // Unable to encode, value left undefined.
  CantEncode = 0,

  // Value is register found.
  EncodedAsRegister,

  // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8
  // value.
  EncodedAsRotatedImm8,

  // EncodedAsImmRegOffset is a memory operand that can take three forms, based
  // on type EncodedImmAddress:
  //
  // ***** RotatedImm8Address *****
  //
  // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
  // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
  // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value.
  //
  // ***** RotatedImm8Div4Address *****
  //
  // Value=00000000pu0w0nnnn0000iiii0000jjjj where nnnn=Rn, iiiijjjj=Imm8, p=1
  // if pre-indexed addressing, u=1 if offset positive, and w=1 if writeback to
  // Rn.
  //
  // ***** Imm12Address *****
  //
  // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
  // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
  // Rn should be used, and iiiiiiiiiiii defines the immediate 12-bit value.
  //
  // ***** NoImmOffsetAddress *****
  //
  // Value=000000001000nnnn0000000000000000 where nnnn=Rn.
  EncodedAsImmRegOffset,

  // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
  // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
  // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if
  // writeback to Rn.
  EncodedAsShiftRotateImm5,

  // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value
  // to shift.
  EncodedAsShiftImm5,

  // Value=iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift
  // kind, and iiiii is the shift amount.
  EncodedAsShiftedRegister,

  // Value=ssss0tt1mmmm where mmmm=Rm, tt is an encoded ShiftKind, and ssss=Rms.
  EncodedAsRegShiftReg,

  // Value is 32bit integer constant.
  EncodedAsConstI32
};

// Sets Encoding to a rotated Imm8 encoding of Value, if possible.
IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
  assert(RotateAmt < (1 << kRotateBits));
  assert(Immed8 < (1 << kImmed8Bits));
  return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift);
}

// Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5,
// tt=Shift, and mmmm=Rm.
IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift,
                              IOffsetT imm5) {
  (void)kShiftImmBits;
  assert(imm5 < (1 << kShiftImmBits));
  return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
}

// Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and
// tt=Shift.
IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
                             IValueT Rs) {
  return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 |
         (Rm << kRmShift);
}

// Defines the set of registers expected in an operand.
enum RegSetWanted { WantGPRegs, WantSRegs, WantDRegs, WantQRegs };

EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value,
                             RegSetWanted WantedRegSet) {
  Value = 0; // Make sure initialized.
  if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
    if (Var->hasReg()) {
      switch (WantedRegSet) {
      case WantGPRegs:
        Value = getEncodedGPRegNum(Var);
        break;
      case WantSRegs:
        Value = getEncodedSRegNum(Var);
        break;
      case WantDRegs:
        Value = getEncodedDRegNum(Var);
        break;
      case WantQRegs:
        Value = getEncodedQRegNum(Var);
        break;
      }
      return EncodedAsRegister;
    }
    return CantEncode;
  }
  if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
    const IValueT Immed8 = FlexImm->getImm();
    const IValueT Rotate = FlexImm->getRotateAmt();
    if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))))
      return CantEncode;
    Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
    return EncodedAsRotatedImm8;
  }
  if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) {
    Value = Const->getValue();
    return EncodedAsConstI32;
  }
  if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) {
    Operand *Amt = FlexReg->getShiftAmt();
    IValueT Rm;
    if (encodeOperand(FlexReg->getReg(), Rm, WantGPRegs) != EncodedAsRegister)
      return CantEncode;
    if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) {
      IValueT Rs;
      if (encodeOperand(Var, Rs, WantGPRegs) != EncodedAsRegister)
        return CantEncode;
      Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs);
      return EncodedAsRegShiftReg;
    }
    // If reached, the amount is a shifted amount by some 5-bit immediate.
    uint32_t Imm5;
    if (const auto *ShAmt = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) {
      Imm5 = ShAmt->getShAmtImm();
    } else if (const auto *IntConst = llvm::dyn_cast<ConstantInteger32>(Amt)) {
      int32_t Val = IntConst->getValue();
      if (Val < 0)
        return CantEncode;
      Imm5 = static_cast<uint32_t>(Val);
    } else
      return CantEncode;
    Value = encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5);
    return EncodedAsShiftedRegister;
  }
  if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
    const IValueT Immed5 = ShImm->getShAmtImm();
    assert(Immed5 < (1 << kShiftImmBits));
    Value = (Immed5 << kShiftImmShift);
    return EncodedAsShiftImm5;
  }
  return CantEncode;
}

IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset,
                           OperandARM32Mem::AddrMode Mode, IOffsetT MaxOffset,
                           IValueT OffsetShift) {
  IValueT Value = Mode | (Reg << kRnShift);
  if (Offset < 0) {
    Offset = -Offset;
    Value ^= U; // Flip U to adjust sign.
  }
  assert(Offset <= MaxOffset);
  (void)MaxOffset;
  return Value | (Offset >> OffsetShift);
}

// Encodes immediate register offset using encoding 3.
IValueT encodeImmRegOffsetEnc3(IValueT Rn, IOffsetT Imm8,
                               OperandARM32Mem::AddrMode Mode) {
  IValueT Value = Mode | (Rn << kRnShift);
  if (Imm8 < 0) {
    Imm8 = -Imm8;
    Value = (Value ^ U);
  }
  assert(Imm8 < (1 << 8));
  Value = Value | B22 | ((Imm8 & 0xf0) << 4) | (Imm8 & 0x0f);
  return Value;
}

IValueT encodeImmRegOffset(EncodedImmAddress ImmEncoding, IValueT Reg,
                           IOffsetT Offset, OperandARM32Mem::AddrMode Mode) {
  switch (ImmEncoding) {
  case RotatedImm8Address: {
    constexpr IOffsetT MaxOffset = (1 << 8) - 1;
    constexpr IValueT NoRightShift = 0;
    return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, NoRightShift);
  }
  case RotatedImm8Div4Address: {
    assert((Offset & 0x3) == 0);
    constexpr IOffsetT MaxOffset = (1 << 8) - 1;
    constexpr IValueT RightShift2 = 2;
    return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, RightShift2);
  }
  case Imm12Address: {
    constexpr IOffsetT MaxOffset = (1 << 12) - 1;
    constexpr IValueT NoRightShift = 0;
    return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, NoRightShift);
  }
  case RotatedImm8Enc3Address:
    return encodeImmRegOffsetEnc3(Reg, Offset, Mode);
  case NoImmOffsetAddress: {
    assert(Offset == 0);
    assert(Mode == OperandARM32Mem::Offset);
    return Reg << kRnShift;
  }
  }
  llvm_unreachable("(silence g++ warning)");
}

// Encodes memory address Opnd, and encodes that information into Value, based
// on how ARM represents the address. Returns how the value was encoded.
EncodedOperand encodeAddress(const Operand *Opnd, IValueT &Value,
                             const AssemblerARM32::TargetInfo &TInfo,
                             EncodedImmAddress ImmEncoding) {
  Value = 0; // Make sure initialized.
  if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
    // Should be a stack variable, with an offset.
    if (Var->hasReg())
      return CantEncode;
    IOffsetT Offset = Var->getStackOffset();
    if (!Utils::IsAbsoluteUint(12, Offset))
      return CantEncode;
    const auto BaseRegNum =
        Var->hasReg() ? Var->getBaseRegNum() : TInfo.FrameOrStackReg;
    Value = encodeImmRegOffset(ImmEncoding, BaseRegNum, Offset,
                               OperandARM32Mem::Offset);
    return EncodedAsImmRegOffset;
  }
  if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) {
    Variable *Var = Mem->getBase();
    if (!Var->hasReg())
      return CantEncode;
    IValueT Rn = getEncodedGPRegNum(Var);
    if (Mem->isRegReg()) {
      const Variable *Index = Mem->getIndex();
      if (Var == nullptr)
        return CantEncode;
      Value = (Rn << kRnShift) | Mem->getAddrMode() |
              encodeShiftRotateImm5(getEncodedGPRegNum(Index),
                                    Mem->getShiftOp(), Mem->getShiftAmt());
      return EncodedAsShiftRotateImm5;
    }
    // Encoded as immediate register offset.
    ConstantInteger32 *Offset = Mem->getOffset();
    Value = encodeImmRegOffset(ImmEncoding, Rn, Offset->getValue(),
                               Mem->getAddrMode());
    return EncodedAsImmRegOffset;
  }
  return CantEncode;
}

// Checks that Offset can fit in imm24 constant of branch (b) instruction.
void assertCanEncodeBranchOffset(IOffsetT Offset) {
  (void)Offset;
  (void)kBranchOffsetBits;
  assert(Utils::IsAligned(Offset, 4) &&
         Utils::IsInt(kBranchOffsetBits, Offset >> 2));
}

IValueT encodeBranchOffset(IOffsetT Offset, IValueT Inst) {
  // Adjust offset to the way ARM CPUs read PC.
  Offset -= kPCReadOffset;

  assertCanEncodeBranchOffset(Offset);

  // Properly preserve only the bits supported in the instruction.
  Offset >>= 2;
  Offset &= kBranchOffsetMask;
  return (Inst & ~kBranchOffsetMask) | Offset;
}

IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet,
                       const char *RegName, const char *InstName) {
  IValueT Reg = 0;
  if (encodeOperand(OpReg, Reg, WantedRegSet) != EncodedAsRegister)
    llvm::report_fatal_error(std::string(InstName) + ": Can't find register " +
                             RegName);
  return Reg;
}

IValueT encodeGPRegister(const Operand *OpReg, const char *RegName,
                         const char *InstName) {
  return encodeRegister(OpReg, WantGPRegs, RegName, InstName);
}

IValueT encodeSRegister(const Operand *OpReg, const char *RegName,
                        const char *InstName) {
  return encodeRegister(OpReg, WantSRegs, RegName, InstName);
}

IValueT encodeDRegister(const Operand *OpReg, const char *RegName,
                        const char *InstName) {
  return encodeRegister(OpReg, WantDRegs, RegName, InstName);
}

IValueT encodeQRegister(const Operand *OpReg, const char *RegName,
                        const char *InstName) {
  return encodeRegister(OpReg, WantQRegs, RegName, InstName);
}

void verifyPOrNotW(IValueT Address, const char *InstName) {
  if (BuildDefs::minimal())
    return;
  if (!isBitSet(P, Address) && isBitSet(W, Address))
    llvm::report_fatal_error(std::string(InstName) +
                             ": P=0 when W=1 not allowed");
}

void verifyRegsNotEq(IValueT Reg1, const char *Reg1Name, IValueT Reg2,
                     const char *Reg2Name, const char *InstName) {
  if (BuildDefs::minimal())
    return;
  if (Reg1 == Reg2)
    llvm::report_fatal_error(std::string(InstName) + ": " + Reg1Name + "=" +
                             Reg2Name + " not allowed");
}

void verifyRegNotPc(IValueT Reg, const char *RegName, const char *InstName) {
  verifyRegsNotEq(Reg, RegName, RegARM32::Encoded_Reg_pc, "pc", InstName);
}

void verifyAddrRegNotPc(IValueT RegShift, IValueT Address, const char *RegName,
                        const char *InstName) {
  if (BuildDefs::minimal())
    return;
  if (getGPRReg(RegShift, Address) == RegARM32::Encoded_Reg_pc)
    llvm::report_fatal_error(std::string(InstName) + ": " + RegName +
                             "=pc not allowed");
}

void verifyRegNotPcWhenSetFlags(IValueT Reg, bool SetFlags,
                                const char *InstName) {
  if (BuildDefs::minimal())
    return;
  if (SetFlags && (Reg == RegARM32::Encoded_Reg_pc))
    llvm::report_fatal_error(std::string(InstName) + ": " +
                             RegARM32::getRegName(RegARM32::Reg_pc) +
                             "=pc not allowed when CC=1");
}

} // end of anonymous namespace

namespace Ice {
namespace ARM32 {

size_t MoveRelocatableFixup::emit(GlobalContext *Ctx,
                                  const Assembler &Asm) const {
  if (!BuildDefs::dump())
    return InstARM32::InstSize;
  Ostream &Str = Ctx->getStrEmit();
  IValueT Inst = Asm.load<IValueT>(position());
  const bool IsMovw = kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ||
                      kind() == llvm::ELF::R_ARM_MOVW_PREL_NC;
  const auto Symbol = symbol().toString();
  const bool NeedsPCRelSuffix =
      (Asm.fixupIsPCRel(kind()) || Symbol == GlobalOffsetTable);
  Str << "\t"
         "mov" << (IsMovw ? "w" : "t") << "\t"
      << RegARM32::getRegName(RegNumT::fixme((Inst >> kRdShift) & 0xF))
      << ", #:" << (IsMovw ? "lower" : "upper") << "16:" << Symbol
      << (NeedsPCRelSuffix ? " - ." : "") << "\t@ .word "
      // TODO(jpp): This is broken, it also needs to add a magic constant.
      << llvm::format_hex_no_prefix(Inst, 8) << "\n";
  return InstARM32::InstSize;
}

IValueT AssemblerARM32::encodeElmtType(Type ElmtTy) {
  switch (ElmtTy) {
  case IceType_i8:
    return 0;
  case IceType_i16:
    return 1;
  case IceType_i32:
  case IceType_f32:
    return 2;
  case IceType_i64:
    return 3;
  default:
    llvm::report_fatal_error("SIMD op: Don't understand element type " +
                             typeStdString(ElmtTy));
  }
}

// This fixup points to an ARM32 instruction with the following format:
void MoveRelocatableFixup::emitOffset(Assembler *Asm) const {
  // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd,
  // iiiiiiiiiiiiiiii = Imm16, and T=1 for movt.

  const IValueT Inst = Asm->load<IValueT>(position());
  constexpr IValueT Imm16Mask = 0x000F0FFF;
  const IValueT Imm16 = offset() & 0xffff;
  Asm->store(position(),
             (Inst & ~Imm16Mask) | ((Imm16 >> 12) << 16) | (Imm16 & 0xfff));
}

MoveRelocatableFixup *AssemblerARM32::createMoveFixup(bool IsMovW,
                                                      const Constant *Value) {
  MoveRelocatableFixup *F =
      new (allocate<MoveRelocatableFixup>()) MoveRelocatableFixup();
  F->set_kind(IsMovW ? (IsNonsfi ? llvm::ELF::R_ARM_MOVW_PREL_NC
                                 : llvm::ELF::R_ARM_MOVW_ABS_NC)
                     : (IsNonsfi ? llvm::ELF::R_ARM_MOVT_PREL
                                 : llvm::ELF::R_ARM_MOVT_ABS));
  F->set_value(Value);
  Buffer.installFixup(F);
  return F;
}

size_t BlRelocatableFixup::emit(GlobalContext *Ctx,
                                const Assembler &Asm) const {
  if (!BuildDefs::dump())
    return InstARM32::InstSize;
  Ostream &Str = Ctx->getStrEmit();
  IValueT Inst = Asm.load<IValueT>(position());
  Str << "\t"
         "bl\t" << symbol() << "\t@ .word "
      << llvm::format_hex_no_prefix(Inst, 8) << "\n";
  return InstARM32::InstSize;
}

void BlRelocatableFixup::emitOffset(Assembler *Asm) const {
  // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
  // iiiiiiiiiiiiiiiiiiiiiiii=
  // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
  const IValueT Inst = Asm->load<IValueT>(position());
  constexpr IValueT OffsetMask = 0x00FFFFFF;
  Asm->store(position(), encodeBranchOffset(offset(), Inst & ~OffsetMask));
}

void AssemblerARM32::padWithNop(intptr_t Padding) {
  constexpr intptr_t InstWidth = sizeof(IValueT);
  assert(Padding % InstWidth == 0 &&
         "Padding not multiple of instruction size");
  for (intptr_t i = 0; i < Padding; i += InstWidth)
    nop();
}

BlRelocatableFixup *
AssemblerARM32::createBlFixup(const ConstantRelocatable *BlTarget) {
  BlRelocatableFixup *F =
      new (allocate<BlRelocatableFixup>()) BlRelocatableFixup();
  F->set_kind(llvm::ELF::R_ARM_CALL);
  F->set_value(BlTarget);
  Buffer.installFixup(F);
  return F;
}

void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) {
  GlobalContext *Ctx = Node->getCfg()->getContext();
  if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) {
    // Generate label name so that branches can find it.
    constexpr SizeT InstSize = 0;
    emitTextInst(Node->getAsmName() + ":", InstSize);
  }
  SizeT NodeNumber = Node->getIndex();
  assert(!getPreliminary());
  Label *L = getOrCreateCfgNodeLabel(NodeNumber);
  this->bind(L);
}

Label *AssemblerARM32::getOrCreateLabel(SizeT Number, LabelVector &Labels) {
  Label *L = nullptr;
  if (Number == Labels.size()) {
    L = new (this->allocate<Label>()) Label();
    Labels.push_back(L);
    return L;
  }
  if (Number > Labels.size()) {
    Labels.resize(Number + 1);
  }
  L = Labels[Number];
  if (!L) {
    L = new (this->allocate<Label>()) Label();
    Labels[Number] = L;
  }
  return L;
}

// Pull out offset from branch Inst.
IOffsetT AssemblerARM32::decodeBranchOffset(IValueT Inst) {
  // Sign-extend, left-shift by 2, and adjust to the way ARM CPUs read PC.
  const IOffsetT Offset = (Inst & kBranchOffsetMask) << 8;
  return (Offset >> 6) + kPCReadOffset;
}

void AssemblerARM32::bind(Label *L) {
  IOffsetT BoundPc = Buffer.size();
  assert(!L->isBound()); // Labels can only be bound once.
  while (L->isLinked()) {
    IOffsetT Position = L->getLinkPosition();
    IOffsetT Dest = BoundPc - Position;
    IValueT Inst = Buffer.load<IValueT>(Position);
    Buffer.store<IValueT>(Position, encodeBranchOffset(Dest, Inst));
    L->setPosition(decodeBranchOffset(Inst));
  }
  L->bindTo(BoundPc);
}

void AssemblerARM32::emitTextInst(const std::string &Text, SizeT InstSize) {
  AssemblerFixup *F = createTextFixup(Text, InstSize);
  emitFixup(F);
  for (SizeT I = 0; I < InstSize; ++I) {
    AssemblerBuffer::EnsureCapacity ensured(&Buffer);
    Buffer.emit<char>(0);
  }
}

void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT InstType,
                                IValueT Opcode, bool SetFlags, IValueT Rn,
                                IValueT Rd, IValueT Imm12,
                                EmitChecks RuleChecks, const char *InstName) {
  switch (RuleChecks) {
  case NoChecks:
    break;
  case RdIsPcAndSetFlags:
    verifyRegNotPcWhenSetFlags(Rd, SetFlags, InstName);
    break;
  }
  assert(Rd < RegARM32::getNumGPRegs());
  assert(CondARM32::isDefined(Cond));
  const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
                           (InstType << kTypeShift) | (Opcode << kOpcodeShift) |
                           (encodeBool(SetFlags) << kSShift) |
                           (Rn << kRnShift) | (Rd << kRdShift) | Imm12;
  emitInst(Encoding);
}

void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
                                const Operand *OpRd, const Operand *OpRn,
                                const Operand *OpSrc1, bool SetFlags,
                                EmitChecks RuleChecks, const char *InstName) {
  IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
  IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName);
  emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName);
}

void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
                                IValueT Rd, IValueT Rn, const Operand *OpSrc1,
                                bool SetFlags, EmitChecks RuleChecks,
                                const char *InstName) {
  IValueT Src1Value;
  // TODO(kschimpf) Other possible decodings of data operations.
  switch (encodeOperand(OpSrc1, Src1Value, WantGPRegs)) {
  default:
    llvm::report_fatal_error(std::string(InstName) +
                             ": Can't encode instruction");
    return;
  case EncodedAsRegister: {
    // XXX (register)
    //   xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
    //
    // cccc000xxxxsnnnnddddiiiiitt0mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
    // nnnn=Rn, mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
    constexpr IValueT Imm5 = 0;
    Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
    emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
               RuleChecks, InstName);
    return;
  }
  case EncodedAsShiftedRegister: {
    // Form is defined in case EncodedAsRegister. (i.e. XXX (register)).
    emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
               RuleChecks, InstName);
    return;
  }
  case EncodedAsConstI32: {
    // See if we can convert this to an XXX (immediate).
    IValueT RotateAmt;
    IValueT Imm8;
    if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8))
      llvm::report_fatal_error(std::string(InstName) +
                               ": Immediate rotated constant not valid");
    Src1Value = encodeRotatedImm8(RotateAmt, Imm8);
    // Intentionally fall to next case!
  }
  case EncodedAsRotatedImm8: {
    // XXX (Immediate)
    //   xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8>
    //
    // cccc001xxxxsnnnnddddiiiiiiiiiiii where cccc=Cond, xxxx=Opcode, dddd=Rd,
    // nnnn=Rn, s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
    emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd,
               Src1Value, RuleChecks, InstName);
    return;
  }
  case EncodedAsRegShiftReg: {
    // XXX (register-shifted reg)
    //   xxx{s}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
    //
    // cccc000xxxxfnnnnddddssss0tt1mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
    // nnnn=Rn, ssss=Rs, f=SetFlags, tt is encoding of type, and
    // Src1Value=ssss01tt1mmmm.
    emitType01(Cond, kInstTypeDataRegShift, Opcode, SetFlags, Rn, Rd, Src1Value,
               RuleChecks, InstName);
    return;
  }
  }
}

void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset,
                                bool Link) {
  // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
  // iiiiiiiiiiiiiiiiiiiiiiii=
  // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
  assert(CondARM32::isDefined(Cond));
  IValueT Encoding = static_cast<int32_t>(Cond) << kConditionShift |
                     5 << kTypeShift | (Link ? 1 : 0) << kLinkShift;
  Encoding = encodeBranchOffset(Offset, Encoding);
  emitInst(Encoding);
}

void AssemblerARM32::emitBranch(Label *L, CondARM32::Cond Cond, bool Link) {
  // TODO(kschimpf): Handle far jumps.
  if (L->isBound()) {
    const int32_t Dest = L->getPosition() - Buffer.size();
    emitType05(Cond, Dest, Link);
    return;
  }
  const IOffsetT Position = Buffer.size();
  // Use the offset field of the branch instruction for linking the sites.
  emitType05(Cond, L->getEncodedPosition(), Link);
  L->linkTo(*this, Position);
}

void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode,
                                   const Operand *OpRn, const Operand *OpSrc1,
                                   const char *InstName) {
  // XXX (register)
  //   XXX<c> <Rn>, <Rm>{, <shift>}
  //
  // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii
  // defines shift constant, tt=ShiftKind, yyy=kInstTypeDataRegister, and
  // xxxx=Opcode.
  //
  // XXX (immediate)
  //  XXX<c> <Rn>, #<RotatedImm8>
  //
  // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value
  // defining RotatedImm8.
  constexpr bool SetFlags = true;
  constexpr IValueT Rd = RegARM32::Encoded_Reg_r0;
  IValueT Rn = encodeGPRegister(OpRn, "Rn", InstName);
  emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, NoChecks, InstName);
}

void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType,
                               bool IsLoad, bool IsByte, IValueT Rt,
                               IValueT Address) {
  assert(Rt < RegARM32::getNumGPRegs());
  assert(CondARM32::isDefined(Cond));
  const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
                           (InstType << kTypeShift) | (IsLoad ? L : 0) |
                           (IsByte ? B : 0) | (Rt << kRdShift) | Address;
  emitInst(Encoding);
}

void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte,
                               IValueT Rt, const Operand *OpAddress,
                               const TargetInfo &TInfo, const char *InstName) {
  IValueT Address;
  switch (encodeAddress(OpAddress, Address, TInfo, Imm12Address)) {
  default:
    llvm::report_fatal_error(std::string(InstName) +
                             ": Memory address not understood");
  case EncodedAsImmRegOffset: {
    // XXX{B} (immediate):
    //   xxx{b}<c> <Rt>, [<Rn>{, #+/-<imm12>}]      ; p=1, w=0
    //   xxx{b}<c> <Rt>, [<Rn>], #+/-<imm12>        ; p=1, w=1
    //   xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]!       ; p=0, w=1
    //
    // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
    // iiiiiiiiiiii=imm12, b=IsByte, pu0w<<21 is a BlockAddr, l=IsLoad, and
    // pu0w0nnnn0000iiiiiiiiiiii=Address.
    RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);

    // Check if conditions of rules violated.
    verifyRegNotPc(Rn, "Rn", InstName);
    verifyPOrNotW(Address, InstName);
    if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) &&
        isBitSet(U, Address) && !isBitSet(W, Address) &&
        (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
      llvm::report_fatal_error(std::string(InstName) +
                               ": Use push/pop instead");

    emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
    return;
  }
  case EncodedAsShiftRotateImm5: {
    // XXX{B} (register)
    //   xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
    //   xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
    //
    // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt,
    // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and
    // pu0w0nnnn0000iiiiiss0mmmm=Address.
    RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
    RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);

    // Check if conditions of rules violated.
    verifyPOrNotW(Address, InstName);
    verifyRegNotPc(Rm, "Rm", InstName);
    if (IsByte)
      verifyRegNotPc(Rt, "Rt", InstName);
    if (isBitSet(W, Address)) {
      verifyRegNotPc(Rn, "Rn", InstName);
      verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
    }
    emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
    return;
  }
  }
}

void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
                                   IValueT Rt, const Operand *OpAddress,
                                   const TargetInfo &TInfo,
                                   const char *InstName) {
  IValueT Address;
  switch (encodeAddress(OpAddress, Address, TInfo, RotatedImm8Enc3Address)) {
  default:
    llvm::report_fatal_error(std::string(InstName) +
                             ": Memory address not understood");
  case EncodedAsImmRegOffset: {
    // XXXH (immediate)
    //   xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}]
    //   xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]
    //   xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
    //
    // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt,
    // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode,
    // and pu0w0nnnn0000iiii0000jjjj=Address.
    assert(Rt < RegARM32::getNumGPRegs());
    assert(CondARM32::isDefined(Cond));
    verifyPOrNotW(Address, InstName);
    verifyRegNotPc(Rt, "Rt", InstName);
    if (isBitSet(W, Address))
      verifyRegsNotEq(getGPRReg(kRnShift, Address), "Rn", Rt, "Rt", InstName);
    const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
                             Opcode | (Rt << kRdShift) | Address;
    emitInst(Encoding);
    return;
  }
  case EncodedAsShiftRotateImm5: {
    // XXXH (register)
    //   xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!}
    //   xxxh<c> <Rt>, [<Rn>], +/-<Rm>
    //
    // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn,
    // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and
    // pu0w0nnnn000000000000mmmm=Address.
    assert(Rt < RegARM32::getNumGPRegs());
    assert(CondARM32::isDefined(Cond));
    verifyPOrNotW(Address, InstName);
    verifyRegNotPc(Rt, "Rt", InstName);
    verifyAddrRegNotPc(kRmShift, Address, "Rm", InstName);
    const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
    if (isBitSet(W, Address)) {
      verifyRegNotPc(Rn, "Rn", InstName);
      verifyRegsNotEq(Rn, "Rn", Rt, "Rt", InstName);
    }
    if (mask(Address, kShiftImmShift, 5) != 0)
      // For encoding 3, no shift is allowed.
      llvm::report_fatal_error(std::string(InstName) +
                               ": Shift constant not allowed");
    const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
                             Opcode | (Rt << kRdShift) | Address;
    emitInst(Encoding);
    return;
  }
  }
}

void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
                               IValueT Rn, IValueT Rm) {
  assert(Rd < RegARM32::getNumGPRegs());
  assert(Rn < RegARM32::getNumGPRegs());
  assert(Rm < RegARM32::getNumGPRegs());
  assert(CondARM32::isDefined(Cond));
  const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
                           (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 |
                           B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 |
                           (Rm << kDivRmShift);
  emitInst(Encoding);
}

void AssemblerARM32::emitInsertExtractInt(CondARM32::Cond Cond,
                                          const Operand *OpQn, uint32_t Index,
                                          const Operand *OpRt, bool IsExtract,
                                          const char *InstName) {
  const IValueT Rt = encodeGPRegister(OpRt, "Rt", InstName);
  IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", InstName));
  assert(Rt != RegARM32::Encoded_Reg_pc);
  assert(Rt != RegARM32::Encoded_Reg_sp);
  assert(CondARM32::isDefined(Cond));
  const uint32_t BitSize = typeWidthInBytes(OpRt->getType()) * CHAR_BIT;
  IValueT Opcode1 = 0;
  IValueT Opcode2 = 0;
  switch (BitSize) {
  default:
    llvm::report_fatal_error(std::string(InstName) +
                             ": Unable to process type " +
                             typeStdString(OpRt->getType()));
  case 8:
    assert(Index < 16);
    Dn = Dn | mask(Index, 3, 1);
    Opcode1 = B1 | mask(Index, 2, 1);
    Opcode2 = mask(Index, 0, 2);
    break;
  case 16:
    assert(Index < 8);
    Dn = Dn | mask(Index, 2, 1);
    Opcode1 = mask(Index, 1, 1);
    Opcode2 = (mask(Index, 0, 1) << 1) | B0;
    break;
  case 32:
    assert(Index < 4);
    Dn = Dn | mask(Index, 1, 1);
    Opcode1 = mask(Index, 0, 1);
    break;
  }
  const IValueT Encoding = B27 | B26 | B25 | B11 | B9 | B8 | B4 |
                           (encodeCondition(Cond) << kConditionShift) |
                           (Opcode1 << 21) |
                           (getXXXXInRegYXXXX(Dn) << kRnShift) | (Rt << 12) |
                           (encodeBool(IsExtract) << 20) |
                           (getYInRegYXXXX(Dn) << 7) | (Opcode2 << 5);
  emitInst(Encoding);
}

void AssemblerARM32::emitMoveSS(CondARM32::Cond Cond, IValueT Sd, IValueT Sm) {
  // VMOV (register) - ARM section A8.8.340, encoding A2:
  //   vmov<c>.f32 <Sd>, <Sm>
  //
  // cccc11101D110000dddd101001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
  constexpr IValueT VmovssOpcode = B23 | B21 | B20 | B6;
  constexpr IValueT S0 = 0;
  emitVFPsss(Cond, VmovssOpcode, Sd, S0, Sm);
}

void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
                               IValueT Rn, IValueT Rm, IValueT Rs,
                               bool SetFlags) {
  assert(Rd < RegARM32::getNumGPRegs());
  assert(Rn < RegARM32::getNumGPRegs());
  assert(Rm < RegARM32::getNumGPRegs());
  assert(Rs < RegARM32::getNumGPRegs());
  assert(CondARM32::isDefined(Cond));
  IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
                     (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) |
                     (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 |
                     (Rm << kRmShift);
  emitInst(Encoding);
}

void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond,
                                    BlockAddressMode AddressMode, bool IsLoad,
                                    IValueT BaseReg, IValueT Registers) {
  assert(CondARM32::isDefined(Cond));
  assert(BaseReg < RegARM32::getNumGPRegs());
  assert(Registers < (1 << RegARM32::getNumGPRegs()));
  IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 |
                     AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) |
                     Registers;
  emitInst(Encoding);
}

void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode,
                                    const Operand *OpRd, const Operand *OpSrc0,
                                    const char *InstName) {
  IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
  IValueT Rm = encodeGPRegister(OpSrc0, "Rm", InstName);
  // Note: For the moment, we assume no rotation is specified.
  RotationValue Rotation = kRotateNone;
  constexpr IValueT Rn = RegARM32::Encoded_Reg_pc;
  const Type Ty = OpSrc0->getType();
  switch (Ty) {
  default:
    llvm::report_fatal_error(std::string(InstName) + ": Type " +
                             typeString(Ty) + " not allowed");
    break;
  case IceType_i1:
  case IceType_i8: {
    // SXTB/UXTB - Arm sections A8.8.233 and A8.8.274, encoding A1:
    //   sxtb<c> <Rd>, <Rm>{, <rotate>}
    //   uxtb<c> <Rd>, <Rm>{, <rotate>}
    //
    // ccccxxxxxxxx1111ddddrr000111mmmm where cccc=Cond, xxxxxxxx<<20=Opcode,
    // dddd=Rd, mmmm=Rm, and rr defined (RotationValue) rotate.
    break;
  }
  case IceType_i16: {
    // SXTH/UXTH - ARM sections A8.8.235 and A8.8.276, encoding A1:
    //   uxth<c> <Rd>< <Rm>{, <rotate>}
    //
    // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and
    // rr defined (RotationValue) rotate.
    Opcode |= B20;
    break;
  }
  }

  assert(CondARM32::isDefined(Cond));
  IValueT Rot = encodeRotation(Rotation);
  if (!Utils::IsUint(2, Rot))
    llvm::report_fatal_error(std::string(InstName) +
                             ": Illegal rotation value");
  IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode |
                     (Rn << kRnShift) | (Rd << kRdShift) |
                     (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift);
  emitInst(Encoding);
}

void AssemblerARM32::emitSIMDBase(IValueT Opcode, IValueT Dd, IValueT Dn,
                                  IValueT Dm, bool UseQRegs, bool IsFloatTy) {
  const IValueT Encoding =
      Opcode | B25 | (encodeCondition(CondARM32::kNone) << kConditionShift) |
      (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
      (getXXXXInRegYXXXX(Dd) << 12) | (IsFloatTy ? B10 : 0) |
      (getYInRegYXXXX(Dn) << 7) | (encodeBool(UseQRegs) << 6) |
      (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
  emitInst(Encoding);
}

void AssemblerARM32::emitSIMD(IValueT Opcode, Type ElmtTy, IValueT Dd,
                              IValueT Dn, IValueT Dm, bool UseQRegs) {
  constexpr IValueT ElmtShift = 20;
  const IValueT ElmtSize = encodeElmtType(ElmtTy);
  assert(Utils::IsUint(2, ElmtSize));
  emitSIMDBase(Opcode | (ElmtSize << ElmtShift), Dd, Dn, Dm, UseQRegs,
               isFloatingType(ElmtTy));
}

void AssemblerARM32::emitSIMDqqqBase(IValueT Opcode, const Operand *OpQd,
                                     const Operand *OpQn, const Operand *OpQm,
                                     bool IsFloatTy, const char *OpcodeName) {
  const IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
  const IValueT Qn = encodeQRegister(OpQn, "Qn", OpcodeName);
  const IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
  constexpr bool UseQRegs = true;
  emitSIMDBase(Opcode, mapQRegToDReg(Qd), mapQRegToDReg(Qn), mapQRegToDReg(Qm),
               UseQRegs, IsFloatTy);
}

void AssemblerARM32::emitSIMDqqq(IValueT Opcode, Type ElmtTy,
                                 const Operand *OpQd, const Operand *OpQn,
                                 const Operand *OpQm, const char *OpcodeName) {
  constexpr IValueT ElmtShift = 20;
  const IValueT ElmtSize = encodeElmtType(ElmtTy);
  assert(Utils::IsUint(2, ElmtSize));
  emitSIMDqqqBase(Opcode | (ElmtSize << ElmtShift), OpQd, OpQn, OpQm,
                  isFloatingType(ElmtTy), OpcodeName);
}

void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
                                IValueT Dd, IValueT Dn, IValueT Dm) {
  assert(Dd < RegARM32::getNumDRegs());
  assert(Dn < RegARM32::getNumDRegs());
  assert(Dm < RegARM32::getNumDRegs());
  assert(CondARM32::isDefined(Cond));
  constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8;
  const IValueT Encoding =
      Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
      (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
      (getXXXXInRegYXXXX(Dd) << 12) | (getYInRegYXXXX(Dn) << 7) |
      (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
  emitInst(Encoding);
}

void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
                                const Operand *OpDd, const Operand *OpDn,
                                const Operand *OpDm, const char *InstName) {
  IValueT Dd = encodeDRegister(OpDd, "Dd", InstName);
  IValueT Dn = encodeDRegister(OpDn, "Dn", InstName);
  IValueT Dm = encodeDRegister(OpDm, "Dm", InstName);
  emitVFPddd(Cond, Opcode, Dd, Dn, Dm);
}

void AssemblerARM32::emitVFPsss(CondARM32::Cond Cond, IValueT Opcode,
                                IValueT Sd, IValueT Sn, IValueT Sm) {
  assert(Sd < RegARM32::getNumSRegs());
  assert(Sn < RegARM32::getNumSRegs());
  assert(Sm < RegARM32::getNumSRegs());
  assert(CondARM32::isDefined(Cond));
  constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
  const IValueT Encoding =
      Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
      (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sn) << 16) |
      (getXXXXInRegXXXXY(Sd) << 12) | (getYInRegXXXXY(Sn) << 7) |
      (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm);
  emitInst(Encoding);
}

void AssemblerARM32::emitVFPsss(CondARM32::Cond Cond, IValueT Opcode,
                                const Operand *OpSd, const Operand *OpSn,
                                const Operand *OpSm, const char *InstName) {
  const IValueT Sd = encodeSRegister(OpSd, "Sd", InstName);
  const IValueT Sn = encodeSRegister(OpSn, "Sn", InstName);
  const IValueT Sm = encodeSRegister(OpSm, "Sm", InstName);
  emitVFPsss(Cond, Opcode, Sd, Sn, Sm);
}

void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // ADC (register) - ARM section 18.8.2, encoding A1:
  //   adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
  //
  // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
  //
  // ADC (Immediate) - ARM section A8.8.1, encoding A1:
  //   adc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
  //
  // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  constexpr const char *AdcName = "adc";
  constexpr IValueT AdcOpcode = B2 | B0; // 0101
  emitType01(Cond, AdcOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             AdcName);
}

void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // ADD (register) - ARM section A8.8.7, encoding A1:
  //   add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
  // ADD (Sp plus register) - ARM section A8.8.11, encoding A1:
  //   add{s}<c> sp, <Rn>, <Rm>{, <shiff>}
  //
  // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
  //
  // ADD (Immediate) - ARM section A8.8.5, encoding A1:
  //   add{s}<c> <Rd>, <Rn>, #<RotatedImm8>
  // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1.
  //   add{s}<c> <Rd>, sp, #<RotatedImm8>
  //
  // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  constexpr const char *AddName = "add";
  constexpr IValueT Add = B2; // 0100
  emitType01(Cond, Add, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             AddName);
}

void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn,
                          const Operand *OpSrc1, bool SetFlags,
                          CondARM32::Cond Cond) {
  // AND (register) - ARM section A8.8.14, encoding A1:
  //   and{s}<c> <Rd>, <Rn>{, <shift>}
  //
  // cccc0000000snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
  //
  // AND (Immediate) - ARM section A8.8.13, encoding A1:
  //   and{s}<c> <Rd>, <Rn>, #<RotatedImm8>
  //
  // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  constexpr const char *AndName = "and";
  constexpr IValueT And = 0; // 0000
  emitType01(Cond, And, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             AndName);
}

void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) {
  emitBranch(L, Cond, false);
}

void AssemblerARM32::bkpt(uint16_t Imm16) {
  // BKPT - ARM section A*.8.24 - encoding A1:
  //   bkpt #<Imm16>
  //
  // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and iiiiiiiiiiiiiiii=Imm16
  const IValueT Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 |
                           ((Imm16 >> 4) << 8) | B6 | B5 | B4 | (Imm16 & 0xf);
  emitInst(Encoding);
}

void AssemblerARM32::bic(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // BIC (register) - ARM section A8.8.22, encoding A1:
  //   bic{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
  //
  // cccc0001110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
  //
  // BIC (immediate) - ARM section A8.8.21, encoding A1:
  //   bic{s}<c> <Rd>, <Rn>, #<RotatedImm8>
  //
  // cccc0011110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rn, nnnn=Rn,
  // s=SetFlags, and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  constexpr const char *BicName = "bic";
  constexpr IValueT BicOpcode = B3 | B2 | B1; // i.e. 1110
  emitType01(Cond, BicOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             BicName);
}

void AssemblerARM32::bl(const ConstantRelocatable *Target) {
  // BL (immediate) - ARM section A8.8.25, encoding A1:
  //   bl<c> <label>
  //
  // cccc1011iiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond (not currently allowed)
  // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to.
  emitFixup(createBlFixup(Target));
  constexpr CondARM32::Cond Cond = CondARM32::AL;
  constexpr IValueT Immed = 0;
  constexpr bool Link = true;
  emitType05(Cond, Immed, Link);
}

void AssemblerARM32::blx(const Operand *Target) {
  // BLX (register) - ARM section A8.8.26, encoding A1:
  //   blx<c> <Rm>
  //
  // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed)
  // and mmmm=Rm.
  constexpr const char *BlxName = "Blx";
  IValueT Rm = encodeGPRegister(Target, "Rm", BlxName);
  verifyRegNotPc(Rm, "Rm", BlxName);
  constexpr CondARM32::Cond Cond = CondARM32::AL;
  int32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 |
                     (0xfff << 8) | B5 | B4 | (Rm << kRmShift);
  emitInst(Encoding);
}

void AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) {
  // BX - ARM section A8.8.27, encoding A1:
  //   bx<c> <Rm>
  //
  // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond.
  assert(CondARM32::isDefined(Cond));
  const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 |
                           B21 | (0xfff << 8) | B4 |
                           (encodeGPRRegister(Rm) << kRmShift);
  emitInst(Encoding);
}

void AssemblerARM32::clz(const Operand *OpRd, const Operand *OpSrc,
                         CondARM32::Cond Cond) {
  // CLZ - ARM section A8.8.33, encoding A1:
  //   clz<c> <Rd> <Rm>
  //
  // cccc000101101111dddd11110001mmmm where cccc=Cond, dddd=Rd, and mmmm=Rm.
  constexpr const char *ClzName = "clz";
  constexpr const char *RdName = "Rd";
  constexpr const char *RmName = "Rm";
  IValueT Rd = encodeGPRegister(OpRd, RdName, ClzName);
  assert(Rd < RegARM32::getNumGPRegs());
  verifyRegNotPc(Rd, RdName, ClzName);
  IValueT Rm = encodeGPRegister(OpSrc, RmName, ClzName);
  assert(Rm < RegARM32::getNumGPRegs());
  verifyRegNotPc(Rm, RmName, ClzName);
  assert(CondARM32::isDefined(Cond));
  constexpr IValueT PredefinedBits =
      B24 | B22 | B21 | (0xF << 16) | (0xf << 8) | B4;
  const IValueT Encoding = PredefinedBits | (Cond << kConditionShift) |
                           (Rd << kRdShift) | (Rm << kRmShift);
  emitInst(Encoding);
}

void AssemblerARM32::cmn(const Operand *OpRn, const Operand *OpSrc1,
                         CondARM32::Cond Cond) {
  // CMN (immediate) - ARM section A8.8.34, encoding A1:
  //   cmn<c> <Rn>, #<RotatedImm8>
  //
  // cccc00110111nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  //
  // CMN (register) - ARM section A8.8.35, encodeing A1:
  //   cmn<c> <Rn>, <Rm>{, <shift>}
  //
  // cccc00010111nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
  // iiiii=Shift, and tt=ShiftKind.
  constexpr const char *CmnName = "cmn";
  constexpr IValueT CmnOpcode = B3 | B1 | B0; // ie. 1011
  emitCompareOp(Cond, CmnOpcode, OpRn, OpSrc1, CmnName);
}

void AssemblerARM32::cmp(const Operand *OpRn, const Operand *OpSrc1,
                         CondARM32::Cond Cond) {
  // CMP (register) - ARM section A8.8.38, encoding A1:
  //   cmp<c> <Rn>, <Rm>{, <shift>}
  //
  // cccc00010101nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
  // iiiii=Shift, and tt=ShiftKind.
  //
  // CMP (immediate) - ARM section A8.8.37
  //  cmp<c: <Rn>, #<RotatedImm8>
  //
  // cccc00110101nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  constexpr const char *CmpName = "cmp";
  constexpr IValueT CmpOpcode = B3 | B1; // ie. 1010
  emitCompareOp(Cond, CmpOpcode, OpRn, OpSrc1, CmpName);
}

void AssemblerARM32::dmb(IValueT Option) {
  // DMB - ARM section A8.8.43, encoding A1:
  //   dmb <option>
  //
  // 1111010101111111111100000101xxxx where xxxx=Option.
  assert(Utils::IsUint(4, Option) && "Bad dmb option");
  const IValueT Encoding =
      (encodeCondition(CondARM32::kNone) << kConditionShift) | B26 | B24 | B22 |
      B21 | B20 | B19 | B18 | B17 | B16 | B15 | B14 | B13 | B12 | B6 | B4 |
      Option;
  emitInst(Encoding);
}

void AssemblerARM32::eor(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // EOR (register) - ARM section A*.8.47, encoding A1:
  //   eor{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
  //
  // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
  //
  // EOR (Immediate) - ARM section A8.*.46, encoding A1:
  //   eor{s}<c> <Rd>, <Rn>, #RotatedImm8
  //
  // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  constexpr const char *EorName = "eor";
  constexpr IValueT EorOpcode = B0; // 0001
  emitType01(Cond, EorOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             EorName);
}

void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
                         CondARM32::Cond Cond, const TargetInfo &TInfo) {
  constexpr const char *LdrName = "ldr";
  constexpr bool IsLoad = true;
  IValueT Rt = encodeGPRegister(OpRt, "Rt", LdrName);
  const Type Ty = OpRt->getType();
  switch (Ty) {
  case IceType_i64:
    // LDRD is not implemented because target lowering handles i64 and double by
    // using two (32-bit) load instructions. Note: Intentionally drop to default
    // case.
    llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) +
                             " not implemented");
  default:
    llvm::report_fatal_error(std::string("ldr : Type ") + typeString(Ty) +
                             " not allowed");
  case IceType_i1:
  case IceType_i8: {
    // LDRB (immediate) - ARM section A8.8.68, encoding A1:
    //   ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}]     ; p=1, w=0
    //   ldrb<c> <Rt>, [<Rn>], #+/-<imm12>       ; p=1, w=1
    //   ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]!      ; p=0, w=1
    //
    // cccc010pu1w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
    // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
    // pu0w0nnnn0000iiiiiiiiiiii=Address.
    //
    // LDRB (register) - ARM section A8.8.66, encoding A1:
    //   ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
    //   ldrb<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
    //
    // cccc011pu1w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
    // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
    constexpr bool IsByte = true;
    emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName);
    return;
  }
  case IceType_i16: {
    // LDRH (immediate) - ARM section A8.8.80, encoding A1:
    //   ldrh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
    //   ldrh<c> <Rt>, [<Rn>], #+/-<Imm8>
    //   ldrh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
    //
    // cccc000pu1w1nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
    // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
    // pu0w0nnnn0000iiiiiiiiiiii=Address.
    constexpr const char *Ldrh = "ldrh";
    emitMemOpEnc3(Cond, L | B7 | B5 | B4, Rt, OpAddress, TInfo, Ldrh);
    return;
  }
  case IceType_i32: {
    // LDR (immediate) - ARM section A8.8.63, encoding A1:
    //   ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}]      ; p=1, w=0
    //   ldr<c> <Rt>, [<Rn>], #+/-<imm12>        ; p=1, w=1
    //   ldr<c> <Rt>, [<Rn>, #+/-<imm12>]!       ; p=0, w=1
    //
    // cccc010pu0w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
    // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
    //
    // LDR (register) - ARM section A8.8.70, encoding A1:
    //   ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
    //   ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>}
    //
    // cccc011pu0w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
    // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
    constexpr bool IsByte = false;
    emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, LdrName);
    return;
  }
  }
}

void AssemblerARM32::emitMemExOp(CondARM32::Cond Cond, Type Ty, bool IsLoad,
                                 const Operand *OpRd, IValueT Rt,
                                 const Operand *OpAddress,
                                 const TargetInfo &TInfo,
                                 const char *InstName) {
  IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
  IValueT MemExOpcode = IsLoad ? B0 : 0;
  switch (Ty) {
  default:
    llvm::report_fatal_error(std::string(InstName) + ": Type " +
                             typeString(Ty) + " not allowed");
  case IceType_i1:
  case IceType_i8:
    MemExOpcode |= B2;
    break;
  case IceType_i16:
    MemExOpcode |= B2 | B1;
    break;
  case IceType_i32:
    break;
  case IceType_i64:
    MemExOpcode |= B1;
  }
  IValueT AddressRn;
  if (encodeAddress(OpAddress, AddressRn, TInfo, NoImmOffsetAddress) !=
      EncodedAsImmRegOffset)
    llvm::report_fatal_error(std::string(InstName) +
                             ": Can't extract Rn from address");
  assert(Utils::IsAbsoluteUint(3, MemExOpcode));
  assert(Rd < RegARM32::getNumGPRegs());
  assert(Rt < RegARM32::getNumGPRegs());
  assert(CondARM32::isDefined(Cond));
  IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 |
                     B8 | B7 | B4 | (MemExOpcode << kMemExOpcodeShift) |
                     AddressRn | (Rd << kRdShift) | (Rt << kRmShift);
  emitInst(Encoding);
  return;
}

void AssemblerARM32::ldrex(const Operand *OpRt, const Operand *OpAddress,
                           CondARM32::Cond Cond, const TargetInfo &TInfo) {
  // LDREXB - ARM section A8.8.76, encoding A1:
  //   ldrexb<c> <Rt>, [<Rn>]
  //
  // cccc00011101nnnntttt111110011111 where cccc=Cond, tttt=Rt, and nnnn=Rn.
  //
  // LDREXH - ARM section A8.8.78, encoding A1:
  //   ldrexh<c> <Rt>, [<Rn>]
  //
  // cccc00011111nnnntttt111110011111 where cccc=Cond, tttt=Rt, and nnnn=Rn.
  //
  // LDREX - ARM section A8.8.75, encoding A1:
  //   ldrex<c> <Rt>, [<Rn>]
  //
  // cccc00011001nnnntttt111110011111 where cccc=Cond, tttt=Rt, and nnnn=Rn.
  //
  // LDREXD - ARM section A8.
  //   ldrexd<c> <Rt>, [<Rn>]
  //
  // cccc00011001nnnntttt111110011111 where cccc=Cond, tttt=Rt, and nnnn=Rn.
  constexpr const char *LdrexName = "ldrex";
  const Type Ty = OpRt->getType();
  constexpr bool IsLoad = true;
  constexpr IValueT Rm = RegARM32::Encoded_Reg_pc;
  emitMemExOp(Cond, Ty, IsLoad, OpRt, Rm, OpAddress, TInfo, LdrexName);
}

void AssemblerARM32::emitShift(const CondARM32::Cond Cond,
                               const OperandARM32::ShiftKind Shift,
                               const Operand *OpRd, const Operand *OpRm,
                               const Operand *OpSrc1, const bool SetFlags,
                               const char *InstName) {
  constexpr IValueT ShiftOpcode = B3 | B2 | B0; // 1101
  IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
  IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName);
  IValueT Value;
  switch (encodeOperand(OpSrc1, Value, WantGPRegs)) {
  default:
    llvm::report_fatal_error(std::string(InstName) +
                             ": Last operand not understood");
  case EncodedAsShiftImm5: {
    // XXX (immediate)
    //   xxx{s}<c> <Rd>, <Rm>, #imm5
    //
    // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
    // iiiii=imm5, and mmmm=Rm.
    constexpr IValueT Rn = 0; // Rn field is not used.
    Value = Value | (Rm << kRmShift) | (Shift << kShiftShift);
    emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd,
               Value, RdIsPcAndSetFlags, InstName);
    return;
  }
  case EncodedAsRegister: {
    // XXX (register)
    //   xxx{S}<c> <Rd>, <Rm>, <Rs>
    //
    // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
    // mmmm=Rm, and ssss=Rs.
    constexpr IValueT Rn = 0; // Rn field is not used.
    IValueT Rs = encodeGPRegister(OpSrc1, "Rs", InstName);
    verifyRegNotPc(Rd, "Rd", InstName);
    verifyRegNotPc(Rm, "Rm", InstName);
    verifyRegNotPc(Rs, "Rs", InstName);
    emitType01(Cond, kInstTypeDataRegShift, ShiftOpcode, SetFlags, Rn, Rd,
               encodeShiftRotateReg(Rm, Shift, Rs), NoChecks, InstName);
    return;
  }
  }
}

void AssemblerARM32::asr(const Operand *OpRd, const Operand *OpRm,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  constexpr const char *AsrName = "asr";
  emitShift(Cond, OperandARM32::ASR, OpRd, OpRm, OpSrc1, SetFlags, AsrName);
}

void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  constexpr const char *LslName = "lsl";
  emitShift(Cond, OperandARM32::LSL, OpRd, OpRm, OpSrc1, SetFlags, LslName);
}

void AssemblerARM32::lsr(const Operand *OpRd, const Operand *OpRm,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  constexpr const char *LsrName = "lsr";
  emitShift(Cond, OperandARM32::LSR, OpRd, OpRm, OpSrc1, SetFlags, LsrName);
}

void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
                         CondARM32::Cond Cond) {
  // MOV (register) - ARM section A8.8.104, encoding A1:
  //   mov{S}<c> <Rd>, <Rn>
  //
  // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
  // and nnnn=Rn.
  //
  // MOV (immediate) - ARM section A8.8.102, encoding A1:
  //   mov{S}<c> <Rd>, #<RotatedImm8>
  //
  // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
  // and iiiiiiiiiiii=RotatedImm8=Src.  Note: We don't use movs in this
  // assembler.
  constexpr const char *MovName = "mov";
  IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName);
  constexpr bool SetFlags = false;
  constexpr IValueT Rn = 0;
  constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101.
  emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
             MovName);
}

void AssemblerARM32::emitMovwt(CondARM32::Cond Cond, bool IsMovW,
                               const Operand *OpRd, const Operand *OpSrc,
                               const char *MovName) {
  IValueT Opcode = B25 | B24 | (IsMovW ? 0 : B22);
  IValueT Rd = encodeGPRegister(OpRd, "Rd", MovName);
  IValueT Imm16;
  if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
    emitFixup(createMoveFixup(IsMovW, Src));
    // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
    // install the correct bits.
    Imm16 = 0;
  } else if (encodeOperand(OpSrc, Imm16, WantGPRegs) != EncodedAsConstI32) {
    llvm::report_fatal_error(std::string(MovName) + ": Not i32 constant");
  }
  assert(CondARM32::isDefined(Cond));
  if (!Utils::IsAbsoluteUint(16, Imm16))
    llvm::report_fatal_error(std::string(MovName) + ": Constant not i16");
  const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode |
                           ((Imm16 >> 12) << 16) | Rd << kRdShift |
                           (Imm16 & 0xfff);
  emitInst(Encoding);
}

void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc,
                          CondARM32::Cond Cond) {
  // MOV (immediate) - ARM section A8.8.102, encoding A2:
  //  movw<c> <Rd>, #<imm16>
  //
  // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
  // iiiiiiiiiiiiiiii=imm16.
  constexpr const char *MovwName = "movw";
  constexpr bool IsMovW = true;
  emitMovwt(Cond, IsMovW, OpRd, OpSrc, MovwName);
}

void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc,
                          CondARM32::Cond Cond) {
  // MOVT - ARM section A8.8.106, encoding A1:
  //  movt<c> <Rd>, #<imm16>
  //
  // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
  // iiiiiiiiiiiiiiii=imm16.
  constexpr const char *MovtName = "movt";
  constexpr bool IsMovW = false;
  emitMovwt(Cond, IsMovW, OpRd, OpSrc, MovtName);
}

void AssemblerARM32::mvn(const Operand *OpRd, const Operand *OpSrc,
                         CondARM32::Cond Cond) {
  // MVN (immediate) - ARM section A8.8.115, encoding A1:
  //   mvn{s}<c> <Rd>, #<const>
  //
  // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd,
  // and iiiiiiiiiiii=const
  //
  // MVN (register) - ARM section A8.8.116, encoding A1:
  //   mvn{s}<c> <Rd>, <Rm>{, <shift>
  //
  // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd,
  // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind.
  constexpr const char *MvnName = "mvn";
  IValueT Rd = encodeGPRegister(OpRd, "Rd", MvnName);
  constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111
  constexpr IValueT Rn = 0;
  constexpr bool SetFlags = false;
  emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags,
             MvnName);
}

void AssemblerARM32::nop() {
  // NOP - Section A8.8.119, encoding A1:
  //  nop<c>
  //
  // cccc0011001000001111000000000000 where cccc=Cond.
  constexpr CondARM32::Cond Cond = CondARM32::AL;
  const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B25 |
                           B24 | B21 | B15 | B14 | B13 | B12;
  emitInst(Encoding);
}

void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // SBC (register) - ARM section 18.8.162, encoding A1:
  //   sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
  //
  // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
  //
  // SBC (Immediate) - ARM section A8.8.161, encoding A1:
  //   sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
  //
  // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  constexpr const char *SbcName = "sbc";
  constexpr IValueT SbcOpcode = B2 | B1; // 0110
  emitType01(Cond, SbcOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             SbcName);
}

void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn,
                          const Operand *OpSrc1, CondARM32::Cond Cond) {
  // SDIV - ARM section A8.8.165, encoding A1.
  //   sdiv<c> <Rd>, <Rn>, <Rm>
  //
  // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
  // mmmm=Rm.
  constexpr const char *SdivName = "sdiv";
  IValueT Rd = encodeGPRegister(OpRd, "Rd", SdivName);
  IValueT Rn = encodeGPRegister(OpRn, "Rn", SdivName);
  IValueT Rm = encodeGPRegister(OpSrc1, "Rm", SdivName);
  verifyRegNotPc(Rd, "Rd", SdivName);
  verifyRegNotPc(Rn, "Rn", SdivName);
  verifyRegNotPc(Rm, "Rm", SdivName);
  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
  constexpr IValueT SdivOpcode = 0;
  emitDivOp(Cond, SdivOpcode, Rd, Rn, Rm);
}

void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
                         CondARM32::Cond Cond, const TargetInfo &TInfo) {
  constexpr const char *StrName = "str";
  constexpr bool IsLoad = false;
  IValueT Rt = encodeGPRegister(OpRt, "Rt", StrName);
  const Type Ty = OpRt->getType();
  switch (Ty) {
  case IceType_i64:
    // STRD is not implemented because target lowering handles i64 and double by
    // using two (32-bit) store instructions.  Note: Intentionally drop to
    // default case.
    llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) +
                             " not implemented");
  default:
    llvm::report_fatal_error(std::string(StrName) + ": Type " + typeString(Ty) +
                             " not allowed");
  case IceType_i1:
  case IceType_i8: {
    // STRB (immediate) - ARM section A8.8.207, encoding A1:
    //   strb<c> <Rt>, [<Rn>{, #+/-<imm12>}]     ; p=1, w=0
    //   strb<c> <Rt>, [<Rn>], #+/-<imm12>       ; p=1, w=1
    //   strb<c> <Rt>, [<Rn>, #+/-<imm12>]!      ; p=0, w=1
    //
    // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
    // iiiiiiiiiiii=imm12, u=1 if +.
    constexpr bool IsByte = true;
    emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName);
    return;
  }
  case IceType_i16: {
    // STRH (immediate) - ARM section A8.*.217, encoding A1:
    //   strh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
    //   strh<c> <Rt>, [<Rn>], #+/-<Imm8>
    //   strh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
    //
    // cccc000pu1w0nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
    // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
    // pu0w0nnnn0000iiiiiiiiiiii=Address.
    constexpr const char *Strh = "strh";
    emitMemOpEnc3(Cond, B7 | B5 | B4, Rt, OpAddress, TInfo, Strh);
    return;
  }
  case IceType_i32: {
    // Note: Handles i32 and float stores. Target lowering handles i64 and
    // double by using two (32 bit) store instructions.
    //
    // STR (immediate) - ARM section A8.8.207, encoding A1:
    //   str<c> <Rt>, [<Rn>{, #+/-<imm12>}]     ; p=1, w=0
    //   str<c> <Rt>, [<Rn>], #+/-<imm12>       ; p=1, w=1
    //   str<c> <Rt>, [<Rn>, #+/-<imm12>]!      ; p=0, w=1
    //
    // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
    // iiiiiiiiiiii=imm12, u=1 if +.
    constexpr bool IsByte = false;
    emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName);
    return;
  }
  }
}

void AssemblerARM32::strex(const Operand *OpRd, const Operand *OpRt,
                           const Operand *OpAddress, CondARM32::Cond Cond,
                           const TargetInfo &TInfo) {
  // STREXB - ARM section A8.8.213, encoding A1:
  //   strexb<c> <Rd>, <Rt>, [<Rn>]
  //
  // cccc00011100nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
  // nnnn=Rn.
  //
  // STREXH - ARM section A8.8.215, encoding A1:
  //   strexh<c> <Rd>, <Rt>, [<Rn>]
  //
  // cccc00011110nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
  // nnnn=Rn.
  //
  // STREX - ARM section A8.8.212, encoding A1:
  //   strex<c> <Rd>, <Rt>, [<Rn>]
  //
  // cccc00011000nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
  // nnnn=Rn.
  //
  // STREXD - ARM section A8.8.214, encoding A1:
  //   strexd<c> <Rd>, <Rt>, [<Rn>]
  //
  // cccc00011010nnnndddd11111001tttt where cccc=Cond, dddd=Rd, tttt=Rt, and
  // nnnn=Rn.
  constexpr const char *StrexName = "strex";
  // Note: Rt uses Rm shift in encoding.
  IValueT Rt = encodeGPRegister(OpRt, "Rt", StrexName);
  const Type Ty = OpRt->getType();
  constexpr bool IsLoad = true;
  emitMemExOp(Cond, Ty, !IsLoad, OpRd, Rt, OpAddress, TInfo, StrexName);
}

void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // ORR (register) - ARM Section A8.8.123, encoding A1:
  //   orr{s}<c> <Rd>, <Rn>, <Rm>
  //
  // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags.
  //
  // ORR (register) - ARM Section A8.8.123, encoding A1:
  //   orr{s}<c> <Rd>, <Rn>,  #<RotatedImm8>
  //
  // cccc0001100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
  constexpr const char *OrrName = "orr";
  constexpr IValueT OrrOpcode = B3 | B2; // i.e. 1100
  emitType01(Cond, OrrOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             OrrName);
}

void AssemblerARM32::pop(const Variable *OpRt, CondARM32::Cond Cond) {
  // POP - ARM section A8.8.132, encoding A2:
  //   pop<c> {Rt}
  //
  // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
  constexpr const char *Pop = "pop";
  IValueT Rt = encodeGPRegister(OpRt, "Rt", Pop);
  verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop);
  // Same as load instruction.
  constexpr bool IsLoad = true;
  constexpr bool IsByte = false;
  constexpr IOffsetT MaxOffset = (1 << 8) - 1;
  constexpr IValueT NoShiftRight = 0;
  IValueT Address =
      encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
                         OperandARM32Mem::PostIndex, MaxOffset, NoShiftRight);
  emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
}

void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) {
  // POP - ARM section A8.*.131, encoding A1:
  //   pop<c> <registers>
  //
  // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and
  // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
  constexpr bool IsLoad = true;
  emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
}

void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
  // PUSH - ARM section A8.8.133, encoding A2:
  //   push<c> {Rt}
  //
  // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond.
  constexpr const char *Push = "push";
  IValueT Rt = encodeGPRegister(OpRt, "Rt", Push);
  verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push);
  // Same as store instruction.
  constexpr bool isLoad = false;
  constexpr bool isByte = false;
  constexpr IOffsetT MaxOffset = (1 << 8) - 1;
  constexpr IValueT NoShiftRight = 0;
  IValueT Address =
      encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
                         OperandARM32Mem::PreIndex, MaxOffset, NoShiftRight);
  emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address);
}

void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) {
  // PUSH - ARM section A8.8.133, encoding A1:
  //   push<c> <Registers>
  //
  // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and
  // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
  constexpr bool IsLoad = false;
  emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
}

void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpRm, const Operand *OpRa,
                         CondARM32::Cond Cond) {
  // MLA - ARM section A8.8.114, encoding A1.
  //   mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra>
  //
  // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd,
  // aaaa=Ra, mmmm=Rm, and nnnn=Rn.
  constexpr const char *MlaName = "mla";
  IValueT Rd = encodeGPRegister(OpRd, "Rd", MlaName);
  IValueT Rn = encodeGPRegister(OpRn, "Rn", MlaName);
  IValueT Rm = encodeGPRegister(OpRm, "Rm", MlaName);
  IValueT Ra = encodeGPRegister(OpRa, "Ra", MlaName);
  verifyRegNotPc(Rd, "Rd", MlaName);
  verifyRegNotPc(Rn, "Rn", MlaName);
  verifyRegNotPc(Rm, "Rm", MlaName);
  verifyRegNotPc(Ra, "Ra", MlaName);
  constexpr IValueT MlaOpcode = B21;
  constexpr bool SetFlags = true;
  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
  emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, !SetFlags);
}

void AssemblerARM32::mls(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpRm, const Operand *OpRa,
                         CondARM32::Cond Cond) {
  constexpr const char *MlsName = "mls";
  IValueT Rd = encodeGPRegister(OpRd, "Rd", MlsName);
  IValueT Rn = encodeGPRegister(OpRn, "Rn", MlsName);
  IValueT Rm = encodeGPRegister(OpRm, "Rm", MlsName);
  IValueT Ra = encodeGPRegister(OpRa, "Ra", MlsName);
  verifyRegNotPc(Rd, "Rd", MlsName);
  verifyRegNotPc(Rn, "Rn", MlsName);
  verifyRegNotPc(Rm, "Rm", MlsName);
  verifyRegNotPc(Ra, "Ra", MlsName);
  constexpr IValueT MlsOpcode = B22 | B21;
  constexpr bool SetFlags = true;
  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
  emitMulOp(Cond, MlsOpcode, Ra, Rd, Rn, Rm, !SetFlags);
}

void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // MUL - ARM section A8.8.114, encoding A1.
  //   mul{s}<c> <Rd>, <Rn>, <Rm>
  //
  // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, and s=SetFlags.
  constexpr const char *MulName = "mul";
  IValueT Rd = encodeGPRegister(OpRd, "Rd", MulName);
  IValueT Rn = encodeGPRegister(OpRn, "Rn", MulName);
  IValueT Rm = encodeGPRegister(OpSrc1, "Rm", MulName);
  verifyRegNotPc(Rd, "Rd", MulName);
  verifyRegNotPc(Rn, "Rn", MulName);
  verifyRegNotPc(Rm, "Rm", MulName);
  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
  constexpr IValueT MulOpcode = 0;
  emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags);
}

void AssemblerARM32::emitRdRm(CondARM32::Cond Cond, IValueT Opcode,
                              const Operand *OpRd, const Operand *OpRm,
                              const char *InstName) {
  IValueT Rd = encodeGPRegister(OpRd, "Rd", InstName);
  IValueT Rm = encodeGPRegister(OpRm, "Rm", InstName);
  IValueT Encoding =
      (Cond << kConditionShift) | Opcode | (Rd << kRdShift) | (Rm << kRmShift);
  emitInst(Encoding);
}

void AssemblerARM32::rbit(const Operand *OpRd, const Operand *OpRm,
                          CondARM32::Cond Cond) {
  // RBIT - ARM section A8.8.144, encoding A1:
  //   rbit<c> <Rd>, <Rm>
  //
  // cccc011011111111dddd11110011mmmm where cccc=Cond, dddd=Rn, and mmmm=Rm.
  constexpr const char *RbitName = "rev";
  constexpr IValueT RbitOpcode = B26 | B25 | B23 | B22 | B21 | B20 | B19 | B18 |
                                 B17 | B16 | B11 | B10 | B9 | B8 | B5 | B4;
  emitRdRm(Cond, RbitOpcode, OpRd, OpRm, RbitName);
}

void AssemblerARM32::rev(const Operand *OpRd, const Operand *OpRm,
                         CondARM32::Cond Cond) {
  // REV - ARM section A8.8.145, encoding A1:
  //   rev<c> <Rd>, <Rm>
  //
  // cccc011010111111dddd11110011mmmm where cccc=Cond, dddd=Rn, and mmmm=Rm.
  constexpr const char *RevName = "rev";
  constexpr IValueT RevOpcode = B26 | B25 | B23 | B21 | B20 | B19 | B18 | B17 |
                                B16 | B11 | B10 | B9 | B8 | B5 | B4;
  emitRdRm(Cond, RevOpcode, OpRd, OpRm, RevName);
}

void AssemblerARM32::rsb(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // RSB (immediate) - ARM section A8.8.152, encoding A1.
  //   rsb{s}<c> <Rd>, <Rn>, #<RotatedImm8>
  //
  // cccc0010011snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=setFlags and iiiiiiiiiiii defines the RotatedImm8 value.
  //
  // RSB (register) - ARM section A8.8.163, encoding A1.
  //   rsb{s}<c> <Rd>, <Rn>, <Rm>{, <Shift>}
  //
  // cccc0000011snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=shift, tt==ShiftKind, and s=SetFlags.
  constexpr const char *RsbName = "rsb";
  constexpr IValueT RsbOpcode = B1 | B0; // 0011
  emitType01(Cond, RsbOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             RsbName);
}

void AssemblerARM32::rsc(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // RSC (immediate) - ARM section A8.8.155, encoding A1:
  //   rsc{s}<c> <Rd>, <Rn>, #<RotatedImm8>
  //
  // cccc0010111snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=shift, tt=ShiftKind, and s=SetFlags.
  //
  // RSC (register) - ARM section A8.8.156, encoding A1:
  //   rsc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
  //
  // cccc0000111snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=shift, tt=ShiftKind, and s=SetFlags.
  //
  // RSC (register-shifted register) - ARM section A8.8.157, encoding A1:
  //   rsc{s}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
  //
  // cccc0000111fnnnnddddssss0tt1mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, ssss=Rs, tt defined <type>, and f=SetFlags.
  constexpr const char *RscName = "rsc";
  constexpr IValueT RscOpcode = B2 | B1 | B0; // i.e. 0111.
  emitType01(Cond, RscOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             RscName);
}

void AssemblerARM32::sxt(const Operand *OpRd, const Operand *OpSrc0,
                         CondARM32::Cond Cond) {
  constexpr const char *SxtName = "sxt";
  constexpr IValueT SxtOpcode = B26 | B25 | B23 | B21;
  emitSignExtend(Cond, SxtOpcode, OpRd, OpSrc0, SxtName);
}

void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
                         const Operand *OpSrc1, bool SetFlags,
                         CondARM32::Cond Cond) {
  // SUB (register) - ARM section A8.8.223, encoding A1:
  //   sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>}
  // SUB (SP minus register): See ARM section 8.8.226, encoding A1:
  //   sub{s}<c> <Rd>, sp, <Rm>{, <Shift>}
  //
  // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
  // mmmm=Rm, iiiii=shift, tt=ShiftKind, and s=SetFlags.
  //
  // Sub (Immediate) - ARM section A8.8.222, encoding A1:
  //    sub{s}<c> <Rd>, <Rn>, #<RotatedImm8>
  // Sub (Sp minus immediate) - ARM section A8.8.225, encoding A1:
  //    sub{s}<c> sp, <Rn>, #<RotatedImm8>
  //
  // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
  // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8
  constexpr const char *SubName = "sub";
  constexpr IValueT SubOpcode = B1; // 0010
  emitType01(Cond, SubOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags,
             SubName);
}

namespace {

// Use a particular UDF encoding -- TRAPNaCl in LLVM: 0xE7FEDEF0
// http://llvm.org/viewvc/llvm-project?view=revision&revision=173943
const uint8_t TrapBytesRaw[] = {0xE7, 0xFE, 0xDE, 0xF0};

const auto TrapBytes =
    llvm::ArrayRef<uint8_t>(TrapBytesRaw, llvm::array_lengthof(TrapBytesRaw));

} // end of anonymous namespace

llvm::ArrayRef<uint8_t> AssemblerARM32::getNonExecBundlePadding() const {
  return TrapBytes;
}

void AssemblerARM32::trap() {
  AssemblerBuffer::EnsureCapacity ensured(&Buffer);
  for (const uint8_t &Byte : reverse_range(TrapBytes))
    Buffer.emit<uint8_t>(Byte);
}

void AssemblerARM32::tst(const Operand *OpRn, const Operand *OpSrc1,
                         CondARM32::Cond Cond) {
  // TST (register) - ARM section A8.8.241, encoding A1:
  //   tst<c> <Rn>, <Rm>(, <shift>}
  //
  // cccc00010001nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm,
  // iiiii=Shift, and tt=ShiftKind.
  //
  // TST (immediate) - ARM section A8.8.240, encoding A1:
  //   tst<c> <Rn>, #<RotatedImm8>
  //
  // cccc00110001nnnn0000iiiiiiiiiiii where cccc=Cond, nnnn=Rn, and
  // iiiiiiiiiiii defines RotatedImm8.
  constexpr const char *TstName = "tst";
  constexpr IValueT TstOpcode = B3; // ie. 1000
  emitCompareOp(Cond, TstOpcode, OpRn, OpSrc1, TstName);
}

void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn,
                          const Operand *OpSrc1, CondARM32::Cond Cond) {
  // UDIV - ARM section A8.8.248, encoding A1.
  //   udiv<c> <Rd>, <Rn>, <Rm>
  //
  // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
  // mmmm=Rm.
  constexpr const char *UdivName = "udiv";
  IValueT Rd = encodeGPRegister(OpRd, "Rd", UdivName);
  IValueT Rn = encodeGPRegister(OpRn, "Rn", UdivName);
  IValueT Rm = encodeGPRegister(OpSrc1, "Rm", UdivName);
  verifyRegNotPc(Rd, "Rd", UdivName);
  verifyRegNotPc(Rn, "Rn", UdivName);
  verifyRegNotPc(Rm, "Rm", UdivName);
  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
  constexpr IValueT UdivOpcode = B21;
  emitDivOp(Cond, UdivOpcode, Rd, Rn, Rm);
}

void AssemblerARM32::umull(const Operand *OpRdLo, const Operand *OpRdHi,
                           const Operand *OpRn, const Operand *OpRm,
                           CondARM32::Cond Cond) {
  // UMULL - ARM section A8.8.257, encoding A1:
  //   umull<c> <RdLo>, <RdHi>, <Rn>, <Rm>
  //
  // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn,
  // mmmm=Rm, and s=SetFlags
  constexpr const char *UmullName = "umull";
  IValueT RdLo = encodeGPRegister(OpRdLo, "RdLo", UmullName);
  IValueT RdHi = encodeGPRegister(OpRdHi, "RdHi", UmullName);
  IValueT Rn = encodeGPRegister(OpRn, "Rn", UmullName);
  IValueT Rm = encodeGPRegister(OpRm, "Rm", UmullName);
  verifyRegNotPc(RdLo, "RdLo", UmullName);
  verifyRegNotPc(RdHi, "RdHi", UmullName);
  verifyRegNotPc(Rn, "Rn", UmullName);
  verifyRegNotPc(Rm, "Rm", UmullName);
  verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName);
  constexpr IValueT UmullOpcode = B23;
  constexpr bool SetFlags = false;
  emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags);
}

void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
                         CondARM32::Cond Cond) {
  constexpr const char *UxtName = "uxt";
  constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21;
  emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
}

void AssemblerARM32::vabss(const Operand *OpSd, const Operand *OpSm,
                           CondARM32::Cond Cond) {
  // VABS - ARM section A8.8.280, encoding A2:
  //   vabs<c>.f32 <Sd>, <Sm>
  //
  // cccc11101D110000dddd101011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
  constexpr const char *Vabss = "vabss";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vabss);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vabss);
  constexpr IValueT S0 = 0;
  constexpr IValueT VabssOpcode = B23 | B21 | B20 | B7 | B6;
  emitVFPsss(Cond, VabssOpcode, Sd, S0, Sm);
}

void AssemblerARM32::vabsd(const Operand *OpDd, const Operand *OpDm,
                           CondARM32::Cond Cond) {
  // VABS - ARM section A8.8.280, encoding A2:
  //   vabs<c>.f64 <Dd>, <Dm>
  //
  // cccc11101D110000dddd101111M0mmmm where cccc=Cond, Ddddd=Dd, and Mmmmm=Dm.
  constexpr const char *Vabsd = "vabsd";
  const IValueT Dd = encodeDRegister(OpDd, "Dd", Vabsd);
  const IValueT Dm = encodeDRegister(OpDm, "Dm", Vabsd);
  constexpr IValueT D0 = 0;
  constexpr IValueT VabsdOpcode = B23 | B21 | B20 | B7 | B6;
  emitVFPddd(Cond, VabsdOpcode, Dd, D0, Dm);
}

void AssemblerARM32::vabsq(const Operand *OpQd, const Operand *OpQm) {
  // VABS - ARM section A8.8.280, encoding A1:
  //   vabs.<dt> <Qd>, <Qm>
  //
  // 111100111D11ss01ddd0f1101M0mmm0 where Dddd=OpQd, Mddd=OpQm, and
  // <dt> in {s8, s16, s32, f32} and ss is the encoding of <dt>.
  const Type ElmtTy = typeElementType(OpQd->getType());
  assert(ElmtTy != IceType_i64 && "vabsq doesn't allow i64!");
  constexpr const char *Vabsq = "vabsq";
  const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vabsq));
  const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vabsq));
  constexpr IValueT Dn = 0;
  const IValueT VabsqOpcode =
      B24 | B23 | B21 | B20 | B16 | B9 | B8 | (encodeElmtType(ElmtTy) << 18);
  constexpr bool UseQRegs = true;
  emitSIMDBase(VabsqOpcode, Dd, Dn, Dm, UseQRegs, isFloatingType(ElmtTy));
}

void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn,
                           const Operand *OpSm, CondARM32::Cond Cond) {
  // VADD (floating-point) - ARM section A8.8.283, encoding A2:
  //   vadd<c>.f32 <Sd>, <Sn>, <Sm>
  //
  // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
  // and mmmmM=Rm.
  constexpr const char *Vadds = "vadds";
  constexpr IValueT VaddsOpcode = B21 | B20;
  emitVFPsss(Cond, VaddsOpcode, OpSd, OpSn, OpSm, Vadds);
}

void AssemblerARM32::vaddqi(Type ElmtTy, const Operand *OpQd,
                            const Operand *OpQm, const Operand *OpQn) {
  // VADD (integer) - ARM section A8.8.282, encoding A1:
  //   vadd.<dt> <Qd>, <Qn>, <Qm>
  //
  // 111100100Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
  // and dt in [i8, i16, i32, i64] where ss is the index.
  assert(isScalarIntegerType(ElmtTy) &&
         "vaddqi expects vector with integer element type");
  constexpr const char *Vaddqi = "vaddqi";
  constexpr IValueT VaddqiOpcode = B11;
  emitSIMDqqq(VaddqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vaddqi);
}

void AssemblerARM32::vaddqf(const Operand *OpQd, const Operand *OpQn,
                            const Operand *OpQm) {
  // VADD (floating-point) - ARM section A8.8.283, Encoding A1:
  //   vadd.f32 <Qd>, <Qn>, <Qm>
  //
  // 111100100D00nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
  assert(OpQd->getType() == IceType_v4f32 && "vaddqf expects type <4 x float>");
  constexpr const char *Vaddqf = "vaddqf";
  constexpr IValueT VaddqfOpcode = B11 | B8;
  constexpr bool IsFloatTy = true;
  emitSIMDqqqBase(VaddqfOpcode, OpQd, OpQn, OpQm, IsFloatTy, Vaddqf);
}

void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn,
                           const Operand *OpDm, CondARM32::Cond Cond) {
  // VADD (floating-point) - ARM section A8.8.283, encoding A2:
  //   vadd<c>.f64 <Dd>, <Dn>, <Dm>
  //
  // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
  // and Mmmmm=Rm.
  constexpr const char *Vaddd = "vaddd";
  constexpr IValueT VadddOpcode = B21 | B20;
  emitVFPddd(Cond, VadddOpcode, OpDd, OpDn, OpDm, Vaddd);
}

void AssemblerARM32::vandq(const Operand *OpQd, const Operand *OpQm,
                           const Operand *OpQn) {
  // VAND (register) - ARM section A8.8.287, encoding A1:
  //   vand <Qd>, <Qn>, <Qm>
  //
  // 111100100D00nnn0ddd00001N1M1mmm0 where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
  constexpr const char *Vandq = "vandq";
  constexpr IValueT VandqOpcode = B8 | B4;
  constexpr Type ElmtTy = IceType_i8;
  emitSIMDqqq(VandqOpcode, ElmtTy, OpQd, OpQm, OpQn, Vandq);
}

void AssemblerARM32::vcmpd(const Operand *OpDd, const Operand *OpDm,
                           CondARM32::Cond Cond) {
  constexpr const char *Vcmpd = "vcmpd";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Vcmpd);
  IValueT Dm = encodeDRegister(OpDm, "Dm", Vcmpd);
  constexpr IValueT VcmpdOpcode = B23 | B21 | B20 | B18 | B6;
  constexpr IValueT Dn = 0;
  emitVFPddd(Cond, VcmpdOpcode, Dd, Dn, Dm);
}

void AssemblerARM32::vcmpdz(const Operand *OpDd, CondARM32::Cond Cond) {
  constexpr const char *Vcmpdz = "vcmpdz";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Vcmpdz);
  constexpr IValueT VcmpdzOpcode = B23 | B21 | B20 | B18 | B16 | B6;
  constexpr IValueT Dn = 0;
  constexpr IValueT Dm = 0;
  emitVFPddd(Cond, VcmpdzOpcode, Dd, Dn, Dm);
}

void AssemblerARM32::vcmps(const Operand *OpSd, const Operand *OpSm,
                           CondARM32::Cond Cond) {
  constexpr const char *Vcmps = "vcmps";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcmps);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vcmps);
  constexpr IValueT VcmpsOpcode = B23 | B21 | B20 | B18 | B6;
  constexpr IValueT Sn = 0;
  emitVFPsss(Cond, VcmpsOpcode, Sd, Sn, Sm);
}

void AssemblerARM32::vcmpsz(const Operand *OpSd, CondARM32::Cond Cond) {
  constexpr const char *Vcmpsz = "vcmps";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcmpsz);
  constexpr IValueT VcmpszOpcode = B23 | B21 | B20 | B18 | B16 | B6;
  constexpr IValueT Sn = 0;
  constexpr IValueT Sm = 0;
  emitVFPsss(Cond, VcmpszOpcode, Sd, Sn, Sm);
}

void AssemblerARM32::emitVFPsd(CondARM32::Cond Cond, IValueT Opcode, IValueT Sd,
                               IValueT Dm) {
  assert(Sd < RegARM32::getNumSRegs());
  assert(Dm < RegARM32::getNumDRegs());
  assert(CondARM32::isDefined(Cond));
  constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
  const IValueT Encoding =
      Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
      (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) |
      (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
  emitInst(Encoding);
}

void AssemblerARM32::vcvtdi(const Operand *OpDd, const Operand *OpSm,
                            CondARM32::Cond Cond) {
  // VCVT (between floating-point and integer, Floating-point)
  //      - ARM Section A8.8.306, encoding A1:
  //   vcvt<c>.f64.s32 <Dd>, <Sm>
  //
  // cccc11101D111000dddd10111M0mmmm where cccc=Cond, Ddddd=Dd, and mmmmM=Sm.
  constexpr const char *Vcvtdi = "vcvtdi";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Vcvtdi);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtdi);
  constexpr IValueT VcvtdiOpcode = B23 | B21 | B20 | B19 | B8 | B7 | B6;
  emitVFPds(Cond, VcvtdiOpcode, Dd, Sm);
}

void AssemblerARM32::vcvtdu(const Operand *OpDd, const Operand *OpSm,
                            CondARM32::Cond Cond) {
  // VCVT (between floating-point and integer, Floating-point)
  //      - ARM Section A8.8.306, encoding A1:
  //   vcvt<c>.f64.u32 <Dd>, <Sm>
  //
  // cccc11101D111000dddd10101M0mmmm where cccc=Cond, Ddddd=Dd, and mmmmM=Sm.
  constexpr const char *Vcvtdu = "vcvtdu";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Vcvtdu);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtdu);
  constexpr IValueT VcvtduOpcode = B23 | B21 | B20 | B19 | B8 | B6;
  emitVFPds(Cond, VcvtduOpcode, Dd, Sm);
}

void AssemblerARM32::vcvtsd(const Operand *OpSd, const Operand *OpDm,
                            CondARM32::Cond Cond) {
  constexpr const char *Vcvtsd = "vcvtsd";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtsd);
  IValueT Dm = encodeDRegister(OpDm, "Dm", Vcvtsd);
  constexpr IValueT VcvtsdOpcode =
      B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6;
  emitVFPsd(Cond, VcvtsdOpcode, Sd, Dm);
}

void AssemblerARM32::vcvtis(const Operand *OpSd, const Operand *OpSm,
                            CondARM32::Cond Cond) {
  // VCVT (between floating-point and integer, Floating-point)
  //      - ARM Section A8.8.306, encoding A1:
  //   vcvt<c>.s32.f32 <Sd>, <Sm>
  //
  // cccc11101D111101dddd10011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
  constexpr const char *Vcvtis = "vcvtis";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtis);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtis);
  constexpr IValueT VcvtisOpcode = B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6;
  constexpr IValueT S0 = 0;
  emitVFPsss(Cond, VcvtisOpcode, Sd, S0, Sm);
}

void AssemblerARM32::vcvtid(const Operand *OpSd, const Operand *OpDm,
                            CondARM32::Cond Cond) {
  // VCVT (between floating-point and integer, Floating-point)
  //      - ARM Section A8.8.306, encoding A1:
  //   vcvt<c>.s32.f64 <Sd>, <Dm>
  //
  // cccc11101D111101dddd10111M0mmmm where cccc=Cond, ddddD=Sd, and Mmmmm=Dm.
  constexpr const char *Vcvtid = "vcvtid";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtid);
  IValueT Dm = encodeDRegister(OpDm, "Dm", Vcvtid);
  constexpr IValueT VcvtidOpcode =
      B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6;
  emitVFPsd(Cond, VcvtidOpcode, Sd, Dm);
}

void AssemblerARM32::vcvtsi(const Operand *OpSd, const Operand *OpSm,
                            CondARM32::Cond Cond) {
  // VCVT (between floating-point and integer, Floating-point)
  //      - ARM Section A8.8.306, encoding A1:
  //   vcvt<c>.f32.s32 <Sd>, <Sm>
  //
  // cccc11101D111000dddd10011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
  constexpr const char *Vcvtsi = "vcvtsi";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtsi);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtsi);
  constexpr IValueT VcvtsiOpcode = B23 | B21 | B20 | B19 | B7 | B6;
  constexpr IValueT S0 = 0;
  emitVFPsss(Cond, VcvtsiOpcode, Sd, S0, Sm);
}

void AssemblerARM32::vcvtsu(const Operand *OpSd, const Operand *OpSm,
                            CondARM32::Cond Cond) {
  // VCVT (between floating-point and integer, Floating-point)
  //      - ARM Section A8.8.306, encoding A1:
  //   vcvt<c>.f32.u32 <Sd>, <Sm>
  //
  // cccc11101D111000dddd10001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
  constexpr const char *Vcvtsu = "vcvtsu";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtsu);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtsu);
  constexpr IValueT VcvtsuOpcode = B23 | B21 | B20 | B19 | B6;
  constexpr IValueT S0 = 0;
  emitVFPsss(Cond, VcvtsuOpcode, Sd, S0, Sm);
}

void AssemblerARM32::vcvtud(const Operand *OpSd, const Operand *OpDm,
                            CondARM32::Cond Cond) {
  // VCVT (between floating-point and integer, Floating-point)
  //      - ARM Section A8.8.306, encoding A1:
  //   vcvt<c>.u32.f64 <Sd>, <Dm>
  //
  // cccc11101D111100dddd10111M0mmmm where cccc=Cond, ddddD=Sd, and Mmmmm=Dm.
  constexpr const char *Vcvtud = "vcvtud";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtud);
  IValueT Dm = encodeDRegister(OpDm, "Dm", Vcvtud);
  constexpr IValueT VcvtudOpcode = B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6;
  emitVFPsd(Cond, VcvtudOpcode, Sd, Dm);
}

void AssemblerARM32::vcvtus(const Operand *OpSd, const Operand *OpSm,
                            CondARM32::Cond Cond) {
  // VCVT (between floating-point and integer, Floating-point)
  //      - ARM Section A8.8.306, encoding A1:
  //   vcvt<c>.u32.f32 <Sd>, <Sm>
  //
  // cccc11101D111100dddd10011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
  constexpr const char *Vcvtus = "vcvtus";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtus);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtus);
  constexpr IValueT VcvtsiOpcode = B23 | B21 | B20 | B19 | B18 | B7 | B6;
  constexpr IValueT S0 = 0;
  emitVFPsss(Cond, VcvtsiOpcode, Sd, S0, Sm);
}

void AssemblerARM32::emitVFPds(CondARM32::Cond Cond, IValueT Opcode, IValueT Dd,
                               IValueT Sm) {
  assert(Dd < RegARM32::getNumDRegs());
  assert(Sm < RegARM32::getNumSRegs());
  assert(CondARM32::isDefined(Cond));
  constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
  const IValueT Encoding =
      Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
      (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dd) << 12) |
      (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm);
  emitInst(Encoding);
}

void AssemblerARM32::vcvtds(const Operand *OpDd, const Operand *OpSm,
                            CondARM32::Cond Cond) {
  constexpr const char *Vcvtds = "Vctds";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Vcvtds);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtds);
  constexpr IValueT VcvtdsOpcode = B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6;
  emitVFPds(Cond, VcvtdsOpcode, Dd, Sm);
}

void AssemblerARM32::vdivs(const Operand *OpSd, const Operand *OpSn,
                           const Operand *OpSm, CondARM32::Cond Cond) {
  // VDIV (floating-point) - ARM section A8.8.283, encoding A2:
  //   vdiv<c>.f32 <Sd>, <Sn>, <Sm>
  //
  // cccc11101D00nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
  // and mmmmM=Rm.
  constexpr const char *Vdivs = "vdivs";
  constexpr IValueT VdivsOpcode = B23;
  emitVFPsss(Cond, VdivsOpcode, OpSd, OpSn, OpSm, Vdivs);
}

void AssemblerARM32::vdivd(const Operand *OpDd, const Operand *OpDn,
                           const Operand *OpDm, CondARM32::Cond Cond) {
  // VDIV (floating-point) - ARM section A8.8.283, encoding A2:
  //   vdiv<c>.f64 <Dd>, <Dn>, <Dm>
  //
  // cccc11101D00nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
  // and Mmmmm=Rm.
  constexpr const char *Vdivd = "vdivd";
  constexpr IValueT VdivdOpcode = B23;
  emitVFPddd(Cond, VdivdOpcode, OpDd, OpDn, OpDm, Vdivd);
}

void AssemblerARM32::veord(const Operand *OpDd, const Operand *OpDn,
                           const Operand *OpDm) {
  // VEOR - ARM secdtion A8.8.315, encoding A1:
  //   veor<c> <Dd>, <Dn>, <Dm>
  //
  // 111100110D00nnnndddd0001N0M1mmmm where Ddddd=Dd, Nnnnn=Dn, and Mmmmm=Dm.
  constexpr const char *Veord = "veord";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Veord);
  IValueT Dn = encodeDRegister(OpDn, "Dn", Veord);
  IValueT Dm = encodeDRegister(OpDm, "Dm", Veord);
  const IValueT Encoding =
      B25 | B24 | B8 | B4 |
      (encodeCondition(CondARM32::Cond::kNone) << kConditionShift) |
      (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
      (getXXXXInRegYXXXX(Dd) << 12) | (getYInRegYXXXX(Dn) << 7) |
      (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
  emitInst(Encoding);
}

void AssemblerARM32::veorq(const Operand *OpQd, const Operand *OpQn,
                           const Operand *OpQm) {
  // VEOR - ARM section A8.8.316, encoding A1:
  //   veor <Qd>, <Qn>, <Qm>
  //
  // 111100110D00nnn0ddd00001N1M1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
  constexpr const char *Veorq = "veorq";
  constexpr IValueT VeorqOpcode = B24 | B8 | B4;
  emitSIMDqqq(VeorqOpcode, IceType_i8, OpQd, OpQn, OpQm, Veorq);
}

void AssemblerARM32::vldrd(const Operand *OpDd, const Operand *OpAddress,
                           CondARM32::Cond Cond, const TargetInfo &TInfo) {
  // VLDR - ARM section A8.8.333, encoding A1.
  //   vldr<c> <Dd>, [<Rn>{, #+/-<imm>}]
  //
  // cccc1101UD01nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
  // iiiiiiii=abs(Imm >> 2), and U=1 if Opcode>=0.
  constexpr const char *Vldrd = "vldrd";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Vldrd);
  assert(CondARM32::isDefined(Cond));
  IValueT Address;
  EncodedOperand AddressEncoding =
      encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
  (void)AddressEncoding;
  assert(AddressEncoding == EncodedAsImmRegOffset);
  IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 |
                     (encodeCondition(Cond) << kConditionShift) |
                     (getYInRegYXXXX(Dd) << 22) |
                     (getXXXXInRegYXXXX(Dd) << 12) | Address;
  emitInst(Encoding);
}

void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress,
                           CondARM32::Cond Cond, const TargetInfo &TInfo) {
  // VDLR - ARM section A8.8.333, encoding A2.
  //   vldr<c> <Sd>, [<Rn>{, #+/-<imm>]]
  //
  // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd,
  // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0;
  constexpr const char *Vldrs = "vldrs";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vldrs);
  assert(CondARM32::isDefined(Cond));
  IValueT Address;
  EncodedOperand AddressEncoding =
      encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
  (void)AddressEncoding;
  assert(AddressEncoding == EncodedAsImmRegOffset);
  IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 |
                     (encodeCondition(Cond) << kConditionShift) |
                     (getYInRegXXXXY(Sd) << 22) |
                     (getXXXXInRegXXXXY(Sd) << 12) | Address;
  emitInst(Encoding);
}

void AssemblerARM32::emitVMem1Op(IValueT Opcode, IValueT Dd, IValueT Rn,
                                 IValueT Rm, DRegListSize NumDRegs,
                                 size_t ElmtSize, IValueT Align,
                                 const char *InstName) {
  assert(Utils::IsAbsoluteUint(2, Align));
  IValueT EncodedElmtSize;
  switch (ElmtSize) {
  default: {
    std::string Buffer;
    llvm::raw_string_ostream StrBuf(Buffer);
    StrBuf << InstName << ": found invalid vector element size " << ElmtSize;
    llvm::report_fatal_error(StrBuf.str());
  }
  case 8:
    EncodedElmtSize = 0;
    break;
  case 16:
    EncodedElmtSize = 1;
    break;
  case 32:
    EncodedElmtSize = 2;
    break;
  case 64:
    EncodedElmtSize = 3;
  }
  const IValueT Encoding =
      Opcode | (encodeCondition(CondARM32::kNone) << kConditionShift) |
      (getYInRegYXXXX(Dd) << 22) | (Rn << kRnShift) |
      (getXXXXInRegYXXXX(Dd) << kRdShift) | (NumDRegs << 8) |
      (EncodedElmtSize << 6) | (Align << 4) | Rm;
  emitInst(Encoding);
}

void AssemblerARM32::vld1qr(size_t ElmtSize, const Operand *OpQd,
                            const Operand *OpAddress, const TargetInfo &TInfo) {
  // VLD1 (multiple single elements) - ARM section A8.8.320, encoding A1:
  //   vld1.<size> <Qd>, [<Rn>]
  //
  // 111101000D10nnnnddd0ttttssaammmm where tttt=DRegListSize2, Dddd=Qd,
  // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the
  // encoding of ElmtSize.
  constexpr const char *Vld1qr = "vld1qr";
  const IValueT Qd = encodeQRegister(OpQd, "Qd", Vld1qr);
  const IValueT Dd = mapQRegToDReg(Qd);
  IValueT Address;
  if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) !=
      EncodedAsImmRegOffset)
    llvm::report_fatal_error(std::string(Vld1qr) + ": malform memory address");
  const IValueT Rn = mask(Address, kRnShift, 4);
  constexpr IValueT Rm = RegARM32::Reg_pc;
  constexpr IValueT Opcode = B26 | B21;
  constexpr IValueT Align = 0; // use default alignment.
  emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vld1qr);
}

void AssemblerARM32::vmovd(const Operand *OpDd,
                           const OperandARM32FlexFpImm *OpFpImm,
                           CondARM32::Cond Cond) {
  // VMOV (immediate) - ARM section A8.8.339, encoding A2:
  //   vmov<c>.f64 <Dd>, #<imm>
  //
  // cccc11101D11xxxxdddd10110000yyyy where cccc=Cond, ddddD=Sn, xxxxyyyy=imm.
  constexpr const char *Vmovd = "vmovd";
  IValueT Dd = encodeSRegister(OpDd, "Dd", Vmovd);
  IValueT Imm8 = OpFpImm->getModifiedImm();
  assert(Imm8 < (1 << 8));
  constexpr IValueT VmovsOpcode = B23 | B21 | B20 | B8;
  IValueT OpcodePlusImm8 = VmovsOpcode | ((Imm8 >> 4) << 16) | (Imm8 & 0xf);
  constexpr IValueT D0 = 0;
  emitVFPddd(Cond, OpcodePlusImm8, Dd, D0, D0);
}

void AssemblerARM32::vmovdd(const Operand *OpDd, const Variable *OpDm,
                            CondARM32::Cond Cond) {
  // VMOV (register) - ARM section A8.8.340, encoding A2:
  //   vmov<c>.f64 <Dd>, <Sm>
  //
  // cccc11101D110000dddd101101M0mmmm where cccc=Cond, Ddddd=Sd, and Mmmmm=Sm.
  constexpr const char *Vmovdd = "Vmovdd";
  IValueT Dd = encodeSRegister(OpDd, "Dd", Vmovdd);
  IValueT Dm = encodeSRegister(OpDm, "Dm", Vmovdd);
  constexpr IValueT VmovddOpcode = B23 | B21 | B20 | B6;
  constexpr IValueT D0 = 0;
  emitVFPddd(Cond, VmovddOpcode, Dd, D0, Dm);
}

void AssemblerARM32::vmovdrr(const Operand *OpDm, const Operand *OpRt,
                             const Operand *OpRt2, CondARM32::Cond Cond) {
  // VMOV (between two ARM core registers and a doubleword extension register).
  // ARM section A8.8.345, encoding A1:
  //   vmov<c> <Dm>, <Rt>, <Rt2>
  //
  // cccc11000100xxxxyyyy101100M1mmmm where cccc=Cond, xxxx=Rt, yyyy=Rt2, and
  // Mmmmm=Dm.
  constexpr const char *Vmovdrr = "vmovdrr";
  IValueT Dm = encodeDRegister(OpDm, "Dm", Vmovdrr);
  IValueT Rt = encodeGPRegister(OpRt, "Rt", Vmovdrr);
  IValueT Rt2 = encodeGPRegister(OpRt2, "Rt", Vmovdrr);
  assert(Rt != RegARM32::Encoded_Reg_sp);
  assert(Rt != RegARM32::Encoded_Reg_pc);
  assert(Rt2 != RegARM32::Encoded_Reg_sp);
  assert(Rt2 != RegARM32::Encoded_Reg_pc);
  assert(Rt != Rt2);
  assert(CondARM32::isDefined(Cond));
  IValueT Encoding = B27 | B26 | B22 | B11 | B9 | B8 | B4 |
                     (encodeCondition(Cond) << kConditionShift) | (Rt2 << 16) |
                     (Rt << 12) | (getYInRegYXXXX(Dm) << 5) |
                     getXXXXInRegYXXXX(Dm);
  emitInst(Encoding);
}

void AssemblerARM32::vmovqir(const Operand *OpQn, uint32_t Index,
                             const Operand *OpRt, CondARM32::Cond Cond) {
  // VMOV (ARM core register to scalar) - ARM section A8.8.341, encoding A1:
  //   vmov<c>.<size> <Dn[x]>, <Rt>
  constexpr const char *Vmovdr = "vmovdr";
  constexpr bool IsExtract = true;
  emitInsertExtractInt(Cond, OpQn, Index, OpRt, !IsExtract, Vmovdr);
}

void AssemblerARM32::vmovqis(const Operand *OpQd, uint32_t Index,
                             const Operand *OpSm, CondARM32::Cond Cond) {
  constexpr const char *Vmovqis = "vmovqis";
  assert(Index < 4);
  IValueT Sd = mapQRegToSReg(encodeQRegister(OpQd, "Qd", Vmovqis)) + Index;
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vmovqis);
  emitMoveSS(Cond, Sd, Sm);
}

void AssemblerARM32::vmovrqi(const Operand *OpRt, const Operand *OpQn,
                             uint32_t Index, CondARM32::Cond Cond) {
  // VMOV (scalar to ARM core register) - ARM section A8.8.342, encoding A1:
  //   vmov<c>.<dt> <Rt>, <Dn[x]>
  constexpr const char *Vmovrd = "vmovrd";
  constexpr bool IsExtract = true;
  emitInsertExtractInt(Cond, OpQn, Index, OpRt, IsExtract, Vmovrd);
}

void AssemblerARM32::vmovrrd(const Operand *OpRt, const Operand *OpRt2,
                             const Operand *OpDm, CondARM32::Cond Cond) {
  // VMOV (between two ARM core registers and a doubleword extension register).
  // ARM section A8.8.345, encoding A1:
  //   vmov<c> <Rt>, <Rt2>, <Dm>
  //
  // cccc11000101xxxxyyyy101100M1mmmm where cccc=Cond, xxxx=Rt, yyyy=Rt2, and
  // Mmmmm=Dm.
  constexpr const char *Vmovrrd = "vmovrrd";
  IValueT Rt = encodeGPRegister(OpRt, "Rt", Vmovrrd);
  IValueT Rt2 = encodeGPRegister(OpRt2, "Rt", Vmovrrd);
  IValueT Dm = encodeDRegister(OpDm, "Dm", Vmovrrd);
  assert(Rt != RegARM32::Encoded_Reg_sp);
  assert(Rt != RegARM32::Encoded_Reg_pc);
  assert(Rt2 != RegARM32::Encoded_Reg_sp);
  assert(Rt2 != RegARM32::Encoded_Reg_pc);
  assert(Rt != Rt2);
  assert(CondARM32::isDefined(Cond));
  IValueT Encoding = B27 | B26 | B22 | B20 | B11 | B9 | B8 | B4 |
                     (encodeCondition(Cond) << kConditionShift) | (Rt2 << 16) |
                     (Rt << 12) | (getYInRegYXXXX(Dm) << 5) |
                     getXXXXInRegYXXXX(Dm);
  emitInst(Encoding);
}

void AssemblerARM32::vmovrs(const Operand *OpRt, const Operand *OpSn,
                            CondARM32::Cond Cond) {
  // VMOV (between ARM core register and single-precision register)
  //   ARM section A8.8.343, encoding A1.
  //
  //   vmov<c> <Rt>, <Sn>
  //
  // cccc11100001nnnntttt1010N0010000 where cccc=Cond, nnnnN = Sn, and tttt=Rt.
  constexpr const char *Vmovrs = "vmovrs";
  IValueT Rt = encodeGPRegister(OpRt, "Rt", Vmovrs);
  IValueT Sn = encodeSRegister(OpSn, "Sn", Vmovrs);
  assert(CondARM32::isDefined(Cond));
  IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | B26 |
                     B25 | B20 | B11 | B9 | B4 | (getXXXXInRegXXXXY(Sn) << 16) |
                     (Rt << kRdShift) | (getYInRegXXXXY(Sn) << 7);
  emitInst(Encoding);
}

void AssemblerARM32::vmovs(const Operand *OpSd,
                           const OperandARM32FlexFpImm *OpFpImm,
                           CondARM32::Cond Cond) {
  // VMOV (immediate) - ARM section A8.8.339, encoding A2:
  //   vmov<c>.f32 <Sd>, #<imm>
  //
  // cccc11101D11xxxxdddd10100000yyyy where cccc=Cond, ddddD=Sn, xxxxyyyy=imm.
  constexpr const char *Vmovs = "vmovs";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vmovs);
  IValueT Imm8 = OpFpImm->getModifiedImm();
  assert(Imm8 < (1 << 8));
  constexpr IValueT VmovsOpcode = B23 | B21 | B20;
  IValueT OpcodePlusImm8 = VmovsOpcode | ((Imm8 >> 4) << 16) | (Imm8 & 0xf);
  constexpr IValueT S0 = 0;
  emitVFPsss(Cond, OpcodePlusImm8, Sd, S0, S0);
}

void AssemblerARM32::vmovss(const Operand *OpSd, const Variable *OpSm,
                            CondARM32::Cond Cond) {
  constexpr const char *Vmovss = "Vmovss";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vmovss);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vmovss);
  emitMoveSS(Cond, Sd, Sm);
}

void AssemblerARM32::vmovsqi(const Operand *OpSd, const Operand *OpQm,
                             uint32_t Index, CondARM32::Cond Cond) {
  constexpr const char *Vmovsqi = "vmovsqi";
  const IValueT Sd = encodeSRegister(OpSd, "Sd", Vmovsqi);
  assert(Index < 4);
  const IValueT Sm =
      mapQRegToSReg(encodeQRegister(OpQm, "Qm", Vmovsqi)) + Index;
  emitMoveSS(Cond, Sd, Sm);
}

void AssemblerARM32::vmovsr(const Operand *OpSn, const Operand *OpRt,
                            CondARM32::Cond Cond) {
  // VMOV (between ARM core register and single-precision register)
  //   ARM section A8.8.343, encoding A1.
  //
  //   vmov<c> <Sn>, <Rt>
  //
  // cccc11100000nnnntttt1010N0010000 where cccc=Cond, nnnnN = Sn, and tttt=Rt.
  constexpr const char *Vmovsr = "vmovsr";
  IValueT Sn = encodeSRegister(OpSn, "Sn", Vmovsr);
  IValueT Rt = encodeGPRegister(OpRt, "Rt", Vmovsr);
  assert(Sn < RegARM32::getNumSRegs());
  assert(Rt < RegARM32::getNumGPRegs());
  assert(CondARM32::isDefined(Cond));
  IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | B26 |
                     B25 | B11 | B9 | B4 | (getXXXXInRegXXXXY(Sn) << 16) |
                     (Rt << kRdShift) | (getYInRegXXXXY(Sn) << 7);
  emitInst(Encoding);
}

void AssemblerARM32::vmlad(const Operand *OpDd, const Operand *OpDn,
                           const Operand *OpDm, CondARM32::Cond Cond) {
  // VMLA, VMLS (floating-point), ARM section A8.8.337, encoding A2:
  //   vmla<c>.f64 <Dd>, <Dn>, <Dm>
  //
  // cccc11100d00nnnndddd1011n0M0mmmm where cccc=Cond, Ddddd=Dd, Nnnnn=Dn, and
  // Mmmmm=Dm
  constexpr const char *Vmlad = "vmlad";
  constexpr IValueT VmladOpcode = 0;
  emitVFPddd(Cond, VmladOpcode, OpDd, OpDn, OpDm, Vmlad);
}

void AssemblerARM32::vmlas(const Operand *OpSd, const Operand *OpSn,
                           const Operand *OpSm, CondARM32::Cond Cond) {
  // VMLA, VMLS (floating-point), ARM section A8.8.337, encoding A2:
  //   vmla<c>.f32 <Sd>, <Sn>, <Sm>
  //
  // cccc11100d00nnnndddd1010n0M0mmmm where cccc=Cond, ddddD=Sd, nnnnN=Sn, and
  // mmmmM=Sm
  constexpr const char *Vmlas = "vmlas";
  constexpr IValueT VmlasOpcode = 0;
  emitVFPsss(Cond, VmlasOpcode, OpSd, OpSn, OpSm, Vmlas);
}

void AssemblerARM32::vmlsd(const Operand *OpDd, const Operand *OpDn,
                           const Operand *OpDm, CondARM32::Cond Cond) {
  // VMLA, VMLS (floating-point), ARM section A8.8.337, encoding A2:
  //   vmls<c>.f64 <Dd>, <Dn>, <Dm>
  //
  // cccc11100d00nnnndddd1011n1M0mmmm where cccc=Cond, Ddddd=Dd, Nnnnn=Dn, and
  // Mmmmm=Dm
  constexpr const char *Vmlad = "vmlad";
  constexpr IValueT VmladOpcode = B6;
  emitVFPddd(Cond, VmladOpcode, OpDd, OpDn, OpDm, Vmlad);
}

void AssemblerARM32::vmlss(const Operand *OpSd, const Operand *OpSn,
                           const Operand *OpSm, CondARM32::Cond Cond) {
  // VMLA, VMLS (floating-point), ARM section A8.8.337, encoding A2:
  //   vmls<c>.f32 <Sd>, <Sn>, <Sm>
  //
  // cccc11100d00nnnndddd1010n1M0mmmm where cccc=Cond, ddddD=Sd, nnnnN=Sn, and
  // mmmmM=Sm
  constexpr const char *Vmlas = "vmlas";
  constexpr IValueT VmlasOpcode = B6;
  emitVFPsss(Cond, VmlasOpcode, OpSd, OpSn, OpSm, Vmlas);
}

void AssemblerARM32::vmrsAPSR_nzcv(CondARM32::Cond Cond) {
  // MVRS - ARM section A*.8.348, encoding A1:
  //   vmrs<c> APSR_nzcv, FPSCR
  //
  // cccc111011110001tttt101000010000 where tttt=0x15 (i.e. when Rt=pc, use
  // APSR_nzcv instead).
  assert(CondARM32::isDefined(Cond));
  IValueT Encoding = B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | B15 | B14 |
                     B13 | B12 | B11 | B9 | B4 |
                     (encodeCondition(Cond) << kConditionShift);
  emitInst(Encoding);
}

void AssemblerARM32::vmuls(const Operand *OpSd, const Operand *OpSn,
                           const Operand *OpSm, CondARM32::Cond Cond) {
  // VMUL (floating-point) - ARM section A8.8.351, encoding A2:
  //   vmul<c>.f32 <Sd>, <Sn>, <Sm>
  //
  // cccc11100D10nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
  // and mmmmM=Rm.
  constexpr const char *Vmuls = "vmuls";
  constexpr IValueT VmulsOpcode = B21;
  emitVFPsss(Cond, VmulsOpcode, OpSd, OpSn, OpSm, Vmuls);
}

void AssemblerARM32::vmuld(const Operand *OpDd, const Operand *OpDn,
                           const Operand *OpDm, CondARM32::Cond Cond) {
  // VMUL (floating-point) - ARM section A8.8.351, encoding A2:
  //   vmul<c>.f64 <Dd>, <Dn>, <Dm>
  //
  // cccc11100D10nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
  // and Mmmmm=Rm.
  constexpr const char *Vmuld = "vmuld";
  constexpr IValueT VmuldOpcode = B21;
  emitVFPddd(Cond, VmuldOpcode, OpDd, OpDn, OpDm, Vmuld);
}

void AssemblerARM32::vmulqi(Type ElmtTy, const Operand *OpQd,
                            const Operand *OpQn, const Operand *OpQm) {
  // VMUL, VMULL (integer and polynomial) - ARM section A8.8.350, encoding A1:
  //   vmul<c>.<dt> <Qd>, <Qn>, <Qm>
  //
  // 111100100Dssnnn0ddd01001NqM1mmm0 where Dddd=Qd, Nnnn=Qn, Mmmm=Qm, and
  // dt in [i8, i16, i32] where ss is the index.
  assert(isScalarIntegerType(ElmtTy) &&
         "vmulqi expects vector with integer element type");
  assert(ElmtTy != IceType_i64 && "vmulqi on i64 vector not allowed");
  constexpr const char *Vmulqi = "vmulqi";
  constexpr IValueT VmulqiOpcode = B11 | B8 | B4;
  emitSIMDqqq(VmulqiOpcode, ElmtTy, OpQd, OpQn, OpQm, Vmulqi);
}

void AssemblerARM32::vmulqf(const Operand *OpQd, const Operand *OpQn,
                            const Operand *OpQm) {
  // VMUL (floating-point) - ARM section A8.8.351, encoding A1:
  //   vmul.f32 <Qd>, <Qn>, <Qm>
  //
  // 111100110D00nnn0ddd01101MqM1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
  assert(OpQd->getType() == IceType_v4f32 && "vmulqf expects type <4 x float>");
  constexpr const char *Vmulqf = "vmulqf";
  constexpr IValueT VmulqfOpcode = B24 | B11 | B8 | B4;
  constexpr bool IsFloatTy = true;
  emitSIMDqqqBase(VmulqfOpcode, OpQd, OpQn, OpQm, IsFloatTy, Vmulqf);
}

void AssemblerARM32::vorrq(const Operand *OpQd, const Operand *OpQm,
                           const Operand *OpQn) {
  // VORR (register) - ARM section A8.8.360, encoding A1:
  //   vorr <Qd>, <Qn>, <Qm>
  //
  // 111100100D10nnn0ddd00001N1M1mmm0 where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
  constexpr const char *Vorrq = "vorrq";
  constexpr IValueT VorrqOpcode = B21 | B8 | B4;
  constexpr Type ElmtTy = IceType_i8;
  emitSIMDqqq(VorrqOpcode, ElmtTy, OpQd, OpQm, OpQn, Vorrq);
}

void AssemblerARM32::vstrd(const Operand *OpDd, const Operand *OpAddress,
                           CondARM32::Cond Cond, const TargetInfo &TInfo) {
  // VSTR - ARM section A8.8.413, encoding A1:
  //   vstr<c> <Dd>, [<Rn>{, #+/-<Imm>}]
  //
  // cccc1101UD00nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
  // iiiiiiii=abs(Imm >> 2), and U=1 if Imm>=0.
  constexpr const char *Vstrd = "vstrd";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Vstrd);
  assert(CondARM32::isDefined(Cond));
  IValueT Address;
  IValueT AddressEncoding =
      encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
  (void)AddressEncoding;
  assert(AddressEncoding == EncodedAsImmRegOffset);
  IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 |
                     (encodeCondition(Cond) << kConditionShift) |
                     (getYInRegYXXXX(Dd) << 22) |
                     (getXXXXInRegYXXXX(Dd) << 12) | Address;
  emitInst(Encoding);
}

void AssemblerARM32::vstrs(const Operand *OpSd, const Operand *OpAddress,
                           CondARM32::Cond Cond, const TargetInfo &TInfo) {
  // VSTR - ARM section A8.8.413, encoding A2:
  //   vstr<c> <Sd>, [<Rn>{, #+/-<imm>]]
  //
  // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd,
  // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0;
  constexpr const char *Vstrs = "vstrs";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vstrs);
  assert(CondARM32::isDefined(Cond));
  IValueT Address;
  IValueT AddressEncoding =
      encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address);
  (void)AddressEncoding;
  assert(AddressEncoding == EncodedAsImmRegOffset);
  IValueT Encoding =
      B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) |
      (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address;
  emitInst(Encoding);
}

void AssemblerARM32::vst1qr(size_t ElmtSize, const Operand *OpQd,
                            const Operand *OpAddress, const TargetInfo &TInfo) {
  // VST1 (multiple single elements) - ARM section A8.8.404, encoding A1:
  //   vst1.<size> <Qd>, [<Rn>]
  //
  // 111101000D00nnnnddd0ttttssaammmm where tttt=DRegListSize2, Dddd=Qd,
  // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the
  // encoding of ElmtSize.
  constexpr const char *Vst1qr = "vst1qr";
  const IValueT Qd = encodeQRegister(OpQd, "Qd", Vst1qr);
  const IValueT Dd = mapQRegToDReg(Qd);
  IValueT Address;
  if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) !=
      EncodedAsImmRegOffset)
    llvm::report_fatal_error(std::string(Vst1qr) + ": malform memory address");
  const IValueT Rn = mask(Address, kRnShift, 4);
  constexpr IValueT Rm = RegARM32::Reg_pc;
  constexpr IValueT Opcode = B26;
  constexpr IValueT Align = 0; // use default alignment.
  emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vst1qr);
}

void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn,
                           const Operand *OpSm, CondARM32::Cond Cond) {
  // VSUB (floating-point) - ARM section A8.8.415, encoding A2:
  //   vsub<c>.f32 <Sd>, <Sn>, <Sm>
  //
  // cccc11100D11nnnndddd101sN1M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
  // and mmmmM=Rm.
  constexpr const char *Vsubs = "vsubs";
  constexpr IValueT VsubsOpcode = B21 | B20 | B6;
  emitVFPsss(Cond, VsubsOpcode, OpSd, OpSn, OpSm, Vsubs);
}

void AssemblerARM32::vsubd(const Operand *OpDd, const Operand *OpDn,
                           const Operand *OpDm, CondARM32::Cond Cond) {
  // VSUB (floating-point) - ARM section A8.8.415, encoding A2:
  //   vsub<c>.f64 <Dd>, <Dn>, <Dm>
  //
  // cccc11100D11nnnndddd101sN1M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
  // and Mmmmm=Rm.
  constexpr const char *Vsubd = "vsubd";
  constexpr IValueT VsubdOpcode = B21 | B20 | B6;
  emitVFPddd(Cond, VsubdOpcode, OpDd, OpDn, OpDm, Vsubd);
}

void AssemblerARM32::vsubqi(Type ElmtTy, const Operand *OpQd,
                            const Operand *OpQm, const Operand *OpQn) {
  // VSUB (integer) - ARM section A8.8.414, encoding A1:
  //   vsub.<dt> <Qd>, <Qn>, <Qm>
  //
  // 111100110Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
  // and dt in [i8, i16, i32, i64] where ss is the index.
  assert(isScalarIntegerType(ElmtTy) &&
         "vsubqi expects vector with integer element type");
  constexpr const char *Vsubqi = "vsubqi";
  constexpr IValueT VsubqiOpcode = B24 | B11;
  emitSIMDqqq(VsubqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vsubqi);
}

void AssemblerARM32::vsubqf(const Operand *OpQd, const Operand *OpQn,
                            const Operand *OpQm) {
  // VSUB (floating-point) - ARM section A8.8.415, Encoding A1:
  //   vsub.f32 <Qd>, <Qn>, <Qm>
  //
  // 111100100D10nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
  assert(OpQd->getType() == IceType_v4f32 && "vsubqf expects type <4 x float>");
  constexpr const char *Vsubqf = "vsubqf";
  constexpr IValueT VsubqfOpcode = B21 | B11 | B8;
  emitSIMDqqq(VsubqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vsubqf);
}

void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
                                  const Variable *OpBaseReg,
                                  SizeT NumConsecRegs) {
  const IValueT BaseReg = getEncodedSRegNum(OpBaseReg);
  const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register.
  const IValueT Rd = mask(BaseReg, 1, 4);       // Top 4 bits of base register.
  assert(0 < NumConsecRegs);
  (void)VpushVpopMaxConsecRegs;
  assert(NumConsecRegs <= VpushVpopMaxConsecRegs);
  assert((BaseReg + NumConsecRegs) <= RegARM32::getNumSRegs());
  assert(CondARM32::isDefined(Cond));
  const IValueT Encoding = Opcode | (Cond << kConditionShift) | DLastBit |
                           (Rd << kRdShift) | NumConsecRegs;
  emitInst(Encoding);
}

void AssemblerARM32::vpop(const Variable *OpBaseReg, SizeT NumConsecRegs,
                          CondARM32::Cond Cond) {
  // Note: Current implementation assumes that OpBaseReg is defined using S
  // registers. It doesn't implement the D register form.
  //
  // VPOP - ARM section A8.8.367, encoding A2:
  //  vpop<c> <RegList>
  //
  // cccc11001D111101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
  // iiiiiiii=NumConsecRegs.
  constexpr IValueT VpopOpcode =
      B27 | B26 | B23 | B21 | B20 | B19 | B18 | B16 | B11 | B9;
  emitVStackOp(Cond, VpopOpcode, OpBaseReg, NumConsecRegs);
}

void AssemblerARM32::vpush(const Variable *OpBaseReg, SizeT NumConsecRegs,
                           CondARM32::Cond Cond) {
  // Note: Current implementation assumes that OpBaseReg is defined using S
  // registers. It doesn't implement the D register form.
  //
  // VPUSH - ARM section A8.8.368, encoding A2:
  //   vpush<c> <RegList>
  //
  // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
  // iiiiiiii=NumConsecRegs.
  constexpr IValueT VpushOpcode =
      B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9;
  emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs);
}

void AssemblerARM32::vsqrtd(const Operand *OpDd, const Operand *OpDm,
                            CondARM32::Cond Cond) {
  // VSQRT - ARM section A8.8.401, encoding A1:
  //   vsqrt<c>.f64 <Dd>, <Dm>
  //
  // cccc11101D110001dddd101111M0mmmm where cccc=Cond, Ddddd=Sd, and Mmmmm=Sm.
  constexpr const char *Vsqrtd = "vsqrtd";
  IValueT Dd = encodeDRegister(OpDd, "Dd", Vsqrtd);
  IValueT Dm = encodeDRegister(OpDm, "Dm", Vsqrtd);
  constexpr IValueT VsqrtdOpcode = B23 | B21 | B20 | B16 | B7 | B6;
  constexpr IValueT D0 = 0;
  emitVFPddd(Cond, VsqrtdOpcode, Dd, D0, Dm);
}

void AssemblerARM32::vsqrts(const Operand *OpSd, const Operand *OpSm,
                            CondARM32::Cond Cond) {
  // VSQRT - ARM section A8.8.401, encoding A1:
  //   vsqrt<c>.f32 <Sd>, <Sm>
  //
  // cccc11101D110001dddd101011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
  constexpr const char *Vsqrts = "vsqrts";
  IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts);
  IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts);
  constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6;
  constexpr IValueT S0 = 0;
  emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm);
}

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