ARM64: initial backend import
[oota-llvm.git] / include / llvm / MC / MCAssembler.h
index 981002f79814198c0546af10a55e5724de92a868..34b760c46ee69d14a5ccc375ff713b745e1bb931 100644 (file)
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/ilist.h"
 #include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCDirectives.h"
 #include "llvm/MC/MCFixup.h"
 #include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/DataTypes.h"
+#include <algorithm>
 #include <vector> // FIXME: Shouldn't be needed.
 
 namespace llvm {
@@ -32,6 +36,7 @@ class MCFragment;
 class MCObjectWriter;
 class MCSection;
 class MCSectionData;
+class MCSubtargetInfo;
 class MCSymbol;
 class MCSymbolData;
 class MCValue;
@@ -47,6 +52,7 @@ public:
   enum FragmentType {
     FT_Align,
     FT_Data,
+    FT_Compressed,
     FT_CompactEncodedInst,
     FT_Fill,
     FT_Relaxable,
@@ -63,8 +69,7 @@ private:
   MCSectionData *Parent;
 
   /// Atom - The atom this fragment is in, as represented by it's defining
-  /// symbol. Atom's are only used by backends which set
-  /// \see MCAsmBackend::hasReliableSymbolDifference().
+  /// symbol.
   MCSymbolData *Atom;
 
   /// @name Assembler Backend Data
@@ -142,11 +147,11 @@ public:
   virtual SmallVectorImpl<char> &getContents() = 0;
   virtual const SmallVectorImpl<char> &getContents() const = 0;
 
-  virtual uint8_t getBundlePadding() const {
+  uint8_t getBundlePadding() const override {
     return BundlePadding;
   }
 
-  virtual void setBundlePadding(uint8_t N) {
+  void setBundlePadding(uint8_t N) override {
     BundlePadding = N;
   }
 
@@ -157,6 +162,7 @@ public:
         return false;
       case MCFragment::FT_Relaxable:
       case MCFragment::FT_CompactEncodedInst:
+      case MCFragment::FT_Compressed:
       case MCFragment::FT_Data:
         return true;
     }
@@ -167,7 +173,7 @@ public:
 /// data and also have fixups registered.
 ///
 class MCEncodedFragmentWithFixups : public MCEncodedFragment {
-  virtual void anchor();
+  void anchor() override;
 
 public:
   MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
@@ -191,14 +197,15 @@ public:
 
   static bool classof(const MCFragment *F) {
     MCFragment::FragmentType Kind = F->getKind();
-    return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
+    return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
+           Kind == MCFragment::FT_Compressed;
   }
 };
 
 /// Fragment for data and encoded instructions.
 ///
 class MCDataFragment : public MCEncodedFragmentWithFixups {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief Does this fragment contain encoded instructions anywhere in it?
   bool HasInstructions;
@@ -210,6 +217,11 @@ class MCDataFragment : public MCEncodedFragmentWithFixups {
 
   /// Fixups - The list of fixups in this fragment.
   SmallVector<MCFixup, 4> Fixups;
+protected:
+  MCDataFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
+      : MCEncodedFragmentWithFixups(FType, SD), HasInstructions(false),
+        AlignToBundleEnd(false) {}
+
 public:
   MCDataFragment(MCSectionData *SD = 0)
     : MCEncodedFragmentWithFixups(FT_Data, SD),
@@ -217,41 +229,54 @@ public:
   {
   }
 
-  virtual SmallVectorImpl<char> &getContents() { return Contents; }
-  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override {
+    return Contents;
+  }
 
-  SmallVectorImpl<MCFixup> &getFixups() {
+  SmallVectorImpl<MCFixup> &getFixups() override {
     return Fixups;
   }
 
-  const SmallVectorImpl<MCFixup> &getFixups() const {
+  const SmallVectorImpl<MCFixup> &getFixups() const override {
     return Fixups;
   }
 
-  virtual bool hasInstructions() const { return HasInstructions; }
+  bool hasInstructions() const override { return HasInstructions; }
   virtual void setHasInstructions(bool V) { HasInstructions = V; }
 
-  virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
-  virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+  bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+  void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
 
-  fixup_iterator fixup_begin() { return Fixups.begin(); }
-  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+  fixup_iterator fixup_begin() override { return Fixups.begin(); }
+  const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
 
-  fixup_iterator fixup_end() {return Fixups.end();}
-  const_fixup_iterator fixup_end() const {return Fixups.end();}
+  fixup_iterator fixup_end() override {return Fixups.end();}
+  const_fixup_iterator fixup_end() const override {return Fixups.end();}
 
   static bool classof(const MCFragment *F) {
-    return F->getKind() == MCFragment::FT_Data;
+    return F->getKind() == MCFragment::FT_Data ||
+           F->getKind() == MCFragment::FT_Compressed;
   }
 };
 
+class MCCompressedFragment: public MCDataFragment {
+  mutable SmallVector<char, 32> CompressedContents;
+public:
+  MCCompressedFragment(MCSectionData *SD = nullptr)
+      : MCDataFragment(FT_Compressed, SD) {}
+  const SmallVectorImpl<char> &getCompressedContents() const;
+  using MCDataFragment::getContents;
+  SmallVectorImpl<char> &getContents() override;
+};
+
 /// 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();
+  void anchor() override;
 
   /// \brief Should this fragment be aligned to the end of a bundle?
   bool AlignToBundleEnd;
@@ -263,15 +288,15 @@ public:
   {
   }
 
-  virtual bool hasInstructions() const {
+  bool hasInstructions() const override {
     return true;
   }
 
-  virtual SmallVectorImpl<char> &getContents() { return Contents; }
-  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override { return Contents; }
 
-  virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
-  virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+  bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+  void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
 
   static bool classof(const MCFragment *F) {
     return F->getKind() == MCFragment::FT_CompactEncodedInst;
@@ -282,11 +307,16 @@ public:
 /// relaxed during the assembler layout and relaxation stage.
 ///
 class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
-  virtual void anchor();
+  void anchor() override;
 
   /// Inst - The instruction this is a fragment for.
   MCInst Inst;
 
+  /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
+  /// Keep a copy instead of a reference to make sure that updates to STI
+  /// in the assembler are not seen here.
+  const MCSubtargetInfo STI;
+
   /// Contents - Binary data for the currently encoded instruction.
   SmallVector<char, 8> Contents;
 
@@ -294,31 +324,35 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
   SmallVector<MCFixup, 1> Fixups;
 
 public:
-  MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
-    : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
+  MCRelaxableFragment(const MCInst &_Inst,
+                      const MCSubtargetInfo &_STI,
+                      MCSectionData *SD = 0)
+    : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
   }
 
-  virtual SmallVectorImpl<char> &getContents() { return Contents; }
-  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override { return Contents; }
 
   const MCInst &getInst() const { return Inst; }
   void setInst(const MCInst& Value) { Inst = Value; }
 
-  SmallVectorImpl<MCFixup> &getFixups() {
+  const MCSubtargetInfo &getSubtargetInfo() { return STI; }
+
+  SmallVectorImpl<MCFixup> &getFixups() override {
     return Fixups;
   }
 
-  const SmallVectorImpl<MCFixup> &getFixups() const {
+  const SmallVectorImpl<MCFixup> &getFixups() const override {
     return Fixups;
   }
 
-  virtual bool hasInstructions() const { return true; }
+  bool hasInstructions() const override { return true; }
 
-  fixup_iterator fixup_begin() { return Fixups.begin(); }
-  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+  fixup_iterator fixup_begin() override { return Fixups.begin(); }
+  const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
 
-  fixup_iterator fixup_end() {return Fixups.end();}
-  const_fixup_iterator fixup_end() const {return Fixups.end();}
+  fixup_iterator fixup_end() override {return Fixups.end();}
+  const_fixup_iterator fixup_end() const override {return Fixups.end();}
 
   static bool classof(const MCFragment *F) {
     return F->getKind() == MCFragment::FT_Relaxable;
@@ -451,7 +485,7 @@ class MCLEBFragment : public MCFragment {
 
   SmallString<8> Contents;
 public:
-  MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
+  MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0)
     : MCFragment(FT_LEB, SD),
       Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
 
@@ -487,7 +521,7 @@ class MCDwarfLineAddrFragment : public MCFragment {
 
 public:
   MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
-                      MCSectionData *SD)
+                      MCSectionData *SD = 0)
     : MCFragment(FT_Dwarf, SD),
       LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
 
@@ -518,7 +552,7 @@ class MCDwarfCallFrameFragment : public MCFragment {
   SmallString<8> Contents;
 
 public:
-  MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,  MCSectionData *SD)
+  MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,  MCSectionData *SD = 0)
     : MCFragment(FT_DwarfFrame, SD),
       AddrDelta(&_AddrDelta) { Contents.push_back(0); }
 
@@ -590,6 +624,10 @@ private:
   /// it.
   unsigned HasInstructions : 1;
 
+  /// Mapping from subsection number to insertion point for subsection numbers
+  /// below that number.
+  SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
+
   /// @}
 
 public:
@@ -633,6 +671,8 @@ public:
 
   bool empty() const { return Fragments.empty(); }
 
+  iterator getSubsectionInsertionPoint(unsigned Subsection);
+
   bool isBundleLocked() const {
     return BundleLockState != NotBundleLocked;
   }
@@ -810,6 +850,9 @@ public:
   typedef SymbolDataListType::const_iterator const_symbol_iterator;
   typedef SymbolDataListType::iterator symbol_iterator;
 
+  typedef std::vector<std::string> FileNameVectorType;
+  typedef FileNameVectorType::const_iterator const_file_name_iterator;
+
   typedef std::vector<IndirectSymbolData>::const_iterator
     const_indirect_symbol_iterator;
   typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
@@ -818,6 +861,15 @@ public:
     const_data_region_iterator;
   typedef std::vector<DataRegionData>::iterator data_region_iterator;
 
+  /// MachO specific deployment target version info.
+  // A Major version of 0 indicates that no version information was supplied
+  // and so the corresponding load command should not be emitted.
+  typedef struct {
+    MCVersionMinType Kind;
+    unsigned Major;
+    unsigned Minor;
+    unsigned Update;
+  } VersionMinInfoType;
 private:
   MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
   void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
@@ -849,6 +901,13 @@ 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;
+
+  /// List of declared file names
+  FileNameVectorType FileNames;
+
   /// The set of function symbols for which a .thumb_func directive has
   /// been seen.
   //
@@ -867,6 +926,18 @@ private:
   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;
+
+  /// Used to communicate Linker Optimization Hint information between
+  /// the Streamer and the .o writer
+  MCLOHContainer LOHContainer;
+
+  VersionMinInfoType VersionMinInfo;
 private:
   /// Evaluate a fixup to a relocatable expression and the value which should be
   /// placed into the fixup.
@@ -913,8 +984,8 @@ private:
   /// finishLayout - Finalize a layout, including fragment lowering.
   void finishLayout(MCAsmLayout &Layout);
 
-  uint64_t handleFixup(const MCAsmLayout &Layout,
-                       MCFragment &F, const MCFixup &Fixup);
+  std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
+                                        MCFragment &F, const MCFixup &Fixup);
 
 public:
   /// Compute the effective fragment size assuming it is laid out at the given
@@ -944,6 +1015,20 @@ 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;}
+
+  /// MachO deployment target version information.
+  const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; }
+  void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+                         unsigned Update) {
+    VersionMinInfo.Kind = Kind;
+    VersionMinInfo.Major = Major;
+    VersionMinInfo.Minor = Minor;
+    VersionMinInfo.Update = Update;
+  }
+
 public:
   /// Construct a new assembler instance.
   ///
@@ -1059,6 +1144,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
   /// @{
@@ -1086,6 +1179,19 @@ public:
 
   size_t data_region_size() const { return DataRegions.size(); }
 
+  /// @}
+  /// @name Data Region List Access
+  /// @{
+
+  // FIXME: This is a total hack, this should not be here. Once things are
+  // factored so that the streamer has direct access to the .o writer, it can
+  // disappear.
+  MCLOHContainer & getLOHContainer() {
+    return LOHContainer;
+  }
+  const MCLOHContainer & getLOHContainer() const {
+    return const_cast<MCAssembler *>(this)->getLOHContainer();
+  }
   /// @}
   /// @name Backend Data Access
   /// @{
@@ -1107,6 +1213,10 @@ public:
     return *Entry;
   }
 
+  bool hasSymbolData(const MCSymbol &Symbol) const {
+    return SymbolMap.lookup(&Symbol) != 0;
+  }
+
   MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
     MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
     assert(Entry && "Missing symbol data!");
@@ -1124,6 +1234,20 @@ public:
     return *Entry;
   }
 
+  const_file_name_iterator file_names_begin() const {
+    return FileNames.begin();
+  }
+
+  const_file_name_iterator file_names_end() const {
+    return FileNames.end();
+  }
+
+  void addFileName(StringRef FileName) {
+    if (std::find(file_names_begin(), file_names_end(), FileName) ==
+        file_names_end())
+      FileNames.push_back(FileName);
+  }
+
   /// @}
 
   void dump();