forked from OSchip/llvm-project
[jitlink] add R_RISCV_BRANCH to jitlink
This patch supported the R_RISCV_BRANCH relocation. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D116573
This commit is contained in:
parent
f21473752b
commit
0c6f762622
|
@ -37,6 +37,13 @@ enum EdgeKind_riscv : Edge::Kind {
|
|||
///
|
||||
R_RISCV_64,
|
||||
|
||||
/// Low 12 bits of PC-relative branch pointer value relocation
|
||||
///
|
||||
/// Fixup expression:
|
||||
/// Fixup <- (Target - Fixup + Addend) & 0xFFF
|
||||
///
|
||||
R_RISCV_BRANCH,
|
||||
|
||||
/// High 20 bits of 32-bit pointer value relocation
|
||||
///
|
||||
/// Fixup expression
|
||||
|
|
|
@ -162,6 +162,17 @@ static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) {
|
|||
return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> Low;
|
||||
}
|
||||
|
||||
inline Error checkAlignment(llvm::orc::ExecutorAddr loc, uint64_t v, int n,
|
||||
const Edge &E) {
|
||||
if (v & (n - 1))
|
||||
return make_error<JITLinkError>("0x" + llvm::utohexstr(loc.getValue()) +
|
||||
" improper alignment for relocation " +
|
||||
formatv("{0:d}", E.getKind()) + ": 0x" +
|
||||
llvm::utohexstr(v) + " is not aligned to " +
|
||||
Twine(n) + " bytes");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
static inline bool isInRangeForImmS32(int64_t Value) {
|
||||
return (Value >= std::numeric_limits<int32_t>::min() &&
|
||||
Value <= std::numeric_limits<int32_t>::max());
|
||||
|
@ -194,6 +205,21 @@ private:
|
|||
*(little64_t *)FixupPtr = static_cast<uint64_t>(Value);
|
||||
break;
|
||||
}
|
||||
case R_RISCV_BRANCH: {
|
||||
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
|
||||
Error AlignmentIssue = checkAlignment(FixupAddress, Value, 2, E);
|
||||
if (AlignmentIssue) {
|
||||
return AlignmentIssue;
|
||||
}
|
||||
int64_t Lo = Value & 0xFFF;
|
||||
uint32_t Imm31_25 = extractBits(Lo, 5, 6) << 25 | extractBits(Lo, 12, 1)
|
||||
<< 31;
|
||||
uint32_t Imm11_7 = extractBits(Lo, 1, 4) << 8 | extractBits(Lo, 11, 1)
|
||||
<< 7;
|
||||
uint32_t RawInstr = *(little32_t *)FixupPtr;
|
||||
*(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
|
||||
break;
|
||||
}
|
||||
case R_RISCV_HI20: {
|
||||
int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
|
||||
int64_t Hi = Value + 0x800;
|
||||
|
@ -284,6 +310,8 @@ private:
|
|||
return EdgeKind_riscv::R_RISCV_32;
|
||||
case ELF::R_RISCV_64:
|
||||
return EdgeKind_riscv::R_RISCV_64;
|
||||
case ELF::R_RISCV_BRANCH:
|
||||
return EdgeKind_riscv::R_RISCV_BRANCH;
|
||||
case ELF::R_RISCV_HI20:
|
||||
return EdgeKind_riscv::R_RISCV_HI20;
|
||||
case ELF::R_RISCV_LO12_I:
|
||||
|
|
|
@ -24,6 +24,8 @@ const char *getEdgeKindName(Edge::Kind K) {
|
|||
return "R_RISCV_32";
|
||||
case R_RISCV_64:
|
||||
return "R_RISCV_64";
|
||||
case R_RISCV_BRANCH:
|
||||
return "R_RISCV_BRANCH";
|
||||
case R_RISCV_HI20:
|
||||
return "R_RISCV_HI20";
|
||||
case R_RISCV_LO12_I:
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# RUN: rm -rf %t && mkdir -p %t
|
||||
# RUN: llvm-mc -triple=riscv64 -filetype=obj \
|
||||
# RUN: -o %t/elf_riscv64_branch.o %s
|
||||
# RUN: llvm-mc -triple=riscv32 -filetype=obj \
|
||||
# RUN: -o %t/elf_riscv32_branch.o %s
|
||||
# RUN: llvm-jitlink -noexec \
|
||||
# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
|
||||
# RUN: -define-abs external_func=0xfe \
|
||||
# RUN: -check %s %t/elf_riscv64_branch.o
|
||||
# RUN: llvm-jitlink -noexec \
|
||||
# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
|
||||
# RUN: -define-abs external_func=0xfe \
|
||||
# RUN: -check %s %t/elf_riscv32_branch.o
|
||||
#
|
||||
|
||||
.text
|
||||
.file "testcase.c"
|
||||
|
||||
# Empty main entry point.
|
||||
.globl main
|
||||
.p2align 1
|
||||
.type main,@function
|
||||
main:
|
||||
ret
|
||||
|
||||
.size main, .-main
|
||||
|
||||
# Test R_RISCV_BRANCH
|
||||
|
||||
# jitlink-check: decode_operand(test_branch, 2)[11:0] = (external_func - test_branch)[11:0]
|
||||
.globl test_branch
|
||||
.p2align 1
|
||||
.type test_branch,@function
|
||||
test_branch:
|
||||
bge a0, a1, external_func
|
||||
|
||||
.size test_branch, .-test_branch
|
Loading…
Reference in New Issue