@@ -549,12 +549,6 @@ static void CheckBundleSubtargets(const MCSubtargetInfo *OldSTI,
549
549
void MCELFStreamer::emitInstToData (const MCInst &Inst,
550
550
const MCSubtargetInfo &STI) {
551
551
MCAssembler &Assembler = getAssembler ();
552
- SmallVector<MCFixup, 4 > Fixups;
553
- SmallString<256 > Code;
554
- Assembler.getEmitter ().encodeInstruction (Inst, Code, Fixups, STI);
555
-
556
- for (auto &Fixup : Fixups)
557
- fixSymbolsInTLSFixups (Fixup.getValue ());
558
552
559
553
// There are several possibilities here:
560
554
//
@@ -573,7 +567,16 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
573
567
// the group, though.
574
568
MCDataFragment *DF;
575
569
570
+ // When bundling is enabled, we can't just append to the data fragment, as it
571
+ // might need to be a MCCompactEncodedInstFragment for zero fixups.
576
572
if (Assembler.isBundlingEnabled ()) {
573
+ SmallVector<MCFixup, 4 > Fixups;
574
+ SmallString<256 > Code;
575
+ Assembler.getEmitter ().encodeInstruction (Inst, Code, Fixups, STI);
576
+
577
+ for (auto &Fixup : Fixups)
578
+ fixSymbolsInTLSFixups (Fixup.getValue ());
579
+
577
580
MCSection &Sec = *getCurrentSectionOnly ();
578
581
if (Assembler.getRelaxAll () && isBundleLocked ()) {
579
582
// If the -mc-relax-all flag is used and we are bundle-locked, we re-use
@@ -596,6 +599,9 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
596
599
// Optimize memory usage by emitting the instruction to a
597
600
// MCCompactEncodedInstFragment when not in a bundle-locked group and
598
601
// there are no fixups registered.
602
+ //
603
+ // Apparently, this is not just a performance optimization? Using an
604
+ // MCDataFragment at this point causes test failures.
599
605
MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment ();
600
606
insert (CEIF);
601
607
CEIF->getContents ().append (Code.begin (), Code.end ());
@@ -616,28 +622,44 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst,
616
622
// We're now emitting an instruction in a bundle group, so this flag has
617
623
// to be turned off.
618
624
Sec.setBundleGroupBeforeFirstInst (false );
619
- } else {
620
- DF = getOrCreateDataFragment (&STI);
625
+
626
+ for (auto &Fixup : Fixups) {
627
+ Fixup.setOffset (Fixup.getOffset () + DF->getContents ().size ());
628
+ DF->getFixups ().push_back (Fixup);
629
+ }
630
+
631
+ DF->setHasInstructions (STI);
632
+ if (!Fixups.empty () && Fixups.back ().getTargetKind () ==
633
+ getAssembler ().getBackend ().RelaxFixupKind )
634
+ DF->setLinkerRelaxable ();
635
+
636
+ DF->getContents ().append (Code.begin (), Code.end ());
637
+
638
+ if (Assembler.getRelaxAll () && !isBundleLocked ()) {
639
+ mergeFragment (getOrCreateDataFragment (&STI), DF);
640
+ delete DF;
641
+ }
642
+ return ;
621
643
}
622
644
623
- // Add the fixups and data.
645
+ DF = getOrCreateDataFragment (&STI);
646
+
647
+ // Emit instruction directly into data fragment.
648
+ size_t FixupStartIndex = DF->getFixups ().size ();
649
+ size_t CodeOffset = DF->getContents ().size ();
650
+ Assembler.getEmitter ().encodeInstruction (Inst, DF->getContents (),
651
+ DF->getFixups (), STI);
652
+
653
+ auto Fixups = MutableArrayRef (DF->getFixups ()).slice (FixupStartIndex);
624
654
for (auto &Fixup : Fixups) {
625
- Fixup.setOffset (Fixup.getOffset () + DF-> getContents (). size () );
626
- DF-> getFixups (). push_back (Fixup );
655
+ Fixup.setOffset (Fixup.getOffset () + CodeOffset );
656
+ fixSymbolsInTLSFixups (Fixup. getValue () );
627
657
}
628
658
629
659
DF->setHasInstructions (STI);
630
660
if (!Fixups.empty () && Fixups.back ().getTargetKind () ==
631
661
getAssembler ().getBackend ().RelaxFixupKind )
632
662
DF->setLinkerRelaxable ();
633
- DF->getContents ().append (Code.begin (), Code.end ());
634
-
635
- if (Assembler.isBundlingEnabled () && Assembler.getRelaxAll ()) {
636
- if (!isBundleLocked ()) {
637
- mergeFragment (getOrCreateDataFragment (&STI), DF);
638
- delete DF;
639
- }
640
- }
641
663
}
642
664
643
665
void MCELFStreamer::emitBundleAlignMode (Align Alignment) {
0 commit comments