To do this:
1. Add fixup_riscv_relax fixup types which eventually will
transfer to R_RISCV_RELAX relocation types.
2. Insert R_RISCV_RELAX relocation types to auipc function call
expression when linker relaxation enabled.
Differential Revision: https://reviews.llvm.org/D44886
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333158
91177308-0d34-0410-b5e6-
96231b3b80d8
{ "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel }
+ { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_riscv_relax", 0, 0, 0 }
};
if (Kind < FirstTargetFixupKind)
return ELF::R_RISCV_RVC_BRANCH;
case RISCV::fixup_riscv_call:
return ELF::R_RISCV_CALL;
+ case RISCV::fixup_riscv_relax:
+ return ELF::R_RISCV_RELAX;
}
}
// fixup_riscv_call - A fixup representing a call attached to the auipc
// instruction in a pair composed of adjacent auipc+jalr instructions.
fixup_riscv_call,
+ // fixup_riscv_relax - Used to generate an R_RISCV_RELAX relocation type,
+ // which indicates the linker may relax the instruction pair.
+ fixup_riscv_relax,
// fixup_riscv_invalid - used as a sentinel and a marker, must be last fixup
fixup_riscv_invalid,
unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
-
+ bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax];
const MCOperand &MO = MI.getOperand(OpNo);
MCInstrDesc const &Desc = MCII.get(MI.getOpcode());
MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
++MCNumFixups;
+ if (EnableRelax) {
+ if (FixupKind == RISCV::fixup_riscv_call) {
+ Fixups.push_back(
+ MCFixup::create(0, Expr, MCFixupKind(RISCV::fixup_riscv_relax),
+ MI.getLoc()));
+ ++MCNumFixups;
+ }
+ }
+
return 0;
}
--- /dev/null
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+relax < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=RELAX-RELOC %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=-relax < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=NORELAX-RELOC %s
+# RUN: llvm-mc -triple riscv32 -mattr=+relax < %s -show-encoding \
+# RUN: | FileCheck -check-prefix=RELAX-FIXUP %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+relax < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=RELAX-RELOC %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=-relax < %s \
+# RUN: | llvm-readobj -r | FileCheck -check-prefix=NORELAX-RELOC %s
+# RUN: llvm-mc -triple riscv64 -mattr=+relax < %s -show-encoding \
+# RUN: | FileCheck -check-prefix=RELAX-FIXUP %s
+
+.long foo
+
+.L1:
+call foo
+# NORELAX-RELOC: R_RISCV_CALL foo 0x0
+# NORELAX-RELOC-NOT: R_RISCV_RELAX
+# RELAX-RELOC: R_RISCV_CALL foo 0x0
+# RELAX-RELOC: R_RISCV_RELAX foo 0x0
+# RELAX-FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_relax
+# RELAX-FIXUP: fixup B - offset: 0, value: foo, kind:
+beq s1, s1, .L1
+# RELAX-RELOC: R_RISCV_BRANCH .L1 0x0
+# RELAX-FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_branch