Skip to content

Commit

Permalink
[RISCV] Support linker relax function call from auipc and jalr to jal
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ShivaChen committed May 24, 2018
1 parent cfba053 commit 43bfe84
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 2 deletions.
3 changes: 2 additions & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
Expand Up @@ -88,7 +88,8 @@ class RISCVAsmBackend : public MCAsmBackend {
{ "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)
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
Expand Up @@ -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;
}
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
Expand Up @@ -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,
Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
Expand Up @@ -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());
Expand Down Expand Up @@ -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;
}

Expand Down
26 changes: 26 additions & 0 deletions llvm/test/MC/RISCV/linker-relaxation.s
@@ -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

0 comments on commit 43bfe84

Please sign in to comment.