summaryrefslogtreecommitdiff
path: root/include/llvm/MC/MCFragment.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/MC/MCFragment.h')
-rw-r--r--include/llvm/MC/MCFragment.h105
1 files changed, 100 insertions, 5 deletions
diff --git a/include/llvm/MC/MCFragment.h b/include/llvm/MC/MCFragment.h
index 284ca50e19d5b..7ebde03a758c5 100644
--- a/include/llvm/MC/MCFragment.h
+++ b/include/llvm/MC/MCFragment.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ilist_node.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/SMLoc.h"
#include <cstdint>
#include <utility>
@@ -41,7 +42,8 @@ public:
FT_Dwarf,
FT_DwarfFrame,
FT_LEB,
- FT_SafeSEH,
+ FT_Padding,
+ FT_SymbolId,
FT_CVInlineLines,
FT_CVDefRange,
FT_Dummy
@@ -323,6 +325,98 @@ public:
}
};
+/// Fragment for adding required padding.
+/// This fragment is always inserted before an instruction, and holds that
+/// instruction as context information (as well as a mask of kinds) for
+/// determining the padding size.
+///
+class MCPaddingFragment : public MCFragment {
+ /// A mask containing all the kinds relevant to this fragment. i.e. the i'th
+ /// bit will be set iff kind i is relevant to this fragment.
+ uint64_t PaddingPoliciesMask;
+ /// A boolean indicating if this fragment will actually hold padding. If its
+ /// value is false, then this fragment serves only as a placeholder,
+ /// containing data to assist other insertion point in their decision making.
+ bool IsInsertionPoint;
+
+ uint64_t Size;
+
+ struct MCInstInfo {
+ bool IsInitialized;
+ MCInst Inst;
+ /// A boolean indicating whether the instruction pointed by this fragment is
+ /// a fixed size instruction or a relaxable instruction held by a
+ /// MCRelaxableFragment.
+ bool IsImmutableSizedInst;
+ union {
+ /// If the instruction is a fixed size instruction, hold its size.
+ size_t InstSize;
+ /// Otherwise, hold a pointer to the MCRelaxableFragment holding it.
+ MCRelaxableFragment *InstFragment;
+ };
+ };
+ MCInstInfo InstInfo;
+
+public:
+ static const uint64_t PFK_None = UINT64_C(0);
+
+ enum MCPaddingFragmentKind {
+ // values 0-7 are reserved for future target independet values.
+
+ FirstTargetPerfNopFragmentKind = 8,
+
+ /// Limit range of target MCPerfNopFragment kinds to fit in uint64_t
+ MaxTargetPerfNopFragmentKind = 63
+ };
+
+ MCPaddingFragment(MCSection *Sec = nullptr)
+ : MCFragment(FT_Padding, false, 0, Sec), PaddingPoliciesMask(PFK_None),
+ IsInsertionPoint(false), Size(UINT64_C(0)),
+ InstInfo({false, MCInst(), false, {0}}) {}
+
+ bool isInsertionPoint() const { return IsInsertionPoint; }
+ void setAsInsertionPoint() { IsInsertionPoint = true; }
+ uint64_t getPaddingPoliciesMask() const { return PaddingPoliciesMask; }
+ void setPaddingPoliciesMask(uint64_t Value) { PaddingPoliciesMask = Value; }
+ bool hasPaddingPolicy(uint64_t PolicyMask) const {
+ assert(isPowerOf2_64(PolicyMask) &&
+ "Policy mask must contain exactly one policy");
+ return (getPaddingPoliciesMask() & PolicyMask) != PFK_None;
+ }
+ const MCInst &getInst() const {
+ assert(isInstructionInitialized() && "Fragment has no instruction!");
+ return InstInfo.Inst;
+ }
+ size_t getInstSize() const {
+ assert(isInstructionInitialized() && "Fragment has no instruction!");
+ if (InstInfo.IsImmutableSizedInst)
+ return InstInfo.InstSize;
+ assert(InstInfo.InstFragment != nullptr &&
+ "Must have a valid InstFragment to retrieve InstSize from");
+ return InstInfo.InstFragment->getContents().size();
+ }
+ void setInstAndInstSize(const MCInst &Inst, size_t InstSize) {
+ InstInfo.IsInitialized = true;
+ InstInfo.IsImmutableSizedInst = true;
+ InstInfo.Inst = Inst;
+ InstInfo.InstSize = InstSize;
+ }
+ void setInstAndInstFragment(const MCInst &Inst,
+ MCRelaxableFragment *InstFragment) {
+ InstInfo.IsInitialized = true;
+ InstInfo.IsImmutableSizedInst = false;
+ InstInfo.Inst = Inst;
+ InstInfo.InstFragment = InstFragment;
+ }
+ uint64_t getSize() const { return Size; }
+ void setSize(uint64_t Value) { Size = Value; }
+ bool isInstructionInitialized() const { return InstInfo.IsInitialized; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Padding;
+ }
+};
+
class MCFillFragment : public MCFragment {
/// Value to use for filling bytes.
uint8_t Value;
@@ -469,12 +563,13 @@ public:
}
};
-class MCSafeSEHFragment : public MCFragment {
+/// Represents a symbol table index fragment.
+class MCSymbolIdFragment : public MCFragment {
const MCSymbol *Sym;
public:
- MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
- : MCFragment(FT_SafeSEH, false, 0, Sec), Sym(Sym) {}
+ MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
+ : MCFragment(FT_SymbolId, false, 0, Sec), Sym(Sym) {}
/// \name Accessors
/// @{
@@ -485,7 +580,7 @@ public:
/// @}
static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_SafeSEH;
+ return F->getKind() == MCFragment::FT_SymbolId;
}
};