@@ -227,25 +227,24 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
227
227
return 4 ;
228
228
229
229
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 ());
233
232
234
233
// Insert extra Nops for code alignment if the target define
235
234
// 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;
239
238
240
239
// If we are padding with nops, force the padding to be larger than the
241
240
// minimum nop size.
242
- if (Size > 0 && AF. hasEmitNops ()) {
241
+ if (Size > 0 && F. hasAlignEmitNops ()) {
243
242
while (Size % getBackend ().getMinimumNopSize ())
244
- Size += AF .getAlignment ().value ();
243
+ Size += F .getAlignment ().value ();
245
244
}
246
- if (Size > AF. getMaxBytesToEmit ())
247
- return 0 ;
248
- return Size;
245
+ if (Size > F. getAlignMaxBytesToEmit ())
246
+ Size = 0 ;
247
+ return F. getFixedSize () + Size;
249
248
}
250
249
251
250
case MCFragment::FT_Org: {
@@ -419,6 +418,7 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
419
418
switch (F.getKind ()) {
420
419
case MCFragment::FT_Data:
421
420
case MCFragment::FT_Relaxable:
421
+ case MCFragment::FT_Align:
422
422
case MCFragment::FT_LEB:
423
423
case MCFragment::FT_Dwarf:
424
424
case MCFragment::FT_DwarfFrame:
@@ -431,48 +431,46 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
431
431
const auto &EF = cast<MCFragment>(F);
432
432
OS << StringRef (EF.getContents ().data (), EF.getContents ().size ());
433
433
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
+ }
472
471
}
473
472
}
474
- break ;
475
- }
473
+ } break ;
476
474
477
475
case MCFragment::FT_Fill: {
478
476
++stats::EmittedFillFragments;
@@ -703,34 +701,30 @@ void MCAssembler::layout() {
703
701
for (MCSection &Sec : *this ) {
704
702
for (MCFragment &F : Sec) {
705
703
// 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 ()) {
709
718
uint64_t FixedValue;
710
719
MCValue Target;
711
720
evaluateFixup (F, Fixup, Target, FixedValue,
712
721
/* RecordReloc=*/ true , Contents);
713
722
}
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) {
730
724
// For RISC-V linker relaxation, an alignment relocation might be
731
725
// needed.
732
- if (AF-> hasEmitNops ())
733
- getBackend ().shouldInsertFixupForCodeAlign (*this , *AF );
726
+ if (F. hasAlignEmitNops ())
727
+ getBackend ().shouldInsertFixupForCodeAlign (*this , F );
734
728
}
735
729
}
736
730
}
0 commit comments