From 0ec6aadbe3c07b1e9d0358d783fea89b75f2d8b8 Mon Sep 17 00:00:00 2001 From: Shiva Chen Date: Thu, 24 May 2018 06:21:23 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333158 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 3 ++- .../RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp | 2 ++ lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h | 3 +++ .../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 11 ++++++++- test/MC/RISCV/linker-relaxation.s | 26 ++++++++++++++++++++++ 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 test/MC/RISCV/linker-relaxation.s diff --git a/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index 5ac3273022f..a0ae4bc4df7 100644 --- a/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -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) diff --git a/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp index 57b52aa7add..9b88614aa69 100644 --- a/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ b/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -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; } } diff --git a/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h index 7d9f8fc9b94..6a1224be774 100644 --- a/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h +++ b/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h @@ -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, diff --git a/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 3b0e461842c..63b005cc403 100644 --- a/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -186,7 +186,7 @@ RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo, unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &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; } diff --git a/test/MC/RISCV/linker-relaxation.s b/test/MC/RISCV/linker-relaxation.s new file mode 100644 index 00000000000..92cbe39c049 --- /dev/null +++ b/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 -- 2.11.0