Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2174,6 +2174,49 @@ def mno_inline_all_stringops : Flag<["-"], "mno-inline-all-stringops">, Group; def malign_double : Flag<["-"], "malign-double">, Group, Flags<[CC1Option]>, HelpText<"Align doubles to two words in structs (x86 only)">; +def malign_branch_boundary_EQ + : Joined<["-"], "malign-branch-boundary=">, + Group, + Flags<[DriverOption, HelpHidden]>, + HelpText< + "Control how the assembler should align branches with segment " + "prefixes or NOP. The boundary's size must be a power of 2. It " + "should be 0 or no less than 32. Branches will be aligned within " + "the boundary of specifies size. -malign-branch-boundary=0 " + "doesn't align branches.">; +def malign_branch_EQ + : Joined<["-"], "malign-branch=">, + Group, + Flags<[DriverOption, HelpHidden]>, + HelpText< + "Specify types of branches to align (plus separated list of " + "types). The branches's types is combination of jcc, fused, " + "jmp, call, ret, indirect." + " jcc, which aligns conditional jumps; fused, which aligns fused " + "conditional jumps; jmp, which aligns unconditional jumps; call, " + "which aligns calls; ret, which aligns rets; indirect, which " + "aligns indirect jumps.">; +def malign_branch_prefix_size_EQ + : Joined<["-"], "malign-branch-prefix-size=">, + Group, + Flags<[DriverOption, CC1Option, HelpHidden]>, + HelpText<"Specify the maximum number of prefixes on an instruction to " + "align branches. The number should be between 0 and 5.">; +def mbranches_within_32B_boundaries + : Flag<["-"], "mbranches-within-32B-boundaries">, + Group, + Flags<[DriverOption]>, + HelpText< + "Aligns conditional jumps, fused conditional jumps, and " + "unconditional " + "jumps within 32 byte boundary with up to 5 segment prefixes on an " + "instruction. It is equivalent to -malign-branch-boundary=32, " + "-malign-branch=fused+jcc+jmp, -malign-branch-prefix-size=5.">; +def mno_branches_within_32B_boundaries + : Flag<["-"], "mno-branches-within-32B-boundaries">, + Group, + Flags<[DriverOption]>, + HelpText<"Opposite to -mbranches-within-32B_boundaries.">; def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group, Values<"soft,softfp,hard">; def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group; def mfpu_EQ : Joined<["-"], "mfpu=">, Group; Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -37,6 +37,7 @@ #include "llvm/Support/CodeGen.h" #include "llvm/Support/Compression.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/TargetParser.h" @@ -1905,8 +1906,53 @@ CmdArgs.push_back("-mbackchain"); } +static void AlignBranchesOptions(const Driver &D, const ArgList &Args, + ArgStringList &CmdArgs) { + if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_boundary_EQ)) { + StringRef Value = A->getValue(); + unsigned Num; + if (!Value.getAsInteger(10, Num) && Num >= 32 && llvm::isPowerOf2_32(Num)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString("-x86-align-branch-boundary=" + Value)); + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Value; + } + } + + if (const Arg *A = Args.getLastArg(options::OPT_malign_branch_EQ)) { + StringRef Value = A->getValue(); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-x86-align-branch=" + Value)); + } + + if (const Arg *A = + Args.getLastArg(options::OPT_malign_branch_prefix_size_EQ)) { + StringRef Value = A->getValue(); + unsigned Num; + if (!Value.getAsInteger(10, Num) && Num <= 5) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString("-x86-align-branch-prefix-size=" + Value)); + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Value; + } + } + + if (Args.hasFlag(options::OPT_mbranches_within_32B_boundaries, + options::OPT_mno_branches_within_32B_boundaries, false)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString("-x86-branches-within-32B-boundaries")); + } +} + void Clang::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { + AlignBranchesOptions(getToolChain().getDriver(), Args, CmdArgs); + if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) || Args.hasArg(options::OPT_mkernel) || Args.hasArg(options::OPT_fapple_kext)) @@ -6360,6 +6406,8 @@ void ClangAs::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { + AlignBranchesOptions(getToolChain().getDriver(), Args, CmdArgs); + if (Arg *A = Args.getLastArg(options::OPT_masm_EQ)) { StringRef Value = A->getValue(); if (Value == "intel" || Value == "att") { Index: clang/test/Driver/intel-align-branch.c =================================================================== --- /dev/null +++ clang/test/Driver/intel-align-branch.c @@ -0,0 +1,34 @@ +// RUN: %clang -target x86_64-unknown-unknown -malign-branch-boundary=32 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-BOUNDARY +// CHECK-BOUNDARY: "-mllvm" "-x86-align-branch-boundary=32" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=jcc -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-JCC +// CHECK-JCC: "-mllvm" "-x86-align-branch=jcc" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=fused -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-FUSED +// CHECK-FUSED: "-mllvm" "-x86-align-branch=fused" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=jmp -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-JMP +// CHECK-JMP: "-mllvm" "-x86-align-branch=jmp" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=call -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-CALL +// CHECK-CALL: "-mllvm" "-x86-align-branch=call" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=ret -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-RET +// CHECK-RET: "-mllvm" "-x86-align-branch=ret" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=indirect -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-INDIRECT +// CHECK-INDIRECT: "-mllvm" "-x86-align-branch=indirect" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=fused+jcc+jmp+ret+call+indirect -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-BRANCH +// CHECK-BRANCH: "-mllvm" "-x86-align-branch=fused+jcc+jmp+ret+call+indirect" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch-prefix-size=5 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-PREFIX +// CHECK-PREFIX: "-mllvm" "-x86-align-branch-prefix-size=5" +// +// RUN: %clang -target x86_64-unknown-unknown -mbranches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-TOTAL +// CHECK-TOTAL: "-mllvm" "-x86-branches-within-32B-boundaries" +// +// RUN: %clang -target x86_64-unknown-unknown -mno-branches-within-32B-boundaries -mbranches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-TOTAL2 +// CHECK-TOTAL2: "-mllvm" "-x86-branches-within-32B-boundaries" +// RUN: %clang -target x86_64-unknown-unknown -mbranches-within-32B-boundaries -mno-branches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-TOTAL3 +// CHECK-TOTAL3-NOT: "-mllvm" "-x86-branches-within-32B-boundaries" Index: clang/test/Driver/intel-align-branch.s =================================================================== --- /dev/null +++ clang/test/Driver/intel-align-branch.s @@ -0,0 +1,34 @@ +// RUN: %clang -target x86_64-unknown-unknown -malign-branch-boundary=32 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-BOUNDARY +// CHECK-BOUNDARY: "-mllvm" "-x86-align-branch-boundary=32" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=jcc -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-JCC +// CHECK-JCC: "-mllvm" "-x86-align-branch=jcc" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=fused -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-FUSED +// CHECK-FUSED: "-mllvm" "-x86-align-branch=fused" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=jmp -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-JMP +// CHECK-JMP: "-mllvm" "-x86-align-branch=jmp" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=call -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-CALL +// CHECK-CALL: "-mllvm" "-x86-align-branch=call" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=ret -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-RET +// CHECK-RET: "-mllvm" "-x86-align-branch=ret" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=indirect -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-INDIRECT +// CHECK-INDIRECT: "-mllvm" "-x86-align-branch=indirect" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch=fused+jcc+jmp+ret+call+indirect -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-BRANCH +// CHECK-BRANCH: "-mllvm" "-x86-align-branch=fused+jcc+jmp+ret+call+indirect" +// +// RUN: %clang -target x86_64-unknown-unknown -malign-branch-prefix-size=5 -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-PREFIX +// CHECK-PREFIX: "-mllvm" "-x86-align-branch-prefix-size=5" +// +// RUN: %clang -target x86_64-unknown-unknown -mbranches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-TOTAL +// CHECK-TOTAL: "-mllvm" "-x86-branches-within-32B-boundaries" +// +// RUN: %clang -target x86_64-unknown-unknown -mno-branches-within-32B-boundaries -mbranches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-TOTAL2 +// CHECK-TOTAL2: "-mllvm" "-x86-branches-within-32B-boundaries" +// RUN: %clang -target x86_64-unknown-unknown -mbranches-within-32B-boundaries -mno-branches-within-32B-boundaries -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-TOTAL3 +// CHECK-TOTAL3-NOT: "-mllvm" "-x86-branches-within-32B-boundaries" Index: llvm/include/llvm/MC/MCAsmBackend.h =================================================================== --- llvm/include/llvm/MC/MCAsmBackend.h +++ llvm/include/llvm/MC/MCAsmBackend.h @@ -51,6 +51,9 @@ const support::endianness Endian; + virtual void alignBranchesBegin(MCObjectStreamer &OS, const MCInst &Inst) {} + virtual void alignBranchesEnd(MCObjectStreamer &OS, const MCInst &Inst) {} + /// lifetime management virtual void reset() {} @@ -167,6 +170,14 @@ /// \return - True on success. virtual bool writeNopData(raw_ostream &OS, uint64_t Count) const = 0; + /// Write a segment prefix sequence of Count bytes to the given output. + /// + /// \return - True on success. + virtual bool writeSegmentPrefixData(raw_ostream &OS, uint64_t Count, + char Prefix) const { + return true; + } + /// Give backend an opportunity to finish layout after relaxation virtual void finishLayout(MCAssembler const &Asm, MCAsmLayout &Layout) const {} Index: llvm/include/llvm/MC/MCAssembler.h =================================================================== --- llvm/include/llvm/MC/MCAssembler.h +++ llvm/include/llvm/MC/MCAssembler.h @@ -154,6 +154,13 @@ VersionInfoType VersionInfo; + /// A lookup table from fragments to no-variable symbols, whose offset is 0. + /// This table is empty if there is no branch to be aligned. + // + // FIXME: We really would like this in target specific code rather than here. + mutable DenseMap> + DefiningSymbolMap; + /// Evaluate a fixup to a relocatable expression and the value which should be /// placed into the fixup. /// @@ -190,12 +197,21 @@ /// if any offsets were adjusted. bool layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec); + /// Scan the symbol table to update the lookup table from fragments to + /// no-variable symbols, whose offset is 0. + void updateSymbolMap() const; + + /// Move symbol from the fragment Src to fragment Dst to avoid instructions + /// jump to the internal of an instruction. + void moveSymbol(const MCFragment *Src, MCFragment *Dst) const; + bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF); bool relaxPaddingFragment(MCAsmLayout &Layout, MCPaddingFragment &PF); bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF); - + bool relaxMachineDependent(MCAsmLayout &Layout, + MCMachineDependentFragment &MF); bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF); bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout, MCDwarfCallFrameFragment &DF); Index: llvm/include/llvm/MC/MCFragment.h =================================================================== --- llvm/include/llvm/MC/MCFragment.h +++ llvm/include/llvm/MC/MCFragment.h @@ -41,6 +41,7 @@ FT_Dwarf, FT_DwarfFrame, FT_LEB, + FT_MachineDependent, FT_Padding, FT_SymbolId, FT_CVInlineLines, @@ -656,6 +657,107 @@ } }; +class MCMachineDependentFragment : public MCFragment { +public: + enum SubType : uint8_t { + // BranchPadding - The variable size frag to insert NOP before branch. + BranchPadding, + // BranchPrefix - The variable size frag to insert segment prefixes to an + // instruction. + BranchPrefix, + // BranchSplit - The 0 size frag to separate the instruction + // which is fused with the following conditional jump from fused jcc + BranchSplit, + // FusedJccPadding - The variable size frag to insert NOP before fused + // conditional jump. + FusedJccPadding + }; + + // AlignBoundarySize - The size of the boundary, within which the branches + // need to be aligned. + static unsigned AlignBoundarySize; + // AlignMaxPrefixSize - The maximum size of prefixes per instruction. + static unsigned AlignMaxPrefixSize; + // SubKind - The subtype of this fragment. + mutable SubType SubKind; + +private: + // Size - The size of the MCMachineDependentFragment. + unsigned Size = 0; + // Prefix - The value of the prefix to be emited if the subtype of this + // fragment is BranchPrefix. + char Prefix = 0; + // Branch - The fragment where the branch need to be aligned is. + const MCFragment *Branch = nullptr; + // ExistingSegmentPrefixSize - The size of existing segment prefixes of the + // first intruction in the next fragment. + unsigned ExistingSegmentPrefixSize = 0; + +public: + MCMachineDependentFragment(SubType SubKind, unsigned ExistingPrefixSize, + MCSection *Sec = nullptr) + : MCFragment(FT_MachineDependent, false, Sec), SubKind(SubKind), + ExistingSegmentPrefixSize(ExistingPrefixSize) {} + + StringRef getSubTypeName() const { + switch (SubKind) { + default: + llvm_unreachable("Unknown subtype of MCMachineDependentFragment"); + case BranchPadding: + return "BranchPadding"; + case BranchPrefix: + return "BranchPrefix"; + case BranchSplit: + return "BranchSplit"; + case FusedJccPadding: + return "FusedJccPadding"; + } + } + + void setSize(unsigned Value) { + assert(SubKind != BranchSplit && + "Should not set the size of BranchSplit Fragment"); + Size = Value; + } + + uint64_t getSize() const { return Size; } + + void setPrefix(char Value) { + assert(SubKind == BranchPrefix && + "Unsupported subtype of MCMachineDependentFragment"); + Prefix = Value; + } + + char getPrefix() const { + assert(SubKind == BranchPrefix && + "Unsupported subtype of MCMachineDependentFragment"); + return Prefix; + } + + unsigned getRemaingSegmentPrefix() const { + assert(SubKind == BranchPrefix && + "Unsupported subtype of MCMachineDependentFragment"); + return (AlignMaxPrefixSize >= ExistingSegmentPrefixSize) + ? (AlignMaxPrefixSize - ExistingSegmentPrefixSize) + : 0; + } + + void setBranch(const MCFragment *Fragment) { + assert(SubKind != BranchSplit && + "Unsupported subtype of MCMachineDependentFragment"); + Branch = Fragment; + } + + const MCFragment *getBranch() const { + assert(SubKind != BranchSplit && + "Unsupported subtype of MCMachineDependentFragment"); + return Branch; + } + + static bool classof(const MCFragment *F) { + return F->getKind() == MCFragment::FT_MachineDependent; + } +}; } // end namespace llvm #endif // LLVM_MC_MCFRAGMENT_H Index: llvm/lib/MC/MCAssembler.cpp =================================================================== --- llvm/lib/MC/MCAssembler.cpp +++ llvm/lib/MC/MCAssembler.cpp @@ -313,6 +313,9 @@ case MCFragment::FT_LEB: return cast(F).getContents().size(); + case MCFragment::FT_MachineDependent: + return cast(F).getSize(); + case MCFragment::FT_Padding: return cast(F).getSize(); @@ -612,6 +615,24 @@ break; } + case MCFragment::FT_MachineDependent: { + const MCMachineDependentFragment &MDF = cast(F); + if (FragmentSize == 0) + break; + if (MDF.SubKind == MCMachineDependentFragment::BranchPrefix) { + if (!Asm.getBackend().writeSegmentPrefixData(OS, FragmentSize, + MDF.getPrefix())) + report_fatal_error("unable to write segment prefix sequence of " + + Twine(FragmentSize) + " bytes"); + } else if (MDF.SubKind == MCMachineDependentFragment::BranchPadding || + MDF.SubKind == MCMachineDependentFragment::FusedJccPadding) { + if (!Asm.getBackend().writeNopData(OS, FragmentSize)) + report_fatal_error("unable to write nop sequence of " + + Twine(FragmentSize) + " bytes"); + } + break; + } + case MCFragment::FT_Padding: { if (!Asm.getBackend().writeNopData(OS, FragmentSize)) report_fatal_error("unable to write nop sequence of " + @@ -969,6 +990,141 @@ return OldSize != LF.getContents().size(); } +/// getFixedValue - Get the total size of the MachineDependentFragments from +/// the fragment operand to the fragment where the target branch is. +static unsigned getFixedValue(const MCMachineDependentFragment *MF) { + unsigned FixValue = 0; + const MCFragment *CurrFragment = MF; + const MCFragment *const BranchFragment = MF->getBranch(); + while (CurrFragment && CurrFragment != BranchFragment) { + if (auto *MCF = + dyn_cast_or_null(CurrFragment)) { + FixValue += MCF->getSize(); + } + CurrFragment = CurrFragment->getNextNode(); + } + return FixValue; +} + +/// mayCrossBoundary - Check if the branch with given address and size crosses +/// the boundary. +static bool mayCrossBoundary(unsigned StartAddr, unsigned Size) { + unsigned EndAddr = StartAddr + Size; + return StartAddr / MCMachineDependentFragment::AlignBoundarySize != + ((EndAddr - 1) / MCMachineDependentFragment::AlignBoundarySize); +} + +/// isAgainstBoundary - Check if the branch with given address and size is +/// against the boundary. +static bool isAgainstBoundary(unsigned StartAddr, unsigned Size) { + unsigned EndAddr = StartAddr + Size; + return EndAddr % MCMachineDependentFragment::AlignBoundarySize == 0; +} + +/// needPadding - Check if the branch with given address and size needs padding. +static bool needPadding(unsigned StartAddr, unsigned Size) { + return mayCrossBoundary(StartAddr, Size) || + isAgainstBoundary(StartAddr, Size); +} + +/// getPaddingSize - Get how many bytes need to be padded to align branch with +/// given address if the branch cross or is against the boundary. +static unsigned getPaddingSize(unsigned StartAddr) { + return MCMachineDependentFragment::AlignBoundarySize - + (StartAddr % MCMachineDependentFragment::AlignBoundarySize); +} + +/// getInstSize - Get the size of encoded instruction in the fragment. +static unsigned getInstSize(const MCFragment &F) { + switch (F.getKind()) { + default: + llvm_unreachable("Illegal fragment type"); + case MCFragment::FT_Data: + return cast(F).getContents().size(); + case MCFragment::FT_Relaxable: + return cast(F).getContents().size(); + case MCFragment::FT_CompactEncodedInst: + return cast(F).getContents().size(); + } +} + +/// If prefixes are inserted before an instruction, the symbol must be move +/// to the beginning of the prefixes. There are two reasons for this. First, +/// When prefixes are inserted before the first instruction of the .text +/// section, the prefixes would appear in front of the .text if the symbol .text +/// was not moved, which was obviously wrong. Second, the instruction would have +/// two entry points, one is the beginning of prefixes when falled through, one +/// is the address of the symbol, which would casuse performance regression. +void MCAssembler::moveSymbol(const MCFragment *Src, MCFragment *Dst) const { + if (!(Src && Dst && Dst->getKind() == MCFragment::FT_MachineDependent)) + return; + updateSymbolMap(); + for (auto *Symb : DefiningSymbolMap[Src]) { + Symb->setFragment(Dst); + } + return; +} + +void MCAssembler::updateSymbolMap() const { + if(!DefiningSymbolMap.empty()) return; + for (const MCSymbol &Symbol : symbols()) { + if (Symbol.isInSection() && !Symbol.isVariable() && + Symbol.getOffset() == 0) { + DefiningSymbolMap[Symbol.getFragment()].push_back(&Symbol); + } + } + return; +} + +bool MCAssembler::relaxMachineDependent(MCAsmLayout &Layout, + MCMachineDependentFragment &MF) { + // BranchSplit fragment should not relax since it is a zero-size fragment. + // The MCMachineDependentFragment which doesn't has a target branch to be + // aligned should not relax either. + if (MF.SubKind == MCMachineDependentFragment::BranchSplit || !MF.getBranch()) + return false; + unsigned OldSize = MF.getSize(); + const MCFragment *BranchFragment = MF.getBranch(); + const MCMachineDependentFragment *HintFragment = + cast(BranchFragment->getPrevNode()); + unsigned AlignedSize = getInstSize(*BranchFragment); + unsigned AlignedOffset = Layout.getFragmentOffset(BranchFragment); + // If the branch is macro-fused, it's address and size need to be fixed. + if (HintFragment->SubKind == MCMachineDependentFragment::BranchSplit) { + unsigned CmpSize = getInstSize(*(HintFragment->getPrevNode())); + AlignedSize += CmpSize; + AlignedOffset -= CmpSize; + } + unsigned FixedValue = getFixedValue(&MF); + AlignedOffset -= FixedValue; + unsigned NewSize = 0; + if (needPadding(AlignedOffset, AlignedSize)) { + NewSize = getPaddingSize(AlignedOffset); + } + if (MF.SubKind == MCMachineDependentFragment::BranchPrefix) { + unsigned NextFragmentSize = getInstSize(*(MF.getNextNode())); + // If there is hard-coded assembly code, the size of the fragment may + // exceed 15. Prefixed shouldn't be inserted in this condition since the + // length of first instruction in the fragment is unknown. + if (NextFragmentSize >= 15) + NewSize = 0; + else { + NewSize = std::min( + {NewSize, 15 - NextFragmentSize, MF.getRemaingSegmentPrefix()}); + } + } + if (NewSize != OldSize) { + MF.setSize(NewSize); + if (OldSize == 0) { + moveSymbol(MF.getNextNode(), &MF); + } + Layout.invalidateFragmentsFrom(&MF); + return true; + } else { + return false; + } +} + bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF) { MCContext &Context = Layout.getAssembler().getContext(); @@ -1085,6 +1241,10 @@ case MCFragment::FT_LEB: RelaxedFrag = relaxLEB(Layout, *cast(I)); break; + case MCFragment::FT_MachineDependent: + RelaxedFrag = + relaxMachineDependent(Layout, *cast(I)); + break; case MCFragment::FT_Padding: RelaxedFrag = relaxPaddingFragment(Layout, *cast(I)); break; Index: llvm/lib/MC/MCFragment.cpp =================================================================== --- llvm/lib/MC/MCFragment.cpp +++ llvm/lib/MC/MCFragment.cpp @@ -28,6 +28,8 @@ #include using namespace llvm; +unsigned MCMachineDependentFragment::AlignBoundarySize = 0; +unsigned MCMachineDependentFragment::AlignMaxPrefixSize = 0; MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) { // Compute the section layout order. Virtual sections must go last. @@ -275,6 +277,9 @@ case FT_LEB: delete cast(this); return; + case FT_MachineDependent: + delete cast(this); + return; case FT_Padding: delete cast(this); return; @@ -322,6 +327,7 @@ case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break; case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break; case MCFragment::FT_LEB: OS << "MCLEBFragment"; break; + case MCFragment::FT_MachineDependent: OS<<"MCMachineDependentFragment"; break; case MCFragment::FT_Padding: OS << "MCPaddingFragment"; break; case MCFragment::FT_SymbolId: OS << "MCSymbolIdFragment"; break; case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break; @@ -422,6 +428,13 @@ OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned(); break; } + case MCFragment::FT_MachineDependent: { + const MCMachineDependentFragment *MF = + cast(this); + OS << "\n "; + OS << " Subtype:" << MF->getSubTypeName() << " Size:" << MF->getSize(); + break; + } case MCFragment::FT_Padding: { const MCPaddingFragment *F = cast(this); OS << "\n "; Index: llvm/lib/MC/MCObjectStreamer.cpp =================================================================== --- llvm/lib/MC/MCObjectStreamer.cpp +++ llvm/lib/MC/MCObjectStreamer.cpp @@ -316,7 +316,9 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { getAssembler().getBackend().handleCodePaddingInstructionBegin(Inst); + getAssembler().getBackend().alignBranchesBegin(*this, Inst); EmitInstructionImpl(Inst, STI); + getAssembler().getBackend().alignBranchesEnd(*this, Inst); getAssembler().getBackend().handleCodePaddingInstructionEnd(Inst); } Index: llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -17,13 +17,18 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCMachObjectWriter.h" +#include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/TargetRegistry.h" + using namespace llvm; static unsigned getFixupKindSize(unsigned Kind) { @@ -61,6 +66,81 @@ } namespace { +class X86AlignBranchKind { +private: + uint8_t AlignBranchKind = 0; + +public: + enum Flag : uint8_t { + AlignBranchNone = 0, + AlignBranchFused = 1U << 0, + AlignBranchJcc = 1U << 1, + AlignBranchJmp = 1U << 2, + AlignBranchCall = 1U << 3, + AlignBranchRet = 1U << 4, + AlignBranchIndirect = 1U << 5 + }; + + void operator=(const std::string &Val) { + if (Val.empty()) + return; + SmallVector BranchTypes; + StringRef(Val).split(BranchTypes, '+', -1, false); + for (auto BranchType : BranchTypes) { + if (BranchType == "fused") + addKind(AlignBranchFused); + else if (BranchType == "jcc") + addKind(AlignBranchJcc); + else if (BranchType == "jmp") + addKind(AlignBranchJmp); + else if (BranchType == "call") + addKind(AlignBranchCall); + else if (BranchType == "ret") + addKind(AlignBranchRet); + else if (BranchType == "indirect") + addKind(AlignBranchIndirect); + } + } + + operator uint8_t() const { return AlignBranchKind; } + void addKind(Flag Value) { AlignBranchKind |= Value; } +}; + +X86AlignBranchKind X86AlignBranchKindLoc; + +cl::opt X86AlignBranchBoundary( + "x86-align-branch-boundary", cl::init(0), cl::Hidden, + cl::desc("Control how the assembler should align branches with segment " + "prefixes or NOP. The boundary's size must be a power of 2. It " + "should be 0 or no less than 32. Branches will be aligned within " + "the boundary of specifies size. -x86-align-branch-boundary=0 " + "doesn't align branches.")); + +cl::opt> X86AlignBranch( + "x86-align-branch", + cl::desc("Specify types of branches to align (plus separated list of " + "types). The branches's types is combination of jcc, fused, " + "jmp, call, ret, indirect."), + cl::Hidden, + cl::value_desc( + "jcc, which aligns conditional jumps; fused, which aligns fused " + "conditional jumps; jmp, which aligns unconditional jumps; call, " + "which aligns calls; ret, which aligns rets; indirect, which " + "aligns indirect jumps."), + cl::location(X86AlignBranchKindLoc)); + +cl::opt X86AlignBranchPrefixSize( + "x86-align-branch-prefix-size", cl::init(0), cl::Hidden, + cl::desc("Specify the maximum number of prefixes on an instruction to " + "align branches. The number should be between 0 and 5.")); + +cl::opt X86AlignBranchWithin32BBoundaries( + "x86-branches-within-32B-boundaries", cl::init(false), + cl::desc( + "Aligns conditional jumps, fused conditional jumps, and unconditional " + "jumps within 32 byte boundary with up to 5 segment prefixes on an " + "instruction. It is equivalent to -x86-align-branch-boundary=32, " + "-x86-align-branch=fused+jcc+jmp, -x86-align-branch-prefix-size=5.")); class X86ELFObjectWriter : public MCELFObjectTargetWriter { public: @@ -71,9 +151,45 @@ class X86AsmBackend : public MCAsmBackend { const MCSubtargetInfo &STI; + const MCInstrInfo &MCII; + X86AlignBranchKind AlignBranchType; + unsigned AlignBoundarySize = 0; + unsigned AlignMaxPrefixSize = 0; + + bool isTLSCall(const MCInst &MI) const; + bool isFirstMacroFusibleInst(const MCInst &Inst) const; + bool isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const; + char choosePrefixValue(const MCInst &MI) const; + unsigned getSegmentPrefixSize(const MCInst &MI) const; + bool isRIPRelative(const MCInst &MI) const; + + bool needAlign(const MCAssembler &Assembler, MCSection *Sec) const; + bool needAlignInst(const MCInst &Inst) const; + bool shouldAddPrefix(const MCInst& Inst) const; + std::vector PendingAlignmentFragments; + MCInst PrevInst; + public: X86AsmBackend(const Target &T, const MCSubtargetInfo &STI) - : MCAsmBackend(support::little), STI(STI) {} + : MCAsmBackend(support::little), STI(STI), + MCII(*(T.createMCInstrInfo())) { + if (X86AlignBranchWithin32BBoundaries) { + AlignBoundarySize = 32; + AlignBranchType.addKind(X86AlignBranchKind::AlignBranchFused); + AlignBranchType.addKind(X86AlignBranchKind::AlignBranchJcc); + AlignBranchType.addKind(X86AlignBranchKind::AlignBranchJmp); + AlignMaxPrefixSize = 5; + } else { + AlignBoundarySize = X86AlignBranchBoundary; + AlignBranchType = X86AlignBranchKindLoc; + AlignMaxPrefixSize = X86AlignBranchPrefixSize; + } + MCMachineDependentFragment::AlignBoundarySize = AlignBoundarySize; + MCMachineDependentFragment::AlignMaxPrefixSize = AlignMaxPrefixSize; + } + + void alignBranchesBegin(MCObjectStreamer &OS, const MCInst &Inst) override; + void alignBranchesEnd(MCObjectStreamer &OS, const MCInst &Inst) override; unsigned getNumFixupKinds() const override { return X86::NumTargetFixupKinds; @@ -136,6 +252,8 @@ MCInst &Res) const override; bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + bool writeSegmentPrefixData(raw_ostream &OS, uint64_t Count, + char Prefix) const override; }; } // end anonymous namespace @@ -243,6 +361,282 @@ return getRelaxedOpcodeBranch(Inst, is16BitMode); } +static X86::CondCode getCondFromBranch(const MCInst &MI, + const MCInstrInfo &MCII) { + unsigned Opcode = MI.getOpcode(); + switch (Opcode) { + default: + return X86::COND_INVALID; + case X86::JCC_1: { + const MCInstrDesc &Desc = MCII.get(Opcode); + return static_cast( + MI.getOperand(Desc.getNumOperands() - 1).getImm()); + } + } +} + +static X86::SecondMacroFusionInstKind +classifySecondInstInMacroFusion(const MCInst &MI, const MCInstrInfo &MCII) { + X86::CondCode CC = getCondFromBranch(MI, MCII); + return classifySecondCondCodeInMacroFusion(CC); +} + +bool X86AsmBackend::isTLSCall(const MCInst &MI) const { + const MCInstrDesc &InstDesc = MCII.get(MI.getOpcode()); + if (!InstDesc.isCall()) + return false; + for (auto &Operand : MI) { + if (Operand.isExpr()) { + const MCExpr &Expr = *Operand.getExpr(); + if (Expr.getKind() == MCExpr::SymbolRef && + cast(*Operand.getExpr()) + .getSymbol() + .getName() + .contains("__tls_get_addr")) + return true; + } + } + return false; +} + +/// isFirstMacroFusibleInst - Check if the instruction is valid as the first +/// instruction in macro fusion. +bool X86AsmBackend::isFirstMacroFusibleInst(const MCInst &Inst) const { + // An Intel instruction with RIP relative addressing is not macro fusible. + if (isRIPRelative(Inst)) + return false; + X86::FirstMacroFusionInstKind FIK = + X86::classifyFirstOpcodeInMacroFusion(Inst.getOpcode()); + return FIK != X86::FirstMacroFusionInstKind::Invalid; +} + +/// isMacroFused - Check if the two instructions are macro-fused. +bool X86AsmBackend::isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const { + const MCInstrDesc &InstDesc = MCII.get(Jcc.getOpcode()); + if (!InstDesc.isConditionalBranch()) + return false; + if (!isFirstMacroFusibleInst(Cmp)) + return false; + const X86::FirstMacroFusionInstKind CmpKind = + X86::classifyFirstOpcodeInMacroFusion(Cmp.getOpcode()); + const X86::SecondMacroFusionInstKind BranchKind = + classifySecondInstInMacroFusion(Jcc, MCII); + return X86::isMacroFused(CmpKind, BranchKind); +} + +/// choosePrefixValue - Choose which prefix should be inserted before the +/// instruction. The choice of prefixes are: +/// a. Use the existing segment prefix if there is one. +/// b. Use CS segment prefix in 64-bit mode. +/// c. In 32-bit mode, use SS segment prefix with ESP/EBP base register and use +/// DS segment prefix without ESP/EBP base register. +char X86AsmBackend::choosePrefixValue(const MCInst &MI) const { + for (const auto &Operand : MI) { + if (Operand.isReg()) + switch (Operand.getReg()) { + default: + break; + case X86::CS: + return 0x2e; + case X86::SS: + return 0x36; + case X86::DS: + return 0x3e; + case X86::ES: + return 0x26; + case X86::FS: + return 0x64; + case X86::GS: + return 0x65; + } + } + if (STI.getFeatureBits()[X86::Mode64Bit]) + return 0x2e; + + unsigned Opcode = MI.getOpcode(); + const MCInstrDesc &Desc = MCII.get(Opcode); + uint64_t TSFlags = Desc.TSFlags; + int MemoryOperand = X86II::getMemoryOperandNo(TSFlags); + if (MemoryOperand >= 0) { + unsigned CurOp = X86II::getOperandBias(Desc); + unsigned BaseRegNum = MemoryOperand + CurOp + X86::AddrBaseReg; + unsigned BaseReg = MI.getOperand(BaseRegNum).getReg(); + if (BaseReg == X86::ESP || BaseReg == X86::EBP) + return 0x36; + } + return 0x3e; +} + +/// getSegmentPrefixSize - Count the existing segment prefixes of the +/// instruction. +unsigned X86AsmBackend::getSegmentPrefixSize(const MCInst &MI) const { + unsigned Size = 0; + for (const auto &Operand : MI) { + if (Operand.isReg()) { + unsigned Reg = Operand.getReg(); + if (Reg == X86::CS || Reg == X86::SS || Reg == X86::DS || + Reg == X86::ES || Reg == X86::FS || Reg == X86::GS) + ++Size; + } + } + return Size; +} + +/// isRIPRelative - Check if the instruction operand is RIP relative addressing. +bool X86AsmBackend::isRIPRelative(const MCInst &MI) const { + unsigned Opcode = MI.getOpcode(); + const MCInstrDesc &Desc = MCII.get(Opcode); + uint64_t TSFlags = Desc.TSFlags; + unsigned CurOp = X86II::getOperandBias(Desc); + int MemoryOperand = X86II::getMemoryOperandNo(TSFlags); + if (MemoryOperand >= 0) { + unsigned BaseRegNum = MemoryOperand + CurOp + X86::AddrBaseReg; + unsigned BaseReg = MI.getOperand(BaseRegNum).getReg(); + if (BaseReg == X86::RIP) + return true; + } + return false; +} + +bool X86AsmBackend::needAlign(const MCAssembler &Assembler, + MCSection *Sec) const { + // To be Done: Currently don't deal with Bundle cases. + if (Assembler.isBundlingEnabled() && Sec->isBundleLocked()) + return false; + + if (!(STI.getFeatureBits()[X86::Mode64Bit] || + STI.getFeatureBits()[X86::Mode32Bit])) + return false; + return AlignBoundarySize != 0 && + AlignBranchType != X86AlignBranchKind::AlignBranchNone; +} + +/// needAlignInst - Check if the instruction operand needs to be aligned. +/// Padding is disabled before tls_get_addr calls to keep TLS instruction +/// sequence unchanged. +bool X86AsmBackend::needAlignInst(const MCInst &Inst) const { + const MCInstrDesc &InstDesc = MCII.get(Inst.getOpcode()); + return (InstDesc.isConditionalBranch() && + (AlignBranchType & X86AlignBranchKind::AlignBranchJcc)) || + (InstDesc.isUnconditionalBranch() && + (AlignBranchType & X86AlignBranchKind::AlignBranchJmp)) || + (InstDesc.isCall() && !isTLSCall(Inst) && + (AlignBranchType & X86AlignBranchKind::AlignBranchCall)) || + (InstDesc.isReturn() && + (AlignBranchType & X86AlignBranchKind::AlignBranchRet)) || + (InstDesc.isIndirectBranch() && + (AlignBranchType & X86AlignBranchKind::AlignBranchIndirect)); +} + +bool X86AsmBackend::shouldAddPrefix(const MCInst &Inst) const { + // The longer the instruction, the easier it is to cross 32-Byte boundary. So + // prefixes should not be inserted before branch, call or ret even if these + // instructions are not asked to be aligned. + const MCInstrDesc &InstDesc = MCII.get(Inst.getOpcode()); + if (InstDesc.isBranch() || InstDesc.isCall() || InstDesc.isReturn()) + return false; + + for (auto &Operand : Inst) { + if (Operand.isExpr()) { + const MCExpr &Expr = *Operand.getExpr(); + if (Expr.getKind() == MCExpr::SymbolRef && + cast(*Operand.getExpr()).getKind() != + MCSymbolRefExpr::VK_None) + return false; + } + } + return true; +} + +/// alignBranchesBegin - Insert MCMachineDependentFragment before instructions +/// to align branches. +void X86AsmBackend::alignBranchesBegin(MCObjectStreamer &OS, + const MCInst &Inst) { + MCAssembler &Assembler = OS.getAssembler(); + MCSection *Sec = OS.getCurrentSectionOnly(); + + if (!needAlign(Assembler, Sec)) + return; + + MCFragment *CF = OS.getCurrentFragment(); + // If there is a fragment not holding instructions between + // MCMachineDependentFragment and target branch, we won't relax the + // MCMachineDependentFragment to avoid falling into an infinite loop. + if (CF->getKind() != MCFragment::FT_Data && + CF->getKind() != MCFragment::FT_MachineDependent && + CF->getKind() != MCFragment::FT_Relaxable && + CF->getKind() != MCFragment::FT_CompactEncodedInst) { + PendingAlignmentFragments.clear(); + } + MCFragment *PF = CF ? CF->getPrevNode() : nullptr; + bool IsPFFusedJccPadding = isa_and_nonnull(PF) && + cast(PF)->SubKind == + MCMachineDependentFragment::FusedJccPadding; + bool IsFused = isMacroFused(PrevInst, Inst); + if (IsPFFusedJccPadding && !IsFused) { + // Turn the previous FusedJccPadding into BranchPrefix if the instruction is + // not macro fused indeed. + cast(PF)->SubKind = + MCMachineDependentFragment::BranchPrefix; + cast(PF)->setPrefix( + choosePrefixValue(PrevInst)); + } + PrevInst = Inst; + unsigned SegmentPrefixSize = getSegmentPrefixSize(Inst); + if (isFirstMacroFusibleInst(Inst) && + (AlignBranchType & X86AlignBranchKind::AlignBranchFused)) { + // Insert FusedJccPadding if the instruction to be emitted is valid as + // first instruction in macro fusion. The inserted FusedJccPadding will + // turn to BranchPrefix later if the instruction is not macro fused indeed. + OS.insert(new MCMachineDependentFragment( + MCMachineDependentFragment::FusedJccPadding, SegmentPrefixSize)); + } else if (IsPFFusedJccPadding && IsFused) { + // Insert BranchSplit between the first intruction in macro fusion and + // the second instruction in macro fusion. + OS.insert(new MCMachineDependentFragment( + MCMachineDependentFragment::BranchSplit, SegmentPrefixSize)); + return; + } else if (needAlignInst(Inst)) { + // Insert BranchPadding before the instruction need to be aligned. + OS.insert(new MCMachineDependentFragment( + MCMachineDependentFragment::BranchPadding, SegmentPrefixSize)); + } else { + auto *MF = new MCMachineDependentFragment( + MCMachineDependentFragment::BranchPrefix, SegmentPrefixSize); + // Choose the value of the prefix by the instruction to be emited. + MF->setPrefix(choosePrefixValue(Inst)); + // Insert BranchPrefix to align the next branch. + OS.insert(MF); + if (!shouldAddPrefix(Inst)) + return; + } + // Pend the BranchPrefix, BranchPadding and FusedJccPadding since we + // haven't known the fragment where the next branch is yet. + PendingAlignmentFragments.push_back( + cast(OS.getCurrentFragment())); + return; +} + +/// alignBranchesEnd - Set the target branches for BranchPrefix, BranchPadding +/// and FusedJccPadding. +void X86AsmBackend::alignBranchesEnd(MCObjectStreamer &OS, const MCInst &Inst) { + MCSection *Sec = OS.getCurrentSectionOnly(); + MCAssembler &Assembler = OS.getAssembler(); + if (!needAlign(Assembler, Sec)) + return; + if (!needAlignInst(Inst)) + return; + MCFragment *CF = OS.getCurrentFragment(); + for (MCMachineDependentFragment *MDF : PendingAlignmentFragments) { + MDF->setBranch(CF); + } + PendingAlignmentFragments.clear(); + + // Update the maximum alignment on the current section if necessary. + if (AlignBoundarySize > Sec->getAlignment()) + Sec->setAlignment(Align(AlignBoundarySize)); +} + Optional X86AsmBackend::getFixupKind(StringRef Name) const { if (STI.getTargetTriple().isOSBinFormatELF()) { if (STI.getTargetTriple().getArch() == Triple::x86_64) { @@ -311,6 +705,21 @@ Res.setOpcode(RelaxedOp); } +/// Write a sequence of segment prefixes to the output, covering \p Count +/// bytes. +/// \return - true on success, false on failure +bool X86AsmBackend::writeSegmentPrefixData(raw_ostream &OS, uint64_t Count, + char Prefix) const { + // The function should only write segment prefixes. + // CS:0x2e, SS:0x36, DS:0x3e, ES:0x26, FS:0x64, GS:0x65 + if (!(Prefix == 0x2e || Prefix == 0x36 || Prefix == 0x3e || Prefix == 0x26 || + Prefix == 0x64 || Prefix == 0x65)) + return false; + for (uint64_t i = 0; i < Count; ++i) + OS << Prefix; + return true; +} + /// Write a sequence of optimal nops to the output, covering \p Count /// bytes. /// \return - true on success, false on failure Index: llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -101,6 +101,260 @@ COND_INVALID }; + + // The classification for the first instruction in macro fusion. + enum class FirstMacroFusionInstKind { + // TEST + Test, + // CMP + Cmp, + // AND + And, + // ADD, SUB + AddSub, + // INC, DEC + IncDec, + // Not valid as a first macro fusion instruction + Invalid + }; + + enum class SecondMacroFusionInstKind { + // JA, JB and variants. + AB, + // JE, JL, JG and variants. + ELG, + // JS, JP, JO and variants + SPO, + // Not a fusible jump. + Invalid, + }; + + /// classifyFirstOpcodeInMacroFusion - return the type of the first + /// instruction in macro-fusion. + inline FirstMacroFusionInstKind + classifyFirstOpcodeInMacroFusion(unsigned Opcode) { + switch (Opcode) { + default: + return FirstMacroFusionInstKind::Invalid; + // TEST + case X86::TEST16i16: + case X86::TEST16mr: + case X86::TEST16ri: + case X86::TEST16rr: + case X86::TEST32i32: + case X86::TEST32mr: + case X86::TEST32ri: + case X86::TEST32rr: + case X86::TEST64i32: + case X86::TEST64mr: + case X86::TEST64ri32: + case X86::TEST64rr: + case X86::TEST8i8: + case X86::TEST8mr: + case X86::TEST8ri: + case X86::TEST8rr: + return FirstMacroFusionInstKind::Test; + case X86::AND16i16: + case X86::AND16mr: + case X86::AND16ri: + case X86::AND16ri8: + case X86::AND16rm: + case X86::AND16rr: + case X86::AND16rr_REV: + case X86::AND32i32: + case X86::AND32mr: + case X86::AND32ri: + case X86::AND32ri8: + case X86::AND32rm: + case X86::AND32rr: + case X86::AND32rr_REV: + case X86::AND64i32: + case X86::AND64mr: + case X86::AND64ri32: + case X86::AND64ri8: + case X86::AND64rm: + case X86::AND64rr: + case X86::AND64rr_REV: + case X86::AND8i8: + case X86::AND8mr: + case X86::AND8ri: + case X86::AND8ri8: + case X86::AND8rm: + case X86::AND8rr: + case X86::AND8rr_REV: + return FirstMacroFusionInstKind::And; + // CMP + case X86::CMP16i16: + case X86::CMP16mr: + case X86::CMP16ri: + case X86::CMP16ri8: + case X86::CMP16rm: + case X86::CMP16rr: + case X86::CMP16rr_REV: + case X86::CMP32i32: + case X86::CMP32mr: + case X86::CMP32ri: + case X86::CMP32ri8: + case X86::CMP32rm: + case X86::CMP32rr: + case X86::CMP32rr_REV: + case X86::CMP64i32: + case X86::CMP64mr: + case X86::CMP64ri32: + case X86::CMP64ri8: + case X86::CMP64rm: + case X86::CMP64rr: + case X86::CMP64rr_REV: + case X86::CMP8i8: + case X86::CMP8mr: + case X86::CMP8ri: + case X86::CMP8ri8: + case X86::CMP8rm: + case X86::CMP8rr: + case X86::CMP8rr_REV: + return FirstMacroFusionInstKind::Cmp; + // ADD + case X86::ADD16i16: + case X86::ADD16mr: + case X86::ADD16ri: + case X86::ADD16ri8: + case X86::ADD16rm: + case X86::ADD16rr: + case X86::ADD16rr_REV: + case X86::ADD32i32: + case X86::ADD32mr: + case X86::ADD32ri: + case X86::ADD32ri8: + case X86::ADD32rm: + case X86::ADD32rr: + case X86::ADD32rr_REV: + case X86::ADD64i32: + case X86::ADD64mr: + case X86::ADD64ri32: + case X86::ADD64ri8: + case X86::ADD64rm: + case X86::ADD64rr: + case X86::ADD64rr_REV: + case X86::ADD8i8: + case X86::ADD8mr: + case X86::ADD8ri: + case X86::ADD8ri8: + case X86::ADD8rm: + case X86::ADD8rr: + case X86::ADD8rr_REV: + // SUB + case X86::SUB16i16: + case X86::SUB16mr: + case X86::SUB16ri: + case X86::SUB16ri8: + case X86::SUB16rm: + case X86::SUB16rr: + case X86::SUB16rr_REV: + case X86::SUB32i32: + case X86::SUB32mr: + case X86::SUB32ri: + case X86::SUB32ri8: + case X86::SUB32rm: + case X86::SUB32rr: + case X86::SUB32rr_REV: + case X86::SUB64i32: + case X86::SUB64mr: + case X86::SUB64ri32: + case X86::SUB64ri8: + case X86::SUB64rm: + case X86::SUB64rr: + case X86::SUB64rr_REV: + case X86::SUB8i8: + case X86::SUB8mr: + case X86::SUB8ri: + case X86::SUB8ri8: + case X86::SUB8rm: + case X86::SUB8rr: + case X86::SUB8rr_REV: + return FirstMacroFusionInstKind::AddSub; + // INC + case X86::INC16r: + case X86::INC16r_alt: + case X86::INC32r: + case X86::INC32r_alt: + case X86::INC64r: + case X86::INC8r: + // DEC + case X86::DEC16r: + case X86::DEC16r_alt: + case X86::DEC32r: + case X86::DEC32r_alt: + case X86::DEC64r: + case X86::DEC8r: + return FirstMacroFusionInstKind::IncDec; + } + } + + /// classifySecondCondCodeInMacroFusion - return the type of the second + /// instruction in macro-fusion. + inline SecondMacroFusionInstKind + classifySecondCondCodeInMacroFusion(X86::CondCode CC) { + if (CC == X86::COND_INVALID) + return SecondMacroFusionInstKind::Invalid; + + switch (CC) { + default: + return SecondMacroFusionInstKind::Invalid; + // JE,JZ + case X86::COND_E: + // JNE,JNZ + case X86::COND_NE: + // JL,JNGE + case X86::COND_L: + // JLE,JNG + case X86::COND_LE: + // JG,JNLE + case X86::COND_G: + // JGE,JNL + case X86::COND_GE: + return SecondMacroFusionInstKind::ELG; + // JB,JC + case X86::COND_B: + // JNA,JBE + case X86::COND_BE: + // JA,JNBE + case X86::COND_A: + // JAE,JNC,JNB + case X86::COND_AE: + return SecondMacroFusionInstKind::AB; + // JS + case X86::COND_S: + // JNS + case X86::COND_NS: + // JP,JPE + case X86::COND_P: + // JNP,JPO + case X86::COND_NP: + // JO + case X86::COND_O: + // JNO + case X86::COND_NO: + return SecondMacroFusionInstKind::SPO; + } + } + + inline bool isMacroFused(FirstMacroFusionInstKind FirstKind, + SecondMacroFusionInstKind SecondKind) { + switch (FirstKind) { + case X86::FirstMacroFusionInstKind::Test: + case X86::FirstMacroFusionInstKind::And: + return true; + case X86::FirstMacroFusionInstKind::Cmp: + case X86::FirstMacroFusionInstKind::AddSub: + return SecondKind == X86::SecondMacroFusionInstKind::AB || + SecondKind == X86::SecondMacroFusionInstKind::ELG; + case X86::FirstMacroFusionInstKind::IncDec: + return SecondKind == X86::SecondMacroFusionInstKind::ELG; + case X86::FirstMacroFusionInstKind::Invalid: + return false; + } + llvm_unreachable("unknown fusion type"); + } } // end namespace X86; /// X86II - This namespace holds all of the target specific flags that Index: llvm/lib/Target/X86/X86InstrInfo.td =================================================================== --- llvm/lib/Target/X86/X86InstrInfo.td +++ llvm/lib/Target/X86/X86InstrInfo.td @@ -1017,7 +1017,7 @@ def X86_COND_O : PatLeaf<(i8 0)>; def X86_COND_NO : PatLeaf<(i8 1)>; def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C -def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC +def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC,COND_NB def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z def X86_COND_NE : PatLeaf<(i8 5)>; // alt. COND_NZ def X86_COND_BE : PatLeaf<(i8 6)>; // alt. COND_NA Index: llvm/lib/Target/X86/X86MacroFusion.cpp =================================================================== --- llvm/lib/Target/X86/X86MacroFusion.cpp +++ llvm/lib/Target/X86/X86MacroFusion.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "MCTargetDesc/X86BaseInfo.h" #include "X86MacroFusion.h" #include "X86Subtarget.h" #include "llvm/CodeGen/MacroFusion.h" @@ -18,160 +19,13 @@ using namespace llvm; -namespace { - -// The classification for the first instruction. -enum class FirstInstrKind { Test, Cmp, And, ALU, IncDec, Invalid }; - -// The classification for the second instruction (jump). -enum class JumpKind { - // JE, JL, JG and variants. - ELG, - // JA, JB and variants. - AB, - // JS, JP, JO and variants. - SPO, - // Not a fusable jump. - Invalid, -}; - -} // namespace - -static FirstInstrKind classifyFirst(const MachineInstr &MI) { - switch (MI.getOpcode()) { - default: - return FirstInstrKind::Invalid; - case X86::TEST8rr: - case X86::TEST16rr: - case X86::TEST32rr: - case X86::TEST64rr: - case X86::TEST8ri: - case X86::TEST16ri: - case X86::TEST32ri: - case X86::TEST64ri32: - case X86::TEST8mr: - case X86::TEST16mr: - case X86::TEST32mr: - case X86::TEST64mr: - return FirstInstrKind::Test; - case X86::AND16ri: - case X86::AND16ri8: - case X86::AND16rm: - case X86::AND16rr: - case X86::AND32ri: - case X86::AND32ri8: - case X86::AND32rm: - case X86::AND32rr: - case X86::AND64ri32: - case X86::AND64ri8: - case X86::AND64rm: - case X86::AND64rr: - case X86::AND8ri: - case X86::AND8rm: - case X86::AND8rr: - return FirstInstrKind::And; - case X86::CMP16ri: - case X86::CMP16ri8: - case X86::CMP16rm: - case X86::CMP16rr: - case X86::CMP16mr: - case X86::CMP32ri: - case X86::CMP32ri8: - case X86::CMP32rm: - case X86::CMP32rr: - case X86::CMP32mr: - case X86::CMP64ri32: - case X86::CMP64ri8: - case X86::CMP64rm: - case X86::CMP64rr: - case X86::CMP64mr: - case X86::CMP8ri: - case X86::CMP8rm: - case X86::CMP8rr: - case X86::CMP8mr: - return FirstInstrKind::Cmp; - case X86::ADD16ri: - case X86::ADD16ri8: - case X86::ADD16ri8_DB: - case X86::ADD16ri_DB: - case X86::ADD16rm: - case X86::ADD16rr: - case X86::ADD16rr_DB: - case X86::ADD32ri: - case X86::ADD32ri8: - case X86::ADD32ri8_DB: - case X86::ADD32ri_DB: - case X86::ADD32rm: - case X86::ADD32rr: - case X86::ADD32rr_DB: - case X86::ADD64ri32: - case X86::ADD64ri32_DB: - case X86::ADD64ri8: - case X86::ADD64ri8_DB: - case X86::ADD64rm: - case X86::ADD64rr: - case X86::ADD64rr_DB: - case X86::ADD8ri: - case X86::ADD8ri_DB: - case X86::ADD8rm: - case X86::ADD8rr: - case X86::ADD8rr_DB: - case X86::SUB16ri: - case X86::SUB16ri8: - case X86::SUB16rm: - case X86::SUB16rr: - case X86::SUB32ri: - case X86::SUB32ri8: - case X86::SUB32rm: - case X86::SUB32rr: - case X86::SUB64ri32: - case X86::SUB64ri8: - case X86::SUB64rm: - case X86::SUB64rr: - case X86::SUB8ri: - case X86::SUB8rm: - case X86::SUB8rr: - return FirstInstrKind::ALU; - case X86::INC16r: - case X86::INC32r: - case X86::INC64r: - case X86::INC8r: - case X86::DEC16r: - case X86::DEC32r: - case X86::DEC64r: - case X86::DEC8r: - return FirstInstrKind::IncDec; - } +static X86::FirstMacroFusionInstKind classifyFirst(const MachineInstr &MI) { + return X86::classifyFirstOpcodeInMacroFusion(MI.getOpcode()); } -static JumpKind classifySecond(const MachineInstr &MI) { +static X86::SecondMacroFusionInstKind classifySecond(const MachineInstr &MI) { X86::CondCode CC = X86::getCondFromBranch(MI); - if (CC == X86::COND_INVALID) - return JumpKind::Invalid; - - switch (CC) { - default: - return JumpKind::Invalid; - case X86::COND_E: - case X86::COND_NE: - case X86::COND_L: - case X86::COND_LE: - case X86::COND_G: - case X86::COND_GE: - return JumpKind::ELG; - case X86::COND_B: - case X86::COND_BE: - case X86::COND_A: - case X86::COND_AE: - return JumpKind::AB; - case X86::COND_S: - case X86::COND_NS: - case X86::COND_P: - case X86::COND_NP: - case X86::COND_O: - case X86::COND_NO: - return JumpKind::SPO; - } + return X86::classifySecondCondCodeInMacroFusion(CC); } /// Check if the instr pair, FirstMI and SecondMI, should be fused @@ -187,40 +41,27 @@ if (!(ST.hasBranchFusion() || ST.hasMacroFusion())) return false; - const JumpKind BranchKind = classifySecond(SecondMI); + const X86::SecondMacroFusionInstKind BranchKind = classifySecond(SecondMI); - if (BranchKind == JumpKind::Invalid) + if (BranchKind == X86::SecondMacroFusionInstKind::Invalid) return false; // Second cannot be fused with anything. if (FirstMI == nullptr) return true; // We're only checking whether Second can be fused at all. - const FirstInstrKind TestKind = classifyFirst(*FirstMI); + const X86::FirstMacroFusionInstKind TestKind = classifyFirst(*FirstMI); if (ST.hasBranchFusion()) { // Branch fusion can merge CMP and TEST with all conditional jumps. - return (TestKind == FirstInstrKind::Cmp || - TestKind == FirstInstrKind::Test); + return (TestKind == X86::FirstMacroFusionInstKind::Cmp || + TestKind == X86::FirstMacroFusionInstKind::Test); } if (ST.hasMacroFusion()) { - // Macro Fusion rules are a bit more complex. See Agner Fog's - // Microarchitecture table 9.2 "Instruction Fusion". - switch (TestKind) { - case FirstInstrKind::Test: - case FirstInstrKind::And: - return true; - case FirstInstrKind::Cmp: - case FirstInstrKind::ALU: - return BranchKind == JumpKind::ELG || BranchKind == JumpKind::AB; - case FirstInstrKind::IncDec: - return BranchKind == JumpKind::ELG; - case FirstInstrKind::Invalid: - return false; - } + return X86::isMacroFused(TestKind, BranchKind); } - llvm_unreachable("unknown branch fusion type"); + llvm_unreachable("unknown fusion type"); } namespace llvm { Index: llvm/test/MC/X86/i386-align-branch-1a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-1a.s @@ -0,0 +1,153 @@ +# Check option --x86-branches-within-32B-boundaries is equivalent to the combination of options --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 65 65 65 a3 01 00 00 00 movl %eax, %gs:1 +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 55 pushl %ebp +# CHECK-NEXT: b: 55 pushl %ebp +# CHECK-NEXT: c: 89 e5 movl %esp, %ebp +# CHECK-NEXT: e: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 20: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 22: 74 5e je {{.*}} +# CHECK-NEXT: 24: 3e 89 73 f4 movl %esi, %ds:-12(%ebx) +# CHECK-NEXT: 28: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2b: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3d: 5d popl %ebp +# CHECK-NEXT: 3e: 5d popl %ebp +# CHECK-NEXT: 3f: 5d popl %ebp +# CHECK-NEXT: 40: 74 40 je {{.*}} +# CHECK-NEXT: 42: 5d popl %ebp +# CHECK-NEXT: 43: 74 3d je {{.*}} +# CHECK-NEXT: 45: 36 89 44 24 fc movl %eax, %ss:-4(%esp) +# CHECK-NEXT: 4a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 4d: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 50: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 53: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 56: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 59: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5f: 5d popl %ebp +# CHECK-NEXT: 60: eb 26 jmp {{.*}} +# CHECK-NEXT: 62: eb 24 jmp {{.*}} +# CHECK-NEXT: 64: eb 22 jmp {{.*}} +# CHECK-NEXT: 66: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 69: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 6c: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 6f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 72: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 75: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 78: 5d popl %ebp +# CHECK-NEXT: 79: 5d popl %ebp +# CHECK-NEXT: 7a: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 7c: 74 04 je {{.*}} +# CHECK-NEXT: 7e: 90 nop +# CHECK-NEXT: 7f: 90 nop +# CHECK-NEXT: 80: eb 06 jmp {{.*}} +# CHECK-NEXT: 82: 8b 45 f4 movl -12(%ebp), %eax +# CHECK-NEXT: 85: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 88: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 8e: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 94: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 9a: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: a0: 89 75 0c movl %esi, 12(%ebp) +# CHECK-NEXT: a3: e9 fc ff ff ff jmp {{.*}} +# CHECK-NEXT: a8: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ae: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: b4: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ba: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: c0: 89 75 00 movl %esi, (%ebp) +# CHECK-NEXT: c3: 74 c3 je {{.*}} +# CHECK-NEXT: c5: 74 c1 je {{.*}} + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %gs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + cmp %eax, %ebp + je .L_2 + movl %esi, -12(%ebx) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + popl %ebp + je .L_2 + popl %ebp + je .L_2 + movl %eax, -4(%esp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%ebp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + cmp %eax, %ebp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%ebp), %eax + movl %eax, -4(%ebp) +.L_3: + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, 12(%ebp) + jmp bar + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, (%ebp) + je .L_3 + je .L_3 + Index: llvm/test/MC/X86/i386-align-branch-1b.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-1b.s @@ -0,0 +1,150 @@ +# Check the size of segment prefixes is limited with option --x86-align-branch-prefix-size=NUM +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=1 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 65 a3 01 00 00 00 movl %eax, %gs:1 +# CHECK-NEXT: 6: 3e 55 pushl %ebp +# CHECK-NEXT: 8: 3e 55 pushl %ebp +# CHECK-NEXT: a: 55 pushl %ebp +# CHECK-NEXT: b: 55 pushl %ebp +# CHECK-NEXT: c: 89 e5 movl %esp, %ebp +# CHECK-NEXT: e: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 20: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 22: 74 5e je {{.*}} +# CHECK-NEXT: 24: 3e 89 73 f4 movl %esi, %ds:-12(%ebx) +# CHECK-NEXT: 28: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2b: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3d: 5d popl %ebp +# CHECK-NEXT: 3e: 5d popl %ebp +# CHECK-NEXT: 3f: 5d popl %ebp +# CHECK-NEXT: 40: 74 40 je {{.*}} +# CHECK-NEXT: 42: 5d popl %ebp +# CHECK-NEXT: 43: 74 3d je {{.*}} +# CHECK-NEXT: 45: 36 89 44 24 fc movl %eax, %ss:-4(%esp) +# CHECK-NEXT: 4a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 4d: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 50: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 53: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 56: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 59: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5f: 5d popl %ebp +# CHECK-NEXT: 60: eb 26 jmp {{.*}} +# CHECK-NEXT: 62: eb 24 jmp {{.*}} +# CHECK-NEXT: 64: eb 22 jmp {{.*}} +# CHECK-NEXT: 66: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 69: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 6c: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 6f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 72: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 75: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 78: 5d popl %ebp +# CHECK-NEXT: 79: 5d popl %ebp +# CHECK-NEXT: 7a: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 7c: 74 04 je {{.*}} +# CHECK-NEXT: 7e: 90 nop +# CHECK-NEXT: 7f: 90 nop +# CHECK-NEXT: 80: eb 06 jmp {{.*}} +# CHECK-NEXT: 82: 8b 45 f4 movl -12(%ebp), %eax +# CHECK-NEXT: 85: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 88: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 8e: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 94: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 9a: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: a0: 89 75 0c movl %esi, 12(%ebp) +# CHECK-NEXT: a3: e9 fc ff ff ff jmp {{.*}} +# CHECK-NEXT: a8: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ae: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: b4: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ba: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: c0: 89 75 00 movl %esi, (%ebp) +# CHECK-NEXT: c3: 74 c3 je {{.*}} +# CHECK-NEXT: c5: 74 c1 je {{.*}} + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %gs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + cmp %eax, %ebp + je .L_2 + movl %esi, -12(%ebx) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + popl %ebp + je .L_2 + popl %ebp + je .L_2 + movl %eax, -4(%esp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%ebp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + cmp %eax, %ebp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%ebp), %eax + movl %eax, -4(%ebp) +.L_3: + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, 12(%ebp) + jmp bar + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, (%ebp) + je .L_3 + je .L_3 + Index: llvm/test/MC/X86/i386-align-branch-1c.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-1c.s @@ -0,0 +1,149 @@ +# Check only fused conditional jumps and conditional jumps are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 65 65 65 a3 01 00 00 00 movl %eax, %gs:1 +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 55 pushl %ebp +# CHECK-NEXT: b: 55 pushl %ebp +# CHECK-NEXT: c: 89 e5 movl %esp, %ebp +# CHECK-NEXT: e: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 20: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 22: 74 5b je {{.*}} +# CHECK-NEXT: 24: 3e 89 73 f4 movl %esi, %ds:-12(%ebx) +# CHECK-NEXT: 28: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2b: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3d: 5d popl %ebp +# CHECK-NEXT: 3e: 5d popl %ebp +# CHECK-NEXT: 3f: 5d popl %ebp +# CHECK-NEXT: 40: 74 3d je {{.*}} +# CHECK-NEXT: 42: 5d popl %ebp +# CHECK-NEXT: 43: 74 3a je {{.*}} +# CHECK-NEXT: 45: 89 44 24 fc movl %eax, -4(%esp) +# CHECK-NEXT: 49: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 4c: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 4f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 52: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 55: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 58: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5e: 5d popl %ebp +# CHECK-NEXT: 5f: eb 24 jmp {{.*}} +# CHECK-NEXT: 61: eb 22 jmp {{.*}} +# CHECK-NEXT: 63: eb 20 jmp {{.*}} +# CHECK-NEXT: 65: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 68: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 6b: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 6e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 71: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 74: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 77: 5d popl %ebp +# CHECK-NEXT: 78: 5d popl %ebp +# CHECK-NEXT: 79: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 7b: 74 02 je {{.*}} +# CHECK-NEXT: 7d: eb 06 jmp {{.*}} +# CHECK-NEXT: 7f: 8b 45 f4 movl -12(%ebp), %eax +# CHECK-NEXT: 82: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 85: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 8b: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 91: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 97: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 9d: 89 75 0c movl %esi, 12(%ebp) +# CHECK-NEXT: a0: e9 fc ff ff ff jmp {{.*}} +# CHECK-NEXT: a5: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ab: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: b1: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: b7: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: bd: 89 75 00 movl %esi, (%ebp) +# CHECK-NEXT: c0: 74 c3 je {{.*}} +# CHECK-NEXT: c2: 74 c1 je {{.*}} + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %gs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + cmp %eax, %ebp + je .L_2 + movl %esi, -12(%ebx) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + popl %ebp + je .L_2 + popl %ebp + je .L_2 + movl %eax, -4(%esp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%ebp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + cmp %eax, %ebp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%ebp), %eax + movl %eax, -4(%ebp) +.L_3: + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, 12(%ebp) + jmp bar + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, (%ebp) + je .L_3 + je .L_3 + Index: llvm/test/MC/X86/i386-align-branch-1d.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-1d.s @@ -0,0 +1,151 @@ +# Check only conditional jumps are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=jcc --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=jcc --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 65 a3 01 00 00 00 movl %eax, %gs:1 +# CHECK-NEXT: 6: 55 pushl %ebp +# CHECK-NEXT: 7: 55 pushl %ebp +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 89 e5 movl %esp, %ebp +# CHECK-NEXT: c: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 12: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 15: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 18: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1e: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 20: 74 5a je {{.*}} +# CHECK-NEXT: 22: 89 73 f4 movl %esi, -12(%ebx) +# CHECK-NEXT: 25: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 28: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 2b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3a: 5d popl %ebp +# CHECK-NEXT: 3b: 5d popl %ebp +# CHECK-NEXT: 3c: 5d popl %ebp +# CHECK-NEXT: 3d: 74 3d je {{.*}} +# CHECK-NEXT: 3f: 5d popl %ebp +# CHECK-NEXT: 40: 74 3a je {{.*}} +# CHECK-NEXT: 42: 89 44 24 fc movl %eax, -4(%esp) +# CHECK-NEXT: 46: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 49: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 4c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 4f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 52: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 55: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 58: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5b: 5d popl %ebp +# CHECK-NEXT: 5c: eb 24 jmp {{.*}} +# CHECK-NEXT: 5e: eb 22 jmp {{.*}} +# CHECK-NEXT: 60: eb 20 jmp {{.*}} +# CHECK-NEXT: 62: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 65: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 68: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 6b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 6e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 71: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 74: 5d popl %ebp +# CHECK-NEXT: 75: 5d popl %ebp +# CHECK-NEXT: 76: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 78: 74 02 je {{.*}} +# CHECK-NEXT: 7a: eb 06 jmp {{.*}} +# CHECK-NEXT: 7c: 8b 45 f4 movl -12(%ebp), %eax +# CHECK-NEXT: 7f: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 82: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 88: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 8e: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 94: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 9a: 89 75 0c movl %esi, 12(%ebp) +# CHECK-NEXT: 9d: e9 fc ff ff ff jmp {{.*}} +# CHECK-NEXT: a2: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: a8: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ae: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: b4: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ba: 89 75 00 movl %esi, (%ebp) +# CHECK-NEXT: bd: 74 c3 je {{.*}} +# CHECK-NEXT: bf: 90 nop +# CHECK-NEXT: c0: 74 c0 je {{.*}} + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %gs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + cmp %eax, %ebp + je .L_2 + movl %esi, -12(%ebx) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + popl %ebp + je .L_2 + popl %ebp + je .L_2 + movl %eax, -4(%esp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%ebp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + cmp %eax, %ebp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%ebp), %eax + movl %eax, -4(%ebp) +.L_3: + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, 12(%ebp) + jmp bar + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, (%ebp) + je .L_3 + je .L_3 + Index: llvm/test/MC/X86/i386-align-branch-1e.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-1e.s @@ -0,0 +1,153 @@ +# Check only conditional jumps and unconditional jumps are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=jcc+jmp --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 65 a3 01 00 00 00 movl %eax, %gs:1 +# CHECK-NEXT: 6: 55 pushl %ebp +# CHECK-NEXT: 7: 55 pushl %ebp +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 89 e5 movl %esp, %ebp +# CHECK-NEXT: c: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 12: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 15: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 18: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1e: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 20: 74 5c je {{.*}} +# CHECK-NEXT: 22: 89 73 f4 movl %esi, -12(%ebx) +# CHECK-NEXT: 25: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 28: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 2b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3a: 5d popl %ebp +# CHECK-NEXT: 3b: 5d popl %ebp +# CHECK-NEXT: 3c: 5d popl %ebp +# CHECK-NEXT: 3d: 74 3f je {{.*}} +# CHECK-NEXT: 3f: 5d popl %ebp +# CHECK-NEXT: 40: 74 3c je {{.*}} +# CHECK-NEXT: 42: 89 44 24 fc movl %eax, -4(%esp) +# CHECK-NEXT: 46: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 49: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 4c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 4f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 52: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 55: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 58: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5b: 5d popl %ebp +# CHECK-NEXT: 5c: eb 27 jmp {{.*}} +# CHECK-NEXT: 5e: 90 nop +# CHECK-NEXT: 5f: 90 nop +# CHECK-NEXT: 60: eb 23 jmp {{.*}} +# CHECK-NEXT: 62: eb 21 jmp {{.*}} +# CHECK-NEXT: 64: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 67: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 6a: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 6d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 70: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 73: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 76: 5d popl %ebp +# CHECK-NEXT: 77: 5d popl %ebp +# CHECK-NEXT: 78: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 7a: 74 02 je {{.*}} +# CHECK-NEXT: 7c: eb 07 jmp {{.*}} +# CHECK-NEXT: 7e: 36 8b 45 f4 movl %ss:-12(%ebp), %eax +# CHECK-NEXT: 82: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 85: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 8b: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 91: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 97: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 9d: 89 75 0c movl %esi, 12(%ebp) +# CHECK-NEXT: a0: e9 fc ff ff ff jmp {{.*}} +# CHECK-NEXT: a5: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ab: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: b1: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: b7: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: bd: 89 75 00 movl %esi, (%ebp) +# CHECK-NEXT: c0: 74 c3 je {{.*}} +# CHECK-NEXT: c2: 74 c1 je {{.*}} + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %gs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + cmp %eax, %ebp + je .L_2 + movl %esi, -12(%ebx) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + popl %ebp + je .L_2 + popl %ebp + je .L_2 + movl %eax, -4(%esp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%ebp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + cmp %eax, %ebp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%ebp), %eax + movl %eax, -4(%ebp) +.L_3: + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, 12(%ebp) + jmp bar + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, (%ebp) + je .L_3 + je .L_3 + Index: llvm/test/MC/X86/i386-align-branch-1f.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-1f.s @@ -0,0 +1,148 @@ +# Check no branches is aligned with option --x86-align-branch-boundary=0 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=0 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 65 a3 01 00 00 00 movl %eax, %gs:1 +# CHECK-NEXT: 6: 55 pushl %ebp +# CHECK-NEXT: 7: 55 pushl %ebp +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 89 e5 movl %esp, %ebp +# CHECK-NEXT: c: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 12: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 15: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 18: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1e: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 20: 74 5a je {{.*}} +# CHECK-NEXT: 22: 89 73 f4 movl %esi, -12(%ebx) +# CHECK-NEXT: 25: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 28: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 2b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3a: 5d popl %ebp +# CHECK-NEXT: 3b: 5d popl %ebp +# CHECK-NEXT: 3c: 5d popl %ebp +# CHECK-NEXT: 3d: 74 3d je {{.*}} +# CHECK-NEXT: 3f: 5d popl %ebp +# CHECK-NEXT: 40: 74 3a je {{.*}} +# CHECK-NEXT: 42: 89 44 24 fc movl %eax, -4(%esp) +# CHECK-NEXT: 46: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 49: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 4c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 4f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 52: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 55: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 58: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5b: 5d popl %ebp +# CHECK-NEXT: 5c: eb 24 jmp {{.*}} +# CHECK-NEXT: 5e: eb 22 jmp {{.*}} +# CHECK-NEXT: 60: eb 20 jmp {{.*}} +# CHECK-NEXT: 62: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 65: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 68: 89 7d f8 movl %edi, -8(%ebp) +# CHECK-NEXT: 6b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 6e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 71: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 74: 5d popl %ebp +# CHECK-NEXT: 75: 5d popl %ebp +# CHECK-NEXT: 76: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 78: 74 02 je {{.*}} +# CHECK-NEXT: 7a: eb 06 jmp {{.*}} +# CHECK-NEXT: 7c: 8b 45 f4 movl -12(%ebp), %eax +# CHECK-NEXT: 7f: 89 45 fc movl %eax, -4(%ebp) +# CHECK-NEXT: 82: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 88: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 8e: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 94: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: 9a: 89 75 0c movl %esi, 12(%ebp) +# CHECK-NEXT: 9d: e9 fc ff ff ff jmp {{.*}} +# CHECK-NEXT: a2: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: a8: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ae: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: b4: 89 b5 50 fb ff ff movl %esi, -1200(%ebp) +# CHECK-NEXT: ba: 89 75 00 movl %esi, (%ebp) +# CHECK-NEXT: bd: 74 c3 je {{.*}} +# CHECK-NEXT: bf: 74 c1 je {{.*}} + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %gs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + cmp %eax, %ebp + je .L_2 + movl %esi, -12(%ebx) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + popl %ebp + je .L_2 + popl %ebp + je .L_2 + movl %eax, -4(%esp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%ebp) + movl %esi, -12(%ebp) + movl %edi, -8(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + popl %ebp + popl %ebp + cmp %eax, %ebp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%ebp), %eax + movl %eax, -4(%ebp) +.L_3: + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, 12(%ebp) + jmp bar + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, -1200(%ebp) + movl %esi, (%ebp) + je .L_3 + je .L_3 + Index: llvm/test/MC/X86/i386-align-branch-2a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-2a.s @@ -0,0 +1,106 @@ +# Check indirect jumps and calls are not aligned with option --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 or with option --x86-branches-within-32B-boundaries +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 6: 55 pushl %ebp +# CHECK-NEXT: 7: 55 pushl %ebp +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 89 e5 movl %esp, %ebp +# CHECK-NEXT: c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 12: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 15: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 18: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1e: ff e0 jmpl *%eax +# CHECK-NEXT: 20: 55 pushl %ebp +# CHECK-NEXT: 21: 55 pushl %ebp +# CHECK-NEXT: 22: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 28: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 2a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 30: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 33: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 36: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 39: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3c: ff d0 calll *%eax +# CHECK-NEXT: 3e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 41: 55 pushl %ebp +# CHECK-NEXT: 42: 55 pushl %ebp +# CHECK-NEXT: 43: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 49: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 4b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 4e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 51: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 54: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 57: e8 a4 ff ff ff calll {{.*}} +# CHECK-NEXT: 5c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5f: 55 pushl %ebp +# CHECK-NEXT: 60: 55 pushl %ebp +# CHECK-NEXT: 61: 55 pushl %ebp +# CHECK-NEXT: 62: 55 pushl %ebp +# CHECK-NEXT: 63: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 69: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 6b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 6e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 71: ff 15 00 00 00 00 calll *0 +# CHECK-NEXT: 77: 55 pushl %ebp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + jmp *%eax + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call *%eax + movl %esi, -12(%ebp) + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call foo + movl %esi, -12(%ebp) + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call *foo + pushl %ebp Index: llvm/test/MC/X86/i386-align-branch-2b.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-2b.s @@ -0,0 +1,103 @@ +# Check only indirect jumps are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=indirect --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=indirect --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 64 64 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 55 pushl %ebp +# CHECK-NEXT: b: 55 pushl %ebp +# CHECK-NEXT: c: 89 e5 movl %esp, %ebp +# CHECK-NEXT: e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 20: ff e0 jmpl *%eax +# CHECK-NEXT: 22: 55 pushl %ebp +# CHECK-NEXT: 23: 55 pushl %ebp +# CHECK-NEXT: 24: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2a: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 2c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 32: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 35: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 38: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3e: ff d0 calll *%eax +# CHECK-NEXT: 40: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 43: 55 pushl %ebp +# CHECK-NEXT: 44: 55 pushl %ebp +# CHECK-NEXT: 45: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 4b: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 4d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 50: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 53: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 56: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 59: e8 a2 ff ff ff calll {{.*}} +# CHECK-NEXT: 5e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 61: 55 pushl %ebp +# CHECK-NEXT: 62: 55 pushl %ebp +# CHECK-NEXT: 63: 55 pushl %ebp +# CHECK-NEXT: 64: 55 pushl %ebp +# CHECK-NEXT: 65: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 6b: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 6d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 70: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 73: ff 15 00 00 00 00 calll *0 +# CHECK-NEXT: 79: 55 pushl %ebp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + jmp *%eax + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call *%eax + movl %esi, -12(%ebp) + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call foo + movl %esi, -12(%ebp) + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call *foo + pushl %ebp Index: llvm/test/MC/X86/i386-align-branch-2c.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-2c.s @@ -0,0 +1,103 @@ +# Check only indirect jumps and calls are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=indirect+call --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=indirect+call --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 64 64 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 55 pushl %ebp +# CHECK-NEXT: b: 55 pushl %ebp +# CHECK-NEXT: c: 89 e5 movl %esp, %ebp +# CHECK-NEXT: e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 20: ff e0 jmpl *%eax +# CHECK-NEXT: 22: 3e 3e 55 pushl %ebp +# CHECK-NEXT: 25: 55 pushl %ebp +# CHECK-NEXT: 26: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2c: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 40: ff d0 calll *%eax +# CHECK-NEXT: 42: 36 36 36 36 36 89 75 f4 movl %esi, %ss:-12(%ebp) +# CHECK-NEXT: 4a: 55 pushl %ebp +# CHECK-NEXT: 4b: 55 pushl %ebp +# CHECK-NEXT: 4c: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 52: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 54: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 57: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 5d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 60: e8 9b ff ff ff calll {{.*}} +# CHECK-NEXT: 65: 36 36 36 36 36 89 75 f4 movl %esi, %ss:-12(%ebp) +# CHECK-NEXT: 6d: 3e 55 pushl %ebp +# CHECK-NEXT: 6f: 55 pushl %ebp +# CHECK-NEXT: 70: 55 pushl %ebp +# CHECK-NEXT: 71: 55 pushl %ebp +# CHECK-NEXT: 72: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 78: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 7a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 7d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 80: ff 15 00 00 00 00 calll *0 +# CHECK-NEXT: 86: 55 pushl %ebp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + jmp *%eax + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call *%eax + movl %esi, -12(%ebp) + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call foo + movl %esi, -12(%ebp) + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call *foo + pushl %ebp Index: llvm/test/MC/X86/i386-align-branch-3a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-3a.s @@ -0,0 +1,61 @@ +# Check NOP padding is disabled before tls_get_addr calls +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=call --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 6: 55 pushl %ebp +# CHECK-NEXT: 7: 55 pushl %ebp +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 89 e5 movl %esp, %ebp +# CHECK-NEXT: c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: f: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 12: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 15: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 18: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1b: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1e: e8 fc ff ff ff calll {{.*}} +# CHECK-NEXT: 23: 55 pushl %ebp +# CHECK-NEXT: 24: 55 pushl %ebp +# CHECK-NEXT: 25: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2b: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 2d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 30: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 33: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 36: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 39: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3c: ff 91 00 00 00 00 calll *(%ecx) +# CHECK-NEXT: 42: 89 75 f4 movl %esi, -12(%ebp) + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call ___tls_get_addr + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + call *___tls_get_addr@GOT(%ecx) + movl %esi, -12(%ebp) Index: llvm/test/MC/X86/i386-align-branch-4a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-4a.s @@ -0,0 +1,68 @@ +# Check rets are not aligned with option --x86-branches-within-32B-boundaries or with option --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 6: 55 pushl %ebp +# CHECK-NEXT: 7: 55 pushl %ebp +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 55 pushl %ebp +# CHECK-NEXT: b: 89 e5 movl %esp, %ebp +# CHECK-NEXT: d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 10: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 13: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 16: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 19: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1c: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1f: c3 retl +# CHECK-NEXT: 20: 55 pushl %ebp +# CHECK-NEXT: 21: 55 pushl %ebp +# CHECK-NEXT: 22: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 28: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 2a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 2d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 30: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 33: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 36: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 39: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3c: c2 1e 00 retl $30 +# CHECK-NEXT: 3f: 89 75 f4 movl %esi, -12(%ebp) + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + ret + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + ret $30 + movl %esi, -12(%ebp) Index: llvm/test/MC/X86/i386-align-branch-4b.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-4b.s @@ -0,0 +1,65 @@ +# Check only rets are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=ret --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=ret --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: 64 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 7: 55 pushl %ebp +# CHECK-NEXT: 8: 55 pushl %ebp +# CHECK-NEXT: 9: 55 pushl %ebp +# CHECK-NEXT: a: 55 pushl %ebp +# CHECK-NEXT: b: 55 pushl %ebp +# CHECK-NEXT: c: 89 e5 movl %esp, %ebp +# CHECK-NEXT: e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 20: c3 retl +# CHECK-NEXT: 21: 3e 3e 3e 55 pushl %ebp +# CHECK-NEXT: 25: 55 pushl %ebp +# CHECK-NEXT: 26: 64 a3 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2c: 89 e5 movl %esp, %ebp +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3a: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 3d: 89 75 f4 movl %esi, -12(%ebp) +# CHECK-NEXT: 40: c2 1e 00 retl $30 +# CHECK-NEXT: 43: 89 75 f4 movl %esi, -12(%ebp) + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + pushl %ebp + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + ret + pushl %ebp + pushl %ebp + movl %eax, %fs:0x1 + movl %esp, %ebp + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + movl %esi, -12(%ebp) + ret $30 + movl %esi, -12(%ebp) Index: llvm/test/MC/X86/i386-align-branch-5a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-5a.s @@ -0,0 +1,72 @@ +# Check no nop or prefix is inserted if no branch cross or is against the boundary +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 foo: +# CHECK-NEXT: 0: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 3: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 6: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 9: 89 d1 movl %edx, %ecx +# CHECK-NEXT: b: 31 c0 xorl %eax, %eax +# CHECK-NEXT: d: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 10: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 13: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 16: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 19: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 1c: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 1f: f6 c2 02 testb $2, %dl +# CHECK-NEXT: 22: f3 ab rep stosl %eax, %es:(%edi) +# CHECK-NEXT: 24: 75 dd jne {{.*}} +# CHECK-NEXT: 26: 31 c0 xorl %eax, %eax +# CHECK-NEXT: 28: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 2b: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 2e: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 31: 89 d1 movl %edx, %ecx +# CHECK-NEXT: 33: 31 c0 xorl %eax, %eax +# CHECK-NEXT: 35: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 38: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 3b: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 3e: f6 c2 02 testb $2, %dl +# CHECK-NEXT: 41: e8 fc ff ff ff calll {{.*}} +# CHECK-NEXT: 46: 75 e3 jne {{.*}} +# CHECK-NEXT: 48: 31 c0 xorl %eax, %eax + + .text + .p2align 4,,15 +foo: + shrl $2, %ecx +.L1: + shrl $2, %ecx + shrl $2, %ecx + movl %edx, %ecx + xorl %eax, %eax + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + testb $2, %dl + rep stosl + jne .L1 + xorl %eax, %eax + shrl $2, %ecx +.L2: + shrl $2, %ecx + shrl $2, %ecx + movl %edx, %ecx + xorl %eax, %eax + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + testb $2, %dl + call bar + jne .L2 + xorl %eax, %eax + Index: llvm/test/MC/X86/i386-align-branch-6a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-6a.s @@ -0,0 +1,26 @@ +# Check no prefix is inserted before the fragment whose size is no less than 15 +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=1 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 main: +# CHECK-NEXT: 0: 3e 55 pushl %ebp +# CHECK-NEXT: 2: 89 e5 movl %esp, %ebp +# CHECK-COUNT-28: 90 nop +# CHECK-NEXT: 20: eb 00 jmp 0 +# CHECK: 00000022 infiniteLoop: +# CHECK-NEXT: 22: eb dc jmp -36
+ + .text + .globl infiniteLoop +main: + pushl %ebp + movl %esp, %ebp + .rept 27 + .byte 0x90 + .endr + jmp infiniteLoop +infiniteLoop: + jmp main Index: llvm/test/MC/X86/i386-align-branch-7a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/i386-align-branch-7a.s @@ -0,0 +1,89 @@ +# Check the macro fusion table +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple i386-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + +# CHECK: Disassembly of section .text: +# CHECK: 00000000 main: +# CHECK-NEXT: 0: 55 pushl %ebp +# CHECK-NEXT: 1: 54 pushl %esp +# CHECK-NEXT: 2: eb 17 jmp 23 +# CHECK-COUNT-23: 90 nop +# CHECK: 0000001b infiniteLoop: +# CHECK-NEXT: 1b: 3e 3e 55 pushl %ebp +# CHECK-NEXT: 1e: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 20: 78 de js {{.*}} +# CHECK-COUNT-25: 90 nop +# CHECK-NEXT: 3b: 3e 3e 55 pushl %ebp +# CHECK-NEXT: 3e: 39 c5 cmpl %eax, %ebp +# CHECK-NEXT: 40: 70 be jo {{.*}} +# CHECK-COUNT-25: 90 nop +# CHECK-NEXT: 5b: 3e 3e 55 pushl %ebp +# CHECK-NEXT: 5e: 01 c5 addl %eax, %ebp +# CHECK-NEXT: 60: 71 9e jno {{.*}} +# CHECK-COUNT-25: 90 nop +# CHECK-NEXT: 7b: 3e 3e 55 pushl %ebp +# CHECK-NEXT: 7e: 29 c5 subl %eax, %ebp +# CHECK-NEXT: 80: 0f 8b 7a ff ff ff jnp {{.*}} +# CHECK-COUNT-21: 90 nop +# CHECK-NEXT: 9b: 3e 3e 3e 55 pushl %ebp +# CHECK-NEXT: 9f: 42 incl %edx +# CHECK-NEXT: a0: 0f 82 5a ff ff ff jb {{.*}} +# CHECK-COUNT-21: 90 nop +# CHECK-NEXT: bb: 3e 3e 3e 55 pushl %ebp +# CHECK-NEXT: bf: 4a decl %edx +# CHECK-NEXT: c0: 0f 86 3a ff ff ff jbe {{.*}} + + .text + .globl infiniteLoop +main: + pushl %ebp + pushl %esp + jmp infiniteLoop + + .p2align 4 + .rept 11 + .byte 0x90 + .endr +infiniteLoop: + pushl %ebp + cmp %eax, %ebp + js main + .p2align 4 + .rept 11 + .byte 0x90 + .endr + pushl %ebp + cmp %eax, %ebp + jo main + .p2align 4 + .rept 11 + .byte 0x90 + .endr + pushl %ebp + add %eax, %ebp + jno main + .p2align 4 + .rept 11 + .byte 0x90 + .endr + pushl %ebp + sub %eax, %ebp + jpo main + .p2align 4 + .rept 11 + .byte 0x90 + .endr + pushl %ebp + inc %edx + jb main + .p2align 4 + .rept 11 + .byte 0x90 + .endr + pushl %ebp + dec %edx + jna main Index: llvm/test/MC/X86/x86-64-align-branch-1a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-1a.s @@ -0,0 +1,148 @@ +# Check option --x86-branches-within-32B-boundaries is equivalent to the combination of options --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 64 64 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: b: 55 pushq %rbp +# CHECK-NEXT: c: 55 pushq %rbp +# CHECK-NEXT: d: 55 pushq %rbp +# CHECK-NEXT: e: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 20: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 23: 74 5d je {{.*}} +# CHECK-NEXT: 25: 2e 89 75 f4 movl %esi, %cs:-12(%rbp) +# CHECK-NEXT: 29: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 2c: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 2f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 32: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 35: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 38: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3e: 5d popq %rbp +# CHECK-NEXT: 3f: 5d popq %rbp +# CHECK-NEXT: 40: 74 40 je {{.*}} +# CHECK-NEXT: 42: 5d popq %rbp +# CHECK-NEXT: 43: 74 3d je {{.*}} +# CHECK-NEXT: 45: 2e 89 45 fc movl %eax, %cs:-4(%rbp) +# CHECK-NEXT: 49: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 4c: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 4f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 52: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 55: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 58: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5e: 5d popq %rbp +# CHECK-NEXT: 5f: 5d popq %rbp +# CHECK-NEXT: 60: eb 26 jmp {{.*}} +# CHECK-NEXT: 62: eb 24 jmp {{.*}} +# CHECK-NEXT: 64: eb 22 jmp {{.*}} +# CHECK-NEXT: 66: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 69: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 6c: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 6f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 72: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 75: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 78: 5d popq %rbp +# CHECK-NEXT: 79: 5d popq %rbp +# CHECK-NEXT: 7a: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 7d: 74 03 je {{.*}} +# CHECK-NEXT: 7f: 90 nop +# CHECK-NEXT: 80: eb 06 jmp {{.*}} +# CHECK-NEXT: 82: 8b 45 f4 movl -12(%rbp), %eax +# CHECK-NEXT: 85: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 88: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 8e: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 94: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 9a: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a0: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a6: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: ac: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b2: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b8: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: be: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: c4: eb c2 jmp {{.*}} +# CHECK-NEXT: c6: 5d popq %rbp +# CHECK-NEXT: c7: c3 retq + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + cmp %rax, %rbp + je .L_2 + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + je .L_2 + popq %rbp + je .L_2 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + cmp %rax, %rbp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%rbp), %eax + movl %eax, -4(%rbp) +.L_3: + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + jmp .L_3 + popq %rbp + retq Index: llvm/test/MC/X86/x86-64-align-branch-1b.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-1b.s @@ -0,0 +1,145 @@ +# Check the size of segment prefixes is limited with option --x86-align-branch-prefix-size=NUM +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=1 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 2e 55 pushq %rbp +# CHECK-NEXT: a: 2e 55 pushq %rbp +# CHECK-NEXT: c: 2e 55 pushq %rbp +# CHECK-NEXT: e: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 20: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 23: 74 5d je {{.*}} +# CHECK-NEXT: 25: 2e 89 75 f4 movl %esi, %cs:-12(%rbp) +# CHECK-NEXT: 29: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 2c: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 2f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 32: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 35: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 38: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3e: 5d popq %rbp +# CHECK-NEXT: 3f: 5d popq %rbp +# CHECK-NEXT: 40: 74 40 je {{.*}} +# CHECK-NEXT: 42: 5d popq %rbp +# CHECK-NEXT: 43: 74 3d je {{.*}} +# CHECK-NEXT: 45: 2e 89 45 fc movl %eax, %cs:-4(%rbp) +# CHECK-NEXT: 49: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 4c: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 4f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 52: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 55: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 58: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5e: 5d popq %rbp +# CHECK-NEXT: 5f: 5d popq %rbp +# CHECK-NEXT: 60: eb 26 jmp {{.*}} +# CHECK-NEXT: 62: eb 24 jmp {{.*}} +# CHECK-NEXT: 64: eb 22 jmp {{.*}} +# CHECK-NEXT: 66: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 69: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 6c: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 6f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 72: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 75: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 78: 5d popq %rbp +# CHECK-NEXT: 79: 5d popq %rbp +# CHECK-NEXT: 7a: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 7d: 74 03 je {{.*}} +# CHECK-NEXT: 7f: 90 nop +# CHECK-NEXT: 80: eb 06 jmp {{.*}} +# CHECK-NEXT: 82: 8b 45 f4 movl -12(%rbp), %eax +# CHECK-NEXT: 85: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 88: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 8e: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 94: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 9a: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a0: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a6: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: ac: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b2: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b8: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: be: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: c4: eb c2 jmp {{.*}} +# CHECK-NEXT: c6: 5d popq %rbp +# CHECK-NEXT: c7: c3 retq + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + cmp %rax, %rbp + je .L_2 + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + je .L_2 + popq %rbp + je .L_2 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + cmp %rax, %rbp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%rbp), %eax + movl %eax, -4(%rbp) +.L_3: + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + jmp .L_3 + popq %rbp + retq Index: llvm/test/MC/X86/x86-64-align-branch-1c.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-1c.s @@ -0,0 +1,144 @@ +# Check only fused conditional jumps and conditional jumps are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 64 64 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: b: 55 pushq %rbp +# CHECK-NEXT: c: 55 pushq %rbp +# CHECK-NEXT: d: 55 pushq %rbp +# CHECK-NEXT: e: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 20: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 23: 74 5b je {{.*}} +# CHECK-NEXT: 25: 2e 89 75 f4 movl %esi, %cs:-12(%rbp) +# CHECK-NEXT: 29: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 2c: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 2f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 32: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 35: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 38: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3e: 5d popq %rbp +# CHECK-NEXT: 3f: 5d popq %rbp +# CHECK-NEXT: 40: 74 3e je {{.*}} +# CHECK-NEXT: 42: 5d popq %rbp +# CHECK-NEXT: 43: 74 3b je {{.*}} +# CHECK-NEXT: 45: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 48: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 4b: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 4e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 51: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 54: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 57: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5d: 5d popq %rbp +# CHECK-NEXT: 5e: 5d popq %rbp +# CHECK-NEXT: 5f: eb 25 jmp {{.*}} +# CHECK-NEXT: 61: eb 23 jmp {{.*}} +# CHECK-NEXT: 63: eb 21 jmp {{.*}} +# CHECK-NEXT: 65: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 68: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 6b: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 6e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 71: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 74: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 77: 5d popq %rbp +# CHECK-NEXT: 78: 5d popq %rbp +# CHECK-NEXT: 79: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 7c: 74 02 je {{.*}} +# CHECK-NEXT: 7e: eb 06 jmp {{.*}} +# CHECK-NEXT: 80: 8b 45 f4 movl -12(%rbp), %eax +# CHECK-NEXT: 83: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 86: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 8c: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 92: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 98: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 9e: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a4: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: aa: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b0: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b6: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: bc: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: c2: eb c2 jmp {{.*}} +# CHECK-NEXT: c4: 5d popq %rbp +# CHECK-NEXT: c5: c3 retq + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + cmp %rax, %rbp + je .L_2 + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + je .L_2 + popq %rbp + je .L_2 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + cmp %rax, %rbp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%rbp), %eax + movl %eax, -4(%rbp) +.L_3: + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + jmp .L_3 + popq %rbp + retq Index: llvm/test/MC/X86/x86-64-align-branch-1d.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-1d.s @@ -0,0 +1,144 @@ +# Check only conditional jumps are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=jcc --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=jcc --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushq %rbp +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 20: 74 5b je {{.*}} +# CHECK-NEXT: 22: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 25: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 28: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 2b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3a: 5d popq %rbp +# CHECK-NEXT: 3b: 5d popq %rbp +# CHECK-NEXT: 3c: 74 3f je {{.*}} +# CHECK-NEXT: 3e: 2e 5d popq %rbp +# CHECK-NEXT: 40: 74 3b je {{.*}} +# CHECK-NEXT: 42: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 45: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 48: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 4b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 4e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 51: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 54: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 57: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5a: 5d popq %rbp +# CHECK-NEXT: 5b: 5d popq %rbp +# CHECK-NEXT: 5c: eb 25 jmp {{.*}} +# CHECK-NEXT: 5e: eb 23 jmp {{.*}} +# CHECK-NEXT: 60: eb 21 jmp {{.*}} +# CHECK-NEXT: 62: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 65: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 68: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 6b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 6e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 71: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 74: 5d popq %rbp +# CHECK-NEXT: 75: 5d popq %rbp +# CHECK-NEXT: 76: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 79: 74 02 je {{.*}} +# CHECK-NEXT: 7b: eb 06 jmp {{.*}} +# CHECK-NEXT: 7d: 8b 45 f4 movl -12(%rbp), %eax +# CHECK-NEXT: 80: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 83: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 89: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 8f: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 95: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 9b: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a1: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a7: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: ad: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b3: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b9: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: bf: eb c2 jmp {{.*}} +# CHECK-NEXT: c1: 5d popq %rbp +# CHECK-NEXT: c2: c3 retq + + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + cmp %rax, %rbp + je .L_2 + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + je .L_2 + popq %rbp + je .L_2 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + cmp %rax, %rbp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%rbp), %eax + movl %eax, -4(%rbp) +.L_3: + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + jmp .L_3 + popq %rbp + retq Index: llvm/test/MC/X86/x86-64-align-branch-1e.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-1e.s @@ -0,0 +1,146 @@ +# Check only conditional jumps and unconditional jumps are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=jcc+jmp --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushq %rbp +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 20: 74 5d je {{.*}} +# CHECK-NEXT: 22: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 25: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 28: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 2b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3a: 5d popq %rbp +# CHECK-NEXT: 3b: 5d popq %rbp +# CHECK-NEXT: 3c: 74 41 je {{.*}} +# CHECK-NEXT: 3e: 2e 5d popq %rbp +# CHECK-NEXT: 40: 74 3d je {{.*}} +# CHECK-NEXT: 42: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 45: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 48: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 4b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 4e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 51: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 54: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 57: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5a: 5d popq %rbp +# CHECK-NEXT: 5b: 5d popq %rbp +# CHECK-NEXT: 5c: eb 27 jmp {{.*}} +# CHECK-NEXT: 5e: 90 nop +# CHECK-NEXT: 5f: 90 nop +# CHECK-NEXT: 60: eb 23 jmp {{.*}} +# CHECK-NEXT: 62: eb 21 jmp {{.*}} +# CHECK-NEXT: 64: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 67: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 6a: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 6d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 70: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 73: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 76: 5d popq %rbp +# CHECK-NEXT: 77: 5d popq %rbp +# CHECK-NEXT: 78: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 7b: 74 02 je {{.*}} +# CHECK-NEXT: 7d: eb 06 jmp {{.*}} +# CHECK-NEXT: 7f: 8b 45 f4 movl -12(%rbp), %eax +# CHECK-NEXT: 82: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 85: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 8b: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 91: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 97: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 9d: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a3: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a9: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: af: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b5: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: bb: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: c1: eb c2 jmp {{.*}} +# CHECK-NEXT: c3: 5d popq %rbp +# CHECK-NEXT: c4: c3 retq + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + cmp %rax, %rbp + je .L_2 + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + je .L_2 + popq %rbp + je .L_2 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + cmp %rax, %rbp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%rbp), %eax + movl %eax, -4(%rbp) +.L_3: + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + jmp .L_3 + popq %rbp + retq Index: llvm/test/MC/X86/x86-64-align-branch-1f.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-1f.s @@ -0,0 +1,144 @@ +# Check no branches is aligned with option --x86-align-branch-boundary=0 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=0 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushq %rbp +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 20: 74 5a je {{.*}} +# CHECK-NEXT: 22: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 25: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 28: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 2b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3a: 5d popq %rbp +# CHECK-NEXT: 3b: 5d popq %rbp +# CHECK-NEXT: 3c: 74 3e je {{.*}} +# CHECK-NEXT: 3e: 5d popq %rbp +# CHECK-NEXT: 3f: 74 3b je {{.*}} +# CHECK-NEXT: 41: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 44: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 47: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 4a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 4d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 50: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 53: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 56: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 59: 5d popq %rbp +# CHECK-NEXT: 5a: 5d popq %rbp +# CHECK-NEXT: 5b: eb 25 jmp {{.*}} +# CHECK-NEXT: 5d: eb 23 jmp {{.*}} +# CHECK-NEXT: 5f: eb 21 jmp {{.*}} +# CHECK-NEXT: 61: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 64: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 67: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 6a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 6d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 70: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 73: 5d popq %rbp +# CHECK-NEXT: 74: 5d popq %rbp +# CHECK-NEXT: 75: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 78: 74 02 je {{.*}} +# CHECK-NEXT: 7a: eb 06 jmp {{.*}} +# CHECK-NEXT: 7c: 8b 45 f4 movl -12(%rbp), %eax +# CHECK-NEXT: 7f: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 82: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 88: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 8e: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 94: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 9a: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a0: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a6: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: ac: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b2: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b8: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: be: eb c2 jmp {{.*}} +# CHECK-NEXT: c0: 5d popq %rbp +# CHECK-NEXT: c1: c3 retq + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + cmp %rax, %rbp + je .L_2 + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + je .L_2 + popq %rbp + je .L_2 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + cmp %rax, %rbp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%rbp), %eax + movl %eax, -4(%rbp) +.L_3: + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + jmp .L_3 + popq %rbp + retq Index: llvm/test/MC/X86/x86-64-align-branch-1g.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-1g.s @@ -0,0 +1,144 @@ +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 -mcpu=x86-64 --x86-align-branch=jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushq %rbp +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 20: 74 5d je {{.*}} +# CHECK-NEXT: 22: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 25: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 28: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 2b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3a: 5d popq %rbp +# CHECK-NEXT: 3b: 5d popq %rbp +# CHECK-NEXT: 3c: 74 41 je {{.*}} +# CHECK-NEXT: 3e: 2e 5d popq %rbp +# CHECK-NEXT: 40: 74 3d je {{.*}} +# CHECK-NEXT: 42: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 45: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 48: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 4b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 4e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 51: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 54: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 57: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5a: 5d popq %rbp +# CHECK-NEXT: 5b: 5d popq %rbp +# CHECK-NEXT: 5c: eb 27 jmp {{.*}} +# CHECK-NEXT: 5e: 66 90 nop +# CHECK-NEXT: 60: eb 23 jmp {{.*}} +# CHECK-NEXT: 62: eb 21 jmp {{.*}} +# CHECK-NEXT: 64: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 67: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 6a: 89 7d f8 movl %edi, -8(%rbp) +# CHECK-NEXT: 6d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 70: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 73: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 76: 5d popq %rbp +# CHECK-NEXT: 77: 5d popq %rbp +# CHECK-NEXT: 78: 48 39 c5 cmpq %rax, %rbp +# CHECK-NEXT: 7b: 74 02 je {{.*}} +# CHECK-NEXT: 7d: eb 06 jmp {{.*}} +# CHECK-NEXT: 7f: 8b 45 f4 movl -12(%rbp), %eax +# CHECK-NEXT: 82: 89 45 fc movl %eax, -4(%rbp) +# CHECK-NEXT: 85: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 8b: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 91: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 97: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: 9d: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a3: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: a9: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: af: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: b5: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: bb: 89 b5 50 fb ff ff movl %esi, -1200(%rbp) +# CHECK-NEXT: c1: eb c2 jmp {{.*}} +# CHECK-NEXT: c3: 5d popq %rbp +# CHECK-NEXT: c4: c3 retq + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + cmp %rax, %rbp + je .L_2 + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + je .L_2 + popq %rbp + je .L_2 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + jmp .L_3 + jmp .L_3 + jmp .L_3 + movl %eax, -4(%rbp) + movl %esi, -12(%rbp) + movl %edi, -8(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + popq %rbp + popq %rbp + cmp %rax, %rbp + je .L_2 + jmp .L_3 +.L_2: + movl -12(%rbp), %eax + movl %eax, -4(%rbp) +.L_3: + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + movl %esi, -1200(%rbp) + jmp .L_3 + popq %rbp + retq Index: llvm/test/MC/X86/x86-64-align-branch-2a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-2a.s @@ -0,0 +1,97 @@ +# Check indirect jumps and calls are not aligned with option --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 or with option --x86-branches-within-32B-boundaries +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused-jcc-jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushq %rbp +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 55 pushq %rbp +# CHECK-NEXT: c: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 12: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 15: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 18: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1e: ff e0 jmpq *%rax +# CHECK-NEXT: 20: 55 pushq %rbp +# CHECK-NEXT: 21: 55 pushq %rbp +# CHECK-NEXT: 22: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2a: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 2d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 30: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 33: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 36: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 39: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3c: ff d0 callq *%rax +# CHECK-NEXT: 3e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 41: 55 pushq %rbp +# CHECK-NEXT: 42: 55 pushq %rbp +# CHECK-NEXT: 43: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 4b: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 4e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 51: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 54: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 57: e8 a4 ff ff ff callq {{.*}} +# CHECK-NEXT: 5c: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5f: 55 pushq %rbp +# CHECK-NEXT: 60: 55 pushq %rbp +# CHECK-NEXT: 61: 55 pushq %rbp +# CHECK-NEXT: 62: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 6a: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 6d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 70: ff 14 25 00 00 00 00 callq *0 +# CHECK-NEXT: 77: 55 pushq %rbp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + jmp *%rax + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call *%rax + movl %esi, -12(%rbp) + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call foo + movl %esi, -12(%rbp) + pushq %rbp + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + call *foo + pushq %rbp Index: llvm/test/MC/X86/x86-64-align-branch-2b.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-2b.s @@ -0,0 +1,94 @@ +# Check only indirect jumps are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=indirect --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=indirect --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 64 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 55 pushq %rbp +# CHECK-NEXT: c: 55 pushq %rbp +# CHECK-NEXT: d: 55 pushq %rbp +# CHECK-NEXT: e: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 20: ff e0 jmpq *%rax +# CHECK-NEXT: 22: 55 pushq %rbp +# CHECK-NEXT: 23: 55 pushq %rbp +# CHECK-NEXT: 24: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2c: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 2f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 32: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 35: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 38: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3e: ff d0 callq *%rax +# CHECK-NEXT: 40: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 43: 55 pushq %rbp +# CHECK-NEXT: 44: 55 pushq %rbp +# CHECK-NEXT: 45: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 4d: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 50: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 53: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 56: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 59: e8 a2 ff ff ff callq {{.*}} +# CHECK-NEXT: 5e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 61: 55 pushq %rbp +# CHECK-NEXT: 62: 55 pushq %rbp +# CHECK-NEXT: 63: 55 pushq %rbp +# CHECK-NEXT: 64: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 6c: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 6f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 72: ff 14 25 00 00 00 00 callq *0 +# CHECK-NEXT: 79: 55 pushq %rbp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + jmp *%rax + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call *%rax + movl %esi, -12(%rbp) + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call foo + movl %esi, -12(%rbp) + pushq %rbp + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + call *foo + pushq %rbp Index: llvm/test/MC/X86/x86-64-align-branch-2c.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-2c.s @@ -0,0 +1,94 @@ +# Check only calls are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=call --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=call --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushq %rbp +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 55 pushq %rbp +# CHECK-NEXT: c: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 12: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 15: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 18: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1e: ff e0 jmpq *%rax +# CHECK-NEXT: 20: 55 pushq %rbp +# CHECK-NEXT: 21: 55 pushq %rbp +# CHECK-NEXT: 22: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2a: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 2d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 30: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 33: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 36: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 39: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3c: ff d0 callq *%rax +# CHECK-NEXT: 3e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 41: 55 pushq %rbp +# CHECK-NEXT: 42: 55 pushq %rbp +# CHECK-NEXT: 43: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 4b: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 4e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 51: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 54: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 57: e8 a4 ff ff ff callq {{.*}} +# CHECK-NEXT: 5c: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5f: 55 pushq %rbp +# CHECK-NEXT: 60: 55 pushq %rbp +# CHECK-NEXT: 61: 55 pushq %rbp +# CHECK-NEXT: 62: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 6a: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 6d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 70: ff 14 25 00 00 00 00 callq *0 +# CHECK-NEXT: 77: 55 pushq %rbp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + jmp *%rax + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call *%rax + movl %esi, -12(%rbp) + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call foo + movl %esi, -12(%rbp) + pushq %rbp + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + call *foo + pushq %rbp Index: llvm/test/MC/X86/x86-64-align-branch-2d.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-2d.s @@ -0,0 +1,94 @@ +# Check only indirect jumps and calls are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=indirect+call --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=indirect+call --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 64 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 55 pushq %rbp +# CHECK-NEXT: c: 55 pushq %rbp +# CHECK-NEXT: d: 55 pushq %rbp +# CHECK-NEXT: e: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 20: ff e0 jmpq *%rax +# CHECK-NEXT: 22: 2e 2e 55 pushq %rbp +# CHECK-NEXT: 25: 55 pushq %rbp +# CHECK-NEXT: 26: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2e: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 40: ff d0 callq *%rax +# CHECK-NEXT: 42: 2e 2e 2e 2e 2e 89 75 f4 movl %esi, %cs:-12(%rbp) +# CHECK-NEXT: 4a: 55 pushq %rbp +# CHECK-NEXT: 4b: 55 pushq %rbp +# CHECK-NEXT: 4c: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 54: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 57: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 5d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 60: e8 9b ff ff ff callq {{.*}} +# CHECK-NEXT: 65: 2e 2e 2e 2e 2e 89 75 f4 movl %esi, %cs:-12(%rbp) +# CHECK-NEXT: 6d: 2e 2e 55 pushq %rbp +# CHECK-NEXT: 70: 55 pushq %rbp +# CHECK-NEXT: 71: 55 pushq %rbp +# CHECK-NEXT: 72: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 7a: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 7d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 80: ff 14 25 00 00 00 00 callq *0 +# CHECK-NEXT: 87: 55 pushq %rbp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + jmp *%rax + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call *%rax + movl %esi, -12(%rbp) + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call foo + movl %esi, -12(%rbp) + pushq %rbp + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + call *foo + pushq %rbp Index: llvm/test/MC/X86/x86-64-align-branch-3a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-3a.s @@ -0,0 +1,60 @@ +# Check NOP padding is disabled before tls_get_addr calls +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=call --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushq %rbp +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 55 pushq %rbp +# CHECK-NEXT: c: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: f: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 12: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 15: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 18: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1e: e8 00 00 00 00 callq 0 +# CHECK-NEXT: 23: 55 pushq %rbp +# CHECK-NEXT: 24: 55 pushq %rbp +# CHECK-NEXT: 25: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2d: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: 30: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 33: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 36: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 39: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3c: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3f: ff 15 00 00 00 00 callq *(%rip) +# CHECK-NEXT: 45: 89 75 f4 movl %esi, -12(%rbp) + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call __tls_get_addr + pushq %rbp + pushq %rbp + movl %eax, %fs:0x1 + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + call *__tls_get_addr@GOTPCREL(%rip) + movl %esi, -12(%rbp) Index: llvm/test/MC/X86/x86-64-align-branch-4a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-4a.s @@ -0,0 +1,63 @@ +# Check rets are not aligned with option --x86-branches-within-32B-boundaries or with option --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - >%t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 8: 55 pushq %rbp +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 10: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 13: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 16: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 19: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1c: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1f: c3 retq +# CHECK-NEXT: 20: 55 pushq %rbp +# CHECK-NEXT: 21: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 29: 55 pushq %rbp +# CHECK-NEXT: 2a: 55 pushq %rbp +# CHECK-NEXT: 2b: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3d: c2 1e 00 retq $30 +# CHECK-NEXT: 40: 55 pushq %rbp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + ret + pushq %rbp + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + ret $30 + pushq %rbp Index: llvm/test/MC/X86/x86-64-align-branch-4b.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-4b.s @@ -0,0 +1,60 @@ +# Check only rets are aligned with option --x86-align-branch-boundary=32 --x86-align-branch=ret --x86-align-branch-prefix-size=5 +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=ret --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - | FileCheck %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: 64 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 9: 55 pushq %rbp +# CHECK-NEXT: a: 55 pushq %rbp +# CHECK-NEXT: b: 48 89 e5 movq %rsp, %rbp +# CHECK-NEXT: e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 11: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 14: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 17: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 1d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 20: c3 retq +# CHECK-NEXT: 21: 2e 2e 55 pushq %rbp +# CHECK-NEXT: 24: 64 89 04 25 01 00 00 00 movl %eax, %fs:1 +# CHECK-NEXT: 2c: 55 pushq %rbp +# CHECK-NEXT: 2d: 55 pushq %rbp +# CHECK-NEXT: 2e: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 31: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 34: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 37: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3a: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 3d: 89 75 f4 movl %esi, -12(%rbp) +# CHECK-NEXT: 40: c2 1e 00 retq $30 +# CHECK-NEXT: 43: 55 pushq %rbp + + .text + .globl foo + .p2align 4 +foo: + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + movq %rsp, %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + ret + pushq %rbp + movl %eax, %fs:0x1 + pushq %rbp + pushq %rbp + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + movl %esi, -12(%rbp) + ret $30 + pushq %rbp Index: llvm/test/MC/X86/x86-64-align-branch-5a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-5a.s @@ -0,0 +1,72 @@ +# Check no nop or prefix is inserted if no branch cross or is against the boundary +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + + +# CHECK: Disassembly of section .text: +# CHECK: 0000000000000000 foo: +# CHECK-NEXT: 0: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 3: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 6: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 9: 89 d1 movl %edx, %ecx +# CHECK-NEXT: b: 31 c0 xorl %eax, %eax +# CHECK-NEXT: d: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 10: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 13: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 16: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 19: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 1c: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 1f: f6 c2 02 testb $2, %dl +# CHECK-NEXT: 22: f3 ab rep stosl %eax, %es:(%rdi) +# CHECK-NEXT: 24: 75 dd jne {{.*}} +# CHECK-NEXT: 26: 31 c0 xorl %eax, %eax +# CHECK-NEXT: 28: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 2b: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 2e: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 31: 89 d1 movl %edx, %ecx +# CHECK-NEXT: 33: 31 c0 xorl %eax, %eax +# CHECK-NEXT: 35: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 38: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 3b: c1 e9 02 shrl $2, %ecx +# CHECK-NEXT: 3e: f6 c2 02 testb $2, %dl +# CHECK-NEXT: 41: e8 00 00 00 00 callq {{.*}} +# CHECK-NEXT: 46: 75 e3 jne {{.*}} +# CHECK-NEXT: 48: 31 c0 xorl %eax, %eax + + .text + .p2align 4,,15 +foo: + shrl $2, %ecx +.L1: + shrl $2, %ecx + shrl $2, %ecx + movl %edx, %ecx + xorl %eax, %eax + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + testb $2, %dl + rep stosl + jne .L1 + xorl %eax, %eax + shrl $2, %ecx +.L2: + shrl $2, %ecx + shrl $2, %ecx + movl %edx, %ecx + xorl %eax, %eax + shrl $2, %ecx + shrl $2, %ecx + shrl $2, %ecx + testb $2, %dl + call bar + jne .L2 + xorl %eax, %eax Index: llvm/test/MC/X86/x86-64-align-branch-6a.s =================================================================== --- /dev/null +++ llvm/test/MC/X86/x86-64-align-branch-6a.s @@ -0,0 +1,44 @@ +# Check no prefix is inserted before instruction with special relocation operand +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-branches-within-32B-boundaries %s | llvm-objdump -d - > %t +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown --x86-align-branch-boundary=32 --x86-align-branch=fused+jcc+jmp --x86-align-branch-prefix-size=5 %s | llvm-objdump -d - > %t2 +# RUN: cmp %t %t2 +# RUN: FileCheck --input-file=%t %s + +# CHECK: file format {{.*}} + + +# CHECK: Disassembly of section .text: + +# CHECK: 0000000000000000 _start: +# CHECK-NEXT: 0: 85 d2 testl %edx, %edx +# CHECK-NEXT: 2: 74 21 je 33 <_start+0x25> +# CHECK-NEXT: 4: 48 85 ff testq %rdi, %rdi +# CHECK-NEXT: 7: 74 1c je 28 <_start+0x25> +# CHECK-NEXT: 9: 48 8d 3d 00 00 00 00 leaq (%rip), %rdi +# CHECK-NEXT: 10: e8 00 00 00 00 callq 0 <_start+0x15> +# CHECK-NEXT: 15: 48 8b 98 00 00 00 00 movq (%rax), %rbx +# CHECK-NEXT: 1c: 90 nop +# CHECK-NEXT: 1d: 90 nop +# CHECK-NEXT: 1e: 90 nop +# CHECK-NEXT: 1f: 90 nop +# CHECK-NEXT: 20: 48 85 db testq %rbx, %rbx +# CHECK-NEXT: 23: 74 00 je 0 <_start+0x25> +# CHECK-NEXT: 25: c3 retq + + .text + .globl _start +_start: + testl %edx, %edx + je .L1 + testq %rdi, %rdi + je .L1 + leaq bar@tlsld(%rip), %rdi + call __tls_get_addr@PLT + movq bar@DTPOFF(%rax), %rbx + testq %rbx, %rbx + je .L1 +.L1: + ret + .section ".tdata", "awT", @progbits +bar: + .long 10