summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/MC/MCAssembler.h7
-rw-r--r--llvm/include/llvm/MC/MCFragment.h98
-rw-r--r--llvm/lib/MC/MCAssembler.cpp27
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp1
-rw-r--r--llvm/lib/MC/MCFragment.cpp18
5 files changed, 77 insertions, 74 deletions
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 34bf180be1f..0f9499d705e 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -442,7 +442,7 @@ public:
/// Write the necessary bundle padding to \p OS.
/// Expects a fragment \p F containing instructions and its size \p FSize.
- void writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
+ void writeFragmentPadding(raw_ostream &OS, const MCEncodedFragment &F,
uint64_t FSize) const;
/// @}
@@ -453,8 +453,9 @@ public:
/// Compute the amount of padding required before the fragment \p F to
/// obey bundling restrictions, where \p FOffset is the fragment's offset in
/// its section and \p FSize is the fragment's size.
-uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCFragment *F,
- uint64_t FOffset, uint64_t FSize);
+uint64_t computeBundlePadding(const MCAssembler &Assembler,
+ const MCEncodedFragment *F, uint64_t FOffset,
+ uint64_t FSize);
} // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCFragment.h b/llvm/include/llvm/MC/MCFragment.h
index 16eb124d95e..47b35175fec 100644
--- a/llvm/include/llvm/MC/MCFragment.h
+++ b/llvm/include/llvm/MC/MCFragment.h
@@ -56,11 +56,6 @@ protected:
bool HasInstructions;
private:
- /// 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;
@@ -84,7 +79,7 @@ private:
protected:
MCFragment(FragmentType Kind, bool HasInstructions,
- uint8_t BundlePadding, MCSection *Parent = nullptr);
+ MCSection *Parent = nullptr);
~MCFragment();
@@ -114,21 +109,6 @@ public:
/// this is false, but specific fragment types may set it to true.
bool hasInstructions() const { return HasInstructions; }
- /// Should this fragment be placed at the end of an aligned bundle?
- bool alignToBundleEnd() const { return AlignToBundleEnd; }
- void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
-
- /// 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.
- uint8_t getBundlePadding() const { return BundlePadding; }
-
- /// Set the padding size for this fragment. By default it's a no-op,
- /// and only some fragments have a meaningful implementation.
- void setBundlePadding(uint8_t N) { BundlePadding = N; }
-
/// Return true if given frgment has FT_Dummy type.
bool isDummy() const { return Kind == FT_Dummy; }
@@ -137,8 +117,7 @@ public:
class MCDummyFragment : public MCFragment {
public:
- explicit MCDummyFragment(MCSection *Sec)
- : MCFragment(FT_Dummy, false, 0, Sec) {}
+ explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {}
static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
};
@@ -147,10 +126,19 @@ public:
/// data.
///
class MCEncodedFragment : public MCFragment {
+ /// Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd = false;
+
+ uint8_t BundlePadding = 0;
+
protected:
MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
MCSection *Sec)
- : MCFragment(FType, HasInstructions, 0, Sec) {}
+ : MCFragment(FType, HasInstructions, Sec) {}
+
+ /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
+ /// must be non-null for instructions.
+ const MCSubtargetInfo *STI = nullptr;
public:
static bool classof(const MCFragment *F) {
@@ -164,6 +152,32 @@ public:
return true;
}
}
+
+ /// Should this fragment be placed at the end of an aligned bundle?
+ bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+
+ /// 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.
+ uint8_t getBundlePadding() const { return BundlePadding; }
+
+ /// Set the padding size for this fragment. By default it's a no-op,
+ /// and only some fragments have a meaningful implementation.
+ void setBundlePadding(uint8_t N) { BundlePadding = N; }
+
+ /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
+ /// Guaranteed to be non-null if hasInstructions() == true
+ const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
+
+ /// Record that the fragment contains instructions with the MCSubtargetInfo in
+ /// effect when the instruction was encoded.
+ void setHasInstructions(const MCSubtargetInfo &STI) {
+ HasInstructions = true;
+ this->STI = &STI;
+ }
};
/// Interface implemented by fragments that contain encoded instructions and/or
@@ -201,16 +215,8 @@ protected:
: MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
Sec) {}
- /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
- /// must be non-null for instructions.
- const MCSubtargetInfo *STI = nullptr;
-
public:
- /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
- /// Guaranteed to be non-null if hasInstructions() == true
- const MCSubtargetInfo *getSubtargetInfo() const { return STI; }
-
using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
@@ -237,13 +243,6 @@ public:
MCDataFragment(MCSection *Sec = nullptr)
: MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
- /// Record that the fragment contains instructions with the MCSubtargetInfo in
- /// effect when the instruction was encoded.
- void setHasInstructions(const MCSubtargetInfo &STI) {
- HasInstructions = true;
- this->STI = &STI;
- }
-
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Data;
}
@@ -309,9 +308,8 @@ class MCAlignFragment : public MCFragment {
public:
MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
- : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment),
- EmitNops(false), Value(Value),
- ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
+ : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false),
+ Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
/// \name Accessors
/// @{
@@ -379,7 +377,7 @@ public:
};
MCPaddingFragment(MCSection *Sec = nullptr)
- : MCFragment(FT_Padding, false, 0, Sec), PaddingPoliciesMask(PFK_None),
+ : MCFragment(FT_Padding, false, Sec), PaddingPoliciesMask(PFK_None),
IsInsertionPoint(false), Size(UINT64_C(0)),
InstInfo({false, MCInst(), false, {0}}) {}
@@ -439,7 +437,7 @@ class MCFillFragment : public MCFragment {
public:
MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues,
SMLoc Loc, MCSection *Sec = nullptr)
- : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(VSize),
+ : MCFragment(FT_Fill, false, Sec), Value(Value), ValueSize(VSize),
NumValues(NumValues), Loc(Loc) {}
uint64_t getValue() const { return Value; }
@@ -466,7 +464,7 @@ class MCOrgFragment : public MCFragment {
public:
MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc,
MCSection *Sec = nullptr)
- : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value), Loc(Loc) {}
+ : MCFragment(FT_Org, false, Sec), Offset(&Offset), Value(Value), Loc(Loc) {}
/// \name Accessors
/// @{
@@ -495,7 +493,7 @@ class MCLEBFragment : public MCFragment {
public:
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
- : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) {
+ : MCFragment(FT_LEB, false, Sec), Value(&Value_), IsSigned(IsSigned_) {
Contents.push_back(0);
}
@@ -530,7 +528,7 @@ class MCDwarfLineAddrFragment : public MCFragment {
public:
MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
MCSection *Sec = nullptr)
- : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta),
+ : MCFragment(FT_Dwarf, false, Sec), LineDelta(LineDelta),
AddrDelta(&AddrDelta) {
Contents.push_back(0);
}
@@ -561,7 +559,7 @@ class MCDwarfCallFrameFragment : public MCFragment {
public:
MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
- : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) {
+ : MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) {
Contents.push_back(0);
}
@@ -586,7 +584,7 @@ class MCSymbolIdFragment : public MCFragment {
public:
MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
- : MCFragment(FT_SymbolId, false, 0, Sec), Sym(Sym) {}
+ : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {}
/// \name Accessors
/// @{
@@ -620,7 +618,7 @@ public:
unsigned StartLineNum, const MCSymbol *FnStartSym,
const MCSymbol *FnEndSym,
MCSection *Sec = nullptr)
- : MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId),
+ : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId),
StartFileId(StartFileId), StartLineNum(StartLineNum),
FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 973311c93f6..1470e026d98 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -426,17 +426,18 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
if (Assembler.isBundlingEnabled() && F->hasInstructions()) {
assert(isa<MCEncodedFragment>(F) &&
"Only MCEncodedFragment implementations have instructions");
- uint64_t FSize = Assembler.computeFragmentSize(*this, *F);
+ MCEncodedFragment *EF = cast<MCEncodedFragment>(F);
+ uint64_t FSize = Assembler.computeFragmentSize(*this, *EF);
if (!Assembler.getRelaxAll() && FSize > Assembler.getBundleAlignSize())
report_fatal_error("Fragment can't be larger than a bundle size");
- uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F,
- F->Offset, FSize);
+ uint64_t RequiredBundlePadding =
+ computeBundlePadding(Assembler, EF, EF->Offset, FSize);
if (RequiredBundlePadding > UINT8_MAX)
report_fatal_error("Padding cannot exceed 255 bytes");
- F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
- F->Offset += RequiredBundlePadding;
+ EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
+ EF->Offset += RequiredBundlePadding;
}
}
@@ -450,19 +451,20 @@ void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) {
}
}
-void MCAssembler::writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
+void MCAssembler::writeFragmentPadding(raw_ostream &OS,
+ const MCEncodedFragment &EF,
uint64_t FSize) const {
assert(getBackendPtr() && "Expected assembler backend");
// Should NOP padding be written out before this fragment?
- unsigned BundlePadding = F.getBundlePadding();
+ unsigned BundlePadding = EF.getBundlePadding();
if (BundlePadding > 0) {
assert(isBundlingEnabled() &&
"Writing bundle padding with disabled bundling");
- assert(F.hasInstructions() &&
+ assert(EF.hasInstructions() &&
"Writing bundle padding for a fragment without instructions");
unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize);
- if (F.alignToBundleEnd() && TotalLength > getBundleAlignSize()) {
+ if (EF.alignToBundleEnd() && TotalLength > getBundleAlignSize()) {
// If the padding itself crosses a bundle boundary, it must be emitted
// in 2 pieces, since even nop instructions must not cross boundaries.
// v--------------v <- BundleAlignSize
@@ -473,8 +475,8 @@ void MCAssembler::writeFragmentPadding(raw_ostream &OS, const MCFragment &F,
// ^-------------------^ <- TotalLength
unsigned DistanceToBoundary = TotalLength - getBundleAlignSize();
if (!getBackend().writeNopData(OS, DistanceToBoundary))
- report_fatal_error("unable to write NOP sequence of " +
- Twine(DistanceToBoundary) + " bytes");
+ report_fatal_error("unable to write NOP sequence of " +
+ Twine(DistanceToBoundary) + " bytes");
BundlePadding -= DistanceToBoundary;
}
if (!getBackend().writeNopData(OS, BundlePadding))
@@ -491,7 +493,8 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
support::endianness Endian = Asm.getBackend().Endian;
- Asm.writeFragmentPadding(OS, F, FragmentSize);
+ if (const MCEncodedFragment *EF = dyn_cast<MCEncodedFragment>(&F))
+ Asm.writeFragmentPadding(OS, *EF, FragmentSize);
// This variable (and its dummy usage) is to participate in the assert at
// the end of the function.
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index df11495a954..f44d877e260 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -557,6 +557,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment();
insert(CEIF);
CEIF->getContents().append(Code.begin(), Code.end());
+ CEIF->setHasInstructions(STI);
return;
} else {
DF = new MCDataFragment();
diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp
index 70118f9c371..01ad640ee22 100644
--- a/llvm/lib/MC/MCFragment.cpp
+++ b/llvm/lib/MC/MCFragment.cpp
@@ -189,7 +189,7 @@ uint64_t MCAsmLayout::getSectionFileSize(const MCSection *Sec) const {
}
uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
- const MCFragment *F,
+ const MCEncodedFragment *F,
uint64_t FOffset, uint64_t FSize) {
uint64_t BundleSize = Assembler.getBundleAlignSize();
assert(BundleSize > 0 &&
@@ -236,10 +236,9 @@ void ilist_alloc_traits<MCFragment>::deleteNode(MCFragment *V) { V->destroy(); }
MCFragment::~MCFragment() = default;
MCFragment::MCFragment(FragmentType Kind, bool HasInstructions,
- uint8_t BundlePadding, MCSection *Parent)
- : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false),
- BundlePadding(BundlePadding), Parent(Parent), Atom(nullptr),
- Offset(~UINT64_C(0)) {
+ MCSection *Parent)
+ : Kind(Kind), HasInstructions(HasInstructions), Parent(Parent),
+ Atom(nullptr), Offset(~UINT64_C(0)) {
if (Parent && !isDummy())
Parent->getFragmentList().push_back(this);
}
@@ -333,10 +332,11 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break;
}
- OS << "<MCFragment " << (const void*) this << " LayoutOrder:" << LayoutOrder
- << " Offset:" << Offset
- << " HasInstructions:" << hasInstructions()
- << " BundlePadding:" << static_cast<unsigned>(getBundlePadding()) << ">";
+ OS << "<MCFragment " << (const void *)this << " LayoutOrder:" << LayoutOrder
+ << " Offset:" << Offset << " HasInstructions:" << hasInstructions();
+ if (const MCEncodedFragment *EF = cast<MCEncodedFragment>(this))
+ OS << " BundlePadding:" << static_cast<unsigned>(EF->getBundlePadding());
+ OS << ">";
switch (getKind()) {
case MCFragment::FT_Align: {
OpenPOWER on IntegriCloud