@@ -227,25 +227,24 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
227227 return 4 ;
228228
229229 case MCFragment::FT_Align: {
230- const MCAlignFragment &AF = cast<MCAlignFragment>(F);
231- unsigned Offset = getFragmentOffset (AF);
232- unsigned Size = offsetToAlignment (Offset, AF.getAlignment ());
230+ unsigned Offset = F.Offset + F.getFixedSize ();
231+ unsigned Size = offsetToAlignment (Offset, F.getAlignment ());
233232
234233 // Insert extra Nops for code alignment if the target define
235234 // shouldInsertExtraNopBytesForCodeAlign target hook.
236- if (AF .getParent ()->useCodeAlign () && AF. hasEmitNops () &&
237- getBackend ().shouldInsertExtraNopBytesForCodeAlign (AF , Size))
238- return Size;
235+ if (F .getParent ()->useCodeAlign () && F. hasAlignEmitNops () &&
236+ getBackend ().shouldInsertExtraNopBytesForCodeAlign (F , Size))
237+ return F. getFixedSize () + Size;
239238
240239 // If we are padding with nops, force the padding to be larger than the
241240 // minimum nop size.
242- if (Size > 0 && AF. hasEmitNops ()) {
241+ if (Size > 0 && F. hasAlignEmitNops ()) {
243242 while (Size % getBackend ().getMinimumNopSize ())
244- Size += AF .getAlignment ().value ();
243+ Size += F .getAlignment ().value ();
245244 }
246- if (Size > AF. getMaxBytesToEmit ())
247- return 0 ;
248- return Size;
245+ if (Size > F. getAlignMaxBytesToEmit ())
246+ Size = 0 ;
247+ return F. getFixedSize () + Size;
249248 }
250249
251250 case MCFragment::FT_Org: {
@@ -419,6 +418,7 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
419418 switch (F.getKind ()) {
420419 case MCFragment::FT_Data:
421420 case MCFragment::FT_Relaxable:
421+ case MCFragment::FT_Align:
422422 case MCFragment::FT_LEB:
423423 case MCFragment::FT_Dwarf:
424424 case MCFragment::FT_DwarfFrame:
@@ -431,48 +431,46 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
431431 const auto &EF = cast<MCFragment>(F);
432432 OS << StringRef (EF.getContents ().data (), EF.getContents ().size ());
433433 OS << StringRef (EF.getVarContents ().data (), EF.getVarContents ().size ());
434- break ;
435- }
436- case MCFragment::FT_Align: {
437- ++stats::EmittedAlignFragments;
438- const MCAlignFragment &AF = cast<MCAlignFragment>(F);
439- assert (AF.getFillLen () && " Invalid virtual align in concrete fragment!" );
440-
441- uint64_t Count = FragmentSize / AF.getFillLen ();
442- assert (FragmentSize % AF.getFillLen () == 0 &&
443- " computeFragmentSize computed size is incorrect" );
444-
445- // See if we are aligning with nops, and if so do that first to try to fill
446- // the Count bytes. Then if that did not fill any bytes or there are any
447- // bytes left to fill use the Value and ValueSize to fill the rest.
448- // If we are aligning with nops, ask that target to emit the right data.
449- if (AF.hasEmitNops ()) {
450- if (!Asm.getBackend ().writeNopData (OS, Count, AF.getSubtargetInfo ()))
451- report_fatal_error (" unable to write nop sequence of " +
452- Twine (Count) + " bytes" );
453- break ;
454- }
455-
456- // Otherwise, write out in multiples of the value size.
457- for (uint64_t i = 0 ; i != Count; ++i) {
458- switch (AF.getFillLen ()) {
459- default : llvm_unreachable (" Invalid size!" );
460- case 1 :
461- OS << char (AF.getFill ());
462- break ;
463- case 2 :
464- support::endian::write<uint16_t >(OS, AF.getFill (), Endian);
465- break ;
466- case 4 :
467- support::endian::write<uint32_t >(OS, AF.getFill (), Endian);
468- break ;
469- case 8 :
470- support::endian::write<uint64_t >(OS, AF.getFill (), Endian);
471- break ;
434+ if (F.getKind () == MCFragment::FT_Align) {
435+ ++stats::EmittedAlignFragments;
436+ assert (F.getAlignFillLen () &&
437+ " Invalid virtual align in concrete fragment!" );
438+
439+ uint64_t Count = (FragmentSize - F.getFixedSize ()) / F.getAlignFillLen ();
440+ assert ((FragmentSize - F.getFixedSize ()) % F.getAlignFillLen () == 0 &&
441+ " computeFragmentSize computed size is incorrect" );
442+
443+ // See if we are aligning with nops, and if so do that first to try to
444+ // fill the Count bytes. Then if that did not fill any bytes or there are
445+ // any bytes left to fill use the Value and ValueSize to fill the rest. If
446+ // we are aligning with nops, ask that target to emit the right data.
447+ if (F.hasAlignEmitNops ()) {
448+ if (!Asm.getBackend ().writeNopData (OS, Count, F.getSubtargetInfo ()))
449+ report_fatal_error (" unable to write nop sequence of " + Twine (Count) +
450+ " bytes" );
451+ } else {
452+ // Otherwise, write out in multiples of the value size.
453+ for (uint64_t i = 0 ; i != Count; ++i) {
454+ switch (F.getAlignFillLen ()) {
455+ default :
456+ llvm_unreachable (" Invalid size!" );
457+ case 1 :
458+ OS << char (F.getAlignFill ());
459+ break ;
460+ case 2 :
461+ support::endian::write<uint16_t >(OS, F.getAlignFill (), Endian);
462+ break ;
463+ case 4 :
464+ support::endian::write<uint32_t >(OS, F.getAlignFill (), Endian);
465+ break ;
466+ case 8 :
467+ support::endian::write<uint64_t >(OS, F.getAlignFill (), Endian);
468+ break ;
469+ }
470+ }
472471 }
473472 }
474- break ;
475- }
473+ } break ;
476474
477475 case MCFragment::FT_Fill: {
478476 ++stats::EmittedFillFragments;
@@ -610,9 +608,7 @@ void MCAssembler::writeSectionData(raw_ostream &OS,
610608 case MCFragment::FT_Align:
611609 // Check that we aren't trying to write a non-zero value into a virtual
612610 // section.
613- assert ((cast<MCAlignFragment>(F).getFillLen () == 0 ||
614- cast<MCAlignFragment>(F).getFill () == 0 ) &&
615- " Invalid align in virtual section!" );
611+ assert (F.getAlignFill () == 0 && " Invalid align in virtual section!" );
616612 break ;
617613 case MCFragment::FT_Fill:
618614 assert ((cast<MCFillFragment>(F).getValue () == 0 ) &&
@@ -722,34 +718,30 @@ void MCAssembler::layout() {
722718 for (MCSection &Sec : *this ) {
723719 for (MCFragment &F : Sec) {
724720 // Process fragments with fixups here.
725- if (F.isEncoded ()) {
726- auto Contents = F.getContents ();
727- for (MCFixup &Fixup : F.getFixups ()) {
721+ auto Contents = F.getContents ();
722+ for (MCFixup &Fixup : F.getFixups ()) {
723+ uint64_t FixedValue;
724+ MCValue Target;
725+ evaluateFixup (F, Fixup, Target, FixedValue,
726+ /* RecordReloc=*/ true , Contents);
727+ }
728+ if (F.getVarFixups ().size ()) {
729+ // In the variable part, fixup offsets are relative to the fixed part's
730+ // start. Extend the variable contents to the left to account for the
731+ // fixed part size.
732+ Contents = MutableArrayRef (F.getParent ()->ContentStorage )
733+ .slice (F.VarContentStart - Contents.size (), F.getSize ());
734+ for (MCFixup &Fixup : F.getVarFixups ()) {
728735 uint64_t FixedValue;
729736 MCValue Target;
730737 evaluateFixup (F, Fixup, Target, FixedValue,
731738 /* RecordReloc=*/ true , Contents);
732739 }
733- // In the variable part, fixup offsets are relative to the fixed part's
734- // start. Extend the variable contents to the left to account for the
735- // fixed part size.
736- auto VarFixups = F.getVarFixups ();
737- if (VarFixups.size ()) {
738- Contents =
739- MutableArrayRef (F.getParent ()->ContentStorage )
740- .slice (F.VarContentStart - Contents.size (), F.getSize ());
741- for (MCFixup &Fixup : VarFixups) {
742- uint64_t FixedValue;
743- MCValue Target;
744- evaluateFixup (F, Fixup, Target, FixedValue,
745- /* RecordReloc=*/ true , Contents);
746- }
747- }
748- } else if (auto *AF = dyn_cast<MCAlignFragment>(&F)) {
740+ } else if (F.getKind () == MCFragment::FT_Align) {
749741 // For RISC-V linker relaxation, an alignment relocation might be
750742 // needed.
751- if (AF-> hasEmitNops ())
752- getBackend ().shouldInsertFixupForCodeAlign (*this , *AF );
743+ if (F. hasAlignEmitNops ())
744+ getBackend ().shouldInsertFixupForCodeAlign (*this , F );
753745 }
754746 }
755747 }
0 commit comments