[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:12:09 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/2] [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/2] 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,
More information about the llvm-branch-commits
mailing list