diff options
author | Derek Schuff <dschuff@chromium.org> | 2013-01-30 11:34:40 -0800 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2013-01-30 11:34:40 -0800 |
commit | 1843e19bce9b11fc840858e136c6c52cf8b42e0b (patch) | |
tree | e8bfc928152e2d3b3dd120d141d13dc08a9b49e4 /include/llvm/MC | |
parent | aa0fa8a8df25807f784ec9ca9deeb40328636595 (diff) | |
parent | a662a9862501fc86904e90054f7c1519101d9126 (diff) |
Merge commit 'a662a9862501fc86904e90054f7c1519101d9126'
Conflicts:
include/llvm/CodeGen/IntrinsicLowering.h
include/llvm/MC/MCAssembler.h
include/llvm/MC/MCObjectStreamer.h
lib/LLVMBuild.txt
lib/Linker/LinkArchives.cpp
lib/MC/MCAssembler.cpp
lib/MC/MCELFStreamer.cpp
lib/MC/MCParser/AsmParser.cpp
lib/MC/MCPureStreamer.cpp
lib/MC/WinCOFFStreamer.cpp
lib/Makefile
lib/Support/Unix/Memory.inc
lib/Support/Unix/Process.inc
lib/Support/Unix/Program.inc
lib/Target/ARM/ARM.h
lib/Target/ARM/ARMFastISel.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
lib/Target/Mips/MipsInstrFPU.td
lib/Target/X86/CMakeLists.txt
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86TargetMachine.cpp
lib/Target/X86/X86TargetObjectFile.cpp
lib/Transforms/InstCombine/InstCombineCalls.cpp
test/CodeGen/X86/fast-isel-x86-64.ll
tools/llc/llc.cpp
tools/lto/LTOModule.cpp
utils/TableGen/EDEmitter.cpp
Diffstat (limited to 'include/llvm/MC')
33 files changed, 559 insertions, 467 deletions
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h deleted file mode 100644 index 5b024675cd..0000000000 --- a/include/llvm/MC/EDInstInfo.h +++ /dev/null @@ -1,29 +0,0 @@ -//===-- llvm/MC/EDInstInfo.h - EDis instruction info ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef EDINSTINFO_H -#define EDINSTINFO_H - -#include "llvm/Support/DataTypes.h" - -namespace llvm { - -#define EDIS_MAX_OPERANDS 13 -#define EDIS_MAX_SYNTAXES 2 - -struct EDInstInfo { - uint8_t instructionType; - uint8_t numOperands; - uint8_t operandTypes[EDIS_MAX_OPERANDS]; - uint8_t operandFlags[EDIS_MAX_OPERANDS]; - const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS]; -}; - -} // namespace llvm - -#endif diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index f5ca3d5471..685f2cb89f 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -22,7 +22,7 @@ class MCELFObjectTargetWriter; struct MCFixupKindInfo; class MCFragment; class MCInst; -class MCInstFragment; +class MCRelaxableFragment; class MCObjectWriter; class MCSection; class MCStreamer; @@ -42,6 +42,9 @@ protected: // Can only create subclasses. public: virtual ~MCAsmBackend(); + /// lifetime management + virtual void reset() { } + /// createObjectWriter - Create a new MCObjectWriter instance for use by the /// assembler backend to emit the final object file. virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; @@ -128,7 +131,7 @@ public: /// fixup requires the associated instruction to be relaxed. virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCInstFragment *DF, + const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const = 0; /// RelaxInstruction - Relax the instruction in the given fragment to the next @@ -160,13 +163,6 @@ public: virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} // @LOCALMOD-BEGIN - /// getBundleSize - Return the size (in bytes) of code bundling units - /// for this target. If 0, bundling is disabled. This is used exclusively - /// for Native Client. - virtual unsigned getBundleSize() const { - return 0; - } - /// CustomExpandInst - /// If the MCInst instruction has a custom expansion, write it to the /// MCStreamer 'Out'. This can be used to perform "last minute" rewrites of diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 44087650c2..e8f7f116fe 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_ASM_INFO_H -#define LLVM_TARGET_ASM_INFO_H +#ifndef LLVM_MC_MCASMINFO_H +#define LLVM_MC_MCASMINFO_H #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MachineLocation.h" @@ -110,6 +110,9 @@ namespace llvm { /// LabelSuffix - This is appended to emitted labels. const char *LabelSuffix; // Defaults to ":" + /// LabelSuffix - This is appended to emitted labels. + const char *DebugLabelSuffix; // Defaults to ":" + /// GlobalPrefix - If this is set to a non-empty string, it is prepended /// onto all global symbols. This is often used for "_" or ".". const char *GlobalPrefix; // Defaults to "" @@ -441,6 +444,11 @@ namespace llvm { const char *getLabelSuffix() const { return LabelSuffix; } + + const char *getDebugLabelSuffix() const { + return DebugLabelSuffix; + } + const char *getGlobalPrefix() const { return GlobalPrefix; } diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h index 0ff3e127ed..7286151760 100644 --- a/include/llvm/MC/MCAsmInfoCOFF.h +++ b/include/llvm/MC/MCAsmInfoCOFF.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_COFF_TARGET_ASM_INFO_H -#define LLVM_COFF_TARGET_ASM_INFO_H +#ifndef LLVM_MC_MCASMINFOCOFF_H +#define LLVM_MC_MCASMINFOCOFF_H #include "llvm/MC/MCAsmInfo.h" @@ -33,4 +33,4 @@ namespace llvm { } -#endif // LLVM_COFF_TARGET_ASM_INFO_H +#endif // LLVM_MC_MCASMINFOCOFF_H diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h index af552de6e6..3d249f9306 100644 --- a/include/llvm/MC/MCAsmInfoDarwin.h +++ b/include/llvm/MC/MCAsmInfoDarwin.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DARWIN_TARGET_ASM_INFO_H -#define LLVM_DARWIN_TARGET_ASM_INFO_H +#ifndef LLVM_MC_MCASMINFODARWIN_H +#define LLVM_MC_MCASMINFODARWIN_H #include "llvm/MC/MCAsmInfo.h" @@ -26,4 +26,4 @@ namespace llvm { } -#endif // LLVM_DARWIN_TARGET_ASM_INFO_H +#endif // LLVM_MC_MCASMINFODARWIN_H diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index fdded4ffa7..8cb4601283 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -21,10 +21,10 @@ class MCSymbolData; /// Encapsulates the layout of an assembly file at a particular point in time. /// -/// Assembly may requiring compute multiple layouts for a particular assembly +/// Assembly may require computing multiple layouts for a particular assembly /// file as part of the relaxation process. This class encapsulates the layout /// at a single point in time in such a way that it is always possible to -/// efficiently compute the exact addresses of any symbol in the assembly file, +/// efficiently compute the exact address of any symbol in the assembly file, /// even during the relaxation process. class MCAsmLayout { public: @@ -39,14 +39,20 @@ private: /// The last fragment which was laid out, or 0 if nothing has been laid /// out. Fragments are always laid out in order, so all fragments with a - /// lower ordinal will be up to date. - mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment; + /// lower ordinal will be valid. + mutable DenseMap<const MCSectionData*, MCFragment*> LastValidFragment; /// \brief Make sure that the layout for the given fragment is valid, lazily /// computing it if necessary. - void EnsureValid(const MCFragment *F) const; + void ensureValid(const MCFragment *F) const; - bool isFragmentUpToDate(const MCFragment *F) const; + /// \brief Is the layout for this fragment valid? + bool isFragmentValid(const MCFragment *F) const; + + /// \brief Compute the amount of padding required before this fragment to + /// obey bundling restrictions. + uint64_t computeBundlePadding(const MCFragment *F, + uint64_t FOffset, uint64_t FSize); public: MCAsmLayout(MCAssembler &_Assembler); @@ -54,14 +60,14 @@ public: /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } - /// \brief Invalidate all following fragments because a fragment has been - /// resized. The fragments size should have already been updated. - void Invalidate(MCFragment *F); + /// \brief Invalidate the fragments after F because it has been resized. + /// The fragment's size should have already been updated. + void invalidateFragmentsAfter(MCFragment *F); /// \brief Perform layout for a single fragment, assuming that the previous /// fragment has already been laid out correctly, and the parent section has /// been initialized. - void LayoutFragment(MCFragment *Fragment); + void layoutFragment(MCFragment *Fragment); /// @name Section Access (in layout order) /// @{ @@ -80,11 +86,6 @@ public: /// \brief Get the offset of the given fragment inside its containing section. uint64_t getFragmentOffset(const MCFragment *F) const; - // @LOCALMOD-BEGIN - /// \brief Get the bundle padding of the given fragment. - uint8_t getFragmentPadding(const MCFragment *F) const; - // @LOCALMOD-END - /// @} /// @name Utility Functions /// @{ diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 949e99b50b..57aa08a2d0 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -10,13 +10,13 @@ #ifndef LLVM_MC_MCASSEMBLER_H #define LLVM_MC_MCASSEMBLER_H -#include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCInst.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCInst.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" #include <vector> // FIXME: Shouldn't be needed. @@ -48,43 +48,15 @@ public: FT_Align, FT_Data, FT_Fill, - FT_Inst, + FT_Relaxable, FT_Org, FT_Dwarf, FT_DwarfFrame, - FT_LEB, - FT_Tiny // @LOCALMOD - }; - - // @LOCALMOD-BEGIN - enum BundleAlignType { - BundleAlignNone = 0, - BundleAlignStart = 1, - BundleAlignEnd = 2 + FT_LEB }; - // @LOCALMOD-END private: - // @LOCALMOD-BEGIN - // Try to compress the layout of MCFragment by: - // 1) Making Kind, the bundling flags, and BundlePadding fit in 32 bits. - // 2) Move LayoutOrder to fit in the hole left by aligning for 64 bits. - - FragmentType Kind : 4; - - BundleAlignType BundleAlign : 2; - bool BundleGroupStart : 1; - bool BundleGroupEnd : 1; - - /// BundlePadding - The computed padding for this fragment. This is ~0 - /// until initialized. - uint8_t BundlePadding; - - /// LayoutOrder - The layout order of this fragment. - unsigned LayoutOrder; - - // @LOCALMOD-END - + FragmentType Kind; /// Parent - The data for the section this fragment is in. MCSectionData *Parent; @@ -103,6 +75,9 @@ private: /// initialized. uint64_t Offset; + /// LayoutOrder - The layout order of this fragment. + unsigned LayoutOrder; + /// @} protected: @@ -124,74 +99,107 @@ public: unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - // @LOCALMOD-BEGIN - bool isBundleGroupStart() const { return BundleGroupStart; } - void setBundleGroupStart(bool Value) { BundleGroupStart = Value; } + /// \brief Does this fragment have instructions emitted into it? By default + /// this is false, but specific fragment types may set it to true. + virtual bool hasInstructions() const { return false; } - bool isBundleGroupEnd() const { return BundleGroupEnd; } - void setBundleGroupEnd(bool Value) { BundleGroupEnd = Value; } + /// \brief Should this fragment be placed at the end of an aligned bundle? + virtual bool alignToBundleEnd() const { return false; } - BundleAlignType getBundleAlign() const { return BundleAlign; } - void setBundleAlign(BundleAlignType Value) { BundleAlign = Value; } - // @LOCALMOD-END + /// \brief Get the padding size that must be inserted before this fragment. + /// Used for bundling. By default, no padding is inserted. + /// Note that padding size is restricted to 8 bits. This is an optimization + /// to reduce the amount of space used for each fragment. In practice, larger + /// padding should never be required. + virtual uint8_t getBundlePadding() const { + return 0; + } + + /// \brief Set the padding size for this fragment. By default it's a no-op, + /// and only some fragments have a meaningful implementation. + virtual void setBundlePadding(uint8_t N) { + } void dump(); }; -// @LOCALMOD-BEGIN -// This is just a tiny data fragment with no fixups. -// (To help with memory usage) -class MCTinyFragment : public MCFragment { - private: - SmallString<6> Contents; +class MCEncodedFragment : public MCFragment { + virtual void anchor(); + + uint8_t BundlePadding; +public: + MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0) + : MCFragment(FType, SD), BundlePadding(0) + { + } + virtual ~MCEncodedFragment(); + + typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; + typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; + + virtual SmallVectorImpl<char> &getContents() = 0; + virtual const SmallVectorImpl<char> &getContents() const = 0; - public: + virtual SmallVectorImpl<MCFixup> &getFixups() = 0; + virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; - MCTinyFragment(MCSectionData *SD = 0) : MCFragment(FT_Tiny, SD) {} + virtual fixup_iterator fixup_begin() = 0; + virtual const_fixup_iterator fixup_begin() const = 0; + virtual fixup_iterator fixup_end() = 0; + virtual const_fixup_iterator fixup_end() const = 0; - SmallString<6> &getContents() { return Contents; } - const SmallString<6> &getContents() const { return Contents; } + virtual uint8_t getBundlePadding() const { + return BundlePadding; + } + + virtual void setBundlePadding(uint8_t N) { + BundlePadding = N; + } static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Tiny; + MCFragment::FragmentType Kind = F->getKind(); + return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; } - static bool classof(const MCTinyFragment *) { return true; } }; -// @LOCALMOD-END -class MCDataFragment : public MCFragment { +/// Fragment for data and encoded instructions. +/// +class MCDataFragment : public MCEncodedFragment { virtual void anchor(); - SmallString<6> Contents; // @LOCALMOD: Memory efficiency - /// Fixups - The list of fixups in this fragment. - std::vector<MCFixup> Fixups; + /// \brief Does this fragment contain encoded instructions anywhere in it? + bool HasInstructions; -public: - typedef std::vector<MCFixup>::const_iterator const_fixup_iterator; - typedef std::vector<MCFixup>::iterator fixup_iterator; + /// \brief Should this fragment be aligned to the end of a bundle? + bool AlignToBundleEnd; -public: - MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} + SmallVector<char, 32> Contents; - /// @name Accessors - /// @{ + /// Fixups - The list of fixups in this fragment. + SmallVector<MCFixup, 4> Fixups; +public: + MCDataFragment(MCSectionData *SD = 0) + : MCEncodedFragment(FT_Data, SD), + HasInstructions(false), AlignToBundleEnd(false) + { + } - SmallString<6> &getContents() { return Contents; } // @LOCALMOD - const SmallString<6> &getContents() const { return Contents; } // @LOCALMOD + virtual SmallVectorImpl<char> &getContents() { return Contents; } + virtual const SmallVectorImpl<char> &getContents() const { return Contents; } - /// @} - /// @name Fixup Access - /// @{ + SmallVectorImpl<MCFixup> &getFixups() { + return Fixups; + } - void addFixup(MCFixup Fixup) { - // Enforce invariant that fixups are in offset order. - assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset()) && - "Fixups must be added in order!"); - Fixups.push_back(Fixup); + const SmallVectorImpl<MCFixup> &getFixups() const { + return Fixups; } - std::vector<MCFixup> &getFixups() { return Fixups; } - const std::vector<MCFixup> &getFixups() const { return Fixups; } + virtual bool hasInstructions() const { return HasInstructions; } + virtual void setHasInstructions(bool V) { HasInstructions = V; } + + virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } + virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -199,60 +207,46 @@ public: fixup_iterator fixup_end() {return Fixups.end();} const_fixup_iterator fixup_end() const {return Fixups.end();} - size_t fixup_size() const { return Fixups.size(); } - - /// @} - static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Data; } }; -// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as -// it is almost entirely a duplicate of MCDataFragment. If we decide to stick -// with this approach (as opposed to making MCInstFragment a very light weight -// object with just the MCInst and a code size, then we should just change -// MCDataFragment to have an optional MCInst at its end. -class MCInstFragment : public MCFragment { +/// A relaxable fragment holds on to its MCInst, since it may need to be +/// relaxed during the assembler layout and relaxation stage. +/// +class MCRelaxableFragment : public MCEncodedFragment { virtual void anchor(); /// Inst - The instruction this is a fragment for. MCInst Inst; - /// Code - Binary data for the currently encoded instruction. - SmallString<8> Code; + /// Contents - Binary data for the currently encoded instruction. + SmallVector<char, 8> Contents; /// Fixups - The list of fixups in this fragment. SmallVector<MCFixup, 1> Fixups; public: - typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; - typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; - -public: - MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0) - : MCFragment(FT_Inst, SD), Inst(_Inst) { + MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0) + : MCEncodedFragment(FT_Relaxable, SD), Inst(_Inst) { } - /// @name Accessors - /// @{ - - SmallVectorImpl<char> &getCode() { return Code; } - const SmallVectorImpl<char> &getCode() const { return Code; } - - unsigned getInstSize() const { return Code.size(); } + virtual SmallVectorImpl<char> &getContents() { return Contents; } + virtual const SmallVectorImpl<char> &getContents() const { return Contents; } - MCInst &getInst() { return Inst; } const MCInst &getInst() const { return Inst; } - void setInst(const MCInst& Value) { Inst = Value; } - /// @} - /// @name Fixup Access - /// @{ + SmallVectorImpl<MCFixup> &getFixups() { + return Fixups; + } - SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } - const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } + const SmallVectorImpl<MCFixup> &getFixups() const { + return Fixups; + } + + virtual bool hasInstructions() const { return true; } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -260,12 +254,8 @@ public: fixup_iterator fixup_end() {return Fixups.end();} const_fixup_iterator fixup_end() const {return Fixups.end();} - size_t fixup_size() const { return Fixups.size(); } - - /// @} - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Inst; + return F->getKind() == MCFragment::FT_Relaxable; } }; @@ -499,6 +489,12 @@ public: typedef FragmentListType::const_reverse_iterator const_reverse_iterator; typedef FragmentListType::reverse_iterator reverse_iterator; + /// \brief Express the state of bundle locked groups while emitting code. + enum BundleLockStateType { + NotBundleLocked, + BundleLocked, + BundleLockedAlignToEnd + }; private: FragmentListType Fragments; const MCSection *Section; @@ -512,6 +508,13 @@ private: /// Alignment - The maximum alignment seen in this section. unsigned Alignment; + /// \brief Keeping track of bundle-locked state. + BundleLockStateType BundleLockState; + + /// \brief We've seen a bundle_lock directive but not its first instruction + /// yet. + bool BundleGroupBeforeFirstInst; + /// @name Assembler Backend Data /// @{ // @@ -521,29 +524,6 @@ private: /// it. unsigned HasInstructions : 1; - // @LOCALMOD-BEGIN - bool BundlingEnabled : 1; - bool BundleLocked : 1; - - // Because ".bundle_lock" occurs before the fragment it applies to exists, - // we need to keep this flag around so we know to mark the next fragment - // as the start of a bundle group. A similar flag is not necessary for the - // last fragment, because when a .bundle_unlock occurs, the last fragment - // in the group already exists and can be marked directly. - bool BundleGroupFirstFrag : 1; - - typedef MCFragment::BundleAlignType BundleAlignType; - BundleAlignType BundleAlignNext : 2; - - // Optimization to reduce the number of fragments generated (for memory - // savings). Keep track of when we know the offset of the next point to - // emit an instruction. If we know the offset from a known alignment point, - // we can just append to the previous fragment. - bool BundleOffsetKnown : 1; - unsigned BundleSize; - unsigned BundleOffset; - // @LOCALMOD-END - /// @} public: @@ -565,25 +545,6 @@ public: unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - // @LOCALMOD-BEGIN - bool isBundlingEnabled() const { return BundlingEnabled; } - - bool isBundleLocked() const { return BundleLocked; } - void setBundleLocked(bool Value) { BundleLocked = Value; } - - bool isBundleGroupFirstFrag() const { return BundleGroupFirstFrag; } - void setBundleGroupFirstFrag(bool Value) { BundleGroupFirstFrag = Value; } - - - BundleAlignType getBundleAlignNext() const { return BundleAlignNext; } - void setBundleAlignNext(BundleAlignType Value) { BundleAlignNext = Value; } - - void MarkBundleOffsetUnknown(); - bool ShouldCreateNewFragment(size_t Size); - void UpdateBundleOffset(size_t Size); - void AlignBundleOffsetTo(size_t AlignBase); - // @LOCALMOD-END - /// @name Fragment Access /// @{ @@ -606,6 +567,26 @@ public: bool empty() const { return Fragments.empty(); } + bool isBundleLocked() const { + return BundleLockState != NotBundleLocked; + } + + BundleLockStateType getBundleLockState() const { + return BundleLockState; + } + + void setBundleLockState(BundleLockStateType NewState) { + BundleLockState = NewState; + } + + bool isBundleGroupBeforeFirstInst() const { + return BundleGroupBeforeFirstInst; + } + + void setBundleGroupBeforeFirstInst(bool IsFirst) { + BundleGroupBeforeFirstInst = IsFirst; + } + void dump(); /// @} @@ -811,6 +792,11 @@ private: // refactoring too. SmallPtrSet<const MCSymbol*, 64> ThumbFuncs; + /// \brief The bundle alignment size currently set in the assembler. + /// + /// By default it's 0, which means bundling is disabled. + unsigned BundleAlignSize; + unsigned RelaxAll : 1; unsigned NoExecStack : 1; unsigned SubsectionsViaSymbols : 1; @@ -835,20 +821,22 @@ private: /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). - bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF, + bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const; /// Check whether the given fragment needs relaxation. - bool fragmentNeedsRelaxation(const MCInstFragment *IF, + bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF, const MCAsmLayout &Layout) const; - /// layoutOnce - Perform one layout iteration and return true if any offsets + /// \brief Perform one layout iteration and return true if any offsets /// were adjusted. bool layoutOnce(MCAsmLayout &Layout); + /// \brief Perform one layout iteration of the given section and return true + /// if any offsets were adjusted. bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD); - bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF); + bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); @@ -904,6 +892,10 @@ public: raw_ostream &OS); ~MCAssembler(); + /// Reuse an assembler instance + /// + void reset(); + MCContext &getContext() const { return Context; } MCAsmBackend &getBackend() const { return Backend; } @@ -931,6 +923,20 @@ public: bool getNoExecStack() const { return NoExecStack; } void setNoExecStack(bool Value) { NoExecStack = Value; } + bool isBundlingEnabled() const { + return BundleAlignSize != 0; + } + + unsigned getBundleAlignSize() const { + return BundleAlignSize; + } + + void setBundleAlignSize(unsigned Size) { + assert((Size == 0 || !(Size & (Size - 1))) && + "Expect a power-of-two bundle align size"); + BundleAlignSize = Size; + } + /// @name Section List Access /// @{ |