mirror of
https://github.com/intel/llvm.git
synced 2026-01-15 12:25:46 +08:00
[BOLT][RISCV] Implement R_RISCV_ADD32/SUB32
Thispatch implements the R_RISCV_ADD32 and R_RISCV_SUB32 relocations for RISC-V. Reviewed By: rafauler Differential Revision: https://reviews.llvm.org/D146554
This commit is contained in:
@@ -103,6 +103,8 @@ static bool isSupportedRISCV(uint64_t Type) {
|
||||
case ELF::R_RISCV_PCREL_LO12_I:
|
||||
case ELF::R_RISCV_RVC_JUMP:
|
||||
case ELF::R_RISCV_RVC_BRANCH:
|
||||
case ELF::R_RISCV_ADD32:
|
||||
case ELF::R_RISCV_SUB32:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -196,6 +198,8 @@ static size_t getSizeForTypeRISCV(uint64_t Type) {
|
||||
case ELF::R_RISCV_32_PCREL:
|
||||
case ELF::R_RISCV_CALL:
|
||||
case ELF::R_RISCV_CALL_PLT:
|
||||
case ELF::R_RISCV_ADD32:
|
||||
case ELF::R_RISCV_SUB32:
|
||||
return 4;
|
||||
case ELF::R_RISCV_GOT_HI20:
|
||||
// See extractValueRISCV for why this is necessary.
|
||||
@@ -509,6 +513,9 @@ static uint64_t extractValueRISCV(uint64_t Type, uint64_t Contents,
|
||||
return SignExtend64<11>(Contents >> 2);
|
||||
case ELF::R_RISCV_RVC_BRANCH:
|
||||
return SignExtend64<8>(((Contents >> 2) & 0x1f) | ((Contents >> 5) & 0xe0));
|
||||
case ELF::R_RISCV_ADD32:
|
||||
case ELF::R_RISCV_SUB32:
|
||||
return Contents;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,6 +675,9 @@ static bool isPCRelativeRISCV(uint64_t Type) {
|
||||
switch (Type) {
|
||||
default:
|
||||
llvm_unreachable("Unknown relocation type");
|
||||
case ELF::R_RISCV_ADD32:
|
||||
case ELF::R_RISCV_SUB32:
|
||||
return false;
|
||||
case ELF::R_RISCV_JAL:
|
||||
case ELF::R_RISCV_CALL:
|
||||
case ELF::R_RISCV_CALL_PLT:
|
||||
@@ -858,7 +868,16 @@ const MCExpr *Relocation::createExpr(MCStreamer *Streamer,
|
||||
}
|
||||
|
||||
MCBinaryExpr::Opcode Relocation::getComposeOpcodeFor(uint64_t Type) {
|
||||
llvm_unreachable("not implemented");
|
||||
assert(Arch == Triple::riscv64 && "only implemented for RISC-V");
|
||||
|
||||
switch (Type) {
|
||||
default:
|
||||
llvm_unreachable("not implemented");
|
||||
case ELF::R_RISCV_ADD32:
|
||||
return MCBinaryExpr::Add;
|
||||
case ELF::R_RISCV_SUB32:
|
||||
return MCBinaryExpr::Sub;
|
||||
}
|
||||
}
|
||||
|
||||
#define ELF_RELOC(name, value) #name,
|
||||
|
||||
@@ -2985,7 +2985,9 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
|
||||
};
|
||||
|
||||
if ((ReferencedSection && refersToReorderedSection(ReferencedSection)) ||
|
||||
(opts::ForceToDataRelocations && checkMaxDataRelocations()))
|
||||
(opts::ForceToDataRelocations && checkMaxDataRelocations()) ||
|
||||
// RISC-V has ADD/SUB data-to-data relocations
|
||||
BC->isRISCV())
|
||||
ForceRelocation = true;
|
||||
|
||||
if (IsFromCode) {
|
||||
|
||||
28
bolt/test/RISCV/reloc-jt.s
Normal file
28
bolt/test/RISCV/reloc-jt.s
Normal file
@@ -0,0 +1,28 @@
|
||||
/// NOTE: assign section addresses explicitly to make the symbol difference
|
||||
/// calculation below less fragile.
|
||||
// RUN: %clang %cflags -Wl,--section-start=.text=0x1000,--section-start=.data=0x2000 -o %t %s
|
||||
// RUN: llvm-bolt -o %t.bolt %t
|
||||
// RUN: llvm-readelf -x .data %t.bolt | FileCheck %s
|
||||
|
||||
.text
|
||||
|
||||
.globl _start
|
||||
.p2align 1
|
||||
_start:
|
||||
.LBB0_0:
|
||||
auipc a1, %pcrel_hi(.LJTI0_0)
|
||||
addi a1, a1, %pcrel_lo(.LBB0_0)
|
||||
lw a0, (a1)
|
||||
add a0, a0, a1
|
||||
jr a0
|
||||
.LBB0_1:
|
||||
ret
|
||||
.size _start, .-_start
|
||||
|
||||
.data
|
||||
/// .LJTI0_0 = 0x2000
|
||||
/// .LBB0_1 = 0x40000e
|
||||
// CHECK: Hex dump of section '.data':
|
||||
// CHECK-NEXT: 0x00002000 0ee03f00
|
||||
.LJTI0_0:
|
||||
.word .LBB0_1 - .LJTI0_0
|
||||
23
bolt/test/RISCV/reloc-label-diff.s
Normal file
23
bolt/test/RISCV/reloc-label-diff.s
Normal file
@@ -0,0 +1,23 @@
|
||||
// RUN: %clang %cflags -o %t %s
|
||||
// RUN: llvm-bolt -o %t.bolt %t
|
||||
// RUN: llvm-readelf -x .data %t.bolt | FileCheck %s
|
||||
|
||||
.text
|
||||
.option norvc
|
||||
.globl _start
|
||||
.p2align 1
|
||||
_start:
|
||||
// Force BOLT into relocation mode
|
||||
.reloc 0, R_RISCV_NONE
|
||||
// BOLT removes this nop so the label difference is initially 8 but should be
|
||||
// 4 after BOLT processes it.
|
||||
nop
|
||||
beq x0, x0, _test_end
|
||||
_test_end:
|
||||
ret
|
||||
.size _start, .-_start
|
||||
|
||||
.data
|
||||
// CHECK: Hex dump of section '.data':
|
||||
// CHECK: 0x{{.*}} 04000000
|
||||
.word _test_end - _start
|
||||
Reference in New Issue
Block a user