@@ -228,25 +228,24 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
228
228
return 4 ;
229
229
230
230
case MCFragment::FT_Align: {
231
- const MCAlignFragment &AF = cast<MCAlignFragment>(F);
232
- unsigned Offset = getFragmentOffset (AF);
233
- unsigned Size = offsetToAlignment (Offset, AF.getAlignment ());
231
+ unsigned Offset = F.Offset + F.getFixedSize ();
232
+ unsigned Size = offsetToAlignment (Offset, F.getAlignment ());
234
233
235
234
// Insert extra Nops for code alignment if the target define
236
235
// shouldInsertExtraNopBytesForCodeAlign target hook.
237
- if (AF .getParent ()->useCodeAlign () && AF. hasEmitNops () &&
238
- getBackend ().shouldInsertExtraNopBytesForCodeAlign (AF , Size))
239
- return Size;
236
+ if (F .getParent ()->useCodeAlign () && F. hasAlignEmitNops () &&
237
+ getBackend ().shouldInsertExtraNopBytesForCodeAlign (F , Size))
238
+ return F. getFixedSize () + Size;
240
239
241
240
// If we are padding with nops, force the padding to be larger than the
242
241
// minimum nop size.
243
- if (Size > 0 && AF. hasEmitNops ()) {
242
+ if (Size > 0 && F. hasAlignEmitNops ()) {
244
243
while (Size % getBackend ().getMinimumNopSize ())
245
- Size += AF .getAlignment ().value ();
244
+ Size += F .getAlignment ().value ();
246
245
}
247
- if (Size > AF. getMaxBytesToEmit ())
248
- return 0 ;
249
- return Size;
246
+ if (Size > F. getAlignMaxBytesToEmit ())
247
+ Size = 0 ;
248
+ return F. getFixedSize () + Size;
250
249
}
251
250
252
251
case MCFragment::FT_Org: {
@@ -420,6 +419,7 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
420
419
switch (F.getKind ()) {
421
420
case MCFragment::FT_Data:
422
421
case MCFragment::FT_Relaxable:
422
+ case MCFragment::FT_Align:
423
423
case MCFragment::FT_LEB:
424
424
case MCFragment::FT_Dwarf:
425
425
case MCFragment::FT_DwarfFrame:
@@ -433,48 +433,46 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
433
433
const auto &EF = cast<MCFragment>(F);
434
434
OS << StringRef (EF.getContents ().data (), EF.getContents ().size ());
435
435
OS << StringRef (EF.getVarContents ().data (), EF.getVarContents ().size ());
436
- break ;
437
- }
438
- case MCFragment::FT_Align: {
439
- ++stats::EmittedAlignFragments;
440
- const MCAlignFragment &AF = cast<MCAlignFragment>(F);
441
- assert (AF.getFillLen () && " Invalid virtual align in concrete fragment!" );
442
-
443
- uint64_t Count = FragmentSize / AF.getFillLen ();
444
- assert (FragmentSize % AF.getFillLen () == 0 &&
445
- " computeFragmentSize computed size is incorrect" );
446
-
447
- // See if we are aligning with nops, and if so do that first to try to fill
448
- // the Count bytes. Then if that did not fill any bytes or there are any
449
- // bytes left to fill use the Value and ValueSize to fill the rest.
450
- // If we are aligning with nops, ask that target to emit the right data.
451
- if (AF.hasEmitNops ()) {
452
- if (!Asm.getBackend ().writeNopData (OS, Count, AF.getSubtargetInfo ()))
453
- report_fatal_error (" unable to write nop sequence of " +
454
- Twine (Count) + " bytes" );
455
- break ;
456
- }
457
-
458
- // Otherwise, write out in multiples of the value size.
459
- for (uint64_t i = 0 ; i != Count; ++i) {
460
- switch (AF.getFillLen ()) {
461
- default : llvm_unreachable (" Invalid size!" );
462
- case 1 :
463
- OS << char (AF.getFill ());
464
- break ;
465
- case 2 :
466
- support::endian::write<uint16_t >(OS, AF.getFill (), Endian);
467
- break ;
468
- case 4 :
469
- support::endian::write<uint32_t >(OS, AF.getFill (), Endian);
470
- break ;
471
- case 8 :
472
- support::endian::write<uint64_t >(OS, AF.getFill (), Endian);
473
- break ;
436
+ if (F.getKind () == MCFragment::FT_Align) {
437
+ ++stats::EmittedAlignFragments;
438
+ assert (F.getAlignFillLen () &&
439
+ " Invalid virtual align in concrete fragment!" );
440
+
441
+ uint64_t Count = (FragmentSize - F.getFixedSize ()) / F.getAlignFillLen ();
442
+ assert ((FragmentSize - F.getFixedSize ()) % F.getAlignFillLen () == 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
446
+ // fill the Count bytes. Then if that did not fill any bytes or there are
447
+ // any bytes left to fill use the Value and ValueSize to fill the rest. If
448
+ // we are aligning with nops, ask that target to emit the right data.
449
+ if (F.hasAlignEmitNops ()) {
450
+ if (!Asm.getBackend ().writeNopData (OS, Count, F.getSubtargetInfo ()))
451
+ report_fatal_error (" unable to write nop sequence of " + Twine (Count) +
452
+ " bytes" );
453
+ } else {
454
+ // Otherwise, write out in multiples of the value size.
455
+ for (uint64_t i = 0 ; i != Count; ++i) {
456
+ switch (F.getAlignFillLen ()) {
457
+ default :
458
+ llvm_unreachable (" Invalid size!" );
459
+ case 1 :
460
+ OS << char (F.getAlignFill ());
461
+ break ;
462
+ case 2 :
463
+ support::endian::write<uint16_t >(OS, F.getAlignFill (), Endian);
464
+ break ;
465
+ case 4 :
466
+ support::endian::write<uint32_t >(OS, F.getAlignFill (), Endian);
467
+ break ;
468
+ case 8 :
469
+ support::endian::write<uint64_t >(OS, F.getAlignFill (), Endian);
470
+ break ;
471
+ }
472
+ }
474
473
}
475
474
}
476
- break ;
477
- }
475
+ } break ;
478
476
479
477
case MCFragment::FT_Fill: {
480
478
++stats::EmittedFillFragments;
@@ -612,9 +610,7 @@ void MCAssembler::writeSectionData(raw_ostream &OS,
612
610
case MCFragment::FT_Align:
613
611
// Check that we aren't trying to write a non-zero value into a virtual
614
612
// section.
615
- assert ((cast<MCAlignFragment>(F).getFillLen () == 0 ||
616
- cast<MCAlignFragment>(F).getFill () == 0 ) &&
617
- " Invalid align in virtual section!" );
613
+ assert (F.getAlignFill () == 0 && " Invalid align in virtual section!" );
618
614
break ;
619
615
case MCFragment::FT_Fill:
620
616
assert ((cast<MCFillFragment>(F).getValue () == 0 ) &&
@@ -724,34 +720,30 @@ void MCAssembler::layout() {
724
720
for (MCSection &Sec : *this ) {
725
721
for (MCFragment &F : Sec) {
726
722
// Process fragments with fixups here.
727
- if (F.isEncoded ()) {
728
- auto Contents = F.getContents ();
729
- for (MCFixup &Fixup : F.getFixups ()) {
723
+ auto Contents = F.getContents ();
724
+ for (MCFixup &Fixup : F.getFixups ()) {
725
+ uint64_t FixedValue;
726
+ MCValue Target;
727
+ evaluateFixup (F, Fixup, Target, FixedValue,
728
+ /* RecordReloc=*/ true , Contents);
729
+ }
730
+ if (F.getVarFixups ().size ()) {
731
+ // In the variable part, fixup offsets are relative to the fixed part's
732
+ // start. Extend the variable contents to the left to account for the
733
+ // fixed part size.
734
+ Contents = MutableArrayRef (F.getParent ()->ContentStorage )
735
+ .slice (F.VarContentStart - Contents.size (), F.getSize ());
736
+ for (MCFixup &Fixup : F.getVarFixups ()) {
730
737
uint64_t FixedValue;
731
738
MCValue Target;
732
739
evaluateFixup (F, Fixup, Target, FixedValue,
733
740
/* RecordReloc=*/ true , Contents);
734
741
}
735
- // In the variable part, fixup offsets are relative to the fixed part's
736
- // start. Extend the variable contents to the left to account for the
737
- // fixed part size.
738
- auto VarFixups = F.getVarFixups ();
739
- if (VarFixups.size ()) {
740
- Contents =
741
- MutableArrayRef (F.getParent ()->ContentStorage )
742
- .slice (F.VarContentStart - Contents.size (), F.getSize ());
743
- for (MCFixup &Fixup : VarFixups) {
744
- uint64_t FixedValue;
745
- MCValue Target;
746
- evaluateFixup (F, Fixup, Target, FixedValue,
747
- /* RecordReloc=*/ true , Contents);
748
- }
749
- }
750
- } else if (auto *AF = dyn_cast<MCAlignFragment>(&F)) {
742
+ } else if (F.getKind () == MCFragment::FT_Align) {
751
743
// For RISC-V linker relaxation, an alignment relocation might be
752
744
// needed.
753
- if (AF-> hasEmitNops ())
754
- getBackend ().shouldInsertFixupForCodeAlign (*this , *AF );
745
+ if (F. hasAlignEmitNops ())
746
+ getBackend ().shouldInsertFixupForCodeAlign (*this , F );
755
747
}
756
748
}
757
749
}
0 commit comments