diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index cebd564036b2c..4333b032c9d4e 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1671,8 +1671,9 @@ void RelocationScanner::scan(Relocs rels) { } // Sort relocations by offset for more efficient searching for - // R_RISCV_PCREL_HI20, R_PPC64_ADDR64 and the branch-to-branch optimization. - if (ctx.arg.emachine == EM_RISCV || + // R_RISCV_PCREL_HI20, ALIGN relocations, R_PPC64_ADDR64 and the + // branch-to-branch optimization. + if (is_contained({EM_RISCV, EM_LOONGARCH}, ctx.arg.emachine) || (ctx.arg.emachine == EM_PPC64 && sec->name == ".toc") || ctx.arg.branchToBranch) llvm::stable_sort(sec->relocs(), diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h index cd7c4b79b594b..03dc14736396d 100644 --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -21,12 +21,7 @@ namespace llvm { -class MCAlignFragment; -class MCDwarfCallFrameFragment; -class MCDwarfLineAddrFragment; class MCFragment; -class MCLEBFragment; -class MCRelaxableFragment; class MCSymbol; class MCAssembler; class MCContext; @@ -66,6 +61,9 @@ class LLVM_ABI MCAsmBackend { MCAssembler *Asm = nullptr; + bool AllowAutoPadding = false; + bool AllowEnhancedRelaxation = false; + public: MCAsmBackend(const MCAsmBackend &) = delete; MCAsmBackend &operator=(const MCAsmBackend &) = delete; @@ -79,11 +77,11 @@ class LLVM_ABI MCAsmBackend { /// Return true if this target might automatically pad instructions and thus /// need to emit padding enable/disable directives around sensative code. - virtual bool allowAutoPadding() const { return false; } + bool allowAutoPadding() const { return AllowAutoPadding; } /// Return true if this target allows an unrelaxable instruction to be /// emitted into RelaxableFragment and then we can increase its size in a /// tricky way for optimization. - virtual bool allowEnhancedRelaxation() const { return false; } + bool allowEnhancedRelaxation() const { return AllowEnhancedRelaxation; } /// lifetime management virtual void reset() {} @@ -126,21 +124,6 @@ class LLVM_ABI MCAsmBackend { /// Get information on a fixup kind. virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const; - /// Hook to check if extra nop bytes must be inserted for alignment directive. - /// For some targets this may be necessary in order to support linker - /// relaxation. The number of bytes to insert are returned in Size. - virtual bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF, - unsigned &Size) { - return false; - } - - /// Hook which indicates if the target requires a fixup to be generated when - /// handling an align directive in an executable section - virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, - MCAlignFragment &AF) { - return false; - } - // Evaluate a fixup, returning std::nullopt to use default handling for // `Value` and `IsResolved`. Otherwise, returns `IsResolved` with the // expectation that the hook updates `Value`. @@ -175,8 +158,9 @@ class LLVM_ABI MCAsmBackend { /// Target specific predicate for whether a given fixup requires the /// associated instruction to be relaxed. - virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, - uint64_t, bool Resolved) const; + virtual bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, + const MCValue &, uint64_t, + bool Resolved) const; /// Simple predicate for targets where !Resolved implies requiring relaxation virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, @@ -197,18 +181,20 @@ class LLVM_ABI MCAsmBackend { } // Defined by linker relaxation targets. - virtual bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, - bool &WasRelaxed) const { + + // Return false to use default handling. Otherwise, set `Size` to the number + // of padding bytes. + virtual bool relaxAlign(MCFragment &F, unsigned &Size) { return false; } + virtual bool relaxDwarfLineAddr(MCFragment &, bool &WasRelaxed) const { return false; } - virtual bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, - bool &WasRelaxed) const { + virtual bool relaxDwarfCFA(MCFragment &, bool &WasRelaxed) const { return false; } // Defined by linker relaxation targets to possibly emit LEB128 relocations // and set Value at the relocated location. - virtual std::pair relaxLEB128(MCLEBFragment &LF, + virtual std::pair relaxLEB128(MCFragment &, int64_t &Value) const { return std::make_pair(false, false); } @@ -246,8 +232,7 @@ class LLVM_ABI MCAsmBackend { bool isDarwinCanonicalPersonality(const MCSymbol *Sym) const; - // Return STI for fragments of type MCRelaxableFragment and MCDataFragment - // with hasInstructions() == true. + // Return STI for fragments with hasInstructions() == true. static const MCSubtargetInfo *getSubtargetInfo(const MCFragment &F); }; diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index 1015992cedf29..467ad4eabd3b0 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -34,13 +34,8 @@ namespace llvm { class MCBoundaryAlignFragment; class MCCVDefRangeFragment; class MCCVInlineLineTableFragment; -class MCDwarfCallFrameFragment; -class MCDwarfLineAddrFragment; -class MCEncodedFragment; +class MCFragment; class MCFixup; -class MCLEBFragment; -class MCPseudoProbeAddrFragment; -class MCRelaxableFragment; class MCSymbolRefExpr; class raw_ostream; class MCAsmBackend; @@ -72,6 +67,13 @@ class MCAssembler { SmallVector Symbols; + struct RelocDirective { + const MCExpr &Offset; + const MCExpr *Expr; + uint32_t Kind; + }; + SmallVector relocDirectives; + mutable SmallVector, 0> PendingErrors; MCDwarfLineTableParams LTParams; @@ -85,11 +87,6 @@ class MCAssembler { // refactoring too. mutable SmallPtrSet ThumbFuncs; - /// The bundle alignment size currently set in the assembler. - /// - /// By default it's 0, which means bundling is disabled. - unsigned BundleAlignSize = 0; - /// Evaluate a fixup to a relocatable expression and the value which should be /// placed into the fixup. /// @@ -107,7 +104,7 @@ class MCAssembler { /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). - bool fixupNeedsRelaxation(const MCRelaxableFragment &, const MCFixup &) const; + bool fixupNeedsRelaxation(const MCFragment &, const MCFixup &) const; void layoutSection(MCSection &Sec); /// Perform one layout iteration and return the index of the first stable @@ -116,15 +113,14 @@ class MCAssembler { /// Perform relaxation on a single fragment. bool relaxFragment(MCFragment &F); - bool relaxInstruction(MCRelaxableFragment &IF); - bool relaxLEB(MCLEBFragment &IF); + bool relaxInstruction(MCFragment &F); + bool relaxLEB(MCFragment &F); bool relaxBoundaryAlign(MCBoundaryAlignFragment &BF); - bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF); - bool relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF); + bool relaxDwarfLineAddr(MCFragment &F); + bool relaxDwarfCallFrameFragment(MCFragment &F); bool relaxCVInlineLineTable(MCCVInlineLineTableFragment &DF); bool relaxCVDefRange(MCCVDefRangeFragment &DF); bool relaxFill(MCFillFragment &F); - bool relaxPseudoProbeAddr(MCPseudoProbeAddrFragment &DF); public: /// Construct a new assembler instance. @@ -143,8 +139,6 @@ class MCAssembler { /// Compute the effective fragment size. LLVM_ABI uint64_t computeFragmentSize(const MCFragment &F) const; - LLVM_ABI void layoutBundle(MCFragment *Prev, MCFragment *F) const; - // Get the offset of the given fragment inside its containing section. uint64_t getFragmentOffset(const MCFragment &F) const { return F.Offset; } @@ -203,16 +197,6 @@ class MCAssembler { bool getRelaxAll() const { return RelaxAll; } void setRelaxAll(bool Value) { RelaxAll = Value; } - bool isBundlingEnabled() const { return BundleAlignSize != 0; } - - unsigned getBundleAlignSize() const { return BundleAlignSize; } - - void setBundleAlignSize(unsigned Size) { - assert((Size == 0 || !(Size & (Size - 1))) && - "Expect a power-of-two bundle align size"); - BundleAlignSize = Size; - } - const_iterator begin() const { return Sections.begin(); } const_iterator end() const { return Sections.end(); } @@ -225,12 +209,7 @@ class MCAssembler { LLVM_ABI bool registerSection(MCSection &Section); LLVM_ABI bool registerSymbol(const MCSymbol &Symbol); - - /// Write the necessary bundle padding to \p OS. - /// Expects a fragment \p F containing instructions and its size \p FSize. - LLVM_ABI void writeFragmentPadding(raw_ostream &OS, - const MCEncodedFragment &F, - uint64_t FSize) const; + void addRelocDirective(RelocDirective RD); LLVM_ABI void reportError(SMLoc L, const Twine &Msg) const; // Record pending errors during layout iteration, as they may go away once the diff --git a/llvm/include/llvm/MC/MCCodeView.h b/llvm/include/llvm/MC/MCCodeView.h index 88f84a2462841..9cde44c71baff 100644 --- a/llvm/include/llvm/MC/MCCodeView.h +++ b/llvm/include/llvm/MC/MCCodeView.h @@ -26,7 +26,6 @@ namespace llvm { class MCAssembler; class MCCVDefRangeFragment; class MCCVInlineLineTableFragment; -class MCDataFragment; class MCFragment; class MCSection; class MCSymbol; @@ -231,7 +230,7 @@ class CodeViewContext { StringMap StringTable; /// The fragment that ultimately holds our strings. - MCDataFragment *StrTabFragment = nullptr; + MCFragment *StrTabFragment = nullptr; SmallVector StrTab = {'\0'}; /// Get a string table offset. diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index 5a8ec17dae1cc..c137f6184a9a7 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -47,7 +47,6 @@ namespace llvm { class CodeViewContext; class MCAsmInfo; -class MCDataFragment; class MCInst; class MCLabel; class MCObjectFileInfo; @@ -334,7 +333,7 @@ class MCContext { void reportCommon(SMLoc Loc, std::function); - MCDataFragment *allocInitialFragment(MCSection &Sec); + MCFragment *allocInitialFragment(MCSection &Sec); MCSymbolTableEntry &getSymbolTableEntry(StringRef Name); diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index fa0b5cbde71d9..144f6bc3bd91c 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -17,7 +17,6 @@ namespace llvm { class ELFObjectWriter; class MCContext; -class MCDataFragment; class MCFragment; class MCObjectWriter; class MCSection; @@ -51,7 +50,7 @@ class MCELFStreamer : public MCObjectStreamer { void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override; void changeSection(MCSection *Section, uint32_t Subsection = 0) override; void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; - void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, + void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment &F, uint64_t Offset) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Target) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; @@ -65,13 +64,8 @@ class MCELFStreamer : public MCObjectStreamer { void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment) override; - void emitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc = SMLoc()) override; - void emitIdent(StringRef IdentString) override; - void emitValueToAlignment(Align, int64_t, uint8_t, unsigned) override; - void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count) override; @@ -79,10 +73,6 @@ class MCELFStreamer : public MCObjectStreamer { // target-specific code. void finishImpl() final; - void emitBundleAlignMode(Align Alignment) override; - void emitBundleLock(bool AlignToEnd) override; - void emitBundleUnlock() override; - /// ELF object attributes section emission support struct AttributeItem { // This structure holds all attributes, accounting for their string / @@ -151,10 +141,8 @@ class MCELFStreamer : public MCObjectStreamer { } private: - bool isBundleLocked() const; - void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; - - void finalizeCGProfileEntry(const MCSymbolRefExpr *&S, uint64_t Offset); + void finalizeCGProfileEntry(const MCSymbolRefExpr *Sym, uint64_t Offset, + const MCSymbolRefExpr *&S); void finalizeCGProfile(); bool SeenIdent = false; diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 2b42507d66920..429a1bb3321f6 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -40,14 +40,6 @@ class MCObjectStreamer : public MCStreamer { std::unique_ptr Assembler; bool EmitEHFrame; bool EmitDebugFrame; - struct PendingMCFixup { - const MCSymbol *Sym; - MCFixup Fixup; - MCDataFragment *DF; - PendingMCFixup(const MCSymbol *McSym, MCDataFragment *F, MCFixup McFixup) - : Sym(McSym), Fixup(McFixup), DF(F) {} - }; - SmallVector PendingFixups; struct PendingAssignment { MCSymbol *Symbol; @@ -59,11 +51,9 @@ class MCObjectStreamer : public MCStreamer { DenseMap> pendingAssignments; - virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &); + void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &); void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; - void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI); - void resolvePendingFixups(); protected: MCObjectStreamer(MCContext &Context, std::unique_ptr TAB, @@ -82,21 +72,6 @@ class MCObjectStreamer : public MCStreamer { MCSymbol *emitCFILabel() override; void emitCFISections(bool EH, bool Debug) override; - void insert(MCFragment *F) { - auto *Sec = CurFrag->getParent(); - F->setParent(Sec); - F->setLayoutOrder(CurFrag->getLayoutOrder() + 1); - CurFrag->Next = F; - CurFrag = F; - Sec->curFragList()->Tail = F; - } - - /// Get a data fragment to write into, creating a new one if the current - /// fragment is not a data fragment. - /// Optionally a \p STI can be passed in so that a new fragment is created - /// if the Subtarget differs from the current fragment. - MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr); - protected: bool changeSectionImpl(MCSection *Section, uint32_t Subsection); @@ -109,7 +84,7 @@ class MCObjectStreamer : public MCStreamer { /// @{ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; - virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, + virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment &F, uint64_t Offset); void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void emitConditionalAssignment(MCSymbol *Symbol, @@ -127,9 +102,6 @@ class MCObjectStreamer : public MCStreamer { /// can change its size during relaxation. void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &); - void emitBundleAlignMode(Align Alignment) override; - void emitBundleLock(bool AlignToEnd) override; - void emitBundleUnlock() override; void emitBytes(StringRef Data) override; void emitValueToAlignment(Align Alignment, int64_t Fill = 0, uint8_t FillLen = 1, @@ -165,9 +137,8 @@ class MCObjectStreamer : public MCStreamer { void emitCVStringTableDirective() override; void emitCVFileChecksumsDirective() override; void emitCVFileChecksumOffsetDirective(unsigned FileNo) override; - std::optional> - emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, - SMLoc Loc, const MCSubtargetInfo &STI) override; + void emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc = {}) override; using MCStreamer::emitFill; void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc = SMLoc()) override; diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h index e9f3820319281..ce295728c4efd 100644 --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -46,8 +46,6 @@ class LLVM_ABI MCSection { friend MCAssembler; friend MCObjectStreamer; friend class MCFragment; - friend class MCEncodedFragment; - friend class MCRelaxableFragment; static constexpr unsigned NonUniqueID = ~0U; enum SectionVariant { @@ -62,13 +60,6 @@ class LLVM_ABI MCSection { SV_CAS, // MCCAS }; - /// Express the state of bundle locked groups while emitting code. - enum BundleLockStateType { - NotBundleLocked, - BundleLocked, - BundleLockedAlignToEnd - }; - struct iterator { MCFragment *F = nullptr; iterator() = default; @@ -95,24 +86,13 @@ class LLVM_ABI MCSection { /// The section index in the assemblers section list. unsigned Ordinal = 0; - /// Keeping track of bundle-locked state. - BundleLockStateType BundleLockState = NotBundleLocked; - - /// Current nesting depth of bundle_lock directives. - unsigned BundleLockNestingDepth = 0; - - /// We've seen a bundle_lock directive but not its first instruction - /// yet. - bool BundleGroupBeforeFirstInst : 1; - /// Whether this section has had instructions emitted into it. bool HasInstructions : 1; bool IsRegistered : 1; bool IsText : 1; - - bool IsVirtual : 1; + bool IsBss : 1; /// Whether the section contains linker-relaxable fragments. If true, the /// offset between two locations may not be fully resolved. @@ -133,7 +113,7 @@ class LLVM_ABI MCSection { StringRef Name; SectionVariant Variant; - MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsVirtual, + MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsBss, MCSymbol *Begin); // Protected non-virtual dtor prevents destroy through a base class pointer. ~MCSection() {} @@ -170,17 +150,6 @@ class LLVM_ABI MCSection { unsigned getOrdinal() const { return Ordinal; } void setOrdinal(unsigned Value) { Ordinal = Value; } - BundleLockStateType getBundleLockState() const { return BundleLockState; } - void setBundleLockState(BundleLockStateType NewState); - bool isBundleLocked() const { return BundleLockState != NotBundleLocked; } - - bool isBundleGroupBeforeFirstInst() const { - return BundleGroupBeforeFirstInst; - } - void setBundleGroupBeforeFirstInst(bool IsFirst) { - BundleGroupBeforeFirstInst = IsFirst; - } - bool hasInstructions() const { return HasInstructions; } void setHasInstructions(bool Value) { HasInstructions = Value; } @@ -209,9 +178,7 @@ class LLVM_ABI MCSection { /// Check whether this section is "virtual", that is has no actual object /// file contents. - bool isVirtualSection() const { return IsVirtual; } - - virtual StringRef getVirtualSectionKind() const; + bool isBssSection() const { return IsBss; } }; // Represents a contiguous piece of code or data within a section. Its size is @@ -219,6 +186,7 @@ class LLVM_ABI MCSection { // destructors. class MCFragment { friend class MCAssembler; + friend class MCStreamer; friend class MCObjectStreamer; friend class MCSection; @@ -237,7 +205,6 @@ class MCFragment { FT_SymbolId, FT_CVInlineLines, FT_CVDefRange, - FT_PseudoProbe, }; private: @@ -256,94 +223,104 @@ class MCFragment { FragmentType Kind; protected: - /// Used by subclasses for better packing. + bool LinkerRelaxable : 1; + + /// Used by certain fragment types for better packing. /// - /// MCEncodedFragment + /// FT_Data, FT_Relaxable bool HasInstructions : 1; - bool AlignToBundleEnd : 1; - /// MCDataFragment - bool LinkerRelaxable : 1; - /// MCRelaxableFragment: x86-specific + /// FT_Relaxable, x86-specific bool AllowAutoPadding : 1; - LLVM_ABI MCFragment(FragmentType Kind, bool HasInstructions); - -public: - MCFragment() = delete; - MCFragment(const MCFragment &) = delete; - MCFragment &operator=(const MCFragment &) = delete; - - MCFragment *getNext() const { return Next; } - - FragmentType getKind() const { return Kind; } - - MCSection *getParent() const { return Parent; } - void setParent(MCSection *Value) { Parent = Value; } - - LLVM_ABI const MCSymbol *getAtom() const; - - unsigned getLayoutOrder() const { return LayoutOrder; } - void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - - /// Does this fragment have instructions emitted into it? By default - /// this is false, but specific fragment types may set it to true. - bool hasInstructions() const { return HasInstructions; } - - bool isLinkerRelaxable() const { return LinkerRelaxable; } - void setLinkerRelaxable() { LinkerRelaxable = true; } - - LLVM_ABI void dump() const; -}; - -/// Interface implemented by fragments that contain encoded instructions and/or -/// data. -class MCEncodedFragment : public MCFragment { - uint8_t BundlePadding = 0; uint32_t ContentStart = 0; uint32_t ContentEnd = 0; uint32_t FixupStart = 0; uint32_t FixupEnd = 0; -protected: - MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions) - : MCFragment(FType, HasInstructions) {} + uint32_t VarContentStart = 0; + uint32_t VarContentEnd = 0; + uint32_t VarFixupStart = 0; + uint32_t VarFixupEnd = 0; - /// The MCSubtargetInfo in effect when the instruction was encoded. - /// It must be non-null for instructions. const MCSubtargetInfo *STI = nullptr; + // Optional variable-size tail used by various fragment types. + union Tail { + struct { + uint32_t Opcode; + uint32_t Flags; + uint32_t OperandStart; + uint32_t OperandSize; + } relax; + struct { + // The alignment to ensure, in bytes. + Align Alignment; + // The size of the integer (in bytes) of \p Value. + uint8_t FillLen; + // If true, fill with target-specific nop instructions. + bool EmitNops; + // The maximum number of bytes to emit; if the alignment + // cannot be satisfied in this width then this fragment is ignored. + unsigned MaxBytesToEmit; + // Value to use for filling padding bytes. + int64_t Fill; + } align; + struct { + // True if this is a sleb128, false if uleb128. + bool IsSigned; + // The value this fragment should contain. + const MCExpr *Value; + } leb; + // Used by .debug_frame and .debug_line to encode an address difference. + struct { + // The address difference between two labels. + const MCExpr *AddrDelta; + // The value of the difference between the two line numbers between two + // .loc dwarf directives. + int64_t LineDelta; + } dwarf; + } u{}; + public: - static bool classof(const MCFragment *F) { - MCFragment::FragmentType Kind = F->getKind(); + LLVM_ABI MCFragment(FragmentType Kind = MCFragment::FT_Data, + bool HasInstructions = false); + MCFragment(const MCFragment &) = delete; + MCFragment &operator=(const MCFragment &) = delete; + + bool isEncoded() const { + MCFragment::FragmentType Kind = getKind(); switch (Kind) { default: return false; case MCFragment::FT_Relaxable: case MCFragment::FT_Data: + case MCFragment::FT_Align: case MCFragment::FT_Dwarf: case MCFragment::FT_DwarfFrame: case MCFragment::FT_LEB: - case MCFragment::FT_PseudoProbe: case MCFragment::FT_CVInlineLines: case MCFragment::FT_CVDefRange: 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; } + MCFragment *getNext() const { return Next; } + + FragmentType getKind() const { return Kind; } + + MCSection *getParent() const { return Parent; } + void setParent(MCSection *Value) { Parent = Value; } + + LLVM_ABI const MCSymbol *getAtom() const; + + unsigned getLayoutOrder() const { return LayoutOrder; } + void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } - /// 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; } + /// Does this fragment have instructions emitted into it? By default + /// this is false, but specific fragment types may set it to true. + bool hasInstructions() const { return HasInstructions; } - /// 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; } + LLVM_ABI void dump() const; /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded. /// Guaranteed to be non-null if hasInstructions() == true @@ -356,6 +333,9 @@ class MCEncodedFragment : public MCFragment { this->STI = &STI; } + bool isLinkerRelaxable() const { return LinkerRelaxable; } + void setLinkerRelaxable() { LinkerRelaxable = true; } + bool getAllowAutoPadding() const { return AllowAutoPadding; } void setAllowAutoPadding(bool V) { AllowAutoPadding = V; } @@ -395,7 +375,24 @@ class MCEncodedFragment : public MCFragment { .slice(ContentStart, ContentEnd - ContentStart); } - // Fixup-related functions manage parent's storage using FixupStart and + void setVarContents(ArrayRef Contents); + void clearVarContents() { setVarContents({}); } + MutableArrayRef getVarContents() { + return MutableArrayRef(getParent()->ContentStorage) + .slice(VarContentStart, VarContentEnd - VarContentStart); + } + ArrayRef getVarContents() const { + return ArrayRef(getParent()->ContentStorage) + .slice(VarContentStart, VarContentEnd - VarContentStart); + } + + size_t getFixedSize() const { return ContentEnd - ContentStart; } + size_t getVarSize() const { return VarContentEnd - VarContentStart; } + size_t getSize() const { + return ContentEnd - ContentStart + (VarContentEnd - VarContentStart); + } + + //== Fixup-related functions manage parent's storage using FixupStart and // FixupSize. void clearFixups() { FixupEnd = FixupStart; } LLVM_ABI void addFixup(MCFixup Fixup); @@ -410,109 +407,128 @@ class MCEncodedFragment : public MCFragment { .slice(FixupStart, FixupEnd - FixupStart); } - size_t getSize() const { return ContentEnd - ContentStart; } -}; - -/// Fragment for data and encoded instructions. -/// -class MCDataFragment : public MCEncodedFragment { -public: - MCDataFragment() : MCEncodedFragment(FT_Data, false) {} - - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Data; + // Source fixup offsets are relative to the variable part's start. + // Stored fixup offsets are relative to the fixed part's start. + void setVarFixups(ArrayRef Fixups); + void clearVarFixups() { setVarFixups({}); } + MutableArrayRef getVarFixups() { + return MutableArrayRef(getParent()->FixupStorage) + .slice(VarFixupStart, VarFixupEnd - VarFixupStart); } -}; - -/// A relaxable fragment holds on to its MCInst, since it may need to be -/// relaxed during the assembler layout and relaxation stage. -/// -class MCRelaxableFragment : public MCEncodedFragment { - uint32_t Opcode = 0; - uint32_t Flags = 0; - uint32_t OperandStart = 0; - uint32_t OperandSize = 0; - -public: - MCRelaxableFragment(const MCSubtargetInfo &STI) - : MCEncodedFragment(FT_Relaxable, true) { - this->STI = &STI; + ArrayRef getVarFixups() const { + return ArrayRef(getParent()->FixupStorage) + .slice(VarFixupStart, VarFixupEnd - VarFixupStart); } - unsigned getOpcode() const { return Opcode; } + //== FT_Relaxable functions + unsigned getOpcode() const { + assert(Kind == FT_Relaxable); + return u.relax.Opcode; + } ArrayRef getOperands() const { + assert(Kind == FT_Relaxable); return MutableArrayRef(getParent()->MCOperandStorage) - .slice(OperandStart, OperandSize); + .slice(u.relax.OperandStart, u.relax.OperandSize); } MCInst getInst() const { + assert(Kind == FT_Relaxable); MCInst Inst; - Inst.setOpcode(Opcode); - Inst.setFlags(Flags); + Inst.setOpcode(u.relax.Opcode); + Inst.setFlags(u.relax.Flags); Inst.setOperands(ArrayRef(getParent()->MCOperandStorage) - .slice(OperandStart, OperandSize)); + .slice(u.relax.OperandStart, u.relax.OperandSize)); return Inst; } void setInst(const MCInst &Inst) { - Opcode = Inst.getOpcode(); - Flags = Inst.getFlags(); + assert(Kind == FT_Relaxable); + u.relax.Opcode = Inst.getOpcode(); + u.relax.Flags = Inst.getFlags(); auto &S = getParent()->MCOperandStorage; - if (Inst.getNumOperands() > OperandSize) { - OperandStart = S.size(); + if (Inst.getNumOperands() > u.relax.OperandSize) { + u.relax.OperandStart = S.size(); S.resize_for_overwrite(S.size() + Inst.getNumOperands()); } - OperandSize = Inst.getNumOperands(); - llvm::copy(Inst, S.begin() + OperandStart); + u.relax.OperandSize = Inst.getNumOperands(); + llvm::copy(Inst, S.begin() + u.relax.OperandStart); } - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Relaxable; + //== FT_Align functions + void makeAlign(Align Alignment, int64_t Fill, uint8_t FillLen, + unsigned MaxBytesToEmit) { + Kind = FT_Align; + u.align.EmitNops = false; + u.align.Alignment = Alignment; + u.align.Fill = Fill; + u.align.FillLen = FillLen; + u.align.MaxBytesToEmit = MaxBytesToEmit; } -}; - -class MCAlignFragment : public MCFragment { - /// Flag to indicate that (optimal) NOPs should be emitted instead - /// of using the provided value. The exact interpretation of this flag is - /// target dependent. - bool EmitNops : 1; - - /// The alignment to ensure, in bytes. - Align Alignment; - - /// The size of the integer (in bytes) of \p Value. - uint8_t FillLen; - - /// The maximum number of bytes to emit; if the alignment - /// cannot be satisfied in this width then this fragment is ignored. - unsigned MaxBytesToEmit; - - /// Value to use for filling padding bytes. - int64_t Fill; - - /// When emitting Nops some subtargets have specific nop encodings. - const MCSubtargetInfo *STI = nullptr; -public: - MCAlignFragment(Align Alignment, int64_t Fill, uint8_t FillLen, - unsigned MaxBytesToEmit) - : MCFragment(FT_Align, false), EmitNops(false), Alignment(Alignment), - FillLen(FillLen), MaxBytesToEmit(MaxBytesToEmit), Fill(Fill) {} - - Align getAlignment() const { return Alignment; } - int64_t getFill() const { return Fill; } - uint8_t getFillLen() const { return FillLen; } - unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; } - - bool hasEmitNops() const { return EmitNops; } - void setEmitNops(bool Value, const MCSubtargetInfo *STI) { - EmitNops = Value; - this->STI = STI; + Align getAlignment() const { + assert(Kind == FT_Align); + return u.align.Alignment; + } + int64_t getAlignFill() const { + assert(Kind == FT_Align); + return u.align.Fill; + } + uint8_t getAlignFillLen() const { + assert(Kind == FT_Align); + return u.align.FillLen; + } + unsigned getAlignMaxBytesToEmit() const { + assert(Kind == FT_Align); + return u.align.MaxBytesToEmit; + } + bool hasAlignEmitNops() const { + assert(Kind == FT_Align); + return u.align.EmitNops; } - const MCSubtargetInfo *getSubtargetInfo() const { return STI; } + //== FT_LEB functions + void makeLEB(bool IsSigned, const MCExpr *Value) { + assert(Kind == FT_Data); + Kind = MCFragment::FT_LEB; + u.leb.IsSigned = IsSigned; + u.leb.Value = Value; + } + const MCExpr &getLEBValue() const { + assert(Kind == FT_LEB); + return *u.leb.Value; + } + void setLEBValue(const MCExpr *Expr) { + assert(Kind == FT_LEB); + u.leb.Value = Expr; + } + bool isLEBSigned() const { + assert(Kind == FT_LEB); + return u.leb.IsSigned; + } - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Align; + //== FT_DwarfFrame functions + const MCExpr &getDwarfAddrDelta() const { + assert(Kind == FT_Dwarf || Kind == FT_DwarfFrame); + return *u.dwarf.AddrDelta; + } + void setDwarfAddrDelta(const MCExpr *E) { + assert(Kind == FT_Dwarf || Kind == FT_DwarfFrame); + u.dwarf.AddrDelta = E; + } + int64_t getDwarfLineDelta() const { + assert(Kind == FT_Dwarf); + return u.dwarf.LineDelta; } + void setDwarfLineDelta(int64_t LineDelta) { + assert(Kind == FT_Dwarf); + u.dwarf.LineDelta = LineDelta; + } +}; + +/// Interface implemented by fragments that contain encoded instructions and/or +/// data. +class MCEncodedFragment : public MCFragment { +protected: + MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions) + : MCFragment(FType, HasInstructions) {} }; class MCFillFragment : public MCFragment { @@ -600,67 +616,6 @@ class MCOrgFragment : public MCFragment { } }; -class MCLEBFragment final : public MCEncodedFragment { - /// True if this is a sleb128, false if uleb128. - bool IsSigned; - - /// The value this fragment should contain. - const MCExpr *Value; - -public: - MCLEBFragment(const MCExpr &Value, bool IsSigned) - : MCEncodedFragment(FT_LEB, false), IsSigned(IsSigned), Value(&Value) {} - - const MCExpr &getValue() const { return *Value; } - void setValue(const MCExpr *Expr) { Value = Expr; } - - bool isSigned() const { return IsSigned; } - - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_LEB; - } -}; - -class MCDwarfLineAddrFragment : public MCEncodedFragment { - /// The value of the difference between the two line numbers - /// between two .loc dwarf directives. - int64_t LineDelta; - - /// The expression for the difference of the two symbols that - /// make up the address delta between two .loc dwarf directives. - const MCExpr *AddrDelta; - -public: - MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta) - : MCEncodedFragment(FT_Dwarf, false), LineDelta(LineDelta), - AddrDelta(&AddrDelta) {} - - int64_t getLineDelta() const { return LineDelta; } - - const MCExpr &getAddrDelta() const { return *AddrDelta; } - - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_Dwarf; - } -}; - -class MCDwarfCallFrameFragment : public MCEncodedFragment { - /// The expression for the difference of the two symbols that - /// make up the address delta between two .cfi_* dwarf directives. - const MCExpr *AddrDelta; - -public: - MCDwarfCallFrameFragment(const MCExpr &AddrDelta) - : MCEncodedFragment(FT_DwarfFrame, false), AddrDelta(&AddrDelta) {} - - const MCExpr &getAddrDelta() const { return *AddrDelta; } - void setAddrDelta(const MCExpr *E) { AddrDelta = E; } - - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_DwarfFrame; - } -}; - /// Represents a symbol table index fragment. class MCSymbolIdFragment : public MCFragment { const MCSymbol *Sym; @@ -773,22 +728,6 @@ class MCBoundaryAlignFragment : public MCFragment { } }; -class MCPseudoProbeAddrFragment : public MCEncodedFragment { - /// The expression for the difference of the two symbols that - /// make up the address delta between two .pseudoprobe directives. - const MCExpr *AddrDelta; - -public: - MCPseudoProbeAddrFragment(const MCExpr *AddrDelta) - : MCEncodedFragment(FT_PseudoProbe, false), AddrDelta(AddrDelta) {} - - const MCExpr &getAddrDelta() const { return *AddrDelta; } - - static bool classof(const MCFragment *F) { - return F->getKind() == MCFragment::FT_PseudoProbe; - } -}; - inline MCSection::iterator &MCSection::iterator::operator++() { F = F->Next; return *this; diff --git a/llvm/include/llvm/MC/MCSectionCOFF.h b/llvm/include/llvm/MC/MCSectionCOFF.h index 4472a128caa6b..f979413a3791e 100644 --- a/llvm/include/llvm/MC/MCSectionCOFF.h +++ b/llvm/include/llvm/MC/MCSectionCOFF.h @@ -82,7 +82,6 @@ class MCSectionCOFF final : public MCSection { raw_ostream &OS, uint32_t Subsection) const override; bool useCodeAlign() const override; - StringRef getVirtualSectionKind() const override; unsigned getOrAssignWinCFISectionID(unsigned *NextID) const { if (WinCFISectionID == ~0U) diff --git a/llvm/include/llvm/MC/MCSectionELF.h b/llvm/include/llvm/MC/MCSectionELF.h index f09d30591a3cf..a01f95f44c954 100644 --- a/llvm/include/llvm/MC/MCSectionELF.h +++ b/llvm/include/llvm/MC/MCSectionELF.h @@ -88,7 +88,6 @@ class MCSectionELF final : public MCSection { raw_ostream &OS, uint32_t Subsection) const override; bool useCodeAlign() const override; - StringRef getVirtualSectionKind() const override; bool isUnique() const { return UniqueID != NonUniqueID; } unsigned getUniqueID() const { return UniqueID; } diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h index 9e3f95e82a14c..b166397b5d370 100644 --- a/llvm/include/llvm/MC/MCSectionGOFF.h +++ b/llvm/include/llvm/MC/MCSectionGOFF.h @@ -111,7 +111,7 @@ class LLVM_ABI MCSectionGOFF final : public MCSection { // Returns the text style for a section. Only defined for ED and PR sections. GOFF::ESDTextStyle getTextStyle() const { - assert((isED() || isPR() || isVirtualSection()) && "Expect ED or PR section"); + assert((isED() || isPR() || isBssSection()) && "Expect ED or PR section"); if (isED()) return EDAttributes.TextStyle; if (isPR()) diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index a6eab17b4cf0f..c57a646c89247 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -273,6 +273,8 @@ class LLVM_ABI MCStreamer { /// section changes. virtual void changeSection(MCSection *, uint32_t); + void addFragment(MCFragment *F); + virtual void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame); virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame); @@ -435,11 +437,14 @@ class LLVM_ABI MCStreamer { } MCFragment *getCurrentFragment() const { + // Ensure consistency with the section stack. assert(!getCurrentSection().first || CurFrag->getParent() == getCurrentSection().first); + // Ensure we eagerly allocate an empty fragment after adding fragment with a + // variable-size tail. + assert(!CurFrag || CurFrag->getKind() == MCFragment::FT_Data); return CurFrag; } - /// Save the current and previous section on the section stack. void pushSection() { SectionStack.push_back( @@ -467,6 +472,11 @@ class LLVM_ABI MCStreamer { MCSymbol *endSection(MCSection *Section); + /// Add a new fragment to the current section without a variable-size tail. + void newFragment(); + /// Add a fragment with a variable-size tail and start a new empty fragment. + void insert(MCFragment *F); + /// Returns the mnemonic for \p MI, if the streamer has access to a /// instruction printer and returns an empty string otherwise. virtual StringRef getMnemonic(const MCInst &MI) const { return ""; } @@ -1061,13 +1071,9 @@ class LLVM_ABI MCStreamer { virtual void emitSyntaxDirective(); - /// Record a relocation described by the .reloc directive. Return std::nullopt - /// if succeeded. Otherwise, return a pair (Name is invalid, error message). - virtual std::optional> - emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, - SMLoc Loc, const MCSubtargetInfo &STI) { - return std::nullopt; - } + /// Record a relocation described by the .reloc directive. + virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc = {}) {} virtual void emitAddrsig() {} virtual void emitAddrsigSym(const MCSymbol *Sym) {} @@ -1081,19 +1087,6 @@ class LLVM_ABI MCStreamer { const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym); - /// Set the bundle alignment mode from now on in the section. - /// The value 1 means turn the bundle alignment off. - virtual void emitBundleAlignMode(Align Alignment); - - /// The following instructions are a bundle-locked group. - /// - /// \param AlignToEnd - If true, the bundle-locked group will be aligned to - /// the end of a bundle. - virtual void emitBundleLock(bool AlignToEnd); - - /// Ends a bundle-locked group. - virtual void emitBundleUnlock(); - /// If this file is backed by a assembly streamer, this dumps the /// specified string in the output .s file. This capability is indicated by /// the hasRawTextSupport() predicate. By default this aborts. diff --git a/llvm/include/llvm/MC/MCWasmStreamer.h b/llvm/include/llvm/MC/MCWasmStreamer.h index 2598c261ea02a..e8a71975c5d62 100644 --- a/llvm/include/llvm/MC/MCWasmStreamer.h +++ b/llvm/include/llvm/MC/MCWasmStreamer.h @@ -42,7 +42,7 @@ class MCWasmStreamer : public MCObjectStreamer { void changeSection(MCSection *Section, uint32_t Subsection) override; void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; - void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, + void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment &F, uint64_t Offset) override; bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/llvm/include/llvm/MCCAS/MCCASObjectV1.def b/llvm/include/llvm/MCCAS/MCCASObjectV1.def index df630e851dd35..aab14eda7012f 100644 --- a/llvm/include/llvm/MCCAS/MCCASObjectV1.def +++ b/llvm/include/llvm/MCCAS/MCCASObjectV1.def @@ -88,7 +88,6 @@ MCFRAGMENT_NODE_REF(MCRelaxableFragment, FT_Relaxable, mc:relaxable) MCFRAGMENT_NODE_REF(MCDwarfLineAddrFragment, FT_Dwarf, mc:dwarf) MCFRAGMENT_NODE_REF(MCDwarfCallFrameFragment, FT_DwarfFrame, mc:dwarf_frame) MCFRAGMENT_NODE_REF(MCCVDefRangeFragment, FT_CVDefRange, mc:cv_def_range) -MCFRAGMENT_NODE_REF(MCPseudoProbeAddrFragment, FT_PseudoProbe, mc:presudo_pro) #undef MCFRAGMENT_NODE_REF #endif /* MCFRAGMENT_NODE_REF */ diff --git a/llvm/include/llvm/MCCAS/MCCASObjectV1.h b/llvm/include/llvm/MCCAS/MCCASObjectV1.h index 6cce778a8e803..2aaf858ebd247 100644 --- a/llvm/include/llvm/MCCAS/MCCASObjectV1.h +++ b/llvm/include/llvm/MCCAS/MCCASObjectV1.h @@ -392,7 +392,7 @@ class SpecificRef : public MCObjectProxy { public: \ static constexpr StringLiteral KindString = #MCEnumIdentifier; \ static Expected \ - create(MCCASBuilder &MB, const MCFragmentName &Fragment, \ + create(MCCASBuilder &MB, const MCFragment &Fragment, \ unsigned FragmentSize, ArrayRef FragmentContents); \ static Expected get(Expected Ref) { \ auto Specific = SpecificRefT::getSpecific(std::move(Ref)); \ @@ -404,7 +404,7 @@ class SpecificRef : public MCObjectProxy { cas::ObjectRef ID) { \ return get(Schema.get(ID)); \ } \ - static std::optional Cast(MCObjectProxy Ref) { \ + static std::optional Cast(MCObjectProxy Ref) { \ auto Specific = SpecificRefT::Cast(Ref); \ if (!Specific) \ return std::nullopt; \ diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index be0a1c3b0a0c2..4f00c8e7b4127 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -810,7 +810,7 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { // If we have a bss global going to a section that supports the // zerofill directive, do so here. - if (GVKind.isBSS() && MAI->isMachO() && TheSection->isVirtualSection()) { + if (GVKind.isBSS() && MAI->isMachO() && TheSection->isBssSection()) { if (Size == 0) Size = 1; // zerofill of 0 bytes is undefined. emitLinkage(GV, GVSym); diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp index b55907254fb2d..6579a59b3af0c 100644 --- a/llvm/lib/MC/MCAsmBackend.cpp +++ b/llvm/lib/MC/MCAsmBackend.cpp @@ -132,7 +132,8 @@ MCFixupKindInfo MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { return Builtins[Kind - FK_NONE]; } -bool MCAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, +bool MCAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &, + const MCFixup &Fixup, const MCValue &, uint64_t Value, bool Resolved) const { if (!Resolved) @@ -165,9 +166,7 @@ bool MCAsmBackend::isDarwinCanonicalPersonality(const MCSymbol *Sym) const { const MCSubtargetInfo *MCAsmBackend::getSubtargetInfo(const MCFragment &F) { const MCSubtargetInfo *STI = nullptr; - if (auto *DF = dyn_cast(&F)) { - STI = DF->getSubtargetInfo(); - assert(!DF->hasInstructions() || STI != nullptr); - } + STI = F.getSubtargetInfo(); + assert(!F.hasInstructions() || STI != nullptr); return STI; } diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 53ea5cf0bf657..3ec236df312ea 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -409,13 +409,8 @@ class MCAsmStreamer final : public MCStreamer { const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym) override; - void emitBundleAlignMode(Align Alignment) override; - void emitBundleLock(bool AlignToEnd) override; - void emitBundleUnlock() override; - - std::optional> - emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, - SMLoc Loc, const MCSubtargetInfo &STI) override; + void emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc) override; void emitAddrsig() override; void emitAddrsigSym(const MCSymbol *Sym) override; @@ -2484,27 +2479,8 @@ void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, EmitEOL(); } -void MCAsmStreamer::emitBundleAlignMode(Align Alignment) { - OS << "\t.bundle_align_mode " << Log2(Alignment); - EmitEOL(); -} - -void MCAsmStreamer::emitBundleLock(bool AlignToEnd) { - OS << "\t.bundle_lock"; - if (AlignToEnd) - OS << " align_to_end"; - EmitEOL(); -} - -void MCAsmStreamer::emitBundleUnlock() { - OS << "\t.bundle_unlock"; - EmitEOL(); -} - -std::optional> -MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, - const MCExpr *Expr, SMLoc, - const MCSubtargetInfo &STI) { +void MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc) { OS << "\t.reloc "; MAI->printExpr(OS, Offset); OS << ", " << Name; @@ -2513,7 +2489,6 @@ MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, MAI->printExpr(OS, *Expr); } EmitEOL(); - return std::nullopt; } void MCAsmStreamer::emitAddrsig() { diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index fd8a8c3a79c9f..26726c0902f5a 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -94,7 +94,6 @@ void MCAssembler::reset() { Sections.clear(); Symbols.clear(); ThumbFuncs.clear(); - BundleAlignSize = 0; // reset objects owned by us if (getBackendPtr()) @@ -197,13 +196,13 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const { switch (F.getKind()) { case MCFragment::FT_Data: case MCFragment::FT_Relaxable: + case MCFragment::FT_Align: case MCFragment::FT_LEB: case MCFragment::FT_Dwarf: case MCFragment::FT_DwarfFrame: case MCFragment::FT_CVInlineLines: case MCFragment::FT_CVDefRange: - case MCFragment::FT_PseudoProbe: - return cast(F).getContents().size(); + return F.getSize(); case MCFragment::FT_Fill: { auto &FF = cast(F); int64_t NumValues = 0; @@ -228,28 +227,6 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const { case MCFragment::FT_SymbolId: return 4; - case MCFragment::FT_Align: { - const MCAlignFragment &AF = cast(F); - unsigned Offset = getFragmentOffset(AF); - unsigned Size = offsetToAlignment(Offset, AF.getAlignment()); - - // Insert extra Nops for code alignment if the target define - // shouldInsertExtraNopBytesForCodeAlign target hook. - if (AF.getParent()->useCodeAlign() && AF.hasEmitNops() && - getBackend().shouldInsertExtraNopBytesForCodeAlign(AF, Size)) - return Size; - - // If we are padding with nops, force the padding to be larger than the - // minimum nop size. - if (Size > 0 && AF.hasEmitNops()) { - while (Size % getBackend().getMinimumNopSize()) - Size += AF.getAlignment().value(); - } - if (Size > AF.getMaxBytesToEmit()) - return 0; - return Size; - } - case MCFragment::FT_Org: { const MCOrgFragment &OF = cast(F); MCValue Value; @@ -282,87 +259,6 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const { llvm_unreachable("invalid fragment kind"); } -// 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. -static uint64_t computeBundlePadding(unsigned BundleSize, - const MCEncodedFragment *F, - uint64_t FOffset, uint64_t FSize) { - uint64_t OffsetInBundle = FOffset & (BundleSize - 1); - 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 - // would, add padding until the end of the bundle so that the fragment - // will start in a new one. - if (F->alignToBundleEnd()) { - // Three possibilities here: - // - // A) The fragment just happens to end at a bundle boundary, so we're good. - // B) The fragment ends before the current bundle boundary: pad it just - // enough to reach the boundary. - // C) The fragment ends after the current bundle boundary: pad it until it - // reaches the end of the next bundle boundary. - // - // Note: this code could be made shorter with some modulo trickery, but it's - // intentionally kept in its more explicit form for simplicity. - if (EndOfFragment == BundleSize) - return 0; - else if (EndOfFragment < BundleSize) - return BundleSize - EndOfFragment; - else { // EndOfFragment > BundleSize - return 2 * BundleSize - EndOfFragment; - } - } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize) - return BundleSize - OffsetInBundle; - else - return 0; -} - -void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const { - // If bundling is enabled and this fragment has instructions in it, it has to - // obey the bundling restrictions. With padding, we'll have: - // - // - // BundlePadding - // ||| - // ------------------------------------- - // Prev |##########| F | - // ------------------------------------- - // ^ - // | - // F->Offset - // - // The fragment's offset will point to after the padding, and its computed - // size won't include the padding. - // - // ".align N" is an example of a directive that introduces multiple - // fragments. We could add a special case to handle ".align N" by emitting - // within-fragment padding (which would produce less padding when N is less - // than the bundle size), but for now we don't. - // - assert(isa(F) && - "Only MCEncodedFragment implementations have instructions"); - MCEncodedFragment *EF = cast(F); - uint64_t FSize = computeFragmentSize(*EF); - - if (FSize > getBundleAlignSize()) - report_fatal_error("Fragment can't be larger than a bundle size"); - - uint64_t RequiredBundlePadding = - computeBundlePadding(getBundleAlignSize(), EF, EF->Offset, FSize); - if (RequiredBundlePadding > UINT8_MAX) - report_fatal_error("Padding cannot exceed 255 bytes"); - EF->setBundlePadding(static_cast(RequiredBundlePadding)); - EF->Offset += RequiredBundlePadding; - if (auto *DF = dyn_cast_or_null(Prev)) - if (DF->getContents().empty()) - DF->Offset = EF->Offset; -} - // Simple getSymbolOffset helper for the non-variable case. static bool getLabelOffset(const MCAssembler &Asm, const MCSymbol &S, bool ReportError, uint64_t &Val) { @@ -466,7 +362,7 @@ uint64_t MCAssembler::getSectionAddressSize(const MCSection &Sec) const { uint64_t MCAssembler::getSectionFileSize(const MCSection &Sec) const { // Virtual sections have no file size. - if (Sec.isVirtualSection()) + if (Sec.isBssSection()) return 0; return getSectionAddressSize(Sec); } @@ -480,39 +376,8 @@ bool MCAssembler::registerSymbol(const MCSymbol &Symbol) { return Changed; } -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 = EF.getBundlePadding(); - if (BundlePadding > 0) { - assert(isBundlingEnabled() && - "Writing bundle padding with disabled bundling"); - assert(EF.hasInstructions() && - "Writing bundle padding for a fragment without instructions"); - - unsigned TotalLength = BundlePadding + static_cast(FSize); - const MCSubtargetInfo *STI = EF.getSubtargetInfo(); - 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 - // v---------v <- BundlePadding - // ---------------------------- - // | Prev |####|####| F | - // ---------------------------- - // ^-------------------^ <- TotalLength - unsigned DistanceToBoundary = TotalLength - getBundleAlignSize(); - if (!getBackend().writeNopData(OS, DistanceToBoundary, STI)) - report_fatal_error("unable to write NOP sequence of " + - Twine(DistanceToBoundary) + " bytes"); - BundlePadding -= DistanceToBoundary; - } - if (!getBackend().writeNopData(OS, BundlePadding, STI)) - report_fatal_error("unable to write NOP sequence of " + - Twine(BundlePadding) + " bytes"); - } +void MCAssembler::addRelocDirective(RelocDirective RD) { + relocDirectives.push_back(RD); } /// Write the fragment \p F to the output file. @@ -523,9 +388,6 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm, llvm::endianness Endian = Asm.getBackend().Endian; - if (const MCEncodedFragment *EF = dyn_cast(&F)) - Asm.writeFragmentPadding(OS, *EF, FragmentSize); - // This variable (and its dummy usage) is to participate in the assert at // the end of the function. uint64_t Start = OS.tell(); @@ -540,56 +402,53 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm, case MCFragment::FT_Dwarf: case MCFragment::FT_DwarfFrame: case MCFragment::FT_CVInlineLines: - case MCFragment::FT_CVDefRange: - case MCFragment::FT_PseudoProbe: { + case MCFragment::FT_CVDefRange: { if (F.getKind() == MCFragment::FT_Data) ++stats::EmittedDataFragments; else if (F.getKind() == MCFragment::FT_Relaxable) ++stats::EmittedRelaxableFragments; - const auto &EF = cast(F); + const auto &EF = cast(F); OS << StringRef(EF.getContents().data(), EF.getContents().size()); - break; - } + OS << StringRef(EF.getVarContents().data(), EF.getVarContents().size()); + } break; + case MCFragment::FT_Align: { ++stats::EmittedAlignFragments; - const MCAlignFragment &AF = cast(F); - assert(AF.getFillLen() && "Invalid virtual align in concrete fragment!"); + OS << StringRef(F.getContents().data(), F.getContents().size()); + assert(F.getAlignFillLen() && + "Invalid virtual align in concrete fragment!"); - uint64_t Count = FragmentSize / AF.getFillLen(); - assert(FragmentSize % AF.getFillLen() == 0 && + uint64_t Count = (FragmentSize - F.getFixedSize()) / F.getAlignFillLen(); + assert((FragmentSize - F.getFixedSize()) % F.getAlignFillLen() == 0 && "computeFragmentSize computed size is incorrect"); - // See if we are aligning with nops, and if so do that first to try to fill - // the Count bytes. Then if that did not fill any bytes or there are any - // bytes left to fill use the Value and ValueSize to fill the rest. - // If we are aligning with nops, ask that target to emit the right data. - if (AF.hasEmitNops()) { - if (!Asm.getBackend().writeNopData(OS, Count, AF.getSubtargetInfo())) - report_fatal_error("unable to write nop sequence of " + - Twine(Count) + " bytes"); - break; - } - - // Otherwise, write out in multiples of the value size. - for (uint64_t i = 0; i != Count; ++i) { - switch (AF.getFillLen()) { - default: llvm_unreachable("Invalid size!"); - case 1: - OS << char(AF.getFill()); - break; - case 2: - support::endian::write(OS, AF.getFill(), Endian); - break; - case 4: - support::endian::write(OS, AF.getFill(), Endian); - break; - case 8: - support::endian::write(OS, AF.getFill(), Endian); - break; + // In the nops mode, call the backend hook to write `Count` nops. + if (F.hasAlignEmitNops()) { + if (!Asm.getBackend().writeNopData(OS, Count, F.getSubtargetInfo())) + reportFatalInternalError("unable to write nop sequence of " + + Twine(Count) + " bytes"); + } else { + // Otherwise, write out in multiples of the value size. + for (uint64_t i = 0; i != Count; ++i) { + switch (F.getAlignFillLen()) { + default: + llvm_unreachable("Invalid size!"); + case 1: + OS << char(F.getAlignFill()); + break; + case 2: + support::endian::write(OS, F.getAlignFill(), Endian); + break; + case 4: + support::endian::write(OS, F.getAlignFill(), Endian); + break; + case 8: + support::endian::write(OS, F.getAlignFill(), Endian); + break; + } } } - break; - } + } break; case MCFragment::FT_Fill: { ++stats::EmittedFillFragments; @@ -700,43 +559,45 @@ void MCAssembler::writeSectionData(raw_ostream &OS, const MCSection *Sec) const { assert(getBackendPtr() && "Expected assembler backend"); - // Ignore virtual sections. - if (Sec->isVirtualSection()) { + if (Sec->isBssSection()) { assert(getSectionFileSize(*Sec) == 0 && "Invalid size for section!"); - // Check that contents are only things legal inside a virtual section. + // Ensure no fixups or non-zero bytes are written to BSS sections, catching + // errors in both input assembly code and MCStreamer API usage. Location is + // not tracked for efficiency. + auto Fn = [](char c) { return c != 0; }; for (const MCFragment &F : *Sec) { + bool HasNonZero = false; switch (F.getKind()) { - default: llvm_unreachable("Invalid fragment in virtual section!"); - case MCFragment::FT_Data: { - // Check that we aren't trying to write a non-zero contents (or fixups) - // into a virtual section. This is to support clients which use standard - // directives to fill the contents of virtual sections. - const MCDataFragment &DF = cast(F); - if (DF.getFixups().size()) - reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" + - Sec->getName() + "' cannot have fixups"); - for (char C : DF.getContents()) - if (C) { - reportError(SMLoc(), Sec->getVirtualSectionKind() + " section '" + - Sec->getName() + - "' cannot have non-zero initializers"); - break; - } + default: + reportFatalInternalError("BSS section '" + Sec->getName() + + "' contains invalid fragment"); + break; + case MCFragment::FT_Data: + case MCFragment::FT_Relaxable: + HasNonZero = + any_of(F.getContents(), Fn) || any_of(F.getVarContents(), Fn); break; - } case MCFragment::FT_Align: - // Check that we aren't trying to write a non-zero value into a virtual - // section. - assert((cast(F).getFillLen() == 0 || - cast(F).getFill() == 0) && - "Invalid align in virtual section!"); + // Disallowed for API usage. AsmParser changes non-zero fill values to + // 0. + assert(F.getAlignFill() == 0 && "Invalid align in virtual section!"); break; case MCFragment::FT_Fill: - assert((cast(F).getValue() == 0) && - "Invalid fill in virtual section!"); + HasNonZero = cast(F).getValue() != 0; break; case MCFragment::FT_Org: + HasNonZero = cast(F).getValue() != 0; + break; + } + if (HasNonZero) { + reportError(SMLoc(), "BSS section '" + Sec->getName() + + "' cannot have non-zero bytes"); + break; + } + if (F.getFixups().size() || F.getVarFixups().size()) { + reportError(SMLoc(), + "BSS section '" + Sec->getName() + "' cannot have fixups"); break; } } @@ -769,7 +630,7 @@ void MCAssembler::layout() { // Chain together fragments from all subsections. if (Sec.Subsections.size() > 1) { - MCDataFragment Dummy; + MCFragment Dummy; MCFragment *Tail = &Dummy; for (auto &[_, List] : Sec.Subsections) { assert(List.Head); @@ -815,23 +676,50 @@ void MCAssembler::layout() { // helps check whether a PC-relative fixup is fully resolved. this->HasFinalLayout = true; + // Resolve .reloc offsets and add fixups. + for (auto &PF : relocDirectives) { + MCValue Res; + auto &O = PF.Offset; + if (!O.evaluateAsValue(Res, *this)) { + getContext().reportError(O.getLoc(), ".reloc offset is not relocatable"); + continue; + } + auto *Sym = Res.getAddSym(); + auto *F = Sym ? Sym->getFragment() : nullptr; + auto *Sec = F ? F->getParent() : nullptr; + if (Res.getSubSym() || !Sec) { + getContext().reportError(O.getLoc(), + ".reloc offset is not relative to a section"); + continue; + } + + uint64_t Offset = Sym ? Sym->getOffset() + Res.getConstant() : 0; + F->addFixup(MCFixup::create(Offset, PF.Expr, PF.Kind)); + } + // Evaluate and apply the fixups, generating relocation entries as necessary. for (MCSection &Sec : *this) { - for (MCFragment &Frag : Sec) { + for (MCFragment &F : Sec) { // Process fragments with fixups here. - if (auto *F = dyn_cast(&Frag)) { - auto Contents = F->getContents(); - for (MCFixup &Fixup : F->getFixups()) { + auto Contents = F.getContents(); + for (MCFixup &Fixup : F.getFixups()) { + uint64_t FixedValue; + MCValue Target; + evaluateFixup(F, Fixup, Target, FixedValue, + /*RecordReloc=*/true, Contents); + } + if (F.getVarFixups().size()) { + // In the variable part, fixup offsets are relative to the fixed part's + // start. Extend the variable contents to the left to account for the + // fixed part size. + Contents = MutableArrayRef(F.getParent()->ContentStorage) + .slice(F.VarContentStart - Contents.size(), F.getSize()); + for (MCFixup &Fixup : F.getVarFixups()) { uint64_t FixedValue; MCValue Target; - evaluateFixup(Frag, Fixup, Target, FixedValue, + evaluateFixup(F, Fixup, Target, FixedValue, /*RecordReloc=*/true, Contents); } - } else if (auto *AF = dyn_cast(&Frag)) { - // For RISC-V linker relaxation, an alignment relocation might be - // needed. - if (AF->hasEmitNops()) - getBackend().shouldInsertFixupForCodeAlign(*this, *AF); } } } @@ -847,18 +735,18 @@ void MCAssembler::Finish() { assert(PendingErrors.empty()); } -bool MCAssembler::fixupNeedsRelaxation(const MCRelaxableFragment &F, +bool MCAssembler::fixupNeedsRelaxation(const MCFragment &F, const MCFixup &Fixup) const { assert(getBackendPtr() && "Expected assembler backend"); MCValue Target; uint64_t Value; bool Resolved = evaluateFixup(F, const_cast(Fixup), Target, Value, /*RecordReloc=*/false, {}); - return getBackend().fixupNeedsRelaxationAdvanced(Fixup, Target, Value, + return getBackend().fixupNeedsRelaxationAdvanced(F, Fixup, Target, Value, Resolved); } -bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) { +bool MCAssembler::relaxInstruction(MCFragment &F) { assert(getEmitterPtr() && "Expected CodeEmitter defined for relaxInstruction"); // If this inst doesn't ever need relaxation, ignore it. This occurs when we @@ -869,7 +757,7 @@ bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) { return false; bool DoRelax = false; - for (const MCFixup &Fixup : F.getFixups()) + for (const MCFixup &Fixup : F.getVarFixups()) if ((DoRelax = fixupNeedsRelaxation(F, Fixup))) break; if (!DoRelax) @@ -877,7 +765,7 @@ bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) { ++stats::RelaxedInstructions; - // TODO Refactor relaxInstruction to accept MCRelaxableFragment and remove + // TODO Refactor relaxInstruction to accept MCFragment and remove // `setInst`. MCInst Relaxed = F.getInst(); getBackend().relaxInstruction(Relaxed, *F.getSubtargetInfo()); @@ -887,30 +775,30 @@ bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) { SmallVector Data; SmallVector Fixups; getEmitter().encodeInstruction(Relaxed, Data, Fixups, *F.getSubtargetInfo()); - F.setContents(Data); - F.setFixups(Fixups); + F.setVarContents(Data); + F.setVarFixups(Fixups); return true; } -bool MCAssembler::relaxLEB(MCLEBFragment &LF) { - const unsigned OldSize = static_cast(LF.getContents().size()); +bool MCAssembler::relaxLEB(MCFragment &F) { + const unsigned OldSize = F.getVarSize(); unsigned PadTo = OldSize; int64_t Value; - LF.clearFixups(); + F.clearVarFixups(); // Use evaluateKnownAbsolute for Mach-O as a hack: .subsections_via_symbols // requires that .uleb128 A-B is foldable where A and B reside in different // fragments. This is used by __gcc_except_table. bool Abs = getWriter().getSubsectionsViaSymbols() - ? LF.getValue().evaluateKnownAbsolute(Value, *this) - : LF.getValue().evaluateAsAbsolute(Value, *this); + ? F.getLEBValue().evaluateKnownAbsolute(Value, *this) + : F.getLEBValue().evaluateAsAbsolute(Value, *this); if (!Abs) { bool Relaxed, UseZeroPad; - std::tie(Relaxed, UseZeroPad) = getBackend().relaxLEB128(LF, Value); + std::tie(Relaxed, UseZeroPad) = getBackend().relaxLEB128(F, Value); if (!Relaxed) { - reportError(LF.getValue().getLoc(), - Twine(LF.isSigned() ? ".s" : ".u") + + reportError(F.getLEBValue().getLoc(), + Twine(F.isLEBSigned() ? ".s" : ".u") + "leb128 expression is not absolute"); - LF.setValue(MCConstantExpr::create(0, Context)); + F.setLEBValue(MCConstantExpr::create(0, Context)); } uint8_t Tmp[10]; // maximum size: ceil(64/7) PadTo = std::max(PadTo, encodeULEB128(uint64_t(Value), Tmp)); @@ -923,11 +811,11 @@ bool MCAssembler::relaxLEB(MCLEBFragment &LF) { // without either adding padding to an LEB fragment or adding extra padding // to a later alignment fragment. To accommodate such tables, relaxation can // only increase an LEB fragment size here, not decrease it. See PR35809. - if (LF.isSigned()) + if (F.isLEBSigned()) Size = encodeSLEB128(Value, Data, PadTo); else Size = encodeULEB128(Value, Data, PadTo); - LF.setContents({reinterpret_cast(Data), Size}); + F.setVarContents({reinterpret_cast(Data), Size}); return OldSize != Size; } @@ -992,48 +880,45 @@ bool MCAssembler::relaxBoundaryAlign(MCBoundaryAlignFragment &BF) { return true; } -bool MCAssembler::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF) { +bool MCAssembler::relaxDwarfLineAddr(MCFragment &F) { bool WasRelaxed; - if (getBackend().relaxDwarfLineAddr(DF, WasRelaxed)) + if (getBackend().relaxDwarfLineAddr(F, WasRelaxed)) return WasRelaxed; MCContext &Context = getContext(); - auto OldSize = DF.getContents().size(); + auto OldSize = F.getVarSize(); int64_t AddrDelta; - bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this); + bool Abs = F.getDwarfAddrDelta().evaluateKnownAbsolute(AddrDelta, *this); assert(Abs && "We created a line delta with an invalid expression"); (void)Abs; - int64_t LineDelta; - LineDelta = DF.getLineDelta(); SmallVector Data; - - MCDwarfLineAddr::encode(Context, getDWARFLinetableParams(), LineDelta, - AddrDelta, Data); - DF.setContents(Data); - DF.clearFixups(); + MCDwarfLineAddr::encode(Context, getDWARFLinetableParams(), + F.getDwarfLineDelta(), AddrDelta, Data); + F.setVarContents(Data); + F.clearVarFixups(); return OldSize != Data.size(); } -bool MCAssembler::relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF) { +bool MCAssembler::relaxDwarfCallFrameFragment(MCFragment &F) { bool WasRelaxed; - if (getBackend().relaxDwarfCFA(DF, WasRelaxed)) + if (getBackend().relaxDwarfCFA(F, WasRelaxed)) return WasRelaxed; MCContext &Context = getContext(); int64_t Value; - bool Abs = DF.getAddrDelta().evaluateAsAbsolute(Value, *this); + bool Abs = F.getDwarfAddrDelta().evaluateAsAbsolute(Value, *this); if (!Abs) { - reportError(DF.getAddrDelta().getLoc(), + reportError(F.getDwarfAddrDelta().getLoc(), "invalid CFI advance_loc expression"); - DF.setAddrDelta(MCConstantExpr::create(0, Context)); + F.setDwarfAddrDelta(MCConstantExpr::create(0, Context)); return false; } - auto OldSize = DF.getContents().size(); + auto OldSize = F.getVarContents().size(); SmallVector Data; MCDwarfFrameEmitter::encodeAdvanceLoc(Context, Value, Data); - DF.setContents(Data); - DF.clearFixups(); + F.setVarContents(Data); + F.clearVarFixups(); return OldSize != Data.size(); } @@ -1057,36 +942,19 @@ bool MCAssembler::relaxFill(MCFillFragment &F) { return true; } -bool MCAssembler::relaxPseudoProbeAddr(MCPseudoProbeAddrFragment &PF) { - uint64_t OldSize = PF.getContents().size(); - int64_t AddrDelta; - bool Abs = PF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this); - assert(Abs && "We created a pseudo probe with an invalid expression"); - (void)Abs; - SmallVector Data; - raw_svector_ostream OSE(Data); - - // AddrDelta is a signed integer - encodeSLEB128(AddrDelta, OSE, OldSize); - PF.setContents(Data); - PF.clearFixups(); - return OldSize != Data.size(); -} - bool MCAssembler::relaxFragment(MCFragment &F) { switch(F.getKind()) { default: return false; case MCFragment::FT_Relaxable: - assert(!getRelaxAll() && - "Did not expect a MCRelaxableFragment in RelaxAll mode"); - return relaxInstruction(cast(F)); + assert(!getRelaxAll() && "Did not expect a FT_Relaxable in RelaxAll mode"); + return relaxInstruction(F); + case MCFragment::FT_LEB: + return relaxLEB(F); case MCFragment::FT_Dwarf: - return relaxDwarfLineAddr(cast(F)); + return relaxDwarfLineAddr(F); case MCFragment::FT_DwarfFrame: - return relaxDwarfCallFrameFragment(cast(F)); - case MCFragment::FT_LEB: - return relaxLEB(cast(F)); + return relaxDwarfCallFrameFragment(F); case MCFragment::FT_BoundaryAlign: return relaxBoundaryAlign(cast(F)); case MCFragment::FT_CVInlineLines: @@ -1095,24 +963,39 @@ bool MCAssembler::relaxFragment(MCFragment &F) { return relaxCVDefRange(cast(F)); case MCFragment::FT_Fill: return relaxFill(cast(F)); - case MCFragment::FT_PseudoProbe: - return relaxPseudoProbeAddr(cast(F)); } } void MCAssembler::layoutSection(MCSection &Sec) { - MCFragment *Prev = nullptr; uint64_t Offset = 0; for (MCFragment &F : Sec) { F.Offset = Offset; - if (LLVM_UNLIKELY(isBundlingEnabled())) { - if (F.hasInstructions()) { - layoutBundle(Prev, &F); - Offset = F.Offset; + if (F.getKind() == MCFragment::FT_Align) { + Offset += F.getFixedSize(); + unsigned Size = offsetToAlignment(Offset, F.getAlignment()); + // In the nops mode, RISC-V style linker relaxation might adjust the size + // and add a fixup, even if `Size` is originally 0. + bool AlignFixup = false; + if (F.hasAlignEmitNops()) { + AlignFixup = getBackend().relaxAlign(F, Size); + // If the backend does not handle the fragment specially, pad with nops, + // but ensure that the padding is larger than the minimum nop size. + if (!AlignFixup) + while (Size % getBackend().getMinimumNopSize()) + Size += F.getAlignment().value(); } - Prev = &F; + if (!AlignFixup && Size > F.getAlignMaxBytesToEmit()) + Size = 0; + // Update the variable tail size. The content is ignored. + assert(F.VarContentStart == 0 && + "VarContentStart should not be modified"); + F.VarContentEnd = Size; + if (F.VarContentEnd > F.getParent()->ContentStorage.size()) + F.getParent()->ContentStorage.resize(F.VarContentEnd); + Offset += Size; + } else { + Offset += computeFragmentSize(F); } - Offset += computeFragmentSize(F); } } diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp index 5d7914396e09f..b151a2545ddb2 100644 --- a/llvm/lib/MC/MCCodeView.cpp +++ b/llvm/lib/MC/MCCodeView.cpp @@ -166,8 +166,8 @@ void CodeViewContext::emitStringTable(MCObjectStreamer &OS) { // somewhere else. If somebody wants two string tables in their .s file, one // will just be empty. if (!StrTabFragment) { - StrTabFragment = Ctx.allocFragment(); - OS.insert(StrTabFragment); + OS.newFragment(); + StrTabFragment = OS.getCurrentFragment(); } OS.emitValueToAlignment(Align(4), 0); diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 3e63038dc90ae..12b3fbab8fb8f 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -200,10 +200,10 @@ MCInst *MCContext::createMCInst() { return new (MCInstAllocator.Allocate()) MCInst; } -// Allocate the initial MCDataFragment for the begin symbol. -MCDataFragment *MCContext::allocInitialFragment(MCSection &Sec) { +// Allocate the initial MCFragment for the begin symbol. +MCFragment *MCContext::allocInitialFragment(MCSection &Sec) { assert(!Sec.curFragList()->Head); - auto *F = allocFragment(); + auto *F = allocFragment(); F->setParent(&Sec); Sec.curFragList()->Head = F; Sec.curFragList()->Tail = F; diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 4bc3f4642ea02..49071bdec3dbd 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -48,10 +48,6 @@ ELFObjectWriter &MCELFStreamer::getWriter() { return static_cast(getAssembler().getWriter()); } -bool MCELFStreamer::isBundleLocked() const { - return getCurrentSectionOnly()->isBundleLocked(); -} - void MCELFStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) { MCContext &Ctx = getContext(); switchSection(Ctx.getObjectFileInfo()->getTextSection()); @@ -72,7 +68,7 @@ void MCELFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) { Symbol->setType(ELF::STT_TLS); } -void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F, +void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCFragment &F, uint64_t Offset) { auto *Symbol = cast(S); MCObjectStreamer::emitLabelAtPos(Symbol, Loc, F, Offset); @@ -83,23 +79,8 @@ void MCELFStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F, Symbol->setType(ELF::STT_TLS); } -// If bundle alignment is used and there are any instructions in the section, it -// needs to be aligned to at least the bundle size. -static void setSectionAlignmentForBundling(const MCAssembler &Assembler, - MCSection *Section) { - if (Assembler.isBundlingEnabled() && Section->hasInstructions()) - Section->ensureMinAlignment(Align(Assembler.getBundleAlignSize())); -} - void MCELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) { MCAssembler &Asm = getAssembler(); - if (auto *F = getCurrentFragment()) { - if (isBundleLocked()) - report_fatal_error("Unterminated .bundle_lock when changing a section"); - - // Ensure the previous section gets aligned if necessary. - setSectionAlignmentForBundling(Asm, F->getParent()); - } auto *SectionELF = static_cast(Section); const MCSymbol *Grp = SectionELF->getGroup(); if (Grp) @@ -313,22 +294,6 @@ void MCELFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size, emitCommonSymbol(Symbol, Size, ByteAlignment); } -void MCELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc) { - if (isBundleLocked()) - report_fatal_error("Emitting values inside a locked bundle is forbidden"); - MCObjectStreamer::emitValueImpl(Value, Size, Loc); -} - -void MCELFStreamer::emitValueToAlignment(Align Alignment, int64_t Value, - uint8_t ValueSize, - unsigned MaxBytesToEmit) { - if (isBundleLocked()) - report_fatal_error("Emitting values inside a locked bundle is forbidden"); - MCObjectStreamer::emitValueToAlignment(Alignment, Value, ValueSize, - MaxBytesToEmit); -} - void MCELFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count) { @@ -349,8 +314,9 @@ void MCELFStreamer::emitIdent(StringRef IdentString) { popSection(); } -void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE, - uint64_t Offset) { +void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *Sym, + uint64_t Offset, + const MCSymbolRefExpr *&SRE) { const MCSymbol *S = &SRE->getSymbol(); if (S->isTemporary()) { if (!S->isInSection()) { @@ -363,13 +329,9 @@ void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE, S->setUsedInReloc(); SRE = MCSymbolRefExpr::create(S, getContext(), SRE->getLoc()); } - const MCConstantExpr *MCOffset = MCConstantExpr::create(Offset, getContext()); - if (std::optional> Err = - MCObjectStreamer::emitRelocDirective( - *MCOffset, "BFD_RELOC_NONE", SRE, SRE->getLoc(), - *getContext().getSubtargetInfo())) - report_fatal_error("Relocation for CG Profile could not be created: " + - Twine(Err->second)); + auto *O = MCBinaryExpr::createAdd( + Sym, MCConstantExpr::create(Offset, getContext()), getContext()); + MCObjectStreamer::emitRelocDirective(*O, "BFD_RELOC_NONE", SRE); } void MCELFStreamer::finalizeCGProfile() { @@ -382,126 +344,17 @@ void MCELFStreamer::finalizeCGProfile() { pushSection(); switchSection(CGProfile); uint64_t Offset = 0; + auto *Sym = + MCSymbolRefExpr::create(CGProfile->getBeginSymbol(), getContext()); for (auto &E : W.getCGProfile()) { - finalizeCGProfileEntry(E.From, Offset); - finalizeCGProfileEntry(E.To, Offset); + finalizeCGProfileEntry(Sym, Offset, E.From); + finalizeCGProfileEntry(Sym, Offset, E.To); emitIntValue(E.Count, sizeof(uint64_t)); Offset += sizeof(uint64_t); } popSection(); } -// A fragment can only have one Subtarget, and when bundling is enabled we -// sometimes need to use the same fragment. We give an error if there -// are conflicting Subtargets. -static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI, - const MCSubtargetInfo *NewSTI) { - if (OldSTI && NewSTI && OldSTI != NewSTI) - report_fatal_error("A Bundle can only have one Subtarget."); -} - -void MCELFStreamer::emitInstToData(const MCInst &Inst, - const MCSubtargetInfo &STI) { - MCAssembler &Assembler = getAssembler(); - - // There are several possibilities here: - // - // If bundling is disabled, append the encoded instruction to the current data - // fragment (or create a new such fragment if the current fragment is not a - // data fragment, or the Subtarget has changed). - // - // If bundling is enabled: - // - If we're not in a bundle-locked group, emit the instruction into a - // fragment of its own. - // - If we're in a bundle-locked group, append the instruction to the current - // data fragment because we want all the instructions in a group to get into - // the same fragment. Be careful not to do that for the first instruction in - // the group, though. - MCDataFragment *DF; - - if (Assembler.isBundlingEnabled()) { - MCSection &Sec = *getCurrentSectionOnly(); - if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) { - // If we are bundle-locked, we re-use the current fragment. - // The bundle-locking directive ensures this is a new data fragment. - DF = cast(getCurrentFragment()); - CheckBundleSubtargets(DF->getSubtargetInfo(), &STI); - } else { - DF = getContext().allocFragment(); - insert(DF); - } - if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) { - // If this fragment is for a group marked "align_to_end", set a flag - // in the fragment. This can happen after the fragment has already been - // created if there are nested bundle_align groups and an inner one - // is the one marked align_to_end. - DF->setAlignToBundleEnd(true); - } - - // We're now emitting an instruction in a bundle group, so this flag has - // to be turned off. - Sec.setBundleGroupBeforeFirstInst(false); - } else { - DF = getOrCreateDataFragment(&STI); - } - - // Emit instruction directly into data fragment. - size_t FixupStartIndex = DF->getFixups().size(); - size_t CodeOffset = DF->getContents().size(); - SmallVector Fixups; - Assembler.getEmitter().encodeInstruction(Inst, DF->getContentsForAppending(), - Fixups, STI); - DF->doneAppending(); - if (!Fixups.empty()) - DF->appendFixups(Fixups); - - for (auto &Fixup : MutableArrayRef(DF->getFixups()).slice(FixupStartIndex)) { - Fixup.setOffset(Fixup.getOffset() + CodeOffset); - if (Fixup.isLinkerRelaxable()) { - DF->setLinkerRelaxable(); - getCurrentSectionOnly()->setLinkerRelaxable(); - } - } - - DF->setHasInstructions(STI); -} - -void MCELFStreamer::emitBundleAlignMode(Align Alignment) { - assert(Log2(Alignment) <= 30 && "Invalid bundle alignment"); - MCAssembler &Assembler = getAssembler(); - if (Alignment > 1 && (Assembler.getBundleAlignSize() == 0 || - Assembler.getBundleAlignSize() == Alignment.value())) - Assembler.setBundleAlignSize(Alignment.value()); - else - report_fatal_error(".bundle_align_mode cannot be changed once set"); -} - -void MCELFStreamer::emitBundleLock(bool AlignToEnd) { - MCSection &Sec = *getCurrentSectionOnly(); - - if (!getAssembler().isBundlingEnabled()) - report_fatal_error(".bundle_lock forbidden when bundling is disabled"); - - if (!isBundleLocked()) - Sec.setBundleGroupBeforeFirstInst(true); - - Sec.setBundleLockState(AlignToEnd ? MCSection::BundleLockedAlignToEnd - : MCSection::BundleLocked); -} - -void MCELFStreamer::emitBundleUnlock() { - MCSection &Sec = *getCurrentSectionOnly(); - - if (!getAssembler().isBundlingEnabled()) - report_fatal_error(".bundle_unlock forbidden when bundling is disabled"); - else if (!isBundleLocked()) - report_fatal_error(".bundle_unlock without matching lock"); - else if (Sec.isBundleGroupBeforeFirstInst()) - report_fatal_error("Empty bundle-locked group is forbidden"); - - Sec.setBundleLockState(MCSection::NotBundleLocked); -} - void MCELFStreamer::finishImpl() { // Emit the .gnu attributes section if any attributes have been added. if (!GNUAttributes.empty()) { @@ -510,10 +363,6 @@ void MCELFStreamer::finishImpl() { DummyAttributeSection, GNUAttributes); } - // Ensure the last section gets aligned if necessary. - if (MCFragment *F = getCurrentFragment()) - setSectionAlignmentForBundling(getAssembler(), F->getParent()); - finalizeCGProfile(); emitFrames(nullptr); diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index a196591744099..dbb2fd16eb2e5 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -324,7 +324,7 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, // symbols is limited to specific cases where the fragments between two // symbols (including the fragments the symbols are defined in) are // fixed-size fragments so the difference can be calculated. For example, - // this is important when the Subtarget is changed and a new MCDataFragment + // this is important when the Subtarget is changed and a new MCFragment // is created in the case of foo: instr; .arch_extension ext; instr .if . - // foo. if (SA.isVariable() || SB.isVariable()) @@ -352,7 +352,7 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, // the linker. bool BBeforeRelax = false, AAfterRelax = false; for (auto F = FB; F; F = F->getNext()) { - auto DF = dyn_cast(F); + auto DF = F->getKind() == MCFragment::FT_Data ? F : nullptr; if (DF && DF->isLinkerRelaxable()) { if (&*F != FB || SBOffset != DF->getContents().size()) BBeforeRelax = true; @@ -370,20 +370,17 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, } int64_t Num; - unsigned Count; if (DF) { Displacement += DF->getContents().size(); - } else if (auto *RF = dyn_cast(F); - RF && Asm->hasFinalLayout()) { + } else if (F->getKind() == MCFragment::FT_Relaxable && + Asm->hasFinalLayout()) { // Before finishLayout, a relaxable fragment's size is indeterminate. // After layout, during relocation generation, it can be treated as a // data fragment. - Displacement += RF->getContents().size(); - } else if (auto *AF = dyn_cast(F); - AF && Layout && AF->hasEmitNops() && - !Asm->getBackend().shouldInsertExtraNopBytesForCodeAlign( - *AF, Count)) { - Displacement += Asm->computeFragmentSize(*AF); + Displacement += F->getSize(); + } else if (F->getKind() == MCFragment::FT_Align && Layout && + F->isLinkerRelaxable()) { + Displacement += Asm->computeFragmentSize(*F); } else if (auto *FF = dyn_cast(F); FF && FF->getNumValues().evaluateAsAbsolute(Num)) { Displacement += Num * FF->getValueSize(); diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp index c59fabe5df1b9..3c395e5ccdb0b 100644 --- a/llvm/lib/MC/MCFragment.cpp +++ b/llvm/lib/MC/MCFragment.cpp @@ -24,12 +24,15 @@ using namespace llvm; -static_assert(std::is_trivially_destructible_v, +static_assert(std::is_trivially_destructible_v, "fragment classes must be trivially destructible"); MCFragment::MCFragment(FragmentType Kind, bool HasInstructions) - : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false), - LinkerRelaxable(false), AllowAutoPadding(false) {} + : Kind(Kind), LinkerRelaxable(false), HasInstructions(HasInstructions), + AllowAutoPadding(false) { + static_assert(sizeof(MCFragment::Tail) <= 16, + "Keep the variable-size tail small"); +} const MCSymbol *MCFragment::getAtom() const { return cast(Parent)->getAtom(LayoutOrder); @@ -55,14 +58,9 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { case MCFragment::FT_SymbolId: OS << "SymbolId"; break; case MCFragment::FT_CVInlineLines: OS << "CVInlineLineTable"; break; case MCFragment::FT_CVDefRange: OS << "CVDefRangeTable"; break; - case MCFragment::FT_PseudoProbe: OS << "PseudoProbe"; break; // clang-format on } - if (const auto *EF = dyn_cast(this)) - if (auto Pad = static_cast(EF->getBundlePadding())) - OS << " BundlePadding:" << Pad; - auto printFixups = [&](llvm::ArrayRef Fixups) { if (Fixups.empty()) return; @@ -74,27 +72,69 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { }; switch (getKind()) { - case MCFragment::FT_Align: { - const auto *AF = cast(this); - OS << " Align:" << AF->getAlignment().value() << " Fill:" << AF->getFill() - << " FillLen:" << unsigned(AF->getFillLen()) - << " MaxBytesToEmit:" << AF->getMaxBytesToEmit(); - if (AF->hasEmitNops()) - OS << " Nops"; - break; - } - case MCFragment::FT_Data: { - const auto *F = cast(this); - if (F->isLinkerRelaxable()) + case MCFragment::FT_Data: + case MCFragment::FT_Relaxable: + case MCFragment::FT_Align: + case MCFragment::FT_LEB: + case MCFragment::FT_Dwarf: + case MCFragment::FT_DwarfFrame: { + if (isLinkerRelaxable()) OS << " LinkerRelaxable"; - auto Contents = F->getContents(); - OS << " Size:" << Contents.size() << " ["; - for (unsigned i = 0, e = Contents.size(); i != e; ++i) { + auto Fixed = getContents(); + auto Var = getVarContents(); + OS << " Size:" << Fixed.size(); + if (getKind() != MCFragment::FT_Data) { + OS << '+' << Var.size(); + // FT_Align uses getVarContents to track the size, but the content is + // ignored and not useful. + if (getKind() == MCFragment::FT_Align) + Var = {}; + } + OS << " ["; + for (unsigned i = 0, e = Fixed.size(); i != e; ++i) { if (i) OS << ","; - OS << format("%02x", uint8_t(Contents[i])); + OS << format("%02x", uint8_t(Fixed[i])); + } + for (unsigned i = 0, e = Var.size(); i != e; ++i) { + if (Fixed.size() || i) + OS << ","; + OS << format("%02x", uint8_t(Var[i])); } OS << ']'; - printFixups(F->getFixups()); + switch (getKind()) { + case MCFragment::FT_Data: + break; + case MCFragment::FT_Relaxable: + OS << ' '; + getInst().dump_pretty(OS); + break; + case MCFragment::FT_Align: + OS << "\n Align:" << getAlignment().value() << " Fill:" << getAlignFill() + << " FillLen:" << unsigned(getAlignFillLen()) + << " MaxBytesToEmit:" << getAlignMaxBytesToEmit(); + if (hasAlignEmitNops()) + OS << " Nops"; + break; + case MCFragment::FT_LEB: { + OS << " Value:"; + getLEBValue().print(OS, nullptr); + OS << " Signed:" << isLEBSigned(); + break; + } + case MCFragment::FT_Dwarf: + OS << " AddrDelta:"; + getDwarfAddrDelta().print(OS, nullptr); + OS << " LineDelta:" << getDwarfLineDelta(); + break; + case MCFragment::FT_DwarfFrame: + OS << " AddrDelta:"; + getDwarfAddrDelta().print(OS, nullptr); + break; + default: + llvm_unreachable(""); + } + printFixups(getFixups()); + printFixups(getVarFixups()); break; } case MCFragment::FT_Fill: { @@ -111,13 +151,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { << " ControlledNopLength:" << NF->getControlledNopLength(); break; } - case MCFragment::FT_Relaxable: { - const auto *F = cast(this); - OS << " Size:" << F->getContents().size() << ' '; - F->getInst().dump_pretty(OS); - printFixups(F->getFixups()); - break; - } case MCFragment::FT_Org: { const auto *OF = cast(this); OS << " Offset:"; @@ -125,26 +158,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { OS << " Value:" << static_cast(OF->getValue()); break; } - case MCFragment::FT_Dwarf: { - const auto *OF = cast(this); - OS << " AddrDelta:"; - OF->getAddrDelta().print(OS, nullptr); - OS << " LineDelta:" << OF->getLineDelta(); - break; - } - case MCFragment::FT_DwarfFrame: { - const auto *CF = cast(this); - OS << " AddrDelta:"; - CF->getAddrDelta().print(OS, nullptr); - break; - } - case MCFragment::FT_LEB: { - const auto *LF = cast(this); - OS << " Value:"; - LF->getValue().print(OS, nullptr); - OS << " Signed:" << LF->isSigned(); - break; - } case MCFragment::FT_BoundaryAlign: { const auto *BF = cast(this); OS << " BoundarySize:" << BF->getAlignment().value() @@ -172,12 +185,6 @@ LLVM_DUMP_METHOD void MCFragment::dump() const { } break; } - case MCFragment::FT_PseudoProbe: { - const auto *OF = cast(this); - OS << " AddrDelta:"; - OF->getAddrDelta().print(OS, nullptr); - break; - } } } #endif diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index 4ede2997a4455..4d76299f3c821 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -163,7 +163,7 @@ void MCMachOStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { // We have to create a new fragment if this is an atom defining symbol, // fragments cannot span atoms. if (cast(Symbol)->isSymbolLinkerVisible()) - insert(getContext().allocFragment()); + newFragment(); MCObjectStreamer::emitLabel(Symbol, Loc); @@ -401,7 +401,7 @@ void MCMachOStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol, // On darwin all virtual sections have zerofill type. Disallow the usage of // .zerofill in non-virtual functions. If something similar is needed, use // .space or .zero. - if (!Section->isVirtualSection()) { + if (!Section->isBssSection()) { getContext().reportError( Loc, "The usage of .zerofill is restricted to sections of " "ZEROFILL type. Use .zero or .space instead."); @@ -491,8 +491,7 @@ void MCMachOStreamer::finalizeCGProfile() { // For each entry, reserve space for 2 32-bit indices and a 64-bit count. size_t SectionBytes = W.getCGProfile().size() * (2 * sizeof(uint32_t) + sizeof(uint64_t)); - cast(*CGProfileSection->begin()) - .appendContents(SectionBytes, 0); + (*CGProfileSection->begin()).appendContents(SectionBytes, 0); } MCStreamer *llvm::createMachOStreamer(MCContext &Context, @@ -521,7 +520,7 @@ void MCMachOStreamer::createAddrSigSection() { MCSection *AddrSigSection = Asm.getContext().getObjectFileInfo()->getAddrSigSection(); changeSection(AddrSigSection); - auto *Frag = cast(AddrSigSection->curFragList()->Head); + auto *Frag = cast(AddrSigSection->curFragList()->Head); // We will generate a series of pointer-sized symbol relocations at offset // 0x0. Set the section size to be large enough to contain a single pointer // (instead of emitting a zero-sized section) so these relocations are diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 44a82f75576b6..4c99010700fc7 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -46,37 +46,9 @@ MCAssembler *MCObjectStreamer::getAssemblerPtr() { return nullptr; } -// When fixup's offset is a forward declared label, e.g.: -// -// .reloc 1f, R_MIPS_JALR, foo -// 1: nop -// -// postpone adding it to Fixups vector until the label is defined and its offset -// is known. -void MCObjectStreamer::resolvePendingFixups() { - for (PendingMCFixup &PendingFixup : PendingFixups) { - if (!PendingFixup.Sym || PendingFixup.Sym->isUndefined ()) { - getContext().reportError(PendingFixup.Fixup.getLoc(), - "unresolved relocation offset"); - continue; - } - PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset() + - PendingFixup.Fixup.getOffset()); - - // If the location symbol to relocate is in MCEncodedFragment, - // put the Fixup into location symbol's fragment. Otherwise - // put into PendingFixup.DF - MCFragment *SymFragment = PendingFixup.Sym->getFragment(); - if (auto *F = dyn_cast(SymFragment)) - F->addFixup(PendingFixup.Fixup); - else - PendingFixup.DF->addFixup(PendingFixup.Fixup); - } - PendingFixups.clear(); -} - // As a compile-time optimization, avoid allocating and evaluating an MCExpr -// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment. +// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment's fixed +// part. static std::optional absoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo) { assert(Hi && Lo); @@ -85,8 +57,11 @@ static std::optional absoluteSymbolDiff(const MCSymbol *Hi, if (Hi->isVariable() || Lo->isVariable()) return std::nullopt; auto *LoF = Lo->getFragment(); - if (!LoF || LoF->getKind() != MCFragment::FT_Data || - Hi->getFragment() != LoF || LoF->isLinkerRelaxable()) + if (!LoF || Hi->getFragment() != LoF || LoF->isLinkerRelaxable()) + return std::nullopt; + // If either symbol resides in the variable part, bail out. + auto Fixed = LoF->getFixedSize(); + if (Lo->getOffset() > Fixed || Hi->getOffset() > Fixed) return std::nullopt; return Hi->getOffset() - Lo->getOffset(); @@ -131,35 +106,6 @@ void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) { MCDwarfFrameEmitter::Emit(*this, MAB, false); } -static bool canReuseDataFragment(const MCDataFragment &F, - const MCAssembler &Assembler, - const MCSubtargetInfo *STI) { - if (!F.hasInstructions()) - return true; - // Do not add data after a linker-relaxable instruction. The difference - // between a new label and a label at or before the linker-relaxable - // instruction cannot be resolved at assemble-time. - if (F.isLinkerRelaxable()) - return false; - // When bundling is enabled, we don't want to add data to a fragment that - // already has instructions (see MCELFStreamer::emitInstToData for details) - if (Assembler.isBundlingEnabled()) - return false; - // If the subtarget is changed mid fragment we start a new fragment to record - // the new STI. - return !STI || F.getSubtargetInfo() == STI; -} - -MCDataFragment * -MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) { - auto *F = dyn_cast(getCurrentFragment()); - if (!F || !canReuseDataFragment(*F, *Assembler, STI)) { - F = getContext().allocFragment(); - insert(F); - } - return F; -} - void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { Assembler->registerSymbol(Sym); } @@ -173,7 +119,7 @@ void MCObjectStreamer::emitCFISections(bool EH, bool Debug) { void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { MCStreamer::emitValueImpl(Value, Size, Loc); - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); MCDwarfLineEntry::make(this, getCurrentSectionOnly()); @@ -222,7 +168,7 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { // If there is a current fragment, mark the symbol as pointing into it. // Otherwise queue the label and set its fragment pointer when we emit the // next fragment. - MCDataFragment *F = getOrCreateDataFragment(); + MCFragment *F = getCurrentFragment(); Symbol->setFragment(F); Symbol->setOffset(F->getContents().size()); @@ -242,7 +188,7 @@ void MCObjectStreamer::emitPendingAssignments(MCSymbol *Symbol) { // Emit a label at a previously emitted fragment/offset position. This must be // within the currently-active section. void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, - MCDataFragment &F, uint64_t Offset) { + MCFragment &F, uint64_t Offset) { assert(F.getParent() == getCurrentSectionOnly()); MCStreamer::emitLabel(Symbol, Loc); getAssembler().registerSymbol(*Symbol); @@ -256,7 +202,9 @@ void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) { emitULEB128IntValue(IntValue); return; } - insert(getContext().allocFragment(*Value, false)); + auto *F = getCurrentFragment(); + F->makeLEB(false, Value); + newFragment(); } void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) { @@ -265,7 +213,9 @@ void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) { emitSLEB128IntValue(IntValue); return; } - insert(getContext().allocFragment(*Value, true)); + auto *F = getCurrentFragment(); + F->makeLEB(true, Value); + newFragment(); } void MCObjectStreamer::emitWeakReference(MCSymbol *Alias, @@ -289,7 +239,7 @@ bool MCObjectStreamer::changeSectionImpl(MCSection *Section, // If the subsection number is not in the sorted Subsections list, create a // new fragment list. if (I == E || Subsections[I].first != Subsection) { - auto *F = getContext().allocFragment(); + auto *F = getContext().allocFragment(); F->setParent(Section); Subsections.insert(Subsections.begin() + I, {Subsection, MCSection::FragList{F, F}}); @@ -329,18 +279,6 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { void MCObjectStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { - const MCSection &Sec = *getCurrentSectionOnly(); - if (Sec.isVirtualSection()) { - getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) + - " section '" + Sec.getName() + - "' cannot have instructions"); - return; - } - emitInstructionImpl(Inst, STI); -} - -void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, - const MCSubtargetInfo &STI) { MCStreamer::emitInstruction(Inst, STI); MCSection *Sec = getCurrentSectionOnly(); @@ -359,13 +297,8 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, return; } - // Otherwise, relax and emit it as data if either: - // - The RelaxAll flag was passed - // - Bundling is enabled and this instruction is inside a bundle-locked - // group. We want to emit all such instructions into the same data - // fragment. - if (Assembler.getRelaxAll() || - (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { + // Otherwise, relax and emit it as data if RelaxAll is specified. + if (Assembler.getRelaxAll()) { MCInst Relaxed = Inst; while (Backend.mayNeedRelaxation(Relaxed.getOpcode(), Relaxed.getOperands(), STI)) @@ -374,57 +307,55 @@ void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst, return; } - // Otherwise emit to a separate fragment. emitInstToFragment(Inst, STI); } void MCObjectStreamer::emitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) { - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *F = getCurrentFragment(); + + // Append the instruction to the data fragment. + size_t FixupStartIndex = F->getFixups().size(); + size_t CodeOffset = F->getContents().size(); SmallVector Fixups; - SmallString<256> Code; - getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI); + getAssembler().getEmitter().encodeInstruction( + Inst, F->getContentsForAppending(), Fixups, STI); + F->doneAppending(); + if (!Fixups.empty()) + F->appendFixups(Fixups); + F->setHasInstructions(STI); - auto CodeOffset = DF->getContents().size(); - for (MCFixup &Fixup : Fixups) + bool MarkedLinkerRelaxable = false; + for (auto &Fixup : MutableArrayRef(F->getFixups()).slice(FixupStartIndex)) { Fixup.setOffset(Fixup.getOffset() + CodeOffset); - if (!Fixups.empty()) - DF->appendFixups(Fixups); - DF->setHasInstructions(STI); - DF->appendContents(Code); + if (!Fixup.isLinkerRelaxable()) + continue; + F->setLinkerRelaxable(); + // Do not add data after a linker-relaxable instruction. The difference + // between a new label and a label at or before the linker-relaxable + // instruction cannot be resolved at assemble-time. + if (!MarkedLinkerRelaxable) { + MarkedLinkerRelaxable = true; + getCurrentSectionOnly()->setLinkerRelaxable(); + newFragment(); + } + } } void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &STI) { - // Always create a new, separate fragment here, because its size can change - // during relaxation. - MCRelaxableFragment *IF = - getContext().allocFragment(STI); - insert(IF); - IF->setInst(Inst); - + auto *F = getCurrentFragment(); + SmallVector Data; SmallVector Fixups; - getAssembler().getEmitter().encodeInstruction( - Inst, IF->getContentsForAppending(), Fixups, STI); - IF->doneAppending(); - IF->appendFixups(Fixups); -} - -#ifndef NDEBUG -static const char *const BundlingNotImplementedMsg = - "Aligned bundling is not implemented for this object format"; -#endif - -void MCObjectStreamer::emitBundleAlignMode(Align Alignment) { - llvm_unreachable(BundlingNotImplementedMsg); -} + getAssembler().getEmitter().encodeInstruction(Inst, Data, Fixups, STI); -void MCObjectStreamer::emitBundleLock(bool AlignToEnd) { - llvm_unreachable(BundlingNotImplementedMsg); -} - -void MCObjectStreamer::emitBundleUnlock() { - llvm_unreachable(BundlingNotImplementedMsg); + F->Kind = MCFragment::FT_Relaxable; + F->STI = &STI; + F->HasInstructions = true; + F->setVarContents(Data); + F->setVarFixups(Fixups); + F->setInst(Inst); + newFragment(); } void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -486,9 +417,11 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta, return; } - const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, SMLoc()); - insert(getContext().allocFragment(LineDelta, - *AddrDelta)); + auto *F = getCurrentFragment(); + F->Kind = MCFragment::FT_Dwarf; + F->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, SMLoc())); + F->setDwarfLineDelta(LineDelta); + newFragment(); } void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section, @@ -516,8 +449,10 @@ void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section, void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label, SMLoc Loc) { - const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel, Loc); - insert(getContext().allocFragment(*AddrDelta)); + auto *F = getCurrentFragment(); + F->Kind = MCFragment::FT_DwarfFrame; + F->setDwarfAddrDelta(buildSymbolDiff(*this, Label, LastLabel, Loc)); + newFragment(); } void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo, @@ -576,7 +511,7 @@ void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) { void MCObjectStreamer::emitBytes(StringRef Data) { MCDwarfLineEntry::make(this, getCurrentSectionOnly()); - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); DF->appendContents(ArrayRef(Data.data(), Data.size())); } @@ -585,26 +520,21 @@ void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Fill, unsigned MaxBytesToEmit) { if (MaxBytesToEmit == 0) MaxBytesToEmit = Alignment.value(); - insert(getContext().allocFragment(Alignment, Fill, FillLen, - MaxBytesToEmit)); + MCFragment *F = getCurrentFragment(); + F->makeAlign(Alignment, Fill, FillLen, MaxBytesToEmit); + newFragment(); // Update the maximum alignment on the current section if necessary. - MCSection *CurSec = getCurrentSectionOnly(); - CurSec->ensureMinAlignment(Alignment); + F->getParent()->ensureMinAlignment(Alignment); } void MCObjectStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit) { + auto *F = getCurrentFragment(); emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit); - auto *F = cast(getCurrentFragment()); - F->setEmitNops(true, STI); - // With RISC-V style linker relaxation, mark the section as linker-relaxable - // if the alignment is larger than the minimum NOP size. - unsigned Size; - if (getAssembler().getBackend().shouldInsertExtraNopBytesForCodeAlign(*F, - Size)) - getCurrentSectionOnly()->setLinkerRelaxable(); + F->u.align.EmitNops = true; + F->STI = STI; } void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, @@ -613,76 +543,14 @@ void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, insert(getContext().allocFragment(*Offset, Value, Loc)); } -static std::optional> -getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset, - MCDataFragment *&DF) { - if (Symbol.isVariable()) { - const MCExpr *SymbolExpr = Symbol.getVariableValue(); - MCValue OffsetVal; - if (!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr)) - return std::make_pair(false, - std::string("symbol in .reloc offset is not " - "relocatable")); - if (OffsetVal.isAbsolute()) { - RelocOffset = OffsetVal.getConstant(); - MCFragment *Fragment = Symbol.getFragment(); - // FIXME Support symbols with no DF. For example: - // .reloc .data, ENUM_VALUE, - if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) - return std::make_pair(false, - std::string("symbol in offset has no data " - "fragment")); - DF = cast(Fragment); - return std::nullopt; - } - - if (OffsetVal.getSubSym()) - return std::make_pair(false, - std::string(".reloc symbol offset is not " - "representable")); - - const MCSymbol &SA = *OffsetVal.getAddSym(); - if (!SA.isDefined()) - return std::make_pair(false, - std::string("symbol used in the .reloc offset is " - "not defined")); - - if (SA.isVariable()) - return std::make_pair(false, - std::string("symbol used in the .reloc offset is " - "variable")); - - MCFragment *Fragment = SA.getFragment(); - // FIXME Support symbols with no DF. For example: - // .reloc .data, ENUM_VALUE, - if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) - return std::make_pair(false, - std::string("symbol in offset has no data " - "fragment")); - RelocOffset = SA.getOffset() + OffsetVal.getConstant(); - DF = cast(Fragment); - } else { - RelocOffset = Symbol.getOffset(); - MCFragment *Fragment = Symbol.getFragment(); - // FIXME Support symbols with no DF. For example: - // .reloc .data, ENUM_VALUE, - if (!Fragment || Fragment->getKind() != MCFragment::FT_Data) - return std::make_pair(false, - std::string("symbol in offset has no data " - "fragment")); - DF = cast(Fragment); - } - return std::nullopt; -} - -std::optional> -MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, - const MCExpr *Expr, SMLoc Loc, - const MCSubtargetInfo &STI) { +void MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, + const MCExpr *Expr, SMLoc Loc) { std::optional MaybeKind = Assembler->getBackend().getFixupKind(Name); - if (!MaybeKind) - return std::make_pair(true, std::string("unknown relocation name")); + if (!MaybeKind) { + getContext().reportError(Loc, "unknown relocation name"); + return; + } MCFixupKind Kind = *MaybeKind; if (Expr) @@ -691,38 +559,14 @@ MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name, Expr = MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext()); - MCDataFragment *DF = getOrCreateDataFragment(&STI); - MCValue OffsetVal; - if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr)) - return std::make_pair(false, - std::string(".reloc offset is not relocatable")); - if (OffsetVal.isAbsolute()) { - if (OffsetVal.getConstant() < 0) - return std::make_pair(false, std::string(".reloc offset is negative")); - DF->addFixup(MCFixup::create(OffsetVal.getConstant(), Expr, Kind)); - return std::nullopt; + auto *O = &Offset; + int64_t Val; + if (Offset.evaluateAsAbsolute(Val, nullptr)) { + auto *SecSym = getCurrentSectionOnly()->getBeginSymbol(); + O = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(SecSym, getContext()), + O, getContext(), Loc); } - if (OffsetVal.getSubSym()) - return std::make_pair(false, - std::string(".reloc offset is not representable")); - - const MCSymbol &Symbol = *OffsetVal.getAddSym(); - if (Symbol.isDefined()) { - uint32_t SymbolOffset = 0; - std::optional> Error = - getOffsetAndDataFragment(Symbol, SymbolOffset, DF); - - if (Error != std::nullopt) - return Error; - - DF->addFixup( - MCFixup::create(SymbolOffset + OffsetVal.getConstant(), Expr, Kind)); - return std::nullopt; - } - - PendingFixups.emplace_back( - &Symbol, DF, MCFixup::create(OffsetVal.getConstant(), Expr, Kind)); - return std::nullopt; + getAssembler().addRelocDirective({*O, Expr, Kind}); } void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, @@ -805,6 +649,5 @@ void MCObjectStreamer::finishImpl() { // Emit pseudo probes for the current module. MCPseudoProbeTable::emit(this); - resolvePendingFixups(); getAssembler().Finish(); } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 9fd6c05a846db..d0b6ea4cfd562 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -421,9 +421,6 @@ class AsmParser : public MCAsmParser { DK_ORG, DK_FILL, DK_ENDR, - DK_BUNDLE_ALIGN_MODE, - DK_BUNDLE_LOCK, - DK_BUNDLE_UNLOCK, DK_ZERO, DK_EXTERN, DK_GLOBL, @@ -624,12 +621,6 @@ class AsmParser : public MCAsmParser { bool parseDirectiveMacrosOnOff(StringRef Directive); // alternate macro mode directives bool parseDirectiveAltmacro(StringRef Directive); - // ".bundle_align_mode" - bool parseDirectiveBundleAlignMode(); - // ".bundle_lock" - bool parseDirectiveBundleLock(); - // ".bundle_unlock" - bool parseDirectiveBundleUnlock(); // ".space", ".skip" bool parseDirectiveSpace(StringRef IDVal); @@ -2062,12 +2053,6 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, return parseDirectiveIrpc(IDLoc); case DK_ENDR: return parseDirectiveEndr(IDLoc); - case DK_BUNDLE_ALIGN_MODE: - return parseDirectiveBundleAlignMode(); - case DK_BUNDLE_LOCK: - return parseDirectiveBundleLock(); - case DK_BUNDLE_UNLOCK: - return parseDirectiveBundleUnlock(); case DK_SLEB128: return parseDirectiveLEB128(true); case DK_ULEB128: @@ -3094,7 +3079,6 @@ bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) { const MCExpr *Offset; const MCExpr *Expr = nullptr; - SMLoc OffsetLoc = Lexer.getTok().getLoc(); if (parseExpression(Offset)) return true; @@ -3120,13 +3104,7 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) { if (parseEOL()) return true; - const MCTargetAsmParser &MCT = getTargetParser(); - const MCSubtargetInfo &STI = MCT.getSTI(); - if (std::optional> Err = - getStreamer().emitRelocDirective(*Offset, Name, Expr, DirectiveLoc, - STI)) - return Error(Err->first ? NameLoc : OffsetLoc, Err->second); - + getStreamer().emitRelocDirective(*Offset, Name, Expr, NameLoc); return false; } @@ -3426,11 +3404,10 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, uint8_t ValueSize) { const MCSection *Section = getStreamer().getCurrentSectionOnly(); assert(Section && "must have section to emit alignment"); - if (HasFillExpr && FillExpr != 0 && Section->isVirtualSection()) { + if (HasFillExpr && FillExpr != 0 && Section->isBssSection()) { ReturnVal |= - Warning(FillExprLoc, "ignoring non-zero fill value in " + - Section->getVirtualSectionKind() + - " section '" + Section->getName() + "'"); + Warning(FillExprLoc, "ignoring non-zero fill value in BSS section '" + + Section->getName() + "'"); FillExpr = 0; } @@ -4779,56 +4756,6 @@ bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) { return false; } -/// parseDirectiveBundleAlignMode -/// ::= {.bundle_align_mode} expression -bool AsmParser::parseDirectiveBundleAlignMode() { - // Expect a single argument: an expression that evaluates to a constant - // in the inclusive range 0-30. - SMLoc ExprLoc = getLexer().getLoc(); - int64_t AlignSizePow2; - if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) || - parseEOL() || - check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc, - "invalid bundle alignment size (expected between 0 and 30)")) - return true; - - getStreamer().emitBundleAlignMode(Align(1ULL << AlignSizePow2)); - return false; -} - -/// parseDirectiveBundleLock -/// ::= {.bundle_lock} [align_to_end] -bool AsmParser::parseDirectiveBundleLock() { - if (checkForValidSection()) - return true; - bool AlignToEnd = false; - - StringRef Option; - SMLoc Loc = getTok().getLoc(); - const char *kInvalidOptionError = - "invalid option for '.bundle_lock' directive"; - - if (!parseOptionalToken(AsmToken::EndOfStatement)) { - if (check(parseIdentifier(Option), Loc, kInvalidOptionError) || - check(Option != "align_to_end", Loc, kInvalidOptionError) || parseEOL()) - return true; - AlignToEnd = true; - } - - getStreamer().emitBundleLock(AlignToEnd); - return false; -} - -/// parseDirectiveBundleLock -/// ::= {.bundle_lock} -bool AsmParser::parseDirectiveBundleUnlock() { - if (checkForValidSection() || parseEOL()) - return true; - - getStreamer().emitBundleUnlock(); - return false; -} - /// parseDirectiveSpace /// ::= (.skip | .space) expression [ , expression ] bool AsmParser::parseDirectiveSpace(StringRef IDVal) { @@ -5477,9 +5404,6 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".irp"] = DK_IRP; DirectiveKindMap[".irpc"] = DK_IRPC; DirectiveKindMap[".endr"] = DK_ENDR; - DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE; - DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK; - DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK; DirectiveKindMap[".if"] = DK_IF; DirectiveKindMap[".ifeq"] = DK_IFEQ; DirectiveKindMap[".ifge"] = DK_IFGE; diff --git a/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp b/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp index 665d92eb9a21c..7f0934971b27c 100644 --- a/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp +++ b/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp @@ -9,6 +9,7 @@ #include "llvm/MC/MCParser/MCTargetAsmParser.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCRegister.h" +#include "llvm/MC/MCStreamer.h" using namespace llvm; @@ -22,6 +23,10 @@ MCTargetAsmParser::~MCTargetAsmParser() = default; MCSubtargetInfo &MCTargetAsmParser::copySTI() { MCSubtargetInfo &STICopy = getContext().getSubtargetCopy(getSTI()); STI = &STICopy; + // The returned STI will likely be modified. Create a new fragment to prevent + // mixing STI values within a fragment. + if (getStreamer().getCurrentFragment()) + getStreamer().newFragment(); return STICopy; } diff --git a/llvm/lib/MC/MCPseudoProbe.cpp b/llvm/lib/MC/MCPseudoProbe.cpp index f87d27f4adcc5..b493337b39317 100644 --- a/llvm/lib/MC/MCPseudoProbe.cpp +++ b/llvm/lib/MC/MCPseudoProbe.cpp @@ -81,8 +81,9 @@ void MCPseudoProbe::emit(MCObjectStreamer *MCOS, if (AddrDelta->evaluateAsAbsolute(Delta, MCOS->getAssemblerPtr())) { MCOS->emitSLEB128IntValue(Delta); } else { - MCOS->insert(MCOS->getContext().allocFragment( - AddrDelta)); + auto *F = MCOS->getCurrentFragment(); + F->makeLEB(true, AddrDelta); + MCOS->newFragment(); } } else { // Emit the GUID of the split function that the sentinel probe represents. diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp index beb472b7c7deb..1b5a7b337c207 100644 --- a/llvm/lib/MC/MCSection.cpp +++ b/llvm/lib/MC/MCSection.cpp @@ -18,11 +18,10 @@ using namespace llvm; -MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText, - bool IsVirtual, MCSymbol *Begin) - : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false), - IsRegistered(false), IsText(IsText), IsVirtual(IsVirtual), - LinkerRelaxable(false), Name(Name), Variant(V) { +MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText, bool IsBss, + MCSymbol *Begin) + : Begin(Begin), HasInstructions(false), IsRegistered(false), IsText(IsText), + IsBss(IsBss), LinkerRelaxable(false), Name(Name), Variant(V) { // The initial subsection number is 0. Create a fragment list. CurFragList = &Subsections.emplace_back(0u, FragList{}).second; } @@ -35,27 +34,6 @@ MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) { bool MCSection::hasEnded() const { return End && End->isInSection(); } -void MCSection::setBundleLockState(BundleLockStateType NewState) { - if (NewState == NotBundleLocked) { - if (BundleLockNestingDepth == 0) { - report_fatal_error("Mismatched bundle_lock/unlock directives"); - } - if (--BundleLockNestingDepth == 0) { - BundleLockState = NotBundleLocked; - } - return; - } - - // If any of the directives is an align_to_end directive, the whole nested - // group is align_to_end. So don't downgrade from align_to_end to just locked. - if (BundleLockState != BundleLockedAlignToEnd) { - BundleLockState = NewState; - } - ++BundleLockNestingDepth; -} - -StringRef MCSection::getVirtualSectionKind() const { return "virtual"; } - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void MCSection::dump( DenseMap> *FragToSyms) @@ -80,7 +58,7 @@ LLVM_DUMP_METHOD void MCSection::dump( } #endif -void MCEncodedFragment::setContents(ArrayRef Contents) { +void MCFragment::setContents(ArrayRef Contents) { auto &S = getParent()->ContentStorage; if (ContentStart + Contents.size() > ContentEnd) { ContentStart = S.size(); @@ -90,9 +68,19 @@ void MCEncodedFragment::setContents(ArrayRef Contents) { llvm::copy(Contents, S.begin() + ContentStart); } -void MCEncodedFragment::addFixup(MCFixup Fixup) { appendFixups({Fixup}); } +void MCFragment::setVarContents(ArrayRef Contents) { + auto &S = getParent()->ContentStorage; + if (VarContentStart + Contents.size() > VarContentEnd) { + VarContentStart = S.size(); + S.resize_for_overwrite(S.size() + Contents.size()); + } + VarContentEnd = VarContentStart + Contents.size(); + llvm::copy(Contents, S.begin() + VarContentStart); +} + +void MCFragment::addFixup(MCFixup Fixup) { appendFixups({Fixup}); } -void MCEncodedFragment::appendFixups(ArrayRef Fixups) { +void MCFragment::appendFixups(ArrayRef Fixups) { auto &S = getParent()->FixupStorage; if (LLVM_UNLIKELY(FixupEnd != S.size())) { // Move the elements to the end. Reserve space to avoid invalidating @@ -106,7 +94,7 @@ void MCEncodedFragment::appendFixups(ArrayRef Fixups) { FixupEnd = S.size(); } -void MCEncodedFragment::setFixups(ArrayRef Fixups) { +void MCFragment::setFixups(ArrayRef Fixups) { auto &S = getParent()->FixupStorage; if (FixupStart + Fixups.size() > FixupEnd) { FixupStart = S.size(); @@ -115,3 +103,19 @@ void MCEncodedFragment::setFixups(ArrayRef Fixups) { FixupEnd = FixupStart + Fixups.size(); llvm::copy(Fixups, S.begin() + FixupStart); } + +void MCFragment::setVarFixups(ArrayRef Fixups) { + auto &S = getParent()->FixupStorage; + if (VarFixupStart + Fixups.size() > VarFixupEnd) { + VarFixupStart = S.size(); + S.resize_for_overwrite(S.size() + Fixups.size()); + } + VarFixupEnd = VarFixupStart + Fixups.size(); + // Source fixup offsets are relative to the variable part's start. Add the + // fixed part size to make them relative to the fixed part's start. + std::transform(Fixups.begin(), Fixups.end(), S.begin() + VarFixupStart, + [Fixed = getFixedSize()](MCFixup F) { + F.setOffset(Fixed + F.getOffset()); + return F; + }); +} diff --git a/llvm/lib/MC/MCSectionCOFF.cpp b/llvm/lib/MC/MCSectionCOFF.cpp index 94e29ce27d881..5bf14735eda9b 100644 --- a/llvm/lib/MC/MCSectionCOFF.cpp +++ b/llvm/lib/MC/MCSectionCOFF.cpp @@ -115,7 +115,3 @@ void MCSectionCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, } bool MCSectionCOFF::useCodeAlign() const { return isText(); } - -StringRef MCSectionCOFF::getVirtualSectionKind() const { - return "IMAGE_SCN_CNT_UNINITIALIZED_DATA"; -} diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp index 299fe40706e3a..ef33f9c314579 100644 --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -215,5 +215,3 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, bool MCSectionELF::useCodeAlign() const { return getFlags() & ELF::SHF_EXECINSTR; } - -StringRef MCSectionELF::getVirtualSectionKind() const { return "SHT_NOBITS"; } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 6d2fb41760044..b0e52bf511ba4 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1333,10 +1333,7 @@ void MCStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit) {} void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc) {} -void MCStreamer::emitBundleAlignMode(Align Alignment) {} -void MCStreamer::emitBundleLock(bool AlignToEnd) {} void MCStreamer::finishImpl() {} -void MCStreamer::emitBundleUnlock() {} bool MCStreamer::popSection() { if (SectionStack.size() <= 1) @@ -1407,6 +1404,26 @@ MCSymbol *MCStreamer::endSection(MCSection *Section) { return Sym; } +void MCStreamer::addFragment(MCFragment *F) { + auto *Sec = CurFrag->getParent(); + F->setParent(Sec); + F->setLayoutOrder(CurFrag->getLayoutOrder() + 1); + CurFrag->Next = F; + CurFrag = F; + Sec->curFragList()->Tail = F; +} + +void MCStreamer::newFragment() { + addFragment(getContext().allocFragment()); +} + +void MCStreamer::insert(MCFragment *F) { + assert(F->getKind() != MCFragment::FT_Data && + "F should have a variable-size tail"); + addFragment(F); + newFragment(); +} + static VersionTuple targetVersionOrMinimumSupportedOSVersion(const Triple &Target, VersionTuple TargetVersion) { diff --git a/llvm/lib/MC/MCSymbol.cpp b/llvm/lib/MC/MCSymbol.cpp index baf1ff89c0188..8192896eeb6bb 100644 --- a/llvm/lib/MC/MCSymbol.cpp +++ b/llvm/lib/MC/MCSymbol.cpp @@ -21,7 +21,7 @@ using namespace llvm; // Only the address of this fragment is ever actually used. -static MCDataFragment SentinelFragment; +static MCFragment SentinelFragment; // Sentinel value for the absolute pseudo fragment. MCFragment *MCSymbol::AbsolutePseudoFragment = &SentinelFragment; diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp index 44d98acdb31f1..5891420c0727d 100644 --- a/llvm/lib/MC/MCWasmStreamer.cpp +++ b/llvm/lib/MC/MCWasmStreamer.cpp @@ -45,7 +45,7 @@ void MCWasmStreamer::emitLabel(MCSymbol *S, SMLoc Loc) { Symbol->setTLS(); } -void MCWasmStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCDataFragment &F, +void MCWasmStreamer::emitLabelAtPos(MCSymbol *S, SMLoc Loc, MCFragment &F, uint64_t Offset) { auto *Symbol = cast(S); MCObjectStreamer::emitLabelAtPos(Symbol, Loc, F, Offset); diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp index 8cc74db9beea4..a1c049aaed9cb 100644 --- a/llvm/lib/MC/MCWin64EH.cpp +++ b/llvm/lib/MC/MCWin64EH.cpp @@ -318,7 +318,7 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { // Emit the epilog instructions. if (EnableUnwindV2) { - MCDataFragment *DF = OS->getOrCreateDataFragment(); + MCFragment *DF = OS->getCurrentFragment(); bool IsLast = true; for (const auto &Epilog : llvm::reverse(info->EpilogMap)) { diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp index 0c0866f9e36a4..370280eb87cfd 100644 --- a/llvm/lib/MC/MCWinCOFFStreamer.cpp +++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp @@ -278,7 +278,7 @@ void MCWinCOFFStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) { void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) { visitUsedSymbol(*Symbol); - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext()); MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2); DF->addFixup(Fixup); @@ -288,7 +288,7 @@ void MCWinCOFFStreamer::emitCOFFSectionIndex(const MCSymbol *Symbol) { void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol, uint64_t Offset) { visitUsedSymbol(*Symbol); - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); // Create Symbol A for the relocation relative reference. const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext()); // Add the constant offset, if given. @@ -306,7 +306,7 @@ void MCWinCOFFStreamer::emitCOFFSecRel32(const MCSymbol *Symbol, void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol, int64_t Offset) { visitUsedSymbol(*Symbol); - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); // Create Symbol A for the relocation relative reference. const MCExpr *MCE = MCSymbolRefExpr::create( Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32, getContext()); @@ -324,7 +324,7 @@ void MCWinCOFFStreamer::emitCOFFImgRel32(const MCSymbol *Symbol, void MCWinCOFFStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) { visitUsedSymbol(*Symbol); - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); // Create Symbol for section number. const MCExpr *MCE = MCCOFFSectionNumberTargetExpr::create( *Symbol, this->getWriter(), getContext()); @@ -338,7 +338,7 @@ void MCWinCOFFStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) { void MCWinCOFFStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) { visitUsedSymbol(*Symbol); - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); // Create Symbol for section offset. const MCExpr *MCE = MCCOFFSectionOffsetTargetExpr::create(*Symbol, getContext()); diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp index 12e6680bcf074..63381b4f81859 100644 --- a/llvm/lib/MC/MCXCOFFStreamer.cpp +++ b/llvm/lib/MC/MCXCOFFStreamer.cpp @@ -89,7 +89,7 @@ void MCXCOFFStreamer::emitXCOFFSymbolLinkageWithVisibility( void MCXCOFFStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) { // Add a Fixup here to later record a relocation of type R_REF to prevent the // ref symbol from being garbage collected (by the binder). - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext()); std::optional MaybeKind = getAssembler().getBackend().getFixupKind("R_REF"); diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index a2e73b9807bcf..34a7f6c4afab1 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -134,7 +134,7 @@ uint64_t MachObjectWriter::getPaddingSize(const MCAssembler &Asm, return 0; const MCSection &NextSec = *SectionOrder[Next]; - if (NextSec.isVirtualSection()) + if (NextSec.isBssSection()) return 0; return offsetToAlignment(EndAddr, NextSec.getAlign()); } @@ -277,7 +277,7 @@ void MachObjectWriter::writeSection(const MCAssembler &Asm, const MCSectionMachO &Section = cast(Sec); // The offset is unused for virtual sections. - if (Section.isVirtualSection()) { + if (Section.isBssSection()) { assert(Asm.getSectionFileSize(Sec) == 0 && "Invalid file size!"); FileOffset = 0; } @@ -692,13 +692,13 @@ void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm) { unsigned i = 0; // Compute the section layout order. Virtual sections must go last. for (MCSection &Sec : Asm) { - if (!Sec.isVirtualSection()) { + if (!Sec.isBssSection()) { SectionOrder.push_back(&Sec); cast(Sec).setLayoutOrder(i++); } } for (MCSection &Sec : Asm) { - if (Sec.isVirtualSection()) { + if (Sec.isBssSection()) { SectionOrder.push_back(&Sec); cast(Sec).setLayoutOrder(i++); } @@ -806,7 +806,7 @@ void MachObjectWriter::prepareObject(MCAssembler &Asm) { if (!CGProfile.empty()) { MCSection *CGProfileSection = getContext().getMachOSection( "__LLVM", "__cg_profile", 0, SectionKind::getMetadata()); - auto &Frag = cast(*CGProfileSection->begin()); + auto &Frag = *CGProfileSection->begin(); Frag.clearContents(); raw_svector_ostream OS(Frag.getContentsForAppending()); for (const MCObjectWriter::CGProfileEntry &CGPE : CGProfile) { @@ -895,7 +895,7 @@ void MachObjectWriter::writeMachOHeader(MCAssembler &Asm) { VMSize = std::max(VMSize, Address + Size); - if (Sec.isVirtualSection()) + if (Sec.isBssSection()) continue; SectionDataSize = std::max(SectionDataSize, Address + Size); @@ -938,7 +938,7 @@ void MachObjectWriter::writeMachOHeader(MCAssembler &Asm) { unsigned Flags = Sec.getTypeAndAttributes(); if (Sec.hasInstructions()) Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS; - if (!cast(Sec).isVirtualSection() && + if (!cast(Sec).isBssSection() && !isUInt<32>(SectionStart)) { getContext().reportError( SMLoc(), "cannot encode offset of section; object file too large"); diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 4c226d4420e1d..3b99af47eb45b 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -696,14 +696,15 @@ static void addData(SmallVectorImpl &DataBytes, if (Frag.hasInstructions()) report_fatal_error("only data supported in data sections"); - if (auto *Align = dyn_cast(&Frag)) { - if (Align->getFillLen() != 1) + llvm::append_range(DataBytes, Frag.getContents()); + if (Frag.getKind() == MCFragment::FT_Align) { + if (Frag.getAlignFillLen() != 1) report_fatal_error("only byte values supported for alignment"); // If nops are requested, use zeros, as this is the data section. - uint8_t Value = Align->hasEmitNops() ? 0 : Align->getFill(); + uint8_t Value = Frag.hasAlignEmitNops() ? 0 : Frag.getAlignFill(); uint64_t Size = - std::min(alignTo(DataBytes.size(), Align->getAlignment()), - DataBytes.size() + Align->getMaxBytesToEmit()); + std::min(alignTo(DataBytes.size(), Frag.getAlignment()), + DataBytes.size() + Frag.getAlignMaxBytesToEmit()); DataBytes.resize(Size, Value); } else if (auto *Fill = dyn_cast(&Frag)) { int64_t NumValues; @@ -711,10 +712,10 @@ static void addData(SmallVectorImpl &DataBytes, llvm_unreachable("The fill should be an assembler constant"); DataBytes.insert(DataBytes.end(), Fill->getValueSize() * NumValues, Fill->getValue()); - } else if (auto *LEB = dyn_cast(&Frag)) { - llvm::append_range(DataBytes, LEB->getContents()); + } else if (Frag.getKind() == MCFragment::FT_LEB) { + llvm::append_range(DataBytes, Frag.getVarContents()); } else { - llvm::append_range(DataBytes, cast(Frag).getContents()); + assert(Frag.getKind() == MCFragment::FT_Data); } } @@ -1856,23 +1857,9 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, auto IT = WS.begin(); if (IT == WS.end()) continue; - const MCFragment &EmptyFrag = *IT; - if (EmptyFrag.getKind() != MCFragment::FT_Data) - report_fatal_error(".init_array section should be aligned"); - - const MCFragment *nextFrag = EmptyFrag.getNext(); - while (nextFrag != nullptr) { - const MCFragment &AlignFrag = *nextFrag; - if (AlignFrag.getKind() != MCFragment::FT_Align) - report_fatal_error(".init_array section should be aligned"); - if (cast(AlignFrag).getAlignment() != - Align(is64Bit() ? 8 : 4)) - report_fatal_error( - ".init_array section should be aligned for pointers"); - - const MCFragment &Frag = *AlignFrag.getNext(); - nextFrag = Frag.getNext(); - if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data) + for (auto *Frag = &*IT; Frag; Frag = Frag->getNext()) { + if (Frag->hasInstructions() || (Frag->getKind() != MCFragment::FT_Align && + Frag->getKind() != MCFragment::FT_Data)) report_fatal_error("only data supported in .init_array section"); uint16_t Priority = UINT16_MAX; @@ -1884,9 +1871,8 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority)) report_fatal_error("invalid .init_array section priority"); } - const auto &DataFrag = cast(Frag); - assert(llvm::all_of(DataFrag.getContents(), [](char C) { return !C; })); - for (const MCFixup &Fixup : DataFrag.getFixups()) { + assert(llvm::all_of(Frag->getContents(), [](char C) { return !C; })); + for (const MCFixup &Fixup : Frag->getFixups()) { assert(Fixup.getKind() == MCFixup::getDataKindForSize(is64Bit() ? 8 : 4)); const MCExpr *Expr = Fixup.getValue(); diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index c2ef430984ed4..c69b8d669235f 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -179,7 +179,7 @@ class llvm::WinCOFFWriter { void SetSymbolName(COFFSymbol &S); void SetSectionName(COFFSection &S); - bool IsPhysicalSection(COFFSection *S); + bool isUninitializedData(const COFFSection &S); // Entity writing methods. void WriteFileHeader(const COFF::header &Header); @@ -453,8 +453,8 @@ void WinCOFFWriter::SetSymbolName(COFFSymbol &S) { std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size()); } -bool WinCOFFWriter::IsPhysicalSection(COFFSection *S) { - return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == +bool WinCOFFWriter::isUninitializedData(const COFFSection &S) { + return (S.Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0; } @@ -606,6 +606,9 @@ void WinCOFFWriter::writeSection(const COFFSection &Sec) { assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition); AuxSymbol &SecDef = AuxSyms[0]; SecDef.Aux.SectionDefinition.CheckSum = CRC; + } else if (isUninitializedData(Sec)) { + // Error if fixups or non-zero bytes are present. + writeSectionContents(*Sec.MCSection); } // Write relocations for this section. @@ -745,7 +748,7 @@ void WinCOFFWriter::assignFileOffsets() { Sec->Header.SizeOfRawData = Asm->getSectionAddressSize(Section); - if (IsPhysicalSection(Sec)) { + if (!isUninitializedData(*Sec)) { Sec->Header.PointerToRawData = Offset; Offset += Sec->Header.SizeOfRawData; } @@ -1069,7 +1072,7 @@ uint64_t WinCOFFWriter::writeObject() { if (Mode != DwoOnly && OWriter.getEmitAddrsigSection()) { auto *Sec = getContext().getCOFFSection(".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE); - auto *Frag = cast(Sec->curFragList()->Head); + auto *Frag = Sec->curFragList()->Head; raw_svector_ostream OS(Frag->getContentsForAppending()); for (const MCSymbol *S : OWriter.AddrsigSyms) { if (!S->isRegistered()) @@ -1092,7 +1095,7 @@ uint64_t WinCOFFWriter::writeObject() { if (Mode != DwoOnly && !OWriter.getCGProfile().empty()) { auto *Sec = getContext().getCOFFSection(".llvm.call-graph-profile", COFF::IMAGE_SCN_LNK_REMOVE); - auto *Frag = cast(Sec->curFragList()->Head); + auto *Frag = Sec->curFragList()->Head; raw_svector_ostream OS(Frag->getContentsForAppending()); for (const auto &CGPE : OWriter.getCGProfile()) { uint32_t FromIndex = CGPE.From->getSymbol().getIndex(); diff --git a/llvm/lib/MCCAS/MCCASObjectV1.cpp b/llvm/lib/MCCAS/MCCASObjectV1.cpp index e35dcf9985c4f..253152fea5c4e 100644 --- a/llvm/lib/MCCAS/MCCASObjectV1.cpp +++ b/llvm/lib/MCCAS/MCCASObjectV1.cpp @@ -1532,15 +1532,17 @@ Expected AtomRef::materialize(MCCASReader &Reader, } Expected -MCAlignFragmentRef::create(MCCASBuilder &MB, const MCAlignFragment &F, +MCAlignFragmentRef::create(MCCASBuilder &MB, const MCFragment &F, unsigned FragmentSize, ArrayRef FragmentContents) { Expected B = Builder::startNode(MB.Schema, KindString); if (!B) return B.takeError(); - uint64_t Count = FragmentSize / F.getFillLen(); - if (F.hasEmitNops()) { + writeVBR8(FragmentContents.size(), B->Data); + B->Data.append(FragmentContents.begin(), FragmentContents.end()); + uint64_t Count = (FragmentSize - F.getFixedSize()) / F.getAlignFillLen(); + if (F.hasAlignEmitNops()) { // Write 0 as size and use backend to emit nop. writeVBR8(0, B->Data); if (!MB.Asm.getBackend().writeNopData(MB.FragmentOS, Count, @@ -1551,23 +1553,31 @@ MCAlignFragmentRef::create(MCCASBuilder &MB, const MCAlignFragment &F, return get(B->build()); } writeVBR8(Count, B->Data); - writeVBR8(F.getFill(), B->Data); - writeVBR8(F.getFillLen(), B->Data); + writeVBR8(F.getAlignFill(), B->Data); + writeVBR8(F.getAlignFillLen(), B->Data); return get(B->build()); } Expected MCAlignFragmentRef::materialize(MCCASReader &Reader, - raw_ostream *Stream) const { - uint64_t Count; + raw_ostream *Stream) const + { + uint64_t Count, FragContentSize; auto Remaining = getData(); auto Endian = Reader.getEndian(); + if (auto E = consumeVBR8(Remaining, FragContentSize)) + return std::move(E); + + *Stream << Remaining.substr(0, FragContentSize); + + Remaining = Remaining.drop_front(FragContentSize); + if (auto E = consumeVBR8(Remaining, Count)) return std::move(E); // hasEmitNops. if (!Count) { *Stream << Remaining; - return Remaining.size(); + return Remaining.size() + FragContentSize; } int64_t Value; unsigned ValueSize; @@ -1594,12 +1604,13 @@ Expected MCAlignFragmentRef::materialize(MCCASReader &Reader, break; } } - return Count * ValueSize; + return (Count * ValueSize) + FragContentSize; } -Expected MCBoundaryAlignFragmentRef::create( - MCCASBuilder &MB, const MCBoundaryAlignFragment &F, unsigned FragmentSize, - ArrayRef FragmentContents) { +Expected +MCBoundaryAlignFragmentRef::create(MCCASBuilder &MB, const MCFragment &F, + unsigned FragmentSize, + ArrayRef FragmentContents) { Expected B = Builder::startNode(MB.Schema, KindString); if (!B) return B.takeError(); @@ -1618,9 +1629,10 @@ MCBoundaryAlignFragmentRef::materialize(MCCASReader &Reader, return getData().size(); } -Expected MCCVInlineLineTableFragmentRef::create( - MCCASBuilder &MB, const MCCVInlineLineTableFragment &F, - unsigned FragmentSize, ArrayRef FragmentContents) { +Expected +MCCVInlineLineTableFragmentRef::create(MCCASBuilder &MB, const MCFragment &F, + unsigned FragmentSize, + ArrayRef FragmentContents) { Expected B = Builder::startNode(MB.Schema, KindString); if (!B) return B.takeError(); @@ -1636,15 +1648,16 @@ MCCVInlineLineTableFragmentRef::materialize(MCCASReader &Reader, } Expected -MCFillFragmentRef::create(MCCASBuilder &MB, const MCFillFragment &F, +MCFillFragmentRef::create(MCCASBuilder &MB, const MCFragment &F, unsigned FragmentSize, ArrayRef FragmentContents) { + auto *FillFrag = dyn_cast(&F); Expected B = Builder::startNode(MB.Schema, KindString); if (!B) return B.takeError(); writeVBR8(FragmentSize, B->Data); - writeVBR8(F.getValue(), B->Data); - writeVBR8(F.getValueSize(), B->Data); + writeVBR8(FillFrag->getValue(), B->Data); + writeVBR8(FillFrag->getValueSize(), B->Data); return get(B->build()); } @@ -1686,7 +1699,7 @@ Expected MCFillFragmentRef::materialize(MCCASReader &Reader, } Expected -MCLEBFragmentRef::create(MCCASBuilder &MB, const MCLEBFragment &F, +MCLEBFragmentRef::create(MCCASBuilder &MB, const MCFragment &F, unsigned FragmentSize, ArrayRef FragmentContents) { Expected B = Builder::startNode(MB.Schema, KindString); @@ -1703,14 +1716,15 @@ Expected MCLEBFragmentRef::materialize(MCCASReader &Reader, } Expected -MCNopsFragmentRef::create(MCCASBuilder &MB, const MCNopsFragment &F, +MCNopsFragmentRef::create(MCCASBuilder &MB, const MCFragment &F, unsigned FragmentSize, ArrayRef FragmentContents) { + auto *NopsFrag = dyn_cast(&F); Expected B = Builder::startNode(MB.Schema, KindString); if (!B) return B.takeError(); - int64_t NumBytes = F.getNumBytes(); - int64_t ControlledNopLength = F.getControlledNopLength(); + int64_t NumBytes = NopsFrag->getNumBytes(); + int64_t ControlledNopLength = NopsFrag->getControlledNopLength(); int64_t MaximumNopLength = MB.Asm.getBackend().getMaximumNopSize(*F.getSubtargetInfo()); if (ControlledNopLength > MaximumNopLength) @@ -1739,14 +1753,15 @@ Expected MCNopsFragmentRef::materialize(MCCASReader &Reader, } Expected -MCOrgFragmentRef::create(MCCASBuilder &MB, const MCOrgFragment &F, +MCOrgFragmentRef::create(MCCASBuilder &MB, const MCFragment &F, unsigned FragmentSize, ArrayRef FragmentContents) { + auto *OrgFrag = dyn_cast(&F); Expected B = Builder::startNode(MB.Schema, KindString); if (!B) return B.takeError(); writeVBR8(FragmentSize, B->Data); - writeVBR8((char)F.getValue(), B->Data); + writeVBR8((char)OrgFrag->getValue(), B->Data); return get(B->build()); } @@ -1757,13 +1772,14 @@ Expected MCOrgFragmentRef::materialize(MCCASReader &Reader, } Expected -MCSymbolIdFragmentRef::create(MCCASBuilder &MB, const MCSymbolIdFragment &F, +MCSymbolIdFragmentRef::create(MCCASBuilder &MB, const MCFragment &F, unsigned FragmentSize, ArrayRef FragmentContents) { + auto *SymbolIDFrag = dyn_cast(&F); Expected B = Builder::startNode(MB.Schema, KindString); if (!B) return B.takeError(); - writeVBR8(F.getSymbol()->getIndex(), B->Data); + writeVBR8(SymbolIDFrag->getSymbol()->getIndex(), B->Data); return get(B->build()); } @@ -1776,12 +1792,11 @@ MCSymbolIdFragmentRef::materialize(MCCASReader &Reader, #define MCFRAGMENT_NODE_REF(MCFragmentName, MCEnumName, MCEnumIdentifier) \ Expected MCFragmentName##Ref::create( \ - MCCASBuilder &MB, const MCFragmentName &F, unsigned FragmentSize, \ + MCCASBuilder &MB, const MCFragment &F, unsigned FragmentSize, \ ArrayRef FragmentContents) { \ Expected B = Builder::startNode(MB.Schema, KindString); \ if (!B) \ return B.takeError(); \ - MB.Asm.writeFragmentPadding(MB.FragmentOS, F, FragmentSize); \ B->Data.append(MB.FragmentData); \ B->Data.append(FragmentContents.begin(), FragmentContents.end()); \ assert( \ @@ -1850,8 +1865,7 @@ Error MCCASBuilder::buildFragment(const MCFragment &F, unsigned Size, switch (F.getKind()) { #define MCFRAGMENT_NODE_REF(MCFragmentName, MCEnumName, MCEnumIdentifier) \ case MCFragment::MCEnumName: { \ - const MCFragmentName &SF = cast(F); \ - auto FN = MCFragmentName##Ref::create(*this, SF, Size, FragmentContents); \ + auto FN = MCFragmentName##Ref::create(*this, F, Size, FragmentContents); \ if (!FN) \ return FN.takeError(); \ addNode(*FN); \ @@ -1888,7 +1902,7 @@ Error MCDataFragmentMerger::tryMerge(const MCFragment &F, unsigned Size, bool Oversized = CurrentSize + Size > MCDataMergeThreshold; // TODO: Try merge align fragment? bool IsMergeableFragment = - isa(F) || isa(F); + F.isEncoded() || F.getKind() == MCFragment::FT_Align; // If not the same atom, flush merge candidate and return false. if (!IsSameAtom || !IsMergeableFragment || Oversized) { if (auto E = emitMergedFragments()) @@ -1920,11 +1934,11 @@ Error MCDataFragmentMerger::tryMerge(const MCFragment &F, unsigned Size, return Error::success(); } -static Error writeAlignFragment(MCCASBuilder &Builder, - const MCAlignFragment &AF, raw_ostream &OS, - unsigned FragmentSize) { - uint64_t Count = FragmentSize / AF.getFillLen(); - if (AF.hasEmitNops()) { +static Error writeAlignFragment(MCCASBuilder &Builder, const MCFragment &AF, + raw_ostream &OS, unsigned FragmentSize) { + OS << StringRef(AF.getContents().data(), AF.getContents().size()); + uint64_t Count = (FragmentSize - AF.getFixedSize()) / AF.getAlignFillLen(); + if (AF.hasAlignEmitNops()) { if (!Builder.Asm.getBackend().writeNopData(OS, Count, AF.getSubtargetInfo())) return createStringError(inconvertibleErrorCode(), @@ -1935,20 +1949,20 @@ static Error writeAlignFragment(MCCASBuilder &Builder, auto Endian = Builder.ObjectWriter.Target.isLittleEndian() ? endianness::little : endianness::big; for (uint64_t I = 0; I != Count; ++I) { - switch (AF.getFillLen()) { + switch (AF.getAlignFillLen()) { default: llvm_unreachable("Invalid size!"); case 1: - OS << char(AF.getFill()); + OS << char(AF.getAlignFill()); break; case 2: - support::endian::write(OS, AF.getFill(), Endian); + support::endian::write(OS, AF.getAlignFill(), Endian); break; case 4: - support::endian::write(OS, AF.getFill(), Endian); + support::endian::write(OS, AF.getAlignFill(), Endian); break; case 8: - support::endian::write(OS, AF.getFill(), Endian); + support::endian::write(OS, AF.getAlignFill(), Endian); break; } } @@ -1974,17 +1988,14 @@ Error MCDataFragmentMerger::emitMergedFragments() { switch (Candidate.first->getKind()) { #define MCFRAGMENT_NODE_REF(MCFragmentName, MCEnumName, MCEnumIdentifier) \ case MCFragment::MCEnumName: { \ - const MCFragmentName *SF = cast(Candidate.first); \ - Builder.Asm.writeFragmentPadding(FragmentOS, *SF, Candidate.second); \ FragmentData.append(CandidateContents); \ break; \ } #define MCFRAGMENT_ENCODED_FRAGMENT_ONLY #include "llvm/MCCAS/MCCASObjectV1.def" case MCFragment::FT_Align: { - const MCAlignFragment *AF = cast(Candidate.first); - if (auto E = - writeAlignFragment(Builder, *AF, FragmentOS, Candidate.second)) + if (auto E = writeAlignFragment(Builder, *Candidate.first, FragmentOS, + Candidate.second)) return E; break; } @@ -2128,39 +2139,27 @@ MCCASBuilder::mergeMCFragmentContents(const MCSection *Section, bool IsDebugLineSection) { SmallVector mergedData; for (const MCFragment &Fragment : *Section) { - if (const auto *DataFragment = dyn_cast(&Fragment)) - llvm::append_range(mergedData, DataFragment->getContents()); - else if (const auto *RelaxableFragment = - dyn_cast(&Fragment)) - llvm::append_range(mergedData, RelaxableFragment->getContents()); - else if (const auto *DwarfLineAddrFrag = - dyn_cast(&Fragment)) + if (Fragment.getKind() == MCFragment::FT_Dwarf) if (IsDebugLineSection) - llvm::append_range(mergedData, DwarfLineAddrFrag->getContents()); + llvm::append_range(mergedData, Fragment.getContents()); else return createStringError( inconvertibleErrorCode(), - "Invalid MCDwarfLineAddrFragment in a non debug line section"); - else if (const auto *DwarfCallFrameFragment = - dyn_cast(&Fragment)) - llvm::append_range(mergedData, DwarfCallFrameFragment->getContents()); + "Invalid MCFragment::FT_Dwarf type in a non debug line section"); else if (const auto *CVDefRangeFragment = dyn_cast(&Fragment)) llvm::append_range(mergedData, CVDefRangeFragment->getContents()); - else if (const auto *PseudoProbeAddrFragment = - dyn_cast(&Fragment)) - llvm::append_range(mergedData, PseudoProbeAddrFragment->getContents()); - else if (const auto *LEBFragment = dyn_cast(&Fragment)) - llvm::append_range(mergedData, LEBFragment->getContents()); else if (const auto *CVInlineLineTableFragment = dyn_cast(&Fragment)) llvm::append_range(mergedData, CVInlineLineTableFragment->getContents()); - else if (const auto *AlignFragment = dyn_cast(&Fragment)) { + else if (Fragment.getKind() == MCFragment::FT_Align) { auto FragmentSize = Asm.computeFragmentSize(Fragment); raw_svector_ostream OS(mergedData); - if (auto E = writeAlignFragment(*this, *AlignFragment, OS, FragmentSize)) + if (auto E = writeAlignFragment(*this, Fragment, OS, FragmentSize)) return std::move(E); - } else + } else if (Fragment.getFixedSize() != 0) + llvm::append_range(mergedData, Fragment.getContents()); + else // All other fragment types can be considered empty, see // getFragmentContents() for all fragments that have contents. continue; @@ -2611,7 +2610,7 @@ Expected> MCCASBuilder::createDebugStringRefs() { SmallVector DebugStringRefs; ArrayRef DebugStrData = - cast(*DwarfSections.Str->begin()).getContents(); + cast(*DwarfSections.Str->begin()).getContents(); StringRef S(DebugStrData.data(), DebugStrData.size()); if (auto E = createStringSection(S, [&](StringRef S) -> Error { auto Sym = DebugStrRef::create(*this, S); @@ -2863,26 +2862,38 @@ Error MCCASBuilder::createAppleObjCSection() { return finalizeSection(); } -static ArrayRef getFragmentContents(const MCFragment &Fragment) { +static void getFragmentContents(const MCFragment &Fragment, + SmallVectorImpl &FragContents) { switch (Fragment.getKind()) { #define MCFRAGMENT_NODE_REF(MCFragmentName, MCEnumName, MCEnumIdentifier) \ case MCFragment::MCEnumName: { \ - const MCFragmentName &SF = cast(Fragment); \ - return SF.getContents(); \ + FragContents.append(Fragment.getContents().begin(), \ + Fragment.getContents().end()); \ + \ + return; \ } #define MCFRAGMENT_ENCODED_FRAGMENT_ONLY #include "llvm/MCCAS/MCCASObjectV1.def" case MCFragment::FT_CVInlineLines: { const MCCVInlineLineTableFragment &SF = cast(Fragment); - return SF.getContents(); + FragContents.append(SF.getContents().begin(), SF.getContents().end()); + return; } case MCFragment::FT_LEB: { - const MCLEBFragment &SF = cast(Fragment); - return SF.getContents(); + auto FixedContent = Fragment.getContents(); + auto VarContent = Fragment.getVarContents(); + FragContents.append(FixedContent.begin(), FixedContent.end()); + FragContents.append(VarContent.begin(), VarContent.end()); + return; + } + case MCFragment::FT_Align: { + FragContents.append(Fragment.getContents().begin(), + Fragment.getContents().end()); + return; } default: - return ArrayRef(); + return; } } @@ -2914,7 +2925,8 @@ partitionFragment(MCAssembler &Asm, SmallVector &Addends, ArrayRef RelocationBuffer, const MCFragment &Fragment, uint64_t &RelocationBufferIndex, bool IsLittleEndian) { - auto FragmentContents = getFragmentContents(Fragment); + SmallVector FragmentContents; + getFragmentContents(Fragment, FragmentContents); /// FragmentIndex: It denotes the index into the FragmentContents that is used /// to copy the data that deduplicates in the \p FinalFragmentContents. uint64_t FragmentIndex = 0; @@ -2963,7 +2975,7 @@ Error MCCASBuilder::buildFragments() { startGroup(); for (const MCSection &Sec : Asm) { - if (Sec.isVirtualSection()) + if (Sec.isBssSection()) continue; // Handle Debug Info sections separately. diff --git a/llvm/lib/ObjCopy/MachO/MachOObject.h b/llvm/lib/ObjCopy/MachO/MachOObject.h index 8f9444f5fb025..86c6b120fa6c3 100644 --- a/llvm/lib/ObjCopy/MachO/MachOObject.h +++ b/llvm/lib/ObjCopy/MachO/MachOObject.h @@ -64,14 +64,14 @@ struct Section { return static_cast(Flags & MachO::SECTION_TYPE); } - bool isVirtualSection() const { + bool isBssSection() const { return (getType() == MachO::S_ZEROFILL || getType() == MachO::S_GB_ZEROFILL || getType() == MachO::S_THREAD_LOCAL_ZEROFILL); } bool hasValidOffset() const { - return !(isVirtualSection() || OriginalOffset == 0); + return !(isBssSection() || OriginalOffset == 0); } }; diff --git a/llvm/lib/ObjCopy/MachO/MachOWriter.cpp b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp index 7c24d1277dc8d..89c1df8699298 100644 --- a/llvm/lib/ObjCopy/MachO/MachOWriter.cpp +++ b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp @@ -112,7 +112,7 @@ size_t MachOWriter::totalSize() const { for (const std::unique_ptr
&S : LC.Sections) { if (!S->hasValidOffset()) { assert((S->Offset == 0) && "Skipped section's offset must be zero"); - assert((S->isVirtualSection() || S->Size == 0) && + assert((S->isBssSection() || S->Size == 0) && "Non-zero-fill sections with zero offset must have zero size"); continue; } @@ -240,7 +240,7 @@ void MachOWriter::writeSections() { for (const std::unique_ptr
&Sec : LC.Sections) { if (!Sec->hasValidOffset()) { assert((Sec->Offset == 0) && "Skipped section's offset must be zero"); - assert((Sec->isVirtualSection() || Sec->Size == 0) && + assert((Sec->isBssSection() || Sec->Size == 0) && "Non-zero-fill sections with zero offset must have zero size"); continue; } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp index f2144375fd95e..08f547a85073e 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -529,11 +529,9 @@ void AArch64TargetELFStreamer::finish() { static_cast(Ctx.getObjectFileInfo()->getTextSection()); bool Empty = true; for (auto &F : *Text) { - if (auto *DF = dyn_cast(&F)) { - if (!DF->getContents().empty()) { - Empty = false; - break; - } + if (F.getSize()) { + Empty = false; + break; } } if (Empty) @@ -561,8 +559,7 @@ void AArch64TargetELFStreamer::finish() { if (!Sym.isMemtag()) continue; auto *SRE = MCSymbolRefExpr::create(&Sym, Ctx); - (void)S.emitRelocDirective(*Zero, "BFD_RELOC_NONE", SRE, SMLoc(), - *Ctx.getSubtargetInfo()); + S.emitRelocDirective(*Zero, "BFD_RELOC_NONE", SRE); } } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 164acdec4544b..146fc6704c6da 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -311,7 +311,8 @@ static bool needsInterworking(const MCAssembler &Asm, const MCSymbol *Sym, return false; } -bool ARMAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, +bool ARMAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &, + const MCFixup &Fixup, const MCValue &Target, uint64_t Value, bool Resolved) const { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h index 877e3afdb1d57..07d2cf784c442 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -51,7 +51,8 @@ class ARMAsmBackend : public MCAsmBackend { const char *reasonForFixupRelaxation(const MCFixup &Fixup, uint64_t Value) const; - bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t, + bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, + const MCValue &, uint64_t, bool) const override; void relaxInstruction(MCInst &Inst, diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index c61e405bd3a02..a7a9911de2d04 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -593,7 +593,7 @@ class ARMELFStreamer : public MCELFStreamer { getContext().reportError(Loc, "relocated expression must be 32-bit"); return; } - getOrCreateDataFragment(); + getCurrentFragment(); } emitDataMappingSymbol(); @@ -638,7 +638,7 @@ class ARMELFStreamer : public MCELFStreamer { Offset = 0; } bool hasInfo() { return F != nullptr; } - MCDataFragment *F = nullptr; + MCFragment *F = nullptr; uint64_t Offset = 0; ElfMappingSymbol State = EMS_None; }; @@ -650,11 +650,11 @@ class ARMELFStreamer : public MCELFStreamer { // This is a tentative symbol, it won't really be emitted until it's // actually needed. ElfMappingSymbolInfo *EMS = LastEMSInfo.get(); - auto *DF = dyn_cast_or_null(getCurrentFragment()); - if (!DF) + auto *DF = getCurrentFragment(); + if (DF->getKind() != MCFragment::FT_Data) return; EMS->F = DF; - EMS->Offset = DF->getContents().size(); + EMS->Offset = DF->getFixedSize(); LastEMSInfo->State = EMS_Data; return; } @@ -686,7 +686,7 @@ class ARMELFStreamer : public MCELFStreamer { Symbol->setBinding(ELF::STB_LOCAL); } - void emitMappingSymbol(StringRef Name, MCDataFragment &F, uint64_t Offset) { + void emitMappingSymbol(StringRef Name, MCFragment &F, uint64_t Offset) { auto *Symbol = cast(getContext().createLocalSymbol(Name)); emitLabelAtPos(Symbol, SMLoc(), F, Offset); Symbol->setType(ELF::STT_NOTYPE); @@ -1145,9 +1145,8 @@ void ARMTargetELFStreamer::finish() { auto *Text = static_cast(Ctx.getObjectFileInfo()->getTextSection()); for (auto &F : *Text) - if (auto *DF = dyn_cast(&F)) - if (!DF->getContents().empty()) - return; + if (F.getSize()) + return; Text->setFlags(Text->getFlags() | ELF::SHF_ARM_PURECODE); } } @@ -1208,7 +1207,7 @@ inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) { } void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) { - MCDataFragment *Frag = getOrCreateDataFragment(); + MCFragment *Frag = getCurrentFragment(); Frag->addFixup(MCFixup::create(Frag->getContents().size(), Expr, Kind)); } @@ -1296,7 +1295,7 @@ void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { MCSymbolRefExpr::create(PersonalitySym, ARM::S_ARM_NONE, getContext()); visitUsedExpr(*PersonalityRef); - MCDataFragment *DF = getOrCreateDataFragment(); + MCFragment *DF = getCurrentFragment(); DF->addFixup( MCFixup::create(DF->getContents().size(), PersonalityRef, FK_Data_4)); } diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp index 062b4356420ab..694d9eab9694b 100644 --- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp +++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp @@ -157,7 +157,8 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, } } -bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, +bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &, + const MCFixup &Fixup, const MCValue &, uint64_t Value, bool Resolved) const { diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h index 1d3a22c2bbbb4..1c8516fbf53a7 100644 --- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h +++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h @@ -38,7 +38,8 @@ class CSKYAsmBackend : public MCAsmBackend { void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; - bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t, + bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, + const MCValue &, uint64_t, bool) const override; bool writeNopData(raw_ostream &OS, uint64_t Count, diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp index 287bdc5bfd4d4..7d3074ba6b5d2 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -46,16 +46,15 @@ class HexagonAsmBackend : public MCAsmBackend { MCInst * Extender; unsigned MaxPacketSize; - void ReplaceInstruction(MCCodeEmitter &E, MCRelaxableFragment &RF, - MCInst &HMB) const { + void ReplaceInstruction(MCCodeEmitter &E, MCFragment &RF, MCInst &HMB) const { SmallVector Fixups; SmallString<256> Code; E.encodeInstruction(HMB, Code, Fixups, *RF.getSubtargetInfo()); // Update the fragment. RF.setInst(HMB); - RF.setContents(Code); - RF.getFixups() = Fixups; + RF.setVarContents(Code); + RF.setVarFixups(Fixups); } public: @@ -438,15 +437,15 @@ class HexagonAsmBackend : public MCAsmBackend { /// fixupNeedsRelaxation - Target specific predicate for whether a given /// fixup requires the associated instruction to be relaxed. - bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, const MCValue &, - uint64_t Value, + bool fixupNeedsRelaxationAdvanced(const MCFragment &F, const MCFixup &Fixup, + const MCValue &, uint64_t Value, bool Resolved) const override { MCInst const &MCB = RelaxedMCB; assert(HexagonMCInstrInfo::isBundle(MCB)); *RelaxTarget = nullptr; MCInst &MCI = const_cast(HexagonMCInstrInfo::instruction( - MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE)); + MCB, (Fixup.getOffset() - F.getFixedSize()) / HEXAGON_INSTR_SIZE)); bool Relaxable = isInstRelaxable(MCI); if (Relaxable == false) return false; @@ -595,7 +594,7 @@ class HexagonAsmBackend : public MCAsmBackend { } case MCFragment::FT_Relaxable: { MCContext &Context = getContext(); - auto &RF = cast(*Frags[K]); + auto &RF = *Frags[K]; MCInst Inst = RF.getInst(); const bool WouldTraverseLabel = llvm::any_of( diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp index 3dbf7683cdade..8fa72bc9a30a7 100644 --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp @@ -177,74 +177,6 @@ void LoongArchAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup, } } -// Linker relaxation may change code size. We have to insert Nops -// for .align directive when linker relaxation enabled. So then Linker -// could satisfy alignment by removing Nops. -// The function returns the total Nops Size we need to insert. -bool LoongArchAsmBackend::shouldInsertExtraNopBytesForCodeAlign( - const MCAlignFragment &AF, unsigned &Size) { - // Calculate Nops Size only when linker relaxation enabled. - if (!AF.getSubtargetInfo()->hasFeature(LoongArch::FeatureRelax)) - return false; - - // Ignore alignment if MaxBytesToEmit is less than the minimum Nop size. - const unsigned MinNopLen = 4; - if (AF.getMaxBytesToEmit() < MinNopLen) - return false; - Size = AF.getAlignment().value() - MinNopLen; - return AF.getAlignment() > MinNopLen; -} - -// We need to insert R_LARCH_ALIGN relocation type to indicate the -// position of Nops and the total bytes of the Nops have been inserted -// when linker relaxation enabled. -// The function inserts fixup_loongarch_align fixup which eventually will -// transfer to R_LARCH_ALIGN relocation type. -// The improved R_LARCH_ALIGN requires symbol index. The lowest 8 bits of -// addend represent alignment and the other bits of addend represent the -// maximum number of bytes to emit. The maximum number of bytes is zero -// means ignore the emit limit. -bool LoongArchAsmBackend::shouldInsertFixupForCodeAlign(MCAssembler &Asm, - MCAlignFragment &AF) { - // Insert the fixup only when linker relaxation enabled. - if (!AF.getSubtargetInfo()->hasFeature(LoongArch::FeatureRelax)) - return false; - - // Calculate total Nops we need to insert. If there are none to insert - // then simply return. - unsigned InsertedNopBytes; - if (!shouldInsertExtraNopBytesForCodeAlign(AF, InsertedNopBytes)) - return false; - - MCSection *Sec = AF.getParent(); - MCContext &Ctx = getContext(); - const MCExpr *Dummy = MCConstantExpr::create(0, Ctx); - MCFixup Fixup = MCFixup::create(0, Dummy, ELF::R_LARCH_ALIGN); - unsigned MaxBytesToEmit = AF.getMaxBytesToEmit(); - - auto createExtendedValue = [&]() { - const MCSymbolRefExpr *MCSym = getSecToAlignSym()[Sec]; - if (MCSym == nullptr) { - // Define a marker symbol at the section with an offset of 0. - MCSymbol *Sym = Ctx.createNamedTempSymbol("la-relax-align"); - Sym->setFragment(&*Sec->getBeginSymbol()->getFragment()); - Asm.registerSymbol(*Sym); - MCSym = MCSymbolRefExpr::create(Sym, Ctx); - getSecToAlignSym()[Sec] = MCSym; - } - return MCValue::get(&MCSym->getSymbol(), nullptr, - MaxBytesToEmit << 8 | Log2(AF.getAlignment())); - }; - - uint64_t FixedValue = 0; - MCValue Value = MaxBytesToEmit >= InsertedNopBytes - ? MCValue::get(InsertedNopBytes) - : createExtendedValue(); - Asm.getWriter().recordRelocation(AF, Fixup, Value, FixedValue); - - return true; -} - bool LoongArchAsmBackend::shouldForceRelocation(const MCFixup &Fixup, const MCValue &Target) { switch (Fixup.getKind()) { @@ -279,23 +211,70 @@ getRelocPairForSize(unsigned Size) { } } -std::pair LoongArchAsmBackend::relaxLEB128(MCLEBFragment &LF, +// Check if an R_LARCH_ALIGN relocation is needed for an alignment directive. +// If conditions are met, compute the padding size and create a fixup encoding +// the padding size in the addend. If MaxBytesToEmit is smaller than the padding +// size, the fixup encodes MaxBytesToEmit in the higher bits and references a +// per-section marker symbol. +bool LoongArchAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) { + // Use default handling unless linker relaxation is enabled and the + // MaxBytesToEmit >= the nop size. + if (!F.getSubtargetInfo()->hasFeature(LoongArch::FeatureRelax)) + return false; + const unsigned MinNopLen = 4; + unsigned MaxBytesToEmit = F.getAlignMaxBytesToEmit(); + if (MaxBytesToEmit < MinNopLen) + return false; + + Size = F.getAlignment().value() - MinNopLen; + if (F.getAlignment() <= MinNopLen) + return false; + + MCContext &Ctx = getContext(); + const MCExpr *Expr = nullptr; + if (MaxBytesToEmit >= Size) { + Expr = MCConstantExpr::create(Size, getContext()); + } else { + MCSection *Sec = F.getParent(); + const MCSymbolRefExpr *SymRef = getSecToAlignSym()[Sec]; + if (SymRef == nullptr) { + // Define a marker symbol at the section with an offset of 0. + MCSymbol *Sym = Ctx.createNamedTempSymbol("la-relax-align"); + Sym->setFragment(&*Sec->getBeginSymbol()->getFragment()); + Asm->registerSymbol(*Sym); + SymRef = MCSymbolRefExpr::create(Sym, Ctx); + getSecToAlignSym()[Sec] = SymRef; + } + Expr = MCBinaryExpr::createAdd( + SymRef, + MCConstantExpr::create((MaxBytesToEmit << 8) | Log2(F.getAlignment()), + Ctx), + Ctx); + } + MCFixup Fixup = + MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN); + F.setVarFixups({Fixup}); + F.getParent()->setLinkerRelaxable(); + return true; +} + +std::pair LoongArchAsmBackend::relaxLEB128(MCFragment &F, int64_t &Value) const { - const MCExpr &Expr = LF.getValue(); - if (LF.isSigned() || !Expr.evaluateKnownAbsolute(Value, *Asm)) + const MCExpr &Expr = F.getLEBValue(); + if (F.isLEBSigned() || !Expr.evaluateKnownAbsolute(Value, *Asm)) return std::make_pair(false, false); - LF.addFixup(MCFixup::create(0, &Expr, FK_Data_leb128)); + F.setVarFixups({MCFixup::create(0, &Expr, FK_Data_leb128)}); return std::make_pair(true, true); } -bool LoongArchAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, +bool LoongArchAsmBackend::relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const { MCContext &C = getContext(); - int64_t LineDelta = DF.getLineDelta(); - const MCExpr &AddrDelta = DF.getAddrDelta(); + int64_t LineDelta = F.getDwarfLineDelta(); + const MCExpr &AddrDelta = F.getDwarfAddrDelta(); SmallVector Fixups; - size_t OldSize = DF.getContents().size(); + size_t OldSize = F.getVarSize(); int64_t Value; if (AddrDelta.evaluateAsAbsolute(Value, *Asm)) @@ -349,17 +328,16 @@ bool LoongArchAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, OS << uint8_t(dwarf::DW_LNS_copy); } - DF.setContents(Data); - DF.setFixups(Fixups); + F.setVarContents(Data); + F.setVarFixups(Fixups); WasRelaxed = OldSize != Data.size(); return true; } -bool LoongArchAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF, - bool &WasRelaxed) const { - const MCExpr &AddrDelta = DF.getAddrDelta(); +bool LoongArchAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const { + const MCExpr &AddrDelta = F.getDwarfAddrDelta(); SmallVector Fixups; - size_t OldSize = DF.getContents().size(); + size_t OldSize = F.getVarContents().size(); int64_t Value; if (AddrDelta.evaluateAsAbsolute(Value, *Asm)) @@ -371,9 +349,9 @@ bool LoongArchAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF, assert(getContext().getAsmInfo()->getMinInstAlignment() == 1 && "expected 1-byte alignment"); if (Value == 0) { - DF.clearContents(); - DF.clearFixups(); - WasRelaxed = OldSize != DF.getContents().size(); + F.clearVarContents(); + F.clearVarFixups(); + WasRelaxed = OldSize != 0; return true; } @@ -405,8 +383,8 @@ bool LoongArchAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF, } else { llvm_unreachable("unsupported CFA encoding"); } - DF.setContents(Data); - DF.setFixups(Fixups); + F.setVarContents(Data); + F.setVarFixups(Fixups); WasRelaxed = OldSize != Data.size(); return true; @@ -435,7 +413,7 @@ bool LoongArchAsmBackend::isPCRelFixupResolved(const MCSymbol *SymA, // Otherwise, check if the offset between the symbol and fragment is fully // resolved, unaffected by linker-relaxable fragments (e.g. instructions or - // offset-affected MCAlignFragment). Complements the generic + // offset-affected FT_Align fragments). Complements the generic // isSymbolRefDifferenceFullyResolvedImpl. if (!PCRelTemp) PCRelTemp = getContext().createTempSymbol(); diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h index 4446cadf11e22..3d929fc49f95e 100644 --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h @@ -45,25 +45,16 @@ class LoongArchAsmBackend : public MCAsmBackend { MutableArrayRef Data, uint64_t Value, bool IsResolved) override; - // Return Size with extra Nop Bytes for alignment directive in code section. - bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF, - unsigned &Size) override; - - // Insert target specific fixup type for alignment directive in code section. - bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, - MCAlignFragment &AF) override; - bool shouldForceRelocation(const MCFixup &Fixup, const MCValue &Target); std::optional getFixupKind(StringRef Name) const override; MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override; - bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, - bool &WasRelaxed) const override; - bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, - bool &WasRelaxed) const override; - std::pair relaxLEB128(MCLEBFragment &LF, + bool relaxAlign(MCFragment &F, unsigned &Size) override; + bool relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const override; + bool relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const override; + std::pair relaxLEB128(MCFragment &F, int64_t &Value) const override; bool writeNopData(raw_ostream &OS, uint64_t Count, diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 01e4d17f6236d..259b71b37d9a3 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -2101,7 +2101,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, TOut.getStreamer().emitRelocDirective( *TmpExpr, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR", - RelocJalrExpr, IDLoc, *STI); + RelocJalrExpr); TOut.getStreamer().emitLabel(TmpLabel); } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index c69fc68ab5af1..5c7f34b870847 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -1033,42 +1033,42 @@ MCELFStreamer &MipsTargetELFStreamer::getStreamer() { } void MipsTargetELFStreamer::emitGPRel32Value(const MCExpr *Value) { - MCDataFragment *DF = getStreamer().getOrCreateDataFragment(); + MCFragment *DF = getStreamer().getCurrentFragment(); DF->addFixup(MCFixup::create(DF->getContents().size(), Value, Mips::fixup_Mips_GPREL32)); DF->appendContents(4, 0); } void MipsTargetELFStreamer::emitGPRel64Value(const MCExpr *Value) { - MCDataFragment *DF = getStreamer().getOrCreateDataFragment(); + MCFragment *DF = getStreamer().getCurrentFragment(); DF->addFixup(MCFixup::create(DF->getContents().size(), Value, Mips::fixup_Mips_GPREL32)); DF->appendContents(8, 0); } void MipsTargetELFStreamer::emitDTPRel32Value(const MCExpr *Value) { - MCDataFragment *DF = getStreamer().getOrCreateDataFragment(); + MCFragment *DF = getStreamer().getCurrentFragment(); DF->addFixup(MCFixup::create(DF->getContents().size(), Value, Mips::fixup_Mips_DTPREL32)); DF->appendContents(4, 0); } void MipsTargetELFStreamer::emitDTPRel64Value(const MCExpr *Value) { - MCDataFragment *DF = getStreamer().getOrCreateDataFragment(); + MCFragment *DF = getStreamer().getCurrentFragment(); DF->addFixup(MCFixup::create(DF->getContents().size(), Value, Mips::fixup_Mips_DTPREL64)); DF->appendContents(8, 0); } void MipsTargetELFStreamer::emitTPRel32Value(const MCExpr *Value) { - MCDataFragment *DF = getStreamer().getOrCreateDataFragment(); + MCFragment *DF = getStreamer().getCurrentFragment(); DF->addFixup(MCFixup::create(DF->getContents().size(), Value, Mips::fixup_Mips_TPREL32)); DF->appendContents(4, 0); } void MipsTargetELFStreamer::emitTPRel64Value(const MCExpr *Value) { - MCDataFragment *DF = getStreamer().getOrCreateDataFragment(); + MCFragment *DF = getStreamer().getCurrentFragment(); DF->addFixup(MCFixup::create(DF->getContents().size(), Value, Mips::fixup_Mips_TPREL64)); DF->appendContents(8, 0); diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index c18ba44bea08e..ca0331006be74 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -166,7 +166,7 @@ static void emitDirectiveRelocJalr(const MachineInstr &MI, OutStreamer.emitRelocDirective( *OffsetExpr, Subtarget.inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR", - CaleeExpr, SMLoc(), *TM.getMCSubtargetInfo()); + CaleeExpr); OutStreamer.emitLabel(OffsetLabel); return; } diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp index ee99cfc7d655d..2dbc31fce72c2 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp @@ -155,11 +155,10 @@ void PPCELFStreamer::emitGOTToPCRelReloc(const MCInst &Inst) { const MCExpr *SubExpr2 = MCBinaryExpr::createSub(CurrentLocationExpr, SubExpr, getContext()); - MCDataFragment *DF = static_cast(LabelSym->getFragment()); - assert(DF && "Expecting a valid data fragment."); - MCFixupKind FixupKind = static_cast(FirstLiteralRelocationKind + - ELF::R_PPC64_PCREL_OPT); - DF->addFixup(MCFixup::create(LabelSym->getOffset() - 8, SubExpr2, FixupKind)); + MCFragment *F = LabelSym->getFragment(); + F->addFixup( + MCFixup::create(LabelSym->getOffset() - 8, SubExpr2, + FirstLiteralRelocationKind + ELF::R_PPC64_PCREL_OPT)); emitLabel(CurrentLocation, Inst.getLoc()); } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index e42d6c539a349..2c37c3bfd0fe3 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -104,7 +104,8 @@ MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { return Infos[Kind - FirstTargetFixupKind]; } -bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, +bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &, + const MCFixup &Fixup, const MCValue &, uint64_t Value, bool Resolved) const { @@ -301,14 +302,36 @@ void RISCVAsmBackend::relaxInstruction(MCInst &Inst, Inst = std::move(Res); } -bool RISCVAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, +// Check if an R_RISCV_ALIGN relocation is needed for an alignment directive. +// If conditions are met, compute the padding size and create a fixup encoding +// the padding size in the addend. +bool RISCVAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) { + // Use default handling unless linker relaxation is enabled and the alignment + // is larger than the nop size. + const MCSubtargetInfo *STI = F.getSubtargetInfo(); + if (!STI->hasFeature(RISCV::FeatureRelax)) + return false; + unsigned MinNopLen = STI->hasFeature(RISCV::FeatureStdExtZca) ? 2 : 4; + if (F.getAlignment() <= MinNopLen) + return false; + + Size = F.getAlignment().value() - MinNopLen; + auto *Expr = MCConstantExpr::create(Size, getContext()); + MCFixup Fixup = + MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_RISCV_ALIGN); + F.setVarFixups({Fixup}); + F.getParent()->setLinkerRelaxable(); + return true; +} + +bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const { MCContext &C = getContext(); - int64_t LineDelta = DF.getLineDelta(); - const MCExpr &AddrDelta = DF.getAddrDelta(); + int64_t LineDelta = F.getDwarfLineDelta(); + const MCExpr &AddrDelta = F.getDwarfAddrDelta(); SmallVector Fixups; - size_t OldSize = DF.getContents().size(); + size_t OldSize = F.getVarSize(); int64_t Value; [[maybe_unused]] bool IsAbsolute = @@ -361,17 +384,16 @@ bool RISCVAsmBackend::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, OS << uint8_t(dwarf::DW_LNS_copy); } - DF.setContents(Data); - DF.setFixups(Fixups); + F.setVarContents(Data); + F.setVarFixups(Fixups); WasRelaxed = OldSize != Data.size(); return true; } -bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF, - bool &WasRelaxed) const { - const MCExpr &AddrDelta = DF.getAddrDelta(); +bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const { + const MCExpr &AddrDelta = F.getDwarfAddrDelta(); SmallVector Fixups; - size_t OldSize = DF.getContents().size(); + size_t OldSize = F.getVarSize(); int64_t Value; if (AddrDelta.evaluateAsAbsolute(Value, *Asm)) @@ -383,9 +405,9 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF, assert(getContext().getAsmInfo()->getMinInstAlignment() == 1 && "expected 1-byte alignment"); if (Value == 0) { - DF.clearContents(); - DF.clearFixups(); - WasRelaxed = OldSize != DF.getContents().size(); + F.clearVarContents(); + F.clearVarFixups(); + WasRelaxed = OldSize != 0; return true; } @@ -416,20 +438,20 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCDwarfCallFrameFragment &DF, } else { llvm_unreachable("unsupported CFA encoding"); } - DF.setContents(Data); - DF.setFixups(Fixups); + F.setVarContents(Data); + F.setVarFixups(Fixups); WasRelaxed = OldSize != Data.size(); return true; } -std::pair RISCVAsmBackend::relaxLEB128(MCLEBFragment &LF, +std::pair RISCVAsmBackend::relaxLEB128(MCFragment &LF, int64_t &Value) const { - if (LF.isSigned()) + if (LF.isLEBSigned()) return std::make_pair(false, false); - const MCExpr &Expr = LF.getValue(); + const MCExpr &Expr = LF.getLEBValue(); if (ULEB128Reloc) { - LF.addFixup(MCFixup::create(0, &Expr, FK_Data_leb128)); + LF.setVarFixups({MCFixup::create(0, &Expr, FK_Data_leb128)}); } return std::make_pair(Expr.evaluateKnownAbsolute(Value, *Asm), false); } @@ -637,7 +659,7 @@ bool RISCVAsmBackend::isPCRelFixupResolved(const MCSymbol *SymA, // Otherwise, check if the offset between the symbol and fragment is fully // resolved, unaffected by linker-relaxable fragments (e.g. instructions or - // offset-affected MCAlignFragment). Complements the generic + // offset-affected FT_Align fragments). Complements the generic // isSymbolRefDifferenceFullyResolvedImpl. if (!PCRelTemp) PCRelTemp = getContext().createTempSymbol(); @@ -662,14 +684,13 @@ static const MCFixup *getPCRelHiFixup(const MCSpecifierExpr &Expr, const MCSymbol *AUIPCSymbol = AUIPCLoc.getAddSym(); if (!AUIPCSymbol) return nullptr; - const auto *DF = dyn_cast_or_null(AUIPCSymbol->getFragment()); - + const auto *DF = AUIPCSymbol->getFragment(); if (!DF) return nullptr; uint64_t Offset = AUIPCSymbol->getOffset(); if (DF->getContents().size() == Offset) { - DF = dyn_cast_or_null(DF->getNext()); + DF = DF->getNext(); if (!DF) return nullptr; Offset = 0; @@ -888,55 +909,6 @@ void RISCVAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup, } } -// Linker relaxation may change code size. We have to insert Nops -// for .align directive when linker relaxation enabled. So then Linker -// could satisfy alignment by removing Nops. -// The function return the total Nops Size we need to insert. -bool RISCVAsmBackend::shouldInsertExtraNopBytesForCodeAlign( - const MCAlignFragment &AF, unsigned &Size) { - // Calculate Nops Size only when linker relaxation enabled. - const MCSubtargetInfo *STI = AF.getSubtargetInfo(); - if (!STI->hasFeature(RISCV::FeatureRelax)) - return false; - - unsigned MinNopLen = STI->hasFeature(RISCV::FeatureStdExtZca) ? 2 : 4; - - if (AF.getAlignment() <= MinNopLen) { - return false; - } else { - Size = AF.getAlignment().value() - MinNopLen; - return true; - } -} - -// We need to insert R_RISCV_ALIGN relocation type to indicate the -// position of Nops and the total bytes of the Nops have been inserted -// when linker relaxation enabled. -// The function insert fixup_riscv_align fixup which eventually will -// transfer to R_RISCV_ALIGN relocation type. -bool RISCVAsmBackend::shouldInsertFixupForCodeAlign(MCAssembler &Asm, - MCAlignFragment &AF) { - // Insert the fixup only when linker relaxation enabled. - const MCSubtargetInfo *STI = AF.getSubtargetInfo(); - if (!STI->hasFeature(RISCV::FeatureRelax)) - return false; - - // Calculate total Nops we need to insert. If there are none to insert - // then simply return. - unsigned Count; - if (!shouldInsertExtraNopBytesForCodeAlign(AF, Count) || (Count == 0)) - return false; - - MCContext &Ctx = getContext(); - const MCExpr *Dummy = MCConstantExpr::create(0, Ctx); - MCFixup Fixup = MCFixup::create(0, Dummy, ELF::R_RISCV_ALIGN); - - uint64_t FixedValue = 0; - MCValue NopBytes = MCValue::get(Count); - Asm.getWriter().recordRelocation(AF, Fixup, NopBytes, FixedValue); - return true; -} - std::unique_ptr RISCVAsmBackend::createObjectTargetWriter() const { return createRISCVELFObjectWriter(OSABI, Is64Bit); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h index 1f1a6f5fe31a0..d97d63204e7e4 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -38,14 +38,6 @@ class RISCVAsmBackend : public MCAsmBackend { const MCTargetOptions &Options); ~RISCVAsmBackend() override = default; - // Return Size with extra Nop Bytes for alignment directive in code section. - bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF, - unsigned &Size) override; - - // Insert target specific fixup type for alignment directive in code section. - bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, - MCAlignFragment &AF) override; - std::optional evaluateFixup(const MCFragment &, MCFixup &, MCValue &, uint64_t &) override; bool addReloc(const MCFragment &, const MCFixup &, const MCValue &, @@ -60,7 +52,8 @@ class RISCVAsmBackend : public MCAsmBackend { std::unique_ptr createObjectTargetWriter() const override; - bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t, + bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, + const MCValue &, uint64_t, bool) const override; std::optional getFixupKind(StringRef Name) const override; @@ -72,11 +65,10 @@ class RISCVAsmBackend : public MCAsmBackend { void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; - bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, - bool &WasRelaxed) const override; - bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, - bool &WasRelaxed) const override; - std::pair relaxLEB128(MCLEBFragment &LF, + bool relaxAlign(MCFragment &F, unsigned &Size) override; + bool relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const override; + bool relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const override; + std::pair relaxLEB128(MCFragment &LF, int64_t &Value) const override; bool writeNopData(raw_ostream &OS, uint64_t Count, diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 54853e3f858e9..e213923ccf38e 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -26,6 +26,7 @@ #include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSection.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/TargetRegistry.h" @@ -126,7 +127,6 @@ class X86AsmBackend : public MCAsmBackend { unsigned PrevInstOpcode = 0; MCBoundaryAlignFragment *PendingBA = nullptr; std::pair PrevInstPosition; - bool IsRightAfterData = false; uint8_t determinePaddingPrefix(const MCInst &Inst) const; bool isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const; @@ -155,10 +155,13 @@ class X86AsmBackend : public MCAsmBackend { AlignBranchType = X86AlignBranchKindLoc; if (X86PadMaxPrefixSize.getNumOccurrences()) TargetPrefixMax = X86PadMaxPrefixSize; + + AllowAutoPadding = + AlignBoundary != Align(1) && AlignBranchType != X86::AlignBranchNone; + AllowEnhancedRelaxation = + AllowAutoPadding && TargetPrefixMax != 0 && X86PadForBranchAlign; } - bool allowAutoPadding() const override; - bool allowEnhancedRelaxation() const override; void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst, const MCSubtargetInfo &STI); void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst); @@ -177,20 +180,20 @@ class X86AsmBackend : public MCAsmBackend { bool mayNeedRelaxation(unsigned Opcode, ArrayRef Operands, const MCSubtargetInfo &STI) const override; - bool fixupNeedsRelaxationAdvanced(const MCFixup &, const MCValue &, uint64_t, + bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, + const MCValue &, uint64_t, bool) const override; void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override; - bool padInstructionViaRelaxation(MCRelaxableFragment &RF, - MCCodeEmitter &Emitter, + bool padInstructionViaRelaxation(MCFragment &RF, MCCodeEmitter &Emitter, unsigned &RemainingSize) const; - bool padInstructionViaPrefix(MCRelaxableFragment &RF, MCCodeEmitter &Emitter, + bool padInstructionViaPrefix(MCFragment &RF, MCCodeEmitter &Emitter, unsigned &RemainingSize) const; - bool padInstructionEncoding(MCRelaxableFragment &RF, MCCodeEmitter &Emitter, + bool padInstructionEncoding(MCFragment &RF, MCCodeEmitter &Emitter, unsigned &RemainingSize) const; bool finishLayout(const MCAssembler &Asm) const override; @@ -364,14 +367,6 @@ static bool hasVariantSymbol(const MCInst &MI) { return false; } -bool X86AsmBackend::allowAutoPadding() const { - return (AlignBoundary != Align(1) && AlignBranchType != X86::AlignBranchNone); -} - -bool X86AsmBackend::allowEnhancedRelaxation() const { - return allowAutoPadding() && TargetPrefixMax != 0 && X86PadForBranchAlign; -} - /// X86 has certain instructions which enable interrupts exactly one /// instruction *after* the instruction which stores to SS. Return true if the /// given instruction may have such an interrupt delay slot. @@ -409,10 +404,9 @@ isRightAfterData(MCFragment *CurrentFragment, // it, returns true. // - Otherwise returns false. // - If the fragment is not a DataFragment, returns false. - if (auto *DF = dyn_cast_or_null(F)) - return DF->getContents().size() && - (DF != PrevInstPosition.first || - DF->getContents().size() != PrevInstPosition.second); + if (F->getKind() == MCFragment::FT_Data) + return F->getFixedSize() && (F != PrevInstPosition.first || + F->getFixedSize() != PrevInstPosition.second); return false; } @@ -421,11 +415,7 @@ isRightAfterData(MCFragment *CurrentFragment, static size_t getSizeForInstFragment(const MCFragment *F) { if (!F || !F->hasInstructions()) return 0; - // MCEncodedFragmentWithContents being templated makes this tricky. - if (auto *DF = dyn_cast(F)) - return DF->getContents().size(); - else - llvm_unreachable("Unknown fragment with instructions!"); + return F->getSize(); } /// Return true if we can insert NOP or prefixes automatically before the @@ -451,7 +441,7 @@ bool X86AsmBackend::canPadInst(const MCInst &Inst, MCObjectStreamer &OS) const { // semantic. return false; - if (IsRightAfterData) + if (isRightAfterData(OS.getCurrentFragment(), PrevInstPosition)) // If this instruction follows any data, there is no clear // instruction boundary, inserting a nop/prefix would change semantic. return false; @@ -468,10 +458,6 @@ bool X86AsmBackend::canPadBranches(MCObjectStreamer &OS) const { if (!OS.getCurrentSectionOnly()->isText()) return false; - // To be Done: Currently don't deal with Bundle cases. - if (OS.getAssembler().isBundlingEnabled()) - return false; - // Branches only need to be aligned in 32-bit or 64-bit mode. if (!(STI.hasFeature(X86::Is64Bit) || STI.hasFeature(X86::Is32Bit))) return false; @@ -492,13 +478,26 @@ bool X86AsmBackend::needAlign(const MCInst &Inst) const { (AlignBranchType & X86::AlignBranchIndirect)); } +void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst, + const MCSubtargetInfo &STI) { + bool AutoPadding = S.getAllowAutoPadding(); + if (LLVM_LIKELY(!AutoPadding && !X86PadForAlign)) { + S.MCObjectStreamer::emitInstruction(Inst, STI); + return; + } + + auto &Backend = static_cast(S.getAssembler().getBackend()); + Backend.emitInstructionBegin(S, Inst, STI); + S.MCObjectStreamer::emitInstruction(Inst, STI); + Backend.emitInstructionEnd(S, Inst); +} + /// Insert BoundaryAlignFragment before instructions to align branches. void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst, const MCSubtargetInfo &STI) { - // Used by canPadInst. Done here, because in emitInstructionEnd, the current - // fragment will have changed. - IsRightAfterData = - isRightAfterData(OS.getCurrentFragment(), PrevInstPosition); + bool CanPadInst = canPadInst(Inst, OS); + if (CanPadInst) + OS.getCurrentFragment()->setAllowAutoPadding(true); if (!canPadBranches(OS)) return; @@ -512,7 +511,7 @@ void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS, // we call canPadInst (not cheap) twice. However, in the common case, we can // avoid unnecessary calls to that, as this is otherwise only used for // relaxable fragments. - if (!canPadInst(Inst, OS)) + if (!CanPadInst) return; if (PendingBA && PendingBA->getNext() == OS.getCurrentFragment()) { @@ -550,11 +549,8 @@ void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS, /// Set the last fragment to be aligned for the BoundaryAlignFragment. void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) { - MCFragment *CF = OS.getCurrentFragment(); - if (auto *F = dyn_cast_or_null(CF)) - F->setAllowAutoPadding(canPadInst(Inst, OS)); - // Update PrevInstOpcode here, canPadInst() reads that. + MCFragment *CF = OS.getCurrentFragment(); PrevInstOpcode = Inst.getOpcode(); PrevInstPosition = std::make_pair(CF, getSizeForInstFragment(CF)); @@ -575,12 +571,10 @@ void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS, // DataFragment, so that we can get the size of instructions later in // MCAssembler::relaxBoundaryAlign. The easiest way is to insert a new empty // DataFragment. - if (isa_and_nonnull(CF)) - OS.insert(OS.getContext().allocFragment()); + OS.newFragment(); // Update the maximum alignment on the current section if necessary. - MCSection *Sec = OS.getCurrentSectionOnly(); - Sec->ensureMinAlignment(AlignBoundary); + CF->getParent()->ensureMinAlignment(AlignBoundary); } std::optional X86AsmBackend::getFixupKind(StringRef Name) const { @@ -756,7 +750,8 @@ bool X86AsmBackend::mayNeedRelaxation(unsigned Opcode, Operands[Operands.size() - 1 - SkipOperands].isExpr()); } -bool X86AsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, +bool X86AsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &, + const MCFixup &Fixup, const MCValue &Target, uint64_t Value, bool Resolved) const { @@ -785,7 +780,7 @@ void X86AsmBackend::relaxInstruction(MCInst &Inst, Inst.setOpcode(RelaxedOp); } -bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF, +bool X86AsmBackend::padInstructionViaPrefix(MCFragment &RF, MCCodeEmitter &Emitter, unsigned &RemainingSize) const { if (!RF.getAllowAutoPadding()) @@ -798,7 +793,7 @@ bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF, *RF.getSubtargetInfo())) return false; - const unsigned OldSize = RF.getContents().size(); + const unsigned OldSize = RF.getVarSize(); if (OldSize == 15) return false; @@ -827,19 +822,18 @@ bool X86AsmBackend::padInstructionViaPrefix(MCRelaxableFragment &RF, SmallString<256> Code; Code.append(PrefixBytesToAdd, Prefix); - Code.append(RF.getContents().begin(), RF.getContents().end()); - RF.setContents(Code); + Code.append(RF.getVarContents().begin(), RF.getVarContents().end()); + RF.setVarContents(Code); // Adjust the fixups for the change in offsets - for (auto &F : RF.getFixups()) { - F.setOffset(F.getOffset() + PrefixBytesToAdd); - } + for (auto &F : RF.getVarFixups()) + F.setOffset(PrefixBytesToAdd + F.getOffset()); RemainingSize -= PrefixBytesToAdd; return true; } -bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF, +bool X86AsmBackend::padInstructionViaRelaxation(MCFragment &RF, MCCodeEmitter &Emitter, unsigned &RemainingSize) const { if (!mayNeedRelaxation(RF.getOpcode(), RF.getOperands(), @@ -854,20 +848,20 @@ bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF, SmallVector Fixups; SmallString<15> Code; Emitter.encodeInstruction(Relaxed, Code, Fixups, *RF.getSubtargetInfo()); - const unsigned OldSize = RF.getContents().size(); + const unsigned OldSize = RF.getVarContents().size(); const unsigned NewSize = Code.size(); assert(NewSize >= OldSize && "size decrease during relaxation?"); unsigned Delta = NewSize - OldSize; if (Delta > RemainingSize) return false; RF.setInst(Relaxed); - RF.setContents(Code); - RF.setFixups(Fixups); + RF.setVarContents(Code); + RF.setVarFixups(Fixups); RemainingSize -= Delta; return true; } -bool X86AsmBackend::padInstructionEncoding(MCRelaxableFragment &RF, +bool X86AsmBackend::padInstructionEncoding(MCFragment &RF, MCCodeEmitter &Emitter, unsigned &RemainingSize) const { bool Changed = false; @@ -900,7 +894,7 @@ bool X86AsmBackend::finishLayout(const MCAssembler &Asm) const { if (!Sec.isText()) continue; - SmallVector Relaxable; + SmallVector Relaxable; for (MCSection::iterator I = Sec.begin(), IE = Sec.end(); I != IE; ++I) { MCFragment &F = *I; @@ -911,7 +905,7 @@ bool X86AsmBackend::finishLayout(const MCAssembler &Asm) const { continue; if (F.getKind() == MCFragment::FT_Relaxable) { - auto &RF = cast(*I); + auto &RF = cast(*I); Relaxable.push_back(&RF); continue; } @@ -932,13 +926,11 @@ bool X86AsmBackend::finishLayout(const MCAssembler &Asm) const { continue; } - const uint64_t OrigSize = Asm.computeFragmentSize(F); - // To keep the effects local, prefer to relax instructions closest to // the align directive. This is purely about human understandability // of the resulting code. If we later find a reason to expand // particular instructions over others, we can adjust. - unsigned RemainingSize = OrigSize; + unsigned RemainingSize = Asm.computeFragmentSize(F) - F.getFixedSize(); while (!Relaxable.empty() && RemainingSize != 0) { auto &RF = *Relaxable.pop_back_val(); // Give the backend a chance to play any tricks it wishes to increase @@ -1551,14 +1543,6 @@ class X86ELFStreamer : public MCELFStreamer { }; } // end anonymous namespace -void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst, - const MCSubtargetInfo &STI) { - auto &Backend = static_cast(S.getAssembler().getBackend()); - Backend.emitInstructionBegin(S, Inst, STI); - S.MCObjectStreamer::emitInstruction(Inst, STI); - Backend.emitInstructionEnd(S, Inst); -} - void X86ELFStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { X86_MC::emitInstruction(*this, Inst, STI); diff --git a/llvm/test/MC/ARM/AlignedBundling/group-bundle-arm.s b/llvm/test/MC/ARM/AlignedBundling/group-bundle-arm.s deleted file mode 100644 index ca78f2acc2894..0000000000000 --- a/llvm/test/MC/ARM/AlignedBundling/group-bundle-arm.s +++ /dev/null @@ -1,48 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple armv7-linux-gnueabi %s -o - \ -# RUN: | llvm-objdump --no-show-raw-insn --triple=armv7 -d - | FileCheck %s - -# On ARM each instruction is 4 bytes long so padding for individual -# instructions should not be inserted. However, for bundle-locked groups -# it can be. - - .syntax unified - .text - .bundle_align_mode 4 - - bx lr - and r1, r1, r2 - and r1, r1, r2 - .bundle_lock - bx r9 - bx r8 - .bundle_unlock -# CHECK: c: nop -# CHECK-NEXT: 10: bx -# CHECK-NEXT: 14: bx - - # pow2 here - .align 4 - bx lr - .bundle_lock - bx r9 - bx r9 - bx r9 - bx r8 - .bundle_unlock -# CHECK: 20: bx -# CHECK-NEXT: 24: nop -# CHECK-NEXT: 28: nop -# CHECK-NEXT: 2c: nop -# CHECK-NEXT: 30: bx - - .align 4 -foo: - b foo - .long 3892240112 - .long 3892240112 - .long 3892240112 - .long 3892240112 - .long 3892240112 - .long 3892240112 -# CHECK: 40: b - diff --git a/llvm/test/MC/ARM/AlignedBundling/illegal-subtarget-change.s b/llvm/test/MC/ARM/AlignedBundling/illegal-subtarget-change.s deleted file mode 100644 index e831ac5c2af06..0000000000000 --- a/llvm/test/MC/ARM/AlignedBundling/illegal-subtarget-change.s +++ /dev/null @@ -1,16 +0,0 @@ -# RUN: not --crash llvm-mc -filetype=obj -triple armv7-linux-gnueabi %s -o - 2>&1 | FileCheck %s - - # We cannot switch subtargets mid-bundle - .syntax unified - .text - .bundle_align_mode 4 - .arch armv4t - bx lr - .bundle_lock - bx lr - .arch armv7a - movt r0, #0xffff - movw r0, #0xffff - .bundle_unlock - bx lr -# CHECK: LLVM ERROR: A Bundle can only have one Subtarget. diff --git a/llvm/test/MC/ARM/AlignedBundling/lit.local.cfg b/llvm/test/MC/ARM/AlignedBundling/lit.local.cfg deleted file mode 100644 index 42bf50dcc13c3..0000000000000 --- a/llvm/test/MC/ARM/AlignedBundling/lit.local.cfg +++ /dev/null @@ -1,2 +0,0 @@ -if not "X86" in config.root.targets: - config.unsupported = True diff --git a/llvm/test/MC/ARM/AlignedBundling/pad-align-to-bundle-end.s b/llvm/test/MC/ARM/AlignedBundling/pad-align-to-bundle-end.s deleted file mode 100644 index c01c8c178afeb..0000000000000 --- a/llvm/test/MC/ARM/AlignedBundling/pad-align-to-bundle-end.s +++ /dev/null @@ -1,41 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple armv7-linux-gnueabi %s -o - \ -# RUN: | llvm-objdump --no-show-raw-insn --triple=armv7 -d - | FileCheck %s - - .syntax unified - .text - .bundle_align_mode 4 - - bx lr - and r1, r1, r2 - and r1, r1, r2 - .bundle_lock align_to_end - bx r9 - .bundle_unlock -# No padding required here because bx just happens to be in the -# right offset. -# CHECK: 8: and -# CHECK-NEXT: c: bx - - bx lr - and r1, r1, r2 - .bundle_lock align_to_end - bx r9 - .bundle_unlock -# A 4-byte padding is needed here -# CHECK: 18: nop -# CHECK-NEXT: 1c: bx - - bx lr - and r1, r1, r2 - .bundle_lock align_to_end - bx r9 - bx r9 - bx r9 - .bundle_unlock -# A 12-byte padding is needed here to push the group to the end of the next -# bundle -# CHECK: 28: nop -# CHECK-NEXT: 2c: nop -# CHECK-NEXT: 30: nop -# CHECK-NEXT: 34: bx - diff --git a/llvm/test/MC/ARM/AlignedBundling/subtarget-change.s b/llvm/test/MC/ARM/AlignedBundling/subtarget-change.s deleted file mode 100644 index 5672560376d46..0000000000000 --- a/llvm/test/MC/ARM/AlignedBundling/subtarget-change.s +++ /dev/null @@ -1,33 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple armv7-linux-gnueabi %s -o - \ -# RUN: | llvm-objdump --no-print-imm-hex --no-show-raw-insn --triple=armv7 -d - | FileCheck %s - - # We can switch subtargets with .arch outside of a bundle - .syntax unified - .text - .bundle_align_mode 4 - .arch armv4t - bx lr - .bundle_lock - and r1, r1, r1 - and r1, r1, r1 - .bundle_unlock - bx lr - - # We can switch subtargets at the start of a bundle - bx lr - .bundle_lock align_to_end - .arch armv7a - movt r0, #0xffff - movw r0, #0xffff - .bundle_unlock - bx lr - -# CHECK: 0: bx lr -# CHECK-NEXT: 4: and r1, r1, r1 -# CHECK-NEXT: 8: and r1, r1, r1 -# CHECK-NEXT: c: bx lr -# CHECK-NEXT: 10: bx lr -# CHECK-NEXT: 14: nop -# CHECK-NEXT: 18: movt r0, #65535 -# CHECK-NEXT: 1c: movw r0, #65535 -# CHECK-NEXT: 20: bx lr diff --git a/llvm/test/MC/AsmParser/AArch64/directive-parse-err.s b/llvm/test/MC/AsmParser/AArch64/directive-parse-err.s index 02cdfd7829198..5e2dd4adcdf8c 100644 --- a/llvm/test/MC/AsmParser/AArch64/directive-parse-err.s +++ b/llvm/test/MC/AsmParser/AArch64/directive-parse-err.s @@ -1,5 +1,5 @@ // RUN: not llvm-mc -triple aarch64 %s 2>&1 | FileCheck %s -// RUN: not llvm-mc -triple aarch64 %s 2>&1 | grep "error:" | count 60 +// RUN: not llvm-mc -triple aarch64 %s 2>&1 | grep "error:" | count 59 // CHECK: [[#@LINE+1]]:19: error: expected newline .equ ident1, 0 $ @@ -175,11 +175,6 @@ // CHECK-NOT: :[[#@LINE+1]]:{{[0-9]+}}: error: .cv_loc 1 1 // EOL COMMENT - // CHECK: [[#@LINE+1]]:28: error: expected newline - .bundle_lock align_to_end $ - // CHECK-NOT: [[#@LINE+1]]:{{[0-9]+}}: error: - .bundle_lock align_to_end // EOL COMMENT - // CHECK: [[#@LINE+1]]:11: error: invalid token in expression .sleb128 $ // CHECK-NOT: :[[#@LINE+1]]:{{[0-9]+}}: error: diff --git a/llvm/test/MC/COFF/bss-text.s b/llvm/test/MC/COFF/bss-text.s index ed6890565b9a3..cedbb2f032236 100644 --- a/llvm/test/MC/COFF/bss-text.s +++ b/llvm/test/MC/COFF/bss-text.s @@ -1,13 +1,15 @@ -# RUN: not llvm-mc -filetype=obj -triple=x86_64-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s +# RUN: not llvm-mc -filetype=obj -triple=x86_64-pc-win32 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: ## -filetype=asm does not check the error. # RUN: llvm-mc -triple=x86_64-pc-win32 %s +.bss +# CHECK: :0: error: BSS section '.bss' cannot have non-zero bytes + addb %bl,(%rax) + .section uninitialized,"b" -# MCRelaxableFragment -# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section 'uninitialized' cannot have instructions +# CHECK: :0: error: BSS section 'uninitialized' cannot have non-zero bytes jmp foo -.bss -# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: IMAGE_SCN_CNT_UNINITIALIZED_DATA section '.bss' cannot have instructions +.section bss0,"b" addb %al,(%rax) diff --git a/llvm/test/MC/COFF/section.s b/llvm/test/MC/COFF/section.s index 9c1a11effa341..fdd65701b1050 100644 --- a/llvm/test/MC/COFF/section.s +++ b/llvm/test/MC/COFF/section.s @@ -29,7 +29,7 @@ .section s ; .long 1 .section s_, "" ; .long 1 .section s_a,"a"; .long 1 -.section s_b,"b"; .long 1 +.section s_b,"b"; .long 0 .section s_d,"d"; .long 1 .section s_D,"D"; .long 1 .section s_n,"n"; .long 1 diff --git a/llvm/test/MC/ELF/mc-dump.s b/llvm/test/MC/ELF/mc-dump.s index 9cf15a7ddee46..fd6cf95f4af44 100644 --- a/llvm/test/MC/ELF/mc-dump.s +++ b/llvm/test/MC/ELF/mc-dump.s @@ -6,45 +6,51 @@ #CHECK-LABEL:assembler backend - final-layout # CHECK:Sections:[ # CHECK-NEXT:MCSection Name:.text -# CHECK-NEXT:0 Data Size:0 [] +# CHECK-NEXT:0 Align Size:0+0 [] +# CHECK-NEXT: Align:4 Fill:0 FillLen:1 MaxBytesToEmit:4 Nops # CHECK-NEXT: Symbol @0 .text -# CHECK-NEXT:0 Align Align:4 Fill:0 FillLen:1 MaxBytesToEmit:4 Nops # CHECK-NEXT:0 Data Size:0 [] # CHECK-NEXT: Symbol @0 _start +# CHECK-NEXT: Symbol @0 Temporary # CHECK-NEXT:0 Org Offset:3 Value:0 -# CHECK-NEXT:3 Relaxable Size:2 > +# CHECK-NEXT:3 Relaxable Size:0+2 [eb,00] > # CHECK-NEXT: Fixup @1 Value:.Ltmp0 Kind:4001 # CHECK-NEXT:5 Data Size:16 [48,8b,04,25,00,00,00,00,48,8b,04,25,00,00,00,00] # CHECK-NEXT: Fixup @4 Value:f0@ Kind:4017 # CHECK-NEXT: Fixup @12 Value:_start@ Kind:4017 # CHECK-NEXT: Symbol @16 .Ltmp0 Temporary +# CHECK-NEXT: Symbol @0 Temporary +# CHECK-NEXT: Symbol @16 Temporary # CHECK-NEXT:MCSection Name:.data -# CHECK-NEXT:0 Data Size:0 [] +# CHECK-NEXT:0 Align Size:0+0 [] +# CHECK-NEXT: Align:4 Fill:0 FillLen:1 MaxBytesToEmit:4 # CHECK-NEXT: Symbol @0 .data -# CHECK-NEXT:0 Align Align:4 Fill:0 FillLen:1 MaxBytesToEmit:4 # CHECK-NEXT:0 Data Size:4 [01,00,00,00] # CHECK-NEXT:4 Fill Value:0 ValueSize:1 NumValues:1 -# CHECK-NEXT:5 LEB Value:.Ltmp0-_start Signed:0 -# CHECK-NEXT:] +# CHECK-NEXT:5 LEB Size:0+1 [15] Value:.Ltmp0-_start Signed:0 +# CHECK:] # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t -debug-only=mc-dump -save-temp-labels -g 2>&1 | FileCheck %s --check-prefix=CHECK2 # CHECK2:5 Data Size:16 [48,8b,04,25,00,00,00,00,48,8b,04,25,00,00,00,00] # CHECK2-NEXT: Fixup @4 Value:f0@ Kind:4017 # CHECK2-NEXT: Fixup @12 Value:_start@ Kind:4017 -# CHECK2-NEXT: Symbol @16 .Ltmp1 -# CHECK2-NEXT: Symbol @0 .Ltmp3 Temporary -# CHECK2-NEXT: Symbol @8 .Ltmp4 Temporary -# CHECK2-NEXT: Symbol @16 .Ltmp5 Temporary -# CHECK2-NEXT: Symbol @16 .Lsec_end0 Temporary +# CHECK2-NEXT: Symbol @16 .Ltmp2 +# CHECK2-NEXT: Symbol @0 .Lcfi0 Temporary +# CHECK2:MCSection Name:.eh_frame +# CHECK2:24 DwarfCallFrame Size:17+1 [00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,45] AddrDelta:.Lcfi0-.Ltmp1 +# CHECK2-NEXT: Fixup @0 Value:.Ltmp12-.Ltmp11-0 Kind:4003 _start: var = _start +.cfi_startproc .org 3 jmp 1f +.cfi_offset %rbp, -24 movq f0@GOTPCREL, %rax movq _start@GOTPCREL, %rax 1: +.cfi_endproc .data .p2align 2 diff --git a/llvm/test/MC/ELF/nobits-non-zero-value.s b/llvm/test/MC/ELF/nobits-non-zero-value.s index ff43e69baaedc..ea95ec97ac8d2 100644 --- a/llvm/test/MC/ELF/nobits-non-zero-value.s +++ b/llvm/test/MC/ELF/nobits-non-zero-value.s @@ -1,26 +1,45 @@ -# RUN: not llvm-mc -filetype=obj -triple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: +# RUN: not llvm-mc -filetype=obj -triple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: --implicit-check-not=warning: ## -filetype=asm does not check the error. # RUN: llvm-mc -triple=x86_64 %s .section .tbss,"aw",@nobits -# MCRelaxableFragment -# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: SHT_NOBITS section '.tbss' cannot have instructions jmp foo .bss -# CHECK: {{.*}}.s:[[#@LINE+1]]:3: error: SHT_NOBITS section '.bss' cannot have instructions addb %al,(%rax) -# CHECK: {{.*}}.s:[[#@LINE+1]]:11: warning: ignoring non-zero fill value in SHT_NOBITS section '.bss' +# CHECK: {{.*}}.s:[[#@LINE+1]]:11: warning: ignoring non-zero fill value in BSS section '.bss' .align 4, 42 -# CHECK-NOT: {{.*}}.s:[[#@LINE+1]]:11: warning: ignoring non-zero fill value in SHT_NOBITS section '.bss' -.align 4, 0 - -# CHECK: :0: error: SHT_NOBITS section '.bss' cannot have non-zero initializers .long 1 -.section .bss1,"aw",%nobits -# CHECK: :0: error: SHT_NOBITS section '.bss1' cannot have fixups +.section .bss0,"aw",%nobits +addb %al,(%rax) + +.section data_fixup,"aw",%nobits .quad foo + +.section fill,"aw",%nobits +.fill b-a,1,1 + +.section org,"aw",%nobits +.org 1,1 + +.section ok,"aw",%nobits +.org 1 +.fill 1 +.fill b-a,1,0 +.align 4, 0 +.long 0 + +.text +a: nop +b: + +## Location is not tracked for efficiency. +# CHECK: :0: error: BSS section '.tbss' cannot have non-zero bytes +# CHECK: :0: error: BSS section '.bss' cannot have non-zero bytes +# CHECK: :0: error: BSS section 'data_fixup' cannot have fixups +# CHECK: :0: error: BSS section 'fill' cannot have non-zero bytes +# CHECK: :0: error: BSS section 'org' cannot have non-zero bytes diff --git a/llvm/test/MC/ELF/reloc-directive.s b/llvm/test/MC/ELF/reloc-directive.s index 42995aa9e7d81..9871fba2e0021 100644 --- a/llvm/test/MC/ELF/reloc-directive.s +++ b/llvm/test/MC/ELF/reloc-directive.s @@ -9,15 +9,18 @@ # ASM-NEXT: .reloc .Ltmp1-1, R_X86_64_NONE, foo # ASM-NEXT: .Ltmp2: # ASM-NEXT: .reloc 2+.Ltmp2, R_X86_64_NONE, local -# ASM-NEXT: .reloc 1+foo+3, R_X86_64_NONE, data+1 -# ASM-NEXT: .Ltmp3: -# ASM-NEXT: .reloc .Ltmp3, BFD_RELOC_NONE, unused # CHECK: 0x2 R_X86_64_NONE foo 0x0 # CHECK-NEXT: 0x0 R_X86_64_NONE foo 0x0 # CHECK-NEXT: 0x3 R_X86_64_NONE local 0x0 -# CHECK-NEXT: 0x4 R_X86_64_NONE data 0x1 # CHECK-NEXT: 0x1 R_X86_64_NONE unused 0x0 +# CHECK-NEXT: 0x4 R_X86_64_NONE data 0x1 + +# CHECK: .rela.my { +# CHECK: 0x0 R_X86_64_NONE foo 0x0 +# CHECK-NEXT: 0x4 R_X86_64_NONE foo 0x0 +# CHECK-NEXT: 0x8 R_X86_64_NONE foo 0x0 +# CHECK-NEXT: } .text .globl foo @@ -27,17 +30,25 @@ local: .reloc .+3-2, R_X86_64_NONE, foo .reloc .-1, R_X86_64_NONE, foo .reloc 2+., R_X86_64_NONE, local - .reloc 1+foo+3, R_X86_64_NONE, data+1 .reloc ., BFD_RELOC_NONE, unused + .space 3 .data .globl data data: + .reloc 1+foo+3, R_X86_64_NONE, data+1 .long 0 -# RUN: not llvm-mc -filetype=obj -triple=x86_64 --defsym=ERR=1 %s 2>&1 | FileCheck %s --check-prefix=ERR +## Constant offsets are relative to the section start. +.section .my +.word 0 +.reloc 0, BFD_RELOC_NONE, foo +.word 0 +.p2align 3 +.reloc 2+2, BFD_RELOC_NONE, foo +.p2align 4 +.reloc 8, BFD_RELOC_NONE, foo -.ifdef ERR .text .globl a, b a: ret @@ -45,22 +56,26 @@ b: ret x: ret y: ret -# ERR: {{.*}}.s:[[#@LINE+1]]:10: error: expected comma +# RUN: not llvm-mc -filetype=obj -triple=x86_64 --defsym=PARSE=1 %s 2>&1 | FileCheck %s --check-prefix=PARSE +# RUN: not llvm-mc -filetype=obj -triple=x86_64 --defsym=ERR=1 %s 2>&1 | FileCheck %s --check-prefix=ERR + +.ifdef PARSE +# PARSE: {{.*}}.s:[[#@LINE+1]]:10: error: expected comma .reloc 0 R_X86_64_NONE, a -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is negative +# PARSE: {{.*}}.s:[[#@LINE+1]]:8: error: directional label undefined +.reloc 1f, R_X86_64_NONE, a +.endif + +.ifdef ERR .reloc -1, R_X86_64_NONE, a -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is not relocatable +# ERR: {{.*}}.s:[[#@LINE+1]]:9: error: .reloc offset is not relocatable .reloc 2*., R_X86_64_NONE, a -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is not relocatable +# ERR: {{.*}}.s:[[#@LINE+1]]:9: error: .reloc offset is not relocatable .reloc a+a, R_X86_64_NONE, a -## GNU as accepts a-a but rejects b-a. -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is not representable -.reloc a-a, R_X86_64_NONE, a -## TODO GNU as accepts x-x and y-x. -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: .reloc offset is not representable +# ERR: {{.*}}.s:[[#@LINE+1]]:9: error: .reloc offset is not relative to a section +.reloc b-a, R_X86_64_NONE, a +# ERR: {{.*}}.s:[[#@LINE+1]]:9: error: .reloc offset is not relative to a section .reloc x-x, R_X86_64_NONE, a -# ERR: {{.*}}.s:[[#@LINE+1]]:8: error: directional label undefined -.reloc 1f, R_X86_64_NONE, a .endif diff --git a/llvm/test/MC/Mips/reloc-directive-bad-obj.s b/llvm/test/MC/Mips/reloc-directive-bad-obj.s index 86d6d0cc66c57..74e5dae5264f6 100644 --- a/llvm/test/MC/Mips/reloc-directive-bad-obj.s +++ b/llvm/test/MC/Mips/reloc-directive-bad-obj.s @@ -2,8 +2,8 @@ # RUN: -target-abi=o32 -filetype=obj -o /dev/null 2>&1 | FileCheck %s .text nop -.reloc foo, R_MIPS_32, .text # CHECK: :[[@LINE]]:24: error: unresolved relocation offset +.reloc foo, R_MIPS_32, .text # CHECK: :[[@LINE]]:8: error: .reloc offset is not relative to a section nop nop -.reloc bar, R_MIPS_32, .text # CHECK: :[[@LINE]]:24: error: unresolved relocation offset +.reloc bar, R_MIPS_32, .text # CHECK: :[[@LINE]]:8: error: .reloc offset is not relative to a section nop diff --git a/llvm/test/MC/Mips/reloc-directive-label-offset.s b/llvm/test/MC/Mips/reloc-directive-label-offset.s index 257bfeb10d151..279fc7860dcea 100644 --- a/llvm/test/MC/Mips/reloc-directive-label-offset.s +++ b/llvm/test/MC/Mips/reloc-directive-label-offset.s @@ -58,18 +58,18 @@ bar: # OBJ-N32-LABEL: Relocations [ # OBJ-N32: 0x4 R_MIPS_NONE .text -# OBJ-N32-NEXT: 0x1C R_MIPS_GOT_OFST .text -# OBJ-N32-NEXT: 0x0 R_MIPS_32 .text # OBJ-N32-NEXT: 0xC R_MIPS_32 .text # OBJ-N32-NEXT: 0x10 R_MIPS_CALL16 foo # OBJ-N32-NEXT: 0x20 R_MIPS_GOT_DISP foo # OBJ-N32-NEXT: 0x24 R_MIPS_GOT_PAGE .text +# OBJ-N32-NEXT: 0x1C R_MIPS_GOT_OFST .text +# OBJ-N32-NEXT: 0x0 R_MIPS_32 .text # OBJ-N64-LABEL: Relocations [ # OBJ-N64: 0x4 R_MIPS_NONE/R_MIPS_NONE/R_MIPS_NONE .text 0x0 -# OBJ-N64-NEXT: 0x1C R_MIPS_GOT_OFST/R_MIPS_NONE/R_MIPS_NONE .text 0x0 -# OBJ-N64-NEXT: 0x0 R_MIPS_32/R_MIPS_NONE/R_MIPS_NONE .text 0x0 # OBJ-N64-NEXT: 0xC R_MIPS_32/R_MIPS_NONE/R_MIPS_NONE .text 0x0 # OBJ-N64-NEXT: 0x10 R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE foo 0x0 # OBJ-N64-NEXT: 0x20 R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE foo 0x0 # OBJ-N64-NEXT: 0x24 R_MIPS_GOT_PAGE/R_MIPS_NONE/R_MIPS_NONE .text 0x0 +# OBJ-N64-NEXT: 0x1C R_MIPS_GOT_OFST/R_MIPS_NONE/R_MIPS_NONE .text 0x0 +# OBJ-N64-NEXT: 0x0 R_MIPS_32/R_MIPS_NONE/R_MIPS_NONE .text 0x0 diff --git a/llvm/test/MC/RISCV/Relocations/mc-dump.s b/llvm/test/MC/RISCV/Relocations/mc-dump.s index 24f3e67ebbdda..e8f4b14ce3725 100644 --- a/llvm/test/MC/RISCV/Relocations/mc-dump.s +++ b/llvm/test/MC/RISCV/Relocations/mc-dump.s @@ -3,15 +3,18 @@ # CHECK:Sections:[ # CHECK-NEXT:MCSection Name:.text -# CHECK-NEXT:0 Data Size:0 [] +# CHECK-NEXT:0 Align Size:0+0 [] +# CHECK-NEXT: Align:4 Fill:0 FillLen:1 MaxBytesToEmit:4 Nops # CHECK-NEXT: Symbol @0 .text -# CHECK-NEXT:0 Align Align:4 Fill:0 FillLen:1 MaxBytesToEmit:4 Nops # CHECK-NEXT:0 Data LinkerRelaxable Size:8 [97,00,00,00,e7,80,00,00] # CHECK-NEXT: Fixup @0 Value:specifier(19,ext) Kind:4023 # CHECK-NEXT: Symbol @0 $x -# CHECK-NEXT:8 Align Align:8 Fill:0 FillLen:1 MaxBytesToEmit:8 Nops -# CHECK-NEXT:12 Data Size:4 [13,05,30,00] -# CHECK-NEXT:16 Align Align:8 Fill:0 FillLen:1 MaxBytesToEmit:8 Nops +# CHECK-NEXT:8 Align Size:0+4 [] +# CHECK-NEXT: Align:8 Fill:0 FillLen:1 MaxBytesToEmit:8 Nops +# CHECK-NEXT: Fixup @0 Value:4 Kind:[[#]] +# CHECK-NEXT:12 Align Size:4+4 [13,05,30,00] +# CHECK-NEXT: Align:8 Fill:0 FillLen:1 MaxBytesToEmit:8 Nops +# CHECK-NEXT: Fixup @4 Value:4 Kind:[[#]] # CHECK-NEXT:] call ext diff --git a/llvm/test/MC/X86/AlignedBundling/align-mode-argument-error.s b/llvm/test/MC/X86/AlignedBundling/align-mode-argument-error.s deleted file mode 100644 index 37c74c86f754e..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/align-mode-argument-error.s +++ /dev/null @@ -1,8 +0,0 @@ -# RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s - -# Missing .bundle_align_mode argument -# CHECK: error: unknown token - - .bundle_align_mode - imull $17, %ebx, %ebp - diff --git a/llvm/test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s b/llvm/test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s deleted file mode 100644 index 387e0fe59bf29..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/asm-printing-bundle-directives.s +++ /dev/null @@ -1,22 +0,0 @@ -# RUN: llvm-mc -filetype=asm -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s - -# Just a simple test for the assembly emitter - making sure it emits back the -# bundling directives. - - .text -foo: - .bundle_align_mode 4 -# CHECK: .bundle_align_mode 4 - pushq %rbp - .bundle_lock -# CHECK: .bundle_lock - cmpl %r14d, %ebp - jle .L_ELSE - .bundle_unlock -# CHECK: .bundle_unlock - .bundle_lock align_to_end -# CHECK: .bundle_lock align_to_end - add %rbx, %rdx - .bundle_unlock - - diff --git a/llvm/test/MC/X86/AlignedBundling/autogen-inst-offset-align-to-end.s b/llvm/test/MC/X86/AlignedBundling/autogen-inst-offset-align-to-end.s deleted file mode 100644 index 6dabafc394e99..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/autogen-inst-offset-align-to-end.s +++ /dev/null @@ -1,2899 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - \ -# RUN: | llvm-objdump --triple=i386 -d --no-show-raw-insn - | FileCheck %s - -# !!! This test is auto-generated from utils/testgen/mc-bundling-x86-gen.py !!! -# It tests that bundle-aligned grouping works correctly in MC. Read the -# source of the script for more details. - - .text - .bundle_align_mode 4 - - .align 32, 0x90 -INSTRLEN_1_OFFSET_0: - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 0: nop -# CHECK: f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 21: nop -# CHECK: 2f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 42: nop -# CHECK: 4f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 63: nop -# CHECK: 6f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 84: nop -# CHECK: 8f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: a5: nop -# CHECK: af: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: c6: nop -# CHECK: cf: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: e7: nop -# CHECK: ef: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 108: nop -# CHECK: 10f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 129: nop -# CHECK: 12f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 14a: nop -# CHECK: 14f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 16b: nop -# CHECK: 16f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 18c: nop -# CHECK: 18f: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ad: nop -# CHECK: 1af: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ce: nop -# CHECK: 1cf: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ef: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_0: - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 200: nop -# CHECK: 20e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 221: nop -# CHECK: 22e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 242: nop -# CHECK: 24e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 263: nop -# CHECK: 26e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 284: nop -# CHECK: 28e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 2a5: nop -# CHECK: 2ae: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 2c6: nop -# CHECK: 2ce: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 2e7: nop -# CHECK: 2ee: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 308: nop -# CHECK: 30e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 329: nop -# CHECK: 32e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 34a: nop -# CHECK: 34e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 36b: nop -# CHECK: 36e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 38c: nop -# CHECK: 38e: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 3ad: nop -# CHECK: 3ae: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 3ce: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 3ef: nop -# CHECK: 3f0: nop -# CHECK: 3fe: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_0: - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 400: nop -# CHECK: 40d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 421: nop -# CHECK: 42d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 442: nop -# CHECK: 44d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 463: nop -# CHECK: 46d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 484: nop -# CHECK: 48d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 4a5: nop -# CHECK: 4ad: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 4c6: nop -# CHECK: 4cd: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 4e7: nop -# CHECK: 4ed: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 508: nop -# CHECK: 50d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 529: nop -# CHECK: 52d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 54a: nop -# CHECK: 54d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 56b: nop -# CHECK: 56d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 58c: nop -# CHECK: 58d: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 5ad: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 5ce: nop -# CHECK: 5d0: nop -# CHECK: 5dd: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 5ef: nop -# CHECK: 5f0: nop -# CHECK: 5fd: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_0: - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 600: nop -# CHECK: 60c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 621: nop -# CHECK: 62c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 642: nop -# CHECK: 64c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 663: nop -# CHECK: 66c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 684: nop -# CHECK: 68c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 6a5: nop -# CHECK: 6ac: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 6c6: nop -# CHECK: 6cc: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 6e7: nop -# CHECK: 6ec: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 708: nop -# CHECK: 70c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 729: nop -# CHECK: 72c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 74a: nop -# CHECK: 74c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 76b: nop -# CHECK: 76c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 78c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 7ad: nop -# CHECK: 7b0: nop -# CHECK: 7bc: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 7ce: nop -# CHECK: 7d0: nop -# CHECK: 7dc: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 7ef: nop -# CHECK: 7f0: nop -# CHECK: 7fc: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_0: - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 800: nop -# CHECK: 80b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 821: nop -# CHECK: 82b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 842: nop -# CHECK: 84b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 863: nop -# CHECK: 86b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 884: nop -# CHECK: 88b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 8a5: nop -# CHECK: 8ab: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 8c6: nop -# CHECK: 8cb: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 8e7: nop -# CHECK: 8eb: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 908: nop -# CHECK: 90b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 929: nop -# CHECK: 92b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 94a: nop -# CHECK: 94b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 96b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 98c: nop -# CHECK: 990: nop -# CHECK: 99b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 9ad: nop -# CHECK: 9b0: nop -# CHECK: 9bb: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 9ce: nop -# CHECK: 9d0: nop -# CHECK: 9db: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 9ef: nop -# CHECK: 9f0: nop -# CHECK: 9fb: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_0: - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a00: nop -# CHECK: a0a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a21: nop -# CHECK: a2a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a42: nop -# CHECK: a4a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a63: nop -# CHECK: a6a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a84: nop -# CHECK: a8a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: aa5: nop -# CHECK: aaa: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: ac6: nop -# CHECK: aca: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: ae7: nop -# CHECK: aea: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b08: nop -# CHECK: b0a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b29: nop -# CHECK: b2a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b4a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b6b: nop -# CHECK: b70: nop -# CHECK: b7a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b8c: nop -# CHECK: b90: nop -# CHECK: b9a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: bad: nop -# CHECK: bb0: nop -# CHECK: bba: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: bce: nop -# CHECK: bd0: nop -# CHECK: bda: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: bef: nop -# CHECK: bf0: nop -# CHECK: bfa: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_0: - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c00: nop -# CHECK: c09: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c21: nop -# CHECK: c29: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c42: nop -# CHECK: c49: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c63: nop -# CHECK: c69: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c84: nop -# CHECK: c89: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: ca5: nop -# CHECK: ca9: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: cc6: nop -# CHECK: cc9: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: ce7: nop -# CHECK: ce9: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d08: nop -# CHECK: d09: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d29: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d4a: nop -# CHECK: d50: nop -# CHECK: d59: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d6b: nop -# CHECK: d70: nop -# CHECK: d79: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d8c: nop -# CHECK: d90: nop -# CHECK: d99: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: dad: nop -# CHECK: db0: nop -# CHECK: db9: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: dce: nop -# CHECK: dd0: nop -# CHECK: dd9: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: def: nop -# CHECK: df0: nop -# CHECK: df9: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_0: - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e00: nop -# CHECK: e08: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e21: nop -# CHECK: e28: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e42: nop -# CHECK: e48: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e63: nop -# CHECK: e68: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e84: nop -# CHECK: e88: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: ea5: nop -# CHECK: ea8: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: ec6: nop -# CHECK: ec8: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: ee7: nop -# CHECK: ee8: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f08: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f29: nop -# CHECK: f30: nop -# CHECK: f38: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f4a: nop -# CHECK: f50: nop -# CHECK: f58: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f6b: nop -# CHECK: f70: nop -# CHECK: f78: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f8c: nop -# CHECK: f90: nop -# CHECK: f98: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: fad: nop -# CHECK: fb0: nop -# CHECK: fb8: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: fce: nop -# CHECK: fd0: nop -# CHECK: fd8: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: fef: nop -# CHECK: ff0: nop -# CHECK: ff8: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_0: - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1000: nop -# CHECK: 1007: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1021: nop -# CHECK: 1027: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1042: nop -# CHECK: 1047: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1063: nop -# CHECK: 1067: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1084: nop -# CHECK: 1087: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 10a5: nop -# CHECK: 10a7: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 10c6: nop -# CHECK: 10c7: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 10e7: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1108: nop -# CHECK: 1110: nop -# CHECK: 1117: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1129: nop -# CHECK: 1130: nop -# CHECK: 1137: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 114a: nop -# CHECK: 1150: nop -# CHECK: 1157: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 116b: nop -# CHECK: 1170: nop -# CHECK: 1177: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 118c: nop -# CHECK: 1190: nop -# CHECK: 1197: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 11ad: nop -# CHECK: 11b0: nop -# CHECK: 11b7: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 11ce: nop -# CHECK: 11d0: nop -# CHECK: 11d7: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 11ef: nop -# CHECK: 11f0: nop -# CHECK: 11f7: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_0: - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1200: nop -# CHECK: 1206: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1221: nop -# CHECK: 1226: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1242: nop -# CHECK: 1246: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1263: nop -# CHECK: 1266: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1284: nop -# CHECK: 1286: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 12a5: nop -# CHECK: 12a6: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 12c6: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 12e7: nop -# CHECK: 12f0: nop -# CHECK: 12f6: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1308: nop -# CHECK: 1310: nop -# CHECK: 1316: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1329: nop -# CHECK: 1330: nop -# CHECK: 1336: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 134a: nop -# CHECK: 1350: nop -# CHECK: 1356: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 136b: nop -# CHECK: 1370: nop -# CHECK: 1376: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 138c: nop -# CHECK: 1390: nop -# CHECK: 1396: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 13ad: nop -# CHECK: 13b0: nop -# CHECK: 13b6: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 13ce: nop -# CHECK: 13d0: nop -# CHECK: 13d6: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 13ef: nop -# CHECK: 13f0: nop -# CHECK: 13f6: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_0: - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1400: nop -# CHECK: 1405: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1421: nop -# CHECK: 1425: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1442: nop -# CHECK: 1445: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1463: nop -# CHECK: 1465: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1484: nop -# CHECK: 1485: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 14a5: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 14c6: nop -# CHECK: 14d0: nop -# CHECK: 14d5: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 14e7: nop -# CHECK: 14f0: nop -# CHECK: 14f5: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1508: nop -# CHECK: 1510: nop -# CHECK: 1515: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1529: nop -# CHECK: 1530: nop -# CHECK: 1535: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 154a: nop -# CHECK: 1550: nop -# CHECK: 1555: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 156b: nop -# CHECK: 1570: nop -# CHECK: 1575: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 158c: nop -# CHECK: 1590: nop -# CHECK: 1595: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 15ad: nop -# CHECK: 15b0: nop -# CHECK: 15b5: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 15ce: nop -# CHECK: 15d0: nop -# CHECK: 15d5: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 15ef: nop -# CHECK: 15f0: nop -# CHECK: 15f5: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_0: - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1600: nop -# CHECK: 1604: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1621: nop -# CHECK: 1624: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1642: nop -# CHECK: 1644: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1663: nop -# CHECK: 1664: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1684: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 16a5: nop -# CHECK: 16b0: nop -# CHECK: 16b4: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 16c6: nop -# CHECK: 16d0: nop -# CHECK: 16d4: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 16e7: nop -# CHECK: 16f0: nop -# CHECK: 16f4: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1708: nop -# CHECK: 1710: nop -# CHECK: 1714: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1729: nop -# CHECK: 1730: nop -# CHECK: 1734: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 174a: nop -# CHECK: 1750: nop -# CHECK: 1754: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 176b: nop -# CHECK: 1770: nop -# CHECK: 1774: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 178c: nop -# CHECK: 1790: nop -# CHECK: 1794: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 17ad: nop -# CHECK: 17b0: nop -# CHECK: 17b4: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 17ce: nop -# CHECK: 17d0: nop -# CHECK: 17d4: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 17ef: nop -# CHECK: 17f0: nop -# CHECK: 17f4: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_0: - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1800: nop -# CHECK: 1803: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1821: nop -# CHECK: 1823: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1842: nop -# CHECK: 1843: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1863: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1884: nop -# CHECK: 1890: nop -# CHECK: 1893: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 18a5: nop -# CHECK: 18b0: nop -# CHECK: 18b3: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 18c6: nop -# CHECK: 18d0: nop -# CHECK: 18d3: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 18e7: nop -# CHECK: 18f0: nop -# CHECK: 18f3: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1908: nop -# CHECK: 1910: nop -# CHECK: 1913: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1929: nop -# CHECK: 1930: nop -# CHECK: 1933: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 194a: nop -# CHECK: 1950: nop -# CHECK: 1953: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 196b: nop -# CHECK: 1970: nop -# CHECK: 1973: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 198c: nop -# CHECK: 1990: nop -# CHECK: 1993: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 19ad: nop -# CHECK: 19b0: nop -# CHECK: 19b3: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 19ce: nop -# CHECK: 19d0: nop -# CHECK: 19d3: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 19ef: nop -# CHECK: 19f0: nop -# CHECK: 19f3: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_0: - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a00: nop -# CHECK: 1a02: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a21: nop -# CHECK: 1a22: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a42: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a63: nop -# CHECK: 1a70: nop -# CHECK: 1a72: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a84: nop -# CHECK: 1a90: nop -# CHECK: 1a92: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1aa5: nop -# CHECK: 1ab0: nop -# CHECK: 1ab2: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ac6: nop -# CHECK: 1ad0: nop -# CHECK: 1ad2: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ae7: nop -# CHECK: 1af0: nop -# CHECK: 1af2: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b08: nop -# CHECK: 1b10: nop -# CHECK: 1b12: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b29: nop -# CHECK: 1b30: nop -# CHECK: 1b32: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b4a: nop -# CHECK: 1b50: nop -# CHECK: 1b52: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b6b: nop -# CHECK: 1b70: nop -# CHECK: 1b72: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b8c: nop -# CHECK: 1b90: nop -# CHECK: 1b92: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1bad: nop -# CHECK: 1bb0: nop -# CHECK: 1bb2: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1bce: nop -# CHECK: 1bd0: nop -# CHECK: 1bd2: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1bef: nop -# CHECK: 1bf0: nop -# CHECK: 1bf2: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_0: - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c00: nop -# CHECK: 1c01: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c21: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c42: nop -# CHECK: 1c50: nop -# CHECK: 1c51: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c63: nop -# CHECK: 1c70: nop -# CHECK: 1c71: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c84: nop -# CHECK: 1c90: nop -# CHECK: 1c91: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ca5: nop -# CHECK: 1cb0: nop -# CHECK: 1cb1: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1cc6: nop -# CHECK: 1cd0: nop -# CHECK: 1cd1: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ce7: nop -# CHECK: 1cf0: nop -# CHECK: 1cf1: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d08: nop -# CHECK: 1d10: nop -# CHECK: 1d11: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d29: nop -# CHECK: 1d30: nop -# CHECK: 1d31: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d4a: nop -# CHECK: 1d50: nop -# CHECK: 1d51: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d6b: nop -# CHECK: 1d70: nop -# CHECK: 1d71: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d8c: nop -# CHECK: 1d90: nop -# CHECK: 1d91: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1dad: nop -# CHECK: 1db0: nop -# CHECK: 1db1: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1dce: nop -# CHECK: 1dd0: nop -# CHECK: 1dd1: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1def: nop -# CHECK: 1df0: nop -# CHECK: 1df1: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_0: - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e00: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e21: nop -# CHECK: 1e30: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e42: nop -# CHECK: 1e50: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e63: nop -# CHECK: 1e70: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e84: nop -# CHECK: 1e90: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ea5: nop -# CHECK: 1eb0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ec6: nop -# CHECK: 1ed0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ee7: nop -# CHECK: 1ef0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f08: nop -# CHECK: 1f10: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f29: nop -# CHECK: 1f30: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f4a: nop -# CHECK: 1f50: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f6b: nop -# CHECK: 1f70: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f8c: nop -# CHECK: 1f90: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1fad: nop -# CHECK: 1fb0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1fce: nop -# CHECK: 1fd0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock align_to_end - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1fef: nop -# CHECK: 1ff0: incl - diff --git a/llvm/test/MC/X86/AlignedBundling/autogen-inst-offset-padding.s b/llvm/test/MC/X86/AlignedBundling/autogen-inst-offset-padding.s deleted file mode 100644 index d486ec5fca00e..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/autogen-inst-offset-padding.s +++ /dev/null @@ -1,2674 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - \ -# RUN: | llvm-objdump --triple=i386 -d --no-show-raw-insn - | FileCheck %s - -# !!! This test is auto-generated from utils/testgen/mc-bundling-x86-gen.py !!! -# It tests that bundle-aligned grouping works correctly in MC. Read the -# source of the script for more details. - - .text - .bundle_align_mode 4 - - .align 32, 0x90 -INSTRLEN_1_OFFSET_0: - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 0: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 21: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 42: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 63: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 84: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: a5: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: c6: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: e7: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 108: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 129: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 14a: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 16b: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 18c: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ad: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ce: incl - - .align 32, 0x90 -INSTRLEN_1_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 1 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ef: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_0: - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 200: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 221: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 242: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 263: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 284: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 2a5: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 2c6: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 2e7: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 308: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 329: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 34a: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 36b: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 38c: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 3ad: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 3ce: incl - - .align 32, 0x90 -INSTRLEN_2_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 2 - inc %eax - .endr - .bundle_unlock -# CHECK: 3ef: nop -# CHECK: 3f0: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_0: - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 400: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 421: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 442: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 463: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 484: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 4a5: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 4c6: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 4e7: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 508: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 529: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 54a: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 56b: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 58c: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 5ad: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 5ce: nop -# CHECK: 5d0: incl - - .align 32, 0x90 -INSTRLEN_3_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 3 - inc %eax - .endr - .bundle_unlock -# CHECK: 5ef: nop -# CHECK: 5f0: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_0: - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 600: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 621: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 642: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 663: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 684: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 6a5: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 6c6: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 6e7: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 708: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 729: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 74a: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 76b: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 78c: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 7ad: nop -# CHECK: 7b0: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 7ce: nop -# CHECK: 7d0: incl - - .align 32, 0x90 -INSTRLEN_4_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 4 - inc %eax - .endr - .bundle_unlock -# CHECK: 7ef: nop -# CHECK: 7f0: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_0: - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 800: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 821: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 842: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 863: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 884: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 8a5: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 8c6: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 8e7: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 908: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 929: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 94a: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 96b: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 98c: nop -# CHECK: 990: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 9ad: nop -# CHECK: 9b0: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 9ce: nop -# CHECK: 9d0: incl - - .align 32, 0x90 -INSTRLEN_5_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 5 - inc %eax - .endr - .bundle_unlock -# CHECK: 9ef: nop -# CHECK: 9f0: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_0: - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a00: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a21: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a42: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a63: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: a84: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: aa5: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: ac6: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: ae7: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b08: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b29: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b4a: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b6b: nop -# CHECK: b70: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: b8c: nop -# CHECK: b90: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: bad: nop -# CHECK: bb0: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: bce: nop -# CHECK: bd0: incl - - .align 32, 0x90 -INSTRLEN_6_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 6 - inc %eax - .endr - .bundle_unlock -# CHECK: bef: nop -# CHECK: bf0: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_0: - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c00: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c21: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c42: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c63: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: c84: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: ca5: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: cc6: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: ce7: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d08: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d29: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d4a: nop -# CHECK: d50: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d6b: nop -# CHECK: d70: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: d8c: nop -# CHECK: d90: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: dad: nop -# CHECK: db0: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: dce: nop -# CHECK: dd0: incl - - .align 32, 0x90 -INSTRLEN_7_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 7 - inc %eax - .endr - .bundle_unlock -# CHECK: def: nop -# CHECK: df0: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_0: - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e00: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e21: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e42: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e63: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: e84: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: ea5: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: ec6: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: ee7: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f08: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f29: nop -# CHECK: f30: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f4a: nop -# CHECK: f50: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f6b: nop -# CHECK: f70: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: f8c: nop -# CHECK: f90: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: fad: nop -# CHECK: fb0: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: fce: nop -# CHECK: fd0: incl - - .align 32, 0x90 -INSTRLEN_8_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 8 - inc %eax - .endr - .bundle_unlock -# CHECK: fef: nop -# CHECK: ff0: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_0: - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1000: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1021: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1042: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1063: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1084: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 10a5: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 10c6: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 10e7: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1108: nop -# CHECK: 1110: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 1129: nop -# CHECK: 1130: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 114a: nop -# CHECK: 1150: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 116b: nop -# CHECK: 1170: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 118c: nop -# CHECK: 1190: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 11ad: nop -# CHECK: 11b0: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 11ce: nop -# CHECK: 11d0: incl - - .align 32, 0x90 -INSTRLEN_9_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 9 - inc %eax - .endr - .bundle_unlock -# CHECK: 11ef: nop -# CHECK: 11f0: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_0: - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1200: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1221: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1242: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1263: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1284: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 12a5: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 12c6: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 12e7: nop -# CHECK: 12f0: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1308: nop -# CHECK: 1310: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 1329: nop -# CHECK: 1330: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 134a: nop -# CHECK: 1350: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 136b: nop -# CHECK: 1370: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 138c: nop -# CHECK: 1390: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 13ad: nop -# CHECK: 13b0: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 13ce: nop -# CHECK: 13d0: incl - - .align 32, 0x90 -INSTRLEN_10_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 10 - inc %eax - .endr - .bundle_unlock -# CHECK: 13ef: nop -# CHECK: 13f0: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_0: - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1400: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1421: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1442: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1463: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1484: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 14a5: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 14c6: nop -# CHECK: 14d0: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 14e7: nop -# CHECK: 14f0: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1508: nop -# CHECK: 1510: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 1529: nop -# CHECK: 1530: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 154a: nop -# CHECK: 1550: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 156b: nop -# CHECK: 1570: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 158c: nop -# CHECK: 1590: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 15ad: nop -# CHECK: 15b0: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 15ce: nop -# CHECK: 15d0: incl - - .align 32, 0x90 -INSTRLEN_11_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 11 - inc %eax - .endr - .bundle_unlock -# CHECK: 15ef: nop -# CHECK: 15f0: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_0: - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1600: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1621: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1642: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1663: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1684: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 16a5: nop -# CHECK: 16b0: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 16c6: nop -# CHECK: 16d0: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 16e7: nop -# CHECK: 16f0: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1708: nop -# CHECK: 1710: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 1729: nop -# CHECK: 1730: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 174a: nop -# CHECK: 1750: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 176b: nop -# CHECK: 1770: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 178c: nop -# CHECK: 1790: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 17ad: nop -# CHECK: 17b0: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 17ce: nop -# CHECK: 17d0: incl - - .align 32, 0x90 -INSTRLEN_12_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 12 - inc %eax - .endr - .bundle_unlock -# CHECK: 17ef: nop -# CHECK: 17f0: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_0: - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1800: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1821: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1842: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1863: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1884: nop -# CHECK: 1890: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 18a5: nop -# CHECK: 18b0: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 18c6: nop -# CHECK: 18d0: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 18e7: nop -# CHECK: 18f0: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1908: nop -# CHECK: 1910: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 1929: nop -# CHECK: 1930: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 194a: nop -# CHECK: 1950: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 196b: nop -# CHECK: 1970: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 198c: nop -# CHECK: 1990: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 19ad: nop -# CHECK: 19b0: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 19ce: nop -# CHECK: 19d0: incl - - .align 32, 0x90 -INSTRLEN_13_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 13 - inc %eax - .endr - .bundle_unlock -# CHECK: 19ef: nop -# CHECK: 19f0: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_0: - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a00: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a21: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a42: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a63: nop -# CHECK: 1a70: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1a84: nop -# CHECK: 1a90: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1aa5: nop -# CHECK: 1ab0: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ac6: nop -# CHECK: 1ad0: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ae7: nop -# CHECK: 1af0: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b08: nop -# CHECK: 1b10: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b29: nop -# CHECK: 1b30: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b4a: nop -# CHECK: 1b50: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b6b: nop -# CHECK: 1b70: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1b8c: nop -# CHECK: 1b90: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1bad: nop -# CHECK: 1bb0: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1bce: nop -# CHECK: 1bd0: incl - - .align 32, 0x90 -INSTRLEN_14_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 14 - inc %eax - .endr - .bundle_unlock -# CHECK: 1bef: nop -# CHECK: 1bf0: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_0: - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c00: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c21: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c42: nop -# CHECK: 1c50: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c63: nop -# CHECK: 1c70: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1c84: nop -# CHECK: 1c90: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ca5: nop -# CHECK: 1cb0: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1cc6: nop -# CHECK: 1cd0: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ce7: nop -# CHECK: 1cf0: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d08: nop -# CHECK: 1d10: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d29: nop -# CHECK: 1d30: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d4a: nop -# CHECK: 1d50: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d6b: nop -# CHECK: 1d70: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1d8c: nop -# CHECK: 1d90: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1dad: nop -# CHECK: 1db0: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1dce: nop -# CHECK: 1dd0: incl - - .align 32, 0x90 -INSTRLEN_15_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 15 - inc %eax - .endr - .bundle_unlock -# CHECK: 1def: nop -# CHECK: 1df0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_0: - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e00: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_1: - .fill 1, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e21: nop -# CHECK: 1e30: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_2: - .fill 2, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e42: nop -# CHECK: 1e50: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_3: - .fill 3, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e63: nop -# CHECK: 1e70: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_4: - .fill 4, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1e84: nop -# CHECK: 1e90: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_5: - .fill 5, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ea5: nop -# CHECK: 1eb0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_6: - .fill 6, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ec6: nop -# CHECK: 1ed0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_7: - .fill 7, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1ee7: nop -# CHECK: 1ef0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_8: - .fill 8, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f08: nop -# CHECK: 1f10: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_9: - .fill 9, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f29: nop -# CHECK: 1f30: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_10: - .fill 10, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f4a: nop -# CHECK: 1f50: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_11: - .fill 11, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f6b: nop -# CHECK: 1f70: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_12: - .fill 12, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1f8c: nop -# CHECK: 1f90: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_13: - .fill 13, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1fad: nop -# CHECK: 1fb0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_14: - .fill 14, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1fce: nop -# CHECK: 1fd0: incl - - .align 32, 0x90 -INSTRLEN_16_OFFSET_15: - .fill 15, 1, 0x90 - .bundle_lock - .rept 16 - inc %eax - .endr - .bundle_unlock -# CHECK: 1fef: nop -# CHECK: 1ff0: incl - diff --git a/llvm/test/MC/X86/AlignedBundling/bundle-group-too-large-error.s b/llvm/test/MC/X86/AlignedBundling/bundle-group-too-large-error.s deleted file mode 100644 index 697b8bf6ab6c0..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/bundle-group-too-large-error.s +++ /dev/null @@ -1,18 +0,0 @@ -# RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s -# RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mc-relax-all %s -o - 2>&1 | FileCheck %s - -# CHECK: ERROR: Fragment can't be larger than a bundle size - - .text -foo: - .bundle_align_mode 4 - pushq %rbp - - .bundle_lock - pushq %r14 - callq bar - callq bar - callq bar - callq bar - .bundle_unlock - diff --git a/llvm/test/MC/X86/AlignedBundling/bundle-lock-option-error.s b/llvm/test/MC/X86/AlignedBundling/bundle-lock-option-error.s deleted file mode 100644 index b849d2b333007..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/bundle-lock-option-error.s +++ /dev/null @@ -1,11 +0,0 @@ -# RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s - -# Missing .bundle_align_mode argument -# CHECK: error: invalid option - - .bundle_align_mode 4 - .bundle_lock 5 - imull $17, %ebx, %ebp - .bundle_unlock - - diff --git a/llvm/test/MC/X86/AlignedBundling/bundle-subtarget-change-error.s b/llvm/test/MC/X86/AlignedBundling/bundle-subtarget-change-error.s deleted file mode 100644 index c02d0d6b19b4e..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/bundle-subtarget-change-error.s +++ /dev/null @@ -1,16 +0,0 @@ -# RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro %s -o - 2>&1 | FileCheck %s -# RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - 2>&1 | FileCheck %s - -# Switching mode will change subtarget, which we can't do within a bundle - .text - .code64 - .bundle_align_mode 4 -foo: - pushq %rbp - .bundle_lock - addl %ebp, %eax - .code32 - movb $0x0, (%si) - .bundle_unlock - -CHECK: LLVM ERROR: A Bundle can only have one Subtarget. diff --git a/llvm/test/MC/X86/AlignedBundling/different-sections.s b/llvm/test/MC/X86/AlignedBundling/different-sections.s deleted file mode 100644 index bc4f20132dbe7..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/different-sections.s +++ /dev/null @@ -1,27 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s - -# Test two different executable sections with bundling. - - .bundle_align_mode 3 - .section text1, "x" -# CHECK: section text1 - imull $17, %ebx, %ebp - imull $17, %ebx, %ebp - - imull $17, %ebx, %ebp -# CHECK: 6: nop -# CHECK-NEXT: 8: imull - - .section text2, "x" -# CHECK: section text2 - imull $17, %ebx, %ebp - imull $17, %ebx, %ebp - - imull $17, %ebx, %ebp -# CHECK: 6: nop -# CHECK-NEXT: 8: imull - - diff --git a/llvm/test/MC/X86/AlignedBundling/labeloffset.s b/llvm/test/MC/X86/AlignedBundling/labeloffset.s deleted file mode 100644 index 7f6150a8aa17c..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/labeloffset.s +++ /dev/null @@ -1,81 +0,0 @@ -# RUN: llvm-mc -triple=i686-linux -filetype=obj %s -o - | \ -# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn -r - | FileCheck %s - - .bundle_align_mode 5 - .text - .globl main - .align 32, 0x90 - .type main,@function -main: # @main -# CHECK-LABEL:
: -# Call + pop sequence for determining the PIC base. - .bundle_lock align_to_end - calll .L0$pb - .bundle_unlock -.L0$pb: - popl %eax -# CHECK: 20: popl -# 26 bytes of instructions between the pop and the use of the pic base symbol. - movl $3, 2(%ebx, %ebx) - movl $3, 2(%ebx, %ebx) - movl $3, 2(%ebx, %ebx) - hlt - hlt -# CHECK: nop -.Ltmp0: - addl (.Ltmp0-.L0$pb), %eax -# The addl has bundle padding to push it from 0x3b to 0x40. -# The difference between the labels should be 0x20 (0x40-0x20) not 0x1b -# (0x3b-0x20) -# CHECK: 40: addl 32, %eax - popl %ecx - jmp *%ecx - - -# Also make sure it works with a non-relaxable instruction (cmp vs add) -# and for 2 adjacent labels that both point to the correct instruction - .section .text.bar, "ax" - .globl bar - .align 32, 0x90 - .type bar,@function -bar: -# CHECK-LABEL: bar: - .bundle_lock align_to_end - calll .L1$pb - .bundle_unlock -.L1$pb: - popl %eax -# CHECK: 20: popl -# 26 bytes of instructions between the pop and the use of the pic base symbol. - movl $3, 2(%ebx, %ebx) - movl $3, 2(%ebx, %ebx) - movl $3, 2(%ebx, %ebx) - hlt - hlt -# CHECK: nop -.Ltmp1: -.Ltmp2: - cmpl %eax, .Ltmp1 -# CHECK: 40: cmpl %eax, 64 - cmpl %eax, (.Ltmp2-.L1$pb) -# CHECK: 46: cmpl %eax, 32 - popl %ecx - jmp *%ecx - - -# Switch sections in the middle of a function - .section .text.foo, "ax" - .globl foo - .align 32, 0x90 - .type foo,@function -# CHECK-LABEL: foo: -foo: - inc %eax -tmp3: - .rodata - .type obj,@object - .comm obj,4,4 - .section .text.foo - inc %eax -# CHECK: : -# CHECK-NEXT: 1: incl diff --git a/llvm/test/MC/X86/AlignedBundling/lit.local.cfg b/llvm/test/MC/X86/AlignedBundling/lit.local.cfg deleted file mode 100644 index 42bf50dcc13c3..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/lit.local.cfg +++ /dev/null @@ -1,2 +0,0 @@ -if not "X86" in config.root.targets: - config.unsupported = True diff --git a/llvm/test/MC/X86/AlignedBundling/lock-without-bundle-mode-error.s b/llvm/test/MC/X86/AlignedBundling/lock-without-bundle-mode-error.s deleted file mode 100644 index 65ee2d5b9f385..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/lock-without-bundle-mode-error.s +++ /dev/null @@ -1,10 +0,0 @@ -# RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s - -# .bundle_lock can't come without a .bundle_align_mode before it - -# CHECK: ERROR: .bundle_lock forbidden when bundling is disabled - - imull $17, %ebx, %ebp - .bundle_lock - - diff --git a/llvm/test/MC/X86/AlignedBundling/long-nop-pad.s b/llvm/test/MC/X86/AlignedBundling/long-nop-pad.s deleted file mode 100644 index 439915dfd0b5b..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/long-nop-pad.s +++ /dev/null @@ -1,31 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s - -# Test that long nops are generated for padding where possible. - - .text -foo: - .bundle_align_mode 5 - -# This callq instruction is 5 bytes long - .bundle_lock align_to_end - callq bar - .bundle_unlock -# To align this group to a bundle end, we need a two 10-byte NOPs and a 7-byte NOP. -# CHECK: 0: nop -# CHECK-NEXT: a: nop -# CHECK-NEXT: 14: nop -# CHECK: 1b: callq - -# This push instruction is 1 byte long - .bundle_lock align_to_end - push %rax - .bundle_unlock -# To align this group to a bundle end, we need three 10-byte NOPs, and a 1-byte. -# CHECK: 20: nop -# CHECK-NEXT: 2a: nop -# CHECK-NEXT: 34: nop -# CHECK-NEXT: 3e: nop -# CHECK-NEXT: 3f: pushq diff --git a/llvm/test/MC/X86/AlignedBundling/misaligned-bundle-group.s b/llvm/test/MC/X86/AlignedBundling/misaligned-bundle-group.s deleted file mode 100644 index 92bd9ec016bd5..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/misaligned-bundle-group.s +++ /dev/null @@ -1,19 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -mcpu=pentiumpro %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - \ -# RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-OPT %s -# RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - \ -# RUN: | FileCheck --check-prefixes=CHECK,CHECK-OPT %s - - .text -foo: - .bundle_align_mode 5 - push %ebp # 1 byte - .align 16 - .bundle_lock align_to_end -# CHECK: 1: nopw %cs:(%eax,%eax) -# CHECK: 10: nopw %cs:(%eax,%eax) -# CHECK-OPT: 1b: calll 0x1c - calll bar # 5 bytes - .bundle_unlock - ret # 1 byte diff --git a/llvm/test/MC/X86/AlignedBundling/misaligned-bundle.s b/llvm/test/MC/X86/AlignedBundling/misaligned-bundle.s deleted file mode 100644 index 0bf5cfd802be9..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/misaligned-bundle.s +++ /dev/null @@ -1,26 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -mcpu=pentiumpro %s -o - \ -# RUN: | llvm-objdump --no-print-imm-hex -d --no-show-raw-insn - \ -# RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-OPT %s -# RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - \ -# RUN: | llvm-objdump --no-print-imm-hex -d --no-show-raw-insn - \ -# RUN: | FileCheck --check-prefixes=CHECK,CHECK-OPT %s - - .text -foo: - .bundle_align_mode 5 - push %ebp # 1 byte - .align 16 -# CHECK: 1: nopw %cs:(%eax,%eax) -# CHECK-OPT: 10: movl $1, (%esp) - movl $0x1, (%esp) # 7 bytes - movl $0x1, (%esp) # 7 bytes -# CHECK-OPT: 1e: nop - movl $0x2, 0x1(%esp) # 8 bytes - movl $0x2, 0x1(%esp) # 8 bytes - movl $0x2, 0x1(%esp) # 8 bytes - movl $0x2, (%esp) # 7 bytes -# CHECK-OPT: 3f: nop -# CHECK-OPT: 40: movl $3, (%esp) - movl $0x3, (%esp) # 7 bytes - movl $0x3, (%esp) # 7 bytes - ret diff --git a/llvm/test/MC/X86/AlignedBundling/nesting.s b/llvm/test/MC/X86/AlignedBundling/nesting.s deleted file mode 100644 index e107a413521b3..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/nesting.s +++ /dev/null @@ -1,73 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s - -# Will be bundle-aligning to 16 byte boundaries - .bundle_align_mode 4 - .text -# CHECK-LABEL: : -.type foo,@function -foo: -# Test that bundle alignment mode can be set more than once. - .bundle_align_mode 4 -# Each of these callq instructions is 5 bytes long - callq bar - callq bar - .bundle_lock - .bundle_lock - callq bar - callq bar - .bundle_unlock - .bundle_unlock -# CHECK: 10: callq {{.*}} -# CHECK-NEXT: 15: callq {{.*}} - - .p2align 4 -# CHECK-LABEL: : -.type bar,@function -bar: - callq foo - callq foo -# Check that the callqs get bundled together, and that the whole group is -# align_to_end - .bundle_lock - callq bar - .bundle_lock align_to_end - callq bar - .bundle_unlock - .bundle_unlock -# CHECK: 36: callq {{.*}} -# CHECK-NEXT: 3b: callq {{.*}} - -# CHECK-LABEL: : -.type baz,@function -baz: - callq foo - callq foo -# Check that the callqs get bundled together, and that the whole group is -# align_to_end (with the outer directive marked align_to_end) - .bundle_lock align_to_end - callq bar - .bundle_lock - callq bar - .bundle_unlock - .bundle_unlock -# CHECK: 56: callq {{.*}} -# CHECK-NEXT: 5b: callq {{.*}} - -# CHECK-LABEL: quux -.type quux,@function -quux: - callq bar - callq bar - .bundle_lock - .bundle_lock - callq bar - .bundle_unlock - callq bar - .bundle_unlock -# Check that the calls are bundled together when the second one is after the -# inner nest is closed. -# CHECK: 70: callq {{.*}} -# CHECK-NEXT: 75: callq {{.*}} diff --git a/llvm/test/MC/X86/AlignedBundling/pad-align-to-bundle-end.s b/llvm/test/MC/X86/AlignedBundling/pad-align-to-bundle-end.s deleted file mode 100644 index d725724f8fd44..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/pad-align-to-bundle-end.s +++ /dev/null @@ -1,35 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s - -# Test some variations of padding to the end of a bundle. - - .text -foo: - .bundle_align_mode 4 - -# Each of these callq instructions is 5 bytes long - callq bar - callq bar - .bundle_lock align_to_end - callq bar - .bundle_unlock -# To align this group to a bundle end, we need a 1-byte NOP. -# CHECK: a: nop -# CHECK-NEXT: b: callq - - callq bar - callq bar - .bundle_lock align_to_end - callq bar - callq bar - .bundle_unlock -# Here we have to pad until the end of the *next* boundary because -# otherwise the group crosses a boundary. -# CHECK: 1a: nop -# The nop sequence may be implemented as one instruction or many, but if -# it's one instruction, that instruction cannot itself cross the boundary. -# CHECK: 20: nop -# CHECK-NEXT: 26: callq -# CHECK-NEXT: 2b: callq diff --git a/llvm/test/MC/X86/AlignedBundling/pad-bundle-groups.s b/llvm/test/MC/X86/AlignedBundling/pad-bundle-groups.s deleted file mode 100644 index 9e07b5994864b..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/pad-bundle-groups.s +++ /dev/null @@ -1,49 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s - -# Test some variations of padding for bundle-locked groups. - - .text -foo: - .bundle_align_mode 4 - -# Each of these callq instructions is 5 bytes long - callq bar - callq bar - - .bundle_lock - callq bar - callq bar - .bundle_unlock -# We'll need a 6-byte NOP before this group -# CHECK: a: nop -# CHECK-NEXT: 10: callq -# CHECK-NEXT: 15: callq - - .bundle_lock - callq bar - callq bar - .bundle_unlock -# Same here -# CHECK: 1a: nop -# CHECK-NEXT: 20: callq -# CHECK-NEXT: 25: callq - - .align 16, 0x90 - callq bar - .bundle_lock - callq bar - callq bar - callq bar - .bundle_unlock -# And here we'll need a 10-byte NOP + 1-byte NOP -# CHECK: 30: callq -# CHECK: 35: nop -# CHECK: 3f: nop -# CHECK-NEXT: 40: callq -# CHECK-NEXT: 45: callq - - - diff --git a/llvm/test/MC/X86/AlignedBundling/relax-at-bundle-end.s b/llvm/test/MC/X86/AlignedBundling/relax-at-bundle-end.s deleted file mode 100644 index 2c510f796e19f..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/relax-at-bundle-end.s +++ /dev/null @@ -1,18 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck %s -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d --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 - diff --git a/llvm/test/MC/X86/AlignedBundling/relax-in-bundle-group.s b/llvm/test/MC/X86/AlignedBundling/relax-in-bundle-group.s deleted file mode 100644 index 2419a02f9ab74..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/relax-in-bundle-group.s +++ /dev/null @@ -1,44 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro %s -o - \ -# RUN: | llvm-objdump -d - | FileCheck %s -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d - | FileCheck %s - -# Test that instructions inside bundle-locked groups are relaxed even if their -# fixup is short enough not to warrant relaxation on its own. - - .text -foo: - .bundle_align_mode 4 - pushq %rbp - - movl %edi, %ebx - callq bar - movl %eax, %r14d - imull $17, %ebx, %ebp - movl %ebx, %edi - callq bar - cmpl %r14d, %ebp - .bundle_lock - - jle .L_ELSE -# This group would've started at 0x18 and is too long, so a chunky NOP padding -# is inserted to push it to 0x20. -# CHECK: 18: {{[a-f0-9 ]+}} nopl - -# The long encoding for JLE should be used here even though its target is close -# CHECK-NEXT: 20: 0f 8e - - addl %ebp, %eax - - jmp .L_RET -# Same for the JMP -# CHECK: 28: e9 - - .bundle_unlock - -.L_ELSE: - imull %ebx, %eax -.L_RET: - - popq %rbx - diff --git a/llvm/test/MC/X86/AlignedBundling/section-alignment.s b/llvm/test/MC/X86/AlignedBundling/section-alignment.s deleted file mode 100644 index d5277d194576e..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/section-alignment.s +++ /dev/null @@ -1,23 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - \ -# RUN: | llvm-readobj --sections - | FileCheck %s - -# Test that bundle-aligned sections with instructions are aligned - - .bundle_align_mode 5 -# CHECK: Sections -# Check that the empty .text section has the default alignment -# CHECK-LABEL: Name: .text -# CHECK-NOT: Name -# CHECK: AddressAlignment: 4 - - .section text1, "x" - imull $17, %ebx, %ebp -# CHECK-LABEL: Name: text1 -# CHECK-NOT: Name -# CHECK: AddressAlignment: 32 - - .section text2, "x" - imull $17, %ebx, %ebp -# CHECK-LABEL: Name: text2 -# CHECK-NOT: Name -# CHECK: AddressAlignment: 32 diff --git a/llvm/test/MC/X86/AlignedBundling/single-inst-bundling.s b/llvm/test/MC/X86/AlignedBundling/single-inst-bundling.s deleted file mode 100644 index 1bcd010240ae3..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/single-inst-bundling.s +++ /dev/null @@ -1,52 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-OPT %s -# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -mcpu=pentiumpro -mc-relax-all %s -o - \ -# RUN: | llvm-objdump -d --no-show-raw-insn - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-RELAX %s - -# Test simple NOP insertion for single instructions. - - .text -foo: - # Will be bundle-aligning to 16 byte boundaries - .bundle_align_mode 4 - pushq %rbp - pushq %r14 - pushq %rbx - - movl %edi, %ebx - callq bar - movl %eax, %r14d - - imull $17, %ebx, %ebp -# This imull is 3 bytes long and should have started at 0xe, so two bytes -# of nop padding are inserted instead and it starts at 0x10 -# CHECK: nop -# CHECK-NEXT: 10: imull - - movl %ebx, %edi - callq bar - cmpl %r14d, %ebp -# CHECK-RELAX: nopl - jle .L_ELSE -# Due to the padding that's inserted before the addl, the jump target -# becomes farther by one byte. -# CHECK-OPT: jle 0x24 -# CHECK-RELAX: jle 0x2d - - addl %ebp, %eax -# CHECK-OPT: nop -# CHECK-OPT-NEXT:20: addl -# CHECK-RELAX: 26: addl - - jmp .L_RET -.L_ELSE: - imull %ebx, %eax -.L_RET: - ret - -# Just verifying that data fills don't drive bundling crazy - .data - .byte 40 - .byte 98 - - diff --git a/llvm/test/MC/X86/AlignedBundling/switch-section-locked-error.s b/llvm/test/MC/X86/AlignedBundling/switch-section-locked-error.s deleted file mode 100644 index 6ea3c36beb1cc..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/switch-section-locked-error.s +++ /dev/null @@ -1,16 +0,0 @@ -# RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s - -# This test invokes .bundle_lock and then switches to a different section -# w/o the appropriate unlock. - -# CHECK: ERROR: Unterminated .bundle_lock - - .bundle_align_mode 3 - .section text1, "x" - imull $17, %ebx, %ebp - .bundle_lock - imull $17, %ebx, %ebp - - .section text2, "x" - imull $17, %ebx, %ebp - diff --git a/llvm/test/MC/X86/AlignedBundling/unlock-without-lock-error.s b/llvm/test/MC/X86/AlignedBundling/unlock-without-lock-error.s deleted file mode 100644 index 811ef95a451d4..0000000000000 --- a/llvm/test/MC/X86/AlignedBundling/unlock-without-lock-error.s +++ /dev/null @@ -1,11 +0,0 @@ -# RUN: not --crash llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s - -# .bundle_unlock can't come without a .bundle_lock before it - -# CHECK: ERROR: .bundle_unlock without matching lock - - .bundle_align_mode 3 - imull $17, %ebx, %ebp - .bundle_unlock - - diff --git a/llvm/test/MC/X86/align-branch-bundle.s b/llvm/test/MC/X86/align-branch-bundle.s deleted file mode 100644 index aba90f02a8a69..0000000000000 --- a/llvm/test/MC/X86/align-branch-bundle.s +++ /dev/null @@ -1,21 +0,0 @@ -# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=16 --x86-align-branch=fused+jcc --mc-relax-all %s | llvm-objdump --no-print-imm-hex -d --no-show-raw-insn - | FileCheck %s - -# Check using option --x86-align-branch-boundary=16 --x86-align-branch=fused+jcc --mc-relax-all with bundle won't make code crazy - -# CHECK: 0: pushq %rbp -# CHECK-NEXT: 1: testq $2, %rdx -# CHECK-NEXT: 8: jne -# CHECK-NEXT: e: nop -# CHECK-NEXT: 10: jle - - .text - .p2align 4 -foo: - push %rbp - # Will be bundle-aligning to 8 byte boundaries - .bundle_align_mode 3 - test $2, %rdx - jne foo -# This jle is 6 bytes long and should have started at 0xe, so two bytes -# of nop padding are inserted instead and it starts at 0x10 - jle foo