xref: /openbsd/gnu/llvm/llvm/include/llvm/MC/MCFragment.h (revision d415bd75)
1 //===- MCFragment.h - Fragment type hierarchy -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_MC_MCFRAGMENT_H
10 #define LLVM_MC_MCFRAGMENT_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/ilist_node.h"
17 #include "llvm/MC/MCFixup.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/Support/Alignment.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_Nops,
40     FT_Relaxable,
41     FT_Org,
42     FT_Dwarf,
43     FT_DwarfFrame,
44     FT_LEB,
45     FT_BoundaryAlign,
46     FT_SymbolId,
47     FT_CVInlineLines,
48     FT_CVDefRange,
49     FT_PseudoProbe,
50     FT_Dummy
51   };
52 
53 private:
54   /// The data for the section this fragment is in.
55   MCSection *Parent;
56 
57   /// The atom this fragment is in, as represented by its defining symbol.
58   const MCSymbol *Atom;
59 
60   /// The offset of this fragment in its section. This is ~0 until
61   /// initialized.
62   uint64_t Offset;
63 
64   /// The layout order of this fragment.
65   unsigned LayoutOrder;
66 
67   /// The subsection this fragment belongs to. This is 0 if the fragment is not
68   // in any subsection.
69   unsigned SubsectionNumber = 0;
70 
71   FragmentType Kind;
72 
73   /// Whether fragment is being laid out.
74   bool IsBeingLaidOut;
75 
76 protected:
77   bool HasInstructions;
78 
79   MCFragment(FragmentType Kind, bool HasInstructions,
80              MCSection *Parent = nullptr);
81 
82 public:
83   MCFragment() = delete;
84   MCFragment(const MCFragment &) = delete;
85   MCFragment &operator=(const MCFragment &) = delete;
86 
87   /// Destroys the current fragment.
88   ///
89   /// This must be used instead of delete as MCFragment is non-virtual.
90   /// This method will dispatch to the appropriate subclass.
91   void destroy();
92 
getKind()93   FragmentType getKind() const { return Kind; }
94 
getParent()95   MCSection *getParent() const { return Parent; }
setParent(MCSection * Value)96   void setParent(MCSection *Value) { Parent = Value; }
97 
getAtom()98   const MCSymbol *getAtom() const { return Atom; }
setAtom(const MCSymbol * Value)99   void setAtom(const MCSymbol *Value) { Atom = Value; }
100 
getLayoutOrder()101   unsigned getLayoutOrder() const { return LayoutOrder; }
setLayoutOrder(unsigned Value)102   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
103 
104   /// Does this fragment have instructions emitted into it? By default
105   /// this is false, but specific fragment types may set it to true.
hasInstructions()106   bool hasInstructions() const { return HasInstructions; }
107 
108   void dump() const;
109 
setSubsectionNumber(unsigned Value)110   void setSubsectionNumber(unsigned Value) { SubsectionNumber = Value; }
getSubsectionNumber()111   unsigned getSubsectionNumber() const { return SubsectionNumber; }
112 };
113 
114 class MCDummyFragment : public MCFragment {
115 public:
MCDummyFragment(MCSection * Sec)116   explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
117 
classof(const MCFragment * F)118   static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
119 };
120 
121 /// Interface implemented by fragments that contain encoded instructions and/or
122 /// data.
123 ///
124 class MCEncodedFragment : public MCFragment {
125   /// Should this fragment be aligned to the end of a bundle?
126   bool AlignToBundleEnd = false;
127 
128   uint8_t BundlePadding = 0;
129 
130 protected:
MCEncodedFragment(MCFragment::FragmentType FType,bool HasInstructions,MCSection * Sec)131   MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
132                     MCSection *Sec)
133       : MCFragment(FType, HasInstructions, Sec) {}
134 
135   /// The MCSubtargetInfo in effect when the instruction was encoded.
136   /// It must be non-null for instructions.
137   const MCSubtargetInfo *STI = nullptr;
138 
139 public:
classof(const MCFragment * F)140   static bool classof(const MCFragment *F) {
141     MCFragment::FragmentType Kind = F->getKind();
142     switch (Kind) {
143     default:
144       return false;
145     case MCFragment::FT_Relaxable:
146     case MCFragment::FT_CompactEncodedInst:
147     case MCFragment::FT_Data:
148     case MCFragment::FT_Dwarf:
149     case MCFragment::FT_DwarfFrame:
150     case MCFragment::FT_PseudoProbe:
151       return true;
152     }
153   }
154 
155   /// Should this fragment be placed at the end of an aligned bundle?
alignToBundleEnd()156   bool alignToBundleEnd() const { return AlignToBundleEnd; }
setAlignToBundleEnd(bool V)157   void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
158 
159   /// Get the padding size that must be inserted before this fragment.
160   /// Used for bundling. By default, no padding is inserted.
161   /// Note that padding size is restricted to 8 bits. This is an optimization
162   /// to reduce the amount of space used for each fragment. In practice, larger
163   /// padding should never be required.
getBundlePadding()164   uint8_t getBundlePadding() const { return BundlePadding; }
165 
166   /// Set the padding size for this fragment. By default it's a no-op,
167   /// and only some fragments have a meaningful implementation.
setBundlePadding(uint8_t N)168   void setBundlePadding(uint8_t N) { BundlePadding = N; }
169 
170   /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
171   /// Guaranteed to be non-null if hasInstructions() == true
getSubtargetInfo()172   const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
173 
174   /// Record that the fragment contains instructions with the MCSubtargetInfo in
175   /// effect when the instruction was encoded.
setHasInstructions(const MCSubtargetInfo & STI)176   void setHasInstructions(const MCSubtargetInfo &STI) {
177     HasInstructions = true;
178     this->STI = &STI;
179   }
180 };
181 
182 /// Interface implemented by fragments that contain encoded instructions and/or
183 /// data.
184 ///
185 template<unsigned ContentsSize>
186 class MCEncodedFragmentWithContents : public MCEncodedFragment {
187   SmallVector<char, ContentsSize> Contents;
188 
189 protected:
MCEncodedFragmentWithContents(MCFragment::FragmentType FType,bool HasInstructions,MCSection * Sec)190   MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
191                                 bool HasInstructions,
192                                 MCSection *Sec)
193       : MCEncodedFragment(FType, HasInstructions, Sec) {}
194 
195 public:
getContents()196   SmallVectorImpl<char> &getContents() { return Contents; }
getContents()197   const SmallVectorImpl<char> &getContents() const { return Contents; }
198 };
199 
200 /// Interface implemented by fragments that contain encoded instructions and/or
201 /// data and also have fixups registered.
202 ///
203 template<unsigned ContentsSize, unsigned FixupsSize>
204 class MCEncodedFragmentWithFixups :
205   public MCEncodedFragmentWithContents<ContentsSize> {
206 
207   /// The list of fixups in this fragment.
208   SmallVector<MCFixup, FixupsSize> Fixups;
209 
210 protected:
MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,bool HasInstructions,MCSection * Sec)211   MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
212                               bool HasInstructions,
213                               MCSection *Sec)
214       : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
215                                                     Sec) {}
216 
217 public:
218 
219   using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
220   using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
221 
getFixups()222   SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
getFixups()223   const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
224 
fixup_begin()225   fixup_iterator fixup_begin() { return Fixups.begin(); }
fixup_begin()226   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
227 
fixup_end()228   fixup_iterator fixup_end() { return Fixups.end(); }
fixup_end()229   const_fixup_iterator fixup_end() const { return Fixups.end(); }
230 
classof(const MCFragment * F)231   static bool classof(const MCFragment *F) {
232     MCFragment::FragmentType Kind = F->getKind();
233     return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
234            Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf ||
235            Kind == MCFragment::FT_DwarfFrame;
236   }
237 };
238 
239 /// Fragment for data and encoded instructions.
240 ///
241 class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
242 public:
243   MCDataFragment(MCSection *Sec = nullptr)
244       : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
245 
classof(const MCFragment * F)246   static bool classof(const MCFragment *F) {
247     return F->getKind() == MCFragment::FT_Data;
248   }
249 };
250 
251 /// This is a compact (memory-size-wise) fragment for holding an encoded
252 /// instruction (non-relaxable) that has no fixups registered. When applicable,
253 /// it can be used instead of MCDataFragment and lead to lower memory
254 /// consumption.
255 ///
256 class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
257 public:
258   MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
MCEncodedFragmentWithContents(FT_CompactEncodedInst,true,Sec)259       : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
260   }
261 
classof(const MCFragment * F)262   static bool classof(const MCFragment *F) {
263     return F->getKind() == MCFragment::FT_CompactEncodedInst;
264   }
265 };
266 
267 /// A relaxable fragment holds on to its MCInst, since it may need to be
268 /// relaxed during the assembler layout and relaxation stage.
269 ///
270 class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
271 
272   /// The instruction this is a fragment for.
273   MCInst Inst;
274   /// Can we auto pad the instruction?
275   bool AllowAutoPadding = false;
276 
277 public:
278   MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
279                       MCSection *Sec = nullptr)
MCEncodedFragmentWithFixups(FT_Relaxable,true,Sec)280       : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
281         Inst(Inst) { this->STI = &STI; }
282 
getInst()283   const MCInst &getInst() const { return Inst; }
setInst(const MCInst & Value)284   void setInst(const MCInst &Value) { Inst = Value; }
285 
getAllowAutoPadding()286   bool getAllowAutoPadding() const { return AllowAutoPadding; }
setAllowAutoPadding(bool V)287   void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }
288 
classof(const MCFragment * F)289   static bool classof(const MCFragment *F) {
290     return F->getKind() == MCFragment::FT_Relaxable;
291   }
292 };
293 
294 class MCAlignFragment : public MCFragment {
295   /// The alignment to ensure, in bytes.
296   Align Alignment;
297 
298   /// Flag to indicate that (optimal) NOPs should be emitted instead
299   /// of using the provided value. The exact interpretation of this flag is
300   /// target dependent.
301   bool EmitNops : 1;
302 
303   /// Value to use for filling padding bytes.
304   int64_t Value;
305 
306   /// The size of the integer (in bytes) of \p Value.
307   unsigned ValueSize;
308 
309   /// The maximum number of bytes to emit; if the alignment
310   /// cannot be satisfied in this width then this fragment is ignored.
311   unsigned MaxBytesToEmit;
312 
313   /// When emitting Nops some subtargets have specific nop encodings.
314   const MCSubtargetInfo *STI;
315 
316 public:
317   MCAlignFragment(Align Alignment, int64_t Value, unsigned ValueSize,
318                   unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
MCFragment(FT_Align,false,Sec)319       : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
320         Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
321 
getAlignment()322   Align getAlignment() const { return Alignment; }
323 
getValue()324   int64_t getValue() const { return Value; }
325 
getValueSize()326   unsigned getValueSize() const { return ValueSize; }
327 
getMaxBytesToEmit()328   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
329 
hasEmitNops()330   bool hasEmitNops() const { return EmitNops; }
setEmitNops(bool Value,const MCSubtargetInfo * STI)331   void setEmitNops(bool Value, const MCSubtargetInfo *STI) {
332     EmitNops = Value;
333     this->STI = STI;
334   }
335 
getSubtargetInfo()336   const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
337 
classof(const MCFragment * F)338   static bool classof(const MCFragment *F) {
339     return F->getKind() == MCFragment::FT_Align;
340   }
341 };
342 
343 class MCFillFragment : public MCFragment {
344   uint8_t ValueSize;
345   /// Value to use for filling bytes.
346   uint64_t Value;
347   /// The number of bytes to insert.
348   const MCExpr &NumValues;
349 
350   /// Source location of the directive that this fragment was created for.
351   SMLoc Loc;
352 
353 public:
354   MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues,
355                  SMLoc Loc, MCSection *Sec = nullptr)
MCFragment(FT_Fill,false,Sec)356       : MCFragment(FT_Fill, false, Sec), ValueSize(VSize), Value(Value),
357         NumValues(NumValues), Loc(Loc) {}
358 
getValue()359   uint64_t getValue() const { return Value; }
getValueSize()360   uint8_t getValueSize() const { return ValueSize; }
getNumValues()361   const MCExpr &getNumValues() const { return NumValues; }
362 
getLoc()363   SMLoc getLoc() const { return Loc; }
364 
classof(const MCFragment * F)365   static bool classof(const MCFragment *F) {
366     return F->getKind() == MCFragment::FT_Fill;
367   }
368 };
369 
370 class MCNopsFragment : public MCFragment {
371   /// The number of bytes to insert.
372   int64_t Size;
373   /// Maximum number of bytes allowed in each NOP instruction.
374   int64_t ControlledNopLength;
375 
376   /// Source location of the directive that this fragment was created for.
377   SMLoc Loc;
378 
379   /// When emitting Nops some subtargets have specific nop encodings.
380   const MCSubtargetInfo &STI;
381 
382 public:
383   MCNopsFragment(int64_t NumBytes, int64_t ControlledNopLength, SMLoc L,
384                  const MCSubtargetInfo &STI, MCSection *Sec = nullptr)
MCFragment(FT_Nops,false,Sec)385       : MCFragment(FT_Nops, false, Sec), Size(NumBytes),
386         ControlledNopLength(ControlledNopLength), Loc(L), STI(STI) {}
387 
getNumBytes()388   int64_t getNumBytes() const { return Size; }
getControlledNopLength()389   int64_t getControlledNopLength() const { return ControlledNopLength; }
390 
getLoc()391   SMLoc getLoc() const { return Loc; }
392 
getSubtargetInfo()393   const MCSubtargetInfo *getSubtargetInfo() const { return &STI; }
394 
classof(const MCFragment * F)395   static bool classof(const MCFragment *F) {
396     return F->getKind() == MCFragment::FT_Nops;
397   }
398 };
399 
400 class MCOrgFragment : public MCFragment {
401   /// Value to use for filling bytes.
402   int8_t Value;
403 
404   /// The offset this fragment should start at.
405   const MCExpr *Offset;
406 
407   /// Source location of the directive that this fragment was created for.
408   SMLoc Loc;
409 
410 public:
411   MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc,
412                 MCSection *Sec = nullptr)
MCFragment(FT_Org,false,Sec)413       : MCFragment(FT_Org, false, Sec), Value(Value), Offset(&Offset),
414         Loc(Loc) {}
415 
getOffset()416   const MCExpr &getOffset() const { return *Offset; }
417 
getValue()418   uint8_t getValue() const { return Value; }
419 
getLoc()420   SMLoc getLoc() const { return Loc; }
421 
classof(const MCFragment * F)422   static bool classof(const MCFragment *F) {
423     return F->getKind() == MCFragment::FT_Org;
424   }
425 };
426 
427 class MCLEBFragment : public MCFragment {
428   /// True if this is a sleb128, false if uleb128.
429   bool IsSigned;
430 
431   /// The value this fragment should contain.
432   const MCExpr *Value;
433 
434   SmallString<8> Contents;
435 
436 public:
437   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
MCFragment(FT_LEB,false,Sec)438       : MCFragment(FT_LEB, false, Sec), IsSigned(IsSigned_), Value(&Value_) {
439     Contents.push_back(0);
440   }
441 
getValue()442   const MCExpr &getValue() const { return *Value; }
443 
isSigned()444   bool isSigned() const { return IsSigned; }
445 
getContents()446   SmallString<8> &getContents() { return Contents; }
getContents()447   const SmallString<8> &getContents() const { return Contents; }
448 
449   /// @}
450 
classof(const MCFragment * F)451   static bool classof(const MCFragment *F) {
452     return F->getKind() == MCFragment::FT_LEB;
453   }
454 };
455 
456 class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
457   /// The value of the difference between the two line numbers
458   /// between two .loc dwarf directives.
459   int64_t LineDelta;
460 
461   /// The expression for the difference of the two symbols that
462   /// make up the address delta between two .loc dwarf directives.
463   const MCExpr *AddrDelta;
464 
465 public:
466   MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
467                           MCSection *Sec = nullptr)
468       : MCEncodedFragmentWithFixups<8, 1>(FT_Dwarf, false, Sec),
469         LineDelta(LineDelta), AddrDelta(&AddrDelta) {}
470 
getLineDelta()471   int64_t getLineDelta() const { return LineDelta; }
472 
getAddrDelta()473   const MCExpr &getAddrDelta() const { return *AddrDelta; }
474 
classof(const MCFragment * F)475   static bool classof(const MCFragment *F) {
476     return F->getKind() == MCFragment::FT_Dwarf;
477   }
478 };
479 
480 class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups<8, 1> {
481   /// The expression for the difference of the two symbols that
482   /// make up the address delta between two .cfi_* dwarf directives.
483   const MCExpr *AddrDelta;
484 
485 public:
486   MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
487       : MCEncodedFragmentWithFixups<8, 1>(FT_DwarfFrame, false, Sec),
488         AddrDelta(&AddrDelta) {}
489 
getAddrDelta()490   const MCExpr &getAddrDelta() const { return *AddrDelta; }
491 
classof(const MCFragment * F)492   static bool classof(const MCFragment *F) {
493     return F->getKind() == MCFragment::FT_DwarfFrame;
494   }
495 };
496 
497 /// Represents a symbol table index fragment.
498 class MCSymbolIdFragment : public MCFragment {
499   const MCSymbol *Sym;
500 
501 public:
502   MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
MCFragment(FT_SymbolId,false,Sec)503       : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
504 
getSymbol()505   const MCSymbol *getSymbol() { return Sym; }
getSymbol()506   const MCSymbol *getSymbol() const { return Sym; }
507 
classof(const MCFragment * F)508   static bool classof(const MCFragment *F) {
509     return F->getKind() == MCFragment::FT_SymbolId;
510   }
511 };
512 
513 /// Fragment representing the binary annotations produced by the
514 /// .cv_inline_linetable directive.
515 class MCCVInlineLineTableFragment : public MCFragment {
516   unsigned SiteFuncId;
517   unsigned StartFileId;
518   unsigned StartLineNum;
519   const MCSymbol *FnStartSym;
520   const MCSymbol *FnEndSym;
521   SmallString<8> Contents;
522 
523   /// CodeViewContext has the real knowledge about this format, so let it access
524   /// our members.
525   friend class CodeViewContext;
526 
527 public:
528   MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
529                               unsigned StartLineNum, const MCSymbol *FnStartSym,
530                               const MCSymbol *FnEndSym,
531                               MCSection *Sec = nullptr)
MCFragment(FT_CVInlineLines,false,Sec)532       : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
533         StartFileId(StartFileId), StartLineNum(StartLineNum),
534         FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
535 
getFnStartSym()536   const MCSymbol *getFnStartSym() const { return FnStartSym; }
getFnEndSym()537   const MCSymbol *getFnEndSym() const { return FnEndSym; }
538 
getContents()539   SmallString<8> &getContents() { return Contents; }
getContents()540   const SmallString<8> &getContents() const { return Contents; }
541 
classof(const MCFragment * F)542   static bool classof(const MCFragment *F) {
543     return F->getKind() == MCFragment::FT_CVInlineLines;
544   }
545 };
546 
547 /// Fragment representing the .cv_def_range directive.
548 class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
549   SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges;
550   SmallString<32> FixedSizePortion;
551 
552   /// CodeViewContext has the real knowledge about this format, so let it access
553   /// our members.
554   friend class CodeViewContext;
555 
556 public:
557   MCCVDefRangeFragment(
558       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
559       StringRef FixedSizePortion, MCSection *Sec = nullptr)
560       : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),
561         Ranges(Ranges.begin(), Ranges.end()),
562         FixedSizePortion(FixedSizePortion) {}
563 
getRanges()564   ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
565     return Ranges;
566   }
567 
getFixedSizePortion()568   StringRef getFixedSizePortion() const { return FixedSizePortion.str(); }
569 
classof(const MCFragment * F)570   static bool classof(const MCFragment *F) {
571     return F->getKind() == MCFragment::FT_CVDefRange;
572   }
573 };
574 
575 /// Represents required padding such that a particular other set of fragments
576 /// does not cross a particular power-of-two boundary. The other fragments must
577 /// follow this one within the same section.
578 class MCBoundaryAlignFragment : public MCFragment {
579   /// The alignment requirement of the branch to be aligned.
580   Align AlignBoundary;
581   /// The last fragment in the set of fragments to be aligned.
582   const MCFragment *LastFragment = nullptr;
583   /// The size of the fragment.  The size is lazily set during relaxation, and
584   /// is not meaningful before that.
585   uint64_t Size = 0;
586 
587   /// When emitting Nops some subtargets have specific nop encodings.
588   const MCSubtargetInfo &STI;
589 
590 public:
591   MCBoundaryAlignFragment(Align AlignBoundary, const MCSubtargetInfo &STI,
592                           MCSection *Sec = nullptr)
MCFragment(FT_BoundaryAlign,false,Sec)593       : MCFragment(FT_BoundaryAlign, false, Sec), AlignBoundary(AlignBoundary),
594         STI(STI) {}
595 
getSize()596   uint64_t getSize() const { return Size; }
setSize(uint64_t Value)597   void setSize(uint64_t Value) { Size = Value; }
598 
getAlignment()599   Align getAlignment() const { return AlignBoundary; }
setAlignment(Align Value)600   void setAlignment(Align Value) { AlignBoundary = Value; }
601 
getLastFragment()602   const MCFragment *getLastFragment() const { return LastFragment; }
setLastFragment(const MCFragment * F)603   void setLastFragment(const MCFragment *F) {
604     assert(!F || getParent() == F->getParent());
605     LastFragment = F;
606   }
607 
getSubtargetInfo()608   const MCSubtargetInfo *getSubtargetInfo() const { return &STI; }
609 
classof(const MCFragment * F)610   static bool classof(const MCFragment *F) {
611     return F->getKind() == MCFragment::FT_BoundaryAlign;
612   }
613 };
614 
615 class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
616   /// The expression for the difference of the two symbols that
617   /// make up the address delta between two .pseudoprobe directives.
618   const MCExpr *AddrDelta;
619 
620 public:
621   MCPseudoProbeAddrFragment(const MCExpr *AddrDelta, MCSection *Sec = nullptr)
622       : MCEncodedFragmentWithFixups<8, 1>(FT_PseudoProbe, false, Sec),
623         AddrDelta(AddrDelta) {}
624 
getAddrDelta()625   const MCExpr &getAddrDelta() const { return *AddrDelta; }
626 
classof(const MCFragment * F)627   static bool classof(const MCFragment *F) {
628     return F->getKind() == MCFragment::FT_PseudoProbe;
629   }
630 };
631 } // end namespace llvm
632 
633 #endif // LLVM_MC_MCFRAGMENT_H
634