[llvm] [JITLink][LoongArch] Support large code model (PR #155566)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 27 00:28:29 PDT 2025
https://github.com/Ami-zhang created https://github.com/llvm/llvm-project/pull/155566
None
>From cd95f7e2348a93dd4844de1479c12e257e0d6edf Mon Sep 17 00:00:00 2001
From: Ami-zhang <zhanglimin at loongson.cn>
Date: Wed, 27 Aug 2025 14:48:24 +0800
Subject: [PATCH] [JITLink][LoongArch] Support large code model
---
.../llvm/ExecutionEngine/JITLink/loongarch.h | 80 +++++++++++++++++++
.../ExecutionEngine/JITLink/ELF_loongarch.cpp | 8 ++
.../lib/ExecutionEngine/JITLink/loongarch.cpp | 4 +
3 files changed, 92 insertions(+)
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
index 04c5a67ac4fe3..c3225d368a45a 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h
@@ -161,6 +161,18 @@ enum EdgeKind_loongarch : Edge::Kind {
///
Page20,
+ /// The signed 20-bit delta from the fixup page to the page containing the
+ /// target for 64-bit addresses.
+ ///
+ /// Fixup expression:
+ /// Fixup <- getLoongArchPageDelta(Target + Addend, FixupAddress,
+ /// Type)[51:32]
+ ///
+ /// Notes:
+ /// For PCALAU12I fixups in large code model.
+ ///
+ Page64Lo20,
+
/// The 12-bit offset of the target within its page.
///
/// Typically used to fix up ADDI/LD_W/LD_D immediates.
@@ -170,6 +182,17 @@ enum EdgeKind_loongarch : Edge::Kind {
///
PageOffset12,
+ /// The 12-bit high part of the 64-bit page delta.
+ ///
+ /// Fixup expression:
+ /// Fixup <- getLoongArchPageDelta(Target + Addend, FixupAddress,
+ /// Type)[63:52]
+ ///
+ /// Notes:
+ /// For large code model instructions.
+ ///
+ Page64Hi12,
+
/// A GOT entry getter/constructor, transformed to Page20 pointing at the GOT
/// entry for the original target.
///
@@ -206,6 +229,16 @@ enum EdgeKind_loongarch : Edge::Kind {
///
RequestGOTAndTransformToPageOffset12,
+ /// A GOT entry getter/constructor, transformed to Page64Lo20 pointing at the
+ /// GOT entry for the original target.
+ ///
+ RequestGOTAndTransformToPage64Lo20,
+
+ /// A GOT entry getter/constructor, transformed to Page64Hi12 pointing at the
+ /// GOT entry for the original target.
+ ///
+ RequestGOTAndTransformToPage64Hi12,
+
/// A 36-bit PC-relative call.
///
/// Represents a PC-relative call to a target within [-128G - 0x20000, +128G
@@ -330,6 +363,29 @@ inline uint32_t extractBits(uint64_t Val, unsigned Hi, unsigned Lo) {
return Hi == 63 ? Val >> Lo : (Val & ((((uint64_t)1 << (Hi + 1)) - 1))) >> Lo;
}
+inline uint64_t getLoongArchPageDelta(uint64_t Target, uint64_t FixupAddr,
+ Edge::Kind Kind) {
+ uint64_t PC;
+ switch (Kind) {
+ case Page64Lo20:
+ PC = FixupAddr - 8;
+ break;
+ case Page64Hi12:
+ PC = FixupAddr - 12;
+ break;
+ default:
+ PC = FixupAddr;
+ break;
+ }
+
+ uint64_t Result = (Target & ~0xfffULL) - (PC & ~0xfffULL);
+ if (Target & 0x800)
+ Result += 0x1000 - 0x1'0000'0000;
+ if (Result & 0x8000'0000)
+ Result += 0x1'0000'0000;
+ return Result;
+}
+
/// Apply fixup expression for edge to block content.
inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E) {
using namespace support;
@@ -456,6 +512,24 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E) {
*(little32_t *)(FixupPtr + 4) = Jirl | Lo16;
break;
}
+ case Page64Lo20: {
+ uint64_t Target = TargetAddress + Addend;
+ uint64_t PageDelta =
+ getLoongArchPageDelta(Target, FixupAddress, Page64Lo20);
+ uint32_t Imm51_32 = extractBits(PageDelta, /*Hi=*/51, /*Lo=*/32) << 5;
+ *(ulittle32_t *)FixupPtr =
+ (*(ulittle32_t *)FixupPtr & 0xfe00001f) | Imm51_32;
+ break;
+ }
+ case Page64Hi12: {
+ uint64_t Target = TargetAddress + Addend;
+ uint64_t PageDelta =
+ getLoongArchPageDelta(Target, FixupAddress, Page64Hi12);
+ uint32_t Imm63_52 = extractBits(PageDelta, /*Hi=*/63, /*Lo=*/52) << 10;
+ *(ulittle32_t *)FixupPtr =
+ (*(ulittle32_t *)FixupPtr & 0xffc003ff) | Imm63_52;
+ break;
+ }
case Add6: {
int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
Value += ((TargetAddress + Addend) & 0x3f);
@@ -631,6 +705,12 @@ class GOTTableManager : public TableManager<GOTTableManager> {
case RequestGOTAndTransformToPageOffset12:
KindToSet = PageOffset12;
break;
+ case RequestGOTAndTransformToPage64Lo20:
+ KindToSet = Page64Lo20;
+ break;
+ case RequestGOTAndTransformToPage64Hi12:
+ KindToSet = Page64Hi12;
+ break;
default:
return false;
}
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
index f23fb346c55f9..715df5c72f19a 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
@@ -306,6 +306,14 @@ class ELFLinkGraphBuilder_loongarch : public ELFLinkGraphBuilder<ELFT> {
return RequestGOTAndTransformToPageOffset12;
case ELF::R_LARCH_CALL36:
return Call36PCRel;
+ case ELF::R_LARCH_PCALA64_LO20:
+ return Page64Lo20;
+ case ELF::R_LARCH_PCALA64_HI12:
+ return Page64Hi12;
+ case ELF::R_LARCH_GOT64_PC_LO20:
+ return RequestGOTAndTransformToPage64Lo20;
+ case ELF::R_LARCH_GOT64_PC_HI12:
+ return RequestGOTAndTransformToPage64Hi12;
case ELF::R_LARCH_ADD6:
return Add6;
case ELF::R_LARCH_ADD8:
diff --git a/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp b/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
index 55389adb31b60..d59df676c3f41 100644
--- a/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/loongarch.cpp
@@ -52,6 +52,10 @@ const char *getEdgeKindName(Edge::Kind K) {
KIND_NAME_CASE(RequestGOTAndTransformToPage20)
KIND_NAME_CASE(RequestGOTAndTransformToPageOffset12)
KIND_NAME_CASE(Call36PCRel)
+ KIND_NAME_CASE(Page64Lo20)
+ KIND_NAME_CASE(Page64Hi12)
+ KIND_NAME_CASE(RequestGOTAndTransformToPage64Lo20)
+ KIND_NAME_CASE(RequestGOTAndTransformToPage64Hi12)
KIND_NAME_CASE(Add6)
KIND_NAME_CASE(Add8)
KIND_NAME_CASE(Add16)
More information about the llvm-commits
mailing list