//===-- ARM/ARMCodeEmitter.cpp - Convert ARM code to machine code ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the pass that transforms the ARM machine instructions into
// relocatable machine code.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "jit"
#include "ARM.h"
#include "ARMBaseInstrInfo.h"
#include "ARMConstantPoolValue.h"
#include "ARMRelocations.h"
#include "ARMSubtarget.h"
#include "ARMTargetMachine.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/PassManager.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#ifndef NDEBUG
#include <iomanip>
#endif
using namespace llvm;

STATISTIC(NumEmitted, "Number of machine instructions emitted");

namespace {

  class ARMCodeEmitter : public MachineFunctionPass {
    ARMJITInfo                *JTI;
    const ARMBaseInstrInfo    *II;
    const DataLayout          *TD;
    const ARMSubtarget        *Subtarget;
    TargetMachine             &TM;
    JITCodeEmitter            &MCE;
    MachineModuleInfo *MMI;
    const std::vector<MachineConstantPoolEntry> *MCPEs;
    const std::vector<MachineJumpTableEntry> *MJTEs;
    bool IsPIC;
    bool IsThumb;

    void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<MachineModuleInfo>();
      MachineFunctionPass::getAnalysisUsage(AU);
    }

    static char ID;
  public:
    ARMCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
      : MachineFunctionPass(ID), JTI(0),
        II((const ARMBaseInstrInfo *)tm.getInstrInfo()),
        TD(tm.getDataLayout()), TM(tm),
        MCE(mce), MCPEs(0), MJTEs(0),
        IsPIC(TM.getRelocationModel() == Reloc::PIC_), IsThumb(false) {}

    /// getBinaryCodeForInstr - This function, generated by the
    /// CodeEmitterGenerator using TableGen, produces the binary encoding for
    /// machine instructions.
    uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;

    bool runOnMachineFunction(MachineFunction &MF);

    virtual const char *getPassName() const {
      return "ARM Machine Code Emitter";
    }

    void emitInstruction(const MachineInstr &MI);

  private:

    void emitWordLE(unsigned Binary);
    void emitDWordLE(uint64_t Binary);
    void emitConstantToMemory(unsigned CPI, const Constant *CV);
    void emitConstPoolInstruction(const MachineInstr &MI);
    void emitMOVi32immInstruction(const MachineInstr &MI);
    void emitMOVi2piecesInstruction(const MachineInstr &MI);
    void emitLEApcrelInstruction(const MachineInstr &MI);
    void emitLEApcrelJTInstruction(const MachineInstr &MI);
    void emitPseudoMoveInstruction(const MachineInstr &MI);
    void addPCLabel(unsigned LabelID);
    void emitPseudoInstruction(const MachineInstr &MI);
    unsigned getMachineSoRegOpValue(const MachineInstr &MI,
                                    const MCInstrDesc &MCID,
                                    const MachineOperand &MO,
                                    unsigned OpIdx);

    unsigned getMachineSoImmOpValue(unsigned SoImm);
    unsigned getAddrModeSBit(const MachineInstr &MI,
                             const MCInstrDesc &MCID) const;

    void emitDataProcessingInstruction(const MachineInstr &MI,
                                       unsigned ImplicitRd = 0,
                                       unsigned ImplicitRn = 0);

    void emitLoadStoreInstruction(const MachineInstr &MI,
                                  unsigned ImplicitRd = 0,
                                  unsigned ImplicitRn = 0);

    void emitMiscLoadStoreInstruction(const MachineInstr &MI,
                                      unsigned ImplicitRn = 0);

    void emitLoadStoreMultipleInstruction(const MachineInstr &MI);

    void emitMulFrmInstruction(const MachineInstr &MI);

    void emitExtendInstruction(const MachineInstr &MI);

    void emitMiscArithInstruction(const MachineInstr &MI);

    void emitSaturateInstruction(const MachineInstr &MI);

    void emitBranchInstruction(const MachineInstr &MI);

    void emitInlineJumpTable(unsigned JTIndex);

    void emitMiscBranchInstruction(const MachineInstr &MI);

    void emitVFPArithInstruction(const MachineInstr &MI);

    void emitVFPConversionInstruction(const MachineInstr &MI);

    void emitVFPLoadStoreInstruction(const MachineInstr &MI);

    void emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI);

    void emitMiscInstruction(const MachineInstr &MI);

    void emitNEONLaneInstruction(const MachineInstr &MI);
    void emitNEONDupInstruction(const MachineInstr &MI);
    void emitNEON1RegModImmInstruction(const MachineInstr &MI);
    void emitNEON2RegInstruction(const MachineInstr &MI);
    void emitNEON3RegInstruction(const MachineInstr &MI);

    /// getMachineOpValue - Return binary encoding of operand. If the machine
    /// operand requires relocation, record the relocation and return zero.
    unsigned getMachineOpValue(const MachineInstr &MI,
                               const MachineOperand &MO) const;
    unsigned getMachineOpValue(const MachineInstr &MI, unsigned OpIdx) const {
      return getMachineOpValue(MI, MI.getOperand(OpIdx));
    }

    // FIXME: The legacy JIT ARMCodeEmitter doesn't rely on the the
    //  TableGen'erated getBinaryCodeForInstr() function to encode any
    //  operand values, instead querying getMachineOpValue() directly for
    //  each operand it needs to encode. Thus, any of the new encoder
    //  helper functions can simply return 0 as the values the return
    //  are already handled elsewhere. They are placeholders to allow this
    //  encoder to continue to function until the MC encoder is sufficiently
    //  far along that this one can be eliminated entirely.
    unsigned NEONThumb2DataIPostEncoder(const MachineInstr &MI, unsigned Val)
      const { return 0; }
    unsigned NEONThumb2LoadStorePostEncoder(const MachineInstr &MI,unsigned Val)
      const { return 0; }
    unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val)
      const { return 0; }
    unsigned VFPThumb2PostEncoder(const MachineInstr&MI, unsigned Val)
      const {
      if (IsThumb) {
        Val &= 0x0FFFFFFF;
        Val |= 0xE0000000;
      }
      return Val;
    }
    unsigned getAdrLabelOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getThumbAdrLabelOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getThumbBLTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getThumbBLXTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getThumbBRTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getThumbBCCTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getThumbCBTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getUnconditionalBranchTargetOpValue(const MachineInstr &MI,
      unsigned Op) const { return 0; }
    unsigned getARMBranchTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getARMBLTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getARMBLXTargetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getCCOutOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2SOImmOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getSORegRegOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getSORegImmOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getThumbAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2AddrModeImm12OpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2AddrModeImm8OpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2Imm8s4OpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2AddrModeImm8s4OpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2AddrModeImm0_1020s4OpValue(const MachineInstr &MI,unsigned Op)
      const { return 0; }
    unsigned getT2AddrModeImm8OffsetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2AddrModeImm12OffsetOpValue(const MachineInstr &MI,unsigned Op)
      const { return 0; }
    unsigned getT2AddrModeSORegOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getAddrMode6OneLane32AddressOpValue(const MachineInstr &MI,
                                                 unsigned Op)
      const { return 0; }
    unsigned getAddrMode6DupAddressOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getAddrMode6OffsetOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI,
                                            unsigned Op) const { return 0; }
    unsigned getSsatBitPosValue(const MachineInstr &MI,
                                unsigned Op) const { return 0; }
    uint32_t getLdStmModeOpValue(const MachineInstr &MI, unsigned OpIdx)
      const {return 0; }
    uint32_t getLdStSORegOpValue(const MachineInstr &MI, unsigned OpIdx)
      const { return 0; }

    unsigned getAddrModeImm12OpValue(const MachineInstr &MI, unsigned Op)
      const {
      // {17-13} = reg
      // {12}    = (U)nsigned (add == '1', sub == '0')
      // {11-0}  = imm12
      const MachineOperand &MO  = MI.getOperand(Op);
      const MachineOperand &MO1 = MI.getOperand(Op + 1);
      if (!MO.isReg()) {
        emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
        return 0;
      }
      unsigned Reg = II->getRegisterInfo().getEncodingValue(MO.getReg());
      int32_t Imm12 = MO1.getImm();
      uint32_t Binary;
      Binary = Imm12 & 0xfff;
      if (Imm12 >= 0)
        Binary |= (1 << 12);
      Binary |= (Reg << 13);
      return Binary;
    }

    unsigned getHiLo16ImmOpValue(const MachineInstr &MI, unsigned Op)
      const {
      const MCInstrDesc &MCID = MI.getDesc();
      const MachineOperand &MO = MI.getOperand(Op);

      unsigned Reloc = (MCID.Opcode == ARM::MOVi16 ?
                       ARM::reloc_arm_movw : ARM::reloc_arm_movt);

      if (!MO.isImm()) {
        emitGlobalAddress(MO.getGlobal(), Reloc, true, false);
        return 0;
      }
      unsigned Imm16 = static_cast<unsigned>(MO.getImm());
      return Imm16;
    }

    uint32_t getAddrMode2OpValue(const MachineInstr &MI, unsigned OpIdx)
      const { return 0;}
    uint32_t getAddrMode2OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
      const { return 0;}
    uint32_t getPostIdxRegOpValue(const MachineInstr &MI, unsigned OpIdx)
      const { return 0;}
    uint32_t getAddrMode3OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
      const { return 0;}
    uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    uint32_t getAddrModeThumbSPOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    uint32_t getAddrModeSOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    uint32_t getAddrModeISOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    uint32_t getAddrModePCOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const {
      // {12-9}  = reg
      // {8}     = (U)nsigned (add == '1', sub == '0')
      // {7-0}   = imm8
      uint32_t Binary = 0;
      const MachineOperand &MO  = MI.getOperand(Op);
      const MachineOperand &MO1 = MI.getOperand(Op + 1);
      if (!MO.isReg()) {
        emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
        return 0;
      }
      unsigned Reg = II->getRegisterInfo().getEncodingValue(MO.getReg());
      int32_t Imm12 = MO1.getImm();

      // Special value for #-0
      if (Imm12 == INT32_MIN)
        Imm12 = 0;

      // Immediate is always encoded as positive. The 'U' bit controls add vs
      // sub.
      bool isAdd = true;
      if (Imm12 < 0) {
        Imm12 = -Imm12;
        isAdd = false;
      }

      // If immediate offset is omitted, default to +0.
      Binary |= 1 << 8;
      return Binary;
    }
    unsigned getNEONVcvtImm32OpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }

    unsigned getRegisterListOpValue(const MachineInstr &MI, unsigned Op)
      const { return 0; }

    unsigned getShiftRight8Imm(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getShiftRight16Imm(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getShiftRight32Imm(const MachineInstr &MI, unsigned Op)
      const { return 0; }
    unsigned getShiftRight64Imm(const MachineInstr &MI, unsigned Op)
      const { return 0; }

    /// getMovi32Value - Return binary encoding of operand for movw/movt. If the
    /// machine operand requires relocation, record the relocation and return
    /// zero.
    unsigned getMovi32Value(const MachineInstr &MI,const MachineOperand &MO,
                            unsigned Reloc);

    /// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
    ///
    unsigned getShiftOp(unsigned Imm) const ;

    /// Routines that handle operands which add machine relocations which are
    /// fixed up by the relocation stage.
    void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
                           bool MayNeedFarStub,  bool Indirect,
                           intptr_t ACPV = 0) const;
    void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
    void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
    void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
    void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
                               intptr_t JTBase = 0) const;
    unsigned encodeVFPRd(const MachineInstr &MI, unsigned OpIdx) const;
    unsigned encodeVFPRn(const MachineInstr &MI, unsigned OpIdx) const;
    unsigned encodeVFPRm(const MachineInstr &MI, unsigned OpIdx) const;
    unsigned encodeNEONRd(const MachineInstr &MI, unsigned OpIdx) const;
    unsigned encodeNEONRn(const MachineInstr &MI, unsigned OpIdx) const;
    unsigned encodeNEONRm(const MachineInstr &MI, unsigned OpIdx) const;
  };
}

char ARMCodeEmitter::ID = 0;

/// createARMJITCodeEmitterPass - Return a pass that emits the collected ARM
/// code to the specified MCE object.
FunctionPass *llvm::createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
                                                JITCodeEmitter &JCE) {
  return new ARMCodeEmitter(TM, JCE);
}

bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
  TargetMachine &Target = const_cast<TargetMachine&>(MF.getTarget());

  assert((Target.getRelocationModel() != Reloc::Default ||
          Target.getRelocationModel() != Reloc::Static) &&
         "JIT relocation model must be set to static or default!");

  JTI = static_cast<ARMJITInfo*>(Target.getJITInfo());
  II = static_cast<const ARMBaseInstrInfo*>(Target.getInstrInfo());
  TD = Target.getDataLayout();

  Subtarget = &TM.getSubtarget<ARMSubtarget>();
  MCPEs = &MF.getConstantPool()->getConstants();
  MJTEs = 0;
  if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
  IsPIC = TM.getRelocationModel() == Reloc::PIC_;
  IsThumb = MF.getInfo<ARMFunctionInfo>()->isThumbFunction();
  JTI->Initialize(MF, IsPIC);
  MMI = &getAnalysis<MachineModuleInfo>();
  MCE.setModuleInfo(MMI);

  do {
    DEBUG(errs() << "JITTing function '"
          << MF.getName() << "'\n");
    MCE.startFunction(MF);
    for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
         MBB != E; ++MBB) {
      MCE.StartMachineBasicBlock(MBB);
      for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
           I != E; ++I)
        emitInstruction(*I);
    }
  } while (MCE.finishFunction(MF));

  return false;
}

/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
///
unsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const {
  switch (ARM_AM::getAM2ShiftOpc(Imm)) {
  default: llvm_unreachable("Unknown shift opc!");
  case ARM_AM::asr: return 2;
  case ARM_AM::lsl: return 0;
  case ARM_AM::lsr: return 1;
  case ARM_AM::ror:
  case ARM_AM::rrx: return 3;
  }
}

/// getMovi32Value - Return binary encoding of operand for movw/movt. If the
/// machine operand requires relocation, record the relocation and return zero.
unsigned ARMCodeEmitter::getMovi32Value(const MachineInstr &MI,
                                        const MachineOperand &MO,
                                        unsigned Reloc) {
  assert(((Reloc == ARM::reloc_arm_movt) || (Reloc == ARM::reloc_arm_movw))
      && "Relocation to this function should be for movt or movw");

  if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());
  else if (MO.isGlobal())
    emitGlobalAddress(MO.getGlobal(), Reloc, true, false);
  else if (MO.isSymbol())
    emitExternalSymbolAddress(MO.getSymbolName(), Reloc);
  else if (MO.isMBB())
    emitMachineBasicBlock(MO.getMBB(), Reloc);
  else {
#ifndef NDEBUG
    errs() << MO;
#endif
    llvm_unreachable("Unsupported operand type for movw/movt");
  }
  return 0;
}

/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                           const MachineOperand &MO) const {
  if (MO.isReg())
    return II->getRegisterInfo().getEncodingValue(MO.getReg());
  else if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());
  else if (MO.isFPImm())
    return static_cast<unsigned>(MO.getFPImm()->getValueAPF()
                      .bitcastToAPInt().getHiBits(32).getLimitedValue());
  else if (MO.isGlobal())
    emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true, false);
  else if (MO.isSymbol())
    emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_branch);
  else if (MO.isCPI()) {
    const MCInstrDesc &MCID = MI.getDesc();
    // For VFP load, the immediate offset is multiplied by 4.
    unsigned Reloc =  ((MCID.TSFlags & ARMII::FormMask) == ARMII::VFPLdStFrm)
      ? ARM::reloc_arm_vfp_cp_entry : ARM::reloc_arm_cp_entry;
    emitConstPoolAddress(MO.getIndex(), Reloc);
  } else if (MO.isJTI())
    emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative);
  else if (MO.isMBB())
    emitMachineBasicBlock(MO.getMBB(), ARM::reloc_arm_branch);
  else
    llvm_unreachable("Unable to encode MachineOperand!");
  return 0;
}

/// emitGlobalAddress - Emit the specified address to the code stream.
///
void ARMCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
                                       bool MayNeedFarStub, bool Indirect,
                                       intptr_t ACPV) const {
  MachineRelocation MR = Indirect
    ? MachineRelocation::getIndirectSymbol(MCE.getCurrentPCOffset(), Reloc,
                                           const_cast<GlobalValue *>(GV),
                                           ACPV, MayNeedFarStub)
    : MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
                               const_cast<GlobalValue *>(GV), ACPV,
                               MayNeedFarStub);
  MCE.addRelocation(MR);
}

/// emitExternalSymbolAddress - Arrange for the address of an external symbol to
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
void ARMCodeEmitter::
emitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
  MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
                                                 Reloc, ES));
}

/// emitConstPoolAddress - Arrange for the address of an constant pool
/// to be emitted to the current location in the function, and allow it to be PC
/// relative.
void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
  // Tell JIT emitter we'll resolve the address.
  MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
                                                    Reloc, CPI, 0, true));
}

/// emitJumpTableAddress - Arrange for the address of a jump table to
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
void ARMCodeEmitter::
emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
  MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
                                                    Reloc, JTIndex, 0, true));
}

/// emitMachineBasicBlock - Emit the specified address basic block.
void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
                                           unsigned Reloc,
                                           intptr_t JTBase) const {
  MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
                                             Reloc, BB, JTBase));
}

void ARMCodeEmitter::emitWordLE(unsigned Binary) {
  DEBUG(errs() << "  0x";
        errs().write_hex(Binary) << "\n");
  MCE.emitWordLE(Binary);
}

void ARMCodeEmitter::emitDWordLE(uint64_t Binary) {
  DEBUG(errs() << "  0x";
        errs().write_hex(Binary) << "\n");
  MCE.emitDWordLE(Binary);
}

void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);

  MCE.processDebugLoc(MI.getDebugLoc(), true);

  ++NumEmitted;  // Keep track of the # of mi's emitted
  switch (MI.getDesc().TSFlags & ARMII::FormMask) {
  default: {
    llvm_unreachable("Unhandled instruction encoding format!");
  }
  case ARMII::MiscFrm:
    if (MI.getOpcode() == ARM::LEApcrelJT) {
      // Materialize jumptable address.
      emitLEApcrelJTInstruction(MI);
      break;
    }
    llvm_unreachable("Unhandled instruction encoding!");
  case ARMII::Pseudo:
    emitPseudoInstruction(MI);
    break;
  case ARMII::DPFrm:
  case ARMII::DPSoRegFrm:
    emitDataProcessingInstruction(MI);
    break;
  case ARMII::LdFrm:
  case ARMII::StFrm:
    emitLoadStoreInstruction(MI);
    break;
  case ARMII::LdMiscFrm:
  case ARMII::StMiscFrm:
    emitMiscLoadStoreInstruction(MI);
    break;
  case ARMII::LdStMulFrm:
    emitLoadStoreMultipleInstruction(MI);
    break;
  case ARMII::MulFrm:
    emitMulFrmInstruction(MI);
    break;
  case ARMII::ExtFrm:
    emitExtendInstruction(MI);
    break;
  case ARMII::ArithMiscFrm:
    emitMiscArithInstruction(MI);
    break;
  case ARMII::SatFrm:
    emitSaturateInstruction(MI);
    break;
  case ARMII::BrFrm:
    emitBranchInstruction(MI);
    break;
  case ARMII::BrMiscFrm:
    emitMiscBranchInstruction(MI);
    break;
  // VFP instructions.
  case ARMII::VFPUnaryFrm:
  case ARMII::VFPBinaryFrm:
    emitVFPArithInstruction(MI);
    break;
  case ARMII::VFPConv1Frm:
  case ARMII::VFPConv2Frm:
  case ARMII::VFPConv3Frm:
  case ARMII::VFPConv4Frm:
  case ARMII::VFPConv5Frm:
    emitVFPConversionInstruction(MI);
    break;
  case ARMII::VFPLdStFrm:
    emitVFPLoadStoreInstruction(MI);
    break;
  case ARMII::VFPLdStMulFrm:
    emitVFPLoadStoreMultipleInstruction(MI);
    break;
  case ARMII::VFPMiscFrm:
    emitMiscInstruction(MI);
    break;
  // NEON instructions.
  case ARMII::NGetLnFrm:
  case ARMII::NSetLnFrm:
    emitNEONLaneInstruction(MI);
    break;
  case ARMII::NDupFrm:
    emitNEONDupInstruction(MI);
    break;
  case ARMII::N1RegModImmFrm:
    emitNEON1RegModImmInstruction(MI);
    break;
  case ARMII::N2RegFrm:
    emitNEON2RegInstruction(MI);
    break;
  case ARMII::N3RegFrm:
    emitNEON3RegInstruction(MI);
    break;
  }
  MCE.processDebugLoc(MI.getDebugLoc(), false);
}

void ARMCodeEmitter::emitConstantToMemory(unsigned CPI, const Constant *C) {
  DEBUG({
      errs() << "  ** Constant pool #" << CPI << " @ "
             << (void*)MCE.getCurrentPCValue() << " ";
      if (const Function *F = dyn_cast<Function>(C))
        errs() << F->getName();
      else
        errs() << *C;
      errs() << '\n';
    });

  switch (C->getValueID()) {
  default: {
    llvm_unreachable("Unable to handle this constantpool entry!");
    break;
  }
  case Value::GlobalVariableVal: {
    emitGlobalAddress(static_cast<const GlobalValue*>(C),
                      ARM::reloc_arm_absolute, isa<Function>(C), false);
    emitWordLE(0);
    break;
  }
  case Value::ConstantIntVal: {
    const ConstantInt *CI = static_cast<const ConstantInt*>(C);
    uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
    emitWordLE(Val);
    break;
  }
  case Value::ConstantFPVal: {
    const ConstantFP *CFP = static_cast<const ConstantFP*>(C);
    if (CFP->getType()->isFloatTy())
      emitWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
    else if (CFP->getType()->isDoubleTy())
      emitDWordLE(CFP->getValueAPF().bitcastToAPInt().getZExtValue());
    else {
      llvm_unreachable("Unable to handle this constantpool entry!");
    }
    break;
  }
  case Value::ConstantArrayVal: {
    const ConstantArray *CA = static_cast<const ConstantArray*>(C);
    for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
      emitConstantToMemory(CPI, CA->getOperand(i));
    break;
  }
  }

  return;
}

void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
  unsigned CPI = MI.getOperand(0).getImm();       // CP instruction index.
  unsigned CPIndex = MI.getOperand(1).getIndex(); // Actual cp entry index.
  const MachineConstantPoolEntry &MCPE = (*MCPEs)[CPIndex];

  // Remember the CONSTPOOL_ENTRY address for later relocation.
  JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue());

  // Emit constpool island entry. In most cases, the actual values will be
  // resolved and relocated after code emission.
  if (MCPE.isMachineConstantPoolEntry()) {
    ARMConstantPoolValue *ACPV =
      static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);

    DEBUG(errs() << "  ** ARM constant pool #" << CPI << " @ "
          << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n');

    assert(ACPV->isGlobalValue() && "unsupported constant pool value");
    const GlobalValue *GV = cast<ARMConstantPoolConstant>(ACPV)->getGV();
    if (GV) {
      Reloc::Model RelocM = TM.getRelocationModel();
      emitGlobalAddress(GV, ARM::reloc_arm_machine_cp_entry,
                        isa<Function>(GV),
                        Subtarget->GVIsIndirectSymbol(GV, RelocM),
                        (intptr_t)ACPV);
    } else  {
      const char *Sym = cast<ARMConstantPoolSymbol>(ACPV)->getSymbol();
      emitExternalSymbolAddress(Sym, ARM::reloc_arm_absolute);
    }
    emitWordLE(0);
  } else {
    emitConstantToMemory(CPI, MCPE.Val.ConstVal);
  }
}

void ARMCodeEmitter::emitMOVi32immInstruction(const MachineInstr &MI) {
  const MachineOperand &MO0 = MI.getOperand(0);
  const MachineOperand &MO1 = MI.getOperand(1);

  // Emit the 'movw' instruction.
  unsigned Binary = 0x30 << 20;  // mov: Insts{27-20} = 0b00110000

  unsigned Lo16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movw) & 0xFFFF;

  // Set the conditional execution predicate.
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode Rd.
  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;

  // Encode imm16 as imm4:imm12
  Binary |= Lo16 & 0xFFF; // Insts{11-0} = imm12
  Binary |= ((Lo16 >> 12) & 0xF) << 16; // Insts{19-16} = imm4
  emitWordLE(Binary);

  unsigned Hi16 = getMovi32Value(MI, MO1, ARM::reloc_arm_movt) >> 16;
  // Emit the 'movt' instruction.
  Binary = 0x34 << 20; // movt: Insts{27-20} = 0b00110100

  // Set the conditional execution predicate.
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode Rd.
  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;

  // Encode imm16 as imm4:imm1, same as movw above.
  Binary |= Hi16 & 0xFFF;
  Binary |= ((Hi16 >> 12) & 0xF) << 16;
  emitWordLE(Binary);
}

void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
  const MachineOperand &MO0 = MI.getOperand(0);
  const MachineOperand &MO1 = MI.getOperand(1);
  assert(MO1.isImm() && ARM_AM::isSOImmTwoPartVal(MO1.getImm()) &&
                                                  "Not a valid so_imm value!");
  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO1.getImm());
  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO1.getImm());

  // Emit the 'mov' instruction.
  unsigned Binary = 0xd << 21;  // mov: Insts{24-21} = 0b1101

  // Set the conditional execution predicate.
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode Rd.
  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;

  // Encode so_imm.
  // Set bit I(25) to identify this is the immediate form of <shifter_op>
  Binary |= 1 << ARMII::I_BitShift;
  Binary |= getMachineSoImmOpValue(V1);
  emitWordLE(Binary);

  // Now the 'orr' instruction.
  Binary = 0xc << 21;  // orr: Insts{24-21} = 0b1100

  // Set the conditional execution predicate.
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode Rd.
  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRdShift;

  // Encode Rn.
  Binary |= getMachineOpValue(MI, MO0) << ARMII::RegRnShift;

  // Encode so_imm.
  // Set bit I(25) to identify this is the immediate form of <shifter_op>
  Binary |= 1 << ARMII::I_BitShift;
  Binary |= getMachineSoImmOpValue(V2);
  emitWordLE(Binary);
}

void ARMCodeEmitter::emitLEApcrelInstruction(const MachineInstr &MI) {
  // It's basically add r, pc, (LCPI - $+8)
  const MCInstrDesc &MCID = MI.getDesc();

  unsigned Binary = 0;

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode S bit if MI modifies CPSR.
  Binary |= getAddrModeSBit(MI, MCID);

  // Encode Rd.
  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;

  // Encode Rn which is PC.
  Binary |= II->getRegisterInfo().getEncodingValue(ARM::PC) << ARMII::RegRnShift;

  // Encode the displacement which is a so_imm.
  // Set bit I(25) to identify this is the immediate form of <shifter_op>
  Binary |= 1 << ARMII::I_BitShift;
  emitConstPoolAddress(MI.getOperand(1).getIndex(), ARM::reloc_arm_so_imm_cp_entry);

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitLEApcrelJTInstruction(const MachineInstr &MI) {
  // It's basically add r, pc, (LJTI - $+8)

  const MCInstrDesc &MCID = MI.getDesc();

  // Emit the 'add' instruction.
  unsigned Binary = 0x4 << 21;  // add: Insts{24-21} = 0b0100

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode S bit if MI modifies CPSR.
  Binary |= getAddrModeSBit(MI, MCID);

  // Encode Rd.
  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;

  // Encode Rn which is PC.
  Binary |= II->getRegisterInfo().getEncodingValue(ARM::PC) << ARMII::RegRnShift;

  // Encode the displacement.
  Binary |= 1 << ARMII::I_BitShift;
  emitJumpTableAddress(MI.getOperand(1).getIndex(), ARM::reloc_arm_jt_base);

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitPseudoMoveInstruction(const MachineInstr &MI) {
  unsigned Opcode = MI.getDesc().Opcode;

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode S bit if MI modifies CPSR.
  if (Opcode == ARM::MOVsrl_flag || Opcode == ARM::MOVsra_flag)
    Binary |= 1 << ARMII::S_BitShift;

  // Encode register def if there is one.
  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;

  // Encode the shift operation.
  switch (Opcode) {
  default: break;
  case ARM::RRX:
    // rrx
    Binary |= 0x6 << 4;
    break;
  case ARM::MOVsrl_flag:
    // lsr #1
    Binary |= (0x2 << 4) | (1 << 7);
    break;
  case ARM::MOVsra_flag:
    // asr #1
    Binary |= (0x4 << 4) | (1 << 7);
    break;
  }

  // Encode register Rm.
  Binary |= getMachineOpValue(MI, 1);

  emitWordLE(Binary);
}

void ARMCodeEmitter::addPCLabel(unsigned LabelID) {
  DEBUG(errs() << "  ** LPC" << LabelID << " @ "
        << (void*)MCE.getCurrentPCValue() << '\n');
  JTI->addPCLabelAddr(LabelID, MCE.getCurrentPCValue());
}

void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
  unsigned Opcode = MI.getDesc().Opcode;
  switch (Opcode) {
  default:
    llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
  case ARM::B:
    emitBranchInstruction(MI);
    break;
  case ARM::BR_JTr:
  case ARM::BR_JTm:
  case ARM::BR_JTadd:
    emitMiscBranchInstruction(MI);
    break;
  case ARM::BX_CALL:
  case ARM::BMOVPCRX_CALL: {
    // First emit mov lr, pc
    unsigned Binary = 0x01a0e00f;
    Binary |= II->getPredicate(&MI) << ARMII::CondShift;
    emitWordLE(Binary);

    // and then emit the branch.
    emitMiscBranchInstruction(MI);
    break;
  }
  case TargetOpcode::INLINEASM: {
    // We allow inline assembler nodes with empty bodies - they can
    // implicitly define registers, which is ok for JIT.
    if (MI.getOperand(0).getSymbolName()[0]) {
      report_fatal_error("JIT does not support inline asm!");
    }
    break;
  }
  case TargetOpcode::PROLOG_LABEL:
  case TargetOpcode::EH_LABEL:
    MCE.emitLabel(MI.getOperand(0).getMCSymbol());
    break;
  case TargetOpcode::IMPLICIT_DEF:
  case TargetOpcode::KILL:
    // Do nothing.
    break;
  case ARM::CONSTPOOL_ENTRY:
    emitConstPoolInstruction(MI);
    break;
  case ARM::LDMIA_RET:
    emitLoadStoreMultipleInstruction(MI);
    break;
  case ARM::PICADD: {
    // Remember of the address of the PC label for relocation later.
    addPCLabel(MI.getOperand(2).getImm());
    // PICADD is just an add instruction that implicitly read pc.
    emitDataProcessingInstruction(MI, 0, ARM::PC);
    break;
  }
  case ARM::PICLDR:
  case ARM::PICLDRB:
  case ARM::PICSTR:
  case ARM::PICSTRB: {
    // Remember of the address of the PC label for relocation later.
    addPCLabel(MI.getOperand(2).getImm());
    // These are just load / store instructions that implicitly read pc.
    emitLoadStoreInstruction(MI, 0, ARM::PC);
    break;
  }
  case ARM::PICLDRH:
  case ARM::PICLDRSH:
  case ARM::PICLDRSB:
  case ARM::PICSTRH: {
    // Remember of the address of the PC label for relocation later.
    addPCLabel(MI.getOperand(2).getImm());
    // These are just load / store instructions that implicitly read pc.
    emitMiscLoadStoreInstruction(MI, ARM::PC);
    break;
  }

  case ARM::MOVi32imm:
    // Two instructions to materialize a constant.
    if (Subtarget->hasV6T2Ops())
      emitMOVi32immInstruction(MI);
    else
      emitMOVi2piecesInstruction(MI);
    break;
  case ARM::LEApcrel:
    // Materialize constantpool index address.
    emitLEApcrelInstruction(MI);
    break;
  case ARM::LEApcrelJT:
    // Materialize jumptable address.
    emitLEApcrelJTInstruction(MI);
    break;
  case ARM::RRX:
  case ARM::MOVsrl_flag:
  case ARM::MOVsra_flag:
    emitPseudoMoveInstruction(MI);
    break;
  }
}

unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI,
                                                const MCInstrDesc &MCID,
                                                const MachineOperand &MO,
                                                unsigned OpIdx) {
  unsigned Binary = getMachineOpValue(MI, MO);

  const MachineOperand &MO1 = MI.getOperand(OpIdx + 1);
  const MachineOperand &MO2 = MI.getOperand(OpIdx + 2);
  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());

  // Encode the shift opcode.
  unsigned SBits = 0;
  unsigned Rs = MO1.getReg();
  if (Rs) {
    // Set shift operand (bit[7:4]).
    // LSL - 0001
    // LSR - 0011
    // ASR - 0101
    // ROR - 0111
    // RRX - 0110 and bit[11:8] clear.
    switch (SOpc) {
    default: llvm_unreachable("Unknown shift opc!");
    case ARM_AM::lsl: SBits = 0x1; break;
    case ARM_AM::lsr: SBits = 0x3; break;
    case ARM_AM::asr: SBits = 0x5; break;
    case ARM_AM::ror: SBits = 0x7; break;
    case ARM_AM::rrx: SBits = 0x6; break;
    }
  } else {
    // Set shift operand (bit[6:4]).
    // LSL - 000
    // LSR - 010
    // ASR - 100
    // ROR - 110
    switch (SOpc) {
    default: llvm_unreachable("Unknown shift opc!");
    case ARM_AM::lsl: SBits = 0x0; break;
    case ARM_AM::lsr: SBits = 0x2; break;
    case ARM_AM::asr: SBits = 0x4; break;
    case ARM_AM::ror: SBits = 0x6; break;
    }
  }
  Binary |= SBits << 4;
  if (SOpc == ARM_AM::rrx)
    return Binary;

  // Encode the shift operation Rs or shift_imm (except rrx).
  if (Rs) {
    // Encode Rs bit[11:8].
    assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
    return Binary | (II->getRegisterInfo().getEncodingValue(Rs) << ARMII::RegRsShift);
  }

  // Encode shift_imm bit[11:7].
  return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
}

unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) {
  int SoImmVal = ARM_AM::getSOImmVal(SoImm);
  assert(SoImmVal != -1 && "Not a valid so_imm value!");

  // Encode rotate_imm.
  unsigned Binary = (ARM_AM::getSOImmValRot((unsigned)SoImmVal) >> 1)
    << ARMII::SoRotImmShift;

  // Encode immed_8.
  Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
  return Binary;
}

unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
                                         const MCInstrDesc &MCID) const {
  for (unsigned i = MI.getNumOperands(), e = MCID.getNumOperands(); i >= e;--i){
    const MachineOperand &MO = MI.getOperand(i-1);
    if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR)
      return 1 << ARMII::S_BitShift;
  }
  return 0;
}

void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI,
                                                   unsigned ImplicitRd,
                                                   unsigned ImplicitRn) {
  const MCInstrDesc &MCID = MI.getDesc();

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  if (MCID.Opcode == ARM::MOVi16 || MCID.Opcode == ARM::MOVTi16) {
      emitWordLE(Binary);
      return;
  }

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode S bit if MI modifies CPSR.
  Binary |= getAddrModeSBit(MI, MCID);

  // Encode register def if there is one.
  unsigned NumDefs = MCID.getNumDefs();
  unsigned OpIdx = 0;
  if (NumDefs)
    Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;
  else if (ImplicitRd)
    // Special handling for implicit use (e.g. PC).
    Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRd) << ARMII::RegRdShift);

  if (MCID.Opcode == ARM::MOVi16) {
      // Get immediate from MI.
      unsigned Lo16 = getMovi32Value(MI, MI.getOperand(OpIdx),
                      ARM::reloc_arm_movw);
      // Encode imm which is the same as in emitMOVi32immInstruction().
      Binary |= Lo16 & 0xFFF;
      Binary |= ((Lo16 >> 12) & 0xF) << 16;
      emitWordLE(Binary);
      return;
  } else if(MCID.Opcode == ARM::MOVTi16) {
      unsigned Hi16 = (getMovi32Value(MI, MI.getOperand(OpIdx),
                       ARM::reloc_arm_movt) >> 16);
      Binary |= Hi16 & 0xFFF;
      Binary |= ((Hi16 >> 12) & 0xF) << 16;
      emitWordLE(Binary);
      return;
  } else if ((MCID.Opcode == ARM::BFC) || (MCID.Opcode == ARM::BFI)) {
      uint32_t v = ~MI.getOperand(2).getImm();
      int32_t lsb = CountTrailingZeros_32(v);
      int32_t msb = (32 - CountLeadingZeros_32(v)) - 1;
      // Instr{20-16} = msb, Instr{11-7} = lsb
      Binary |= (msb & 0x1F) << 16;
      Binary |= (lsb & 0x1F) << 7;
      emitWordLE(Binary);
      return;
  } else if ((MCID.Opcode == ARM::UBFX) || (MCID.Opcode == ARM::SBFX)) {
      // Encode Rn in Instr{0-3}
      Binary |= getMachineOpValue(MI, OpIdx++);

      uint32_t lsb = MI.getOperand(OpIdx++).getImm();
      uint32_t widthm1 = MI.getOperand(OpIdx++).getImm() - 1;

      // Instr{20-16} = widthm1, Instr{11-7} = lsb
      Binary |= (widthm1 & 0x1F) << 16;
      Binary |= (lsb & 0x1F) << 7;
      emitWordLE(Binary);
      return;
  }

  // If this is a two-address operand, skip it. e.g. MOVCCr operand 1.
  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
    ++OpIdx;

  // Encode first non-shifter register operand if there is one.
  bool isUnary = MCID.TSFlags & ARMII::UnaryDP;
  if (!isUnary) {
    if (ImplicitRn)
      // Special handling for implicit use (e.g. PC).
      Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRn) << ARMII::RegRnShift);
    else {
      Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRnShift;
      ++OpIdx;
    }
  }

  // Encode shifter operand.
  const MachineOperand &MO = MI.getOperand(OpIdx);
  if ((MCID.TSFlags & ARMII::FormMask) == ARMII::DPSoRegFrm) {
    // Encode SoReg.
    emitWordLE(Binary | getMachineSoRegOpValue(MI, MCID, MO, OpIdx));
    return;
  }

  if (MO.isReg()) {
    // Encode register Rm.
    emitWordLE(Binary | II->getRegisterInfo().getEncodingValue(MO.getReg()));
    return;
  }

  // Encode so_imm.
  Binary |= getMachineSoImmOpValue((unsigned)MO.getImm());

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
                                              unsigned ImplicitRd,
                                              unsigned ImplicitRn) {
  const MCInstrDesc &MCID = MI.getDesc();
  unsigned Form = MCID.TSFlags & ARMII::FormMask;
  bool IsPrePost = (MCID.TSFlags & ARMII::IndexModeMask) != 0;

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // If this is an LDRi12, STRi12 or LDRcp, nothing more needs be done.
  if (MI.getOpcode() == ARM::LDRi12 || MI.getOpcode() == ARM::LDRcp ||
      MI.getOpcode() == ARM::STRi12 || MI.getOpcode() == ARM::LDRBi12 ||
      MI.getOpcode() == ARM::STRBi12) {
    emitWordLE(Binary);
    return;
  }

  if (MI.getOpcode() == ARM::BR_JTm)
    Binary = 0x710F000;
  else if (MI.getOpcode() == ARM::BR_JTr)
    Binary = 0x1A0F000;

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  unsigned OpIdx = 0;

  // Operand 0 of a pre- and post-indexed store is the address base
  // writeback. Skip it.
  bool Skipped = false;
  if (IsPrePost && Form == ARMII::StFrm) {
    ++OpIdx;
    Skipped = true;
  }

  // Set first operand
  if (ImplicitRd)
    // Special handling for implicit use (e.g. PC).
    Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRd) << ARMII::RegRdShift);
  else
    Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;

  // Set second operand
  if (ImplicitRn)
    // Special handling for implicit use (e.g. PC).
    Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRn) << ARMII::RegRnShift);
  else
    Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;

  // If this is a two-address operand, skip it. e.g. LDR_PRE.
  if (!Skipped && MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
    ++OpIdx;

  const MachineOperand &MO2 = MI.getOperand(OpIdx);
  unsigned AM2Opc = (ImplicitRn == ARM::PC)
    ? 0 : MI.getOperand(OpIdx+1).getImm();

  // Set bit U(23) according to sign of immed value (positive or negative).
  Binary |= ((ARM_AM::getAM2Op(AM2Opc) == ARM_AM::add ? 1 : 0) <<
             ARMII::U_BitShift);
  if (!MO2.getReg()) { // is immediate
    if (ARM_AM::getAM2Offset(AM2Opc))
      // Set the value of offset_12 field
      Binary |= ARM_AM::getAM2Offset(AM2Opc);
    emitWordLE(Binary);
    return;
  }

  // Set bit I(25), because this is not in immediate encoding.
  Binary |= 1 << ARMII::I_BitShift;
  assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
  // Set bit[3:0] to the corresponding Rm register
  Binary |= II->getRegisterInfo().getEncodingValue(MO2.getReg());

  // If this instr is in scaled register offset/index instruction, set
  // shift_immed(bit[11:7]) and shift(bit[6:5]) fields.
  if (unsigned ShImm = ARM_AM::getAM2Offset(AM2Opc)) {
    Binary |= getShiftOp(AM2Opc) << ARMII::ShiftImmShift;  // shift
    Binary |= ShImm              << ARMII::ShiftShift;     // shift_immed
  }

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
                                                  unsigned ImplicitRn) {
  const MCInstrDesc &MCID = MI.getDesc();
  unsigned Form = MCID.TSFlags & ARMII::FormMask;
  bool IsPrePost = (MCID.TSFlags & ARMII::IndexModeMask) != 0;

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  unsigned OpIdx = 0;

  // Operand 0 of a pre- and post-indexed store is the address base
  // writeback. Skip it.
  bool Skipped = false;
  if (IsPrePost && Form == ARMII::StMiscFrm) {
    ++OpIdx;
    Skipped = true;
  }

  // Set first operand
  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;

  // Skip LDRD and STRD's second operand.
  if (MCID.Opcode == ARM::LDRD || MCID.Opcode == ARM::STRD)
    ++OpIdx;

  // Set second operand
  if (ImplicitRn)
    // Special handling for implicit use (e.g. PC).
    Binary |= (II->getRegisterInfo().getEncodingValue(ImplicitRn) << ARMII::RegRnShift);
  else
    Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;

  // If this is a two-address operand, skip it. e.g. LDRH_POST.
  if (!Skipped && MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
    ++OpIdx;

  const MachineOperand &MO2 = MI.getOperand(OpIdx);
  unsigned AM3Opc = (ImplicitRn == ARM::PC)
    ? 0 : MI.getOperand(OpIdx+1).getImm();

  // Set bit U(23) according to sign of immed value (positive or negative)
  Binary |= ((ARM_AM::getAM3Op(AM3Opc) == ARM_AM::add ? 1 : 0) <<
             ARMII::U_BitShift);

  // If this instr is in register offset/index encoding, set bit[3:0]
  // to the corresponding Rm register.
  if (MO2.getReg()) {
    Binary |= II->getRegisterInfo().getEncodingValue(MO2.getReg());
    emitWordLE(Binary);
    return;
  }

  // This instr is in immediate offset/index encoding, set bit 22 to 1.
  Binary |= 1 << ARMII::AM3_I_BitShift;
  if (unsigned ImmOffs = ARM_AM::getAM3Offset(AM3Opc)) {
    // Set operands
    Binary |= (ImmOffs >> 4) << ARMII::ImmHiShift;  // immedH
    Binary |= (ImmOffs & 0xF);                      // immedL
  }

  emitWordLE(Binary);
}

static unsigned getAddrModeUPBits(unsigned Mode) {
  unsigned Binary = 0;

  // Set addressing mode by modifying bits U(23) and P(24)
  // IA - Increment after  - bit U = 1 and bit P = 0
  // IB - Increment before - bit U = 1 and bit P = 1
  // DA - Decrement after  - bit U = 0 and bit P = 0
  // DB - Decrement before - bit U = 0 and bit P = 1
  switch (Mode) {
  default: llvm_unreachable("Unknown addressing sub-mode!");
  case ARM_AM::da:                                     break;
  case ARM_AM::db: Binary |= 0x1 << ARMII::P_BitShift; break;
  case ARM_AM::ia: Binary |= 0x1 << ARMII::U_BitShift; break;
  case ARM_AM::ib: Binary |= 0x3 << ARMII::U_BitShift; break;
  }

  return Binary;
}

void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();
  bool IsUpdating = (MCID.TSFlags & ARMII::IndexModeMask) != 0;

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  if (MCID.getOpcode() == ARM::LDMIA_RET) {
    IsUpdating = true;
    Binary |= 0x8B00000;
  }

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Skip operand 0 of an instruction with base register update.
  unsigned OpIdx = 0;
  if (IsUpdating)
    ++OpIdx;

  // Set base address operand
  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;

  // Set addressing mode by modifying bits U(23) and P(24)
  ARM_AM::AMSubMode Mode = ARM_AM::getLoadStoreMultipleSubMode(MI.getOpcode());
  Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(Mode));

  // Set bit W(21)
  if (IsUpdating)
    Binary |= 0x1 << ARMII::W_BitShift;

  // Set registers
  for (unsigned i = OpIdx+2, e = MI.getNumOperands(); i != e; ++i) {
    const MachineOperand &MO = MI.getOperand(i);
    if (!MO.isReg() || MO.isImplicit())
      break;
    unsigned RegNum = II->getRegisterInfo().getEncodingValue(MO.getReg());
    assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
           RegNum < 16);
    Binary |= 0x1 << RegNum;
  }

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitMulFrmInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode S bit if MI modifies CPSR.
  Binary |= getAddrModeSBit(MI, MCID);

  // 32x32->64bit operations have two destination registers. The number
  // of register definitions will tell us if that's what we're dealing with.
  unsigned OpIdx = 0;
  if (MCID.getNumDefs() == 2)
    Binary |= getMachineOpValue (MI, OpIdx++) << ARMII::RegRdLoShift;

  // Encode Rd
  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdHiShift;

  // Encode Rm
  Binary |= getMachineOpValue(MI, OpIdx++);

  // Encode Rs
  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRsShift;

  // Many multiple instructions (e.g. MLA) have three src operands. Encode
  // it as Rn (for multiply, that's in the same offset as RdLo.
  if (MCID.getNumOperands() > OpIdx &&
      !MCID.OpInfo[OpIdx].isPredicate() &&
      !MCID.OpInfo[OpIdx].isOptionalDef())
    Binary |= getMachineOpValue(MI, OpIdx) << ARMII::RegRdLoShift;

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitExtendInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  unsigned OpIdx = 0;

  // Encode Rd
  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;

  const MachineOperand &MO1 = MI.getOperand(OpIdx++);
  const MachineOperand &MO2 = MI.getOperand(OpIdx);
  if (MO2.isReg()) {
    // Two register operand form.
    // Encode Rn.
    Binary |= getMachineOpValue(MI, MO1) << ARMII::RegRnShift;

    // Encode Rm.
    Binary |= getMachineOpValue(MI, MO2);
    ++OpIdx;
  } else {
    Binary |= getMachineOpValue(MI, MO1);
  }

  // Encode rot imm (0, 8, 16, or 24) if it has a rotate immediate operand.
  if (MI.getOperand(OpIdx).isImm() &&
      !MCID.OpInfo[OpIdx].isPredicate() &&
      !MCID.OpInfo[OpIdx].isOptionalDef())
    Binary |= (getMachineOpValue(MI, OpIdx) / 8) << ARMII::ExtRotImmShift;

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitMiscArithInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // PKH instructions are finished at this point
  if (MCID.Opcode == ARM::PKHBT || MCID.Opcode == ARM::PKHTB) {
    emitWordLE(Binary);
    return;
  }

  unsigned OpIdx = 0;

  // Encode Rd
  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdShift;

  const MachineOperand &MO = MI.getOperand(OpIdx++);
  if (OpIdx == MCID.getNumOperands() ||
      MCID.OpInfo[OpIdx].isPredicate() ||
      MCID.OpInfo[OpIdx].isOptionalDef()) {
    // Encode Rm and it's done.
    Binary |= getMachineOpValue(MI, MO);
    emitWordLE(Binary);
    return;
  }

  // Encode Rn.
  Binary |= getMachineOpValue(MI, MO) << ARMII::RegRnShift;

  // Encode Rm.
  Binary |= getMachineOpValue(MI, OpIdx++);

  // Encode shift_imm.
  unsigned ShiftAmt = MI.getOperand(OpIdx).getImm();
  if (MCID.Opcode == ARM::PKHTB) {
    assert(ShiftAmt != 0 && "PKHTB shift_imm is 0!");
    if (ShiftAmt == 32)
      ShiftAmt = 0;
  }
  assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
  Binary |= ShiftAmt << ARMII::ShiftShift;

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitSaturateInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();

  // Part of binary is determined by TableGen.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Encode Rd
  Binary |= getMachineOpValue(MI, 0) << ARMII::RegRdShift;

  // Encode saturate bit position.
  unsigned Pos = MI.getOperand(1).getImm();
  if (MCID.Opcode == ARM::SSAT || MCID.Opcode == ARM::SSAT16)
    Pos -= 1;
  assert((Pos < 16 || (Pos < 32 &&
                       MCID.Opcode != ARM::SSAT16 &&
                       MCID.Opcode != ARM::USAT16)) &&
         "saturate bit position out of range");
  Binary |= Pos << 16;

  // Encode Rm
  Binary |= getMachineOpValue(MI, 2);

  // Encode shift_imm.
  if (MCID.getNumOperands() == 4) {
    unsigned ShiftOp = MI.getOperand(3).getImm();
    ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
    if (Opc == ARM_AM::asr)
      Binary |= (1 << 6);
    unsigned ShiftAmt = MI.getOperand(3).getImm();
    if (ShiftAmt == 32 && Opc == ARM_AM::asr)
      ShiftAmt = 0;
    assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
    Binary |= ShiftAmt << ARMII::ShiftShift;
  }

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();

  if (MCID.Opcode == ARM::TPsoft) {
    llvm_unreachable("ARM::TPsoft FIXME"); // FIXME
  }

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  if (MCID.Opcode == ARM::B) {
    Binary = 0xEA000000;
  }

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Set signed_immed_24 field
  Binary |= getMachineOpValue(MI, 0);

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex) {
  // Remember the base address of the inline jump table.
  uintptr_t JTBase = MCE.getCurrentPCValue();
  JTI->addJumpTableBaseAddr(JTIndex, JTBase);
  DEBUG(errs() << "  ** Jump Table #" << JTIndex << " @ " << (void*)JTBase
               << '\n');

  // Now emit the jump table entries.
  const std::vector<MachineBasicBlock*> &MBBs = (*MJTEs)[JTIndex].MBBs;
  for (unsigned i = 0, e = MBBs.size(); i != e; ++i) {
    if (IsPIC)
      // DestBB address - JT base.
      emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_pic_jt, JTBase);
    else
      // Absolute DestBB address.
      emitMachineBasicBlock(MBBs[i], ARM::reloc_arm_absolute);
    emitWordLE(0);
  }
}

void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();

  // Handle jump tables.
  if (MCID.Opcode == ARM::BR_JTr || MCID.Opcode == ARM::BR_JTadd) {
    // First emit a ldr pc, [] instruction.
    emitDataProcessingInstruction(MI, ARM::PC);

    // Then emit the inline jump table.
    unsigned JTIndex =
      (MCID.Opcode == ARM::BR_JTr)
      ? MI.getOperand(1).getIndex() : MI.getOperand(2).getIndex();
    emitInlineJumpTable(JTIndex);
    return;
  } else if (MCID.Opcode == ARM::BR_JTm) {
    // First emit a ldr pc, [] instruction.
    emitLoadStoreInstruction(MI, ARM::PC);

    // Then emit the inline jump table.
    emitInlineJumpTable(MI.getOperand(3).getIndex());
    return;
  }

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  if (MCID.Opcode == ARM::BX_RET || MCID.Opcode == ARM::MOVPCLR)
    // The return register is LR.
    Binary |= II->getRegisterInfo().getEncodingValue(ARM::LR);
  else
    // otherwise, set the return register
    Binary |= getMachineOpValue(MI, 0);

  emitWordLE(Binary);
}

unsigned ARMCodeEmitter::encodeVFPRd(const MachineInstr &MI,
                                     unsigned OpIdx) const {
  unsigned RegD = MI.getOperand(OpIdx).getReg();
  unsigned Binary = 0;
  bool isSPVFP = ARM::SPRRegClass.contains(RegD);
  RegD = II->getRegisterInfo().getEncodingValue(RegD);
  if (!isSPVFP) {
    Binary |=  (RegD & 0x0F)       << ARMII::RegRdShift;
    Binary |= ((RegD & 0x10) >> 4) << ARMII::D_BitShift;
  } else {
    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
  }
  return Binary;
}

unsigned ARMCodeEmitter::encodeVFPRn(const MachineInstr &MI,
                                     unsigned OpIdx) const {
  unsigned RegN = MI.getOperand(OpIdx).getReg();
  unsigned Binary = 0;
  bool isSPVFP = ARM::SPRRegClass.contains(RegN);
  RegN = II->getRegisterInfo().getEncodingValue(RegN);
  if (!isSPVFP) {
    Binary |=  (RegN & 0x0F)       << ARMII::RegRnShift;
    Binary |= ((RegN & 0x10) >> 4) << ARMII::N_BitShift;
  } else {
    Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
    Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
  }
  return Binary;
}

unsigned ARMCodeEmitter::encodeVFPRm(const MachineInstr &MI,
                                     unsigned OpIdx) const {
  unsigned RegM = MI.getOperand(OpIdx).getReg();
  unsigned Binary = 0;
  bool isSPVFP = ARM::SPRRegClass.contains(RegM);
  RegM = II->getRegisterInfo().getEncodingValue(RegM);
  if (!isSPVFP) {
    Binary |=  (RegM & 0x0F);
    Binary |= ((RegM & 0x10) >> 4) << ARMII::M_BitShift;
  } else {
    Binary |= ((RegM & 0x1E) >> 1);
    Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
  }
  return Binary;
}

void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  unsigned OpIdx = 0;

  // Encode Dd / Sd.
  Binary |= encodeVFPRd(MI, OpIdx++);

  // If this is a two-address operand, skip it, e.g. FMACD.
  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
    ++OpIdx;

  // Encode Dn / Sn.
  if ((MCID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm)
    Binary |= encodeVFPRn(MI, OpIdx++);

  if (OpIdx == MCID.getNumOperands() ||
      MCID.OpInfo[OpIdx].isPredicate() ||
      MCID.OpInfo[OpIdx].isOptionalDef()) {
    // FCMPEZD etc. has only one operand.
    emitWordLE(Binary);
    return;
  }

  // Encode Dm / Sm.
  Binary |= encodeVFPRm(MI, OpIdx);

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();
  unsigned Form = MCID.TSFlags & ARMII::FormMask;

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  switch (Form) {
  default: break;
  case ARMII::VFPConv1Frm:
  case ARMII::VFPConv2Frm:
  case ARMII::VFPConv3Frm:
    // Encode Dd / Sd.
    Binary |= encodeVFPRd(MI, 0);
    break;
  case ARMII::VFPConv4Frm:
    // Encode Dn / Sn.
    Binary |= encodeVFPRn(MI, 0);
    break;
  case ARMII::VFPConv5Frm:
    // Encode Dm / Sm.
    Binary |= encodeVFPRm(MI, 0);
    break;
  }

  switch (Form) {
  default: break;
  case ARMII::VFPConv1Frm:
    // Encode Dm / Sm.
    Binary |= encodeVFPRm(MI, 1);
    break;
  case ARMII::VFPConv2Frm:
  case ARMII::VFPConv3Frm:
    // Encode Dn / Sn.
    Binary |= encodeVFPRn(MI, 1);
    break;
  case ARMII::VFPConv4Frm:
  case ARMII::VFPConv5Frm:
    // Encode Dd / Sd.
    Binary |= encodeVFPRd(MI, 1);
    break;
  }

  if (Form == ARMII::VFPConv5Frm)
    // Encode Dn / Sn.
    Binary |= encodeVFPRn(MI, 2);
  else if (Form == ARMII::VFPConv3Frm)
    // Encode Dm / Sm.
    Binary |= encodeVFPRm(MI, 2);

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  if (MI.getOpcode() == ARM::VLDRS || MI.getOpcode() == ARM::VLDRD ||
      MI.getOpcode() == ARM::VSTRS || MI.getOpcode() == ARM::VSTRD){
    emitWordLE(Binary);
    return;
  }

  unsigned OpIdx = 0;

  // Encode Dd / Sd.
  Binary |= encodeVFPRd(MI, OpIdx++);

  // Encode address base.
  const MachineOperand &Base = MI.getOperand(OpIdx++);
  Binary |= getMachineOpValue(MI, Base) << ARMII::RegRnShift;

  // If there is a non-zero immediate offset, encode it.
  if (Base.isReg()) {
    const MachineOperand &Offset = MI.getOperand(OpIdx);
    if (unsigned ImmOffs = ARM_AM::getAM5Offset(Offset.getImm())) {
      if (ARM_AM::getAM5Op(Offset.getImm()) == ARM_AM::add)
        Binary |= 1 << ARMII::U_BitShift;
      Binary |= ImmOffs;
      emitWordLE(Binary);
      return;
    }
  }

  // If immediate offset is omitted, default to +0.
  Binary |= 1 << ARMII::U_BitShift;

  emitWordLE(Binary);
}

void
ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();
  bool IsUpdating = (MCID.TSFlags & ARMII::IndexModeMask) != 0;

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  // Skip operand 0 of an instruction with base register update.
  unsigned OpIdx = 0;
  if (IsUpdating)
    ++OpIdx;

  // Set base address operand
  Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;

  // Set addressing mode by modifying bits U(23) and P(24)
  ARM_AM::AMSubMode Mode = ARM_AM::getLoadStoreMultipleSubMode(MI.getOpcode());
  Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(Mode));

  // Set bit W(21)
  if (IsUpdating)
    Binary |= 0x1 << ARMII::W_BitShift;

  // First register is encoded in Dd.
  Binary |= encodeVFPRd(MI, OpIdx+2);

  // Count the number of registers.
  unsigned NumRegs = 1;
  for (unsigned i = OpIdx+3, e = MI.getNumOperands(); i != e; ++i) {
    const MachineOperand &MO = MI.getOperand(i);
    if (!MO.isReg() || MO.isImplicit())
      break;
    ++NumRegs;
  }
  // Bit 8 will be set if <list> is consecutive 64-bit registers (e.g., D0)
  // Otherwise, it will be 0, in the case of 32-bit registers.
  if(Binary & 0x100)
    Binary |= NumRegs * 2;
  else
    Binary |= NumRegs;

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
  unsigned Opcode = MI.getDesc().Opcode;
  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  if (Opcode == ARM::FCONSTS) {
    unsigned Imm = getMachineOpValue(MI, 1);
    Binary &= ~(0x780000 >> 19);
    Binary |= (Imm & 0x780000) >> 19;
    Binary &= ~(0x3800000 >> 7);
    Binary |= (Imm & 0x3800000) >> 7;
    Binary = VFPThumb2PostEncoder(MI, Binary);
  }

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;

  emitWordLE(Binary);
}

unsigned ARMCodeEmitter::encodeNEONRd(const MachineInstr &MI,
                                      unsigned OpIdx) const {
  unsigned RegD = MI.getOperand(OpIdx).getReg();
  unsigned Binary = 0;
  RegD = II->getRegisterInfo().getEncodingValue(RegD);
  Binary |= (RegD & 0xf) << ARMII::RegRdShift;
  Binary |= ((RegD >> 4) & 1) << ARMII::D_BitShift;
  return Binary;
}

unsigned ARMCodeEmitter::encodeNEONRn(const MachineInstr &MI,
                                      unsigned OpIdx) const {
  unsigned RegN = MI.getOperand(OpIdx).getReg();
  unsigned Binary = 0;
  RegN = II->getRegisterInfo().getEncodingValue(RegN);
  Binary |= (RegN & 0xf) << ARMII::RegRnShift;
  Binary |= ((RegN >> 4) & 1) << ARMII::N_BitShift;
  return Binary;
}

unsigned ARMCodeEmitter::encodeNEONRm(const MachineInstr &MI,
                                      unsigned OpIdx) const {
  unsigned RegM = MI.getOperand(OpIdx).getReg();
  unsigned Binary = 0;
  RegM = II->getRegisterInfo().getEncodingValue(RegM);
  Binary |= (RegM & 0xf);
  Binary |= ((RegM >> 4) & 1) << ARMII::M_BitShift;
  return Binary;
}

/// convertNEONDataProcToThumb - Convert the ARM mode encoding for a NEON
/// data-processing instruction to the corresponding Thumb encoding.
static unsigned convertNEONDataProcToThumb(unsigned Binary) {
  assert((Binary & 0xfe000000) == 0xf2000000 &&
         "not an ARM NEON data-processing instruction");
  unsigned UBit = (Binary >> 24) & 1;
  return 0xef000000 | (UBit << 28) | (Binary & 0xffffff);
}

void ARMCodeEmitter::emitNEONLaneInstruction(const MachineInstr &MI) {
  unsigned Binary = getBinaryCodeForInstr(MI);

  unsigned RegTOpIdx, RegNOpIdx, LnOpIdx;
  const MCInstrDesc &MCID = MI.getDesc();
  if ((MCID.TSFlags & ARMII::FormMask) == ARMII::NGetLnFrm) {
    RegTOpIdx = 0;
    RegNOpIdx = 1;
    LnOpIdx = 2;
  } else { // ARMII::NSetLnFrm
    RegTOpIdx = 2;
    RegNOpIdx = 0;
    LnOpIdx = 3;
  }

  // Set the conditional execution predicate
  Binary |= (IsThumb ? ARMCC::AL : II->getPredicate(&MI)) << ARMII::CondShift;

  unsigned RegT = MI.getOperand(RegTOpIdx).getReg();
  RegT = II->getRegisterInfo().getEncodingValue(RegT);
  Binary |= (RegT << ARMII::RegRdShift);
  Binary |= encodeNEONRn(MI, RegNOpIdx);

  unsigned LaneShift;
  if ((Binary & (1 << 22)) != 0)
    LaneShift = 0; // 8-bit elements
  else if ((Binary & (1 << 5)) != 0)
    LaneShift = 1; // 16-bit elements
  else
    LaneShift = 2; // 32-bit elements

  unsigned Lane = MI.getOperand(LnOpIdx).getImm() << LaneShift;
  unsigned Opc1 = Lane >> 2;
  unsigned Opc2 = Lane & 3;
  assert((Opc1 & 3) == 0 && "out-of-range lane number operand");
  Binary |= (Opc1 << 21);
  Binary |= (Opc2 << 5);

  emitWordLE(Binary);
}

void ARMCodeEmitter::emitNEONDupInstruction(const MachineInstr &MI) {
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= (IsThumb ? ARMCC::AL : II->getPredicate(&MI)) << ARMII::CondShift;

  unsigned RegT = MI.getOperand(1).getReg();
  RegT = II->getRegisterInfo().getEncodingValue(RegT);
  Binary |= (RegT << ARMII::RegRdShift);
  Binary |= encodeNEONRn(MI, 0);
  emitWordLE(Binary);
}

void ARMCodeEmitter::emitNEON1RegModImmInstruction(const MachineInstr &MI) {
  unsigned Binary = getBinaryCodeForInstr(MI);
  // Destination register is encoded in Dd.
  Binary |= encodeNEONRd(MI, 0);
  // Immediate fields: Op, Cmode, I, Imm3, Imm4
  unsigned Imm = MI.getOperand(1).getImm();
  unsigned Op = (Imm >> 12) & 1;
  unsigned Cmode = (Imm >> 8) & 0xf;
  unsigned I = (Imm >> 7) & 1;
  unsigned Imm3 = (Imm >> 4) & 0x7;
  unsigned Imm4 = Imm & 0xf;
  Binary |= (I << 24) | (Imm3 << 16) | (Cmode << 8) | (Op << 5) | Imm4;
  if (IsThumb)
    Binary = convertNEONDataProcToThumb(Binary);
  emitWordLE(Binary);
}

void ARMCodeEmitter::emitNEON2RegInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();
  unsigned Binary = getBinaryCodeForInstr(MI);
  // Destination register is encoded in Dd; source register in Dm.
  unsigned OpIdx = 0;
  Binary |= encodeNEONRd(MI, OpIdx++);
  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
    ++OpIdx;
  Binary |= encodeNEONRm(MI, OpIdx);
  if (IsThumb)
    Binary = convertNEONDataProcToThumb(Binary);
  // FIXME: This does not handle VDUPfdf or VDUPfqf.
  emitWordLE(Binary);
}

void ARMCodeEmitter::emitNEON3RegInstruction(const MachineInstr &MI) {
  const MCInstrDesc &MCID = MI.getDesc();
  unsigned Binary = getBinaryCodeForInstr(MI);
  // Destination register is encoded in Dd; source registers in Dn and Dm.
  unsigned OpIdx = 0;
  Binary |= encodeNEONRd(MI, OpIdx++);
  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
    ++OpIdx;
  Binary |= encodeNEONRn(MI, OpIdx++);
  if (MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
    ++OpIdx;
  Binary |= encodeNEONRm(MI, OpIdx);
  if (IsThumb)
    Binary = convertNEONDataProcToThumb(Binary);
  // FIXME: This does not handle VMOVDneon or VMOVQ.
  emitWordLE(Binary);
}

#include "ARMGenCodeEmitter.inc"
