Index: include/llvm/Target/TargetRegistry.h
===================================================================
--- include/llvm/Target/TargetRegistry.h	(revision 136769)
+++ include/llvm/Target/TargetRegistry.h	(working copy)
@@ -86,7 +86,9 @@
                                                   CodeModel::Model CM);
     typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
                                             MCStreamer &Streamer);
-    typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, StringRef TT);
+    typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, 
+                                                const MCSubtargetInfo &STI, 
+                                                StringRef TT);
     typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T,
                                                   const MCRegisterInfo &MRI,
                                                   const MCAsmInfo &MAI);
@@ -325,10 +327,11 @@
     ///
     /// \arg Triple - The target triple string.
     /// \arg Backend - The target independent assembler object.
-    MCAsmBackend *createMCAsmBackend(StringRef Triple) const {
+    MCAsmBackend *createMCAsmBackend(const MCSubtargetInfo &STI,
+                                     StringRef Triple) const {
       if (!MCAsmBackendCtorFn)
         return 0;
-      return MCAsmBackendCtorFn(*this, Triple);
+      return MCAsmBackendCtorFn(*this, STI, Triple);
     }
 
     /// createMCAsmLexer - Create a target specific assembly lexer.
Index: tools/llvm-mc/llvm-mc.cpp
===================================================================
--- tools/llvm-mc/llvm-mc.cpp	(revision 136769)
+++ tools/llvm-mc/llvm-mc.cpp	(working copy)
@@ -392,7 +392,7 @@
     MCAsmBackend *MAB = 0;
     if (ShowEncoding) {
       CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
-      MAB = TheTarget->createMCAsmBackend(TripleName);
+      MAB = TheTarget->createMCAsmBackend(*STI, TripleName);
     }
     Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
                                            /*useLoc*/ true,
@@ -403,7 +403,7 @@
   } else {
     assert(FileType == OFT_ObjectFile && "Invalid file type!");
     MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
-    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName);
+    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*STI, TripleName);
     Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
                                                 FOS, CE, RelaxAll,
                                                 NoExecStack));
Index: lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
===================================================================
--- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp	(revision 136769)
+++ lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp	(working copy)
@@ -425,7 +425,9 @@
 
 } // end anonymous namespace
 
-MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, StringRef TT) {
+MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
+                                           const MCSubtargetInfo &STI,
+                                           StringRef TT) {
   Triple TheTriple(TT);
 
   if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
@@ -437,7 +439,9 @@
   return new ELFX86_32AsmBackend(T, TheTriple.getOS());
 }
 
-MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringRef TT) {
+MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
+                                           const MCSubtargetInfo &STI,
+                                           StringRef TT) {
   Triple TheTriple(TT);
 
   if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
Index: lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
===================================================================
--- lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h	(revision 136769)
+++ lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h	(working copy)
@@ -74,8 +74,12 @@
                                       const MCSubtargetInfo &STI,
                                       MCContext &Ctx);
 
-MCAsmBackend *createX86_32AsmBackend(const Target &T, StringRef TT);
-MCAsmBackend *createX86_64AsmBackend(const Target &T, StringRef TT);
+MCAsmBackend *createX86_32AsmBackend(const Target &T, 
+                                     const MCSubtargetInfo &STI,
+                                     StringRef TT);
+MCAsmBackend *createX86_64AsmBackend(const Target &T, 
+                                     const MCSubtargetInfo &STI, 
+                                     StringRef TT);
 
 /// createX86MachObjectWriter - Construct an X86 Mach-O object writer.
 MCObjectWriter *createX86MachObjectWriter(raw_ostream &OS,
Index: lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp
===================================================================
--- lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp	(revision 136769)
+++ lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp	(working copy)
@@ -146,7 +146,9 @@
 }
 } // end anonymous namespace
 
-MCAsmBackend *llvm::createMBlazeAsmBackend(const Target &T, StringRef TT) {
+MCAsmBackend *llvm::createMBlazeAsmBackend(const Target &T, 
+                                           const MCSubtargetInfo &STI, 
+                                           StringRef TT) {
   Triple TheTriple(TT);
 
   if (TheTriple.isOSDarwin())
Index: lib/Target/MBlaze/MCTargetDesc/MBlazeMCTargetDesc.h
===================================================================
--- lib/Target/MBlaze/MCTargetDesc/MBlazeMCTargetDesc.h	(revision 136769)
+++ lib/Target/MBlaze/MCTargetDesc/MBlazeMCTargetDesc.h	(working copy)
@@ -30,7 +30,9 @@
                                          const MCSubtargetInfo &STI,
                                          MCContext &Ctx);
   
-MCAsmBackend *createMBlazeAsmBackend(const Target &T, StringRef TT);
+MCAsmBackend *createMBlazeAsmBackend(const Target &T,
+                                     const MCSubtargetInfo &STI,
+                                     StringRef TT);
 
 } // End llvm namespace
 
Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
===================================================================
--- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp	(revision 136769)
+++ lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp	(working copy)
@@ -20,6 +20,7 @@
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Object/MachOFormat.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -35,12 +36,18 @@
 };
 
 class ARMAsmBackend : public MCAsmBackend {
+  const MCSubtargetInfo &STI;
   bool isThumbMode;  // Currently emitting Thumb code.
 public:
-  ARMAsmBackend(const Target &T) : MCAsmBackend(), isThumbMode(false) {}
+  ARMAsmBackend(const Target &T, const MCSubtargetInfo &sti)
+    : MCAsmBackend(), STI(sti), isThumbMode(false) {}
 
   unsigned getNumFixupKinds() const { return ARM::NumTargetFixupKinds; }
 
+  bool hasNOP() const {
+    return (STI.getFeatureBits() & ARM::HasV6T2Ops) != 0;
+  }
+
   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
     const static MCFixupKindInfo Infos[ARM::NumTargetFixupKinds] = {
 // This table *must* be in the order that the fixup_* kinds are defined in
@@ -122,20 +129,28 @@
 }
 
 bool ARMAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
+  const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8
+  const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP
+  const uint32_t ARMv4_NopEncoding = 0xe1a0000; // using MOV r0,r0
+  const uint32_t ARMv6T2_NopEncoding = 0xe3207800; // NOP
   if (isThumb()) {
-    // FIXME: 0xbf00 is the ARMv7 value. For v6 and before, we'll need to
-    // use 0x46c0 (which is a 'mov r8, r8' insn).
+    const uint16_t nopEncoding = hasNOP() ? Thumb2_16bitNopEncoding 
+                                          : Thumb1_16bitNopEncoding;
     uint64_t NumNops = Count / 2;
     for (uint64_t i = 0; i != NumNops; ++i)
-      OW->Write16(0xbf00);
+      OW->Write16(nopEncoding);
     if (Count & 1)
       OW->Write8(0);
     return true;
   }
   // ARM mode
+  const uint32_t nopEncoding = hasNOP() ? ARMv6T2_NopEncoding
+                                        : ARMv4_NopEncoding;
   uint64_t NumNops = Count / 4;
   for (uint64_t i = 0; i != NumNops; ++i)
-    OW->Write32(0xe1a00000);
+    OW->Write32(nopEncoding);
+  // FIXME: should this function return false when unable to write exactly 
+  // 'Count' bytes with NOP encodings?
   switch (Count % 4) {
   default: break; // No leftover bytes to write
   case 1: OW->Write8(0); break;
@@ -381,8 +396,9 @@
 class ELFARMAsmBackend : public ARMAsmBackend {
 public:
   Triple::OSType OSType;
-  ELFARMAsmBackend(const Target &T, Triple::OSType _OSType)
-    : ARMAsmBackend(T), OSType(_OSType) { }
+  ELFARMAsmBackend(const Target &T, const MCSubtargetInfo &STI,
+                   Triple::OSType _OSType)
+    : ARMAsmBackend(T, STI), OSType(_OSType) { }
 
   void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
                   uint64_t Value) const;
@@ -413,8 +429,9 @@
 class DarwinARMAsmBackend : public ARMAsmBackend {
 public:
   const object::mach::CPUSubtypeARM Subtype;
-  DarwinARMAsmBackend(const Target &T, object::mach::CPUSubtypeARM st)
-    : ARMAsmBackend(T), Subtype(st) { }
+  DarwinARMAsmBackend(const Target &T, const MCSubtargetInfo &STI,
+                      object::mach::CPUSubtypeARM st)
+    : ARMAsmBackend(T, STI), Subtype(st) { }
 
   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
     return createARMMachObjectWriter(OS, /*Is64Bit=*/false,
@@ -491,24 +508,26 @@
 
 } // end anonymous namespace
 
-MCAsmBackend *llvm::createARMAsmBackend(const Target &T, StringRef TT) {
+MCAsmBackend *llvm::createARMAsmBackend(const Target &T,
+                                        const MCSubtargetInfo &STI,
+                                        StringRef TT) {
   Triple TheTriple(TT);
 
   if (TheTriple.isOSDarwin()) {
     if (TheTriple.getArchName() == "armv4t" ||
         TheTriple.getArchName() == "thumbv4t")
-      return new DarwinARMAsmBackend(T, object::mach::CSARM_V4T);
+      return new DarwinARMAsmBackend(T, STI, object::mach::CSARM_V4T);
     else if (TheTriple.getArchName() == "armv5e" ||
         TheTriple.getArchName() == "thumbv5e")
-      return new DarwinARMAsmBackend(T, object::mach::CSARM_V5TEJ);
+      return new DarwinARMAsmBackend(T, STI, object::mach::CSARM_V5TEJ);
     else if (TheTriple.getArchName() == "armv6" ||
         TheTriple.getArchName() == "thumbv6")
-      return new DarwinARMAsmBackend(T, object::mach::CSARM_V6);
-    return new DarwinARMAsmBackend(T, object::mach::CSARM_V7);
+      return new DarwinARMAsmBackend(T, STI, object::mach::CSARM_V6);
+    return new DarwinARMAsmBackend(T, STI, object::mach::CSARM_V7);
   }
 
   if (TheTriple.isOSWindows())
     assert(0 && "Windows not supported on ARM");
 
-  return new ELFARMAsmBackend(T, Triple(TT).getOS());
+  return new ELFARMAsmBackend(T, STI, Triple(TT).getOS());
 }
Index: lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
===================================================================
--- lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h	(revision 136769)
+++ lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h	(working copy)
@@ -44,7 +44,9 @@
                                       const MCSubtargetInfo &STI,
                                       MCContext &Ctx);
 
-MCAsmBackend *createARMAsmBackend(const Target &T, StringRef TT);
+MCAsmBackend *createARMAsmBackend(const Target &T,
+                                  const MCSubtargetInfo &sti,
+                                  StringRef TT);
 
 /// createARMMachObjectWriter - Construct an ARM Mach-O object writer.
 MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS,
Index: lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
===================================================================
--- lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp	(revision 136769)
+++ lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp	(working copy)
@@ -183,7 +183,9 @@
 
 
 
-MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, StringRef TT) {
+MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, 
+                                        const MCSubtargetInfo &sti, 
+                                        StringRef TT) {
   if (Triple(TT).isOSDarwin())
     return new DarwinPPCAsmBackend(T);
 
Index: lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
===================================================================
--- lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h	(revision 136769)
+++ lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h	(working copy)
@@ -30,7 +30,9 @@
                                       const MCSubtargetInfo &STI,
                                       MCContext &Ctx);
 
-MCAsmBackend *createPPCAsmBackend(const Target &T, StringRef TT);
+MCAsmBackend *createPPCAsmBackend(const Target &T, 
+                                  const MCSubtargetInfo &sti, 
+                                  StringRef TT);
   
 } // End llvm namespace
 
Index: lib/MC/MCAssembler.cpp
===================================================================
--- lib/MC/MCAssembler.cpp	(revision 136769)
+++ lib/MC/MCAssembler.cpp	(working copy)
@@ -412,6 +412,12 @@
     // bytes left to fill use the the Value and ValueSize to fill the rest.
     // If we are aligning with nops, ask that target to emit the right data.
     if (AF.hasEmitNops()) {
+    	// FIXME: this assumes that the NOP data to be written is independent
+    	// of the instructions/fragments before or after it.
+    	// I believe that to write NOP data, the ASM writer should be set in
+    	// the correct state, e.g. for ARM compilation, in Thumb state so as
+    	// to produce Thumb NOP's when the NOP data is in the middle of a
+    	// Thumb function.
       if (!Asm.getBackend().WriteNopData(Count, OW))
         report_fatal_error("unable to write nop sequence of " +
                           Twine(Count) + " bytes");
Index: lib/CodeGen/LLVMTargetMachine.cpp
===================================================================
--- lib/CodeGen/LLVMTargetMachine.cpp	(revision 136769)
+++ lib/CodeGen/LLVMTargetMachine.cpp	(working copy)
@@ -141,7 +141,7 @@
     if (ShowMCEncoding) {
       const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
       MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, *Context);
-      MAB = getTarget().createMCAsmBackend(getTargetTriple());
+      MAB = getTarget().createMCAsmBackend(STI, getTargetTriple());
     }
 
     MCStreamer *S = getTarget().createAsmStreamer(*Context, Out,
@@ -160,7 +160,7 @@
     const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
     MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI,
                                                          *Context);
-    MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple());
+    MCAsmBackend *MAB = getTarget().createMCAsmBackend(STI, getTargetTriple());
     if (MCE == 0 || MAB == 0)
       return true;
 
@@ -237,7 +237,7 @@
   // emission fails.
   const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
   MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(),STI, *Ctx);
-  MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple());
+  MCAsmBackend *MAB = getTarget().createMCAsmBackend(STI, getTargetTriple());
   if (MCE == 0 || MAB == 0)
     return true;
 
