@@ -136,9 +136,11 @@ class X86AsmBackend : public MCAsmBackend {
136136
137137 bool needAlign (MCObjectStreamer &OS) const ;
138138 bool needAlignInst (const MCInst &Inst) const ;
139+ bool allowAutoPaddingForInst (const MCInst &Inst, MCObjectStreamer &OS) const ;
139140 MCInst PrevInst;
140141 MCBoundaryAlignFragment *PendingBoundaryAlign = nullptr ;
141142 std::pair<MCFragment *, size_t > PrevInstPosition;
143+ bool AllowAutoPaddingForInst;
142144
143145public:
144146 X86AsmBackend (const Target &T, const MCSubtargetInfo &STI)
@@ -538,13 +540,8 @@ static size_t getSizeForInstFragment(const MCFragment *F) {
538540 }
539541}
540542
541- // / Check if the instruction operand needs to be aligned. Padding is disabled
542- // / before intruction which may be rewritten by linker(e.g. TLSCALL).
543+ // / Check if the instruction operand needs to be aligned.
543544bool X86AsmBackend::needAlignInst (const MCInst &Inst) const {
544- // Linker may rewrite the instruction with variant symbol operand.
545- if (hasVariantSymbol (Inst))
546- return false ;
547-
548545 const MCInstrDesc &InstDesc = MCII->get (Inst.getOpcode ());
549546 return (InstDesc.isConditionalBranch () &&
550547 (AlignBranchType & X86::AlignBranchJcc)) ||
@@ -558,31 +555,53 @@ bool X86AsmBackend::needAlignInst(const MCInst &Inst) const {
558555 (AlignBranchType & X86::AlignBranchIndirect));
559556}
560557
561- // / Insert BoundaryAlignFragment before instructions to align branches.
562- void X86AsmBackend::emitInstructionBegin (MCObjectStreamer &OS,
563- const MCInst &Inst) {
564- if (!needAlign (OS))
565- return ;
558+ // / Return true if we can insert NOP or prefixes automatically before the
559+ // / the instruction to be emitted.
560+ bool X86AsmBackend::allowAutoPaddingForInst (const MCInst &Inst,
561+ MCObjectStreamer &OS) const {
562+ if (hasVariantSymbol (Inst))
563+ // Linker may rewrite the instruction with variant symbol operand(e.g.
564+ // TLSCALL).
565+ return false ;
566566
567567 if (hasInterruptDelaySlot (PrevInst))
568568 // If this instruction follows an interrupt enabling instruction with a one
569569 // instruction delay, inserting a nop would change behavior.
570- return ;
570+ return false ;
571571
572572 if (isPrefix (PrevInst, *MCII))
573- // If this instruction follows a prefix, inserting a nop would change
573+ // If this instruction follows a prefix, inserting a nop/prefix would change
574574 // semantic.
575- return ;
575+ return false ;
576+
577+ if (isPrefix (Inst, *MCII))
578+ // If this instruction is a prefix, inserting a prefix would change
579+ // semantic.
580+ return false ;
576581
577582 if (isRightAfterData (OS.getCurrentFragment (), PrevInstPosition))
578583 // If this instruction follows any data, there is no clear
579- // instruction boundary, inserting a nop would change semantic.
584+ // instruction boundary, inserting a nop/prefix would change semantic.
585+ return false ;
586+
587+ return true ;
588+ }
589+
590+ // / Insert BoundaryAlignFragment before instructions to align branches.
591+ void X86AsmBackend::emitInstructionBegin (MCObjectStreamer &OS,
592+ const MCInst &Inst) {
593+ AllowAutoPaddingForInst = allowAutoPaddingForInst (Inst, OS);
594+
595+ if (!needAlign (OS))
580596 return ;
581597
582598 if (!isMacroFused (PrevInst, Inst))
583599 // Macro fusion doesn't happen indeed, clear the pending.
584600 PendingBoundaryAlign = nullptr ;
585601
602+ if (!AllowAutoPaddingForInst)
603+ return ;
604+
586605 if (PendingBoundaryAlign &&
587606 OS.getCurrentFragment ()->getPrevNode () == PendingBoundaryAlign) {
588607 // Macro fusion actually happens and there is no other fragment inserted
@@ -617,12 +636,14 @@ void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
617636
618637// / Set the last fragment to be aligned for the BoundaryAlignFragment.
619638void X86AsmBackend::emitInstructionEnd (MCObjectStreamer &OS, const MCInst &Inst) {
620- if (!needAlign (OS))
621- return ;
622-
623639 PrevInst = Inst;
624640 MCFragment *CF = OS.getCurrentFragment ();
625641 PrevInstPosition = std::make_pair (CF, getSizeForInstFragment (CF));
642+ if (auto *F = dyn_cast_or_null<MCRelaxableFragment>(CF))
643+ F->setAllowAutoPadding (AllowAutoPaddingForInst);
644+
645+ if (!needAlign (OS))
646+ return ;
626647
627648 if (!needAlignInst (Inst) || !PendingBoundaryAlign)
628649 return ;
@@ -827,12 +848,6 @@ static bool isFullyRelaxed(const MCRelaxableFragment &RF) {
827848 return getRelaxedOpcode (Inst, Is16BitMode) == Inst.getOpcode ();
828849}
829850
830-
831- static bool shouldAddPrefix (const MCInst &Inst, const MCInstrInfo &MCII) {
832- // Linker may rewrite the instruction with variant symbol operand.
833- return !hasVariantSymbol (Inst);
834- }
835-
836851static unsigned getRemainingPrefixSize (const MCInst &Inst,
837852 const MCSubtargetInfo &STI,
838853 MCCodeEmitter &Emitter) {
@@ -856,7 +871,7 @@ static unsigned getRemainingPrefixSize(const MCInst &Inst,
856871bool X86AsmBackend::padInstructionViaPrefix (MCRelaxableFragment &RF,
857872 MCCodeEmitter &Emitter,
858873 unsigned &RemainingSize) const {
859- if (!shouldAddPrefix ( RF.getInst (), *MCII ))
874+ if (!RF.getAllowAutoPadding ( ))
860875 return false ;
861876 // If the instruction isn't fully relaxed, shifting it around might require a
862877 // larger value for one of the fixups then can be encoded. The outer loop
0 commit comments