-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[RuntimeDyld][LoongArch] Support large code model #148584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-backend-loongarch Author: None (Ami-zhang) ChangesFull diff: https://github.com/llvm/llvm-project/pull/148584.diff 2 Files Affected:
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index cca99591c8c45..5cb5138b61514 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -738,6 +738,32 @@ static inline uint32_t extractBits(uint64_t Val, uint32_t Hi, uint32_t Lo) {
return Hi == 63 ? Val >> Lo : (Val & (((1ULL << (Hi + 1)) - 1))) >> Lo;
}
+// Calculate the adjusted page delta between dest and PC. The code is copied
+// from lld and see comments there for more details.
+static uint64_t getLoongArchPageDelta(uint64_t dest, uint64_t pc,
+ uint32_t type) {
+ uint64_t pcalau12i_pc;
+ switch (type) {
+ case ELF::R_LARCH_PCALA64_LO20:
+ case ELF::R_LARCH_GOT64_PC_LO20:
+ pcalau12i_pc = pc - 8;
+ break;
+ case ELF::R_LARCH_PCALA64_HI12:
+ case ELF::R_LARCH_GOT64_PC_HI12:
+ pcalau12i_pc = pc - 12;
+ break;
+ default:
+ pcalau12i_pc = pc;
+ break;
+ }
+ uint64_t result = (dest & ~0xfffULL) - (pcalau12i_pc & ~0xfffULL);
+ if (dest & 0x800)
+ result += 0x1000 - 0x1'0000'0000;
+ if (result & 0x8000'0000)
+ result += 0x1'0000'0000;
+ return result;
+}
+
void RuntimeDyldELF::resolveLoongArch64Relocation(const SectionEntry &Section,
uint64_t Offset,
uint64_t Value, uint32_t Type,
@@ -789,10 +815,7 @@ void RuntimeDyldELF::resolveLoongArch64Relocation(const SectionEntry &Section,
case ELF::R_LARCH_GOT_PC_HI20:
case ELF::R_LARCH_PCALA_HI20: {
uint64_t Target = Value + Addend;
- uint64_t TargetPage =
- (Target + (Target & 0x800)) & ~static_cast<uint64_t>(0xfff);
- uint64_t PCPage = FinalAddress & ~static_cast<uint64_t>(0xfff);
- int64_t PageDelta = TargetPage - PCPage;
+ int64_t PageDelta = getLoongArchPageDelta(Target, FinalAddress, Type);
auto Instr = support::ulittle32_t::ref(TargetPtr);
uint32_t Imm31_12 = extractBits(PageDelta, /*Hi=*/31, /*Lo=*/12) << 5;
Instr = (Instr & 0xfe00001f) | Imm31_12;
@@ -806,6 +829,24 @@ void RuntimeDyldELF::resolveLoongArch64Relocation(const SectionEntry &Section,
Instr = (Instr & 0xffc003ff) | Imm11_0;
break;
}
+ case ELF::R_LARCH_GOT64_PC_LO20:
+ case ELF::R_LARCH_PCALA64_LO20: {
+ uint64_t Target = Value + Addend;
+ int64_t PageDelta = getLoongArchPageDelta(Target, FinalAddress, Type);
+ auto Instr = support::ulittle32_t::ref(TargetPtr);
+ uint32_t Imm51_32 = extractBits(PageDelta, /*Hi=*/51, /*Lo=*/32) << 5;
+ Instr = (Instr & 0xfe00001f) | Imm51_32;
+ break;
+ }
+ case ELF::R_LARCH_GOT64_PC_HI12:
+ case ELF::R_LARCH_PCALA64_HI12: {
+ uint64_t Target = Value + Addend;
+ int64_t PageDelta = getLoongArchPageDelta(Target, FinalAddress, Type);
+ auto Instr = support::ulittle32_t::ref(TargetPtr);
+ uint32_t Imm63_52 = extractBits(PageDelta, /*Hi=*/63, /*Lo=*/52) << 10;
+ Instr = (Instr & 0xffc003ff) | Imm63_52;
+ break;
+ }
case ELF::R_LARCH_ABS_HI20: {
uint64_t Target = Value + Addend;
auto Instr = support::ulittle32_t::ref(TargetPtr);
diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/ELF_LoongArch_relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/ELF_LoongArch_relocations.s
index 0fca88b6e9ba2..4d15846ba0703 100644
--- a/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/ELF_LoongArch_relocations.s
+++ b/llvm/test/ExecutionEngine/RuntimeDyld/LoongArch/ELF_LoongArch_relocations.s
@@ -2,6 +2,9 @@
# RUN: llvm-mc --triple=loongarch64 --filetype=obj -o %t/reloc.o %s
# RUN: llvm-rtdyld --triple=loongarch64 --verify --check=%s %t/reloc.o \
# RUN: --map-section reloc.o,.got=0x21f00 \
+# RUN: --map-section reloc.o,.sec.large.pc=0x0000000012345000 \
+# RUN: --map-section reloc.o,.sec.large.got=0x44433333abcde000 \
+# RUN: --map-section reloc.o,.sec.dummy=0x4443333334567111 \
# RUN: --dummy-extern abs=0x0123456789abcdef \
# RUN: --dummy-extern external_data=0x1234
@@ -100,3 +103,42 @@ named_data:
.quad 0x2222222222222222
.quad 0x3333333333333333
.size named_data, .-named_data
+
+ .section .sec.large.pc,"ax"
+ .globl test_large_pc
+test_large_pc:
+## Code after link should be:
+## 1a44444d pcalau12i $t1, 139810
+## 02c4440c addi.d $t0, 273
+## 1666666c lu32i.d $t0, 209715
+## 0311118c lu52i.d $t0, $t0, 1092
+
+# rtdyld-check: *{4}(test_large_pc) = 0x1a44444d
+ pcalau12i $t1, %pc_hi20(.sec.dummy)
+# rtdyld-check: *{4}(test_large_pc + 4) = 0x02c4440c
+ addi.d $t0, $zero, %pc_lo12(.sec.dummy)
+# rtdyld-check: *{4}(test_large_pc + 8) = 0x1666666c
+ lu32i.d $t0, %pc64_lo20(.sec.dummy)
+# rtdyld-check: *{4}(test_large_pc + 12) = 0x0311118c
+ lu52i.d $t0, $t0, %pc64_hi12(.sec.dummy)
+
+ .section .sec.large.got,"ax"
+ .globl test_large_got
+test_large_got:
+## Code after link should be:
+## 1aa8688d pcalau12i $t1, 344900
+## 02fc000c addi.d $t0, -256
+## 1799998c lu32i.d $t0, -209716
+## 032eed8c lu52i.d $t0, $t0, -1093
+
+# rtdyld-check: *{4}(test_large_got) = 0x1aa8688d
+ pcalau12i $t1, %got_pc_hi20(external_data)
+# rtdyld-check: *{4}(test_large_got + 4) = 0x02fc000c
+ addi.d $t0, $zero, %got_pc_lo12(external_data)
+# rtdyld-check: *{4}(test_large_got + 8) = 0x1799998c
+ lu32i.d $t0, %got64_pc_lo20(external_data)
+# rtdyld-check: *{4}(test_large_got + 12) = 0x032eed8c
+ lu52i.d $t0, $t0, %got64_pc_hi12(external_data)
+
+ .section .sec.dummy,"a"
+ .word 0
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The large got may be wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modified, thank you.
a48cf6c to
f05dae5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ## 02c4440c addi.d $t0, 273 | |
| ## 02c4440c addi.d $t0, $zero, 273 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ## 02fc000c addi.d $t0, -256 | |
| ## 02fc000c addi.d $t0, $zero, -256 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
SixWeining
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Co-authored-by: Weining Lu <[email protected]>
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/210/builds/291 Here is the relevant piece of the build log for the reference |
All of my Hetzner-hosted buildbots had issues connecting to GitHub at about this time. Although this is very rare (I can't recall it happening before) I'll see if I can adjust the builder script so that failures at git checkout don't trigger messages/emails. Sorry for the noise! |
Co-authored-by: Weining Lu <[email protected]>
Co-authored-by: Weining Lu <[email protected]> (cherry picked from commit 4e35ae1)
No description provided.