diff options
-rw-r--r-- | include/llvm/MC/MCAsmLayout.h | 7 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 21 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 4 | ||||
-rw-r--r-- | test/MC/X86/AlignedBundling/relax-at-bundle-end.s | 16 |
5 files changed, 37 insertions, 13 deletions
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index 8cb4601283..3058b7b487 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -60,9 +60,10 @@ public: /// Get the assembler object this is a layout for. MCAssembler &getAssembler() const { return Assembler; } - /// \brief Invalidate the fragments after F because it has been resized. - /// The fragment's size should have already been updated. - void invalidateFragmentsAfter(MCFragment *F); + /// \brief Invalidate the fragments starting with F because it has been + /// resized. The fragment's size should have already been updated, but + /// its bundle padding will be recomputed. + void invalidateFragmentsFrom(MCFragment *F); /// \brief Perform layout for a single fragment, assuming that the previous /// fragment has already been laid out correctly, and the parent section has diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index e5d4995e16..0b572eeca8 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" @@ -82,14 +83,14 @@ bool MCAsmLayout::isFragmentValid(const MCFragment *F) const { return F->getLayoutOrder() <= LastValid->getLayoutOrder(); } -void MCAsmLayout::invalidateFragmentsAfter(MCFragment *F) { +void MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) { // If this fragment wasn't already valid, we don't need to do anything. if (!isFragmentValid(F)) return; // Otherwise, reset the last valid fragment to this fragment. const MCSectionData &SD = *F->getParent(); - LastValidFragment[&SD] = F; + LastValidFragment[&SD] = F->getPrevNode(); } void MCAsmLayout::ensureValid(const MCFragment *F) const { @@ -165,14 +166,14 @@ uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const { uint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F, uint64_t FOffset, uint64_t FSize) { uint64_t BundleSize = Assembler.getBundleAlignSize(); - assert(BundleSize > 0 && + assert(BundleSize > 0 && "computeBundlePadding should only be called if bundling is enabled"); uint64_t BundleMask = BundleSize - 1; uint64_t OffsetInBundle = FOffset & BundleMask; uint64_t EndOfFragment = OffsetInBundle + FSize; // There are two kinds of bundling restrictions: - // + // // 1) For alignToBundleEnd(), add padding to ensure that the fragment will // *end* on a bundle boundary. // 2) Otherwise, check if the fragment would cross a bundle boundary. If it @@ -238,8 +239,14 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(false), HasInstructions(false) { - if (A) + // @LOCALMOD-BEGIN + if (A) { + // TODO(dschuff): Carryover from previous localmods. still necessary? A->getSectionList().push_back(this); + if (A->isBundlingEnabled() && _Section.UseCodeAlign()) + setAlignment(A->getBundleAlignSize()); + } + // @LOCALMOD-END } /* *** */ @@ -938,7 +945,7 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { FirstRelaxedFragment = I; } if (FirstRelaxedFragment) { - Layout.invalidateFragmentsAfter(FirstRelaxedFragment); + Layout.invalidateFragmentsFrom(FirstRelaxedFragment); return true; } return false; @@ -998,7 +1005,7 @@ void MCFragment::dump() { OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder << " Offset:" << Offset << " HasInstructions:" << hasInstructions() - << " BundlePadding:" << getBundlePadding() << ">"; + << " BundlePadding:" << static_cast<unsigned>(getBundlePadding()) << ">"; switch (getKind()) { case MCFragment::FT_Align: { diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index b76cdd3a76..fe1dd3bd7a 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -700,7 +700,7 @@ MCAsmBackend *llvm::createARMAsmBackend(const Target &T, StringRef TT, StringRef uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS()); // @LOCALMOD-END - if (TheTriple.isOSNaCl()) + if (TheTriple.isOSNaCl()) return new NaClARMAsmBackend(T, TT, OSABI); // @LOCALMOD-END return new ELFARMAsmBackend(T, TT, OSABI); diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 39ded8fb57..b5d09fa925 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -146,6 +146,8 @@ private: } void EmitMappingSymbol(StringRef Name) { + // @LOCALMOD, and a terrible hack which should be fixed ASAP + return; MCSymbol *Start = getContext().CreateTempSymbol(); EmitLabel(Start); @@ -197,5 +199,3 @@ namespace llvm { } } - - diff --git a/test/MC/X86/AlignedBundling/relax-at-bundle-end.s b/test/MC/X86/AlignedBundling/relax-at-bundle-end.s new file mode 100644 index 0000000000..ab4affbbea --- /dev/null +++ b/test/MC/X86/AlignedBundling/relax-at-bundle-end.s @@ -0,0 +1,16 @@ +# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - \ +# RUN: | llvm-objdump -disassemble -no-show-raw-insn - | FileCheck %s + +# Test that an instruction near a bundle end gets properly padded +# after it is relaxed. +.text +foo: + .bundle_align_mode 5 + .rept 29 + push %rax + .endr +# CHECK: 1c: push +# CHECK: 1d: nop +# CHECK: 20: jne + jne 0x100 + |