Replace .mips_hack_stocg with ".set micromips" and ".set nomicromips".
[oota-llvm.git] / include / llvm / MC / MCStreamer.h
index a5f8bc05bc7562bcafdd25fcde18694ac0b1c97e..fb94f9d5ffee98e64dc0fef9358d9634b7f251c0 100644 (file)
@@ -31,6 +31,7 @@ class MCExpr;
 class MCInst;
 class MCInstPrinter;
 class MCSection;
+class MCStreamer;
 class MCSymbol;
 class StringRef;
 class Twine;
@@ -39,6 +40,69 @@ class formatted_raw_ostream;
 
 typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
 
+/// Target specific streamer interface. This is used so that targets can
+/// implement support for target specific assembly directives.
+///
+/// If target foo wants to use this, it should implement 3 classes:
+/// * FooTargetStreamer : public MCTargetStreamer
+/// * FooTargetAsmSreamer : public FooTargetStreamer
+/// * FooTargetELFStreamer : public FooTargetStreamer
+///
+/// FooTargetStreamer should have a pure virtual method for each directive. For
+/// example, for a ".bar symbol_name" directive, it should have
+/// virtual emitBar(const MCSymbol &Symbol) = 0;
+///
+/// The FooTargetAsmSreamer and FooTargetELFStreamer classes implement the
+/// method. The assembly streamer just prints ".bar symbol_name". The object
+/// streamer does whatever is needed to implement .bar in the object file.
+///
+/// In the assembly printer and parser the target streamer can be used by
+/// calling getTargetStreamer and casting it to FooTargetStreamer:
+///
+/// MCTargetStreamer &TS = OutStreamer.getTargetStreamer();
+/// FooTargetStreamer &ATS = static_cast<FooTargetStreamer &>(TS);
+///
+/// The base classes FooTargetAsmSreamer and FooTargetELFStreamer should *never*
+/// be treated differently. Callers should always talk to a FooTargetStreamer.
+class MCTargetStreamer {
+protected:
+  MCStreamer *Streamer;
+
+public:
+  virtual ~MCTargetStreamer();
+  void setStreamer(MCStreamer *S) { Streamer = S; }
+
+  // Allow a target to add behavior to the EmitLabel of MCStreamer.
+  virtual void emitLabel(MCSymbol *Symbol);
+};
+
+// FIXME: declared here because it is used from
+// lib/CodeGen/AsmPrinter/ARMException.cpp.
+class ARMTargetStreamer : public MCTargetStreamer {
+  virtual void anchor();
+public:
+  virtual void emitFnStart() = 0;
+  virtual void emitFnEnd() = 0;
+  virtual void emitCantUnwind() = 0;
+  virtual void emitPersonality(const MCSymbol *Personality) = 0;
+  virtual void emitHandlerData() = 0;
+  virtual void emitSetFP(unsigned FpReg, unsigned SpReg,
+                         int64_t Offset = 0) = 0;
+  virtual void emitPad(int64_t Offset) = 0;
+  virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
+                           bool isVector) = 0;
+
+  virtual void switchVendor(StringRef Vendor) = 0;
+  virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0;
+  virtual void emitTextAttribute(unsigned Attribute, StringRef String) = 0;
+  virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
+                                   StringRef StringValue = "") = 0;
+  virtual void emitFPU(unsigned FPU) = 0;
+  virtual void emitArch(unsigned Arch) = 0;
+  virtual void finishAttributeSection() = 0;
+  virtual void emitInst(uint32_t Inst, char Suffix = '\0') = 0;
+};
+
 /// MCStreamer - Streaming machine code generation interface.  This interface
 /// is intended to provide a programatic interface that is very similar to the
 /// level that an assembler .s file provides.  It has callbacks to emit bytes,
@@ -49,24 +113,8 @@ typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
 /// 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;
+  OwningPtr<MCTargetStreamer> TargetStreamer;
 
   MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION;
   MCStreamer &operator=(const MCStreamer &) LLVM_DELETED_FUNCTION;
@@ -97,7 +145,7 @@ private:
   bool AutoInitSections;
 
 protected:
-  MCStreamer(StreamerKind Kind, MCContext &Ctx);
+  MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer);
 
   const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
                                 const MCSymbol *B);
@@ -115,17 +163,21 @@ protected:
   }
   void EmitW64Tables();
 
+  virtual void EmitRawTextImpl(StringRef String);
+
 public:
   virtual ~MCStreamer();
 
-  StreamerKind getKind() const { return Kind; }
-
   /// State management
   ///
   virtual void reset();
 
   MCContext &getContext() const { return Context; }
 
+  MCTargetStreamer *getTargetStreamer() {
+    return TargetStreamer.get();
+  }
+
   unsigned getNumFrameInfos() { return FrameInfos.size(); }
 
   const MCDwarfFrameInfo &getFrameInfo(unsigned i) { return FrameInfos[i]; }
@@ -288,6 +340,8 @@ public:
   /// @param Symbol - The symbol to emit. A given symbol should only be
   /// emitted as a label once, and symbols emitted as a label should never be
   /// used in an assignment.
+  // FIXME: These emission are non-const because we mutate the symbol to
+  // add the section we're emitting it to later.
   virtual void EmitLabel(MCSymbol *Symbol);
 
   virtual void EmitDebugLabel(MCSymbol *Symbol);
@@ -361,9 +415,14 @@ public:
   /// EndCOFFSymbolDef - Marks the end of the symbol definition.
   virtual void EndCOFFSymbolDef() = 0;
 
+  /// EmitCOFFSectionIndex - Emits a COFF section index.
+  ///
+  /// @param Symbol - Symbol the section number relocation should point to.
+  virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
+
   /// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
   ///
-  /// @param Symbol - Symbol the section relative realocation should point to.
+  /// @param Symbol - Symbol the section relative relocation should point to.
   virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
 
   /// EmitELFSize - Emit an ELF .size directive.
@@ -534,6 +593,10 @@ public:
   /// implement the '.file "foo.c"' assembler directive.
   virtual void EmitFileDirective(StringRef Filename) = 0;
 
+  /// Emit the "identifiers" directive.  This implements the
+  /// '.ident "version foo"' assembler directive.
+  virtual void EmitIdent(StringRef IdentString) {}
+
   /// EmitDwarfFileDirective - Associate a filename with a specified logical
   /// file number.  This implements the DWARF2 '.file 4 "foo.c"' assembler
   /// directive.
@@ -616,27 +679,8 @@ public:
   /// 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.
-  virtual void EmitRawText(StringRef String);
   void EmitRawText(const Twine &String);
 
-  /// ARM-related methods.
-  /// FIXME: Eventually we should have some "target MC streamer" and move
-  /// these methods there.
-  virtual void EmitFnStart();
-  virtual void EmitFnEnd();
-  virtual void EmitCantUnwind();
-  virtual void EmitPersonality(const MCSymbol *Personality);
-  virtual void EmitHandlerData();
-  virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
-  virtual void EmitPad(int64_t Offset);
-  virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
-                           bool isVector);
-
-  /// PPC-related methods.
-  /// FIXME: Eventually replace it with some "target MC streamer" and move
-  /// these methods there.
-  virtual void EmitTCEntry(const MCSymbol &S);
-
   /// Flush - Causes any cached state to be written out.
   virtual void Flush() {}
 
@@ -667,9 +711,9 @@ MCStreamer *createNullStreamer(MCContext &Ctx);
 ///
 /// \param ShowInst - Whether to show the MCInst representation inline with
 /// the assembly.
-MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
-                              bool isVerboseAsm, bool useLoc, bool useCFI,
-                              bool useDwarfDirectory,
+MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
+                              formatted_raw_ostream &OS, bool isVerboseAsm,
+                              bool useLoc, bool useCFI, bool useDwarfDirectory,
                               MCInstPrinter *InstPrint = 0,
                               MCCodeEmitter *CE = 0, MCAsmBackend *TAB = 0,
                               bool ShowInst = false);
@@ -692,8 +736,9 @@ MCStreamer *createWinCOFFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
 
 /// createELFStreamer - Create a machine code streamer which will generate
 /// ELF format object files.
-MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
-                              raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll,
+MCStreamer *createELFStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
+                              MCAsmBackend &TAB, raw_ostream &OS,
+                              MCCodeEmitter *CE, bool RelaxAll,
                               bool NoExecStack);
 
 /// createPureStreamer - Create a machine code streamer which will generate