[llvm] 0c6f762 - [jitlink] add R_RISCV_BRANCH to jitlink

via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 14 11:37:07 PST 2022


Author: fourdim
Date: 2022-01-15T03:36:58+08:00
New Revision: 0c6f76262277705c0203bf7c01a3694f780538e1

URL: https://github.com/llvm/llvm-project/commit/0c6f76262277705c0203bf7c01a3694f780538e1
DIFF: https://github.com/llvm/llvm-project/commit/0c6f76262277705c0203bf7c01a3694f780538e1.diff

LOG: [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

Added: 
    llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s

Modified: 
    llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
    llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
    llvm/lib/ExecutionEngine/JITLink/riscv.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h b/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
index b8d08d88c1c91..e948fce9cc9da 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
@@ -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

diff  --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
index ff538dac909b5..34a00debc9272 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
@@ -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 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
       *(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 @@ class ELFLinkGraphBuilder_riscv : public ELFLinkGraphBuilder<ELFT> {
       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:

diff  --git a/llvm/lib/ExecutionEngine/JITLink/riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/riscv.cpp
index 6b73ff95a3b08..236b399392fe5 100644
--- a/llvm/lib/ExecutionEngine/JITLink/riscv.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/riscv.cpp
@@ -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:

diff  --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s
new file mode 100644
index 0000000000000..5bafcc4d477cd
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s
@@ -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, at 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, at function
+test_branch:
+  bge	a0, a1, external_func
+
+  .size test_branch, .-test_branch


        


More information about the llvm-commits mailing list