18dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
28dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
38dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//                     The LLVM Compiler Infrastructure
48dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
58dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// This file is distributed under the University of Illinois Open Source
68dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// License. See LICENSE.TXT for details.
78dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
88dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===----------------------------------------------------------------------===//
98dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
108dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#ifndef LLVM_MC_MCOBJECTSTREAMER_H
118dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#define LLVM_MC_MCOBJECTSTREAMER_H
128dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
13df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne#include "llvm/MC/MCAssembler.h"
148dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCStreamer.h"
158dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
168dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarnamespace llvm {
178dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass MCAssembler;
188dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass MCCodeEmitter;
198dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass MCSectionData;
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass MCSubtargetInfo;
218067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerclass MCExpr;
228067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerclass MCFragment;
238067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerclass MCDataFragment;
2478c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Chengclass MCAsmBackend;
258dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass raw_ostream;
268dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
278dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// \brief Streaming object file generation interface.
288dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar///
298dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// This class provides an implementation of the MCStreamer interface which is
308dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// suitable for use with the assembler backend. Specific object file formats
318dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// are expected to subclass this interface to implement directives specific
328dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// to that file format or custom semantics expected by the object writer
338dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar/// implementation.
348dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarclass MCObjectStreamer : public MCStreamer {
358dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  MCAssembler *Assembler;
3683b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  MCSectionData *CurSectionData;
37df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  MCSectionData::iterator CurInsertionPoint;
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool EmitEHFrame;
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool EmitDebugFrame;
408dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
44f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
458dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarprotected:
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
475e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola                   MCCodeEmitter *_Emitter);
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   MCCodeEmitter *_Emitter, MCAssembler *_Assembler);
508dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  ~MCObjectStreamer();
518dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
525399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigaspublic:
535399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas  /// state management
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void reset() override;
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Object streamers require the integrated assembler.
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isIntegratedAssemblerRequired() const override { return true; }
585399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) {
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return getAssembler().getOrCreateSymbolData(*Symbol);
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitFrames(MCAsmBackend *MAB);
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitCFISections(bool EH, bool Debug) override;
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
655399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigasprotected:
6683b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  MCSectionData *getCurrentSectionData() const {
6783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar    return CurSectionData;
6883b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  }
6983b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
708067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  MCFragment *getCurrentFragment() const;
718067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
72df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  void insert(MCFragment *F) const {
73df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    CurSectionData->getFragmentList().insert(CurInsertionPoint, F);
74df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    F->setParent(CurSectionData);
75df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  }
76df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne
778067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  /// Get a data fragment to write into, creating a new one if the current
788067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  /// fragment is not a data fragment.
798067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  MCDataFragment *getOrCreateDataFragment() const;
808067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
818dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarpublic:
82cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void visitUsedSymbol(const MCSymbol &Sym) override;
83cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
848dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  MCAssembler &getAssembler() { return *Assembler; }
8583b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
8683b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  /// @name MCStreamer Interface
8783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  /// @{
8883b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitLabel(MCSymbol *Symbol) override;
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void EmitValueImpl(const MCExpr *Value, unsigned Size,
92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     const SMLoc &Loc = SMLoc()) override;
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitULEB128Value(const MCExpr *Value) override;
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitSLEB128Value(const MCExpr *Value) override;
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void ChangeSection(const MCSection *Section,
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     const MCExpr *Subsection) override;
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo& STI) override;
994766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky
1004766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  /// \brief Emit an instruction to a special fragment, because this instruction
1014766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  /// can change its size during relaxation.
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitBundleAlignMode(unsigned AlignPow2) override;
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitBundleLock(bool AlignToEnd) override;
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitBundleUnlock() override;
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitBytes(StringRef Data) override;
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                            unsigned ValueSize = 1,
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                            unsigned MaxBytesToEmit = 0) override;
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitCodeAlignment(unsigned ByteAlignment,
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         unsigned MaxBytesToEmit = 0) override;
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value) override;
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             unsigned Column, unsigned Flags,
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             unsigned Isa, unsigned Discriminator,
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             StringRef FileName) override;
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                const MCSymbol *Label,
120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                unsigned PointerSize);
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                 const MCSymbol *Label);
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitGPRel32Value(const MCExpr *Value) override;
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitGPRel64Value(const MCExpr *Value) override;
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitZeros(uint64_t NumBytes) override;
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void FinishImpl() override;
128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  virtual bool mayHaveInstructions() const {
130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return getCurrentSectionData()->hasInstructions();
131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1328dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar};
1338dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
1348dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar} // end namespace llvm
1358dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
1368dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#endif
137