[PATCHES] PR18303: Use appropriate Feature flags for encoding instructions

Jim Grosbach grosbach at apple.com
Wed Jan 8 09:54:56 PST 2014


On Jan 8, 2014, at 9:43 AM, David Woodhouse <dwmw2 at infradead.org> wrote:

> Two preparatory patches to allow the flags to reach the correct
> place(s). And then some relatively simple patches for ARM and X86 to fix
> the actual issue.
> 
> The second one is rather large... but ultimately very simple.
> 
> (No, please don't clang-format the MIPS back end today).
> 
> -- 
> David Woodhouse                            Open Source Technology Centre
> David.Woodhouse at intel.com                              Intel Corporation
> From 155ff80aa49ae1a47c58910a5229473047383dde Mon Sep 17 00:00:00 2001
> From: David Woodhouse <David.Woodhouse at intel.com>
> Date: Sun, 5 Jan 2014 21:10:17 +0000
> Subject: [PATCH 1/4] [MC] Store MCCodeEmitter feature flags in
> MCRelaxableFragment (PR18303)
> 
> The X86 and ARM AsmParsers, and probably others, directly manipulate the
> SubtargetInfo feature bits, affecting the output of the CodeEmitter.
> 
> When we do relaxations, no special consideration is given to this fact.
> All instructions are encoded in whatever mode the AsmParser happened
> to leave active at the end of the input file.
> 
> We can fix this by storing the currently-active set of feature bits in
> the MCRelaxableFragment so that the instruction can be re-encoded
> *correctly* when it becomes necessary to do so.
> 
> We add a getAvailableFeatures() method for the MCCodeEmitter to return
> the "current" values. The uint64_t has meaning private to the CodeEmitter
> implementation, although it's usually going to be STI.getFeatureBits()
> in practice.
> 
> The same feature bits are then passed as an additional argument to the
> EncodeInstruction() method.
> 
> For use in all cases *other* than relaxation, an (inline) overloaded
> form of EncodeInstruction() remains. This will simply call the
> getAvailableFeatures() method and then call the full version of
> EncodeInstruction() with that set of features.
> ---
> include/llvm/MC/MCAssembler.h                            |  6 ++++++
> include/llvm/MC/MCCodeEmitter.h                          | 13 ++++++++++++-
> lib/MC/MCAssembler.cpp                                   |  3 ++-
> lib/MC/MCObjectStreamer.cpp                              |  1 +
> lib/MC/MCPureStreamer.cpp                                |  1 +
> lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp |  6 ++++--
> lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp         |  6 ++++--
> lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp       |  6 ++++--
> lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp     |  3 ++-
> lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp       |  6 ++++--
> lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp         |  6 ++++--
> lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp     |  6 ++++--
> lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp |  6 ++++--
> lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp         |  6 ++++--
> 14 files changed, 56 insertions(+), 19 deletions(-)
> 
> diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
> index 8735a55..44a6f87 100644
> --- a/include/llvm/MC/MCAssembler.h
> +++ b/include/llvm/MC/MCAssembler.h
> @@ -294,6 +294,9 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
>   /// Fixups - The list of fixups in this fragment.
>   SmallVector<MCFixup, 1> Fixups;
> 
> +  /// EmitterFeatures - The feature set for MCCodeEmitter to use.
> +  uint64_t EmitterFeatures;
> +

Why have this be separate value from what’s in the MCSubtargetInfo? Perhaps naively, but I’d have expected to just add a setter method to that rather than keeping a separate copy of the data, which can go out of sync, in the code emitter itself. If that’s practical, it would potentially simplify a lot of things. For example, the isThumb() and friends methods won’t need a new argument for the feature bits.

> public:
>   MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
>     : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
> @@ -305,6 +308,9 @@ public:
>   const MCInst &getInst() const { return Inst; }
>   void setInst(const MCInst& Value) { Inst = Value; }
> 
> +  uint64_t getEmitterFeatures() const { return EmitterFeatures; }
> +  void setEmitterFeatures(uint64_t features) { EmitterFeatures = features; }
> +
>   SmallVectorImpl<MCFixup> &getFixups() {
>     return Fixups;
>   }
> diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
> index 9bfa08e..9c041eb 100644
> --- a/include/llvm/MC/MCCodeEmitter.h
> +++ b/include/llvm/MC/MCCodeEmitter.h
> @@ -11,6 +11,7 @@
> #define LLVM_MC_MCCODEEMITTER_H
> 
> #include "llvm/Support/Compiler.h"
> +#include "llvm/Support/DataTypes.h"
> 
> namespace llvm {
> class MCFixup;
> @@ -35,7 +36,17 @@ public:
>   /// EncodeInstruction - Encode the given \p Inst to bytes on the output
>   /// stream \p OS.
>   virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const = 0;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t AvailableFeatures) const = 0;
> +
> +  inline void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
> +                         SmallVectorImpl<MCFixup> &Fixups) {
> +    return EncodeInstruction(Inst, OS, Fixups, getAvailableFeatures());
> +  }
> +
> +  /// getAvailableFeatures - Return the current feature set, for use when an
> +  /// instruction is re-encoded later due to relaxation.
> +  virtual uint64_t getAvailableFeatures() const { return 0; }
> };
> 
> } // End llvm namespace
> diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
> index 68111f1..85ba214 100644
> --- a/lib/MC/MCAssembler.cpp
> +++ b/lib/MC/MCAssembler.cpp
> @@ -875,7 +875,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
>   SmallVector<MCFixup, 4> Fixups;
>   SmallString<256> Code;
>   raw_svector_ostream VecOS(Code);
> -  getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups);
> +  getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups, F.getEmitterFeatures());
>   VecOS.flush();
> 
>   // Update the fragment.
> @@ -1093,6 +1093,7 @@ void MCFragment::dump() {
>     OS << "\n       ";
>     OS << " Inst:";
>     F->getInst().dump_pretty(OS);
> +    OS << " Features:" << F->getEmitterFeatures();
>     break;
>   }
>   case MCFragment::FT_Org:  {
> diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
> index 5c08610..5e03bf5 100644
> --- a/lib/MC/MCObjectStreamer.cpp
> +++ b/lib/MC/MCObjectStreamer.cpp
> @@ -242,6 +242,7 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
>   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
>   VecOS.flush();
>   IF->getContents().append(Code.begin(), Code.end());
> +  IF->setEmitterFeatures(getAssembler().getEmitter().getAvailableFeatures());
> }
> 
> #ifndef NDEBUG
> diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp
> index f7bf002..d60872f 100644
> --- a/lib/MC/MCPureStreamer.cpp
> +++ b/lib/MC/MCPureStreamer.cpp
> @@ -204,6 +204,7 @@ void MCPureStreamer::EmitInstToFragment(const MCInst &Inst) {
> 
>   IF->getContents() = Code;
>   IF->getFixups() = Fixups;
> +  IF->setEmitterFeatures(getAssembler().getEmitter().getAvailableFeatures());
> }
> 
> void MCPureStreamer::EmitInstToData(const MCInst &Inst) {
> diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
> index b41c566..2bb0a78 100644
> --- a/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
> +++ b/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
> @@ -121,7 +121,8 @@ public:
> 
> 
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                         SmallVectorImpl<MCFixup> &Fixups) const;
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t AvailableFeatures) const;
> 
>   template<int hasRs, int hasRt2> unsigned
>   fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue) const;
> @@ -545,7 +546,8 @@ MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
> 
> void AArch64MCCodeEmitter::
> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t AvailableFeatures) const {
>   if (MI.getOpcode() == AArch64::TLSDESCCALL) {
>     // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
>     // following (BLR) instruction. It doesn't emit any code itself so it
> diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> index 25a3d4d..1690926 100644
> --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> @@ -333,7 +333,8 @@ public:
>   }
> 
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                         SmallVectorImpl<MCFixup> &Fixups) const;
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t AvailableFeatures) const;
> };
> 
> } // end anonymous namespace
> @@ -1524,7 +1525,8 @@ getShiftRight64Imm(const MCInst &MI, unsigned Op,
> 
> void ARMMCCodeEmitter::
> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t AvailableFeatures) const {
>   // Pseudo instructions don't get encoded.
>   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
>   uint64_t TSFlags = Desc.TSFlags;
> diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
> index aad777d..9186ca6 100644
> --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
> +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
> @@ -71,7 +71,8 @@ public:
>   }
> 
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                         SmallVectorImpl<MCFixup> &Fixups) const;
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t AvailableFeatures) const;
> 
>   // getBinaryCodeForInstr - TableGen'erated function for getting the
>   // binary encoding for an instruction.
> @@ -215,7 +216,8 @@ static void LowerDextDins(MCInst& InstIn) {
> /// Size the instruction with Desc.getSize().
> void MipsMCCodeEmitter::
> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                  SmallVectorImpl<MCFixup> &Fixups) const
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t AvailableFeatures) const
> {
> 
>   // Non-pseudo instructions that get changed for direct object
> diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
> index 66ebfd2..3f0a944 100644
> --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
> +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
> @@ -76,7 +76,8 @@ public:
>   uint64_t getBinaryCodeForInstr(const MCInst &MI,
>                                  SmallVectorImpl<MCFixup> &Fixups) const;
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                         SmallVectorImpl<MCFixup> &Fixups) const {
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t AvailableFeatures) const {
>     // For fast-isel, a float COPY_TO_REGCLASS can survive this long.
>     // It's just a nop to keep the register classes happy, so don't
>     // generate anything.
> diff --git a/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp b/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
> index dd8df65..873d3ab 100644
> --- a/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
> +++ b/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
> @@ -44,7 +44,8 @@ public:
> 
>   /// \brief Encode the instruction and write it to the OS.
>   virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                         SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t AvailableFeatures) const;
> 
>   /// \returns the encoding for an MCOperand.
>   virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> @@ -87,7 +88,8 @@ MCCodeEmitter *llvm::createR600MCCodeEmitter(const MCInstrInfo &MCII,
> }
> 
> void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                          SmallVectorImpl<MCFixup> &Fixups,
> +                                          uint64_t AvailableFeatures) const {
>   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
>   if (MI.getOpcode() == AMDGPU::RETURN ||
>     MI.getOpcode() == AMDGPU::FETCH_CLAUSE ||
> diff --git a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> index 5af8320..b08f8eb 100644
> --- a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> +++ b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> @@ -55,7 +55,8 @@ public:
> 
>   /// \breif Encode the instruction and write it to the OS.
>   virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                         SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t AvailableFeatures) const;
> 
>   /// \returns the encoding for an MCOperand.
>   virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> @@ -125,7 +126,8 @@ uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO) const {
> }
> 
> void SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                        SmallVectorImpl<MCFixup> &Fixups,
> +                                        uint64_t AvailableFeatures) const {
> 
>   uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups);
>   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
> diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
> index 580e7a2..f6924b9 100644
> --- a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
> +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
> @@ -39,7 +39,8 @@ public:
>   ~SparcMCCodeEmitter() {}
> 
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                         SmallVectorImpl<MCFixup> &Fixups) const;
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t AvailableFeatures) const;
> 
>   // getBinaryCodeForInstr - TableGen'erated function for getting the
>   // binary encoding for an instruction.
> @@ -68,7 +69,8 @@ MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
> 
> void SparcMCCodeEmitter::
> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t AvailableFeatures) const {
>   unsigned Bits = getBinaryCodeForInstr(MI, Fixups);
> 
>   // Output the constant in big endian byte order.
> diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
> index f07ea7b..2bbf36d 100644
> --- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
> +++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
> @@ -35,7 +35,8 @@ public:
> 
>   // OVerride MCCodeEmitter.
>   virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t AvailableFeatures) const
>     LLVM_OVERRIDE;
> 
> private:
> @@ -91,7 +92,8 @@ MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII,
> 
> void SystemZMCCodeEmitter::
> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t AvailableFeatures) const {
>   uint64_t Bits = getBinaryCodeForInstr(MI, Fixups);
>   unsigned Size = MCII.get(MI.getOpcode()).getSize();
>   // Big-endian insertion of Size bytes.
> diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> index 576b6e0..6b6e189 100644
> --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> @@ -152,7 +152,8 @@ public:
>                         SmallVectorImpl<MCFixup> &Fixups) const;
> 
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                         SmallVectorImpl<MCFixup> &Fixups) const;
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t Features) const;
> 
>   void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
>                            const MCInst &MI, const MCInstrDesc &Desc,
> @@ -1266,7 +1267,8 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
> 
> void X86MCCodeEmitter::
> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
>   unsigned Opcode = MI.getOpcode();
>   const MCInstrDesc &Desc = MCII.get(Opcode);
>   uint64_t TSFlags = Desc.TSFlags;
> -- 
> 1.8.4.2
> 
> From a3c8466129b64f4941b225a188877c3405eeb82e Mon Sep 17 00:00:00 2001
> From: David Woodhouse <David.Woodhouse at intel.com>
> Date: Wed, 8 Jan 2014 15:26:15 +0000
> Subject: [PATCH 2/4] Propagate feature flags through TableGen's
> getBinaryCodeForInstr()
> 
> In order to fix PR18303 we want the correct feature flags to be available
> when encoding instructions. That means we have to propagate them from
> the EncodeInstruction() method down to where they're used. Through code
> which comes from TableGen.
> ---
> .../AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp  | 137 +++++---
> lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp   | 369 +++++++++++++--------
> lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 114 ++++---
> .../PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp      | 100 ++++--
> lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h |   6 +-
> lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp |  12 +-
> lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp   |   8 +-
> .../Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp      |  27 +-
> .../SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp  |  86 +++--
> utils/TableGen/CodeEmitterGen.cpp                  |  14 +-
> 10 files changed, 560 insertions(+), 313 deletions(-)
> 
> diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
> index 2bb0a78..32c645e 100644
> --- a/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
> +++ b/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
> @@ -39,56 +39,72 @@ public:
>   ~AArch64MCCodeEmitter() {}
> 
>   unsigned getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
> 
>   unsigned getAdrpLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
> 
>   template<int MemSize>
>   unsigned getOffsetUImm12OpValue(const MCInst &MI, unsigned OpIdx,
> -                                    SmallVectorImpl<MCFixup> &Fixups) const {
> -    return getOffsetUImm12OpValue(MI, OpIdx, Fixups, MemSize);
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features) const {
> +    return getOffsetUImm12OpValue(MI, OpIdx, Fixups, Features, MemSize);
>   }
> 
>   unsigned getOffsetUImm12OpValue(const MCInst &MI, unsigned OpIdx,
> -                                    SmallVectorImpl<MCFixup> &Fixups,
> -                                    int MemSize) const;
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features,int MemSize) const;
> 
>   unsigned getBitfield32LSLOpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const;
>   unsigned getBitfield64LSLOpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const;
> 
>   unsigned getShiftRightImm8(const MCInst &MI, unsigned Op,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getShiftRightImm16(const MCInst &MI, unsigned Op,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
>   unsigned getShiftRightImm32(const MCInst &MI, unsigned Op,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
>   unsigned getShiftRightImm64(const MCInst &MI, unsigned Op,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
> 
>   unsigned getShiftLeftImm8(const MCInst &MI, unsigned Op,
> -                            SmallVectorImpl<MCFixup> &Fixups) const;
> +                            SmallVectorImpl<MCFixup> &Fixups,
> +                            uint64_t Features) const;
>   unsigned getShiftLeftImm16(const MCInst &MI, unsigned Op,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getShiftLeftImm32(const MCInst &MI, unsigned Op,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getShiftLeftImm64(const MCInst &MI, unsigned Op,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   // Labels are handled mostly the same way: a symbol is needed, and
>   // just gets some fixup attached.
>   template<AArch64::Fixups fixupDesired>
>   unsigned getLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                           SmallVectorImpl<MCFixup> &Fixups) const;
> +                           SmallVectorImpl<MCFixup> &Fixups,
> +                           uint64_t Features) const;
> 
>   unsigned  getLoadLitLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const;
> 
> 
>   unsigned getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
> 
> 
>   unsigned getAddressWithFixup(const MCOperand &MO,
> @@ -99,12 +115,14 @@ public:
>   // getBinaryCodeForInstr - TableGen'erated function for getting the
>   // binary encoding for an instruction.
>   uint64_t getBinaryCodeForInstr(const MCInst &MI,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
> 
>   /// getMachineOpValue - Return binary encoding of operand. If the machine
>   /// operand requires relocation, record the relocation and return zero.
>   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
> 
>   void EmitByte(unsigned char C, raw_ostream &OS) const {
> @@ -125,11 +143,14 @@ public:
>                          uint64_t AvailableFeatures) const;
> 
>   template<int hasRs, int hasRt2> unsigned
> -  fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue) const;
> +  fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue,
> +                        uint64_t Features) const;
> 
> -  unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue) const;
> +  unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue,
> +                   uint64_t Features) const;
> 
> -  unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue) const;
> +  unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue,
> +                      uint64_t Features) const;
> 
> 
> };
> @@ -157,7 +178,7 @@ unsigned AArch64MCCodeEmitter::getAddressWithFixup(const MCOperand &MO,
> unsigned AArch64MCCodeEmitter::
> getOffsetUImm12OpValue(const MCInst &MI, unsigned OpIdx,
>                        SmallVectorImpl<MCFixup> &Fixups,
> -                       int MemSize) const {
> +                       uint64_t Features, int MemSize) const {
>   const MCOperand &ImmOp = MI.getOperand(OpIdx);
>   if (ImmOp.isImm())
>     return ImmOp.getImm();
> @@ -242,7 +263,8 @@ getOffsetUImm12OpValue(const MCInst &MI, unsigned OpIdx,
> 
> unsigned
> AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                          SmallVectorImpl<MCFixup> &Fixups,
> +                                          uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpIdx);
>   if (MO.isImm())
>     return static_cast<unsigned>(MO.getImm());
> @@ -275,7 +297,8 @@ AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
> 
> unsigned
> AArch64MCCodeEmitter::getAdrpLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                          SmallVectorImpl<MCFixup> &Fixups,
> +                                          uint64_t Features) const {
> 
>   const MCOperand &MO = MI.getOperand(OpIdx);
>   if (MO.isImm())
> @@ -310,7 +333,8 @@ AArch64MCCodeEmitter::getAdrpLabelOpValue(const MCInst &MI, unsigned OpIdx,
> 
> unsigned
> AArch64MCCodeEmitter::getBitfield32LSLOpValue(const MCInst &MI, unsigned OpIdx,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                              SmallVectorImpl<MCFixup> &Fixups,
> +                                              uint64_t Features) const {
> 
>   const MCOperand &MO = MI.getOperand(OpIdx);
>   assert(MO.isImm() && "Only immediate expected for shift");
> @@ -320,7 +344,8 @@ AArch64MCCodeEmitter::getBitfield32LSLOpValue(const MCInst &MI, unsigned OpIdx,
> 
> unsigned
> AArch64MCCodeEmitter::getBitfield64LSLOpValue(const MCInst &MI, unsigned OpIdx,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                              SmallVectorImpl<MCFixup> &Fixups,
> +                                              uint64_t Features) const {
> 
>   const MCOperand &MO = MI.getOperand(OpIdx);
>   assert(MO.isImm() && "Only immediate expected for shift");
> @@ -328,50 +353,50 @@ AArch64MCCodeEmitter::getBitfield64LSLOpValue(const MCInst &MI, unsigned OpIdx,
>   return ((64 - MO.getImm()) & 0x3f) | (63 - MO.getImm()) << 6;
> }
> 
> -unsigned AArch64MCCodeEmitter::getShiftRightImm8(
> -    const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const {
> +unsigned AArch64MCCodeEmitter::getShiftRightImm8(const MCInst &MI, unsigned Op,
> +     SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   return 8 - MI.getOperand(Op).getImm();
> }
> 
> -unsigned AArch64MCCodeEmitter::getShiftRightImm16(
> -    const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const {
> +unsigned AArch64MCCodeEmitter::getShiftRightImm16(const MCInst &MI, unsigned Op,
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   return 16 - MI.getOperand(Op).getImm();
> }
> 
> -unsigned AArch64MCCodeEmitter::getShiftRightImm32(
> -    const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const {
> +unsigned AArch64MCCodeEmitter::getShiftRightImm32(const MCInst &MI, unsigned Op,
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   return 32 - MI.getOperand(Op).getImm();
> }
> 
> -unsigned AArch64MCCodeEmitter::getShiftRightImm64(
> -    const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const {
> +unsigned AArch64MCCodeEmitter::getShiftRightImm64(const MCInst &MI, unsigned Op,
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   return 64 - MI.getOperand(Op).getImm();
> }
> 
> -unsigned AArch64MCCodeEmitter::getShiftLeftImm8(
> -    const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const {
> +unsigned AArch64MCCodeEmitter::getShiftLeftImm8(const MCInst &MI, unsigned Op,
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   return MI.getOperand(Op).getImm() - 8;
> }
> 
> -unsigned AArch64MCCodeEmitter::getShiftLeftImm16(
> -    const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const {
> +unsigned AArch64MCCodeEmitter::getShiftLeftImm16(const MCInst &MI, unsigned Op,
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   return MI.getOperand(Op).getImm() - 16;
> }
> 
> -unsigned AArch64MCCodeEmitter::getShiftLeftImm32(
> -    const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const {
> +unsigned AArch64MCCodeEmitter::getShiftLeftImm32(const MCInst &MI, unsigned Op,
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   return MI.getOperand(Op).getImm() - 32;
> }
> 
> -unsigned AArch64MCCodeEmitter::getShiftLeftImm64(
> -    const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const {
> +unsigned AArch64MCCodeEmitter::getShiftLeftImm64(const MCInst &MI, unsigned Op,
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   return MI.getOperand(Op).getImm() - 64;
> }
> 
> template<AArch64::Fixups fixupDesired> unsigned
> AArch64MCCodeEmitter::getLabelOpValue(const MCInst &MI,
>                                       unsigned OpIdx,
> -                                      SmallVectorImpl<MCFixup> &Fixups) const {
> +                                      SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpIdx);
> 
>   if (MO.isExpr())
> @@ -384,7 +409,8 @@ AArch64MCCodeEmitter::getLabelOpValue(const MCInst &MI,
> unsigned
> AArch64MCCodeEmitter::getLoadLitLabelOpValue(const MCInst &MI,
>                                        unsigned OpIdx,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                       SmallVectorImpl<MCFixup> &Fixups,
> +                                       uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpIdx);
> 
>   if (MO.isImm())
> @@ -409,7 +435,8 @@ AArch64MCCodeEmitter::getLoadLitLabelOpValue(const MCInst &MI,
> unsigned
> AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI,
>                                        const MCOperand &MO,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                       SmallVectorImpl<MCFixup> &Fixups,
> +                                       uint64_t Features) const {
>   if (MO.isReg()) {
>     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
>   } else if (MO.isImm()) {
> @@ -422,7 +449,8 @@ AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI,
> 
> unsigned
> AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                       SmallVectorImpl<MCFixup> &Fixups,
> +                                       uint64_t Features) const {
>   const MCOperand &UImm16MO = MI.getOperand(OpIdx);
>   const MCOperand &ShiftMO = MI.getOperand(OpIdx + 1);
> 
> @@ -488,7 +516,8 @@ AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
> 
> template<int hasRs, int hasRt2> unsigned
> AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
> -                                            unsigned EncodedValue) const {
> +                                            unsigned EncodedValue,
> +                                            uint64_t Features) const {
>   if (!hasRs) EncodedValue |= 0x001F0000;
>   if (!hasRt2) EncodedValue |= 0x00007C00;
> 
> @@ -496,7 +525,8 @@ AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
> }
> 
> unsigned
> -AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue) const {
> +AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
> +                              uint64_t Features) const {
>   // If one of the signed fixup kinds is applied to a MOVZ instruction, the
>   // eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's
>   // job to ensure that any bits possibly affected by this are 0. This means we
> @@ -530,7 +560,8 @@ AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue) const {
> 
> unsigned
> AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
> -                                 unsigned EncodedValue) const {
> +                                 unsigned EncodedValue,
> +                                 uint64_t Features) const {
>   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
>   // (i.e. all bits 1) but is ignored by the processor.
>   EncodedValue |= 0x1f << 10;
> @@ -559,7 +590,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>     return;
>   }
> 
> -  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
> +  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
> 
>   EmitInstruction(Binary, OS);
> }
> diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> index 1690926..4fb1410 100644
> --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> @@ -50,7 +50,6 @@ public:
>   ~ARMMCCodeEmitter() {}
> 
>   bool isThumb() const {
> -    // FIXME: Can tablegen auto-generate this?
>     return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
>   }
>   bool isThumb2() const {
> @@ -66,18 +65,21 @@ public:
>   // getBinaryCodeForInstr - TableGen'erated function for getting the
>   // binary encoding for an instruction.
>   uint64_t getBinaryCodeForInstr(const MCInst &MI,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
> 
>   /// getMachineOpValue - Return binary encoding of operand. If the machine
>   /// operand requires relocation, record the relocation and return zero.
>   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   /// getHiLo16ImmOpValue - Return the encoding for the hi / low 16-bit of
>   /// the specified operand. This is used for operands with :lower16: and
>   /// :upper16: prefixes.
>   uint32_t getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
> 
>   bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
>                               unsigned &Reg, unsigned &Imm,
> @@ -86,87 +88,107 @@ public:
>   /// getThumbBLTargetOpValue - Return encoding info for Thumb immediate
>   /// BL branch target.
>   uint32_t getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const;
> 
>   /// getThumbBLXTargetOpValue - Return encoding info for Thumb immediate
>   /// BLX branch target.
>   uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                    SmallVectorImpl<MCFixup> &Fixups) const;
> +                                    SmallVectorImpl<MCFixup> &Fixups,
> +                                    uint64_t Features) const;
> 
>   /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
>   uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const;
> 
>   /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
>   uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                    SmallVectorImpl<MCFixup> &Fixups) const;
> +                                    SmallVectorImpl<MCFixup> &Fixups,
> +                                    uint64_t Features) const;
> 
>   /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
>   uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const;
> 
>   /// getBranchTargetOpValue - Return encoding info for 24-bit immediate
>   /// branch target.
>   uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                  SmallVectorImpl<MCFixup> &Fixups) const;
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features) const;
> 
>   /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit
>   /// immediate Thumb2 direct branch target.
>   uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                  SmallVectorImpl<MCFixup> &Fixups) const;
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                               uint64_t Features) const;
> 
>   /// getARMBranchTargetOpValue - Return encoding info for 24-bit immediate
>   /// branch target.
>   uint32_t getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const;
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const;
>   uint32_t getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
>   uint32_t getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                  SmallVectorImpl<MCFixup> &Fixups) const;
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features) const;
> 
>   /// getAdrLabelOpValue - Return encoding info for 12-bit immediate
>   /// ADR label target.
>   uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
>   uint32_t getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const;
>   uint32_t getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
> 
> 
>   /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
>   /// operand.
>   uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const;
> 
>   /// getThumbAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
>   uint32_t getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
> -                                         SmallVectorImpl<MCFixup> &Fixups)const;
> +                                         SmallVectorImpl<MCFixup> &Fixups,
> +                                         uint64_t Features)const;
> 
>   /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
>   /// operand.
>   uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                      SmallVectorImpl<MCFixup> &Fixups,
> +                                      uint64_t Features) const;
> 
>   /// getT2AddrModeImm0_1020s4OpValue - Return encoding info for 'reg + imm8<<2'
>   /// operand.
>   uint32_t getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const;
> +                                           SmallVectorImpl<MCFixup> &Fixups,
> +                                           uint64_t Features) const;
> 
>   /// getT2Imm8s4OpValue - Return encoding info for '+/- imm8<<2'
>   /// operand.
>   uint32_t getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
> 
> 
>   /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
>   /// operand as needed by load/store instructions.
>   uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
> 
>   /// getLdStmModeOpValue - Return encoding for load/store multiple mode.
>   uint32_t getLdStmModeOpValue(const MCInst &MI, unsigned OpIdx,
> -                               SmallVectorImpl<MCFixup> &Fixups) const {
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const {
>     ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm();
>     switch (Mode) {
>     default: llvm_unreachable("Unknown addressing sub-mode!");
> @@ -192,44 +214,54 @@ public:
> 
>   /// getAddrMode2OpValue - Return encoding for addrmode2 operands.
>   uint32_t getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
> 
>   /// getAddrMode2OffsetOpValue - Return encoding for am2offset operands.
>   uint32_t getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const;
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const;
> 
>   /// getPostIdxRegOpValue - Return encoding for postidx_reg operands.
>   uint32_t getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
> -                                SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
> 
>   /// getAddrMode3OffsetOpValue - Return encoding for am3offset operands.
>   uint32_t getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const;
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const;
> 
>   /// getAddrMode3OpValue - Return encoding for addrmode3 operands.
>   uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
> 
>   /// getAddrModeThumbSPOpValue - Return encoding info for 'reg +/- imm12'
>   /// operand.
>   uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const;
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const;
> 
>   /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
>   uint32_t getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
> -                                SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
> 
>   /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
>   uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
> -                                SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
> 
>   /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
>   uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
> 
>   /// getCCOutOpValue - Return encoding of the 's' bit.
>   unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
> -                           SmallVectorImpl<MCFixup> &Fixups) const {
> +                           SmallVectorImpl<MCFixup> &Fixups,
> +                           uint64_t Features) const {
>     // The operand is either reg0 or CPSR. The 's' bit is encoded as '0' or
>     // '1' respectively.
>     return MI.getOperand(Op).getReg() == ARM::CPSR;
> @@ -237,7 +269,8 @@ public:
> 
>   /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
>   unsigned getSOImmOpValue(const MCInst &MI, unsigned Op,
> -                           SmallVectorImpl<MCFixup> &Fixups) const {
> +                           SmallVectorImpl<MCFixup> &Fixups,
> +                           uint64_t Features) const {
>     unsigned SoImm = MI.getOperand(Op).getImm();
>     int SoImmVal = ARM_AM::getSOImmVal(SoImm);
>     assert(SoImmVal != -1 && "Not a valid so_imm value!");
> @@ -253,7 +286,8 @@ public:
> 
>   /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
>   unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
> -                           SmallVectorImpl<MCFixup> &Fixups) const {
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const {
>     unsigned SoImm = MI.getOperand(Op).getImm();
>     unsigned Encoded =  ARM_AM::getT2SOImmVal(SoImm);
>     assert(Encoded != ~0U && "Not a Thumb2 so_imm value?");
> @@ -261,64 +295,84 @@ public:
>   }
> 
>   unsigned getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
> -    SmallVectorImpl<MCFixup> &Fixups) const;
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const;
>   unsigned getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
> -    SmallVectorImpl<MCFixup> &Fixups) const;
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const;
>   unsigned getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
> -    SmallVectorImpl<MCFixup> &Fixups) const;
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const;
>   unsigned getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
> -    SmallVectorImpl<MCFixup> &Fixups) const;
> +    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const;
> 
>   /// getSORegOpValue - Return an encoded so_reg shifted register value.
>   unsigned getSORegRegOpValue(const MCInst &MI, unsigned Op,
> -                           SmallVectorImpl<MCFixup> &Fixups) const;
> +                           SmallVectorImpl<MCFixup> &Fixups,
> +                           uint64_t Features) const;
>   unsigned getSORegImmOpValue(const MCInst &MI, unsigned Op,
> -                           SmallVectorImpl<MCFixup> &Fixups) const;
> +                           SmallVectorImpl<MCFixup> &Fixups,
> +                           uint64_t Features) const;
>   unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
> -                                   SmallVectorImpl<MCFixup> &Fixups) const {
> +                                   SmallVectorImpl<MCFixup> &Fixups,
> +                                   uint64_t Features) const {
>     return 64 - MI.getOperand(Op).getImm();
>   }
> 
>   unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
> -                                      SmallVectorImpl<MCFixup> &Fixups) const;
> +                                          SmallVectorImpl<MCFixup> &Fixups,
> +                                          uint64_t Features) const;
> 
>   unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
> -                                  SmallVectorImpl<MCFixup> &Fixups) const;
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features) const;
>   unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
> -                                      SmallVectorImpl<MCFixup> &Fixups) const;
> +                                      SmallVectorImpl<MCFixup> &Fixups,
> +                                      uint64_t Features) const;
>   unsigned getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
> -                                        SmallVectorImpl<MCFixup> &Fixups) const;
> +                                        SmallVectorImpl<MCFixup> &Fixups,
> +                                        uint64_t Features) const;
>   unsigned getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
> -                                        SmallVectorImpl<MCFixup> &Fixups) const;
> +                                        SmallVectorImpl<MCFixup> &Fixups,
> +                                        uint64_t Features) const;
>   unsigned getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const;
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const;
> 
>   unsigned getShiftRight8Imm(const MCInst &MI, unsigned Op,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getShiftRight16Imm(const MCInst &MI, unsigned Op,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
>   unsigned getShiftRight32Imm(const MCInst &MI, unsigned Op,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
>   unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
> 
>   unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
> 
>   unsigned NEONThumb2DataIPostEncoder(const MCInst &MI,
> -                                      unsigned EncodedValue) const;
> +                                      unsigned EncodedValue,
> +                                      uint64_t Features) const;
>   unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI,
> -                                          unsigned EncodedValue) const;
> +                                          unsigned EncodedValue,
> +                                          uint64_t Features) const;
>   unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
> -                                    unsigned EncodedValue) const;
> +                                    unsigned EncodedValue,
> +                                    uint64_t Features) const;
>   unsigned NEONThumb2V8PostEncoder(const MCInst &MI,
> -                                   unsigned EncodedValue) const;
> +                                   unsigned EncodedValue,
> +                                   uint64_t Features) const;
> 
>   unsigned VFPThumb2PostEncoder(const MCInst &MI,
> -                                unsigned EncodedValue) const;
> +                                unsigned EncodedValue,
> +                                uint64_t Features) const;
> 
>   void EmitByte(unsigned char C, raw_ostream &OS) const {
>     OS << (char)C;
> @@ -349,8 +403,9 @@ MCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
> /// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
> /// instructions, and rewrite them to their Thumb2 form if we are currently in
> /// Thumb2 mode.
> -unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
> -                                                 unsigned EncodedValue) const {
> +unsigned ARMMCCodeEmitter::
> +NEONThumb2DataIPostEncoder(const MCInst &MI, unsigned EncodedValue,
> +                           uint64_t Features) const {
>   if (isThumb2()) {
>     // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
>     // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
> @@ -368,8 +423,9 @@ unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
> /// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
> /// instructions, and rewrite them to their Thumb2 form if we are currently in
> /// Thumb2 mode.
> -unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
> -                                                 unsigned EncodedValue) const {
> +unsigned ARMMCCodeEmitter::
> +NEONThumb2LoadStorePostEncoder(const MCInst &MI, unsigned EncodedValue,
> +                               uint64_t Features) const {
>   if (isThumb2()) {
>     EncodedValue &= 0xF0FFFFFF;
>     EncodedValue |= 0x09000000;
> @@ -381,8 +437,9 @@ unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
> /// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
> /// instructions, and rewrite them to their Thumb2 form if we are currently in
> /// Thumb2 mode.
> -unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
> -                                                 unsigned EncodedValue) const {
> +unsigned ARMMCCodeEmitter::
> +NEONThumb2DupPostEncoder(const MCInst &MI, unsigned EncodedValue,
> +                         uint64_t Features) const {
>   if (isThumb2()) {
>     EncodedValue &= 0x00FFFFFF;
>     EncodedValue |= 0xEE000000;
> @@ -393,8 +450,9 @@ unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
> 
> /// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form
> /// if we are in Thumb2.
> -unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
> -                                                 unsigned EncodedValue) const {
> +unsigned ARMMCCodeEmitter::
> +NEONThumb2V8PostEncoder(const MCInst &MI, unsigned EncodedValue,
> +                        uint64_t Features) const {
>   if (isThumb2()) {
>     EncodedValue |= 0xC000000; // Set bits 27-26
>   }
> @@ -405,7 +463,8 @@ unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
> /// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
> /// them to their Thumb2 form if we are currently in Thumb2 mode.
> unsigned ARMMCCodeEmitter::
> -VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
> +VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue,
> +                     uint64_t Features) const {
>   if (isThumb2()) {
>     EncodedValue &= 0x0FFFFFFF;
>     EncodedValue |= 0xE0000000;
> @@ -417,7 +476,8 @@ VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
> /// operand requires relocation, record the relocation and return zero.
> unsigned ARMMCCodeEmitter::
> getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
>   if (MO.isReg()) {
>     unsigned Reg = MO.getReg();
>     unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
> @@ -510,7 +570,8 @@ static int32_t encodeThumbBLOffset(int32_t offset) {
> /// getThumbBLTargetOpValue - Return encoding info for immediate branch target.
> uint32_t ARMMCCodeEmitter::
> getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                        SmallVectorImpl<MCFixup> &Fixups) const {
> +                        SmallVectorImpl<MCFixup> &Fixups,
> +                        uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
>     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bl,
> @@ -522,7 +583,8 @@ getThumbBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
> /// BLX branch target.
> uint32_t ARMMCCodeEmitter::
> getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                         SmallVectorImpl<MCFixup> &Fixups) const {
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
>     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx,
> @@ -533,7 +595,8 @@ getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
> /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
> uint32_t ARMMCCodeEmitter::
> getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                        SmallVectorImpl<MCFixup> &Fixups) const {
> +                        SmallVectorImpl<MCFixup> &Fixups,
> +                        uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
>     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br,
> @@ -544,7 +607,8 @@ getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
> /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
> uint32_t ARMMCCodeEmitter::
> getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                         SmallVectorImpl<MCFixup> &Fixups) const {
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
>     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc,
> @@ -555,7 +619,8 @@ getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
> /// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
> uint32_t ARMMCCodeEmitter::
> getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                        SmallVectorImpl<MCFixup> &Fixups) const {
> +                        SmallVectorImpl<MCFixup> &Fixups,
> +                        uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
>     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cb, Fixups);
> @@ -583,27 +648,27 @@ static bool HasConditionalBranch(const MCInst &MI) {
> /// target.
> uint32_t ARMMCCodeEmitter::
> getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                       SmallVectorImpl<MCFixup> &Fixups) const {
> -  // FIXME: This really, really shouldn't use TargetMachine. We don't want
> -  // coupling between MC and TM anywhere we can help it.
> +                       SmallVectorImpl<MCFixup> &Fixups,
> +                       uint64_t Features) const {
>   if (isThumb2())
>     return
>       ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
> -  return getARMBranchTargetOpValue(MI, OpIdx, Fixups);
> +  return getARMBranchTargetOpValue(MI, OpIdx, Fixups, Features);
> }
> 
> /// getBranchTargetOpValue - Return encoding info for 24-bit immediate branch
> /// target.
> uint32_t ARMMCCodeEmitter::
> getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                          SmallVectorImpl<MCFixup> &Fixups) const {
> +                          SmallVectorImpl<MCFixup> &Fixups,
> +                          uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr()) {
>     if (HasConditionalBranch(MI))
> -      return ::getBranchTargetOpValue(MI, OpIdx,
> -                                      ARM::fixup_arm_condbranch, Fixups);
> -    return ::getBranchTargetOpValue(MI, OpIdx,
> -                                    ARM::fixup_arm_uncondbranch, Fixups);
> +      return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_condbranch,
> +                                      Fixups);
> +    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbranch,
> +                                    Fixups);
>   }
> 
>   return MO.getImm() >> 2;
> @@ -611,13 +676,15 @@ getARMBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
> 
> uint32_t ARMMCCodeEmitter::
> getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                          SmallVectorImpl<MCFixup> &Fixups) const {
> +                      SmallVectorImpl<MCFixup> &Fixups,
> +                      uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr()) {
>     if (HasConditionalBranch(MI))
> -      return ::getBranchTargetOpValue(MI, OpIdx, 
> -                                      ARM::fixup_arm_condbl, Fixups);
> -    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl, Fixups);
> +      return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_condbl,
> +                                      Fixups);
> +    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_uncondbl,
> +                                    Fixups);
>   }
> 
>   return MO.getImm() >> 2;
> @@ -625,10 +692,12 @@ getARMBLTargetOpValue(const MCInst &MI, unsigned OpIdx,
> 
> uint32_t ARMMCCodeEmitter::
> getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                          SmallVectorImpl<MCFixup> &Fixups) const {
> +                       SmallVectorImpl<MCFixup> &Fixups,
> +                       uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
> -    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx, Fixups);
> +    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_blx,
> +                                    Fixups);
> 
>   return MO.getImm() >> 1;
> }
> @@ -637,12 +706,14 @@ getARMBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
> /// immediate branch target.
> uint32_t ARMMCCodeEmitter::
> getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
> -                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                    SmallVectorImpl<MCFixup> &Fixups,
> +                                    uint64_t Features) const {
>   unsigned Val = 0;
>   const MCOperand MO = MI.getOperand(OpIdx);
> 
>   if(MO.isExpr())
> -    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups);
> +    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch,
> +                                    Fixups);
>   else 
>     Val = MO.getImm() >> 1;
> 
> @@ -666,7 +737,8 @@ getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
> /// ADR label target.
> uint32_t ARMMCCodeEmitter::
> getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                   SmallVectorImpl<MCFixup> &Fixups) const {
> +                   SmallVectorImpl<MCFixup> &Fixups,
> +                   uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
>     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_adr_pcrel_12,
> @@ -706,7 +778,8 @@ getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> /// target.
> uint32_t ARMMCCodeEmitter::
> getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                   SmallVectorImpl<MCFixup> &Fixups) const {
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
>     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_adr_pcrel_12,
> @@ -725,7 +798,8 @@ getT2AdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> /// target.
> uint32_t ARMMCCodeEmitter::
> getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> -                   SmallVectorImpl<MCFixup> &Fixups) const {
> +                        SmallVectorImpl<MCFixup> &Fixups,
> +                        uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
>     return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_thumb_adr_pcrel_10,
> @@ -737,7 +811,7 @@ getThumbAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
> /// operand.
> uint32_t ARMMCCodeEmitter::
> getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
> -                              SmallVectorImpl<MCFixup> &) const {
> +                              SmallVectorImpl<MCFixup> &, uint64_t) const {
>   // [Rn, Rm]
>   //   {5-3} = Rm
>   //   {2-0} = Rn
> @@ -751,7 +825,8 @@ getThumbAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
> /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
> uint32_t ARMMCCodeEmitter::
> getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
> -                        SmallVectorImpl<MCFixup> &Fixups) const {
> +                        SmallVectorImpl<MCFixup> &Fixups,
> +                        uint64_t Features) const {
>   // {17-13} = reg
>   // {12}    = (U)nsigned (add == '1', sub == '0')
>   // {11-0}  = imm12
> @@ -802,7 +877,8 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
> /// '+/- imm8<<2' operand.
> uint32_t ARMMCCodeEmitter::
> getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
> -                   SmallVectorImpl<MCFixup> &Fixups) const {
> +                   SmallVectorImpl<MCFixup> &Fixups,
> +                   uint64_t Features) const {
>   // FIXME: The immediate operand should have already been encoded like this
>   // before ever getting here. The encoder method should just need to combine
>   // the MI operands for the register and the offset into a single
> @@ -833,7 +909,8 @@ getT2Imm8s4OpValue(const MCInst &MI, unsigned OpIdx,
> /// 'reg +/- imm8<<2' operand.
> uint32_t ARMMCCodeEmitter::
> getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
> -                        SmallVectorImpl<MCFixup> &Fixups) const {
> +                           SmallVectorImpl<MCFixup> &Fixups,
> +                           uint64_t Features) const {
>   // {12-9} = reg
>   // {8}    = (U)nsigned (add == '1', sub == '0')
>   // {7-0}  = imm8
> @@ -873,7 +950,8 @@ getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
> /// 'reg + imm8<<2' operand.
> uint32_t ARMMCCodeEmitter::
> getT2AddrModeImm0_1020s4OpValue(const MCInst &MI, unsigned OpIdx,
> -                        SmallVectorImpl<MCFixup> &Fixups) const {
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const {
>   // {11-8} = reg
>   // {7-0}  = imm8
>   const MCOperand &MO = MI.getOperand(OpIdx);
> @@ -898,7 +976,8 @@ static bool EvaluateAsPCRel(const MCExpr *Expr) {
> 
> uint32_t
> ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
> -                                      SmallVectorImpl<MCFixup> &Fixups) const {
> +                                      SmallVectorImpl<MCFixup> &Fixups,
> +                                      uint64_t Features) const {
>   // {20-16} = imm{15-12}
>   // {11-0}  = imm{11-0}
>   const MCOperand &MO = MI.getOperand(OpIdx);
> @@ -957,7 +1036,8 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
> 
> uint32_t ARMMCCodeEmitter::
> getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
> -                    SmallVectorImpl<MCFixup> &Fixups) const {
> +                    SmallVectorImpl<MCFixup> &Fixups,
> +                    uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpIdx);
>   const MCOperand &MO1 = MI.getOperand(OpIdx+1);
>   const MCOperand &MO2 = MI.getOperand(OpIdx+2);
> @@ -990,21 +1070,23 @@ getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
> 
> uint32_t ARMMCCodeEmitter::
> getAddrMode2OpValue(const MCInst &MI, unsigned OpIdx,
> -                    SmallVectorImpl<MCFixup> &Fixups) const {
> +                    SmallVectorImpl<MCFixup> &Fixups,
> +                    uint64_t Features) const {
>   // {17-14}  Rn
>   // {13}     1 == imm12, 0 == Rm
>   // {12}     isAdd
>   // {11-0}   imm12/Rm
>   const MCOperand &MO = MI.getOperand(OpIdx);
>   unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
> -  uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups);
> +  uint32_t Binary = getAddrMode2OffsetOpValue(MI, OpIdx + 1, Fixups, Features);
>   Binary |= Rn << 14;
>   return Binary;
> }
> 
> uint32_t ARMMCCodeEmitter::
> getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
> -                          SmallVectorImpl<MCFixup> &Fixups) const {
> +                          SmallVectorImpl<MCFixup> &Fixups,
> +                          uint64_t Features) const {
>   // {13}     1 == imm12, 0 == Rm
>   // {12}     isAdd
>   // {11-0}   imm12/Rm
> @@ -1026,7 +1108,8 @@ getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
> 
> uint32_t ARMMCCodeEmitter::
> getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
> -                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
>   // {4}      isAdd
>   // {3-0}    Rm
>   const MCOperand &MO = MI.getOperand(OpIdx);
> @@ -1037,7 +1120,8 @@ getPostIdxRegOpValue(const MCInst &MI, unsigned OpIdx,
> 
> uint32_t ARMMCCodeEmitter::
> getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
> -                          SmallVectorImpl<MCFixup> &Fixups) const {
> +                          SmallVectorImpl<MCFixup> &Fixups,
> +                          uint64_t Features) const {
>   // {9}      1 == imm8, 0 == Rm
>   // {8}      isAdd
>   // {7-4}    imm7_4/zero
> @@ -1056,7 +1140,8 @@ getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
> 
> uint32_t ARMMCCodeEmitter::
> getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
> -                    SmallVectorImpl<MCFixup> &Fixups) const {
> +                    SmallVectorImpl<MCFixup> &Fixups,
> +                    uint64_t Features) const {
>   // {13}     1 == imm8, 0 == Rm
>   // {12-9}   Rn
>   // {8}      isAdd
> @@ -1092,7 +1177,8 @@ getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
> /// getAddrModeThumbSPOpValue - Encode the t_addrmode_sp operands.
> uint32_t ARMMCCodeEmitter::
> getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
> -                          SmallVectorImpl<MCFixup> &Fixups) const {
> +                          SmallVectorImpl<MCFixup> &Fixups,
> +                          uint64_t Features) const {
>   // [SP, #imm]
>   //   {7-0} = imm8
>   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
> @@ -1107,7 +1193,8 @@ getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
> /// getAddrModeISOpValue - Encode the t_addrmode_is# operands.
> uint32_t ARMMCCodeEmitter::
> getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
> -                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
>   // [Rn, #imm]
>   //   {7-3} = imm5
>   //   {2-0} = Rn
> @@ -1121,17 +1208,20 @@ getAddrModeISOpValue(const MCInst &MI, unsigned OpIdx,
> /// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
> uint32_t ARMMCCodeEmitter::
> getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
> -                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
>   const MCOperand MO = MI.getOperand(OpIdx);
>   if (MO.isExpr())
> -    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp, Fixups);
> +    return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_cp,
> +                                    Fixups);
>   return (MO.getImm() >> 2);
> }
> 
> /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
> uint32_t ARMMCCodeEmitter::
> getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
> -                    SmallVectorImpl<MCFixup> &Fixups) const {
> +                    SmallVectorImpl<MCFixup> &Fixups,
> +                    uint64_t Features) const {
>   // {12-9} = reg
>   // {8}    = (U)nsigned (add == '1', sub == '0')
>   // {7-0}  = imm8
> @@ -1169,7 +1259,8 @@ getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
> 
> unsigned ARMMCCodeEmitter::
> getSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
> -                SmallVectorImpl<MCFixup> &Fixups) const {
> +                   SmallVectorImpl<MCFixup> &Fixups,
> +                   uint64_t Features) const {
>   // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg to be
>   // shifted. The second is Rs, the amount to shift by, and the third specifies
>   // the type of the shift.
> @@ -1216,7 +1307,8 @@ getSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
> 
> unsigned ARMMCCodeEmitter::
> getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
> -                SmallVectorImpl<MCFixup> &Fixups) const {
> +                   SmallVectorImpl<MCFixup> &Fixups,
> +                   uint64_t Features) const {
>   // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
>   // shifted. The second is the amount to shift by.
>   //
> @@ -1262,7 +1354,8 @@ getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
> 
> unsigned ARMMCCodeEmitter::
> getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
> -                SmallVectorImpl<MCFixup> &Fixups) const {
> +                          SmallVectorImpl<MCFixup> &Fixups,
> +                          uint64_t Features) const {
>   const MCOperand &MO1 = MI.getOperand(OpNum);
>   const MCOperand &MO2 = MI.getOperand(OpNum+1);
>   const MCOperand &MO3 = MI.getOperand(OpNum+2);
> @@ -1280,7 +1373,8 @@ getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum,
> 
> unsigned ARMMCCodeEmitter::
> getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
> -                         SmallVectorImpl<MCFixup> &Fixups) const {
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t Features) const {
>   const MCOperand &MO1 = MI.getOperand(OpNum);
>   const MCOperand &MO2 = MI.getOperand(OpNum+1);
> 
> @@ -1301,7 +1395,8 @@ getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum,
> 
> unsigned ARMMCCodeEmitter::
> getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
> -                         SmallVectorImpl<MCFixup> &Fixups) const {
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const {
>   const MCOperand &MO1 = MI.getOperand(OpNum);
> 
>   // FIXME: Needs fixup support.
> @@ -1317,7 +1412,8 @@ getT2AddrModeImm8OffsetOpValue(const MCInst &MI, unsigned OpNum,
> 
> unsigned ARMMCCodeEmitter::
> getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
> -                         SmallVectorImpl<MCFixup> &Fixups) const {
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const {
>   const MCOperand &MO1 = MI.getOperand(OpNum);
> 
>   // FIXME: Needs fixup support.
> @@ -1333,7 +1429,8 @@ getT2AddrModeImm12OffsetOpValue(const MCInst &MI, unsigned OpNum,
> 
> unsigned ARMMCCodeEmitter::
> getT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
> -                SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
>   // Sub-operands are [reg, imm]. The first register is Rm, the reg to be
>   // shifted. The second is the amount to shift by.
>   //
> @@ -1375,7 +1472,8 @@ getT2SORegOpValue(const MCInst &MI, unsigned OpIdx,
> 
> unsigned ARMMCCodeEmitter::
> getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
> -                               SmallVectorImpl<MCFixup> &Fixups) const {
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const {
>   // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the
>   // msb of the mask.
>   const MCOperand &MO = MI.getOperand(Op);
> @@ -1388,7 +1486,8 @@ getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
> 
> unsigned ARMMCCodeEmitter::
> getRegisterListOpValue(const MCInst &MI, unsigned Op,
> -                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                       SmallVectorImpl<MCFixup> &Fixups,
> +                       uint64_t Features) const {
>   // VLDM/VSTM:
>   //   {12-8} = Vd
>   //   {7-0}  = Number of registers
> @@ -1424,7 +1523,8 @@ getRegisterListOpValue(const MCInst &MI, unsigned Op,
> /// with the alignment operand.
> unsigned ARMMCCodeEmitter::
> getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
> -                           SmallVectorImpl<MCFixup> &Fixups) const {
> +                           SmallVectorImpl<MCFixup> &Fixups,
> +                           uint64_t Features) const {
>   const MCOperand &Reg = MI.getOperand(Op);
>   const MCOperand &Imm = MI.getOperand(Op + 1);
> 
> @@ -1447,7 +1547,8 @@ getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
> /// along  with the alignment operand for use in VST1 and VLD1 with size 32.
> unsigned ARMMCCodeEmitter::
> getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
> -                                    SmallVectorImpl<MCFixup> &Fixups) const {
> +                                    SmallVectorImpl<MCFixup> &Fixups,
> +                                    uint64_t Features) const {
>   const MCOperand &Reg = MI.getOperand(Op);
>   const MCOperand &Imm = MI.getOperand(Op + 1);
> 
> @@ -1473,7 +1574,8 @@ getAddrMode6OneLane32AddressOpValue(const MCInst &MI, unsigned Op,
> /// different for VLD4-dup.
> unsigned ARMMCCodeEmitter::
> getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
> -                              SmallVectorImpl<MCFixup> &Fixups) const {
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const {
>   const MCOperand &Reg = MI.getOperand(Op);
>   const MCOperand &Imm = MI.getOperand(Op + 1);
> 
> @@ -1493,7 +1595,8 @@ getAddrMode6DupAddressOpValue(const MCInst &MI, unsigned Op,
> 
> unsigned ARMMCCodeEmitter::
> getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
> -                          SmallVectorImpl<MCFixup> &Fixups) const {
> +                          SmallVectorImpl<MCFixup> &Fixups,
> +                          uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(Op);
>   if (MO.getReg() == 0) return 0x0D;
>   return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
> @@ -1501,25 +1604,29 @@ getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
> 
> unsigned ARMMCCodeEmitter::
> getShiftRight8Imm(const MCInst &MI, unsigned Op,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
>   return 8 - MI.getOperand(Op).getImm();
> }
> 
> unsigned ARMMCCodeEmitter::
> getShiftRight16Imm(const MCInst &MI, unsigned Op,
> -                   SmallVectorImpl<MCFixup> &Fixups) const {
> +                   SmallVectorImpl<MCFixup> &Fixups,
> +                   uint64_t Features) const {
>   return 16 - MI.getOperand(Op).getImm();
> }
> 
> unsigned ARMMCCodeEmitter::
> getShiftRight32Imm(const MCInst &MI, unsigned Op,
> -                   SmallVectorImpl<MCFixup> &Fixups) const {
> +                   SmallVectorImpl<MCFixup> &Fixups,
> +                   uint64_t Features) const {
>   return 32 - MI.getOperand(Op).getImm();
> }
> 
> unsigned ARMMCCodeEmitter::
> getShiftRight64Imm(const MCInst &MI, unsigned Op,
> -                   SmallVectorImpl<MCFixup> &Fixups) const {
> +                   SmallVectorImpl<MCFixup> &Fixups,
> +                   uint64_t Features) const {
>   return 64 - MI.getOperand(Op).getImm();
> }
> 
> @@ -1539,7 +1646,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>   else
>     llvm_unreachable("Unexpected instruction size!");
> 
> -  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
> +  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
>   // Thumb 32-bit wide instructions need to emit the high order halfword
>   // first.
>   if (isThumb() && Size == 4) {
> diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
> index 9186ca6..8d5188f 100644
> --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
> +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
> @@ -77,55 +77,68 @@ public:
>   // getBinaryCodeForInstr - TableGen'erated function for getting the
>   // binary encoding for an instruction.
>   uint64_t getBinaryCodeForInstr(const MCInst &MI,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
> 
>   // getBranchJumpOpValue - Return binary encoding of the jump
>   // target operand. If the machine operand requires relocation,
>   // record the relocation and return zero.
>   unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
> -                                SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
> 
>   // getBranchJumpOpValueMM - Return binary encoding of the microMIPS jump
>   // target operand. If the machine operand requires relocation,
>   // record the relocation and return zero.
>   unsigned getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
> -                                  SmallVectorImpl<MCFixup> &Fixups) const;
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features) const;
> 
>    // getBranchTargetOpValue - Return binary encoding of the branch
>    // target operand. If the machine operand requires relocation,
>    // record the relocation and return zero.
>   unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
> -                                  SmallVectorImpl<MCFixup> &Fixups) const;
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features) const;
> 
>   // getBranchTargetOpValue - Return binary encoding of the microMIPS branch
>   // target operand. If the machine operand requires relocation,
>   // record the relocation and return zero.
>   unsigned getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
> -                                    SmallVectorImpl<MCFixup> &Fixups) const;
> +                                    SmallVectorImpl<MCFixup> &Fixups,
> +                                    uint64_t Features) const;
> 
>    // getMachineOpValue - Return binary encoding of operand. If the machin
>    // operand requires relocation, record the relocation and return zero.
>   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   unsigned getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   unsigned getMemEncoding(const MCInst &MI, unsigned OpNo,
> -                          SmallVectorImpl<MCFixup> &Fixups) const;
> +                          SmallVectorImpl<MCFixup> &Fixups,
> +                          uint64_t Features) const;
>   unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
>   unsigned getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
>   unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
> 
>   // getLSAImmEncoding - Return binary encoding of LSA immediate.
>   unsigned getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   unsigned
> -  getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const;
> +  getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups,
> +                 uint64_t Features) const;
> 
> }; // class MipsMCCodeEmitter
> }  // namespace
> @@ -240,7 +253,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>   }
> 
>   unsigned long N = Fixups.size();
> -  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups);
> +  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, AvailableFeatures);
> 
>   // Check for unimplemented opcodes.
>   // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
> @@ -256,7 +269,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>         Fixups.pop_back();
>       Opcode = NewOpcode;
>       TmpInst.setOpcode (NewOpcode);
> -      Binary = getBinaryCodeForInstr(TmpInst, Fixups);
> +      Binary = getBinaryCodeForInstr(TmpInst, Fixups, AvailableFeatures);
>     }
>   }
> 
> @@ -275,7 +288,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> /// record the relocation and return zero.
> unsigned MipsMCCodeEmitter::
> getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
> -                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                       SmallVectorImpl<MCFixup> &Fixups,
> +                       uint64_t Features) const {
> 
>   const MCOperand &MO = MI.getOperand(OpNo);
> 
> @@ -296,7 +310,8 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
> /// record the relocation and return zero.
> unsigned MipsMCCodeEmitter::
> getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
> -                         SmallVectorImpl<MCFixup> &Fixups) const {
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t Features) const {
> 
>   const MCOperand &MO = MI.getOperand(OpNo);
> 
> @@ -318,7 +333,8 @@ getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
> /// record the relocation and return zero.
> unsigned MipsMCCodeEmitter::
> getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
> -                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
> 
>   const MCOperand &MO = MI.getOperand(OpNo);
>   // If the destination is an immediate, divide by 4.
> @@ -335,7 +351,8 @@ getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
> 
> unsigned MipsMCCodeEmitter::
> getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
> -                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                       SmallVectorImpl<MCFixup> &Fixups,
> +                       uint64_t Features) const {
> 
>   const MCOperand &MO = MI.getOperand(OpNo);
>   // If the destination is an immediate, divide by 2.
> @@ -351,7 +368,8 @@ getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
> }
> 
> unsigned MipsMCCodeEmitter::
> -getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const {
> +getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups,
> +               uint64_t Features) const {
>   int64_t Res;
> 
>   if (Expr->EvaluateAsAbsolute(Res))
> @@ -363,8 +381,9 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const {
>   }
> 
>   if (Kind == MCExpr::Binary) {
> -    unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups);
> -    Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups);
> +    unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(),
> +                                  Fixups, Features);
> +    Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, Features);
>     return Res;
>   }
>   if (Kind == MCExpr::SymbolRef) {
> @@ -471,7 +490,8 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const {
> /// operand requires relocation, record the relocation and return zero.
> unsigned MipsMCCodeEmitter::
> getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
>   if (MO.isReg()) {
>     unsigned Reg = MO.getReg();
>     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
> @@ -484,18 +504,21 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
>   }
>   // MO must be an Expr.
>   assert(MO.isExpr());
> -  return getExprOpValue(MO.getExpr(),Fixups);
> +  return getExprOpValue(MO.getExpr(), Fixups, Features);
> }
> 
> /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST
> /// instructions.
> unsigned
> MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const {
>   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
>   assert(MI.getOperand(OpNo).isReg());
> -  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups) << 16;
> -  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
> +  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
> +                                       Fixups, Features) << 16;
> +  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
> +                                       Fixups, Features);
> 
>   // The immediate field of an LD/ST instruction is scaled which means it must
>   // be divided (when encoding) by the size (in bytes) of the instructions'
> @@ -534,31 +557,39 @@ MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
> /// If the offset operand requires relocation, record the relocation.
> unsigned
> MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
> -                                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features) const {
>   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
>   assert(MI.getOperand(OpNo).isReg());
> -  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups) << 16;
> -  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
> +  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
> +                                       Fixups, Features) << 16;
> +  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
> +                                       Fixups, Features);
> 
>   return (OffBits & 0xFFFF) | RegBits;
> }
> 
> unsigned MipsMCCodeEmitter::
> getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
> -                      SmallVectorImpl<MCFixup> &Fixups) const {
> +                      SmallVectorImpl<MCFixup> &Fixups,
> +                      uint64_t Features) const {
>   // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
>   assert(MI.getOperand(OpNo).isReg());
> -  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) << 16;
> -  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
> +  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
> +                                       Fixups, Features) << 16;
> +  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
> +                                       Fixups, Features);
> 
>   return (OffBits & 0x0FFF) | RegBits;
> }
> 
> unsigned
> MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
> -                                      SmallVectorImpl<MCFixup> &Fixups) const {
> +                                      SmallVectorImpl<MCFixup> &Fixups,
> +                                      uint64_t Features) const {
>   assert(MI.getOperand(OpNo).isImm());
> -  unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
> +  unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo),
> +                                            Fixups, Features);
>   return SizeEncoding - 1;
> }
> 
> @@ -566,21 +597,24 @@ MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
> //
> unsigned
> MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
> -                                      SmallVectorImpl<MCFixup> &Fixups) const {
> +                                      SmallVectorImpl<MCFixup> &Fixups,
> +                                      uint64_t Features) const {
>   assert(MI.getOperand(OpNo-1).isImm());
>   assert(MI.getOperand(OpNo).isImm());
> -  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups);
> -  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
> +  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1),
> +                                        Fixups, Features);
> +  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, Features);
> 
>   return Position + Size - 1;
> }
> 
> unsigned
> MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const {
>   assert(MI.getOperand(OpNo).isImm());
>   // The immediate is encoded as 'immediate - 1'.
> -  return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) - 1;
> +  return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, Features) - 1;
> }
> 
> #include "MipsGenMCCodeEmitter.inc"
> diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
> index 3f0a944..51c9dc7 100644
> --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
> +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
> @@ -46,35 +46,47 @@ public:
>   ~PPCMCCodeEmitter() {}
> 
>   unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
>   unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
> -                                  SmallVectorImpl<MCFixup> &Fixups) const;
> +                                  SmallVectorImpl<MCFixup> &Fixups,
> +                                  uint64_t Features) const;
>   unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
> -                                SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
>   unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo,
> -                            SmallVectorImpl<MCFixup> &Fixups) const;
> +                            SmallVectorImpl<MCFixup> &Fixups,
> +                            uint64_t Features) const;
>   unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
> -                              SmallVectorImpl<MCFixup> &Fixups) const;
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const;
>   unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
> 
>   /// getMachineOpValue - Return binary encoding of operand. If the machine
>   /// operand requires relocation, record the relocation and return zero.
>   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   // getBinaryCodeForInstr - TableGen'erated function for getting the
>   // binary encoding for an instruction.
>   uint64_t getBinaryCodeForInstr(const MCInst &MI,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>                          SmallVectorImpl<MCFixup> &Fixups,
>                          uint64_t AvailableFeatures) const {
> @@ -85,7 +97,7 @@ public:
>     if (Opcode == TargetOpcode::COPY_TO_REGCLASS)
>       return;
> 
> -    uint64_t Bits = getBinaryCodeForInstr(MI, Fixups);
> +    uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
> 
>     // BL8_NOP etc. all have a size of 8 because of the following 'nop'.
>     unsigned Size = 4; // FIXME: Have Desc.getSize() return the correct value!
> @@ -116,9 +128,11 @@ MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII,
> 
> unsigned PPCMCCodeEmitter::
> getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
> -                    SmallVectorImpl<MCFixup> &Fixups) const {
> +                    SmallVectorImpl<MCFixup> &Fixups,
> +                    uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
> -  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
> +  if (MO.isReg() || MO.isImm())
> +    return getMachineOpValue(MI, MO, Fixups, Features);
> 
>   // Add a fixup for the branch target.
>   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
> @@ -127,9 +141,11 @@ getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
> }
> 
> unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                                             SmallVectorImpl<MCFixup> &Fixups,
> +                                             uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
> -  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
> +  if (MO.isReg() || MO.isImm())
> +    return getMachineOpValue(MI, MO, Fixups, Features);
> 
>   // Add a fixup for the branch target.
>   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
> @@ -139,9 +155,11 @@ unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
> 
> unsigned PPCMCCodeEmitter::
> getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
> -                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                       SmallVectorImpl<MCFixup> &Fixups,
> +                       uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
> -  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
> +  if (MO.isReg() || MO.isImm())
> +    return getMachineOpValue(MI, MO, Fixups, Features);
> 
>   // Add a fixup for the branch target.
>   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
> @@ -151,9 +169,11 @@ getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
> 
> unsigned PPCMCCodeEmitter::
> getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
> -                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
> -  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
> +  if (MO.isReg() || MO.isImm())
> +    return getMachineOpValue(MI, MO, Fixups, Features);
> 
>   // Add a fixup for the branch target.
>   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
> @@ -162,9 +182,11 @@ getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
> }
> 
> unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                            SmallVectorImpl<MCFixup> &Fixups,
> +                                            uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
> -  if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
> +  if (MO.isReg() || MO.isImm())
> +    return getMachineOpValue(MI, MO, Fixups, Features);
> 
>   // Add a fixup for the immediate field.
>   Fixups.push_back(MCFixup::Create(2, MO.getExpr(),
> @@ -173,15 +195,17 @@ unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
> }
> 
> unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
> -                                            SmallVectorImpl<MCFixup> &Fixups) const {
> +                                            SmallVectorImpl<MCFixup> &Fixups,
> +                                            uint64_t Features) const {
>   // Encode (imm, reg) as a memri, which has the low 16-bits as the
>   // displacement and the next 5 bits as the register #.
>   assert(MI.getOperand(OpNo+1).isReg());
> -  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 16;
> +  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
> +                                       Fixups, Features) << 16;
> 
>   const MCOperand &MO = MI.getOperand(OpNo);
>   if (MO.isImm())
> -    return (getMachineOpValue(MI, MO, Fixups) & 0xFFFF) | RegBits;
> +    return (getMachineOpValue(MI, MO, Fixups, Features) & 0xFFFF) | RegBits;
> 
>   // Add a fixup for the displacement field.
>   Fixups.push_back(MCFixup::Create(2, MO.getExpr(),
> @@ -191,15 +215,18 @@ unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
> 
> 
> unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                             SmallVectorImpl<MCFixup> &Fixups,
> +                                             uint64_t Features) const {
>   // Encode (imm, reg) as a memrix, which has the low 14-bits as the
>   // displacement and the next 5 bits as the register #.
>   assert(MI.getOperand(OpNo+1).isReg());
> -  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups) << 14;
> +  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
> +                                       Fixups, Features) << 14;
> 
>   const MCOperand &MO = MI.getOperand(OpNo);
>   if (MO.isImm())
> -    return ((getMachineOpValue(MI, MO, Fixups) >> 2) & 0x3FFF) | RegBits;
> +    return ((getMachineOpValue(MI, MO, Fixups, Features) >> 2) & 0x3FFF) |
> +           RegBits;
> 
>   // Add a fixup for the displacement field.
>   Fixups.push_back(MCFixup::Create(2, MO.getExpr(),
> @@ -209,9 +236,10 @@ unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
> 
> 
> unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                       SmallVectorImpl<MCFixup> &Fixups,
> +                                       uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
> -  if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups);
> +  if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, Features);
> 
>   // Add a fixup for the TLS register, which simply provides a relocation
>   // hint to the linker that this statement is part of a relocation sequence.
> @@ -223,19 +251,20 @@ unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
> }
> 
> unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                       SmallVectorImpl<MCFixup> &Fixups,
> +                                       uint64_t Features) const {
>   // For special TLS calls, we need two fixups; one for the branch target
>   // (__tls_get_addr), which we create via getDirectBrEncoding as usual,
>   // and one for the TLSGD or TLSLD symbol, which is emitted here.
>   const MCOperand &MO = MI.getOperand(OpNo+1);
>   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
>                                    (MCFixupKind)PPC::fixup_ppc_nofixup));
> -  return getDirectBrEncoding(MI, OpNo, Fixups);
> +  return getDirectBrEncoding(MI, OpNo, Fixups, Features);
> }
> 
> unsigned PPCMCCodeEmitter::
> get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
> -                    SmallVectorImpl<MCFixup> &Fixups) const {
> +                    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
>   assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
>           MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
> @@ -246,7 +275,8 @@ get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
> 
> unsigned PPCMCCodeEmitter::
> getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
>   if (MO.isReg()) {
>     // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
>     // The GPR operand should come through here though.
> diff --git a/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h b/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h
> index d8cf64a..48e5fa0 100644
> --- a/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h
> +++ b/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h
> @@ -28,10 +28,12 @@ class AMDGPUMCCodeEmitter : public MCCodeEmitter {
> public:
> 
>   uint64_t getBinaryCodeForInstr(const MCInst &MI,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
> 
>   virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const {
>     return 0;
>   }
> };
> diff --git a/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp b/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
> index 873d3ab..f327fd9 100644
> --- a/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
> +++ b/lib/Target/R600/MCTargetDesc/R600MCCodeEmitter.cpp
> @@ -49,7 +49,8 @@ public:
> 
>   /// \returns the encoding for an MCOperand.
>   virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const;
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const;
> private:
> 
>   void EmitByte(unsigned int byte, raw_ostream &OS) const;
> @@ -98,7 +99,7 @@ void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>     MI.getOpcode() == AMDGPU::KILL) {
>     return;
>   } else if (IS_VTX(Desc)) {
> -    uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups);
> +    uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
>     uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
>     if (!(STI.getFeatureBits() & AMDGPU::FeatureCaymanISA)) {
>       InstWord2 |= 1 << 19; // Mega-Fetch bit
> @@ -122,7 +123,7 @@ void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>         MI.getOperand(8).getImm() & 0x1F
>       };
> 
> -      uint64_t Word01 = getBinaryCodeForInstr(MI, Fixups);
> +      uint64_t Word01 = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
>       uint32_t Word2 = Sampler << 15 | SrcSelect[ELEMENT_X] << 20 |
>           SrcSelect[ELEMENT_Y] << 23 | SrcSelect[ELEMENT_Z] << 26 |
>           SrcSelect[ELEMENT_W] << 29 | Offsets[0] << 0 | Offsets[1] << 5 |
> @@ -132,7 +133,7 @@ void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>       Emit(Word2, OS);
>       Emit((uint32_t) 0, OS);
>   } else {
> -    uint64_t Inst = getBinaryCodeForInstr(MI, Fixups);
> +    uint64_t Inst = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
>     if ((STI.getFeatureBits() & AMDGPU::FeatureR600ALUInst) &&
>        ((Desc.TSFlags & R600_InstFlag::OP1) ||
>          Desc.TSFlags & R600_InstFlag::OP2)) {
> @@ -170,7 +171,8 @@ unsigned R600MCCodeEmitter::getHWReg(unsigned RegNo) const {
> 
> uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
>                                               const MCOperand &MO,
> -                                        SmallVectorImpl<MCFixup> &Fixup) const {
> +                                              SmallVectorImpl<MCFixup> &Fixup,
> +                                              uint64_t Features) const {
>   if (MO.isReg()) {
>     if (HAS_NATIVE_OPERANDS(MCII.get(MI.getOpcode()).TSFlags)) {
>       return MRI.getEncodingValue(MO.getReg());
> diff --git a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> index b08f8eb..6054dac 100644
> --- a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> +++ b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> @@ -60,7 +60,8 @@ public:
> 
>   /// \returns the encoding for an MCOperand.
>   virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                                     SmallVectorImpl<MCFixup> &Fixups) const;
> +                                     SmallVectorImpl<MCFixup> &Fixups,
> +                                     uint64_t Features) const;
> };
> 
> } // End anonymous namespace
> @@ -129,7 +130,7 @@ void SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>                                         SmallVectorImpl<MCFixup> &Fixups,
>                                         uint64_t AvailableFeatures) const {
> 
> -  uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups);
> +  uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
>   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
>   unsigned bytes = Desc.getSize();
> 
> @@ -170,7 +171,8 @@ void SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> 
> uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI,
>                                             const MCOperand &MO,
> -                                       SmallVectorImpl<MCFixup> &Fixups) const {
> +                                            SmallVectorImpl<MCFixup> &Fixups,
> +                                            uint64_t Features) const {
>   if (MO.isReg())
>     return MRI.getEncodingValue(MO.getReg());
> 
> diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
> index f6924b9..5481496 100644
> --- a/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
> +++ b/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
> @@ -45,17 +45,21 @@ public:
>   // getBinaryCodeForInstr - TableGen'erated function for getting the
>   // binary encoding for an instruction.
>   uint64_t getBinaryCodeForInstr(const MCInst &MI,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
> 
>   /// getMachineOpValue - Return binary encoding of operand. If the machine
>   /// operand requires relocation, record the relocation and return zero.
>   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
>   unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
> };
> } // end anonymous namespace
> @@ -71,7 +75,7 @@ void SparcMCCodeEmitter::
> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>                   SmallVectorImpl<MCFixup> &Fixups,
>                   uint64_t AvailableFeatures) const {
> -  unsigned Bits = getBinaryCodeForInstr(MI, Fixups);
> +  unsigned Bits = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
> 
>   // Output the constant in big endian byte order.
>   for (unsigned i = 0; i != 4; ++i) {
> @@ -85,7 +89,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> 
> unsigned SparcMCCodeEmitter::
> getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
> 
>   if (MO.isReg())
>     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
> @@ -140,10 +145,11 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> 
> unsigned SparcMCCodeEmitter::
> getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
> -                     SmallVectorImpl<MCFixup> &Fixups) const {
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
>   if (MO.isReg() || MO.isImm())
> -    return getMachineOpValue(MI, MO, Fixups);
> +    return getMachineOpValue(MI, MO, Fixups, Features);
> 
>   Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
>                                    (MCFixupKind)Sparc::fixup_sparc_call30));
> @@ -152,10 +158,11 @@ getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
> 
> unsigned SparcMCCodeEmitter::
> getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
>   const MCOperand &MO = MI.getOperand(OpNo);
>   if (MO.isReg() || MO.isImm())
> -    return getMachineOpValue(MI, MO, Fixups);
> +    return getMachineOpValue(MI, MO, Fixups, Features);
> 
>   Sparc::Fixups fixup = Sparc::fixup_sparc_br22;
>   if (MI.getOpcode() == SP::BPXCC)
> diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
> index 2bbf36d..33f3840 100644
> --- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
> +++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
> @@ -42,27 +42,34 @@ public:
> private:
>   // Automatically generated by TableGen.
>   uint64_t getBinaryCodeForInstr(const MCInst &MI,
> -                                 SmallVectorImpl<MCFixup> &Fixups) const;
> +                                 SmallVectorImpl<MCFixup> &Fixups,
> +                                 uint64_t Features) const;
> 
>   // Called by the TableGen code to get the binary encoding of operand
>   // MO in MI.  Fixups is the list of fixups against MI.
>   uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                             SmallVectorImpl<MCFixup> &Fixups) const;
> +                             SmallVectorImpl<MCFixup> &Fixups,
> +                             uint64_t Features) const;
> 
>   // Called by the TableGen code to get the binary encoding of an address.
>   // The index or length, if any, is encoded first, followed by the base,
>   // followed by the displacement.  In a 20-bit displacement,
>   // the low 12 bits are encoded before the high 8 bits.
>   uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
>   uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
> -                               SmallVectorImpl<MCFixup> &Fixups) const;
> +                               SmallVectorImpl<MCFixup> &Fixups,
> +                               uint64_t Features) const;
>   uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
> -                                SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
>   uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
> -                                SmallVectorImpl<MCFixup> &Fixups) const;
> +                                SmallVectorImpl<MCFixup> &Fixups,
> +                                uint64_t Features) const;
>   uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
> -                                    SmallVectorImpl<MCFixup> &Fixups) const;
> +                                    SmallVectorImpl<MCFixup> &Fixups,
> +                                    uint64_t Features) const;
> 
>   // Operand OpNum of MI needs a PC-relative fixup of kind Kind at
>   // Offset bytes from the start of MI.  Add the fixup to Fixups
> @@ -73,11 +80,13 @@ private:
>                             unsigned Kind, int64_t Offset) const;
> 
>   uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
> -                              SmallVectorImpl<MCFixup> &Fixups) const {
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const {
>     return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC16DBL, 2);
>   }
>   uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
> -                              SmallVectorImpl<MCFixup> &Fixups) const {
> +                              SmallVectorImpl<MCFixup> &Fixups,
> +                              uint64_t Features) const {
>     return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC32DBL, 2);
>   }
> };
> @@ -94,7 +103,7 @@ void SystemZMCCodeEmitter::
> EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>                   SmallVectorImpl<MCFixup> &Fixups,
>                   uint64_t AvailableFeatures) const {
> -  uint64_t Bits = getBinaryCodeForInstr(MI, Fixups);
> +  uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
>   unsigned Size = MCII.get(MI.getOpcode()).getSize();
>   // Big-endian insertion of Size bytes.
>   unsigned ShiftValue = (Size * 8) - 8;
> @@ -106,7 +115,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> 
> uint64_t SystemZMCCodeEmitter::
> getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> -                  SmallVectorImpl<MCFixup> &Fixups) const {
> +                  SmallVectorImpl<MCFixup> &Fixups,
> +                  uint64_t Features) const {
>   if (MO.isReg())
>     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
>   if (MO.isImm())
> @@ -116,38 +126,52 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
> 
> uint64_t SystemZMCCodeEmitter::
> getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
> -                    SmallVectorImpl<MCFixup> &Fixups) const {
> -  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
> -  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
> +                    SmallVectorImpl<MCFixup> &Fixups,
> +                    uint64_t Features) const {
> +  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum),
> +                                    Fixups, Features);
> +  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1),
> +                                    Fixups, Features);
>   assert(isUInt<4>(Base) && isUInt<12>(Disp));
>   return (Base << 12) | Disp;
> }
> 
> uint64_t SystemZMCCodeEmitter::
> getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
> -                    SmallVectorImpl<MCFixup> &Fixups) const {
> -  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
> -  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
> +                    SmallVectorImpl<MCFixup> &Fixups,
> +                    uint64_t Features) const {
> +  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum),
> +                                    Fixups, Features);
> +  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1),
> +                                    Fixups, Features);
>   assert(isUInt<4>(Base) && isInt<20>(Disp));
>   return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12);
> }
> 
> uint64_t SystemZMCCodeEmitter::
> getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
> -                     SmallVectorImpl<MCFixup> &Fixups) const {
> -  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
> -  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
> -  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups);
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
> +  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum),
> +                                    Fixups, Features);
> +  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1),
> +                                    Fixups, Features);
> +  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2),
> +                                     Fixups, Features);
>   assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index));
>   return (Index << 16) | (Base << 12) | Disp;
> }
> 
> uint64_t SystemZMCCodeEmitter::
> getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
> -                     SmallVectorImpl<MCFixup> &Fixups) const {
> -  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
> -  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
> -  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups);
> +                     SmallVectorImpl<MCFixup> &Fixups,
> +                     uint64_t Features) const {
> +  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum),
> +                                    Fixups, Features);
> +  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1),
> +                                    Fixups, Features);
> +  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2),
> +                                     Fixups, Features);
>   assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index));
>   return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8)
>     | ((Disp & 0xff000) >> 12);
> @@ -155,10 +179,14 @@ getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
> 
> uint64_t SystemZMCCodeEmitter::
> getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
> -                         SmallVectorImpl<MCFixup> &Fixups) const {
> -  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
> -  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
> -  uint64_t Len  = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups) - 1;
> +                         SmallVectorImpl<MCFixup> &Fixups,
> +                         uint64_t Features) const {
> +  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum),
> +                                    Fixups, Features);
> +  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1),
> +                                    Fixups, Features);
> +  uint64_t Len  = getMachineOpValue(MI, MI.getOperand(OpNum + 2),
> +                                    Fixups, Features) - 1;
>   assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len));
>   return (Len << 16) | (Base << 12) | Disp;
> }
> diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
> index b7dea10..aec845f 100644
> --- a/utils/TableGen/CodeEmitterGen.cpp
> +++ b/utils/TableGen/CodeEmitterGen.cpp
> @@ -122,14 +122,14 @@ AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
>       Case += "      // op: " + VarName + "\n" +
>               "      op = " + EncoderMethodName + "(MI, " + utostr(OpIdx);
>       if (MCEmitter)
> -        Case += ", Fixups";
> +        Case += ", Fixups, Features";
>       Case += ");\n";
>     }
>   } else {
>     Case += "      // op: " + VarName + "\n" +
>       "      op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
>     if (MCEmitter)
> -      Case += ", Fixups";
> +      Case += ", Fixups, Features";
>     Case += ");\n";
>   }
> 
> @@ -192,8 +192,12 @@ std::string CodeEmitterGen::getInstructionCase(Record *R,
>   }
> 
>   std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
> -  if (!PostEmitter.empty())
> -    Case += "      Value = " + PostEmitter + "(MI, Value);\n";
> +  if (!PostEmitter.empty()) {
> +    Case += "      Value = " + PostEmitter + "(MI, Value";
> +    if (MCEmitter)
> +      Case += ", Features";
> +    Case += ");\n";
> +  }
> 
>   return Case;
> }
> @@ -212,7 +216,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
>   o << "uint64_t " << Target.getName();
>   if (MCEmitter)
>     o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
> -      << "    SmallVectorImpl<MCFixup> &Fixups) const {\n";
> +      << "    SmallVectorImpl<MCFixup> &Fixups, uint64_t Features) const {\n";
>   else
>     o << "CodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {\n";
> 
> -- 
> 1.8.4.2
> 
> From 00709f3b60b950446aeb5e2ae24ff006adf7ae89 Mon Sep 17 00:00:00 2001
> From: David Woodhouse <David.Woodhouse at intel.com>
> Date: Mon, 6 Jan 2014 01:20:22 +0000
> Subject: [PATCH 3/4] [x86] Fix PR18303 by using appropriate Feature bits for
> is64BitMode() etc.
> 
> This requires that we first allow the flags to propagate from our
> EncodeInstruction method down to where they're needed...
> ---
> lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 81 +++++++++++++-----------
> test/MC/X86/fixup-cpu-mode.s                     |  8 +++
> 2 files changed, 51 insertions(+), 38 deletions(-)
> create mode 100644 test/MC/X86/fixup-cpu-mode.s
> 
> diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> index 6b6e189..3e5b728 100644
> --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> @@ -42,29 +42,26 @@ public:
> 
>   ~X86MCCodeEmitter() {}
> 
> -  bool is64BitMode() const {
> -    // FIXME: Can tablegen auto-generate this?
> -    return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
> +  bool is64BitMode(uint64_t Features) const {
> +    return (Features & X86::Mode64Bit) != 0;
>   }
> 
> -  bool is32BitMode() const {
> -    // FIXME: Can tablegen auto-generate this?
> -    return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
> +  bool is32BitMode(uint64_t Features) const {
> +    return (Features & X86::Mode32Bit) != 0;
>   }
> 
> -  bool is16BitMode() const {
> -    // FIXME: Can tablegen auto-generate this?
> -    return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
> +  bool is16BitMode(uint64_t Features) const {
> +    return (Features & X86::Mode16Bit) != 0;
>   }
> 
>   /// Is16BitMemOperand - Return true if the specified instruction has
>   /// a 16-bit memory operand. Op specifies the operand # of the memoperand.
> -  bool Is16BitMemOperand(const MCInst &MI, unsigned Op) const {
> +  bool Is16BitMemOperand(const MCInst &MI, unsigned Op, uint64_t Features) const {
>     const MCOperand &BaseReg  = MI.getOperand(Op+X86::AddrBaseReg);
>     const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
>     const MCOperand &Disp     = MI.getOperand(Op+X86::AddrDisp);
> 
> -    if (is16BitMode() && BaseReg.getReg() == 0 &&
> +    if (is16BitMode(Features) && BaseReg.getReg() == 0 &&
>         Disp.isImm() && Disp.getImm() < 0x10000)
>       return true;
>     if ((BaseReg.getReg() != 0 &&
> @@ -149,7 +146,12 @@ public:
>   void EmitMemModRMByte(const MCInst &MI, unsigned Op,
>                         unsigned RegOpcodeField,
>                         uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS,
> -                        SmallVectorImpl<MCFixup> &Fixups) const;
> +                        SmallVectorImpl<MCFixup> &Fixups,
> +                        uint64_t Features) const;
> +
> +  uint64_t getAvailableFeatures() const {
> +    return STI.getFeatureBits();
> +  }
> 
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>                          SmallVectorImpl<MCFixup> &Fixups,
> @@ -165,7 +167,7 @@ public:
> 
>   void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
>                         const MCInst &MI, const MCInstrDesc &Desc,
> -                        raw_ostream &OS) const;
> +                        raw_ostream &OS, uint64_t Features) const;
> };
> 
> } // end anonymous namespace
> @@ -376,7 +378,8 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
>                                         unsigned RegOpcodeField,
>                                         uint64_t TSFlags, unsigned &CurByte,
>                                         raw_ostream &OS,
> -                                        SmallVectorImpl<MCFixup> &Fixups) const{
> +                                        SmallVectorImpl<MCFixup> &Fixups,
> +                                        uint64_t Features) const{
>   const MCOperand &Disp     = MI.getOperand(Op+X86::AddrDisp);
>   const MCOperand &Base     = MI.getOperand(Op+X86::AddrBaseReg);
>   const MCOperand &Scale    = MI.getOperand(Op+X86::AddrScaleAmt);
> @@ -386,7 +389,8 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
> 
>   // Handle %rip relative addressing.
>   if (BaseReg == X86::RIP) {    // [disp32+RIP] in X86-64 mode
> -    assert(is64BitMode() && "Rip-relative addressing requires 64-bit mode");
> +    assert(is64BitMode(Features) &&
> +           "Rip-relative addressing requires 64-bit mode");
>     assert(IndexReg.getReg() == 0 && "Invalid rip-relative address");
>     EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
> 
> @@ -414,7 +418,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
> 
>   // 16-bit addressing forms of the ModR/M byte have a different encoding for
>   // the R/M field and are far more limited in which registers can be used.
> -  if (Is16BitMemOperand(MI, Op)) {
> +  if (Is16BitMemOperand(MI, Op, Features)) {
>     if (BaseReg) {
>       // For 32-bit addressing, the row and column values in Table 2-2 are
>       // basically the same. It's AX/CX/DX/BX/SP/BP/SI/DI in that order, with
> @@ -485,7 +489,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
>       BaseRegNo != N86::ESP &&
>       // If there is no base register and we're in 64-bit mode, we need a SIB
>       // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
> -      (!is64BitMode() || BaseReg != 0)) {
> +      (!is64BitMode(Features) || BaseReg != 0)) {
> 
>     if (BaseReg == 0) {          // [disp32]     in X86-32 mode
>       EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
> @@ -1151,7 +1155,8 @@ void X86MCCodeEmitter::EmitSegmentOverridePrefix(uint64_t TSFlags,
> void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
>                                         int MemOperand, const MCInst &MI,
>                                         const MCInstrDesc &Desc,
> -                                        raw_ostream &OS) const {
> +                                        raw_ostream &OS,
> +                                        uint64_t Features) const {
> 
>   // Emit the lock opcode prefix as needed.
>   if (TSFlags & X86II::LOCK)
> @@ -1168,34 +1173,34 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
>   bool need_address_override;
>   // The AdSize prefix is only for 32-bit and 64-bit modes. Hm, perhaps we
>   // should introduce an AdSize16 bit instead of having seven special cases?
> -  if ((!is16BitMode() && TSFlags & X86II::AdSize) ||
> -      (is16BitMode() && (MI.getOpcode() == X86::JECXZ_32 ||
> -                         MI.getOpcode() == X86::MOV8o8a ||
> -                         MI.getOpcode() == X86::MOV16o16a ||
> -                         MI.getOpcode() == X86::MOV32o32a ||
> -                         MI.getOpcode() == X86::MOV8ao8 ||
> -                         MI.getOpcode() == X86::MOV16ao16 ||
> -                         MI.getOpcode() == X86::MOV32ao32))) {
> +  if ((!is16BitMode(Features) && TSFlags & X86II::AdSize) ||
> +      (is16BitMode(Features) && (MI.getOpcode() == X86::JECXZ_32 ||
> +                                 MI.getOpcode() == X86::MOV8o8a ||
> +                                 MI.getOpcode() == X86::MOV16o16a ||
> +                                 MI.getOpcode() == X86::MOV32o32a ||
> +                                 MI.getOpcode() == X86::MOV8ao8 ||
> +                                 MI.getOpcode() == X86::MOV16ao16 ||
> +                                 MI.getOpcode() == X86::MOV32ao32))) {
>     need_address_override = true;
>   } else if (MemOperand == -1) {
>     need_address_override = false;
> -  } else if (is64BitMode()) {
> -    assert(!Is16BitMemOperand(MI, MemOperand));
> +  } else if (is64BitMode(Features)) {
> +    assert(!Is16BitMemOperand(MI, MemOperand, Features));
>     need_address_override = Is32BitMemOperand(MI, MemOperand);
> -  } else if (is32BitMode()) {
> +  } else if (is32BitMode(Features)) {
>     assert(!Is64BitMemOperand(MI, MemOperand));
> -    need_address_override = Is16BitMemOperand(MI, MemOperand);
> +    need_address_override = Is16BitMemOperand(MI, MemOperand, Features);
>   } else {
> -    assert(is16BitMode());
> +    assert(is16BitMode(Features));
>     assert(!Is64BitMemOperand(MI, MemOperand));
> -    need_address_override = !Is16BitMemOperand(MI, MemOperand);
> +    need_address_override = !Is16BitMemOperand(MI, MemOperand, Features);
>   }
> 
>   if (need_address_override)
>     EmitByte(0x67, CurByte, OS);
> 
>   // Emit the operand size opcode prefix as needed.
> -  if (TSFlags & (is16BitMode() ? X86II::OpSize16 : X86II::OpSize))
> +  if (TSFlags & (is16BitMode(Features) ? X86II::OpSize16 : X86II::OpSize))
>     EmitByte(0x66, CurByte, OS);
> 
>   bool Need0FPrefix = false;
> @@ -1236,7 +1241,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
> 
>   // Handle REX prefix.
>   // FIXME: Can this come before F2 etc to simplify emission?
> -  if (is64BitMode()) {
> +  if (is64BitMode(Features)) {
>     if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc))
>       EmitByte(0x40 | REX, CurByte, OS);
>   }
> @@ -1302,7 +1307,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>   if (MemoryOperand != -1) MemoryOperand += CurOp;
> 
>   if (!HasVEXPrefix)
> -    EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS);
> +    EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS, Features);
>   else
>     EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS);
> 
> @@ -1368,7 +1373,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
> 
>     EmitMemModRMByte(MI, CurOp,
>                      GetX86RegNum(MI.getOperand(SrcRegNum)),
> -                     TSFlags, CurByte, OS, Fixups);
> +                     TSFlags, CurByte, OS, Fixups, Features);
>     CurOp = SrcRegNum + 1;
>     break;
> 
> @@ -1416,7 +1421,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>     EmitByte(BaseOpcode, CurByte, OS);
> 
>     EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
> -                     TSFlags, CurByte, OS, Fixups);
> +                     TSFlags, CurByte, OS, Fixups, Features);
>     CurOp += AddrOperands + 1;
>     if (HasVEX_4VOp3)
>       ++CurOp;
> @@ -1442,7 +1447,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>       ++CurOp;
>     EmitByte(BaseOpcode, CurByte, OS);
>     EmitMemModRMByte(MI, CurOp, (TSFlags & X86II::FormMask)-X86II::MRM0m,
> -                     TSFlags, CurByte, OS, Fixups);
> +                     TSFlags, CurByte, OS, Fixups, Features);
>     CurOp += X86::AddrNumOperands;
>     break;
>   case X86II::MRM_C1: case X86II::MRM_C2: case X86II::MRM_C3:
> diff --git a/test/MC/X86/fixup-cpu-mode.s b/test/MC/X86/fixup-cpu-mode.s
> new file mode 100644
> index 0000000..13e0d46
> --- /dev/null
> +++ b/test/MC/X86/fixup-cpu-mode.s
> @@ -0,0 +1,8 @@
> +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
> +// RUN: llvm-objdump -d %t | FileCheck %s
> +
> +//PR18303
> +.global edata
> +sub $edata, %r12 // CHECK: subq $0, %r12
> +.code32
> +
> -- 
> 1.8.4.2
> 
> From 9a608614fec6404a4cec5164093bc8f0ffcb40ff Mon Sep 17 00:00:00 2001
> From: David Woodhouse <David.Woodhouse at intel.com>
> Date: Wed, 8 Jan 2014 17:25:25 +0000
> Subject: [PATCH 4/4] [ARM] Fix PR18303 by using appropriate Feature bits for
> isThumb{2,}().
> 
> ---
> lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 42 +++++++++++++-----------
> test/MC/ARM/fixup-cpu-mode.s                     |  9 +++++
> 2 files changed, 32 insertions(+), 19 deletions(-)
> create mode 100644 test/MC/ARM/fixup-cpu-mode.s
> 
> diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> index 4fb1410..a1d0783 100644
> --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
> @@ -49,11 +49,11 @@ public:
> 
>   ~ARMMCCodeEmitter() {}
> 
> -  bool isThumb() const {
> -    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
> +  bool isThumb(uint64_t Features) const {
> +    return (Features & ARM::ModeThumb) != 0;
>   }
> -  bool isThumb2() const {
> -    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
> +  bool isThumb2(uint64_t Features) const {
> +    return isThumb(Features) && (Features & ARM::FeatureThumb2) != 0;
>   }
>   bool isTargetMachO() const {
>     Triple TT(STI.getTargetTriple());
> @@ -386,6 +386,10 @@ public:
>     }
>   }
> 
> +  uint64_t getAvailableFeatures() const {
> +    return STI.getFeatureBits();
> +  }
> +
>   void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>                          SmallVectorImpl<MCFixup> &Fixups,
>                          uint64_t AvailableFeatures) const;
> @@ -406,7 +410,7 @@ MCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
> unsigned ARMMCCodeEmitter::
> NEONThumb2DataIPostEncoder(const MCInst &MI, unsigned EncodedValue,
>                            uint64_t Features) const {
> -  if (isThumb2()) {
> +  if (isThumb2(Features)) {
>     // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
>     // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
>     // set to 1111.
> @@ -426,7 +430,7 @@ NEONThumb2DataIPostEncoder(const MCInst &MI, unsigned EncodedValue,
> unsigned ARMMCCodeEmitter::
> NEONThumb2LoadStorePostEncoder(const MCInst &MI, unsigned EncodedValue,
>                                uint64_t Features) const {
> -  if (isThumb2()) {
> +  if (isThumb2(Features)) {
>     EncodedValue &= 0xF0FFFFFF;
>     EncodedValue |= 0x09000000;
>   }
> @@ -440,7 +444,7 @@ NEONThumb2LoadStorePostEncoder(const MCInst &MI, unsigned EncodedValue,
> unsigned ARMMCCodeEmitter::
> NEONThumb2DupPostEncoder(const MCInst &MI, unsigned EncodedValue,
>                          uint64_t Features) const {
> -  if (isThumb2()) {
> +  if (isThumb2(Features)) {
>     EncodedValue &= 0x00FFFFFF;
>     EncodedValue |= 0xEE000000;
>   }
> @@ -453,7 +457,7 @@ NEONThumb2DupPostEncoder(const MCInst &MI, unsigned EncodedValue,
> unsigned ARMMCCodeEmitter::
> NEONThumb2V8PostEncoder(const MCInst &MI, unsigned EncodedValue,
>                         uint64_t Features) const {
> -  if (isThumb2()) {
> +  if (isThumb2(Features)) {
>     EncodedValue |= 0xC000000; // Set bits 27-26
>   }
> 
> @@ -465,7 +469,7 @@ NEONThumb2V8PostEncoder(const MCInst &MI, unsigned EncodedValue,
> unsigned ARMMCCodeEmitter::
> VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue,
>                      uint64_t Features) const {
> -  if (isThumb2()) {
> +  if (isThumb2(Features)) {
>     EncodedValue &= 0x0FFFFFFF;
>     EncodedValue |= 0xE0000000;
>   }
> @@ -650,7 +654,7 @@ uint32_t ARMMCCodeEmitter::
> getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
>                        SmallVectorImpl<MCFixup> &Fixups,
>                        uint64_t Features) const {
> -  if (isThumb2())
> +  if (isThumb2(Features))
>     return
>       ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
>   return getARMBranchTargetOpValue(MI, OpIdx, Fixups, Features);
> @@ -843,7 +847,7 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
>       isAdd = false ; // 'U' bit is set as part of the fixup.
> 
>       MCFixupKind Kind;
> -      if (isThumb2())
> +      if (isThumb2(Features))
>         Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
>       else
>         Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
> @@ -996,21 +1000,21 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
>     default: llvm_unreachable("Unsupported ARMFixup");
>     case ARMMCExpr::VK_ARM_HI16:
>       if (!isTargetMachO() && EvaluateAsPCRel(E))
> -        Kind = MCFixupKind(isThumb2()
> +        Kind = MCFixupKind(isThumb2(Features)
>                            ? ARM::fixup_t2_movt_hi16_pcrel
>                            : ARM::fixup_arm_movt_hi16_pcrel);
>       else
> -        Kind = MCFixupKind(isThumb2()
> +        Kind = MCFixupKind(isThumb2(Features)
>                            ? ARM::fixup_t2_movt_hi16
>                            : ARM::fixup_arm_movt_hi16);
>       break;
>     case ARMMCExpr::VK_ARM_LO16:
>       if (!isTargetMachO() && EvaluateAsPCRel(E))
> -        Kind = MCFixupKind(isThumb2()
> +        Kind = MCFixupKind(isThumb2(Features)
>                            ? ARM::fixup_t2_movw_lo16_pcrel
>                            : ARM::fixup_arm_movw_lo16_pcrel);
>       else
> -        Kind = MCFixupKind(isThumb2()
> +        Kind = MCFixupKind(isThumb2(Features)
>                            ? ARM::fixup_t2_movw_lo16
>                            : ARM::fixup_arm_movw_lo16);
>       break;
> @@ -1023,11 +1027,11 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx,
>   // the lower 16 bits of the expression regardless of whether
>   // we have a movt or a movw.
>   if (!isTargetMachO() && EvaluateAsPCRel(E))
> -    Kind = MCFixupKind(isThumb2()
> +    Kind = MCFixupKind(isThumb2(Features)
>                        ? ARM::fixup_t2_movw_lo16_pcrel
>                        : ARM::fixup_arm_movw_lo16_pcrel);
>   else
> -    Kind = MCFixupKind(isThumb2()
> +    Kind = MCFixupKind(isThumb2(Features)
>                        ? ARM::fixup_t2_movw_lo16
>                        : ARM::fixup_arm_movw_lo16);
>   Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc()));
> @@ -1237,7 +1241,7 @@ getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
>     assert(MO.isExpr() && "Unexpected machine operand type!");
>     const MCExpr *Expr = MO.getExpr();
>     MCFixupKind Kind;
> -    if (isThumb2())
> +    if (isThumb2(Features))
>       Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
>     else
>       Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
> @@ -1649,7 +1653,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
>   uint32_t Binary = getBinaryCodeForInstr(MI, Fixups, AvailableFeatures);
>   // Thumb 32-bit wide instructions need to emit the high order halfword
>   // first.
> -  if (isThumb() && Size == 4) {
> +  if (isThumb(AvailableFeatures) && Size == 4) {
>     EmitConstant(Binary >> 16, 2, OS);
>     EmitConstant(Binary & 0xffff, 2, OS);
>   } else
> diff --git a/test/MC/ARM/fixup-cpu-mode.s b/test/MC/ARM/fixup-cpu-mode.s
> new file mode 100644
> index 0000000..17f29f9
> --- /dev/null
> +++ b/test/MC/ARM/fixup-cpu-mode.s
> @@ -0,0 +1,9 @@
> +// RUN: llvm-mc -filetype=obj -triple thumbv7-linux-gnu %s -o %t
> +// RUN: llvm-objdump -triple thumbv7-linux-gnu -d %t | FileCheck %s
> +
> +//PR18303
> +.code 16
> +.global edata
> +b edata // CHECK: b.w
> +.code 32
> +
> -- 
> 1.8.4.2
> 





More information about the llvm-commits mailing list