@@ -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;
@@ -610,9 +608,7 @@ void MCAssembler::writeSectionData(raw_ostream &OS,
610
608
case MCFragment::FT_Align:
611
609
// Check that we aren't trying to write a non-zero value into a virtual
612
610
// 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!" );
616
612
break ;
617
613
case MCFragment::FT_Fill:
618
614
assert ((cast<MCFillFragment>(F).getValue () == 0 ) &&
@@ -722,34 +718,30 @@ void MCAssembler::layout() {
722
718
for (MCSection &Sec : *this ) {
723
719
for (MCFragment &F : Sec) {
724
720
// 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 ()) {
728
735
uint64_t FixedValue;
729
736
MCValue Target;
730
737
evaluateFixup (F, Fixup, Target, FixedValue,
731
738
/* RecordReloc=*/ true , Contents);
732
739
}
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) {
749
741
// For RISC-V linker relaxation, an alignment relocation might be
750
742
// needed.
751
- if (AF-> hasEmitNops ())
752
- getBackend ().shouldInsertFixupForCodeAlign (*this , *AF );
743
+ if (F. hasAlignEmitNops ())
744
+ getBackend ().shouldInsertFixupForCodeAlign (*this , F );
753
745
}
754
746
}
755
747
}
0 commit comments