*(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;
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:
--- /dev/null
+# 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