[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