@@ -403,6 +403,46 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
403
403
llvm_unreachable (" invalid fragment kind" );
404
404
}
405
405
406
+ // Compute the amount of padding required before the fragment \p F to
407
+ // obey bundling restrictions, where \p FOffset is the fragment's offset in
408
+ // its section and \p FSize is the fragment's size.
409
+ static uint64_t computeBundlePadding (unsigned BundleSize,
410
+ const MCEncodedFragment *F,
411
+ uint64_t FOffset, uint64_t FSize) {
412
+ uint64_t OffsetInBundle = FOffset & (BundleSize - 1 );
413
+ uint64_t EndOfFragment = OffsetInBundle + FSize;
414
+
415
+ // There are two kinds of bundling restrictions:
416
+ //
417
+ // 1) For alignToBundleEnd(), add padding to ensure that the fragment will
418
+ // *end* on a bundle boundary.
419
+ // 2) Otherwise, check if the fragment would cross a bundle boundary. If it
420
+ // would, add padding until the end of the bundle so that the fragment
421
+ // will start in a new one.
422
+ if (F->alignToBundleEnd ()) {
423
+ // Three possibilities here:
424
+ //
425
+ // A) The fragment just happens to end at a bundle boundary, so we're good.
426
+ // B) The fragment ends before the current bundle boundary: pad it just
427
+ // enough to reach the boundary.
428
+ // C) The fragment ends after the current bundle boundary: pad it until it
429
+ // reaches the end of the next bundle boundary.
430
+ //
431
+ // Note: this code could be made shorter with some modulo trickery, but it's
432
+ // intentionally kept in its more explicit form for simplicity.
433
+ if (EndOfFragment == BundleSize)
434
+ return 0 ;
435
+ else if (EndOfFragment < BundleSize)
436
+ return BundleSize - EndOfFragment;
437
+ else { // EndOfFragment > BundleSize
438
+ return 2 * BundleSize - EndOfFragment;
439
+ }
440
+ } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize)
441
+ return BundleSize - OffsetInBundle;
442
+ else
443
+ return 0 ;
444
+ }
445
+
406
446
void MCAsmLayout::layoutBundle (MCFragment *Prev, MCFragment *F) {
407
447
// If bundling is enabled and this fragment has instructions in it, it has to
408
448
// obey the bundling restrictions. With padding, we'll have:
@@ -433,8 +473,8 @@ void MCAsmLayout::layoutBundle(MCFragment *Prev, MCFragment *F) {
433
473
if (FSize > Assembler.getBundleAlignSize ())
434
474
report_fatal_error (" Fragment can't be larger than a bundle size" );
435
475
436
- uint64_t RequiredBundlePadding =
437
- computeBundlePadding ( Assembler, EF, EF->Offset , FSize);
476
+ uint64_t RequiredBundlePadding = computeBundlePadding (
477
+ Assembler. getBundleAlignSize () , EF, EF->Offset , FSize);
438
478
if (RequiredBundlePadding > UINT8_MAX)
439
479
report_fatal_error (" Padding cannot exceed 255 bytes" );
440
480
EF->setBundlePadding (static_cast <uint8_t >(RequiredBundlePadding));
0 commit comments