diff options
Diffstat (limited to 'llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp')
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index 49239ac9099..7672fea5d95 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "RISCVAsmBackend.h" +#include "RISCVMCExpr.h" #include "llvm/ADT/APInt.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" @@ -21,6 +22,44 @@ using namespace llvm; +// If linker relaxation is enabled, or the relax option had previously been +// enabled, always emit relocations even if the fixup can be resolved. This is +// necessary for correctness as offsets may change during relaxation. +bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, + const MCFixup &Fixup, + const MCValue &Target) { + bool ShouldForce = false; + + switch ((unsigned)Fixup.getKind()) { + default: + break; + case RISCV::fixup_riscv_pcrel_lo12_i: + case RISCV::fixup_riscv_pcrel_lo12_s: + // For pcrel_lo12, force a relocation if the target of the corresponding + // pcrel_hi20 is not in the same fragment. + const MCFixup *T = cast<RISCVMCExpr>(Fixup.getValue())->getPCRelHiFixup(); + if (!T) { + Asm.getContext().reportError(Fixup.getLoc(), + "could not find corresponding %pcrel_hi"); + return false; + } + + switch ((unsigned)T->getKind()) { + default: + llvm_unreachable("Unexpected fixup kind for pcrel_lo12"); + break; + case RISCV::fixup_riscv_pcrel_hi20: + ShouldForce = T->getValue()->findAssociatedFragment() != + Fixup.getValue()->findAssociatedFragment(); + break; + } + break; + } + + return ShouldForce || STI.getFeatureBits()[RISCV::FeatureRelax] || + ForceRelocs; +} + bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, uint64_t Value, |