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 <zhaoq...@loongson.cn> Date: Fri, 27 Dec 2024 15:39:57 +0800 Subject: [PATCH] [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",@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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits