Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  
  93.   FragmentType getKind() const { return Kind; }
  94.  
  95.   MCSection *getParent() const { return Parent; }
  96.   void setParent(MCSection *Value) { Parent = Value; }
  97.  
  98.   const MCSymbol *getAtom() const { return Atom; }
  99.   void setAtom(const MCSymbol *Value) { Atom = Value; }
  100.  
  101.   unsigned getLayoutOrder() const { return LayoutOrder; }
  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.
  106.   bool hasInstructions() const { return HasInstructions; }
  107.  
  108.   void dump() const;
  109.  
  110.   void setSubsectionNumber(unsigned Value) { SubsectionNumber = Value; }
  111.   unsigned getSubsectionNumber() const { return SubsectionNumber; }
  112. };
  113.  
  114. class MCDummyFragment : public MCFragment {
  115. public:
  116.   explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
  117.  
  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:
  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:
  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?
  156.   bool alignToBundleEnd() const { return AlignToBundleEnd; }
  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.
  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.
  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
  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.
  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:
  190.   MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
  191.                                 bool HasInstructions,
  192.                                 MCSection *Sec)
  193.       : MCEncodedFragment(FType, HasInstructions, Sec) {}
  194.  
  195. public:
  196.   SmallVectorImpl<char> &getContents() { return Contents; }
  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:
  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.  
  222.   SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
  223.   const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
  224.  
  225.   fixup_iterator fixup_begin() { return Fixups.begin(); }
  226.   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
  227.  
  228.   fixup_iterator fixup_end() { return Fixups.end(); }
  229.   const_fixup_iterator fixup_end() const { return Fixups.end(); }
  230.  
  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.  
  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)
  259.       : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
  260.   }
  261.  
  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)
  280.       : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
  281.         Inst(Inst) { this->STI = &STI; }
  282.  
  283.   const MCInst &getInst() const { return Inst; }
  284.   void setInst(const MCInst &Value) { Inst = Value; }
  285.  
  286.   bool getAllowAutoPadding() const { return AllowAutoPadding; }
  287.   void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }
  288.  
  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)
  319.       : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
  320.         Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
  321.  
  322.   Align getAlignment() const { return Alignment; }
  323.  
  324.   int64_t getValue() const { return Value; }
  325.  
  326.   unsigned getValueSize() const { return ValueSize; }
  327.  
  328.   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
  329.  
  330.   bool hasEmitNops() const { return EmitNops; }
  331.   void setEmitNops(bool Value, const MCSubtargetInfo *STI) {
  332.     EmitNops = Value;
  333.     this->STI = STI;
  334.   }
  335.  
  336.   const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
  337.  
  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)
  356.       : MCFragment(FT_Fill, false, Sec), ValueSize(VSize), Value(Value),
  357.         NumValues(NumValues), Loc(Loc) {}
  358.  
  359.   uint64_t getValue() const { return Value; }
  360.   uint8_t getValueSize() const { return ValueSize; }
  361.   const MCExpr &getNumValues() const { return NumValues; }
  362.  
  363.   SMLoc getLoc() const { return Loc; }
  364.  
  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)
  385.       : MCFragment(FT_Nops, false, Sec), Size(NumBytes),
  386.         ControlledNopLength(ControlledNopLength), Loc(L), STI(STI) {}
  387.  
  388.   int64_t getNumBytes() const { return Size; }
  389.   int64_t getControlledNopLength() const { return ControlledNopLength; }
  390.  
  391.   SMLoc getLoc() const { return Loc; }
  392.  
  393.   const MCSubtargetInfo *getSubtargetInfo() const { return &STI; }
  394.  
  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)
  413.       : MCFragment(FT_Org, false, Sec), Value(Value), Offset(&Offset),
  414.         Loc(Loc) {}
  415.  
  416.   const MCExpr &getOffset() const { return *Offset; }
  417.  
  418.   uint8_t getValue() const { return Value; }
  419.  
  420.   SMLoc getLoc() const { return Loc; }
  421.  
  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)
  438.       : MCFragment(FT_LEB, false, Sec), IsSigned(IsSigned_), Value(&Value_) {
  439.     Contents.push_back(0);
  440.   }
  441.  
  442.   const MCExpr &getValue() const { return *Value; }
  443.  
  444.   bool isSigned() const { return IsSigned; }
  445.  
  446.   SmallString<8> &getContents() { return Contents; }
  447.   const SmallString<8> &getContents() const { return Contents; }
  448.  
  449.   /// @}
  450.  
  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.  
  471.   int64_t getLineDelta() const { return LineDelta; }
  472.  
  473.   const MCExpr &getAddrDelta() const { return *AddrDelta; }
  474.  
  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.  
  490.   const MCExpr &getAddrDelta() const { return *AddrDelta; }
  491.  
  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)
  503.       : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
  504.  
  505.   const MCSymbol *getSymbol() { return Sym; }
  506.   const MCSymbol *getSymbol() const { return Sym; }
  507.  
  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)
  532.       : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
  533.         StartFileId(StartFileId), StartLineNum(StartLineNum),
  534.         FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
  535.  
  536.   const MCSymbol *getFnStartSym() const { return FnStartSym; }
  537.   const MCSymbol *getFnEndSym() const { return FnEndSym; }
  538.  
  539.   SmallString<8> &getContents() { return Contents; }
  540.   const SmallString<8> &getContents() const { return Contents; }
  541.  
  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.  
  564.   ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
  565.     return Ranges;
  566.   }
  567.  
  568.   StringRef getFixedSizePortion() const { return FixedSizePortion.str(); }
  569.  
  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)
  593.       : MCFragment(FT_BoundaryAlign, false, Sec), AlignBoundary(AlignBoundary),
  594.         STI(STI) {}
  595.  
  596.   uint64_t getSize() const { return Size; }
  597.   void setSize(uint64_t Value) { Size = Value; }
  598.  
  599.   Align getAlignment() const { return AlignBoundary; }
  600.   void setAlignment(Align Value) { AlignBoundary = Value; }
  601.  
  602.   const MCFragment *getLastFragment() const { return LastFragment; }
  603.   void setLastFragment(const MCFragment *F) {
  604.     assert(!F || getParent() == F->getParent());
  605.     LastFragment = F;
  606.   }
  607.  
  608.   const MCSubtargetInfo *getSubtargetInfo() const { return &STI; }
  609.  
  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.  
  625.   const MCExpr &getAddrDelta() const { return *AddrDelta; }
  626.  
  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.