[ptr-traits] Split the MCFragment type hierarchy out of the MCAssembler
[oota-llvm.git] / include / llvm / MC / MCFragment.h
1 //===- MCFragment.h - Fragment type hierarchy -------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_MC_MCFRAGMENT_H
11 #define LLVM_MC_MCFRAGMENT_H
12
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/ilist.h"
15 #include "llvm/ADT/ilist_node.h"
16 #include "llvm/ADT/iterator.h"
17 #include "llvm/MC/MCFixup.h"
18 #include "llvm/MC/MCInst.h"
19
20 namespace llvm {
21 class MCSection;
22 class MCSymbol;
23 class MCSubtargetInfo;
24
25 class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
26   friend class MCAsmLayout;
27
28   MCFragment(const MCFragment &) = delete;
29   void operator=(const MCFragment &) = delete;
30
31 public:
32   enum FragmentType : uint8_t {
33     FT_Align,
34     FT_Data,
35     FT_CompactEncodedInst,
36     FT_Fill,
37     FT_Relaxable,
38     FT_Org,
39     FT_Dwarf,
40     FT_DwarfFrame,
41     FT_LEB,
42     FT_SafeSEH,
43     FT_Dummy
44   };
45
46 private:
47   FragmentType Kind;
48
49 protected:
50   bool HasInstructions;
51
52 private:
53   /// \brief Should this fragment be aligned to the end of a bundle?
54   bool AlignToBundleEnd;
55
56   uint8_t BundlePadding;
57
58   /// LayoutOrder - The layout order of this fragment.
59   unsigned LayoutOrder;
60
61   /// The data for the section this fragment is in.
62   MCSection *Parent;
63
64   /// Atom - The atom this fragment is in, as represented by it's defining
65   /// symbol.
66   const MCSymbol *Atom;
67
68   /// \name Assembler Backend Data
69   /// @{
70   //
71   // FIXME: This could all be kept private to the assembler implementation.
72
73   /// Offset - The offset of this fragment in its section. This is ~0 until
74   /// initialized.
75   uint64_t Offset;
76
77   /// @}
78
79 protected:
80   MCFragment(FragmentType Kind, bool HasInstructions,
81              uint8_t BundlePadding, MCSection *Parent = nullptr);
82
83   ~MCFragment();
84 private:
85
86   // This is a friend so that the sentinal can be created.
87   friend struct ilist_sentinel_traits<MCFragment>;
88   MCFragment();
89
90 public:
91   /// Destroys the current fragment.
92   ///
93   /// This must be used instead of delete as MCFragment is non-virtual.
94   /// This method will dispatch to the appropriate subclass.
95   void destroy();
96
97   FragmentType getKind() const { return Kind; }
98
99   MCSection *getParent() const { return Parent; }
100   void setParent(MCSection *Value) { Parent = Value; }
101
102   const MCSymbol *getAtom() const { return Atom; }
103   void setAtom(const MCSymbol *Value) { Atom = Value; }
104
105   unsigned getLayoutOrder() const { return LayoutOrder; }
106   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
107
108   /// \brief Does this fragment have instructions emitted into it? By default
109   /// this is false, but specific fragment types may set it to true.
110   bool hasInstructions() const { return HasInstructions; }
111
112   /// \brief Should this fragment be placed at the end of an aligned bundle?
113   bool alignToBundleEnd() const { return AlignToBundleEnd; }
114   void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
115
116   /// \brief Get the padding size that must be inserted before this fragment.
117   /// Used for bundling. By default, no padding is inserted.
118   /// Note that padding size is restricted to 8 bits. This is an optimization
119   /// to reduce the amount of space used for each fragment. In practice, larger
120   /// padding should never be required.
121   uint8_t getBundlePadding() const { return BundlePadding; }
122
123   /// \brief Set the padding size for this fragment. By default it's a no-op,
124   /// and only some fragments have a meaningful implementation.
125   void setBundlePadding(uint8_t N) { BundlePadding = N; }
126
127   /// \brief Return true if given frgment has FT_Dummy type.
128   bool isDummy() const { return Kind == FT_Dummy; }
129
130   void dump();
131 };
132
133 class MCDummyFragment : public MCFragment {
134 public:
135   explicit MCDummyFragment(MCSection *Sec)
136       : MCFragment(FT_Dummy, false, 0, Sec){};
137   static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
138 };
139
140 /// Interface implemented by fragments that contain encoded instructions and/or
141 /// data.
142 ///
143 class MCEncodedFragment : public MCFragment {
144 protected:
145   MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
146                     MCSection *Sec)
147       : MCFragment(FType, HasInstructions, 0, Sec) {}
148
149 public:
150   static bool classof(const MCFragment *F) {
151     MCFragment::FragmentType Kind = F->getKind();
152     switch (Kind) {
153     default:
154       return false;
155     case MCFragment::FT_Relaxable:
156     case MCFragment::FT_CompactEncodedInst:
157     case MCFragment::FT_Data:
158       return true;
159     }
160   }
161 };
162
163 /// Interface implemented by fragments that contain encoded instructions and/or
164 /// data.
165 ///
166 template<unsigned ContentsSize>
167 class MCEncodedFragmentWithContents : public MCEncodedFragment {
168   SmallVector<char, ContentsSize> Contents;
169
170 protected:
171   MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
172                                 bool HasInstructions,
173                                 MCSection *Sec)
174       : MCEncodedFragment(FType, HasInstructions, Sec) {}
175
176 public:
177   SmallVectorImpl<char> &getContents() { return Contents; }
178   const SmallVectorImpl<char> &getContents() const { return Contents; }
179 };
180
181 /// Interface implemented by fragments that contain encoded instructions and/or
182 /// data and also have fixups registered.
183 ///
184 template<unsigned ContentsSize, unsigned FixupsSize>
185 class MCEncodedFragmentWithFixups :
186   public MCEncodedFragmentWithContents<ContentsSize> {
187
188   /// Fixups - The list of fixups in this fragment.
189   SmallVector<MCFixup, FixupsSize> Fixups;
190
191 protected:
192   MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
193                               bool HasInstructions,
194                               MCSection *Sec)
195       : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
196                                                     Sec) {}
197
198 public:
199   typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
200   typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
201
202   SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
203   const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
204
205   fixup_iterator fixup_begin() { return Fixups.begin(); }
206   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
207
208   fixup_iterator fixup_end() { return Fixups.end(); }
209   const_fixup_iterator fixup_end() const { return Fixups.end(); }
210
211   static bool classof(const MCFragment *F) {
212     MCFragment::FragmentType Kind = F->getKind();
213     return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
214   }
215 };
216
217 /// Fragment for data and encoded instructions.
218 ///
219 class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
220 public:
221   MCDataFragment(MCSection *Sec = nullptr)
222       : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
223
224   void setHasInstructions(bool V) { HasInstructions = V; }
225
226   static bool classof(const MCFragment *F) {
227     return F->getKind() == MCFragment::FT_Data;
228   }
229 };
230
231 /// This is a compact (memory-size-wise) fragment for holding an encoded
232 /// instruction (non-relaxable) that has no fixups registered. When applicable,
233 /// it can be used instead of MCDataFragment and lead to lower memory
234 /// consumption.
235 ///
236 class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
237 public:
238   MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
239       : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
240   }
241
242   static bool classof(const MCFragment *F) {
243     return F->getKind() == MCFragment::FT_CompactEncodedInst;
244   }
245 };
246
247 /// A relaxable fragment holds on to its MCInst, since it may need to be
248 /// relaxed during the assembler layout and relaxation stage.
249 ///
250 class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
251
252   /// Inst - The instruction this is a fragment for.
253   MCInst Inst;
254
255   /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
256   const MCSubtargetInfo &STI;
257
258 public:
259   MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
260                       MCSection *Sec = nullptr)
261       : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
262         Inst(Inst), STI(STI) {}
263
264   const MCInst &getInst() const { return Inst; }
265   void setInst(const MCInst &Value) { Inst = Value; }
266
267   const MCSubtargetInfo &getSubtargetInfo() { return STI; }
268
269   static bool classof(const MCFragment *F) {
270     return F->getKind() == MCFragment::FT_Relaxable;
271   }
272 };
273
274 class MCAlignFragment : public MCFragment {
275
276   /// Alignment - The alignment to ensure, in bytes.
277   unsigned Alignment;
278
279   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
280   /// of using the provided value. The exact interpretation of this flag is
281   /// target dependent.
282   bool EmitNops : 1;
283
284   /// Value - Value to use for filling padding bytes.
285   int64_t Value;
286
287   /// ValueSize - The size of the integer (in bytes) of \p Value.
288   unsigned ValueSize;
289
290   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
291   /// cannot be satisfied in this width then this fragment is ignored.
292   unsigned MaxBytesToEmit;
293
294 public:
295   MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
296                   unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
297       : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment),
298         EmitNops(false), Value(Value),
299         ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
300
301   /// \name Accessors
302   /// @{
303
304   unsigned getAlignment() const { return Alignment; }
305
306   int64_t getValue() const { return Value; }
307
308   unsigned getValueSize() const { return ValueSize; }
309
310   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
311
312   bool hasEmitNops() const { return EmitNops; }
313   void setEmitNops(bool Value) { EmitNops = Value; }
314
315   /// @}
316
317   static bool classof(const MCFragment *F) {
318     return F->getKind() == MCFragment::FT_Align;
319   }
320 };
321
322 class MCFillFragment : public MCFragment {
323
324   /// Value - Value to use for filling bytes.
325   int64_t Value;
326
327   /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
328   /// this is a virtual fill fragment.
329   unsigned ValueSize;
330
331   /// Size - The number of bytes to insert.
332   uint64_t Size;
333
334 public:
335   MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size,
336                  MCSection *Sec = nullptr)
337       : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(ValueSize),
338         Size(Size) {
339     assert((!ValueSize || (Size % ValueSize) == 0) &&
340            "Fill size must be a multiple of the value size!");
341   }
342
343   /// \name Accessors
344   /// @{
345
346   int64_t getValue() const { return Value; }
347
348   unsigned getValueSize() const { return ValueSize; }
349
350   uint64_t getSize() const { return Size; }
351
352   /// @}
353
354   static bool classof(const MCFragment *F) {
355     return F->getKind() == MCFragment::FT_Fill;
356   }
357 };
358
359 class MCOrgFragment : public MCFragment {
360
361   /// Offset - The offset this fragment should start at.
362   const MCExpr *Offset;
363
364   /// Value - Value to use for filling bytes.
365   int8_t Value;
366
367 public:
368   MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSection *Sec = nullptr)
369       : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value) {}
370
371   /// \name Accessors
372   /// @{
373
374   const MCExpr &getOffset() const { return *Offset; }
375
376   uint8_t getValue() const { return Value; }
377
378   /// @}
379
380   static bool classof(const MCFragment *F) {
381     return F->getKind() == MCFragment::FT_Org;
382   }
383 };
384
385 class MCLEBFragment : public MCFragment {
386
387   /// Value - The value this fragment should contain.
388   const MCExpr *Value;
389
390   /// IsSigned - True if this is a sleb128, false if uleb128.
391   bool IsSigned;
392
393   SmallString<8> Contents;
394
395 public:
396   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
397       : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) {
398     Contents.push_back(0);
399   }
400
401   /// \name Accessors
402   /// @{
403
404   const MCExpr &getValue() const { return *Value; }
405
406   bool isSigned() const { return IsSigned; }
407
408   SmallString<8> &getContents() { return Contents; }
409   const SmallString<8> &getContents() const { return Contents; }
410
411   /// @}
412
413   static bool classof(const MCFragment *F) {
414     return F->getKind() == MCFragment::FT_LEB;
415   }
416 };
417
418 class MCDwarfLineAddrFragment : public MCFragment {
419
420   /// LineDelta - the value of the difference between the two line numbers
421   /// between two .loc dwarf directives.
422   int64_t LineDelta;
423
424   /// AddrDelta - The expression for the difference of the two symbols that
425   /// make up the address delta between two .loc dwarf directives.
426   const MCExpr *AddrDelta;
427
428   SmallString<8> Contents;
429
430 public:
431   MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
432                           MCSection *Sec = nullptr)
433       : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta),
434         AddrDelta(&AddrDelta) {
435     Contents.push_back(0);
436   }
437
438   /// \name Accessors
439   /// @{
440
441   int64_t getLineDelta() const { return LineDelta; }
442
443   const MCExpr &getAddrDelta() const { return *AddrDelta; }
444
445   SmallString<8> &getContents() { return Contents; }
446   const SmallString<8> &getContents() const { return Contents; }
447
448   /// @}
449
450   static bool classof(const MCFragment *F) {
451     return F->getKind() == MCFragment::FT_Dwarf;
452   }
453 };
454
455 class MCDwarfCallFrameFragment : public MCFragment {
456
457   /// AddrDelta - The expression for the difference of the two symbols that
458   /// make up the address delta between two .cfi_* dwarf directives.
459   const MCExpr *AddrDelta;
460
461   SmallString<8> Contents;
462
463 public:
464   MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
465       : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) {
466     Contents.push_back(0);
467   }
468
469   /// \name Accessors
470   /// @{
471
472   const MCExpr &getAddrDelta() const { return *AddrDelta; }
473
474   SmallString<8> &getContents() { return Contents; }
475   const SmallString<8> &getContents() const { return Contents; }
476
477   /// @}
478
479   static bool classof(const MCFragment *F) {
480     return F->getKind() == MCFragment::FT_DwarfFrame;
481   }
482 };
483
484 class MCSafeSEHFragment : public MCFragment {
485   const MCSymbol *Sym;
486
487 public:
488   MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
489       : MCFragment(FT_SafeSEH, false, 0, Sec), Sym(Sym) {}
490
491   /// \name Accessors
492   /// @{
493
494   const MCSymbol *getSymbol() { return Sym; }
495   const MCSymbol *getSymbol() const { return Sym; }
496
497   /// @}
498
499   static bool classof(const MCFragment *F) {
500     return F->getKind() == MCFragment::FT_SafeSEH;
501   }
502 };
503
504 } // end namespace llvm
505
506 #endif