[llvm-branch-commits] [llvm] [JITLink][LoongArch] Add label addition and subtraction relocations (PR #122262)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jan 9 18:24:58 PST 2025


https://github.com/zhaoqi5 updated https://github.com/llvm/llvm-project/pull/122262

>From 4398bd99d87c58307e55798a3f6dde372b4d0cb6 Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Fri, 27 Dec 2024 15:39:57 +0800
Subject: [PATCH 1/3] [JITLink][LoongArch] Add label addition and subtraction
 relocations

---
 .../llvm/ExecutionEngine/JITLink/loongarch.h  | 180 ++++++++++++++++++
 .../ExecutionEngine/JITLink/ELF_loongarch.cpp |  24 +++
 .../lib/ExecutionEngine/JITLink/loongarch.cpp |  12 ++
 .../JITLink/LoongArch/ELF_reloc_addsub.s      |  53 ++++++
 4 files changed, 269 insertions(+)
 create mode 100644 llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s

diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
index d6025edf7d110d..1d763e1255fc21 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
@@ -14,8 +14,10 @@
 #define LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H
 
 #include "TableManager.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
 #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
+#include "llvm/Support/LEB128.h"
 
 namespace llvm {
 namespace jitlink {
@@ -226,6 +228,90 @@ enum EdgeKind_loongarch : Edge::Kind {
   ///
   Call36PCRel,
 
+  /// low 6 bits label addition
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (*{1}Fixup + (Target + Addend) & 0x3f) : int8
+  ///
+  Add6,
+
+  /// 8 bits label addition
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (Target + *{1}Fixup + Addend) : int8
+  ///
+  Add8,
+
+  /// 16 bits label addition
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (Target + *{2}Fixup + Addend) : int16
+  ///
+  Add16,
+
+  /// 32 bits label addition
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (Target + *{4}Fixup + Addend) : int32
+  ///
+  Add32,
+
+  /// 64 bits label addition
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (Target + *{8}Fixup + Addend) : int64
+  ///
+  Add64,
+
+  /// ULEB128 bits label addition
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (Target + *{16}Fixup + Addend) : uleb128
+  ///
+  AddUleb128,
+
+  /// low 6 bits label subtraction
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (*{1}Fixup - (Target + Addend) & 0x3f) : int8
+  ///
+  Sub6,
+
+  /// 8 bits label subtraction
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (*{1}Fixup - Target - Addend) : int8
+  ///
+  Sub8,
+
+  /// 16 bits label subtraction
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (*{2}Fixup - Target - Addend) : int16
+  ///
+  Sub16,
+
+  /// 32 bits label subtraction
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (*{4}Fixup - Target - Addend) : int32
+  ///
+  Sub32,
+
+  /// 64 bits label subtraction
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (*{8}Fixup - Target - Addend) : int64
+  ///
+  Sub64,
+
+  /// ULEB128 bits label subtraction
+  ///
+  /// Fixup expression:
+  ///   Fixup <- (*{16}Fixup - Target - Addend) : uleb128
+  ///
+  SubUleb128,
+
   /// Alignment requirement used by linker relaxation.
   ///
   /// Linker relaxation will use this to ensure all code sequences are properly
@@ -369,6 +455,100 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E) {
     *(little32_t *)(FixupPtr + 4) = Jirl | Lo16;
     break;
   }
+  case Add6: {
+    int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
+    Value += ((TargetAddress + Addend) & 0x3f);
+    *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);
+    break;
+  }
+  case Add8: {
+    int64_t Value =
+        TargetAddress + *(reinterpret_cast<const int8_t *>(FixupPtr)) + Addend;
+    *FixupPtr = static_cast<int8_t>(Value);
+    break;
+  }
+  case Add16: {
+    int64_t Value =
+        TargetAddress + support::endian::read16le(FixupPtr) + Addend;
+    *(little16_t *)FixupPtr = static_cast<int16_t>(Value);
+    break;
+  }
+  case Add32: {
+    int64_t Value =
+        TargetAddress + support::endian::read32le(FixupPtr) + Addend;
+    *(little32_t *)FixupPtr = static_cast<int32_t>(Value);
+    break;
+  }
+  case Add64: {
+    int64_t Value =
+        TargetAddress + support::endian::read64le(FixupPtr) + Addend;
+    *(little64_t *)FixupPtr = static_cast<int64_t>(Value);
+    break;
+  }
+  case AddUleb128: {
+    const uint32_t Maxcount = 1 + 64 / 7;
+    uint32_t Count;
+    const char *Error = nullptr;
+    uint64_t Orig = decodeULEB128((reinterpret_cast<const uint8_t *>(FixupPtr)),
+                                  &Count, nullptr, &Error);
+
+    if (Count > Maxcount || (Count == Maxcount && Error))
+      return make_error<JITLinkError>(
+          "0x" + llvm::utohexstr(orc::ExecutorAddr(FixupAddress).getValue()) +
+          ": extra space for uleb128");
+
+    uint64_t Mask = Count < Maxcount ? (1ULL << 7 * Count) - 1 : -1ULL;
+    encodeULEB128((Orig + TargetAddress + Addend) & Mask,
+                  (reinterpret_cast<uint8_t *>(FixupPtr)), Count);
+    break;
+  }
+  case Sub6: {
+    int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
+    Value -= ((TargetAddress + Addend) & 0x3f);
+    *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);
+    break;
+  }
+  case Sub8: {
+    int64_t Value =
+        *(reinterpret_cast<const int8_t *>(FixupPtr)) - TargetAddress - Addend;
+    *FixupPtr = static_cast<int8_t>(Value);
+    break;
+  }
+  case Sub16: {
+    int64_t Value =
+        support::endian::read16le(FixupPtr) - TargetAddress - Addend;
+    *(little16_t *)FixupPtr = static_cast<int16_t>(Value);
+    break;
+  }
+  case Sub32: {
+    int64_t Value =
+        support::endian::read32le(FixupPtr) - TargetAddress - Addend;
+    *(little32_t *)FixupPtr = static_cast<int32_t>(Value);
+    break;
+  }
+  case Sub64: {
+    int64_t Value =
+        support::endian::read64le(FixupPtr) - TargetAddress - Addend;
+    *(little64_t *)FixupPtr = static_cast<int64_t>(Value);
+    break;
+  }
+  case SubUleb128: {
+    const uint32_t Maxcount = 1 + 64 / 7;
+    uint32_t Count;
+    const char *Error = nullptr;
+    uint64_t Orig = decodeULEB128((reinterpret_cast<const uint8_t *>(FixupPtr)),
+                                  &Count, nullptr, &Error);
+
+    if (Count > Maxcount || (Count == Maxcount && Error))
+      return make_error<JITLinkError>(
+          "0x" + llvm::utohexstr(orc::ExecutorAddr(FixupAddress).getValue()) +
+          ": extra space for uleb128");
+
+    uint64_t Mask = Count < Maxcount ? (1ULL << 7 * Count) - 1 : -1ULL;
+    encodeULEB128((Orig - TargetAddress - Addend) & Mask,
+                  (reinterpret_cast<uint8_t *>(FixupPtr)), Count);
+    break;
+  }
   case AlignRelaxable:
     // Ignore when the relaxation pass did not run
     break;
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
index 3f0a7b645e83fc..f23fb346c55f90 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
@@ -306,6 +306,30 @@ class ELFLinkGraphBuilder_loongarch : public ELFLinkGraphBuilder<ELFT> {
       return RequestGOTAndTransformToPageOffset12;
     case ELF::R_LARCH_CALL36:
       return Call36PCRel;
+    case ELF::R_LARCH_ADD6:
+      return Add6;
+    case ELF::R_LARCH_ADD8:
+      return Add8;
+    case ELF::R_LARCH_ADD16:
+      return Add16;
+    case ELF::R_LARCH_ADD32:
+      return Add32;
+    case ELF::R_LARCH_ADD64:
+      return Add64;
+    case ELF::R_LARCH_ADD_ULEB128:
+      return AddUleb128;
+    case ELF::R_LARCH_SUB6:
+      return Sub6;
+    case ELF::R_LARCH_SUB8:
+      return Sub8;
+    case ELF::R_LARCH_SUB16:
+      return Sub16;
+    case ELF::R_LARCH_SUB32:
+      return Sub32;
+    case ELF::R_LARCH_SUB64:
+      return Sub64;
+    case ELF::R_LARCH_SUB_ULEB128:
+      return SubUleb128;
     case ELF::R_LARCH_ALIGN:
       return AlignRelaxable;
     }
diff --git a/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
index a5579b074de7cf..55389adb31b60e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
@@ -52,6 +52,18 @@ const char *getEdgeKindName(Edge::Kind K) {
     KIND_NAME_CASE(RequestGOTAndTransformToPage20)
     KIND_NAME_CASE(RequestGOTAndTransformToPageOffset12)
     KIND_NAME_CASE(Call36PCRel)
+    KIND_NAME_CASE(Add6)
+    KIND_NAME_CASE(Add8)
+    KIND_NAME_CASE(Add16)
+    KIND_NAME_CASE(Add32)
+    KIND_NAME_CASE(Add64)
+    KIND_NAME_CASE(AddUleb128)
+    KIND_NAME_CASE(Sub6)
+    KIND_NAME_CASE(Sub8)
+    KIND_NAME_CASE(Sub16)
+    KIND_NAME_CASE(Sub32)
+    KIND_NAME_CASE(Sub64)
+    KIND_NAME_CASE(SubUleb128)
     KIND_NAME_CASE(AlignRelaxable)
   default:
     return getGenericEdgeKindName(K);
diff --git a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s
new file mode 100644
index 00000000000000..86e3008ef40943
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_reloc_addsub.s
@@ -0,0 +1,53 @@
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc --triple=loongarch32 -mattr=+relax --filetype=obj \
+# RUN:     -o %t/la32_reloc_addsub.o %s
+# RUN: llvm-jitlink --noexec --check %s %t/la32_reloc_addsub.o \
+# RUN:     --slab-allocate=1Mb --slab-address=0x1000 --slab-page-size=0x4000
+# RUN: llvm-mc --triple=loongarch64 -mattr=+relax --filetype=obj \
+# RUN:     -o %t/la64_reloc_addsub.o %s
+# RUN: llvm-jitlink --noexec --check %s %t/la64_reloc_addsub.o \
+# RUN:     --slab-allocate=1Mb --slab-address=0x1000 --slab-page-size=0x4000
+
+# jitlink-check: *{8}(named_data) = 0x8
+# jitlink-check: *{4}(named_data+8) = 0x8
+# jitlink-check: *{2}(named_data+12) = 0x8
+# jitlink-check: *{1}(named_data+14) = 0x8
+# jitlink-check: *{1}(named_data+15) = 0x10
+
+# jitlink-check: *{1}(leb_data) = 0x8
+# jitlink-check: *{2}(leb_data+1) = 0x180
+# jitlink-check: *{8}(leb_data+3) = 0xfffffffffffffff8
+# jitlink-check: *{2}(leb_data+11) = 0x1ff
+# jitlink-check: *{1}(leb_data+13) = 0x7f
+# jitlink-check: *{2}(leb_data+14) = 0x181
+
+.section .alloc_data,"ax", at progbits
+.global main
+main:
+.L0:
+# Referencing named_data symbol to avoid the following relocations be
+# skipped. This macro instruction will be expand to two instructions
+# (pcalau12i + ld.w/d).
+  la.global $t0, named_data
+.L1:
+
+named_data:
+.reloc named_data+15, R_LARCH_ADD6, .L1
+.reloc named_data+15, R_LARCH_SUB6, .L0
+.dword .L1 - .L0
+.word .L1 - .L0
+.half .L1 - .L0
+.byte .L1 - .L0
+.byte 0x8
+
+.size named_data, 16
+
+leb_data:
+.uleb128 .L1 - .L0
+.uleb128 .L1 - .L0 + 120
+.uleb128 -(.L1 - .L0)
+.uleb128 leb_end - leb_data + 111
+.uleb128 leb_end - leb_data + 113
+leb_end:
+
+.size leb_data, 16

>From ea920733f0b53436cc83d9dc7fb1baa3fa144d72 Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Fri, 10 Jan 2025 10:08:14 +0800
Subject: [PATCH 2/3] update notes

---
 llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
index 1d763e1255fc21..6dbb9242134725 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
@@ -238,35 +238,35 @@ enum EdgeKind_loongarch : Edge::Kind {
   /// 8 bits label addition
   ///
   /// Fixup expression:
-  ///   Fixup <- (Target + *{1}Fixup + Addend) : int8
+  ///   Fixup <- (*{1}Fixup + Target + Addend) : int8
   ///
   Add8,
 
   /// 16 bits label addition
   ///
   /// Fixup expression:
-  ///   Fixup <- (Target + *{2}Fixup + Addend) : int16
+  ///   Fixup <- (*{2}Fixup + Target + Addend) : int16
   ///
   Add16,
 
   /// 32 bits label addition
   ///
   /// Fixup expression:
-  ///   Fixup <- (Target + *{4}Fixup + Addend) : int32
+  ///   Fixup <- (*{4}Fixup + Target + Addend) : int32
   ///
   Add32,
 
   /// 64 bits label addition
   ///
   /// Fixup expression:
-  ///   Fixup <- (Target + *{8}Fixup + Addend) : int64
+  ///   Fixup <- (*{8}Fixup + Target + Addend) : int64
   ///
   Add64,
 
   /// ULEB128 bits label addition
   ///
   /// Fixup expression:
-  ///   Fixup <- (Target + *{16}Fixup + Addend) : uleb128
+  ///   Fixup <- (*{16}Fixup + Target + Addend) : uleb128
   ///
   AddUleb128,
 

>From d98c5d1b4ca404ab54b893d15c3c39d12a8fba20 Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Fri, 10 Jan 2025 10:21:19 +0800
Subject: [PATCH 3/3] update notes

---
 llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
index 6dbb9242134725..3c664296e9f331 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
@@ -266,7 +266,7 @@ enum EdgeKind_loongarch : Edge::Kind {
   /// ULEB128 bits label addition
   ///
   /// Fixup expression:
-  ///   Fixup <- (*{16}Fixup + Target + Addend) : uleb128
+  ///   Fixup <- (Fixup + Target + Addend) : uleb128
   ///
   AddUleb128,
 
@@ -308,7 +308,7 @@ enum EdgeKind_loongarch : Edge::Kind {
   /// ULEB128 bits label subtraction
   ///
   /// Fixup expression:
-  ///   Fixup <- (*{16}Fixup - Target - Addend) : uleb128
+  ///   Fixup <- (Fixup - Target - Addend) : uleb128
   ///
   SubUleb128,
 



More information about the llvm-branch-commits mailing list