[llvm] [ORC][Mips] Fix calling convention handling for lazy calls (PR #223830)
Jiaxun Yang via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 15 14:03:16 PDT 2026
https://github.com/FlyGoat created https://github.com/llvm/llvm-project/pull/223830
Move the resolved address into $t9 before jumping to it, as jumping target is evaluated before delay slot execution.
Correct the o32 stub size to 16 bytes and reserve the required argument save area around the reentry call for saved registers.
Update resolver sizes to match the emitted instructions.
Validated with existing tests on Mips Linux for both o32 and n64.
>From 1fcfc549c6e68eade7c287c90033d3f299a09e3a Mon Sep 17 00:00:00 2001
From: Jiaxun Yang <jiaxun.yang at flygoat.com>
Date: Tue, 15 Sep 2026 21:01:42 +0100
Subject: [PATCH] [ORC][Mips] Fix calling convention handling for lazy calls
Move the resolved address into $t9 before jumping to it, as jumping
target is evaluated before delay slot execution.
Correct the o32 stub size to 16 bytes and reserve the required argument
save area around the reentry call for saved registers.
Update resolver sizes to match the emitted instructions.
Validated with existing tests on Mips Linux for both o32 and n64.
---
.../llvm/ExecutionEngine/Orc/OrcABISupport.h | 6 +-
.../lib/ExecutionEngine/Orc/OrcABISupport.cpp | 69 ++++++++++---------
2 files changed, 40 insertions(+), 35 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h b/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
index 16ab4fb567728..1852db777556f 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
@@ -238,9 +238,9 @@ class OrcMips32_Base {
public:
static constexpr unsigned PointerSize = 4;
static constexpr unsigned TrampolineSize = 20;
- static constexpr unsigned StubSize = 8;
+ static constexpr unsigned StubSize = 16;
static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
- static constexpr unsigned ResolverCodeSize = 0xfc;
+ static constexpr unsigned ResolverCodeSize = 0x104;
/// Write the requested number of trampolines into the given memory,
/// which must be big enough to hold 1 pointer, plus NumTrampolines
@@ -302,7 +302,7 @@ class OrcMips64 {
static constexpr unsigned TrampolineSize = 40;
static constexpr unsigned StubSize = 32;
static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
- static constexpr unsigned ResolverCodeSize = 0x120;
+ static constexpr unsigned ResolverCodeSize = 0x124;
/// Write the resolver code into the given memory. The user is
/// responsible for allocating the memory and setting permissions.
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp b/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp
index 8e6728281575f..36b724d585e9d 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/OrcABISupport.cpp
@@ -557,46 +557,49 @@ void OrcMips32_Base::writeResolverCode(char *ResolverWorkingMem,
0x00000000, // 0x80: addiu $t9,$t9,reentry
0x0320f809, // 0x84: jalr $t9
- 0x00000000, // 0x88: nop
- 0x8fbf0064, // 0x8c: lw $ra,100($sp)
- 0x8fbe0060, // 0x90: lw $fp,96($sp)
- 0x8fb9005c, // 0x94: lw $t9,92($sp)
- 0x8fb80058, // 0x98: lw $t8,88($sp)
- 0x8faf0054, // 0x9c: lw $t7,84($sp)
- 0x8fae0050, // 0xa0: lw $t6,80($sp)
- 0x8fad004c, // 0xa4: lw $t5,76($sp)
- 0x8fac0048, // 0xa8: lw $t4,72($sp)
- 0x8fab0044, // 0xac: lw $t3,68($sp)
- 0x8faa0040, // 0xb0: lw $t2,64($sp)
- 0x8fa9003c, // 0xb4: lw $t1,60($sp)
- 0x8fa80038, // 0xb8: lw $t0,56($sp)
- 0x8fb70034, // 0xbc: lw $s7,52($sp)
- 0x8fb60030, // 0xc0: lw $s6,48($sp)
- 0x8fb5002c, // 0xc4: lw $s5,44($sp)
- 0x8fb40028, // 0xc8: lw $s4,40($sp)
- 0x8fb30024, // 0xcc: lw $s3,36($sp)
- 0x8fb20020, // 0xd0: lw $s2,32($sp)
- 0x8fb1001c, // 0xd4: lw $s1,28($sp)
- 0x8fb00018, // 0xd8: lw $s0,24($sp)
- 0x8fa70014, // 0xdc: lw $a3,20($sp)
- 0x8fa60010, // 0xe0: lw $a2,16($sp)
- 0x8fa5000c, // 0xe4: lw $a1,12($sp)
- 0x8fa40008, // 0xe8: lw $a0,8($sp)
- 0x27bd0068, // 0xec: addiu $sp,$sp,104
- 0x0300f825, // 0xf0: move $ra, $t8
- 0x03200008, // 0xf4: jr $t9
+ 0x27bdfff0, // 0x88: addiu $sp,$sp,-16 # delay slot
+ 0x27bd0010, // 0x8c: addiu $sp,$sp,16
+ 0x8fbf0064, // 0x90: lw $ra,100($sp)
+ 0x8fbe0060, // 0x94: lw $fp,96($sp)
+ 0x8fb9005c, // 0x98: lw $t9,92($sp)
+ 0x8fb80058, // 0x9c: lw $t8,88($sp)
+ 0x8faf0054, // 0xa0: lw $t7,84($sp)
+ 0x8fae0050, // 0xa4: lw $t6,80($sp)
+ 0x8fad004c, // 0xa8: lw $t5,76($sp)
+ 0x8fac0048, // 0xac: lw $t4,72($sp)
+ 0x8fab0044, // 0xb0: lw $t3,68($sp)
+ 0x8faa0040, // 0xb4: lw $t2,64($sp)
+ 0x8fa9003c, // 0xb8: lw $t1,60($sp)
+ 0x8fa80038, // 0xbc: lw $t0,56($sp)
+ 0x8fb70034, // 0xc0: lw $s7,52($sp)
+ 0x8fb60030, // 0xc4: lw $s6,48($sp)
+ 0x8fb5002c, // 0xc8: lw $s5,44($sp)
+ 0x8fb40028, // 0xcc: lw $s4,40($sp)
+ 0x8fb30024, // 0xd0: lw $s3,36($sp)
+ 0x8fb20020, // 0xd4: lw $s2,32($sp)
+ 0x8fb1001c, // 0xd8: lw $s1,28($sp)
+ 0x8fb00018, // 0xdc: lw $s0,24($sp)
+ 0x8fa70014, // 0xe0: lw $a3,20($sp)
+ 0x8fa60010, // 0xe4: lw $a2,16($sp)
+ 0x8fa5000c, // 0xe8: lw $a1,12($sp)
+ 0x8fa40008, // 0xec: lw $a0,8($sp)
+ 0x27bd0068, // 0xf0: addiu $sp,$sp,104
+ 0x0300f825, // 0xf4: move $ra, $t8
0x00000000, // 0xf8: move $t9, $v0/v1
+ 0x03200008, // 0xfc: jr $t9
+ 0x00000000, // 0x100: nop
};
const unsigned ReentryFnAddrOffset = 0x7c; // JIT re-entry fn addr lui
const unsigned ReentryCtxAddrOffset = 0x6c; // JIT re-entry context addr lui
- const unsigned Offsett = 0xf8;
+ const unsigned MoveLandingAddrOffset = 0xf8;
+ static_assert(sizeof(ResolverCode) == ResolverCodeSize);
memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
// Depending on endian return value will be in v0 or v1.
uint32_t MoveVxT9 = isBigEndian ? 0x0060c825 : 0x0040c825;
- memcpy(ResolverWorkingMem + Offsett, &MoveVxT9, sizeof(MoveVxT9));
+ memcpy(ResolverWorkingMem + MoveLandingAddrOffset, &MoveVxT9, sizeof(MoveVxT9));
uint32_t ReentryCtxLUi =
0x3c040000 | (((ReentryCtxAddr.getValue() + 0x8000) >> 16) & 0xFFFF);
@@ -768,13 +771,15 @@ void OrcMips64::writeResolverCode(char *ResolverWorkingMem,
0xdfa30008, // 0x10c: ld v1, 8(sp)
0x67bd00d0, // 0x110: daddiu $sp,$sp,208
0x0300f825, // 0x114: move $ra, $t8
- 0x03200008, // 0x118: jr $t9
- 0x0040c825, // 0x11c: move $t9, $v0
+ 0x0040c825, // 0x118: move $t9, $v0
+ 0x03200008, // 0x11c: jr $t9
+ 0x00000000, // 0x120: nop
};
const unsigned ReentryFnAddrOffset = 0x8c; // JIT re-entry fn addr lui
const unsigned ReentryCtxAddrOffset = 0x6c; // JIT re-entry ctx addr lui
+ static_assert(sizeof(ResolverCode) == ResolverCodeSize);
memcpy(ResolverWorkingMem, ResolverCode, sizeof(ResolverCode));
uint32_t ReentryCtxLUi =
More information about the llvm-commits
mailing list