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