Skip to content

Commit

Permalink
[MC] bundle alignment: prevent padding instructions from crossing bun…
Browse files Browse the repository at this point in the history
…dle boundaries

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174067 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
dschuff committed Jan 31, 2013
1 parent 1711876 commit b11917c
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 13 deletions.
24 changes: 20 additions & 4 deletions lib/MC/MCAssembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
//
//
// BundlePadding
// |||
// |||
// -------------------------------------
// Prev |##########| F |
// -------------------------------------
Expand Down Expand Up @@ -506,6 +506,9 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment &F) {
MCObjectWriter *OW = &Asm.getWriter();

// FIXME: Embed in fragments instead?
uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);

// Should NOP padding be written out before this fragment?
unsigned BundlePadding = F.getBundlePadding();
if (BundlePadding > 0) {
Expand All @@ -514,6 +517,22 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
assert(F.hasInstructions() &&
"Writing bundle padding for a fragment without instructions");

unsigned TotalLength = BundlePadding + static_cast<unsigned>(FragmentSize);
if (F.alignToBundleEnd() && TotalLength > Asm.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
// v---------v <- BundlePadding
// ----------------------------
// | Prev |####|####| F |
// ----------------------------
// ^-------------------^ <- TotalLength
unsigned DistanceToBoundary = TotalLength - Asm.getBundleAlignSize();
if (!Asm.getBackend().writeNopData(DistanceToBoundary, OW))
report_fatal_error("unable to write NOP sequence of " +
Twine(DistanceToBoundary) + " bytes");
BundlePadding -= DistanceToBoundary;
}
if (!Asm.getBackend().writeNopData(BundlePadding, OW))
report_fatal_error("unable to write NOP sequence of " +
Twine(BundlePadding) + " bytes");
Expand All @@ -526,8 +545,6 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,

++stats::EmittedFragments;

// FIXME: Embed in fragments instead?
uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
switch (F.getKind()) {
case MCFragment::FT_Align: {
++stats::EmittedAlignFragments;
Expand Down Expand Up @@ -1134,4 +1151,3 @@ void MCOrgFragment::anchor() { }
void MCLEBFragment::anchor() { }
void MCDwarfLineAddrFragment::anchor() { }
void MCDwarfCallFrameFragment::anchor() { }

Loading

0 comments on commit b11917c

Please sign in to comment.