diff --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp index 45da2addbb98f..886fa314b2b73 100644 --- a/bolt/lib/Core/Relocation.cpp +++ b/bolt/lib/Core/Relocation.cpp @@ -101,6 +101,7 @@ static bool isSupportedRISCV(uint64_t Type) { case ELF::R_RISCV_GOT_HI20: case ELF::R_RISCV_PCREL_HI20: case ELF::R_RISCV_PCREL_LO12_I: + case ELF::R_RISCV_PCREL_LO12_S: case ELF::R_RISCV_RVC_JUMP: case ELF::R_RISCV_RVC_BRANCH: case ELF::R_RISCV_ADD32: @@ -195,6 +196,7 @@ static size_t getSizeForTypeRISCV(uint64_t Type) { case ELF::R_RISCV_BRANCH: case ELF::R_RISCV_PCREL_HI20: case ELF::R_RISCV_PCREL_LO12_I: + case ELF::R_RISCV_PCREL_LO12_S: case ELF::R_RISCV_32_PCREL: case ELF::R_RISCV_CALL: case ELF::R_RISCV_CALL_PLT: @@ -480,6 +482,10 @@ static uint64_t extractIImmRISCV(uint32_t Contents) { return SignExtend64<12>(Contents >> 20); } +static uint64_t extractSImmRISCV(uint32_t Contents) { + return SignExtend64<12>(((Contents >> 7) & 0x1f) | ((Contents >> 25) << 5)); +} + static uint64_t extractJImmRISCV(uint32_t Contents) { return SignExtend64<21>( (((Contents >> 21) & 0x3ff) << 1) | (((Contents >> 20) & 0x1) << 11) | @@ -516,6 +522,8 @@ static uint64_t extractValueRISCV(uint64_t Type, uint64_t Contents, return extractUImmRISCV(Contents); case ELF::R_RISCV_PCREL_LO12_I: return extractIImmRISCV(Contents); + case ELF::R_RISCV_PCREL_LO12_S: + return extractSImmRISCV(Contents); case ELF::R_RISCV_RVC_JUMP: return SignExtend64<11>(Contents >> 2); case ELF::R_RISCV_RVC_BRANCH: @@ -692,6 +700,7 @@ static bool isPCRelativeRISCV(uint64_t Type) { case ELF::R_RISCV_GOT_HI20: case ELF::R_RISCV_PCREL_HI20: case ELF::R_RISCV_PCREL_LO12_I: + case ELF::R_RISCV_PCREL_LO12_S: case ELF::R_RISCV_RVC_JUMP: case ELF::R_RISCV_RVC_BRANCH: case ELF::R_RISCV_32_PCREL: diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp index badc1bde80b5a..d13eb22f95826 100644 --- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp +++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp @@ -42,6 +42,7 @@ class RISCVMCPlusBuilder : public MCPlusBuilder { case ELF::R_RISCV_GOT_HI20: case ELF::R_RISCV_PCREL_HI20: case ELF::R_RISCV_PCREL_LO12_I: + case ELF::R_RISCV_PCREL_LO12_S: return true; default: llvm_unreachable("Unexpected RISCV relocation type in code"); @@ -352,6 +353,7 @@ class RISCVMCPlusBuilder : public MCPlusBuilder { case ELF::R_RISCV_PCREL_HI20: return RISCVMCExpr::create(Expr, RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx); case ELF::R_RISCV_PCREL_LO12_I: + case ELF::R_RISCV_PCREL_LO12_S: return RISCVMCExpr::create(Expr, RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); case ELF::R_RISCV_CALL: return RISCVMCExpr::create(Expr, RISCVMCExpr::VK_RISCV_CALL, Ctx); diff --git a/bolt/test/RISCV/reloc-pcrel.s b/bolt/test/RISCV/reloc-pcrel.s index 2d5a349d03e78..36b132727291e 100644 --- a/bolt/test/RISCV/reloc-pcrel.s +++ b/bolt/test/RISCV/reloc-pcrel.s @@ -18,5 +18,9 @@ _start: // CHECK: auipc t0, %pcrel_hi(d) // CHECK-NEXT: ld t0, %pcrel_lo(.Ltmp0)(t0) ld t0, d +// CHECK: .Ltmp1 +// CHECK: auipc t1, %pcrel_hi(d) +// CHECK-NEXT: sd t0, %pcrel_lo(.Ltmp1)(t1) + sd t0, d, t1 ret .size _start, .-_start