Index: lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -73,7 +73,9 @@ { "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_call", 0, 32, 0 }, + { "fixup_riscv_relax", 0, 32, 0 } }; if (Kind < FirstTargetFixupKind) Index: lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -78,6 +78,8 @@ 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; } } Index: lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h +++ lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h @@ -50,6 +50,9 @@ // 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, Index: lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -185,7 +185,7 @@ 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()); @@ -253,6 +253,15 @@ 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; } Index: test/MC/RISCV/function-call.s =================================================================== --- test/MC/RISCV/function-call.s +++ test/MC/RISCV/function-call.s @@ -11,12 +11,12 @@ # RELOC: R_RISCV_CALL foo 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: foo, kind: +# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_call call bar # RELOC: R_RISCV_CALL bar 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: bar, kind: +# FIXUP: fixup A - offset: 0, value: bar, kind: fixup_riscv_call # Ensure that calls to functions whose names coincide with register names work. @@ -24,16 +24,16 @@ # RELOC: R_RISCV_CALL zero 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: zero, kind: +# FIXUP: fixup A - offset: 0, value: zero, kind: fixup_riscv_call call f1 # RELOC: R_RISCV_CALL f1 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: f1, kind: +# FIXUP: fixup A - offset: 0, value: f1, kind: fixup_riscv_call call ra # RELOC: R_RISCV_CALL ra 0x0 # INSTR: auipc ra, 0 # INSTR: jalr ra -# FIXUP: fixup A - offset: 0, value: ra, kind: +# FIXUP: fixup A - offset: 0, value: ra, kind: fixup_riscv_call Index: test/MC/RISCV/linker-relaxation.s =================================================================== --- /dev/null +++ test/MC/RISCV/linker-relaxation.s @@ -0,0 +1,18 @@ +# 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=RELOC %s +# RUN: llvm-mc -triple riscv32 -mattr=+relax < %s -show-encoding \ +# RUN: | FileCheck -check-prefix=RELAX-FIXUP %s + +.long foo + +.L1: +call foo +# RELOC: R_RISCV_CALL foo 0x0 +# 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_call +# RELAX-FIXUP: fixup B - offset: 0, value: foo, kind: fixup_riscv_relax +beq s1, s1, .L1 +# RELAX-RELOC: R_RISCV_BRANCH .L1 0x0