[lld] 7198c87 - [ELF][PPC64] Actually implement --no-power10-stubs

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 27 16:19:18 PST 2023


Author: Fangrui Song
Date: 2023-02-27T16:19:13-08:00
New Revision: 7198c87f42f6c15d76b127c1c63530e9b4d5dd39

URL: https://github.com/llvm/llvm-project/commit/7198c87f42f6c15d76b127c1c63530e9b4d5dd39
DIFF: https://github.com/llvm/llvm-project/commit/7198c87f42f6c15d76b127c1c63530e9b4d5dd39.diff

LOG: [ELF][PPC64] Actually implement --no-power10-stubs

When a caller that does not use TOC calls a function, a call stub is needed if
the function may use TOC. --no-power10-stubs avoids PC-relative instructions in
the code sequence.

The --no-power10-stubs=no implementation added in D94627 is wrong.
First, the first instruction incorrectly uses `mflr 0` (instead of `mflr 12`).
Second, for the PLT case, it uses addis+addi with getVA instead of addis+ld with
getGotPltVA.

Added: 
    

Modified: 
    lld/ELF/Thunks.cpp
    lld/ELF/Thunks.h
    lld/test/ELF/ppc64-pcrel-call-to-extern.s
    lld/test/ELF/ppc64-pcrel-call-to-toc.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index ce35bb5258358..ca0d34dce7dc6 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -1089,13 +1089,17 @@ void PPC64R12SetupStub::writeTo(uint8_t *buf) {
         buf, (gotPlt ? PLD_R12_NO_DISP : PADDI_R12_NO_DISP) | imm);
     nextInstOffset = 8;
   } else {
-    uint32_t off = destination.getVA(addend) - getThunkTargetSym()->getVA() - 8;
-    write32(buf + 0, 0x7c0802a6);                      // mflr r12
-    write32(buf + 4, 0x429f0005);                      // bcl 20,31,.+4
-    write32(buf + 8, 0x7d6802a6);                      // mflr r11
-    write32(buf + 12, 0x7d8803a6);                     // mtlr r12
-    write32(buf + 16, 0x3d8b0000 | computeHiBits(off));// addis r12,r11,off at ha
-    write32(buf + 20, 0x398c0000 | (off & 0xffff));    // addi r12,r12,off at l
+    uint32_t off = offset - 8;
+    write32(buf + 0, 0x7d8802a6);                     // mflr 12
+    write32(buf + 4, 0x429f0005);                     // bcl 20,31,.+4
+    write32(buf + 8, 0x7d6802a6);                     // mflr 11
+    write32(buf + 12, 0x7d8803a6);                    // mtlr 12
+    write32(buf + 16,
+            0x3d8b0000 | ((off + 0x8000) >> 16));     // addis 12,11,off at ha
+    if (gotPlt)
+      write32(buf + 20, 0xe98c0000 | (off & 0xffff)); // ld 12, off at l(12)
+    else
+      write32(buf + 20, 0x398c0000 | (off & 0xffff)); // addi 12,12,off at l
     nextInstOffset = 24;
   }
   write32(buf + nextInstOffset, MTCTR_R12); // mtctr r12

diff  --git a/lld/ELF/Thunks.h b/lld/ELF/Thunks.h
index 86aaee15f93bb..12ddf08cadc09 100644
--- a/lld/ELF/Thunks.h
+++ b/lld/ELF/Thunks.h
@@ -73,10 +73,6 @@ void writePPC32PltCallStub(uint8_t *buf, uint64_t gotPltVA,
                            const InputFile *file, int64_t addend);
 void writePPC64LoadAndBranch(uint8_t *buf, int64_t offset);
 
-static inline uint16_t computeHiBits(uint32_t toCompute) {
-  return (toCompute + 0x8000) >> 16;
-}
-
 } // namespace lld::elf
 
 #endif

diff  --git a/lld/test/ELF/ppc64-pcrel-call-to-extern.s b/lld/test/ELF/ppc64-pcrel-call-to-extern.s
index ec65c027fee32..a929cb36ef175 100644
--- a/lld/test/ELF/ppc64-pcrel-call-to-extern.s
+++ b/lld/test/ELF/ppc64-pcrel-call-to-extern.s
@@ -115,14 +115,14 @@
 
 ## No P10; branch to next inst to get addr
 # CHECK-NOP10-LABEL: <__plt_pcrel_callee_global_stother0>:
-# CHECK-NOP10:       10010010: mflr 0
-# CHECK-NOP10-NEXT:  10010014: bcl 20, 31, 0x10010018
-# CHECK-NOP10:       10010018: mflr 11
-# CHECK-NOP10:       1001001c: mtlr 12
-# CHECK-NOP10:       10010020: addis 12, 11, -4097
-# CHECK-NOP10:       10010024: addi  12, 12, -24
-# CHECK-NOP10-NEXT:  10010028: mtctr 12
-# CHECK-NOP10-NEXT:  1001002c: bctr
+# CHECK-NOP10:       10010010: mflr 12
+# CHECK-NOP10-NEXT:            bcl 20, 31, 0x10010018
+# CHECK-NOP10-NEXT:  10010018: mflr 11
+# CHECK-NOP10-NEXT:            mtlr 12
+# CHECK-NOP10-NEXT:            addis 12, 11, 2
+# CHECK-NOP10-NEXT:            ld 12, 336(12)
+# CHECK-NOP10-NEXT:            mtctr 12
+# CHECK-NOP10-NEXT:            bctr
 
 # CHECK-LABEL: <caller2>:
 # CHECK:       10020000: bl 0x10020010
@@ -139,15 +139,16 @@
 # CHECK-NEXT:  1002001c: bctr
 
 ## no P10; branch to next inst to get addr
+## .plt[3]-r11 = 0x10030170-0x10020018 = 65536*1+344
 # CHECK-NOP10-LABEL: <__plt_pcrel_callee_global_stother1>:
-# CHECK-NOP10:       10020010: mflr 0
-# CHECK-NOP10-NEXT:  10020014: bcl 20, 31, 0x10020018
+# CHECK-NOP10:       10020010: mflr 12
+# CHECK-NOP10-NEXT:            bcl 20, 31, 0x10020018
 # CHECK-NOP10-NEXT:  10020018: mflr 11
-# CHECK-NOP10-NEXT:  1002001c: mtlr 12
-# CHECK-NOP10-NEXT:  10020020: addis 12, 11, -4098
-# CHECK-NOP10-NEXT:  10020024: addi 12, 12, -24
-# CHECK-NOP10-NEXT:  10020028: mtctr 12
-# CHECK-NOP10-NEXT:  1002002c: bctr
+# CHECK-NOP10-NEXT:            mtlr 12
+# CHECK-NOP10-NEXT:            addis 12, 11, 1
+# CHECK-NOP10-NEXT:            ld 12, 344(12)
+# CHECK-NOP10-NEXT:            mtctr 12
+# CHECK-NOP10-NEXT:            bctr
 
 # CHECK-LABEL: <caller3>:
 # CHECK:       10030000: bl 0x10030010
@@ -164,15 +165,16 @@
 # CHECK-NEXT:  1003001c: bctr
 
 ## no P10; branch to next inst to get addr
+## .plt[4]-r11 = 0x10030178-0x10030018 = 65536*0+352
 # CHECK-NOP10-LABEL: <__plt_pcrel_callee_global_TOC>:
-# CHECK-NOP10-NEXT:  10030010: mflr 0
-# CHECK-NOP10-NEXT:  10030014: bcl 20, 31, 0x10030018
+# CHECK-NOP10-NEXT:  10030010: mflr 12
+# CHECK-NOP10-NEXT:            bcl 20, 31, 0x10030018
 # CHECK-NOP10-NEXT:  10030018: mflr 11
-# CHECK-NOP10-NEXT:  1003001c: mtlr 12
-# CHECK-NOP10-NEXT:  10030020: addis 12, 11, -4099
-# CHECK-NOP10-NEXT:  10030024: addi 12, 12, -24
-# CHECK-NOP10-NEXT:  10030028: mtctr 12
-# CHECK-NOP10-NEXT:  1003002c: bctr
+# CHECK-NOP10-NEXT:            mtlr 12
+# CHECK-NOP10-NEXT:            addis 12, 11, 0
+# CHECK-NOP10-NEXT:            ld 12, 352(12)
+# CHECK-NOP10-NEXT:            mtctr 12
+# CHECK-NOP10-NEXT:            bctr
 
 .ifdef AUX
 .section .text_caller1, "ax", %progbits

diff  --git a/lld/test/ELF/ppc64-pcrel-call-to-toc.s b/lld/test/ELF/ppc64-pcrel-call-to-toc.s
index 9501ace84400d..2a3f92e1d5d37 100644
--- a/lld/test/ELF/ppc64-pcrel-call-to-toc.s
+++ b/lld/test/ELF/ppc64-pcrel-call-to-toc.s
@@ -48,7 +48,7 @@
 # CHECK-NEXT:  bctr
 
 # CHECK-NOP10-LABEL: <__gep_setup_callee>:
-# CHECK-NOP10-NEXT:  mflr 0
+# CHECK-NOP10-NEXT:  mflr 12
 # CHECK-NOP10-NEXT:  bcl 20, 31, 0x10030018
 # CHECK-NOP10-NEXT:  mflr 11
 # CHECK-NOP10-NEXT:  mtlr 12


        


More information about the llvm-commits mailing list