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