diff options
author | Derek Schuff <dschuff@google.com> | 2013-01-31 17:00:03 +0000 |
---|---|---|
committer | Derek Schuff <dschuff@google.com> | 2013-01-31 17:00:03 +0000 |
commit | b11917c1aa7348a67d80149fa9613f09a8d56f14 (patch) | |
tree | d4c8944fea705dc2a7631df663bd9ae2aa82f4b4 /lib | |
parent | 1711876988c796d69ba4d30e3aede4527237f79c (diff) | |
download | external_llvm-b11917c1aa7348a67d80149fa9613f09a8d56f14.zip external_llvm-b11917c1aa7348a67d80149fa9613f09a8d56f14.tar.gz external_llvm-b11917c1aa7348a67d80149fa9613f09a8d56f14.tar.bz2 |
[MC] bundle alignment: prevent padding instructions from crossing bundle boundaries
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174067 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 983de1a..498fbf7 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -467,7 +467,7 @@ void MCAsmLayout::layoutFragment(MCFragment *F) { // // // BundlePadding - // ||| + // ||| // ------------------------------------- // Prev |##########| F | // ------------------------------------- @@ -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) { @@ -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"); @@ -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; @@ -1134,4 +1151,3 @@ void MCOrgFragment::anchor() { } void MCLEBFragment::anchor() { } void MCDwarfLineAddrFragment::anchor() { } void MCDwarfCallFrameFragment::anchor() { } - |