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