aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/MC/MCAssembler.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-06-21 13:59:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-06-21 13:59:01 +0000
commit3a0822f094b578157263e04114075ad7df81db41 (patch)
treebc48361fe2cd1ca5f93ac01b38b183774468fc79 /include/llvm/MC/MCAssembler.h
parent85d8b2bbe386bcfe669575d05b61482d7be07e5d (diff)
downloadsrc-3a0822f094b578157263e04114075ad7df81db41.tar.gz
src-3a0822f094b578157263e04114075ad7df81db41.zip
Vendor import of llvm trunk r240225:vendor/llvm/llvm-trunk-r240225
Notes
Notes: svn path=/vendor/llvm/dist/; revision=284677 svn path=/vendor/llvm/llvm-trunk-r240225/; revision=284678; tag=vendor/llvm/llvm-trunk-r240225
Diffstat (limited to 'include/llvm/MC/MCAssembler.h')
-rw-r--r--include/llvm/MC/MCAssembler.h237
1 files changed, 96 insertions, 141 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index a6178c214d47..0642af837e7e 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -49,7 +49,7 @@ class MCFragment : public ilist_node<MCFragment> {
void operator=(const MCFragment &) = delete;
public:
- enum FragmentType {
+ enum FragmentType : uint8_t {
FT_Align,
FT_Data,
FT_CompactEncodedInst,
@@ -65,6 +65,18 @@ public:
private:
FragmentType Kind;
+protected:
+ bool HasInstructions;
+
+private:
+ /// \brief Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd;
+
+ uint8_t BundlePadding;
+
+ /// LayoutOrder - The layout order of this fragment.
+ unsigned LayoutOrder;
+
/// The data for the section this fragment is in.
MCSection *Parent;
@@ -81,18 +93,25 @@ private:
/// initialized.
uint64_t Offset;
- /// LayoutOrder - The layout order of this fragment.
- unsigned LayoutOrder;
-
/// @}
protected:
- MCFragment(FragmentType Kind, MCSection *Parent = nullptr);
+ MCFragment(FragmentType Kind, bool HasInstructions,
+ uint8_t BundlePadding, MCSection *Parent = nullptr);
-public:
- // Only for sentinel.
+ ~MCFragment();
+private:
+
+ // This is a friend so that the sentinal can be created.
+ friend struct ilist_sentinel_traits<MCFragment>;
MCFragment();
- virtual ~MCFragment();
+
+public:
+ /// Destroys the current fragment.
+ ///
+ /// This must be used instead of delete as MCFragment is non-virtual.
+ /// This method will dispatch to the appropriate subclass.
+ void destroy();
FragmentType getKind() const { return Kind; }
@@ -107,22 +126,22 @@ public:
/// \brief Does this fragment have instructions emitted into it? By default
/// this is false, but specific fragment types may set it to true.
- virtual bool hasInstructions() const { return false; }
+ bool hasInstructions() const { return HasInstructions; }
/// \brief Should this fragment be placed at the end of an aligned bundle?
- virtual bool alignToBundleEnd() const { return false; }
- virtual void setAlignToBundleEnd(bool V) {}
+ bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
/// \brief Get the padding size that must be inserted before this fragment.
/// Used for bundling. By default, no padding is inserted.
/// Note that padding size is restricted to 8 bits. This is an optimization
/// to reduce the amount of space used for each fragment. In practice, larger
/// padding should never be required.
- virtual uint8_t getBundlePadding() const { return 0; }
+ uint8_t getBundlePadding() const { return BundlePadding; }
/// \brief Set the padding size for this fragment. By default it's a no-op,
/// and only some fragments have a meaningful implementation.
- virtual void setBundlePadding(uint8_t N) {}
+ void setBundlePadding(uint8_t N) { BundlePadding = N; }
void dump();
};
@@ -131,22 +150,12 @@ public:
/// data.
///
class MCEncodedFragment : public MCFragment {
- virtual void anchor();
-
- uint8_t BundlePadding;
+protected:
+ MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
+ MCSection *Sec)
+ : MCFragment(FType, HasInstructions, 0, Sec) {}
public:
- MCEncodedFragment(MCFragment::FragmentType FType, MCSection *Sec = nullptr)
- : MCFragment(FType, Sec), BundlePadding(0) {}
- ~MCEncodedFragment() override;
-
- virtual SmallVectorImpl<char> &getContents() = 0;
- virtual const SmallVectorImpl<char> &getContents() const = 0;
-
- uint8_t getBundlePadding() const override { return BundlePadding; }
-
- void setBundlePadding(uint8_t N) override { BundlePadding = N; }
-
static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
switch (Kind) {
@@ -161,28 +170,52 @@ public:
};
/// Interface implemented by fragments that contain encoded instructions and/or
-/// data and also have fixups registered.
+/// data.
///
-class MCEncodedFragmentWithFixups : public MCEncodedFragment {
- void anchor() override;
+template<unsigned ContentsSize>
+class MCEncodedFragmentWithContents : public MCEncodedFragment {
+ SmallVector<char, ContentsSize> Contents;
+
+protected:
+ MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
+ bool HasInstructions,
+ MCSection *Sec)
+ : MCEncodedFragment(FType, HasInstructions, Sec) {}
public:
- MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
- MCSection *Sec = nullptr)
- : MCEncodedFragment(FType, Sec) {}
+ SmallVectorImpl<char> &getContents() { return Contents; }
+ const SmallVectorImpl<char> &getContents() const { return Contents; }
+};
- ~MCEncodedFragmentWithFixups() override;
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data and also have fixups registered.
+///
+template<unsigned ContentsSize, unsigned FixupsSize>
+class MCEncodedFragmentWithFixups :
+ public MCEncodedFragmentWithContents<ContentsSize> {
+ /// Fixups - The list of fixups in this fragment.
+ SmallVector<MCFixup, FixupsSize> Fixups;
+
+protected:
+ MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
+ bool HasInstructions,
+ MCSection *Sec)
+ : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
+ Sec) {}
+
+public:
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
- virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
- virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
+ SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
+ const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
- virtual fixup_iterator fixup_begin() = 0;
- virtual const_fixup_iterator fixup_begin() const = 0;
- virtual fixup_iterator fixup_end() = 0;
- virtual const_fixup_iterator fixup_end() const = 0;
+ fixup_iterator fixup_begin() { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+
+ fixup_iterator fixup_end() { return Fixups.end(); }
+ const_fixup_iterator fixup_end() const { return Fixups.end(); }
static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
@@ -192,43 +225,12 @@ public:
/// Fragment for data and encoded instructions.
///
-class MCDataFragment : public MCEncodedFragmentWithFixups {
- void anchor() override;
-
- /// \brief Does this fragment contain encoded instructions anywhere in it?
- bool HasInstructions;
-
- /// \brief Should this fragment be aligned to the end of a bundle?
- bool AlignToBundleEnd;
-
- SmallVector<char, 32> Contents;
-
- /// Fixups - The list of fixups in this fragment.
- SmallVector<MCFixup, 4> Fixups;
-
+class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
public:
MCDataFragment(MCSection *Sec = nullptr)
- : MCEncodedFragmentWithFixups(FT_Data, Sec), HasInstructions(false),
- AlignToBundleEnd(false) {}
-
- SmallVectorImpl<char> &getContents() override { return Contents; }
- const SmallVectorImpl<char> &getContents() const override { return Contents; }
-
- SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; }
-
- const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; }
+ : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
- bool hasInstructions() const override { return HasInstructions; }
- virtual void setHasInstructions(bool V) { HasInstructions = V; }
-
- bool alignToBundleEnd() const override { return AlignToBundleEnd; }
- void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
-
- fixup_iterator fixup_begin() override { return Fixups.begin(); }
- const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
-
- fixup_iterator fixup_end() override { return Fixups.end(); }
- const_fixup_iterator fixup_end() const override { return Fixups.end(); }
+ void setHasInstructions(bool V) { HasInstructions = V; }
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Data;
@@ -240,27 +242,12 @@ public:
/// it can be used instead of MCDataFragment and lead to lower memory
/// consumption.
///
-class MCCompactEncodedInstFragment : public MCEncodedFragment {
- void anchor() override;
-
- /// \brief Should this fragment be aligned to the end of a bundle?
- bool AlignToBundleEnd;
-
- SmallVector<char, 4> Contents;
-
+class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
public:
MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
- : MCEncodedFragment(FT_CompactEncodedInst, Sec), AlignToBundleEnd(false) {
+ : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
}
- bool hasInstructions() const override { return true; }
-
- SmallVectorImpl<char> &getContents() override { return Contents; }
- const SmallVectorImpl<char> &getContents() const override { return Contents; }
-
- bool alignToBundleEnd() const override { return AlignToBundleEnd; }
- void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
-
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_CompactEncodedInst;
}
@@ -269,8 +256,7 @@ public:
/// A relaxable fragment holds on to its MCInst, since it may need to be
/// relaxed during the assembler layout and relaxation stage.
///
-class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
- void anchor() override;
+class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
/// Inst - The instruction this is a fragment for.
MCInst Inst;
@@ -280,48 +266,32 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
/// in the assembler are not seen here.
const MCSubtargetInfo STI;
- /// Contents - Binary data for the currently encoded instruction.
- SmallVector<char, 8> Contents;
-
- /// Fixups - The list of fixups in this fragment.
- SmallVector<MCFixup, 1> Fixups;
-
public:
MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
MCSection *Sec = nullptr)
- : MCEncodedFragmentWithFixups(FT_Relaxable, Sec), Inst(Inst), STI(STI) {}
-
- SmallVectorImpl<char> &getContents() override { return Contents; }
- const SmallVectorImpl<char> &getContents() const override { return Contents; }
+ : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
+ Inst(Inst), STI(STI) {}
const MCInst &getInst() const { return Inst; }
void setInst(const MCInst &Value) { Inst = Value; }
const MCSubtargetInfo &getSubtargetInfo() { return STI; }
- SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; }
-
- const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; }
-
- bool hasInstructions() const override { return true; }
-
- fixup_iterator fixup_begin() override { return Fixups.begin(); }
- const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
-
- fixup_iterator fixup_end() override { return Fixups.end(); }
- const_fixup_iterator fixup_end() const override { return Fixups.end(); }
-
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Relaxable;
}
};
class MCAlignFragment : public MCFragment {
- virtual void anchor();
/// Alignment - The alignment to ensure, in bytes.
unsigned Alignment;
+ /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
+ /// of using the provided value. The exact interpretation of this flag is
+ /// target dependent.
+ bool EmitNops : 1;
+
/// Value - Value to use for filling padding bytes.
int64_t Value;
@@ -332,16 +302,12 @@ class MCAlignFragment : public MCFragment {
/// cannot be satisfied in this width then this fragment is ignored.
unsigned MaxBytesToEmit;
- /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
- /// of using the provided value. The exact interpretation of this flag is
- /// target dependent.
- bool EmitNops : 1;
-
public:
MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
- : MCFragment(FT_Align, Sec), Alignment(Alignment), Value(Value),
- ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit), EmitNops(false) {}
+ : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment),
+ EmitNops(false), Value(Value),
+ ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
/// \name Accessors
/// @{
@@ -365,7 +331,6 @@ public:
};
class MCFillFragment : public MCFragment {
- virtual void anchor();
/// Value - Value to use for filling bytes.
int64_t Value;
@@ -380,7 +345,7 @@ class MCFillFragment : public MCFragment {
public:
MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size,
MCSection *Sec = nullptr)
- : MCFragment(FT_Fill, Sec), Value(Value), ValueSize(ValueSize),
+ : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(ValueSize),
Size(Size) {
assert((!ValueSize || (Size % ValueSize) == 0) &&
"Fill size must be a multiple of the value size!");
@@ -403,7 +368,6 @@ public:
};
class MCOrgFragment : public MCFragment {
- virtual void anchor();
/// Offset - The offset this fragment should start at.
const MCExpr *Offset;
@@ -413,7 +377,7 @@ class MCOrgFragment : public MCFragment {
public:
MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSection *Sec = nullptr)
- : MCFragment(FT_Org, Sec), Offset(&Offset), Value(Value) {}
+ : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value) {}
/// \name Accessors
/// @{
@@ -430,7 +394,6 @@ public:
};
class MCLEBFragment : public MCFragment {
- virtual void anchor();
/// Value - The value this fragment should contain.
const MCExpr *Value;
@@ -442,7 +405,7 @@ class MCLEBFragment : public MCFragment {
public:
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
- : MCFragment(FT_LEB, Sec), Value(&Value_), IsSigned(IsSigned_) {
+ : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) {
Contents.push_back(0);
}
@@ -464,7 +427,6 @@ public:
};
class MCDwarfLineAddrFragment : public MCFragment {
- virtual void anchor();
/// LineDelta - the value of the difference between the two line numbers
/// between two .loc dwarf directives.
@@ -479,7 +441,8 @@ class MCDwarfLineAddrFragment : public MCFragment {
public:
MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
MCSection *Sec = nullptr)
- : MCFragment(FT_Dwarf, Sec), LineDelta(LineDelta), AddrDelta(&AddrDelta) {
+ : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta),
+ AddrDelta(&AddrDelta) {
Contents.push_back(0);
}
@@ -501,7 +464,6 @@ public:
};
class MCDwarfCallFrameFragment : public MCFragment {
- virtual void anchor();
/// AddrDelta - The expression for the difference of the two symbols that
/// make up the address delta between two .cfi_* dwarf directives.
@@ -511,7 +473,7 @@ class MCDwarfCallFrameFragment : public MCFragment {
public:
MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
- : MCFragment(FT_DwarfFrame, Sec), AddrDelta(&AddrDelta) {
+ : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) {
Contents.push_back(0);
}
@@ -531,13 +493,11 @@ public:
};
class MCSafeSEHFragment : public MCFragment {
- virtual void anchor();
-
const MCSymbol *Sym;
public:
MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
- : MCFragment(FT_SafeSEH, Sec), Sym(Sym) {}
+ : MCFragment(FT_SafeSEH, false, 0, Sec), Sym(Sym) {}
/// \name Accessors
/// @{
@@ -621,8 +581,6 @@ private:
SymbolDataListType Symbols;
- DenseSet<const MCSymbol *> LocalsUsedInReloc;
-
std::vector<IndirectSymbolData> IndirectSymbols;
std::vector<DataRegionData> DataRegions;
@@ -713,9 +671,6 @@ private:
MCFragment &F, const MCFixup &Fixup);
public:
- void addLocalUsedInReloc(const MCSymbol &Sym);
- bool isLocalUsedInReloc(const MCSymbol &Sym) const;
-
/// Compute the effective fragment size assuming it is laid out at the given
/// \p SectionAddress and \p FragmentOffset.
uint64_t computeFragmentSize(const MCAsmLayout &Layout,