@@ -31,8 +31,8 @@ using namespace llvm;
3131LoongArchAsmBackend::LoongArchAsmBackend (const MCSubtargetInfo &STI,
3232 uint8_t OSABI, bool Is64Bit,
3333 const MCTargetOptions &Options)
34- : MCAsmBackend(llvm::endianness::little, ELF::R_LARCH_RELAX), STI(STI ),
35- OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {}
34+ : MCAsmBackend(llvm::endianness::little, /* LinkerRelaxation= */ true ),
35+ STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {}
3636
3737std::optional<MCFixupKind>
3838LoongArchAsmBackend::getFixupKind (StringRef Name) const {
@@ -444,60 +444,72 @@ bool LoongArchAsmBackend::addReloc(MCAssembler &Asm, const MCFragment &F,
444444 return MCAsmBackend::addReloc (Asm, F, Fixup, Target, FixedValue, IsResolved,
445445 CurSTI);
446446 };
447- if (!Target.getSubSym ())
448- return Fallback ();
449- assert (Target.getSpecifier () == 0 &&
450- " relocatable SymA-SymB cannot have relocation specifier" );
451- std::pair<MCFixupKind, MCFixupKind> FK;
452447 uint64_t FixedValueA, FixedValueB;
453- const MCSymbol &SA = *Target.getAddSym ();
454- const MCSymbol &SB = *Target.getSubSym ();
455-
456- bool force = !SA.isInSection () || !SB.isInSection ();
457- if (!force) {
458- const MCSection &SecA = SA.getSection ();
459- const MCSection &SecB = SB.getSection ();
460-
461- // We need record relocation if SecA != SecB. Usually SecB is same as the
462- // section of Fixup, which will be record the relocation as PCRel. If SecB
463- // is not same as the section of Fixup, it will report error. Just return
464- // false and then this work can be finished by handleFixup.
465- if (&SecA != &SecB)
466- return Fallback ();
467-
468- // In SecA == SecB case. If the linker relaxation is enabled, we need record
469- // the ADD, SUB relocations. Otherwise the FixedValue has already been calc-
470- // ulated out in evaluateFixup, return true and avoid record relocations.
471- if (!STI.hasFeature (LoongArch::FeatureRelax))
472- return true ;
448+ if (Target.getSubSym ()) {
449+ assert (Target.getSpecifier () == 0 &&
450+ " relocatable SymA-SymB cannot have relocation specifier" );
451+ std::pair<MCFixupKind, MCFixupKind> FK;
452+ const MCSymbol &SA = *Target.getAddSym ();
453+ const MCSymbol &SB = *Target.getSubSym ();
454+
455+ bool force = !SA.isInSection () || !SB.isInSection ();
456+ if (!force) {
457+ const MCSection &SecA = SA.getSection ();
458+ const MCSection &SecB = SB.getSection ();
459+
460+ // We need record relocation if SecA != SecB. Usually SecB is same as the
461+ // section of Fixup, which will be record the relocation as PCRel. If SecB
462+ // is not same as the section of Fixup, it will report error. Just return
463+ // false and then this work can be finished by handleFixup.
464+ if (&SecA != &SecB)
465+ return Fallback ();
466+
467+ // In SecA == SecB case. If the linker relaxation is enabled, we need
468+ // record the ADD, SUB relocations. Otherwise the FixedValue has already
469+ // been calc- ulated out in evaluateFixup, return true and avoid record
470+ // relocations.
471+ if (!STI.hasFeature (LoongArch::FeatureRelax))
472+ return true ;
473+ }
474+
475+ switch (Fixup.getKind ()) {
476+ case llvm::FK_Data_1:
477+ FK = getRelocPairForSize (8 );
478+ break ;
479+ case llvm::FK_Data_2:
480+ FK = getRelocPairForSize (16 );
481+ break ;
482+ case llvm::FK_Data_4:
483+ FK = getRelocPairForSize (32 );
484+ break ;
485+ case llvm::FK_Data_8:
486+ FK = getRelocPairForSize (64 );
487+ break ;
488+ case llvm::FK_Data_leb128:
489+ FK = getRelocPairForSize (128 );
490+ break ;
491+ default :
492+ llvm_unreachable (" unsupported fixup size" );
493+ }
494+ MCValue A = MCValue::get (Target.getAddSym (), nullptr , Target.getConstant ());
495+ MCValue B = MCValue::get (Target.getSubSym ());
496+ auto FA = MCFixup::create (Fixup.getOffset (), nullptr , std::get<0 >(FK));
497+ auto FB = MCFixup::create (Fixup.getOffset (), nullptr , std::get<1 >(FK));
498+ Asm.getWriter ().recordRelocation (Asm, &F, FA, A, FixedValueA);
499+ Asm.getWriter ().recordRelocation (Asm, &F, FB, B, FixedValueB);
500+ FixedValue = FixedValueA - FixedValueB;
501+ return false ;
473502 }
474503
475- switch (Fixup.getKind ()) {
476- case llvm::FK_Data_1:
477- FK = getRelocPairForSize (8 );
478- break ;
479- case llvm::FK_Data_2:
480- FK = getRelocPairForSize (16 );
481- break ;
482- case llvm::FK_Data_4:
483- FK = getRelocPairForSize (32 );
484- break ;
485- case llvm::FK_Data_8:
486- FK = getRelocPairForSize (64 );
487- break ;
488- case llvm::FK_Data_leb128:
489- FK = getRelocPairForSize (128 );
490- break ;
491- default :
492- llvm_unreachable (" unsupported fixup size" );
504+ IsResolved = Fallback ();
505+ // If linker relaxation is enabled and supported by the current relocation,
506+ // append a RELAX relocation.
507+ if (Fixup.needsRelax ()) {
508+ auto FA = MCFixup::create (Fixup.getOffset (), nullptr , ELF::R_LARCH_RELAX);
509+ Asm.getWriter ().recordRelocation (Asm, &F, FA, MCValue::get (nullptr ),
510+ FixedValueA);
493511 }
494- MCValue A = MCValue::get (Target.getAddSym (), nullptr , Target.getConstant ());
495- MCValue B = MCValue::get (Target.getSubSym ());
496- auto FA = MCFixup::create (Fixup.getOffset (), nullptr , std::get<0 >(FK));
497- auto FB = MCFixup::create (Fixup.getOffset (), nullptr , std::get<1 >(FK));
498- Asm.getWriter ().recordRelocation (Asm, &F, FA, A, FixedValueA);
499- Asm.getWriter ().recordRelocation (Asm, &F, FB, B, FixedValueB);
500- FixedValue = FixedValueA - FixedValueB;
512+
501513 return true ;
502514}
503515
0 commit comments