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;
protected:
MCFragment(FragmentType Kind, bool HasInstructions,
- uint8_t BundlePadding, MCSection *Parent = nullptr);
+ MCSection *Parent = nullptr);
~MCFragment();
/// 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; }
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; }
};
/// 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) {
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
: 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;
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;
}
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
/// @{
};
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}}) {}
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; }
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
/// @{
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);
}
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);
}
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);
}
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
/// @{
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) {}
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;
}
}
}
}
-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
// ^-------------------^ <- 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))
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.