//===-- 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 override {
      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) override;

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

    void emitInstruction(const MachineInstr &MI);

  private:

    void emitWordLE(unsigned Binary);
    void emitDWordLE(uint64_t Binary);
    void emitConstPoolInstruction(const MachineInstr &MI);
    void emitMOVi32immInstruction(const MachineInstr &MI);
    void emitMOVi2piecesInstruction(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 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 NEONThumb2V8PostEncoder(const MachineInstr &MI,unsigned Val)
      const { return 0; }
    unsigned VFPThumb2PostEncoder(const MachineInstr&MI, unsigned Val)
      const { return 0; }
    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 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 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; }
    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 {
      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 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 {
      // {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();

      // 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;
      }

      uint32_t Binary = Imm12 & 0xfff;
      if (isAdd)
        Binary |= (1 << 12);
      Binary |= (Reg << 13);
      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.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;

  // 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::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 {
    const Constant *CV = MCPE.Val.ConstVal;

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

    if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
      emitGlobalAddress(GV, ARM::reloc_arm_absolute, isa<Function>(GV), false);
      emitWordLE(0);
    } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
      uint32_t Val = uint32_t(*CI->getValue().getRawData());
      emitWordLE(Val);
    } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
      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!");
      }
    } else {
      llvm_unreachable("Unable to handle this constantpool entry!");
    }
  }
}

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::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::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::CFI_INSTRUCTION:
    break;
  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::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::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);

  // 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(v);
      int32_t msb = (32 - countLeadingZeros(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) {
    emitWordLE(Binary);
    return;
  }

  // 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);

  // 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);

  // 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               << ARMII::RegRdShift;
  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               << ARMII::RegRnShift;
  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;
  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;
  assert((Binary & ARMII::D_BitShift) == 0 &&
         (Binary & ARMII::N_BitShift) == 0 &&
         (Binary & ARMII::M_BitShift) == 0 && "VFP encoding bug!");

  // 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;

  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);
}

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"
