OSDN Git Service

Merge with LLVM upstream 2011/10/20 (r142530)
[android-x86/external-llvm.git] / lib / Target / ARM / ARMCodeEmitter.cpp
index d6fca62..d74ccfa 100644 (file)
 
 #define DEBUG_TYPE "jit"
 #include "ARM.h"
-#include "ARMAddressingModes.h"
 #include "ARMConstantPoolValue.h"
 #include "ARMInstrInfo.h"
 #include "ARMRelocations.h"
 #include "ARMSubtarget.h"
 #include "ARMTargetMachine.h"
+#include "MCTargetDesc/ARMAddressingModes.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
@@ -88,9 +88,11 @@ namespace {
 
     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);
@@ -139,6 +141,8 @@ namespace {
 
     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);
@@ -161,14 +165,20 @@ namespace {
     //  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) 
+    unsigned NEONThumb2DataIPostEncoder(const MachineInstr &MI, unsigned Val)
       const { return 0; }
-    unsigned NEONThumb2LoadStorePostEncoder(const MachineInstr &MI,unsigned Val) 
+    unsigned NEONThumb2LoadStorePostEncoder(const MachineInstr &MI,unsigned Val)
       const { return 0; }
-    unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val) 
+    unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val)
       const { return 0; }
     unsigned VFPThumb2PostEncoder(const MachineInstr&MI, unsigned Val)
-      const { return 0; }
+      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)
@@ -189,13 +199,17 @@ namespace {
       unsigned Op) const { return 0; }
     unsigned getARMBranchTargetOpValue(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 getSORegOpValue(const MachineInstr &MI, unsigned Op)
+    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; }
@@ -203,8 +217,12 @@ namespace {
       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)
@@ -213,10 +231,6 @@ namespace {
       const { return 0; }
     unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op)
       const { return 0; }
-    unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op)
-      const { return 0; }
-    unsigned getImmMinusOneOpValue(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)
@@ -230,8 +244,6 @@ namespace {
       const { return 0; }
     unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI,
                                             unsigned Op) const { return 0; }
-    unsigned getMsbOpValue(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)
@@ -260,14 +272,28 @@ namespace {
       return Binary;
     }
 
-    unsigned getHiLo16ImmOpValue(const MachineInstr &MI, unsigned Op) const {
-      return 0;
+    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)
@@ -281,34 +307,27 @@ namespace {
     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
+      // {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;
+      uint32_t Reg = getMachineOpValue(MI, MO);
+      Binary |= (Reg << 9);
+
+      // If there is a non-zero immediate offset, encode it.
+      if (MO.isReg()) {
+          const MachineOperand &MO1 = MI.getOperand(Op + 1);
+        if (uint32_t ImmOffs = ARM_AM::getAM5Offset(MO1.getImm())) {
+          if (ARM_AM::getAM5Op(MO1.getImm()) == ARM_AM::add)
+            Binary |= 1 << 8;
+          Binary |= ImmOffs & 0xff;
+          return Binary;
+        }
       }
-      unsigned Reg = getARMRegisterNumbering(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);
+      // If immediate offset is omitted, default to +0.
+      Binary |= 1 << 8;
       return Binary;
     }
     unsigned getNEONVcvtImm32OpValue(const MachineInstr &MI, unsigned Op)
@@ -438,6 +457,9 @@ unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
     return getARMRegisterNumbering(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())
@@ -592,7 +614,9 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
   case ARMII::VFPLdStMulFrm:
     emitVFPLoadStoreMultipleInstruction(MI);
     break;
-
+  case ARMII::VFPMiscFrm:
+    emitMiscInstruction(MI);
+    break;
   // NEON instructions.
   case ARMII::NGetLnFrm:
   case ARMII::NSetLnFrm:
@@ -614,6 +638,61 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
   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;
+  }
+  case Value::ConstantVectorVal:{
+    //FIXME:emit vector
+    const ConstantVector *CV = static_cast<const ConstantVector*>(C);
+    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.
@@ -632,47 +711,20 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
           << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n');
 
     assert(ACPV->isGlobalValue() && "unsupported constant pool value");
-    const GlobalValue *GV = ACPV->getGV();
+    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  {
-      emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
+    } 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!");
-    }
+    emitConstantToMemory(CPI, MCPE.Val.ConstVal);
   }
 }
 
@@ -754,6 +806,32 @@ void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
   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 |= getARMRegisterNumbering(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)
 
@@ -831,6 +909,14 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
   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:
   case ARM::BXr9_CALL:
@@ -863,6 +949,9 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
   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());
@@ -898,7 +987,10 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
     else
       emitMOVi2piecesInstruction(MI);
     break;
-
+  case ARM::LEApcrel:
+    // Materialize constantpool index address.
+    emitLEApcrelInstruction(MI);
+    break;
   case ARM::LEApcrelJT:
     // Materialize jumptable address.
     emitLEApcrelJTInstruction(MI);
@@ -983,7 +1075,7 @@ unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) {
 
 unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
                                          const MCInstrDesc &MCID) const {
-  for (unsigned i = MI.getNumOperands(), e = MCID.getNumOperands(); i >= e; --i){
+  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;
@@ -999,6 +1091,11 @@ void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI,
   // 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;
 
@@ -1101,11 +1198,17 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &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::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;
 
@@ -1261,6 +1364,11 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
   // 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;
 
@@ -1468,6 +1576,10 @@ void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
   // 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;
 
@@ -1541,9 +1653,10 @@ static unsigned encodeVFPRd(const MachineInstr &MI, unsigned OpIdx) {
   unsigned Binary = 0;
   bool isSPVFP = ARM::SPRRegisterClass->contains(RegD);
   RegD = getARMRegisterNumbering(RegD);
-  if (!isSPVFP)
-    Binary |=   RegD               << ARMII::RegRdShift;
-  else {
+  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;
   }
@@ -1555,9 +1668,10 @@ static unsigned encodeVFPRn(const MachineInstr &MI, unsigned OpIdx) {
   unsigned Binary = 0;
   bool isSPVFP = ARM::SPRRegisterClass->contains(RegN);
   RegN = getARMRegisterNumbering(RegN);
-  if (!isSPVFP)
-    Binary |=   RegN               << ARMII::RegRnShift;
-  else {
+  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;
   }
@@ -1569,9 +1683,10 @@ static unsigned encodeVFPRm(const MachineInstr &MI, unsigned OpIdx) {
   unsigned Binary = 0;
   bool isSPVFP = ARM::SPRRegisterClass->contains(RegM);
   RegM = getARMRegisterNumbering(RegM);
-  if (!isSPVFP)
-    Binary |=   RegM;
-  else {
+  if (!isSPVFP) {
+    Binary |=  (RegM & 0x0F);
+    Binary |= ((RegM & 0x10) >> 4) << ARMII::M_BitShift;
+  } else {
     Binary |= ((RegM & 0x1E) >> 1);
     Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
   }
@@ -1588,9 +1703,6 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
   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++);
@@ -1680,6 +1792,12 @@ void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &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.
@@ -1755,6 +1873,26 @@ ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI) {
   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);
+}
+
 static unsigned encodeNEONRd(const MachineInstr &MI, unsigned OpIdx) {
   unsigned RegD = MI.getOperand(OpIdx).getReg();
   unsigned Binary = 0;