diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2013-04-08 18:41:23 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2013-04-08 18:41:23 +0000 | 
| commit | 4a16efa3e43e35f0cc9efe3a67f620f0017c3d36 (patch) | |
| tree | 06099edc18d30894081a822b756f117cbe0b8207 /include/llvm/MC | |
| parent | 482e7bddf617ae804dc47133cb07eb4aa81e45de (diff) | |
Diffstat (limited to 'include/llvm/MC')
43 files changed, 1220 insertions, 448 deletions
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h deleted file mode 100644 index 5b024675cdc8..000000000000 --- 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 72ed1a317c55..9a6b70340808 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 MCValue; @@ -41,6 +41,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; @@ -127,7 +130,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 diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 97aad71fd955..28256b3677ef 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -13,11 +13,11 @@  //  //===----------------------------------------------------------------------===// -#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/MachineLocation.h"  #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MachineLocation.h"  #include <cassert>  #include <vector> @@ -48,6 +48,11 @@ namespace llvm {      ///               Default is 4.      unsigned PointerSize; +    /// CalleeSaveStackSlotSize - Size of the stack slot reserved for +    ///                           callee-saved registers, in bytes. +    ///                           Default is same as pointer size. +    unsigned CalleeSaveStackSlotSize; +      /// IsLittleEndian - True if target is little endian.      ///                  Default is true.      bool IsLittleEndian; @@ -102,6 +107,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 "" @@ -340,7 +348,13 @@ namespace llvm {        return PointerSize;      } -    /// islittleendian - True if the target is little endian. +    /// getCalleeSaveStackSlotSize - Get the callee-saved register stack slot +    /// size in bytes. +    unsigned getCalleeSaveStackSlotSize() const { +      return CalleeSaveStackSlotSize; +    } + +    /// isLittleEndian - True if the target is little endian.      bool isLittleEndian() const {        return IsLittleEndian;      } @@ -426,6 +440,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 0ff3e127ed0e..7286151760c0 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 af552de6e690..3d249f93068d 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 cf79216d076a..3058b7b48742 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,15 @@ 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 starting with F because it has been +  /// resized. The fragment's size should have already been updated, but +  /// its bundle padding will be recomputed. +  void invalidateFragmentsFrom(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)    /// @{ diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 5771415c81cc..43fbdc9301ac 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. @@ -47,8 +47,9 @@ public:    enum FragmentType {      FT_Align,      FT_Data, +    FT_CompactEncodedInst,      FT_Fill, -    FT_Inst, +    FT_Relaxable,      FT_Org,      FT_Dwarf,      FT_DwarfFrame, @@ -99,42 +100,139 @@ public:    unsigned getLayoutOrder() const { return LayoutOrder; }    void setLayoutOrder(unsigned Value) { LayoutOrder = 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; } + +  /// \brief Should this fragment be placed at the end of an aligned bundle? +  virtual bool alignToBundleEnd() const { return false; } +  virtual void setAlignToBundleEnd(bool V) { } + +  /// \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();  }; -class MCDataFragment : public MCFragment { +/// Interface implemented by fragments that contain encoded instructions and/or +/// data. +/// +class MCEncodedFragment : public MCFragment {    virtual void anchor(); -  SmallString<32> Contents; - -  /// Fixups - The list of fixups in this fragment. -  std::vector<MCFixup> Fixups; +  uint8_t BundlePadding;  public: -  typedef std::vector<MCFixup>::const_iterator const_fixup_iterator; -  typedef std::vector<MCFixup>::iterator fixup_iterator; +  MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0) +    : MCFragment(FType, SD), BundlePadding(0) +  { +  } +  virtual ~MCEncodedFragment(); + +  virtual SmallVectorImpl<char> &getContents() = 0; +  virtual const SmallVectorImpl<char> &getContents() const = 0; + +  virtual uint8_t getBundlePadding() const { +    return BundlePadding; +  } + +  virtual void setBundlePadding(uint8_t N) { +    BundlePadding = N; +  } + +  static bool classof(const MCFragment *F) { +    MCFragment::FragmentType Kind = F->getKind(); +    switch (Kind) { +      default: +        return false; +      case MCFragment::FT_Relaxable: +      case MCFragment::FT_CompactEncodedInst: +      case MCFragment::FT_Data: +        return true; +    } +  } +}; + +/// Interface implemented by fragments that contain encoded instructions and/or +/// data and also have fixups registered. +/// +class MCEncodedFragmentWithFixups : public MCEncodedFragment { +  virtual void anchor();  public: -  MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} +  MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, +                              MCSectionData *SD = 0) +    : MCEncodedFragment(FType, SD) +  { +  } -  /// @name Accessors -  /// @{ +  virtual ~MCEncodedFragmentWithFixups(); -  SmallString<32> &getContents() { return Contents; } -  const SmallString<32> &getContents() const { return Contents; } +  typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; +  typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; -  /// @} -  /// @name Fixup Access -  /// @{ +  virtual SmallVectorImpl<MCFixup> &getFixups() = 0; +  virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; + +  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; + +  static bool classof(const MCFragment *F) { +    MCFragment::FragmentType Kind = F->getKind(); +    return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data; +  } +}; + +/// Fragment for data and encoded instructions. +/// +class MCDataFragment : public MCEncodedFragmentWithFixups { +  virtual void anchor(); + +  /// \brief Does this fragment contain encoded instructions anywhere in it? +  bool HasInstructions; + +  /// \brief Should this fragment be aligned to the end of a bundle? +  bool AlignToBundleEnd; + +  SmallVector<char, 32> Contents; -  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); +  /// Fixups - The list of fixups in this fragment. +  SmallVector<MCFixup, 4> Fixups; +public: +  MCDataFragment(MCSectionData *SD = 0) +    : MCEncodedFragmentWithFixups(FT_Data, SD), +      HasInstructions(false), AlignToBundleEnd(false) +  {    } -  std::vector<MCFixup> &getFixups() { return Fixups; } -  const std::vector<MCFixup> &getFixups() const { return Fixups; } +  virtual SmallVectorImpl<char> &getContents() { return Contents; } +  virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + +  SmallVectorImpl<MCFixup> &getFixups() { +    return Fixups; +  } + +  const SmallVectorImpl<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(); } @@ -142,60 +240,79 @@ 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; +  } +}; -  /// @} +/// This is a compact (memory-size-wise) fragment for holding an encoded +/// instruction (non-relaxable) that has no fixups registered. When applicable, +/// it can be used instead of MCDataFragment and lead to lower memory +/// consumption. +/// +class MCCompactEncodedInstFragment : public MCEncodedFragment { +  virtual void anchor(); + +  /// \brief Should this fragment be aligned to the end of a bundle? +  bool AlignToBundleEnd; + +  SmallVector<char, 4> Contents; +public: +  MCCompactEncodedInstFragment(MCSectionData *SD = 0) +    : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false) +  { +  } + +  virtual bool hasInstructions() const { +    return true; +  } + +  virtual SmallVectorImpl<char> &getContents() { return Contents; } +  virtual const SmallVectorImpl<char> &getContents() const { return Contents; } + +  virtual bool alignToBundleEnd() const { return AlignToBundleEnd; } +  virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }    static bool classof(const MCFragment *F) { -    return F->getKind() == MCFragment::FT_Data; +    return F->getKind() == MCFragment::FT_CompactEncodedInst;    }  }; -// 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 MCEncodedFragmentWithFixups {    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) +    : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {    } -  /// @name Accessors -  /// @{ - -  SmallVectorImpl<char> &getCode() { return Code; } -  const SmallVectorImpl<char> &getCode() const { return Code; } +  virtual SmallVectorImpl<char> &getContents() { return Contents; } +  virtual const SmallVectorImpl<char> &getContents() const { return Contents; } -  unsigned getInstSize() const { return Code.size(); } - -  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; +  } + +  const SmallVectorImpl<MCFixup> &getFixups() const { +    return Fixups; +  } -  SmallVectorImpl<MCFixup> &getFixups() { 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(); } @@ -203,12 +320,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;    }  }; @@ -442,6 +555,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; @@ -455,6 +574,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    /// @{    // @@ -507,6 +633,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();    /// @} @@ -703,6 +849,10 @@ private:    std::vector<IndirectSymbolData> IndirectSymbols;    std::vector<DataRegionData> DataRegions; + +  /// The list of linker options to propagate into the object file. +  std::vector<std::vector<std::string> > LinkerOptions; +    /// The set of function symbols for which a .thumb_func directive has    /// been seen.    // @@ -712,10 +862,21 @@ 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; +  /// ELF specific e_header flags +  // It would be good if there were an MCELFAssembler class to hold this. +  // ELF header flags are used both by the integrated and standalone assemblers. +  // Access to the flags is necessary in cases where assembler directives affect +  // which flags to be set. +  unsigned ELFHeaderEFlags;  private:    /// Evaluate a fixup to a relocatable expression and the value which should be    /// placed into the fixup. @@ -736,20 +897,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); @@ -791,6 +954,10 @@ public:    /// Flag a function symbol as the target of a .thumb_func directive.    void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } +  /// ELF e_header flags +  unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;} +  void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;} +  public:    /// Construct a new assembler instance.    /// @@ -805,6 +972,10 @@ public:                raw_ostream &OS);    ~MCAssembler(); +  /// Reuse an assembler instance +  /// +  void reset(); +    MCContext &getContext() const { return Context; }    MCAsmBackend &getBackend() const { return Backend; } @@ -832,6 +1003,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    /// @{ @@ -889,6 +1074,14 @@ public:    size_t indirect_symbol_size() const { return IndirectSymbols.size(); }    /// @} +  /// @name Linker Option List Access +  /// @{ + +  std::vector<std::vector<std::string> > &getLinkerOptions() { +    return LinkerOptions; +  } + +  /// @}    /// @name Data Region List Access    /// @{ diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAtom.h index 682cf7cd76c6..ae5bf0bc2069 100644 --- a/include/llvm/MC/MCAtom.h +++ b/include/llvm/MC/MCAtom.h @@ -46,8 +46,8 @@ class MCAtom {      : Type(T), Parent(P), Begin(B), End(E) { }  public: -  bool isTextAtom() { return Type == TextAtom; } -  bool isDataAtom() { return Type == DataAtom; } +  bool isTextAtom() const { return Type == TextAtom; } +  bool isDataAtom() const { return Type == DataAtom; }    void addInst(const MCInst &I, uint64_t Address, unsigned Size);    void addData(const MCData &D); diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h index 057489090293..9bfa08eb5d01 100644 --- a/include/llvm/MC/MCCodeEmitter.h +++ b/include/llvm/MC/MCCodeEmitter.h @@ -29,6 +29,9 @@ protected: // Can only create subclasses.  public:    virtual ~MCCodeEmitter(); +  /// Lifetime management +  virtual void reset() { } +    /// EncodeInstruction - Encode the given \p Inst to bytes on the output    /// stream \p OS.    virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS, diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 5a8830cb66ce..0db3dee2ff05 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -10,13 +10,15 @@  #ifndef LLVM_MC_MCCONTEXT_H  #define LLVM_MC_MCCONTEXT_H -#include "llvm/MC/SectionKind.h" -#include "llvm/MC/MCDwarf.h"  #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringMap.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/SectionKind.h"  #include "llvm/Support/Allocator.h"  #include "llvm/Support/Compiler.h"  #include "llvm/Support/raw_ostream.h" +#include <map>  #include <vector> // FIXME: Shouldn't be needed.  namespace llvm { @@ -94,9 +96,19 @@ namespace llvm {      /// .secure_log_reset appearing between them.      bool SecureLogUsed; +    /// The compilation directory to use for DW_AT_comp_dir. +    std::string CompilationDir; + +    /// The main file name if passed in explicitly. +    std::string MainFileName; +      /// The dwarf file and directory tables from the dwarf .file directive. -    std::vector<MCDwarfFile *> MCDwarfFiles; -    std::vector<StringRef> MCDwarfDirs; +    /// We now emit a line table for each compile unit. To reduce the prologue +    /// size of each line table, the files and directories used by each compile +    /// unit are separated. +    typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap; +    MCDwarfFilesMap MCDwarfFilesCUMap; +    std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap;      /// The current dwarf line information from the last dwarf .loc directive.      MCDwarfLoc CurrentDwarfLoc; @@ -123,6 +135,10 @@ namespace llvm {      /// non-empty.      StringRef DwarfDebugFlags; +    /// The string to embed in as the dwarf AT_producer for the compile unit, if +    /// non-empty. +    StringRef DwarfDebugProducer; +      /// Honor temporary labels, this is useful for debugging semantic      /// differences between temporary and non-temporary labels (primarily on      /// Darwin). @@ -134,14 +150,22 @@ namespace llvm {      /// We need a deterministic iteration order, so we remember the order      /// the elements were added.      std::vector<const MCSection *> MCLineSectionOrder; +    /// The Compile Unit ID that we are currently processing. +    unsigned DwarfCompileUnitID; +    /// The line table start symbol for each Compile Unit. +    DenseMap<unsigned, MCSymbol *> MCLineTableSymbols;      void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; +    /// Do automatic reset in destructor +    bool AutoReset; +      MCSymbol *CreateSymbol(StringRef Name);    public:      explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, -                       const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0); +                       const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0, +                       bool DoAutoReset = true);      ~MCContext();      const SourceMgr *getSourceManager() const { return SrcMgr; } @@ -154,6 +178,15 @@ namespace llvm {      void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } +    /// @name Module Lifetime Management +    /// @{ + +    /// reset - return object to right after construction state to prepare +    /// to process a new module +    void reset(); + +    /// @} +      /// @name Symbol Management      /// @{ @@ -235,21 +268,45 @@ namespace llvm {      /// @name Dwarf Management      /// @{ +    /// \brief Get the compilation directory for DW_AT_comp_dir +    /// This can be overridden by clients which want to control the reported +    /// compilation directory and have it be something other than the current +    /// working directory. +    const std::string &getCompilationDir() const { return CompilationDir; } + +    /// \brief Set the compilation directory for DW_AT_comp_dir +    /// Override the default (CWD) compilation directory. +    void setCompilationDir(StringRef S) { CompilationDir = S.str(); } + +    /// \brief Get the main file name for use in error messages and debug +    /// info. This can be set to ensure we've got the correct file name +    /// after preprocessing or for -save-temps. +    const std::string &getMainFileName() const { return MainFileName; } + +    /// \brief Set the main file name and override the default. +    void setMainFileName(StringRef S) { MainFileName = S.str(); } +      /// GetDwarfFile - creates an entry in the dwarf file and directory tables.      unsigned GetDwarfFile(StringRef Directory, StringRef FileName, -                          unsigned FileNumber); +                          unsigned FileNumber, unsigned CUID); -    bool isValidDwarfFileNumber(unsigned FileNumber); +    bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);      bool hasDwarfFiles() const { -      return !MCDwarfFiles.empty(); +      // Traverse MCDwarfFilesCUMap and check whether each entry is empty. +      MCDwarfFilesMap::const_iterator MapB, MapE; +      for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end(); +           MapB != MapE; MapB++) +        if (!MapB->second.empty()) +           return true; +      return false;      } -    const std::vector<MCDwarfFile *> &getMCDwarfFiles() { -      return MCDwarfFiles; +    const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) { +      return MCDwarfFilesCUMap[CUID];      } -    const std::vector<StringRef> &getMCDwarfDirs() { -      return MCDwarfDirs; +    const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) { +      return MCDwarfDirsCUMap[CUID];      }      const DenseMap<const MCSection *, MCLineSection *> @@ -263,6 +320,25 @@ namespace llvm {        MCLineSections[Sec] = Line;        MCLineSectionOrder.push_back(Sec);      } +    unsigned getDwarfCompileUnitID() { +      return DwarfCompileUnitID; +    } +    void setDwarfCompileUnitID(unsigned CUIndex) { +      DwarfCompileUnitID = CUIndex; +    } +    const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const { +      return MCLineTableSymbols; +    } +    MCSymbol *getMCLineTableSymbol(unsigned ID) const { +      DenseMap<unsigned, MCSymbol *>::const_iterator CIter = +        MCLineTableSymbols.find(ID); +      if (CIter == MCLineTableSymbols.end()) +        return NULL; +      return CIter->second; +    } +    void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) { +      MCLineTableSymbols[ID] = Sym; +    }      /// setCurrentDwarfLoc - saves the information from the currently parsed      /// dwarf .loc directive and sets DwarfLocSeen.  When the next instruction @@ -309,6 +385,9 @@ namespace llvm {      void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }      StringRef getDwarfDebugFlags() { return DwarfDebugFlags; } +    void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; } +    StringRef getDwarfDebugProducer() { return DwarfDebugProducer; } +      /// @}      char *getSecureLogFile() { return SecureLogFile; } diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index 53a9ce0a3648..36fbcb02d9f6 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -6,11 +6,11 @@  // License. See LICENSE.TXT for details.  //  //===----------------------------------------------------------------------===// -#ifndef MCDISASSEMBLER_H -#define MCDISASSEMBLER_H +#ifndef LLVM_MC_MCDISASSEMBLER_H +#define LLVM_MC_MCDISASSEMBLER_H -#include "llvm/Support/DataTypes.h"  #include "llvm-c/Disassembler.h" +#include "llvm/Support/DataTypes.h"  namespace llvm { @@ -20,8 +20,6 @@ class MemoryObject;  class raw_ostream;  class MCContext; -struct EDInstInfo; -  /// MCDisassembler - Superclass for all disassemblers.  Consumes a memory region  ///   and provides an array of assembly instructions.  class MCDisassembler { @@ -84,14 +82,6 @@ public:                                         raw_ostream &vStream,                                         raw_ostream &cStream) const = 0; -  /// getEDInfo - Returns the enhanced instruction information corresponding to -  ///   the disassembler. -  /// -  /// @return         - An array of instruction information, with one entry for -  ///                   each MCInst opcode this disassembler returns. -  ///                   NULL if there is no info for this target. -  virtual const EDInstInfo   *getEDInfo() const { return (EDInstInfo*)0; } -  private:    //    // Hooks for symbolic disassembly via the public 'C' interface. diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 8fc437f3e691..1a392e8755ee 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -16,10 +16,10 @@  #define LLVM_MC_MCDWARF_H  #include "llvm/ADT/StringRef.h" -#include "llvm/MC/MachineLocation.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Dwarf.h"  #include "llvm/Support/Compiler.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/raw_ostream.h" +#include <map>  #include <vector>  namespace llvm { @@ -187,29 +187,43 @@ namespace llvm {      MCLineSection() {}      // addLineEntry - adds an entry to this MCLineSection's line entries -    void addLineEntry(const MCLineEntry &LineEntry) { -      MCLineEntries.push_back(LineEntry); +    void addLineEntry(const MCLineEntry &LineEntry, unsigned CUID) { +      MCLineDivisions[CUID].push_back(LineEntry);      }      typedef std::vector<MCLineEntry> MCLineEntryCollection;      typedef MCLineEntryCollection::iterator iterator;      typedef MCLineEntryCollection::const_iterator const_iterator; +    typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap;    private: -    MCLineEntryCollection MCLineEntries; +    // A collection of MCLineEntry for each Compile Unit ID. +    MCLineDivisionMap MCLineDivisions;    public: -    const MCLineEntryCollection *getMCLineEntries() const { -      return &MCLineEntries; +    // Returns whether MCLineSection contains entries for a given Compile +    // Unit ID. +    bool containEntriesForID(unsigned CUID) const { +      return MCLineDivisions.count(CUID); +    } +    // Returns the collection of MCLineEntry for a given Compile Unit ID. +    const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const { +      MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID); +      assert(CIter != MCLineDivisions.end()); +      return CIter->second;      }    };    class MCDwarfFileTable {    public:      // -    // This emits the Dwarf file and the line tables. +    // This emits the Dwarf file and the line tables for all Compile Units.      //      static const MCSymbol *Emit(MCStreamer *MCOS); +    // +    // This emits the Dwarf file and the line tables for a given Compile Unit. +    // +    static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);    };    class MCDwarfLineAddr { @@ -266,42 +280,115 @@ namespace llvm {    class MCCFIInstruction {    public: -    enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape, -                  Restore}; +    enum OpType { OpSameValue, OpRememberState, OpRestoreState, OpOffset, +                  OpDefCfaRegister, OpDefCfaOffset, OpDefCfa, OpRelOffset, +                  OpAdjustCfaOffset, OpEscape, OpRestore, OpUndefined, +                  OpRegister };    private:      OpType Operation;      MCSymbol *Label; -    // Move to & from location. -    MachineLocation Destination; -    MachineLocation Source; +    unsigned Register; +    union { +      int Offset; +      unsigned Register2; +    };      std::vector<char> Values; + +    MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) : +      Operation(Op), Label(L), Register(R), Offset(O), +      Values(V.begin(), V.end()) { +      assert(Op != OpRegister); +    } + +    MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) : +      Operation(Op), Label(L), Register(R1), Register2(R2) { +      assert(Op == OpRegister); +    } +    public: -    MCCFIInstruction(OpType Op, MCSymbol *L) -      : Operation(Op), Label(L) { -      assert(Op == RememberState || Op == RestoreState); +    static MCCFIInstruction +    createOffset(MCSymbol *L, unsigned Register, int Offset) { +      return MCCFIInstruction(OpOffset, L, Register, Offset, ""); +    } + +    static MCCFIInstruction +    createDefCfaRegister(MCSymbol *L, unsigned Register) { +      return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, ""); +    } + +    static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) { +      return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, ""); +    } + +    static MCCFIInstruction +    createDefCfa(MCSymbol *L, unsigned Register, int Offset) { +      return MCCFIInstruction(OpDefCfa, L, Register, -Offset, ""); +    } + +    static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) { +      return MCCFIInstruction(OpUndefined, L, Register, 0, "");      } -    MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register) -      : Operation(Op), Label(L), Destination(Register) { -      assert(Op == SameValue || Op == Restore); + +    static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) { +      return MCCFIInstruction(OpRestore, L, Register, 0, ""); +    } + +    static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) { +      return MCCFIInstruction(OpSameValue, L, Register, 0, ""); +    } + +    static MCCFIInstruction createRestoreState(MCSymbol *L) { +      return MCCFIInstruction(OpRestoreState, L, 0, 0, "");      } -    MCCFIInstruction(MCSymbol *L, const MachineLocation &D, -                     const MachineLocation &S) -      : Operation(Move), Label(L), Destination(D), Source(S) { + +    static MCCFIInstruction createRememberState(MCSymbol *L) { +      return MCCFIInstruction(OpRememberState, L, 0, 0, ""); +    } + +    static MCCFIInstruction +    createRelOffset(MCSymbol *L, unsigned Register, int Offset) { +      return MCCFIInstruction(OpRelOffset, L, Register, Offset, ""); +    } + +    static MCCFIInstruction +    createAdjustCfaOffset(MCSymbol *L, int Adjustment) { +      return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");      } -    MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D, -                     const MachineLocation &S) -      : Operation(Op), Label(L), Destination(D), Source(S) { -      assert(Op == RelMove); + +    static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) { +      return MCCFIInstruction(OpEscape, L, 0, 0, Vals);      } -    MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals) -      : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) { -      assert(Op == Escape); + +   static MCCFIInstruction +   createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) { +      return MCCFIInstruction(OpRegister, L, Register1, Register2);      } +      OpType getOperation() const { return Operation; }      MCSymbol *getLabel() const { return Label; } -    const MachineLocation &getDestination() const { return Destination; } -    const MachineLocation &getSource() const { return Source; } + +    unsigned getRegister() const { +      assert(Operation == OpDefCfa || Operation == OpOffset || +             Operation == OpRestore || Operation == OpUndefined || +             Operation == OpSameValue || Operation == OpDefCfaRegister || +             Operation == OpRelOffset || Operation == OpRegister); +      return Register; +    } + +    unsigned getRegister2() const { +      assert(Operation == OpRegister); +      return Register2; +    } + +    int getOffset() const { +      assert(Operation == OpDefCfa || Operation == OpOffset || +             Operation == OpRelOffset || Operation == OpDefCfaOffset || +             Operation == OpAdjustCfaOffset); +      return Offset; +    } +      const StringRef getValues() const { +      assert(Operation == OpEscape);        return StringRef(&Values[0], Values.size());      }    }; diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h new file mode 100644 index 000000000000..7e59911a89c3 --- /dev/null +++ b/include/llvm/MC/MCELF.h @@ -0,0 +1,37 @@ +//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains some support functions used by the ELF Streamer and +// ObjectWriter. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELF_H +#define LLVM_MC_MCELF_H + +#include "llvm/MC/MCExpr.h" + +namespace llvm { +class MCSymbolData; + +class MCELF { + public: +  static void SetBinding(MCSymbolData &SD, unsigned Binding); +  static unsigned GetBinding(const MCSymbolData &SD); +  static void SetType(MCSymbolData &SD, unsigned Type); +  static unsigned GetType(const MCSymbolData &SD); +  static void SetVisibility(MCSymbolData &SD, unsigned Visibility); +  static unsigned GetVisibility(MCSymbolData &SD); +  static void setOther(MCSymbolData &SD, unsigned Other); +  static unsigned getOther(MCSymbolData &SD); +}; + +} + +#endif diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 38cdc7293ba0..a59776d5cdaa 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -79,7 +79,6 @@ public:    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,                                  bool IsPCRel, bool IsRelocWithSymbol,                                  int64_t Addend) const = 0; -  virtual unsigned getEFlags() const;    virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,                                           const MCValue &Target,                                           const MCFragment &F, diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h new file mode 100644 index 000000000000..6fb2d22be2e7 --- /dev/null +++ b/include/llvm/MC/MCELFStreamer.h @@ -0,0 +1,125 @@ +//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCELFSTREAMER_H +#define LLVM_MC_MCELFSTREAMER_H + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/MC/SectionKind.h" +#include "llvm/Support/DataTypes.h" +#include <vector> + +namespace llvm { +class MCAsmBackend; +class MCAssembler; +class MCCodeEmitter; +class MCExpr; +class MCInst; +class MCSymbol; +class MCSymbolData; +class raw_ostream; + +class MCELFStreamer : public MCObjectStreamer { +protected: +  MCELFStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB, +                raw_ostream &OS, MCCodeEmitter *Emitter) +      : MCObjectStreamer(Kind, Context, TAB, OS, Emitter) {} + +public: +  MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, +                MCCodeEmitter *Emitter) +      : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter) {} + +  MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, +                MCCodeEmitter *Emitter, MCAssembler *Assembler) +      : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter, +                         Assembler) {} + +  virtual ~MCELFStreamer(); + +  /// @name MCStreamer Interface +  /// @{ + +  virtual void InitSections(); +  virtual void InitToTextSection(); +  virtual void ChangeSection(const MCSection *Section); +  virtual void EmitLabel(MCSymbol *Symbol); +  virtual void EmitDebugLabel(MCSymbol *Symbol); +  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); +  virtual void EmitThumbFunc(MCSymbol *Func); +  virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); +  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); +  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); +  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, +                                unsigned ByteAlignment); +  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); +  virtual void EmitCOFFSymbolStorageClass(int StorageClass); +  virtual void EmitCOFFSymbolType(int Type); +  virtual void EndCOFFSymbolDef(); + +  virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol); + +  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value); + +  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, +                                     unsigned ByteAlignment); + +  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, +                            uint64_t Size = 0, unsigned ByteAlignment = 0); +  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, +                              uint64_t Size, unsigned ByteAlignment = 0); +  virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, +                             unsigned AddrSpace); + +  virtual void EmitFileDirective(StringRef Filename); + +  virtual void EmitTCEntry(const MCSymbol &S); + +  virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned); + +  virtual void FinishImpl(); +  /// @} + +  static bool classof(const MCStreamer *S) { +    return S->getKind() == SK_ELFStreamer || S->getKind() == SK_ARMELFStreamer; +  } + +private: +  virtual void EmitInstToFragment(const MCInst &Inst); +  virtual void EmitInstToData(const MCInst &Inst); + +  virtual void EmitBundleAlignMode(unsigned AlignPow2); +  virtual void EmitBundleLock(bool AlignToEnd); +  virtual void EmitBundleUnlock(); + +  void fixSymbolsInTLSFixups(const MCExpr *expr); + +  struct LocalCommon { +    MCSymbolData *SD; +    uint64_t Size; +    unsigned ByteAlignment; +  }; + +  std::vector<LocalCommon> LocalCommons; + +  SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet; + + +  void SetSection(StringRef Section, unsigned Type, unsigned Flags, +                  SectionKind Kind); +  void SetSectionData(); +  void SetSectionText(); +  void SetSectionBss(); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 1007aa526493..b5bfed18eca4 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -160,6 +160,7 @@ public:      VK_TLVP,      // Mach-O thread local variable relocation      VK_SECREL,      // FIXME: We'd really like to use the generic Kinds listed above for these. +    VK_ARM_NONE,      VK_ARM_PLT,   // ARM-style PLT references. i.e., (PLT) instead of @PLT      VK_ARM_TLSGD, //   ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF      VK_ARM_GOT, @@ -168,15 +169,29 @@ public:      VK_ARM_GOTTPOFF,      VK_ARM_TARGET1,      VK_ARM_TARGET2, +    VK_ARM_PREL31,      VK_PPC_TOC,          // TOC base      VK_PPC_TOC_ENTRY,    // TOC entry      VK_PPC_DARWIN_HA16,  // ha16(symbol)      VK_PPC_DARWIN_LO16,  // lo16(symbol)      VK_PPC_GAS_HA16,     // symbol@ha -    VK_PPC_GAS_LO16,      // symbol@l +    VK_PPC_GAS_LO16,     // symbol@l      VK_PPC_TPREL16_HA,   // symbol@tprel@ha      VK_PPC_TPREL16_LO,   // symbol@tprel@l +    VK_PPC_DTPREL16_HA,  // symbol@dtprel@ha +    VK_PPC_DTPREL16_LO,  // symbol@dtprel@l +    VK_PPC_TOC16_HA,     // symbol@toc@ha +    VK_PPC_TOC16_LO,     // symbol@toc@l +    VK_PPC_GOT_TPREL16_HA, // symbol@got@tprel@ha +    VK_PPC_GOT_TPREL16_LO, // symbol@got@tprel@l +    VK_PPC_TLS,            // symbol@tls +    VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha +    VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l +    VK_PPC_TLSGD,          // symbol@tlsgd +    VK_PPC_GOT_TLSLD16_HA, // symbol@got@tlsld@ha +    VK_PPC_GOT_TLSLD16_LO, // symbol@got@tlsld@l +    VK_PPC_TLSLD,          // symbol@tlsld      VK_Mips_GPREL,      VK_Mips_GOT_CALL, @@ -457,6 +472,8 @@ public:    virtual void AddValueSymbols(MCAssembler *) const = 0;    virtual const MCSection *FindAssociatedSection() const = 0; +  virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; +    static bool classof(const MCExpr *E) {      return E->getKind() == MCExpr::Target;    } diff --git a/include/llvm/MC/MCFixedLenDisassembler.h b/include/llvm/MC/MCFixedLenDisassembler.h index 22b3c32abde9..ad99943df2c3 100644 --- a/include/llvm/MC/MCFixedLenDisassembler.h +++ b/include/llvm/MC/MCFixedLenDisassembler.h @@ -8,8 +8,8 @@  //===----------------------------------------------------------------------===//  // Fixed length disassembler decoder state machine driver.  //===----------------------------------------------------------------------===// -#ifndef MCFIXEDLENDISASSEMBLER_H -#define MCFIXEDLENDISASSEMBLER_H +#ifndef LLVM_MC_MCFIXEDLENDISASSEMBLER_H +#define LLVM_MC_MCFIXEDLENDISASSEMBLER_H  namespace llvm { diff --git a/include/llvm/MC/MCInstBuilder.h b/include/llvm/MC/MCInstBuilder.h new file mode 100644 index 000000000000..c5acb26eecac --- /dev/null +++ b/include/llvm/MC/MCInstBuilder.h @@ -0,0 +1,68 @@ +//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the MCInstBuilder class for convenient creation of +// MCInsts. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCINSTBUILDER_H +#define LLVM_MC_MCINSTBUILDER_H + +#include "llvm/MC/MCInst.h" + +namespace llvm { + +class MCInstBuilder { +  MCInst Inst; + +public: +  /// \brief Create a new MCInstBuilder for an MCInst with a specific opcode. +  MCInstBuilder(unsigned Opcode) { +    Inst.setOpcode(Opcode); +  } + +  /// \brief Add a new register operand. +  MCInstBuilder &addReg(unsigned Reg) { +    Inst.addOperand(MCOperand::CreateReg(Reg)); +    return *this; +  } + +  /// \brief Add a new integer immediate operand. +  MCInstBuilder &addImm(int64_t Val) { +    Inst.addOperand(MCOperand::CreateImm(Val)); +    return *this; +  } + +  /// \brief Add a new floating point immediate operand. +  MCInstBuilder &addFPImm(double Val) { +    Inst.addOperand(MCOperand::CreateFPImm(Val)); +    return *this; +  } + +  /// \brief Add a new MCExpr operand. +  MCInstBuilder &addExpr(const MCExpr *Val) { +    Inst.addOperand(MCOperand::CreateExpr(Val)); +    return *this; +  } + +  /// \brief Add a new MCInst operand. +  MCInstBuilder &addInst(const MCInst *Val) { +    Inst.addOperand(MCOperand::CreateInst(Val)); +    return *this; +  } + +  operator MCInst&() { +    return Inst; +  } +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 3b9420a40389..a18cbd94bbbf 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -10,6 +10,9 @@  #ifndef LLVM_MC_MCINSTPRINTER_H  #define LLVM_MC_MCINSTPRINTER_H +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Format.h" +  namespace llvm {  class MCInst;  class raw_ostream; @@ -36,13 +39,16 @@ protected:    /// True if we are printing marked up assembly.    bool UseMarkup; +  /// True if we are printing immediates as hex. +  bool PrintImmHex; +    /// Utility function for printing annotations.    void printAnnotation(raw_ostream &OS, StringRef Annot);  public:    MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,                  const MCRegisterInfo &mri)      : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0), -      UseMarkup(0) {} +      UseMarkup(0), PrintImmHex(0) {}    virtual ~MCInstPrinter(); @@ -70,6 +76,12 @@ public:    /// Utility functions to make adding mark ups simpler.    StringRef markup(StringRef s) const;    StringRef markup(StringRef a, StringRef b) const; + +  bool getPrintImmHex() const { return PrintImmHex; } +  void setPrintImmHex(bool Value) { PrintImmHex = Value; } + +  /// Utility function to print immediates in decimal or hex. +  format_object1<int64_t> formatImm(const int64_t Value) const;  };  } // namespace llvm diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 02383f8bc658..9b5415add241 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -15,6 +15,8 @@  #ifndef LLVM_MC_MCINSTRDESC_H  #define LLVM_MC_MCINSTRDESC_H +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h"  #include "llvm/Support/DataTypes.h"  namespace llvm { @@ -144,7 +146,7 @@ public:    const uint16_t *ImplicitDefs;  // Registers implicitly defined by this instr    const MCOperandInfo *OpInfo;   // 'NumOperands' entries about operands -  /// getOperandConstraint - Returns the value of the specific constraint if +  /// \brief Returns the value of the specific constraint if    /// it is set. Returns -1 if it is not set.    int getOperandConstraint(unsigned OpNum,                             MCOI::OperandConstraint Constraint) const { @@ -156,12 +158,12 @@ public:      return -1;    } -  /// getOpcode - Return the opcode number for this descriptor. +  /// \brief Return the opcode number for this descriptor.    unsigned getOpcode() const {      return Opcode;    } -  /// getNumOperands - Return the number of declared MachineOperands for this +  /// \brief Return the number of declared MachineOperands for this    /// MachineInstruction.  Note that variadic (isVariadic() returns true)    /// instructions may have additional operands at the end of the list, and note    /// that the machine instruction may include implicit register def/uses as @@ -170,7 +172,7 @@ public:      return NumOperands;    } -  /// getNumDefs - Return the number of MachineOperands that are register +  /// \brief Return the number of MachineOperands that are register    /// definitions.  Register definitions always occur at the start of the    /// machine operand list.  This is the number of "outs" in the .td file,    /// and does not include implicit defs. @@ -178,11 +180,10 @@ public:      return NumDefs;    } -  /// getFlags - Return flags of this instruction. -  /// +  /// \brief Return flags of this instruction.    unsigned getFlags() const { return Flags; } -  /// isVariadic - Return true if this instruction can have a variable number of +  /// \brief Return true if this instruction can have a variable number of    /// operands.  In this case, the variable operands will be after the normal    /// operands but before the implicit definitions and uses (if any are    /// present). @@ -190,35 +191,37 @@ public:      return Flags & (1 << MCID::Variadic);    } -  /// hasOptionalDef - Set if this instruction has an optional definition, e.g. +  /// \brief Set if this instruction has an optional definition, e.g.    /// ARM instructions which can set condition code if 's' bit is set.    bool hasOptionalDef() const {      return Flags & (1 << MCID::HasOptionalDef);    } -  /// isPseudo - Return true if this is a pseudo instruction that doesn't +  /// \brief Return true if this is a pseudo instruction that doesn't    /// correspond to a real machine instruction.    ///    bool isPseudo() const {      return Flags & (1 << MCID::Pseudo);    } +  /// \brief Return true if the instruction is a return.    bool isReturn() const {      return Flags & (1 << MCID::Return);    } +  /// \brief  Return true if the instruction is a call.    bool isCall() const {      return Flags & (1 << MCID::Call);    } -  /// isBarrier - Returns true if the specified instruction stops control flow +  /// \brief Returns true if the specified instruction stops control flow    /// from executing the instruction immediately following it.  Examples include    /// unconditional branches and return instructions.    bool isBarrier() const {      return Flags & (1 << MCID::Barrier);    } -  /// isTerminator - Returns true if this instruction part of the terminator for +  /// \brief Returns true if this instruction part of the terminator for    /// a basic block.  Typically this is things like return and branch    /// instructions.    /// @@ -228,7 +231,7 @@ public:      return Flags & (1 << MCID::Terminator);    } -  /// isBranch - Returns true if this is a conditional, unconditional, or +  /// \brief Returns true if this is a conditional, unconditional, or    /// indirect branch.  Predicates below can be used to discriminate between    /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to    /// get more information. @@ -236,13 +239,13 @@ public:      return Flags & (1 << MCID::Branch);    } -  /// isIndirectBranch - Return true if this is an indirect branch, such as a +  /// \brief Return true if this is an indirect branch, such as a    /// branch through a register.    bool isIndirectBranch() const {      return Flags & (1 << MCID::IndirectBranch);    } -  /// isConditionalBranch - Return true if this is a branch which may fall +  /// \brief Return true if this is a branch which may fall    /// through to the next instruction or may transfer control flow to some other    /// block.  The TargetInstrInfo::AnalyzeBranch method can be used to get more    /// information about this branch. @@ -250,7 +253,7 @@ public:      return isBranch() & !isBarrier() & !isIndirectBranch();    } -  /// isUnconditionalBranch - Return true if this is a branch which always +  /// \brief Return true if this is a branch which always    /// transfers control flow to some other block.  The    /// TargetInstrInfo::AnalyzeBranch method can be used to get more information    /// about this branch. @@ -258,38 +261,47 @@ public:      return isBranch() & isBarrier() & !isIndirectBranch();    } -  // isPredicable - Return true if this instruction has a predicate operand that -  // controls execution.  It may be set to 'always', or may be set to other -  /// values.   There are various methods in TargetInstrInfo that can be used to +  /// \brief Return true if this is a branch or an instruction which directly +  /// writes to the program counter. Considered 'may' affect rather than +  /// 'does' affect as things like predication are not taken into account. +  bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const { +    if (isBranch() || isCall() || isReturn() || isIndirectBranch()) +      return true; +    unsigned PC = RI.getProgramCounter(); +    if (PC == 0) return false; +    return hasDefOfPhysReg(MI, PC, RI); +  } + +  /// \brief Return true if this instruction has a predicate operand +  /// that controls execution. It may be set to 'always', or may be set to other +  /// values. There are various methods in TargetInstrInfo that can be used to    /// control and modify the predicate in this instruction.    bool isPredicable() const {      return Flags & (1 << MCID::Predicable);    } -  /// isCompare - Return true if this instruction is a comparison. +  /// \brief Return true if this instruction is a comparison.    bool isCompare() const {      return Flags & (1 << MCID::Compare);    } -  /// isMoveImmediate - Return true if this instruction is a move immediate +  /// \brief Return true if this instruction is a move immediate    /// (including conditional moves) instruction.    bool isMoveImmediate() const {      return Flags & (1 << MCID::MoveImm);    } -  /// isBitcast - Return true if this instruction is a bitcast instruction. -  /// +  /// \brief Return true if this instruction is a bitcast instruction.    bool isBitcast() const {      return Flags & (1 << MCID::Bitcast);    } -  /// isSelect - Return true if this is a select instruction. -  /// +  /// \brief Return true if this is a select instruction.    bool isSelect() const {      return Flags & (1 << MCID::Select);    } -  /// isNotDuplicable - Return true if this instruction cannot be safely +  /// \brief Return true if this instruction cannot be safely    /// duplicated.  For example, if the instruction has a unique labels attached    /// to it, duplicating it would cause multiple definition errors.    bool isNotDuplicable() const { @@ -318,7 +330,7 @@ public:    // Side Effect Analysis    //===--------------------------------------------------------------------===// -  /// mayLoad - Return true if this instruction could possibly read memory. +  /// \brief Return true if this instruction could possibly read memory.    /// Instructions with this flag set are not necessarily simple load    /// instructions, they may load a value and modify it, for example.    bool mayLoad() const { @@ -326,7 +338,7 @@ public:    } -  /// mayStore - Return true if this instruction could possibly modify memory. +  /// \brief Return true if this instruction could possibly modify memory.    /// Instructions with this flag set are not necessarily simple store    /// instructions, they may store a modified value based on their operands, or    /// may not actually modify anything, for example. @@ -459,8 +471,7 @@ public:      return ImplicitUses;    } -  /// getNumImplicitUses - Return the number of implicit uses this instruction -  /// has. +  /// \brief Return the number of implicit uses this instruction has.    unsigned getNumImplicitUses() const {      if (ImplicitUses == 0) return 0;      unsigned i = 0; @@ -482,8 +493,7 @@ public:      return ImplicitDefs;    } -  /// getNumImplicitDefs - Return the number of implicit defs this instruction -  /// has. +  /// \brief Return the number of implicit defs this instruct has.    unsigned getNumImplicitDefs() const {      if (ImplicitDefs == 0) return 0;      unsigned i = 0; @@ -491,7 +501,7 @@ public:      return i;    } -  /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly +  /// \brief Return true if this instruction implicitly    /// uses the specified physical register.    bool hasImplicitUseOfPhysReg(unsigned Reg) const {      if (const uint16_t *ImpUses = ImplicitUses) @@ -500,31 +510,43 @@ public:      return false;    } -  /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly +  /// \brief Return true if this instruction implicitly    /// defines the specified physical register. -  bool hasImplicitDefOfPhysReg(unsigned Reg) const { +  bool hasImplicitDefOfPhysReg(unsigned Reg, +                               const MCRegisterInfo *MRI = 0) const {      if (const uint16_t *ImpDefs = ImplicitDefs)        for (; *ImpDefs; ++ImpDefs) -        if (*ImpDefs == Reg) return true; +        if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs))) +            return true;      return false;    } -  /// getSchedClass - Return the scheduling class for this instruction.  The +  /// \brief Return true if this instruction defines the specified physical +  /// register, either explicitly or implicitly. +  bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg, +                       const MCRegisterInfo &RI) const { +    for (int i = 0, e = NumDefs; i != e; ++i) +      if (MI.getOperand(i).isReg() && +          RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) +        return true; +    return hasImplicitDefOfPhysReg(Reg, &RI); +  } + +  /// \brief Return the scheduling class for this instruction.  The    /// scheduling class is an index into the InstrItineraryData table.  This    /// returns zero if there is no known scheduling information for the    /// instruction. -  ///    unsigned getSchedClass() const {      return SchedClass;    } -  /// getSize - Return the number of bytes in the encoding of this instruction, +  /// \brief Return the number of bytes in the encoding of this instruction,    /// or zero if the encoding size cannot be known from the opcode.    unsigned getSize() const {      return Size;    } -  /// findFirstPredOperandIdx() - Find the index of the first operand in the +  /// \brief Find the index of the first operand in the    /// operand list that is used to represent the predicate. It returns -1 if    /// none is found.    int findFirstPredOperandIdx() const { diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index efaabfb9e88b..3c9a588d0413 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -45,6 +45,13 @@ protected:  public:    virtual ~MCMachObjectTargetWriter(); +  /// @name Lifetime Management +  /// @{ + +  virtual void reset() {}; + +  /// @} +    /// @name Accessors    /// @{ @@ -111,6 +118,13 @@ public:      : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {    } +  /// @name Lifetime management Methods +  /// @{ + +  virtual void reset(); + +  /// @} +    /// @name Utility Methods    /// @{ @@ -182,6 +196,8 @@ public:    void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,                                  uint32_t DataSize); +  void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options); +    // FIXME: We really need to improve the relocation validation. Basically, we    // want to implement a separate computation which evaluates the relocation    // entry as the linker would, and verifies that the resultant fixup value is @@ -223,8 +239,6 @@ public:    /// ComputeSymbolTable - Compute the symbol table data    ///    /// \param StringTable [out] - The string table data. -  /// \param StringIndexMap [out] - Map from symbol names to offsets in the -  /// string table.    void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,                            std::vector<MachSymbolData> &LocalSymbolData,                            std::vector<MachSymbolData> &ExternalSymbolData, diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index 23e5513ae35e..c8d748420e31 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -84,15 +84,6 @@ protected:    /// this is the section to emit them into.    const MCSection *CompactUnwindSection; -  /// DwarfAccelNamesSection, DwarfAccelObjCSection, -  /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - -  /// If we use the DWARF accelerated hash tables then we want toe emit these -  /// sections. -  const MCSection *DwarfAccelNamesSection; -  const MCSection *DwarfAccelObjCSection; -  const MCSection *DwarfAccelNamespaceSection; -  const MCSection *DwarfAccelTypesSection; -    // Dwarf sections for debug info.  If a target supports debug info, these must    // be set.    const MCSection *DwarfAbbrevSection; @@ -106,6 +97,28 @@ protected:    const MCSection *DwarfARangesSection;    const MCSection *DwarfRangesSection;    const MCSection *DwarfMacroInfoSection; +  // The pubnames section is no longer generated by default.  The generation +  // can be enabled by a compiler flag. +  const MCSection *DwarfPubNamesSection; + +  // DWARF5 Experimental Debug Info Sections +  /// DwarfAccelNamesSection, DwarfAccelObjCSection, +  /// DwarfAccelNamespaceSection, DwarfAccelTypesSection - +  /// If we use the DWARF accelerated hash tables then we want to emit these +  /// sections. +  const MCSection *DwarfAccelNamesSection; +  const MCSection *DwarfAccelObjCSection; +  const MCSection *DwarfAccelNamespaceSection; +  const MCSection *DwarfAccelTypesSection; + +  /// These are used for the Fission separate debug information files. +  const MCSection *DwarfInfoDWOSection; +  const MCSection *DwarfAbbrevDWOSection; +  const MCSection *DwarfStrDWOSection; +  const MCSection *DwarfLineDWOSection; +  const MCSection *DwarfLocDWOSection; +  const MCSection *DwarfStrOffDWOSection; +  const MCSection *DwarfAddrSection;    // Extra TLS Variable Data section.  If the target needs to put additional    // information for a TLS variable, it'll go here. @@ -195,22 +208,11 @@ public:    const MCSection *getCompactUnwindSection() const{      return CompactUnwindSection;    } -  const MCSection *getDwarfAccelNamesSection() const { -    return DwarfAccelNamesSection; -  } -  const MCSection *getDwarfAccelObjCSection() const { -    return DwarfAccelObjCSection; -  } -  const MCSection *getDwarfAccelNamespaceSection() const { -    return DwarfAccelNamespaceSection; -  } -  const MCSection *getDwarfAccelTypesSection() const { -    return DwarfAccelTypesSection; -  }    const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }    const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }    const MCSection *getDwarfLineSection() const { return DwarfLineSection; }    const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; } +  const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;}    const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;}    const MCSection *getDwarfDebugInlineSection() const {      return DwarfDebugInlineSection; @@ -222,6 +224,42 @@ public:    const MCSection *getDwarfMacroInfoSection() const {      return DwarfMacroInfoSection;    } + +  // DWARF5 Experimental Debug Info Sections +  const MCSection *getDwarfAccelNamesSection() const { +    return DwarfAccelNamesSection; +  } +  const MCSection *getDwarfAccelObjCSection() const { +    return DwarfAccelObjCSection; +  } +  const MCSection *getDwarfAccelNamespaceSection() const { +    return DwarfAccelNamespaceSection; +  } +  const MCSection *getDwarfAccelTypesSection() const { +    return DwarfAccelTypesSection; +  } +  const MCSection *getDwarfInfoDWOSection() const { +    return DwarfInfoDWOSection; +  } +  const MCSection *getDwarfAbbrevDWOSection() const { +    return DwarfAbbrevDWOSection; +  } +  const MCSection *getDwarfStrDWOSection() const { +    return DwarfStrDWOSection; +  } +  const MCSection *getDwarfLineDWOSection() const { +    return DwarfLineDWOSection; +  } +  const MCSection *getDwarfLocDWOSection() const { +    return DwarfLocDWOSection; +  } +  const MCSection *getDwarfStrOffDWOSection() const { +    return DwarfStrOffDWOSection; +  } +  const MCSection *getDwarfAddrSection() const { +    return DwarfAddrSection; +  } +    const MCSection *getTLSExtraDataSection() const {      return TLSExtraDataSection;    } diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 08b00f1c478e..f06c49ff082a 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -38,13 +38,18 @@ class MCObjectStreamer : public MCStreamer {    virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);  protected: -  MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, +  MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,                     raw_ostream &_OS, MCCodeEmitter *_Emitter); -  MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, +  MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,                     raw_ostream &_OS, MCCodeEmitter *_Emitter,                     MCAssembler *_Assembler);    ~MCObjectStreamer(); +public: +  /// state management +  virtual void reset(); + +protected:    MCSectionData *getCurrentSectionData() const {      return CurSectionData;    } @@ -64,6 +69,8 @@ public:    /// @{    virtual void EmitLabel(MCSymbol *Symbol); +  virtual void EmitDebugLabel(MCSymbol *Symbol); +  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);    virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,                               unsigned AddrSpace);    virtual void EmitULEB128Value(const MCExpr *Value); @@ -71,8 +78,15 @@ public:    virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);    virtual void ChangeSection(const MCSection *Section);    virtual void EmitInstruction(const MCInst &Inst); + +  /// \brief Emit an instruction to a special fragment, because this instruction +  /// can change its size during relaxation.    virtual void EmitInstToFragment(const MCInst &Inst); -  virtual void EmitBytes(StringRef Data, unsigned AddrSpace); + +  virtual void EmitBundleAlignMode(unsigned AlignPow2); +  virtual void EmitBundleLock(bool AlignToEnd); +  virtual void EmitBundleUnlock(); +  virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0);    virtual void EmitValueToAlignment(unsigned ByteAlignment,                                      int64_t Value = 0,                                      unsigned ValueSize = 1, @@ -89,10 +103,14 @@ public:    virtual void EmitGPRel32Value(const MCExpr *Value);    virtual void EmitGPRel64Value(const MCExpr *Value);    virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, -                        unsigned AddrSpace); +                        unsigned AddrSpace = 0);    virtual void FinishImpl();    /// @} + +  static bool classof(const MCStreamer *S) { +    return S->getKind() >= SK_ELFStreamer && S->getKind() <= SK_WinCOFFStreamer; +  }  };  } // end namespace llvm diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h index 14fe75fd4c31..4939a3f1fb07 100644 --- a/include/llvm/MC/MCObjectWriter.h +++ b/include/llvm/MC/MCObjectWriter.h @@ -10,9 +10,10 @@  #ifndef LLVM_MC_MCOBJECTWRITER_H  #define LLVM_MC_MCOBJECTWRITER_H -#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/SmallVector.h"  #include "llvm/Support/Compiler.h"  #include "llvm/Support/DataTypes.h" +#include "llvm/Support/raw_ostream.h"  #include <cassert>  namespace llvm { @@ -51,6 +52,9 @@ protected: // Can only create subclasses.  public:    virtual ~MCObjectWriter(); +  /// lifetime management +  virtual void reset() { } +    bool isLittleEndian() const { return IsLittleEndian; }    raw_ostream &getStream() { return OS; } @@ -58,15 +62,15 @@ public:    /// @name High-Level API    /// @{ -  /// Perform any late binding of symbols (for example, to assign symbol indices -  /// for use when generating relocations). +  /// \brief Perform any late binding of symbols (for example, to assign symbol +  /// indices for use when generating relocations).    ///    /// This routine is called by the assembler after layout and relaxation is    /// complete.    virtual void ExecutePostLayoutBinding(MCAssembler &Asm,                                          const MCAsmLayout &Layout) = 0; -  /// Record a relocation entry. +  /// \brief Record a relocation entry.    ///    /// This routine is called by the assembler after layout and relaxation, and    /// post layout binding. The implementation is responsible for storing @@ -96,8 +100,7 @@ public:                                           bool InSet,                                           bool IsPCRel) const; - -  /// Write the object file. +  /// \brief Write the object file.    ///    /// This routine is called by the assembler after layout and relaxation is    /// complete, fixups have been evaluated and applied, and relocations @@ -173,7 +176,13 @@ public:      OS << StringRef(Zeros, N % 16);    } +  void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) { +    WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize); +  } +    void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { +    // TODO: this version may need to go away once all fragment contents are +    // converted to SmallVector<char, N>      assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&        "data size greater than fill size, unexpected large write will occur");      OS << Str; diff --git a/include/llvm/MC/MCParser/AsmCond.h b/include/llvm/MC/MCParser/AsmCond.h index 92a115eb8038..a918b5600ed5 100644 --- a/include/llvm/MC/MCParser/AsmCond.h +++ b/include/llvm/MC/MCParser/AsmCond.h @@ -7,8 +7,8 @@  //  //===----------------------------------------------------------------------===// -#ifndef ASMCOND_H -#define ASMCOND_H +#ifndef LLVM_MC_MCPARSER_ASMCOND_H +#define LLVM_MC_MCPARSER_ASMCOND_H  namespace llvm { diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index e102dfb82c4a..0dab31489fbb 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -11,8 +11,8 @@  //  //===----------------------------------------------------------------------===// -#ifndef ASMLEXER_H -#define ASMLEXER_H +#ifndef LLVM_MC_MCPARSER_ASMLEXER_H +#define LLVM_MC_MCPARSER_ASMLEXER_H  #include "llvm/ADT/StringRef.h"  #include "llvm/MC/MCParser/MCAsmLexer.h" diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 0a961d6d0971..53b380f12f71 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -7,8 +7,8 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCASMLEXER_H -#define LLVM_MC_MCASMLEXER_H +#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H +#define LLVM_MC_MCPARSER_MCASMLEXER_H  #include "llvm/ADT/StringRef.h"  #include "llvm/Support/Compiler.h" @@ -34,9 +34,6 @@ public:      // Real values.      Real, -    // Register values (stored in IntVal).  Only used by MCTargetAsmLexer. -    Register, -      // No-value.      EndOfStatement,      Colon, @@ -104,13 +101,6 @@ public:      assert(Kind == Integer && "This token isn't an integer!");      return IntVal;    } - -  /// getRegVal - Get the register number for the current token, which should -  /// be a register. -  unsigned getRegVal() const { -    assert(Kind == Register && "This token isn't a register!"); -    return static_cast<unsigned>(IntVal); -  }  };  /// MCAsmLexer - Generic assembler lexer interface, for use by target specific diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index a71d3c321741..d7e3902ac478 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -7,14 +7,15 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCASMPARSER_H -#define LLVM_MC_MCASMPARSER_H +#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H +#define LLVM_MC_MCPARSER_MCASMPARSER_H -#include "llvm/Support/DataTypes.h"  #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCParser/AsmLexer.h" +#include "llvm/Support/DataTypes.h"  namespace llvm { -class AsmToken;  class MCAsmInfo;  class MCAsmLexer;  class MCAsmParserExtension; @@ -22,13 +23,11 @@ class MCContext;  class MCExpr;  class MCInstPrinter;  class MCInstrInfo; -class MCParsedAsmOperand;  class MCStreamer;  class MCTargetAsmParser;  class SMLoc;  class SMRange;  class SourceMgr; -class StringRef;  class Twine;  /// MCAsmParserSemaCallback - Generic Sema callback for assembly parser. @@ -36,16 +35,21 @@ class MCAsmParserSemaCallback {  public:    virtual ~MCAsmParserSemaCallback();     virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc, -                                          unsigned &Size) = 0; +                                          unsigned &Length, unsigned &Size,  +                                          unsigned &Type, bool &IsVarDecl) = 0; +    virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,                                      unsigned &Offset) = 0;  }; +  /// MCAsmParser - Generic assembler parser interface, for use by target specific  /// assembly parsers.  class MCAsmParser {  public:    typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc); +  typedef std::pair<MCAsmParserExtension*, DirectiveHandler> +    ExtensionDirectiveHandler;  private:    MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION; @@ -61,9 +65,8 @@ protected: // Can only create subclasses.  public:    virtual ~MCAsmParser(); -  virtual void AddDirectiveHandler(MCAsmParserExtension *Object, -                                   StringRef Directive, -                                   DirectiveHandler Handler) = 0; +  virtual void addDirectiveHandler(StringRef Directive, +                                   ExtensionDirectiveHandler Handler) = 0;    virtual SourceMgr &getSourceManager() = 0; @@ -89,8 +92,8 @@ public:    virtual void setParsingInlineAsm(bool V) = 0;    virtual bool isParsingInlineAsm() = 0; -  /// ParseMSInlineAsm - Parse ms-style inline assembly. -  virtual bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, +  /// parseMSInlineAsm - Parse ms-style inline assembly. +  virtual bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,                                  unsigned &NumOutputs, unsigned &NumInputs,                                  SmallVectorImpl<std::pair<void *, bool> > &OpDecls,                                  SmallVectorImpl<std::string> &Constraints, @@ -123,42 +126,50 @@ public:    bool TokError(const Twine &Msg,                  ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); -  /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) +  /// parseIdentifier - Parse an identifier or string (as a quoted identifier)    /// and set \p Res to the identifier contents. -  virtual bool ParseIdentifier(StringRef &Res) = 0; +  virtual bool parseIdentifier(StringRef &Res) = 0;    /// \brief Parse up to the end of statement and return the contents from the    /// current token until the end of the statement; the current token on exit    /// will be either the EndOfStatement or EOF. -  virtual StringRef ParseStringToEndOfStatement() = 0; +  virtual StringRef parseStringToEndOfStatement() = 0; + +  /// parseEscapedString - Parse the current token as a string which may include +  /// escaped characters and return the string contents. +  virtual bool parseEscapedString(std::string &Data) = 0; -  /// EatToEndOfStatement - Skip to the end of the current statement, for error +  /// eatToEndOfStatement - Skip to the end of the current statement, for error    /// recovery. -  virtual void EatToEndOfStatement() = 0; +  virtual void eatToEndOfStatement() = 0; -  /// ParseExpression - Parse an arbitrary expression. +  /// parseExpression - Parse an arbitrary expression.    ///    /// @param Res - The value of the expression. The result is undefined    /// on error.    /// @result - False on success. -  virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; -  bool ParseExpression(const MCExpr *&Res); +  virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; +  bool parseExpression(const MCExpr *&Res); -  /// ParseParenExpression - Parse an arbitrary expression, assuming that an +  /// parseParenExpression - Parse an arbitrary expression, assuming that an    /// initial '(' has already been consumed.    ///    /// @param Res - The value of the expression. The result is undefined    /// on error.    /// @result - False on success. -  virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; +  virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0; -  /// ParseAbsoluteExpression - Parse an expression which must evaluate to an +  /// parseAbsoluteExpression - Parse an expression which must evaluate to an    /// absolute value.    ///    /// @param Res - The value of the absolute expression. The result is undefined    /// on error.    /// @result - False on success. -  virtual bool ParseAbsoluteExpression(int64_t &Res) = 0; +  virtual bool parseAbsoluteExpression(int64_t &Res) = 0; + +  /// checkForValidSection - Ensure that we have a valid section set in the +  /// streamer. Otherwise, report an error and switch to .text. +  virtual void checkForValidSection() = 0;  };  /// \brief Create an MCAsmParser instance. diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index 0918c93bdf3d..2eda3a9a2143 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -7,11 +7,11 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCASMPARSEREXTENSION_H -#define LLVM_MC_MCASMPARSEREXTENSION_H +#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H +#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H -#include "llvm/MC/MCParser/MCAsmParser.h"  #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCParser/MCAsmParser.h"  #include "llvm/Support/SMLoc.h"  namespace llvm { diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 60e7887a5396..4650bf21be7e 100644 --- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -7,8 +7,8 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCASMOPERAND_H -#define LLVM_MC_MCASMOPERAND_H +#ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H +#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H  namespace llvm {  class SMLoc; @@ -57,18 +57,15 @@ public:    /// isMem - Is this a memory operand?    virtual bool isMem() const = 0; -  virtual unsigned getMemSize() const { return 0; }    /// getStartLoc - Get the location of the first token of this operand.    virtual SMLoc getStartLoc() const = 0;    /// getEndLoc - Get the location of the last token of this operand.    virtual SMLoc getEndLoc() const = 0; -  /// needAsmRewrite - AsmRewrites happen in both the target-independent and -  /// target-dependent parsers.  The target-independent parser calls this -  /// function to determine if the target-dependent parser has already taken -  /// care of the rewrites.  Only valid when parsing MS-style inline assembly. -  virtual bool needAsmRewrite() const { return true; } +  /// needAddressOf - Do we need to emit code to get the address of the +  /// variable/label?   Only valid when parsing MS-style inline assembly. +  virtual bool needAddressOf() const { return false; }    /// isOffsetOf - Do we need to emit code to get the offset of the variable,    /// rather then the value of the variable?   Only valid when parsing MS-style @@ -78,10 +75,6 @@ public:    /// getOffsetOfLoc - Get the location of the offset operator.    virtual SMLoc getOffsetOfLoc() const { return SMLoc(); } -  /// needSizeDirective - Do we need to emit a sizing directive for this -  /// operand?  Only valid when parsing MS-style inline assembly. -  virtual bool needSizeDirective() const { return false; } -    /// print - Print a debug representation of the operand to the given stream.    virtual void print(raw_ostream &OS) const = 0;    /// dump - Print to the debug stream. diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index f05baeaaf689..f5b4dddc5198 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -22,11 +22,15 @@  namespace llvm { +/// An unsigned integer type large enough to represent all physical registers, +/// but not necessarily virtual registers. +typedef uint16_t MCPhysReg; +  /// MCRegisterClass - Base class of TargetRegisterClass.  class MCRegisterClass {  public: -  typedef const uint16_t* iterator; -  typedef const uint16_t* const_iterator; +  typedef const MCPhysReg* iterator; +  typedef const MCPhysReg* const_iterator;    const char *Name;    const iterator RegsBegin; @@ -148,11 +152,12 @@ private:    const MCRegisterDesc *Desc;                 // Pointer to the descriptor array    unsigned NumRegs;                           // Number of entries in the array    unsigned RAReg;                             // Return address register +  unsigned PCReg;                             // Program counter register    const MCRegisterClass *Classes;             // Pointer to the regclass array    unsigned NumClasses;                        // Number of entries in the array    unsigned NumRegUnits;                       // Number of regunits.    const uint16_t (*RegUnitRoots)[2];          // Pointer to regunit root table. -  const uint16_t *DiffLists;                  // Pointer to the difflists array +  const MCPhysReg *DiffLists;                 // Pointer to the difflists array    const char *RegStrings;                     // Pointer to the string table.    const uint16_t *SubRegIndices;              // Pointer to the subreg lookup                                                // array. @@ -177,7 +182,7 @@ public:    /// defined below.    class DiffListIterator {      uint16_t Val; -    const uint16_t *List; +    const MCPhysReg *List;    protected:      /// Create an invalid iterator. Call init() to point to something useful. @@ -186,7 +191,7 @@ public:      /// init - Point the iterator to InitVal, decoding subsequent values from      /// DiffList. The iterator will initially point to InitVal, sub-classes are      /// responsible for skipping the seed value if it is not part of the list. -    void init(uint16_t InitVal, const uint16_t *DiffList) { +    void init(MCPhysReg InitVal, const MCPhysReg *DiffList) {        Val = InitVal;        List = DiffList;      } @@ -196,7 +201,7 @@ public:      /// is the caller's responsibility (by checking for a 0 return value).      unsigned advance() {        assert(isValid() && "Cannot move off the end of the list."); -      uint16_t D = *List++; +      MCPhysReg D = *List++;        Val += D;        return D;      } @@ -225,13 +230,14 @@ public:    friend class MCRegUnitIterator;    friend class MCRegUnitRootIterator; -  /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen +  /// \brief Initialize MCRegisterInfo, called by TableGen    /// auto-generated routines. *DO NOT USE*.    void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, +                          unsigned PC,                            const MCRegisterClass *C, unsigned NC,                            const uint16_t (*RURoots)[2],                            unsigned NRU, -                          const uint16_t *DL, +                          const MCPhysReg *DL,                            const char *Strings,                            const uint16_t *SubIndices,                            unsigned NumIndices, @@ -239,6 +245,7 @@ public:      Desc = D;      NumRegs = NR;      RAReg = RA; +    PCReg = PC;      Classes = C;      DiffLists = DL;      RegStrings = Strings; @@ -250,7 +257,7 @@ public:      RegEncodingTable = RET;    } -  /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf +  /// \brief Used to initialize LLVM register to Dwarf    /// register number mapping. Called by TableGen auto-generated routines.    /// *DO NOT USE*.    void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, @@ -264,7 +271,7 @@ public:      }    } -  /// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM +  /// \brief Used to initialize Dwarf register to LLVM    /// register number mapping. Called by TableGen auto-generated routines.    /// *DO NOT USE*.    void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, @@ -287,77 +294,80 @@ public:      L2SEHRegs[LLVMReg] = SEHReg;    } -  /// getRARegister - This method should return the register where the return +  /// \brief This method should return the register where the return    /// address can be found.    unsigned getRARegister() const {      return RAReg;    } +  /// Return the register which is the program counter. +  unsigned getProgramCounter() const { +    return PCReg; +  } +    const MCRegisterDesc &operator[](unsigned RegNo) const {      assert(RegNo < NumRegs &&             "Attempting to access record for invalid register number!");      return Desc[RegNo];    } -  /// Provide a get method, equivalent to [], but more useful if we have a +  /// \brief Provide a get method, equivalent to [], but more useful with a    /// pointer to this object. -  ///    const MCRegisterDesc &get(unsigned RegNo) const {      return operator[](RegNo);    } -  /// getSubReg - Returns the physical register number of sub-register "Index" +  /// \brief Returns the physical register number of sub-register "Index"    /// for physical register RegNo. Return zero if the sub-register does not    /// exist.    unsigned getSubReg(unsigned Reg, unsigned Idx) const; -  /// getMatchingSuperReg - Return a super-register of the specified register +  /// \brief Return a super-register of the specified register    /// Reg so its sub-register of index SubIdx is Reg.    unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,                                 const MCRegisterClass *RC) const; -  /// getSubRegIndex - For a given register pair, return the sub-register index +  /// \brief For a given register pair, return the sub-register index    /// if the second register is a sub-register of the first. Return zero    /// otherwise.    unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; -  /// getName - Return the human-readable symbolic target-specific name for the +  /// \brief Return the human-readable symbolic target-specific name for the    /// specified physical register.    const char *getName(unsigned RegNo) const {      return RegStrings + get(RegNo).Name;    } -  /// getNumRegs - Return the number of registers this target has (useful for +  /// \brief Return the number of registers this target has (useful for    /// sizing arrays holding per register information)    unsigned getNumRegs() const {      return NumRegs;    } -  /// getNumSubRegIndices - Return the number of sub-register indices +  /// \brief Return the number of sub-register indices    /// understood by the target. Index 0 is reserved for the no-op sub-register,    /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers.    unsigned getNumSubRegIndices() const {      return NumSubRegIndices;    } -  /// getNumRegUnits - Return the number of (native) register units in the +  /// \brief Return the number of (native) register units in the    /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They    /// can be accessed through MCRegUnitIterator defined below.    unsigned getNumRegUnits() const {      return NumRegUnits;    } -  /// getDwarfRegNum - Map a target register to an equivalent dwarf register +  /// \brief Map a target register to an equivalent dwarf register    /// number.  Returns -1 if there is no equivalent value.  The second    /// parameter allows targets to use different numberings for EH info and    /// debugging info.    int getDwarfRegNum(unsigned RegNum, bool isEH) const; -  /// getLLVMRegNum - Map a dwarf register back to a target register. -  /// +  /// \brief Map a dwarf register back to a target register.    int getLLVMRegNum(unsigned RegNum, bool isEH) const; -  /// getSEHRegNum - Map a target register to an equivalent SEH register +  /// \brief Map a target register to an equivalent SEH register    /// number.  Returns LLVM register number if there is no equivalent value.    int getSEHRegNum(unsigned RegNum) const; @@ -368,20 +378,39 @@ public:      return (unsigned)(regclass_end()-regclass_begin());    } -  /// getRegClass - Returns the register class associated with the enumeration +  /// \brief Returns the register class associated with the enumeration    /// value.  See class MCOperandInfo.    const MCRegisterClass& getRegClass(unsigned i) const {      assert(i < getNumRegClasses() && "Register Class ID out of range");      return Classes[i];    } -   /// getEncodingValue - Returns the encoding for RegNo +   /// \brief Returns the encoding for RegNo    uint16_t getEncodingValue(unsigned RegNo) const {      assert(RegNo < NumRegs &&             "Attempting to get encoding for invalid register number!");      return RegEncodingTable[RegNo];    } +  /// \brief Returns true if RegB is a sub-register of RegA. +  bool isSubRegister(unsigned RegA, unsigned RegB) const { +    return isSuperRegister(RegB, RegA); +  } + +  /// \brief Returns true if RegB is a super-register of RegA. +  bool isSuperRegister(unsigned RegA, unsigned RegB) const; + +  /// \brief Returns true if RegB is a sub-register of RegA or if RegB == RegA. +  bool isSubRegisterEq(unsigned RegA, unsigned RegB) const { +    return isSuperRegisterEq(RegB, RegA); +  } + +  /// \brief Returns true if RegB is a super-register of RegA or if +  /// RegB == RegA. +  bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const { +    return RegA == RegB || isSuperRegister(RegA, RegB); +  } +  };  //===----------------------------------------------------------------------===// @@ -422,6 +451,15 @@ public:    }  }; +// Definition for isSuperRegister. Put it down here since it needs the +// iterator defined above in addition to the MCRegisterInfo class itself. +inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{ +  for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I) +    if (*I == RegB) +      return true; +  return false; +} +  //===----------------------------------------------------------------------===//  //                               Register Units  //===----------------------------------------------------------------------===// @@ -441,6 +479,7 @@ public:    /// MCRegUnitIterator - Create an iterator that traverses the register units    /// in Reg.    MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) { +    assert(Reg && "Null register has no regunits");      // Decode the RegUnits MCRegisterDesc field.      unsigned RU = MCRI->get(Reg).RegUnits;      unsigned Scale = RU & 15; @@ -480,17 +519,17 @@ public:      Reg1 = MCRI->RegUnitRoots[RegUnit][1];    } -  /// Dereference to get the current root register. +  /// \brief Dereference to get the current root register.    unsigned operator*() const {      return Reg0;    } -  /// isValid - Check if the iterator is at the end of the list. +  /// \brief Check if the iterator is at the end of the list.    bool isValid() const {      return Reg0;    } -  /// Preincrement to move to the next root register. +  /// \brief Preincrement to move to the next root register.    void operator++() {      assert(isValid() && "Cannot move off the end of the list.");      Reg0 = Reg1; diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h index 0c71ee513500..defa29903543 100644 --- a/include/llvm/MC/MCSchedule.h +++ b/include/llvm/MC/MCSchedule.h @@ -12,8 +12,8 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCSCHEDMODEL_H -#define LLVM_MC_MCSCHEDMODEL_H +#ifndef LLVM_MC_MCSCHEDULE_H +#define LLVM_MC_MCSCHEDULE_H  #include "llvm/Support/DataTypes.h"  #include <cassert> @@ -155,7 +155,7 @@ public:    //      Optional InstrItinerary OperandCycles provides expected latency.    //      TODO: can't yet specify both min and expected latency per operand.    int MinLatency; -  static const unsigned DefaultMinLatency = -1; +  static const int DefaultMinLatency = -1;    // LoadLatency is the expected latency of load instructions.    // @@ -172,6 +172,16 @@ public:    unsigned HighLatency;    static const unsigned DefaultHighLatency = 10; +  // ILPWindow is the number of cycles that the scheduler effectively ignores +  // before attempting to hide latency. This should be zero for in-order cpus to +  // always hide expected latency. For out-of-order cpus, it may be tweaked as +  // desired to roughly approximate instruction buffers. The actual threshold is +  // not very important for an OOO processor, as long as it isn't too high. A +  // nonzero value helps avoid rescheduling to hide latency when its is fairly +  // obviously useless and makes register pressure heuristics more effective. +  unsigned ILPWindow; +  static const unsigned DefaultILPWindow = 0; +    // MispredictPenalty is the typical number of extra cycles the processor    // takes to recover from a branch misprediction.    unsigned MispredictPenalty; @@ -196,6 +206,7 @@ public:                    MinLatency(DefaultMinLatency),                    LoadLatency(DefaultLoadLatency),                    HighLatency(DefaultHighLatency), +                  ILPWindow(DefaultILPWindow),                    MispredictPenalty(DefaultMispredictPenalty),                    ProcID(0), ProcResourceTable(0), SchedClassTable(0),                    NumProcResourceKinds(0), NumSchedClasses(0), @@ -205,12 +216,12 @@ public:    }    // Table-gen driven ctor. -  MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp, -               unsigned pi, const MCProcResourceDesc *pr, +  MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned ilp, +               unsigned mp, unsigned pi, const MCProcResourceDesc *pr,                 const MCSchedClassDesc *sc, unsigned npr, unsigned nsc,                 const InstrItinerary *ii):      IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), -    MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr), +    ILPWindow(ilp), MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),      SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc),      InstrItineraries(ii) {} diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 21fdb6bd39b8..e5754249e91b 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -14,6 +14,7 @@  #ifndef LLVM_MC_MCSECTION_H  #define LLVM_MC_MCSECTION_H +#include "llvm/ADT/StringRef.h"  #include "llvm/MC/SectionKind.h"  #include "llvm/Support/Compiler.h" @@ -49,6 +50,11 @@ namespace llvm {      virtual void PrintSwitchToSection(const MCAsmInfo &MAI,                                        raw_ostream &OS) const = 0; +    // Convenience routines to get label names for the beginning/end of a +    // section. +    virtual std::string getLabelBeginName() const = 0; +    virtual std::string getLabelEndName() const = 0; +      /// isBaseAddressKnownZero - Return true if we know that this section will      /// get a base address of zero.  In cases where we know that this is true we      /// can emit section offsets as direct references to avoid a subtraction diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index b050c0f442b6..07c47144cbdc 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -14,9 +14,9 @@  #ifndef LLVM_MC_MCSECTIONCOFF_H  #define LLVM_MC_MCSECTIONCOFF_H +#include "llvm/ADT/StringRef.h"  #include "llvm/MC/MCSection.h"  #include "llvm/Support/COFF.h" -#include "llvm/ADT/StringRef.h"  namespace llvm { @@ -50,6 +50,12 @@ namespace llvm {      bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;      StringRef getSectionName() const { return SectionName; } +    virtual std::string getLabelBeginName() const { +      return SectionName.str() + "_begin"; +    } +    virtual std::string getLabelEndName() const { +      return SectionName.str() + "_end"; +    }      unsigned getCharacteristics() const { return Characteristics; }      int getSelection () const { return Selection; } diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 4d54465760d4..4b8b849c79ed 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -14,9 +14,11 @@  #ifndef LLVM_MC_MCSECTIONELF_H  #define LLVM_MC_MCSECTIONELF_H +#include "llvm/ADT/StringRef.h"  #include "llvm/MC/MCSection.h" +#include "llvm/Support/Debug.h"  #include "llvm/Support/ELF.h" -#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h"  namespace llvm { @@ -57,6 +59,11 @@ public:    bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;    StringRef getSectionName() const { return SectionName; } +  virtual std::string getLabelBeginName() const { +    return SectionName.str() + "_begin"; } +  virtual std::string getLabelEndName() const { +    return SectionName.str() + "_end"; +  }    unsigned getType() const { return Type; }    unsigned getFlags() const { return Flags; }    unsigned getEntrySize() const { return EntrySize; } diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 71ea8f3e901d..898f5714907f 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -14,8 +14,8 @@  #ifndef LLVM_MC_MCSECTIONMACHO_H  #define LLVM_MC_MCSECTIONMACHO_H -#include "llvm/MC/MCSection.h"  #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCSection.h"  namespace llvm { @@ -145,6 +145,14 @@ public:      return StringRef(SectionName);    } +  virtual std::string getLabelBeginName() const { +    return StringRef(getSegmentName().str() + getSectionName().str() + "_begin"); +  } + +  virtual std::string getLabelEndName() const { +    return StringRef(getSegmentName().str() + getSectionName().str() + "_end"); +  } +    unsigned getTypeAndAttributes() const { return TypeAndAttributes; }    unsigned getStubSize() const { return Reserved2; } diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 230d27ef2ef0..a069a2b0cafa 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -14,12 +14,14 @@  #ifndef LLVM_MC_MCSTREAMER_H  #define LLVM_MC_MCSTREAMER_H -#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCAssembler.h"  #include "llvm/MC/MCDirectives.h"  #include "llvm/MC/MCDwarf.h"  #include "llvm/MC/MCWin64EH.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" +#include <string>  namespace llvm {    class MCAsmBackend; @@ -45,6 +47,23 @@ namespace llvm {    /// a .s file, and implementations that write out .o files of various formats.    ///    class MCStreamer { +  public: +    enum StreamerKind { +      SK_AsmStreamer, +      SK_NullStreamer, +      SK_RecordStreamer, + +      // MCObjectStreamer subclasses. +      SK_ELFStreamer, +      SK_ARMELFStreamer, +      SK_MachOStreamer, +      SK_PureStreamer, +      SK_MipsELFStreamer, +      SK_WinCOFFStreamer +    }; + +  private: +    const StreamerKind Kind;      MCContext &Context;      MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION; @@ -55,6 +74,7 @@ namespace llvm {      std::vector<MCDwarfFrameInfo> FrameInfos;      MCDwarfFrameInfo *getCurrentFrameInfo(); +    MCSymbol *EmitCFICommon();      void EnsureValidFrame();      std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos; @@ -69,8 +89,10 @@ namespace llvm {      SmallVector<std::pair<const MCSection *,                  const MCSection *>, 4> SectionStack; +    bool AutoInitSections; +    protected: -    MCStreamer(MCContext &Ctx); +    MCStreamer(StreamerKind Kind, MCContext &Ctx);      const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,                                    const MCSymbol *B); @@ -89,6 +111,12 @@ namespace llvm {    public:      virtual ~MCStreamer(); +    StreamerKind getKind() const { return Kind; } + +    /// State management +    /// +    virtual void reset(); +      MCContext &getContext() const { return Context; }      unsigned getNumFrameInfos() { @@ -213,9 +241,23 @@ namespace llvm {          SectionStack.back().first = Section;      } +    /// Initialize the streamer. +    void InitStreamer() { +      if (AutoInitSections) +        InitSections(); +    } + +    /// Tell this MCStreamer to call InitSections upon initialization. +    void setAutoInitSections(bool AutoInitSections) { +      this->AutoInitSections = AutoInitSections; +    } +      /// InitSections - Create the default sections and set the initial one.      virtual void InitSections() = 0; +    /// InitToTextSection - Create a text section and switch the streamer to it. +    virtual void InitToTextSection() = 0; +      /// EmitLabel - Emit a label for @p Symbol into the current section.      ///      /// This corresponds to an assembler statement such as: @@ -226,12 +268,18 @@ namespace llvm {      /// used in an assignment.      virtual void EmitLabel(MCSymbol *Symbol); +    virtual void EmitDebugLabel(MCSymbol *Symbol); +      virtual void EmitEHSymAttributes(const MCSymbol *Symbol,                                       MCSymbol *EHSymbol);      /// EmitAssemblerFlag - Note in the output the specified @p Flag.      virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; +    /// EmitLinkerOptions - Emit the given list @p Options of strings as linker +    /// options into the output. +    virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {} +      /// EmitDataRegion - Note in the output the specified region @p Kind.      virtual void EmitDataRegion(MCDataRegionType Kind) {} @@ -239,6 +287,9 @@ namespace llvm {      /// a Thumb mode function (ARM target only).      virtual void EmitThumbFunc(MCSymbol *Func) = 0; +    /// getOrCreateSymbolData - Get symbol data for given symbol. +    virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol); +      /// EmitAssignment - Emit an assignment of @p Value to @p Symbol.      ///      /// This corresponds to an assembler statement such as: @@ -346,7 +397,7 @@ namespace llvm {      ///      /// This is used to implement assembler directives such as .byte, .ascii,      /// etc. -    virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0; +    virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0) = 0;      /// EmitValue - Emit the expression @p Value into the output as a native      /// integer of the given @p Size bytes. @@ -380,8 +431,8 @@ namespace llvm {      /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the      /// client having to pass in a MCExpr for constant integers. -    void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0, -                             unsigned Padding = 0); +    void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0, +                             unsigned AddrSpace = 0);      /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the      /// client having to pass in a MCExpr for constant integers. @@ -409,15 +460,14 @@ namespace llvm {      /// EmitFill - Emit NumBytes bytes worth of the value specified by      /// FillValue.  This implements directives such as '.space'.      virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue, -                          unsigned AddrSpace); +                          unsigned AddrSpace = 0);      /// EmitZeros - Emit NumBytes worth of zeros.  This is a convenience      /// function that just wraps EmitFill. -    void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) { +    void EmitZeros(uint64_t NumBytes, unsigned AddrSpace = 0) {        EmitFill(NumBytes, 0, AddrSpace);      } -      /// EmitValueToAlignment - Emit some number of copies of @p Value until      /// the byte alignment @p ByteAlignment is reached.      /// @@ -475,7 +525,7 @@ namespace llvm {      /// file number.  This implements the DWARF2 '.file 4 "foo.c"' assembler      /// directive.      virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, -                                        StringRef Filename); +                                        StringRef Filename, unsigned CUID = 0);      /// EmitDwarfLocDirective - This implements the DWARF2      // '.loc fileno lineno ...' assembler directive. @@ -515,6 +565,8 @@ namespace llvm {      virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);      virtual void EmitCFIEscape(StringRef Values);      virtual void EmitCFISignalFrame(); +    virtual void EmitCFIUndefined(int64_t Register); +    virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);      virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);      virtual void EmitWin64EHEndProc(); @@ -535,6 +587,20 @@ namespace llvm {      /// section.      virtual void EmitInstruction(const MCInst &Inst) = 0; +    /// \brief Set the bundle alignment mode from now on in the section. +    /// The argument is the power of 2 to which the alignment is set. The +    /// value 0 means turn the bundle alignment off. +    virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0; + +    /// \brief The following instructions are a bundle-locked group. +    /// +    /// \param AlignToEnd - If true, the bundle-locked group will be aligned to +    ///                     the end of a bundle. +    virtual void EmitBundleLock(bool AlignToEnd) = 0; + +    /// \brief Ends a bundle-locked group. +    virtual void EmitBundleUnlock() = 0; +      /// EmitRawText - If this file is backed by a assembly streamer, this dumps      /// the specified string in the output .s file.  This capability is      /// indicated by the hasRawTextSupport() predicate.  By default this aborts. diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index 69213cd77d92..346fb2df0ffc 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -14,8 +14,8 @@  #ifndef LLVM_MC_MCSUBTARGET_H  #define LLVM_MC_MCSUBTARGET_H -#include "llvm/MC/SubtargetFeature.h"  #include "llvm/MC/MCInstrItineraries.h" +#include "llvm/MC/SubtargetFeature.h"  #include <string>  namespace llvm { diff --git a/include/llvm/MC/MCTargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h deleted file mode 100644 index b1cc546e1efa..000000000000 --- a/include/llvm/MC/MCTargetAsmLexer.h +++ /dev/null @@ -1,89 +0,0 @@ -//===-- llvm/MC/MCTargetAsmLexer.h - Target Assembly Lexer ------*- C++ -*-===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_MC_MCTARGETASMLEXER_H -#define LLVM_MC_MCTARGETASMLEXER_H - -#include "llvm/MC/MCParser/MCAsmLexer.h" - -namespace llvm { -class Target; - -/// MCTargetAsmLexer - Generic interface to target specific assembly lexers. -class MCTargetAsmLexer { -  /// The current token -  AsmToken CurTok; - -  /// The location and description of the current error -  SMLoc ErrLoc; -  std::string Err; - -  MCTargetAsmLexer(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION; -  void operator=(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION; -protected: // Can only create subclasses. -  MCTargetAsmLexer(const Target &); - -  virtual AsmToken LexToken() = 0; - -  void SetError(const SMLoc &errLoc, const std::string &err) { -    ErrLoc = errLoc; -    Err = err; -  } - -  /// TheTarget - The Target that this machine was created for. -  const Target &TheTarget; -  MCAsmLexer *Lexer; - -public: -  virtual ~MCTargetAsmLexer(); - -  const Target &getTarget() const { return TheTarget; } - -  /// InstallLexer - Set the lexer to get tokens from lower-level lexer \p L. -  void InstallLexer(MCAsmLexer &L) { -    Lexer = &L; -  } - -  MCAsmLexer *getLexer() { -    return Lexer; -  } - -  /// Lex - Consume the next token from the input stream and return it. -  const AsmToken &Lex() { -    return CurTok = LexToken(); -  } - -  /// getTok - Get the current (last) lexed token. -  const AsmToken &getTok() { -    return CurTok; -  } - -  /// getErrLoc - Get the current error location -  const SMLoc &getErrLoc() { -    return ErrLoc; -  } - -  /// getErr - Get the current error string -  const std::string &getErr() { -    return Err; -  } - -  /// getKind - Get the kind of current token. -  AsmToken::TokenKind getKind() const { return CurTok.getKind(); } - -  /// is - Check if the current token has kind \p K. -  bool is(AsmToken::TokenKind K) const { return CurTok.is(K); } - -  /// isNot - Check if the current token has kind \p K. -  bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 483a80b3b595..4c5b17612569 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -22,6 +22,7 @@ class MCInst;  template <typename T> class SmallVectorImpl;  enum AsmRewriteKind { +  AOK_Align,          // Rewrite align as .align.    AOK_DotOperator,    // Rewrite a dot operator expression as an immediate.                        // E.g., [eax].foo.bar -> [eax].8    AOK_Emit,           // Rewrite _emit as .byte. @@ -142,6 +143,15 @@ public:                            MCStreamer &Out, unsigned &ErrorInfo,                            bool MatchingInlineAsm) = 0; +  /// Allow a target to add special case operand matching for things that +  /// tblgen doesn't/can't handle effectively. For example, literal +  /// immediates on ARM. TableGen expects a token operand, but the parser +  /// will recognize them as immediates. +  virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, +                                              unsigned Kind) { +    return Match_InvalidOperand; +  } +    /// checkTargetMatchPredicate - Validate the instruction match against    /// any complex target predicates not expressible via match classes.    virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index f9af8bcfbf61..a4e730111484 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -14,8 +14,8 @@  #ifndef LLVM_MC_MCVALUE_H  #define LLVM_MC_MCVALUE_H -#include "llvm/Support/DataTypes.h"  #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/DataTypes.h"  #include <cassert>  namespace llvm { diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h index 7a0b1ffaf0a0..11df5749d450 100644 --- a/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -11,6 +11,9 @@  #define LLVM_MC_MCWINCOFFOBJECTWRITER_H  namespace llvm { +  class MCObjectWriter; +  class raw_ostream; +    class MCWinCOFFObjectTargetWriter {      const unsigned Machine; diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index 57f0518cbf3a..37ae03b45ca2 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -18,9 +18,9 @@  #ifndef LLVM_MC_SUBTARGETFEATURE_H  #define LLVM_MC_SUBTARGETFEATURE_H -#include <vector>  #include "llvm/ADT/Triple.h"  #include "llvm/Support/DataTypes.h" +#include <vector>  namespace llvm {    class raw_ostream;  | 
