MCAssembler.h revision 6a3cbc35a75468d565385a0db8e7051478f383f4
1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen//===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen//
3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen//                     The LLVM Compiler Infrastructure
4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen//
5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen// This file is distributed under the University of Illinois Open Source
6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen// License. See LICENSE.TXT for details.
7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen//
8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen//===----------------------------------------------------------------------===//
9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#ifndef LLVM_MC_MCASSEMBLER_H
11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#define LLVM_MC_MCASSEMBLER_H
12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/ADT/DenseMap.h"
14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/ADT/SmallPtrSet.h"
15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/ADT/SmallString.h"
16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/ADT/ilist.h"
17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/ADT/ilist_node.h"
18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/MC/MCFixup.h"
19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/MC/MCInst.h"
20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/Support/Casting.h"
21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include "llvm/Support/DataTypes.h"
22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen#include <vector> // FIXME: Shouldn't be needed.
23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogennamespace llvm {
25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass raw_ostream;
26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCAsmLayout;
27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCAssembler;
28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCContext;
29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCCodeEmitter;
30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCExpr;
31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCFragment;
32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCObjectWriter;
33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCSection;
34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCSectionData;
35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCSymbol;
36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCSymbolData;
37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCValue;
38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCAsmBackend;
39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCFragment : public ilist_node<MCFragment> {
41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  friend class MCAsmLayout;
42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic:
47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  enum FragmentType {
48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_Align,
49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_Data,
50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_CompactEncodedInst,
51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_Fill,
52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_Relaxable,
53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_Org,
54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_Dwarf,
55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_DwarfFrame,
56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    FT_LEB
57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  };
58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenprivate:
60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  FragmentType Kind;
61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// Parent - The data for the section this fragment is in.
63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCSectionData *Parent;
64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// Atom - The atom this fragment is in, as represented by it's defining
66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// symbol. Atom's are only used by backends which set
67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// \see MCAsmBackend::hasReliableSymbolDifference().
68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCSymbolData *Atom;
69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// @name Assembler Backend Data
71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// @{
72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  //
73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  // FIXME: This could all be kept private to the assembler implementation.
74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// Offset - The offset of this fragment in its section. This is ~0 until
76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// initialized.
77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  uint64_t Offset;
78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// LayoutOrder - The layout order of this fragment.
80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  unsigned LayoutOrder;
81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// @}
83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenprotected:
85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic:
88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  // Only for sentinel.
89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCFragment();
90674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual ~MCFragment();
91674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
92674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  FragmentType getKind() const { return Kind; }
93674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
94674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCSectionData *getParent() const { return Parent; }
95674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  void setParent(MCSectionData *Value) { Parent = Value; }
96674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
97674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCSymbolData *getAtom() const { return Atom; }
98674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  void setAtom(MCSymbolData *Value) { Atom = Value; }
99674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
100674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  unsigned getLayoutOrder() const { return LayoutOrder; }
101674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
102674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
103674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// \brief Does this fragment have instructions emitted into it? By default
104674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// this is false, but specific fragment types may set it to true.
105674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual bool hasInstructions() const { return false; }
106674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
107674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// \brief Should this fragment be placed at the end of an aligned bundle?
108674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual bool alignToBundleEnd() const { return false; }
109674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual void setAlignToBundleEnd(bool V) { }
110674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
111674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// \brief Get the padding size that must be inserted before this fragment.
112674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// Used for bundling. By default, no padding is inserted.
113674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// Note that padding size is restricted to 8 bits. This is an optimization
114674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// to reduce the amount of space used for each fragment. In practice, larger
115674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// padding should never be required.
116674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual uint8_t getBundlePadding() const {
117674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    return 0;
118674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  }
119674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
120674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// \brief Set the padding size for this fragment. By default it's a no-op,
121674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  /// and only some fragments have a meaningful implementation.
122674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual void setBundlePadding(uint8_t N) {
123674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  }
124674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
125674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  void dump();
126674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen};
127674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
128674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/// Interface implemented by fragments that contain encoded instructions and/or
129674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/// data.
130674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen///
131674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCEncodedFragment : public MCFragment {
132674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual void anchor();
133674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
134674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  uint8_t BundlePadding;
135674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic:
136674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
137674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    : MCFragment(FType, SD), BundlePadding(0)
138674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  {
139674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  }
140674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual ~MCEncodedFragment();
141674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
142674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual SmallVectorImpl<char> &getContents() = 0;
143674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual const SmallVectorImpl<char> &getContents() const = 0;
144674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
145674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual uint8_t getBundlePadding() const {
146674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    return BundlePadding;
147674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  }
148674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
149674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual void setBundlePadding(uint8_t N) {
150674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    BundlePadding = N;
151674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  }
152674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
153674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  static bool classof(const MCFragment *F) {
154674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    MCFragment::FragmentType Kind = F->getKind();
155674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    switch (Kind) {
156674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      default:
157674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return false;
158674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      case MCFragment::FT_Relaxable:
159674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      case MCFragment::FT_CompactEncodedInst:
160674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      case MCFragment::FT_Data:
161674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return true;
162674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
163674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  }
164674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen};
165674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
166674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/// Interface implemented by fragments that contain encoded instructions and/or
167674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/// data and also have fixups registered.
168674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen///
169674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenclass MCEncodedFragmentWithFixups : public MCEncodedFragment {
170674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual void anchor();
171674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
172674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic:
173674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
174674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                              MCSectionData *SD = 0)
175674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    : MCEncodedFragment(FType, SD)
176674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  {
177674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  }
178674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
179674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual ~MCEncodedFragmentWithFixups();
180674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
181674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
182674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
183674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
184674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
185674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
186674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
187674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual fixup_iterator fixup_begin() = 0;
188674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual const_fixup_iterator fixup_begin() const  = 0;
189674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual fixup_iterator fixup_end() = 0;
190674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  virtual const_fixup_iterator fixup_end() const = 0;
191674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
192674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen  static bool classof(const MCFragment *F) {
193674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    MCFragment::FragmentType Kind = F->getKind();
194    return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
195  }
196};
197
198/// Fragment for data and encoded instructions.
199///
200class MCDataFragment : public MCEncodedFragmentWithFixups {
201  virtual void anchor();
202
203  /// \brief Does this fragment contain encoded instructions anywhere in it?
204  bool HasInstructions;
205
206  /// \brief Should this fragment be aligned to the end of a bundle?
207  bool AlignToBundleEnd;
208
209  SmallVector<char, 32> Contents;
210
211  /// Fixups - The list of fixups in this fragment.
212  SmallVector<MCFixup, 4> Fixups;
213public:
214  MCDataFragment(MCSectionData *SD = 0)
215    : MCEncodedFragmentWithFixups(FT_Data, SD),
216      HasInstructions(false), AlignToBundleEnd(false)
217  {
218  }
219
220  virtual SmallVectorImpl<char> &getContents() { return Contents; }
221  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
222
223  SmallVectorImpl<MCFixup> &getFixups() {
224    return Fixups;
225  }
226
227  const SmallVectorImpl<MCFixup> &getFixups() const {
228    return Fixups;
229  }
230
231  virtual bool hasInstructions() const { return HasInstructions; }
232  virtual void setHasInstructions(bool V) { HasInstructions = V; }
233
234  virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
235  virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
236
237  fixup_iterator fixup_begin() { return Fixups.begin(); }
238  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
239
240  fixup_iterator fixup_end() {return Fixups.end();}
241  const_fixup_iterator fixup_end() const {return Fixups.end();}
242
243  static bool classof(const MCFragment *F) {
244    return F->getKind() == MCFragment::FT_Data;
245  }
246};
247
248/// This is a compact (memory-size-wise) fragment for holding an encoded
249/// instruction (non-relaxable) that has no fixups registered. When applicable,
250/// it can be used instead of MCDataFragment and lead to lower memory
251/// consumption.
252///
253class MCCompactEncodedInstFragment : public MCEncodedFragment {
254  virtual void anchor();
255
256  /// \brief Should this fragment be aligned to the end of a bundle?
257  bool AlignToBundleEnd;
258
259  SmallVector<char, 4> Contents;
260public:
261  MCCompactEncodedInstFragment(MCSectionData *SD = 0)
262    : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
263  {
264  }
265
266  virtual bool hasInstructions() const {
267    return true;
268  }
269
270  virtual SmallVectorImpl<char> &getContents() { return Contents; }
271  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
272
273  virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
274  virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
275
276  static bool classof(const MCFragment *F) {
277    return F->getKind() == MCFragment::FT_CompactEncodedInst;
278  }
279};
280
281/// A relaxable fragment holds on to its MCInst, since it may need to be
282/// relaxed during the assembler layout and relaxation stage.
283///
284class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
285  virtual void anchor();
286
287  /// Inst - The instruction this is a fragment for.
288  MCInst Inst;
289
290  /// Contents - Binary data for the currently encoded instruction.
291  SmallVector<char, 8> Contents;
292
293  /// Fixups - The list of fixups in this fragment.
294  SmallVector<MCFixup, 1> Fixups;
295
296public:
297  MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
298    : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
299  }
300
301  virtual SmallVectorImpl<char> &getContents() { return Contents; }
302  virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
303
304  const MCInst &getInst() const { return Inst; }
305  void setInst(const MCInst& Value) { Inst = Value; }
306
307  SmallVectorImpl<MCFixup> &getFixups() {
308    return Fixups;
309  }
310
311  const SmallVectorImpl<MCFixup> &getFixups() const {
312    return Fixups;
313  }
314
315  virtual bool hasInstructions() const { return true; }
316
317  fixup_iterator fixup_begin() { return Fixups.begin(); }
318  const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
319
320  fixup_iterator fixup_end() {return Fixups.end();}
321  const_fixup_iterator fixup_end() const {return Fixups.end();}
322
323  static bool classof(const MCFragment *F) {
324    return F->getKind() == MCFragment::FT_Relaxable;
325  }
326};
327
328class MCAlignFragment : public MCFragment {
329  virtual void anchor();
330
331  /// Alignment - The alignment to ensure, in bytes.
332  unsigned Alignment;
333
334  /// Value - Value to use for filling padding bytes.
335  int64_t Value;
336
337  /// ValueSize - The size of the integer (in bytes) of \p Value.
338  unsigned ValueSize;
339
340  /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
341  /// cannot be satisfied in this width then this fragment is ignored.
342  unsigned MaxBytesToEmit;
343
344  /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
345  /// of using the provided value. The exact interpretation of this flag is
346  /// target dependent.
347  bool EmitNops : 1;
348
349public:
350  MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
351                  unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
352    : MCFragment(FT_Align, SD), Alignment(_Alignment),
353      Value(_Value),ValueSize(_ValueSize),
354      MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
355
356  /// @name Accessors
357  /// @{
358
359  unsigned getAlignment() const { return Alignment; }
360
361  int64_t getValue() const { return Value; }
362
363  unsigned getValueSize() const { return ValueSize; }
364
365  unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
366
367  bool hasEmitNops() const { return EmitNops; }
368  void setEmitNops(bool Value) { EmitNops = Value; }
369
370  /// @}
371
372  static bool classof(const MCFragment *F) {
373    return F->getKind() == MCFragment::FT_Align;
374  }
375};
376
377class MCFillFragment : public MCFragment {
378  virtual void anchor();
379
380  /// Value - Value to use for filling bytes.
381  int64_t Value;
382
383  /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
384  /// this is a virtual fill fragment.
385  unsigned ValueSize;
386
387  /// Size - The number of bytes to insert.
388  uint64_t Size;
389
390public:
391  MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
392                 MCSectionData *SD = 0)
393    : MCFragment(FT_Fill, SD),
394      Value(_Value), ValueSize(_ValueSize), Size(_Size) {
395    assert((!ValueSize || (Size % ValueSize) == 0) &&
396           "Fill size must be a multiple of the value size!");
397  }
398
399  /// @name Accessors
400  /// @{
401
402  int64_t getValue() const { return Value; }
403
404  unsigned getValueSize() const { return ValueSize; }
405
406  uint64_t getSize() const { return Size; }
407
408  /// @}
409
410  static bool classof(const MCFragment *F) {
411    return F->getKind() == MCFragment::FT_Fill;
412  }
413};
414
415class MCOrgFragment : public MCFragment {
416  virtual void anchor();
417
418  /// Offset - The offset this fragment should start at.
419  const MCExpr *Offset;
420
421  /// Value - Value to use for filling bytes.
422  int8_t Value;
423
424public:
425  MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
426    : MCFragment(FT_Org, SD),
427      Offset(&_Offset), Value(_Value) {}
428
429  /// @name Accessors
430  /// @{
431
432  const MCExpr &getOffset() const { return *Offset; }
433
434  uint8_t getValue() const { return Value; }
435
436  /// @}
437
438  static bool classof(const MCFragment *F) {
439    return F->getKind() == MCFragment::FT_Org;
440  }
441};
442
443class MCLEBFragment : public MCFragment {
444  virtual void anchor();
445
446  /// Value - The value this fragment should contain.
447  const MCExpr *Value;
448
449  /// IsSigned - True if this is a sleb128, false if uleb128.
450  bool IsSigned;
451
452  SmallString<8> Contents;
453public:
454  MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
455    : MCFragment(FT_LEB, SD),
456      Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
457
458  /// @name Accessors
459  /// @{
460
461  const MCExpr &getValue() const { return *Value; }
462
463  bool isSigned() const { return IsSigned; }
464
465  SmallString<8> &getContents() { return Contents; }
466  const SmallString<8> &getContents() const { return Contents; }
467
468  /// @}
469
470  static bool classof(const MCFragment *F) {
471    return F->getKind() == MCFragment::FT_LEB;
472  }
473};
474
475class MCDwarfLineAddrFragment : public MCFragment {
476  virtual void anchor();
477
478  /// LineDelta - the value of the difference between the two line numbers
479  /// between two .loc dwarf directives.
480  int64_t LineDelta;
481
482  /// AddrDelta - The expression for the difference of the two symbols that
483  /// make up the address delta between two .loc dwarf directives.
484  const MCExpr *AddrDelta;
485
486  SmallString<8> Contents;
487
488public:
489  MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
490                      MCSectionData *SD)
491    : MCFragment(FT_Dwarf, SD),
492      LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
493
494  /// @name Accessors
495  /// @{
496
497  int64_t getLineDelta() const { return LineDelta; }
498
499  const MCExpr &getAddrDelta() const { return *AddrDelta; }
500
501  SmallString<8> &getContents() { return Contents; }
502  const SmallString<8> &getContents() const { return Contents; }
503
504  /// @}
505
506  static bool classof(const MCFragment *F) {
507    return F->getKind() == MCFragment::FT_Dwarf;
508  }
509};
510
511class MCDwarfCallFrameFragment : public MCFragment {
512  virtual void anchor();
513
514  /// AddrDelta - The expression for the difference of the two symbols that
515  /// make up the address delta between two .cfi_* dwarf directives.
516  const MCExpr *AddrDelta;
517
518  SmallString<8> Contents;
519
520public:
521  MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,  MCSectionData *SD)
522    : MCFragment(FT_DwarfFrame, SD),
523      AddrDelta(&_AddrDelta) { Contents.push_back(0); }
524
525  /// @name Accessors
526  /// @{
527
528  const MCExpr &getAddrDelta() const { return *AddrDelta; }
529
530  SmallString<8> &getContents() { return Contents; }
531  const SmallString<8> &getContents() const { return Contents; }
532
533  /// @}
534
535  static bool classof(const MCFragment *F) {
536    return F->getKind() == MCFragment::FT_DwarfFrame;
537  }
538};
539
540// FIXME: Should this be a separate class, or just merged into MCSection? Since
541// we anticipate the fast path being through an MCAssembler, the only reason to
542// keep it out is for API abstraction.
543class MCSectionData : public ilist_node<MCSectionData> {
544  friend class MCAsmLayout;
545
546  MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
547  void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
548
549public:
550  typedef iplist<MCFragment> FragmentListType;
551
552  typedef FragmentListType::const_iterator const_iterator;
553  typedef FragmentListType::iterator iterator;
554
555  typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
556  typedef FragmentListType::reverse_iterator reverse_iterator;
557
558  /// \brief Express the state of bundle locked groups while emitting code.
559  enum BundleLockStateType {
560    NotBundleLocked,
561    BundleLocked,
562    BundleLockedAlignToEnd
563  };
564private:
565  FragmentListType Fragments;
566  const MCSection *Section;
567
568  /// Ordinal - The section index in the assemblers section list.
569  unsigned Ordinal;
570
571  /// LayoutOrder - The index of this section in the layout order.
572  unsigned LayoutOrder;
573
574  /// Alignment - The maximum alignment seen in this section.
575  unsigned Alignment;
576
577  /// \brief Keeping track of bundle-locked state.
578  BundleLockStateType BundleLockState;
579
580  /// \brief We've seen a bundle_lock directive but not its first instruction
581  /// yet.
582  bool BundleGroupBeforeFirstInst;
583
584  /// @name Assembler Backend Data
585  /// @{
586  //
587  // FIXME: This could all be kept private to the assembler implementation.
588
589  /// HasInstructions - Whether this section has had instructions emitted into
590  /// it.
591  unsigned HasInstructions : 1;
592
593  /// @}
594
595public:
596  // Only for use as sentinel.
597  MCSectionData();
598  MCSectionData(const MCSection &Section, MCAssembler *A = 0);
599
600  const MCSection &getSection() const { return *Section; }
601
602  unsigned getAlignment() const { return Alignment; }
603  void setAlignment(unsigned Value) { Alignment = Value; }
604
605  bool hasInstructions() const { return HasInstructions; }
606  void setHasInstructions(bool Value) { HasInstructions = Value; }
607
608  unsigned getOrdinal() const { return Ordinal; }
609  void setOrdinal(unsigned Value) { Ordinal = Value; }
610
611  unsigned getLayoutOrder() const { return LayoutOrder; }
612  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
613
614  /// @name Fragment Access
615  /// @{
616
617  const FragmentListType &getFragmentList() const { return Fragments; }
618  FragmentListType &getFragmentList() { return Fragments; }
619
620  iterator begin() { return Fragments.begin(); }
621  const_iterator begin() const { return Fragments.begin(); }
622
623  iterator end() { return Fragments.end(); }
624  const_iterator end() const { return Fragments.end(); }
625
626  reverse_iterator rbegin() { return Fragments.rbegin(); }
627  const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
628
629  reverse_iterator rend() { return Fragments.rend(); }
630  const_reverse_iterator rend() const { return Fragments.rend(); }
631
632  size_t size() const { return Fragments.size(); }
633
634  bool empty() const { return Fragments.empty(); }
635
636  bool isBundleLocked() const {
637    return BundleLockState != NotBundleLocked;
638  }
639
640  BundleLockStateType getBundleLockState() const {
641    return BundleLockState;
642  }
643
644  void setBundleLockState(BundleLockStateType NewState) {
645    BundleLockState = NewState;
646  }
647
648  bool isBundleGroupBeforeFirstInst() const {
649    return BundleGroupBeforeFirstInst;
650  }
651
652  void setBundleGroupBeforeFirstInst(bool IsFirst) {
653    BundleGroupBeforeFirstInst = IsFirst;
654  }
655
656  void dump();
657
658  /// @}
659};
660
661// FIXME: Same concerns as with SectionData.
662class MCSymbolData : public ilist_node<MCSymbolData> {
663public:
664  const MCSymbol *Symbol;
665
666  /// Fragment - The fragment this symbol's value is relative to, if any.
667  MCFragment *Fragment;
668
669  /// Offset - The offset to apply to the fragment address to form this symbol's
670  /// value.
671  uint64_t Offset;
672
673  /// IsExternal - True if this symbol is visible outside this translation
674  /// unit.
675  unsigned IsExternal : 1;
676
677  /// IsPrivateExtern - True if this symbol is private extern.
678  unsigned IsPrivateExtern : 1;
679
680  /// CommonSize - The size of the symbol, if it is 'common', or 0.
681  //
682  // FIXME: Pack this in with other fields? We could put it in offset, since a
683  // common symbol can never get a definition.
684  uint64_t CommonSize;
685
686  /// SymbolSize - An expression describing how to calculate the size of
687  /// a symbol. If a symbol has no size this field will be NULL.
688  const MCExpr *SymbolSize;
689
690  /// CommonAlign - The alignment of the symbol, if it is 'common'.
691  //
692  // FIXME: Pack this in with other fields?
693  unsigned CommonAlign;
694
695  /// Flags - The Flags field is used by object file implementations to store
696  /// additional per symbol information which is not easily classified.
697  uint32_t Flags;
698
699  /// Index - Index field, for use by the object file implementation.
700  uint64_t Index;
701
702public:
703  // Only for use as sentinel.
704  MCSymbolData();
705  MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
706               MCAssembler *A = 0);
707
708  /// @name Accessors
709  /// @{
710
711  const MCSymbol &getSymbol() const { return *Symbol; }
712
713  MCFragment *getFragment() const { return Fragment; }
714  void setFragment(MCFragment *Value) { Fragment = Value; }
715
716  uint64_t getOffset() const { return Offset; }
717  void setOffset(uint64_t Value) { Offset = Value; }
718
719  /// @}
720  /// @name Symbol Attributes
721  /// @{
722
723  bool isExternal() const { return IsExternal; }
724  void setExternal(bool Value) { IsExternal = Value; }
725
726  bool isPrivateExtern() const { return IsPrivateExtern; }
727  void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
728
729  /// isCommon - Is this a 'common' symbol.
730  bool isCommon() const { return CommonSize != 0; }
731
732  /// setCommon - Mark this symbol as being 'common'.
733  ///
734  /// \param Size - The size of the symbol.
735  /// \param Align - The alignment of the symbol.
736  void setCommon(uint64_t Size, unsigned Align) {
737    CommonSize = Size;
738    CommonAlign = Align;
739  }
740
741  /// getCommonSize - Return the size of a 'common' symbol.
742  uint64_t getCommonSize() const {
743    assert(isCommon() && "Not a 'common' symbol!");
744    return CommonSize;
745  }
746
747  void setSize(const MCExpr *SS) {
748    SymbolSize = SS;
749  }
750
751  const MCExpr *getSize() const {
752    return SymbolSize;
753  }
754
755
756  /// getCommonAlignment - Return the alignment of a 'common' symbol.
757  unsigned getCommonAlignment() const {
758    assert(isCommon() && "Not a 'common' symbol!");
759    return CommonAlign;
760  }
761
762  /// getFlags - Get the (implementation defined) symbol flags.
763  uint32_t getFlags() const { return Flags; }
764
765  /// setFlags - Set the (implementation defined) symbol flags.
766  void setFlags(uint32_t Value) { Flags = Value; }
767
768  /// modifyFlags - Modify the flags via a mask
769  void modifyFlags(uint32_t Value, uint32_t Mask) {
770    Flags = (Flags & ~Mask) | Value;
771  }
772
773  /// getIndex - Get the (implementation defined) index.
774  uint64_t getIndex() const { return Index; }
775
776  /// setIndex - Set the (implementation defined) index.
777  void setIndex(uint64_t Value) { Index = Value; }
778
779  /// @}
780
781  void dump();
782};
783
784// FIXME: This really doesn't belong here. See comments below.
785struct IndirectSymbolData {
786  MCSymbol *Symbol;
787  MCSectionData *SectionData;
788};
789
790// FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
791// to one another.
792struct DataRegionData {
793  // This enum should be kept in sync w/ the mach-o definition in
794  // llvm/Object/MachOFormat.h.
795  enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
796  MCSymbol *Start;
797  MCSymbol *End;
798};
799
800class MCAssembler {
801  friend class MCAsmLayout;
802
803public:
804  typedef iplist<MCSectionData> SectionDataListType;
805  typedef iplist<MCSymbolData> SymbolDataListType;
806
807  typedef SectionDataListType::const_iterator const_iterator;
808  typedef SectionDataListType::iterator iterator;
809
810  typedef SymbolDataListType::const_iterator const_symbol_iterator;
811  typedef SymbolDataListType::iterator symbol_iterator;
812
813  typedef std::vector<IndirectSymbolData>::const_iterator
814    const_indirect_symbol_iterator;
815  typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
816
817  typedef std::vector<DataRegionData>::const_iterator
818    const_data_region_iterator;
819  typedef std::vector<DataRegionData>::iterator data_region_iterator;
820
821private:
822  MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
823  void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
824
825  MCContext &Context;
826
827  MCAsmBackend &Backend;
828
829  MCCodeEmitter &Emitter;
830
831  MCObjectWriter &Writer;
832
833  raw_ostream &OS;
834
835  iplist<MCSectionData> Sections;
836
837  iplist<MCSymbolData> Symbols;
838
839  /// The map of sections to their associated assembler backend data.
840  //
841  // FIXME: Avoid this indirection?
842  DenseMap<const MCSection*, MCSectionData*> SectionMap;
843
844  /// The map of symbols to their associated assembler backend data.
845  //
846  // FIXME: Avoid this indirection?
847  DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
848
849  std::vector<IndirectSymbolData> IndirectSymbols;
850
851  std::vector<DataRegionData> DataRegions;
852  /// The set of function symbols for which a .thumb_func directive has
853  /// been seen.
854  //
855  // FIXME: We really would like this in target specific code rather than
856  // here. Maybe when the relocation stuff moves to target specific,
857  // this can go with it? The streamer would need some target specific
858  // refactoring too.
859  SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
860
861  /// \brief The bundle alignment size currently set in the assembler.
862  ///
863  /// By default it's 0, which means bundling is disabled.
864  unsigned BundleAlignSize;
865
866  unsigned RelaxAll : 1;
867  unsigned NoExecStack : 1;
868  unsigned SubsectionsViaSymbols : 1;
869
870private:
871  /// Evaluate a fixup to a relocatable expression and the value which should be
872  /// placed into the fixup.
873  ///
874  /// \param Layout The layout to use for evaluation.
875  /// \param Fixup The fixup to evaluate.
876  /// \param DF The fragment the fixup is inside.
877  /// \param Target [out] On return, the relocatable expression the fixup
878  /// evaluates to.
879  /// \param Value [out] On return, the value of the fixup as currently laid
880  /// out.
881  /// \return Whether the fixup value was fully resolved. This is true if the
882  /// \p Value result is fixed, otherwise the value may change due to
883  /// relocation.
884  bool evaluateFixup(const MCAsmLayout &Layout,
885                     const MCFixup &Fixup, const MCFragment *DF,
886                     MCValue &Target, uint64_t &Value) const;
887
888  /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
889  /// (increased in size, in order to hold its value correctly).
890  bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF,
891                            const MCAsmLayout &Layout) const;
892
893  /// Check whether the given fragment needs relaxation.
894  bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF,
895                               const MCAsmLayout &Layout) const;
896
897  /// \brief Perform one layout iteration and return true if any offsets
898  /// were adjusted.
899  bool layoutOnce(MCAsmLayout &Layout);
900
901  /// \brief Perform one layout iteration of the given section and return true
902  /// if any offsets were adjusted.
903  bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
904
905  bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
906
907  bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
908
909  bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
910  bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
911                                   MCDwarfCallFrameFragment &DF);
912
913  /// finishLayout - Finalize a layout, including fragment lowering.
914  void finishLayout(MCAsmLayout &Layout);
915
916  uint64_t handleFixup(const MCAsmLayout &Layout,
917                       MCFragment &F, const MCFixup &Fixup);
918
919public:
920  /// Compute the effective fragment size assuming it is laid out at the given
921  /// \p SectionAddress and \p FragmentOffset.
922  uint64_t computeFragmentSize(const MCAsmLayout &Layout,
923                               const MCFragment &F) const;
924
925  /// Find the symbol which defines the atom containing the given symbol, or
926  /// null if there is no such symbol.
927  const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
928
929  /// Check whether a particular symbol is visible to the linker and is required
930  /// in the symbol table, or whether it can be discarded by the assembler. This
931  /// also effects whether the assembler treats the label as potentially
932  /// defining a separate atom.
933  bool isSymbolLinkerVisible(const MCSymbol &SD) const;
934
935  /// Emit the section contents using the given object writer.
936  void writeSectionData(const MCSectionData *Section,
937                        const MCAsmLayout &Layout) const;
938
939  /// Check whether a given symbol has been flagged with .thumb_func.
940  bool isThumbFunc(const MCSymbol *Func) const {
941    return ThumbFuncs.count(Func);
942  }
943
944  /// Flag a function symbol as the target of a .thumb_func directive.
945  void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
946
947public:
948  /// Construct a new assembler instance.
949  ///
950  /// \param OS The stream to output to.
951  //
952  // FIXME: How are we going to parameterize this? Two obvious options are stay
953  // concrete and require clients to pass in a target like object. The other
954  // option is to make this abstract, and have targets provide concrete
955  // implementations as we do with AsmParser.
956  MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
957              MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
958              raw_ostream &OS);
959  ~MCAssembler();
960
961  /// Reuse an assembler instance
962  ///
963  void reset();
964
965  MCContext &getContext() const { return Context; }
966
967  MCAsmBackend &getBackend() const { return Backend; }
968
969  MCCodeEmitter &getEmitter() const { return Emitter; }
970
971  MCObjectWriter &getWriter() const { return Writer; }
972
973  /// Finish - Do final processing and write the object to the output stream.
974  /// \p Writer is used for custom object writer (as the MCJIT does),
975  /// if not specified it is automatically created from backend.
976  void Finish();
977
978  // FIXME: This does not belong here.
979  bool getSubsectionsViaSymbols() const {
980    return SubsectionsViaSymbols;
981  }
982  void setSubsectionsViaSymbols(bool Value) {
983    SubsectionsViaSymbols = Value;
984  }
985
986  bool getRelaxAll() const { return RelaxAll; }
987  void setRelaxAll(bool Value) { RelaxAll = Value; }
988
989  bool getNoExecStack() const { return NoExecStack; }
990  void setNoExecStack(bool Value) { NoExecStack = Value; }
991
992  bool isBundlingEnabled() const {
993    return BundleAlignSize != 0;
994  }
995
996  unsigned getBundleAlignSize() const {
997    return BundleAlignSize;
998  }
999
1000  void setBundleAlignSize(unsigned Size) {
1001    assert((Size == 0 || !(Size & (Size - 1))) &&
1002           "Expect a power-of-two bundle align size");
1003    BundleAlignSize = Size;
1004  }
1005
1006  /// @name Section List Access
1007  /// @{
1008
1009  const SectionDataListType &getSectionList() const { return Sections; }
1010  SectionDataListType &getSectionList() { return Sections; }
1011
1012  iterator begin() { return Sections.begin(); }
1013  const_iterator begin() const { return Sections.begin(); }
1014
1015  iterator end() { return Sections.end(); }
1016  const_iterator end() const { return Sections.end(); }
1017
1018  size_t size() const { return Sections.size(); }
1019
1020  /// @}
1021  /// @name Symbol List Access
1022  /// @{
1023
1024  const SymbolDataListType &getSymbolList() const { return Symbols; }
1025  SymbolDataListType &getSymbolList() { return Symbols; }
1026
1027  symbol_iterator symbol_begin() { return Symbols.begin(); }
1028  const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
1029
1030  symbol_iterator symbol_end() { return Symbols.end(); }
1031  const_symbol_iterator symbol_end() const { return Symbols.end(); }
1032
1033  size_t symbol_size() const { return Symbols.size(); }
1034
1035  /// @}
1036  /// @name Indirect Symbol List Access
1037  /// @{
1038
1039  // FIXME: This is a total hack, this should not be here. Once things are
1040  // factored so that the streamer has direct access to the .o writer, it can
1041  // disappear.
1042  std::vector<IndirectSymbolData> &getIndirectSymbols() {
1043    return IndirectSymbols;
1044  }
1045
1046  indirect_symbol_iterator indirect_symbol_begin() {
1047    return IndirectSymbols.begin();
1048  }
1049  const_indirect_symbol_iterator indirect_symbol_begin() const {
1050    return IndirectSymbols.begin();
1051  }
1052
1053  indirect_symbol_iterator indirect_symbol_end() {
1054    return IndirectSymbols.end();
1055  }
1056  const_indirect_symbol_iterator indirect_symbol_end() const {
1057    return IndirectSymbols.end();
1058  }
1059
1060  size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
1061
1062  /// @}
1063  /// @name Data Region List Access
1064  /// @{
1065
1066  // FIXME: This is a total hack, this should not be here. Once things are
1067  // factored so that the streamer has direct access to the .o writer, it can
1068  // disappear.
1069  std::vector<DataRegionData> &getDataRegions() {
1070    return DataRegions;
1071  }
1072
1073  data_region_iterator data_region_begin() {
1074    return DataRegions.begin();
1075  }
1076  const_data_region_iterator data_region_begin() const {
1077    return DataRegions.begin();
1078  }
1079
1080  data_region_iterator data_region_end() {
1081    return DataRegions.end();
1082  }
1083  const_data_region_iterator data_region_end() const {
1084    return DataRegions.end();
1085  }
1086
1087  size_t data_region_size() const { return DataRegions.size(); }
1088
1089  /// @}
1090  /// @name Backend Data Access
1091  /// @{
1092
1093  MCSectionData &getSectionData(const MCSection &Section) const {
1094    MCSectionData *Entry = SectionMap.lookup(&Section);
1095    assert(Entry && "Missing section data!");
1096    return *Entry;
1097  }
1098
1099  MCSectionData &getOrCreateSectionData(const MCSection &Section,
1100                                        bool *Created = 0) {
1101    MCSectionData *&Entry = SectionMap[&Section];
1102
1103    if (Created) *Created = !Entry;
1104    if (!Entry)
1105      Entry = new MCSectionData(Section, this);
1106
1107    return *Entry;
1108  }
1109
1110  MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
1111    MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
1112    assert(Entry && "Missing symbol data!");
1113    return *Entry;
1114  }
1115
1116  MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
1117                                      bool *Created = 0) {
1118    MCSymbolData *&Entry = SymbolMap[&Symbol];
1119
1120    if (Created) *Created = !Entry;
1121    if (!Entry)
1122      Entry = new MCSymbolData(Symbol, 0, 0, this);
1123
1124    return *Entry;
1125  }
1126
1127  /// @}
1128
1129  void dump();
1130};
1131
1132} // end namespace llvm
1133
1134#endif
1135