forked from OSchip/llvm-project
[JITLink][RISCV] fix the extractBits behavior and add R_RISCV_JAL relocation.
This patch supports the R_RISCV_JAL relocation. Moreover, it will fix the extractBits function's behavior as it extracts Size + 1 bits. In the test ELF_jal.s: Before: ``` Hi: 4294836480 extractBits(Hi, 12, 8): 480 ``` After: ``` Hi: 4294836480 extractBits(Hi, 12, 8): 224 ``` Reviewed By: StephenFan Differential Revision: https://reviews.llvm.org/D117975
This commit is contained in:
parent
b45d0b3e8e
commit
1ece3eeeb7
|
@ -44,6 +44,13 @@ enum EdgeKind_riscv : Edge::Kind {
|
|||
///
|
||||
R_RISCV_BRANCH,
|
||||
|
||||
/// High 20 bits of PC-relative jump pointer value relocation
|
||||
///
|
||||
/// Fixup expression:
|
||||
/// Fixup <- Target - Fixup + Addend
|
||||
///
|
||||
R_RISCV_JAL,
|
||||
|
||||
/// High 20 bits of 32-bit pointer value relocation
|
||||
///
|
||||
/// Fixup expression
|
||||
|
|
|
@ -220,6 +220,20 @@ private:
|
|||
*(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
|
||||
break;
|
||||
}
|
||||
case R_RISCV_JAL: {
|
||||
int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress;
|
||||
Error AlignmentIssue = checkAlignment(FixupAddress, Value, 2, E);
|
||||
if (AlignmentIssue) {
|
||||
return AlignmentIssue;
|
||||
}
|
||||
uint32_t Imm20 = extractBits(Value, 20, 1) << 31;
|
||||
uint32_t Imm10_1 = extractBits(Value, 1, 10) << 21;
|
||||
uint32_t Imm11 = extractBits(Value, 11, 1) << 20;
|
||||
uint32_t Imm19_12 = extractBits(Value, 12, 8) << 12;
|
||||
uint32_t RawInstr = *(little32_t *)FixupPtr;
|
||||
*(little32_t *)FixupPtr = RawInstr | Imm20 | Imm10_1 | Imm11 | Imm19_12;
|
||||
break;
|
||||
}
|
||||
case R_RISCV_HI20: {
|
||||
int64_t Value = (E.getTarget().getAddress() + E.getAddend()).getValue();
|
||||
int64_t Hi = Value + 0x800;
|
||||
|
@ -409,6 +423,8 @@ private:
|
|||
return EdgeKind_riscv::R_RISCV_64;
|
||||
case ELF::R_RISCV_BRANCH:
|
||||
return EdgeKind_riscv::R_RISCV_BRANCH;
|
||||
case ELF::R_RISCV_JAL:
|
||||
return EdgeKind_riscv::R_RISCV_JAL;
|
||||
case ELF::R_RISCV_HI20:
|
||||
return EdgeKind_riscv::R_RISCV_HI20;
|
||||
case ELF::R_RISCV_LO12_I:
|
||||
|
|
|
@ -26,6 +26,8 @@ const char *getEdgeKindName(Edge::Kind K) {
|
|||
return "R_RISCV_64";
|
||||
case R_RISCV_BRANCH:
|
||||
return "R_RISCV_BRANCH";
|
||||
case R_RISCV_JAL:
|
||||
return "R_RISCV_JAL";
|
||||
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_jal.o %s
|
||||
# RUN: llvm-mc -triple=riscv32 -filetype=obj \
|
||||
# RUN: -o %t/elf_riscv32_jal.o %s
|
||||
# RUN: llvm-jitlink -noexec \
|
||||
# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \
|
||||
# RUN: -abs external_func=0x1fe000fe \
|
||||
# RUN: -check %s %t/elf_riscv64_jal.o
|
||||
# RUN: llvm-jitlink -noexec \
|
||||
# RUN: -slab-allocate 100Kb -slab-address 0x1ff00000 -slab-page-size 4096 \
|
||||
# RUN: -abs external_func=0x1fe000fe \
|
||||
# RUN: -check %s %t/elf_riscv32_jal.o
|
||||
#
|
||||
|
||||
.text
|
||||
.file "testcase.c"
|
||||
|
||||
# Empty main entry point.
|
||||
.globl main
|
||||
.p2align 1
|
||||
.type main,@function
|
||||
main:
|
||||
ret
|
||||
|
||||
.size main, .-main
|
||||
|
||||
# Test R_RISCV_JAL
|
||||
|
||||
# jitlink-check: decode_operand(test_jal, 1)[31:12] = (external_func - test_jal)[31:12]
|
||||
.globl test_jal
|
||||
.p2align 1
|
||||
.type test_jal,@function
|
||||
test_jal:
|
||||
jal x0, external_func
|
||||
|
||||
.size test_jal, .-test_jal
|
Loading…
Reference in New Issue