[RISCV] Support linker relax function call from auipc and jalr to jal
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 llvm-svn: 333158
This commit is contained in:
parent
cfba053491
commit
43bfe84451
|
@ -88,7 +88,8 @@ public:
|
|||
{ "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)
|
||||
|
|
|
@ -94,6 +94,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,9 @@ enum Fixups {
|
|||
// 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,
|
||||
|
|
|
@ -186,7 +186,7 @@ RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
|
|||
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());
|
||||
|
@ -254,6 +254,15 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# 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
|
Loading…
Reference in New Issue