@@ -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;
@@ -703,34 +701,30 @@ void MCAssembler::layout() {
703701 for (MCSection &Sec : *this ) {
704702 for (MCFragment &F : Sec) {
705703 // Process fragments with fixups here.
706- if (F.isEncoded ()) {
707- auto Contents = F.getContents ();
708- for (MCFixup &Fixup : F.getFixups ()) {
704+ auto Contents = F.getContents ();
705+ for (MCFixup &Fixup : F.getFixups ()) {
706+ uint64_t FixedValue;
707+ MCValue Target;
708+ evaluateFixup (F, Fixup, Target, FixedValue,
709+ /* RecordReloc=*/ true , Contents);
710+ }
711+ if (F.getVarFixups ().size ()) {
712+ // In the variable part, fixup offsets are relative to the fixed part's
713+ // start. Extend the variable contents to the left to account for the
714+ // fixed part size.
715+ Contents = MutableArrayRef (F.getParent ()->ContentStorage )
716+ .slice (F.VarContentStart - Contents.size (), F.getSize ());
717+ for (MCFixup &Fixup : F.getVarFixups ()) {
709718 uint64_t FixedValue;
710719 MCValue Target;
711720 evaluateFixup (F, Fixup, Target, FixedValue,
712721 /* RecordReloc=*/ true , Contents);
713722 }
714- // In the variable part, fixup offsets are relative to the fixed part's
715- // start. Extend the variable contents to the left to account for the
716- // fixed part size.
717- auto VarFixups = F.getVarFixups ();
718- if (VarFixups.size ()) {
719- Contents =
720- MutableArrayRef (F.getParent ()->ContentStorage )
721- .slice (F.VarContentStart - Contents.size (), F.getSize ());
722- for (MCFixup &Fixup : VarFixups) {
723- uint64_t FixedValue;
724- MCValue Target;
725- evaluateFixup (F, Fixup, Target, FixedValue,
726- /* RecordReloc=*/ true , Contents);
727- }
728- }
729- } else if (auto *AF = dyn_cast<MCAlignFragment>(&F)) {
723+ } else if (F.getKind () == MCFragment::FT_Align) {
730724 // For RISC-V linker relaxation, an alignment relocation might be
731725 // needed.
732- if (AF-> hasEmitNops ())
733- getBackend ().shouldInsertFixupForCodeAlign (*this , *AF );
726+ if (F. hasAlignEmitNops ())
727+ getBackend ().shouldInsertFixupForCodeAlign (*this , F );
734728 }
735729 }
736730 }
0 commit comments