[lld] r328846 - ELF: Add support for short thunks on ARM.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 29 15:43:52 PDT 2018


Author: pcc
Date: Thu Mar 29 15:43:52 2018
New Revision: 328846

URL: http://llvm.org/viewvc/llvm-project?rev=328846&view=rev
Log:
ELF: Add support for short thunks on ARM.

A short thunk uses a direct branch (b or b.w) instruction, and is used
when the target has the same thumbness as the thunk and is within
direct branch range (32MB for ARM, 16MB for Thumb-2). Reduces the
size of Chromium for Android's .text section by around 160KB.

Differential Revision: https://reviews.llvm.org/D44963

Added:
    lld/trunk/test/ELF/Inputs/arm-long-thunk-converge.lds
    lld/trunk/test/ELF/Inputs/far-long-arm-abs.s
    lld/trunk/test/ELF/arm-long-thunk-converge.s
Modified:
    lld/trunk/ELF/Thunks.cpp
    lld/trunk/test/ELF/arm-branch-rangethunk.s
    lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s
    lld/trunk/test/ELF/arm-thumb-range-thunk-os.s
    lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s
    lld/trunk/test/ELF/arm-thunk-largesection.s
    lld/trunk/test/ELF/arm-thunk-linkerscript-large.s
    lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s
    lld/trunk/test/ELF/arm-thunk-multipass.s

Modified: lld/trunk/ELF/Thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.cpp?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/ELF/Thunks.cpp (original)
+++ lld/trunk/ELF/Thunks.cpp Thu Mar 29 15:43:52 2018
@@ -64,46 +64,99 @@ public:
   void addSymbols(ThunkSection &IS) override;
 };
 
-// Specific ARM Thunk implementations. The naming convention is:
-// Source State, TargetState, Target Requirement, ABS or PI, Range
-class ARMV7ABSLongThunk final : public Thunk {
+// Base class for ARM thunks.
+//
+// An ARM thunk may be either short or long. A short thunk is simply a branch
+// (B) instruction, and it may be used to call ARM functions when the distance
+// from the thunk to the target is less than 32MB. Long thunks can branch to any
+// virtual address and can switch between ARM and Thumb, and they are
+// implemented in the derived classes. This class tries to create a short thunk
+// if the target is in range, otherwise it creates a long thunk.
+class ARMThunk : public Thunk {
 public:
-  ARMV7ABSLongThunk(Symbol &Dest) : Thunk(Dest) {}
+  ARMThunk(Symbol &Dest) : Thunk(Dest) {}
 
-  uint32_t size() override { return 12; }
+  bool mayUseShortThunk();
+  uint32_t size() override { return mayUseShortThunk() ? 4 : sizeLong(); }
   void writeTo(uint8_t *Buf) override;
-  void addSymbols(ThunkSection &IS) override;
   bool isCompatibleWith(RelType Type) const override;
+
+  // Returns the size of a long thunk.
+  virtual uint32_t sizeLong() = 0;
+
+  // Writes a long thunk to Buf.
+  virtual void writeLong(uint8_t *Buf) = 0;
+
+private:
+  // This field tracks whether all previously considered layouts would allow
+  // this thunk to be short. If we have ever needed a long thunk, we always
+  // create a long thunk, even if the thunk may be short given the current
+  // distance to the target. We do this because transitioning from long to short
+  // can create layout oscillations in certain corner cases which would prevent
+  // the layout from converging.
+  bool MayUseShortThunk = true;
 };
 
-class ARMV7PILongThunk final : public Thunk {
+// Base class for Thumb-2 thunks.
+//
+// This class is similar to ARMThunk, but it uses the Thumb-2 B.W instruction
+// which has a range of 16MB.
+class ThumbThunk : public Thunk {
 public:
-  ARMV7PILongThunk(Symbol &Dest) : Thunk(Dest) {}
+  ThumbThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; }
 
-  uint32_t size() override { return 16; }
+  bool mayUseShortThunk();
+  uint32_t size() override { return mayUseShortThunk() ? 4 : sizeLong(); }
   void writeTo(uint8_t *Buf) override;
-  void addSymbols(ThunkSection &IS) override;
   bool isCompatibleWith(RelType Type) const override;
+
+  // Returns the size of a long thunk.
+  virtual uint32_t sizeLong() = 0;
+
+  // Writes a long thunk to Buf.
+  virtual void writeLong(uint8_t *Buf) = 0;
+
+private:
+  // See comment in ARMThunk above.
+  bool MayUseShortThunk = true;
 };
 
-class ThumbV7ABSLongThunk final : public Thunk {
+// Specific ARM Thunk implementations. The naming convention is:
+// Source State, TargetState, Target Requirement, ABS or PI, Range
+class ARMV7ABSLongThunk final : public ARMThunk {
 public:
-  ThumbV7ABSLongThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; }
+  ARMV7ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
 
-  uint32_t size() override { return 10; }
-  void writeTo(uint8_t *Buf) override;
+  uint32_t sizeLong() override { return 12; }
+  void writeLong(uint8_t *Buf) override;
   void addSymbols(ThunkSection &IS) override;
-  bool isCompatibleWith(RelType Type) const override;
 };
 
-class ThumbV7PILongThunk final : public Thunk {
+class ARMV7PILongThunk final : public ARMThunk {
 public:
-  ThumbV7PILongThunk(Symbol &Dest) : Thunk(Dest) { Alignment = 2; }
+  ARMV7PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
 
-  uint32_t size() override { return 12; }
-  void writeTo(uint8_t *Buf) override;
+  uint32_t sizeLong() override { return 16; }
+  void writeLong(uint8_t *Buf) override;
+  void addSymbols(ThunkSection &IS) override;
+};
+
+class ThumbV7ABSLongThunk final : public ThumbThunk {
+public:
+  ThumbV7ABSLongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+
+  uint32_t sizeLong() override { return 10; }
+  void writeLong(uint8_t *Buf) override;
+  void addSymbols(ThunkSection &IS) override;
+};
+
+class ThumbV7PILongThunk final : public ThumbThunk {
+public:
+  ThumbV7PILongThunk(Symbol &Dest) : ThumbThunk(Dest) {}
+
+  uint32_t sizeLong() override { return 12; }
+  void writeLong(uint8_t *Buf) override;
   void addSymbols(ThunkSection &IS) override;
-  bool isCompatibleWith(RelType Type) const override;
 };
 
 // MIPS LA25 thunk
@@ -211,7 +264,81 @@ static uint64_t getARMThunkDestVA(const
   return SignExtend64<32>(V);
 }
 
-void ARMV7ABSLongThunk::writeTo(uint8_t *Buf) {
+// This function returns true if the target is not Thumb and is within 2^26, and
+// it has not previously returned false (see comment for MayUseShortThunk).
+bool ARMThunk::mayUseShortThunk() {
+  if (!MayUseShortThunk)
+    return false;
+  uint64_t S = getARMThunkDestVA(Destination);
+  if (S & 1) {
+    MayUseShortThunk = false;
+    return false;
+  }
+  uint64_t P = getThunkTargetSym()->getVA();
+  int64_t Offset = S - P - 8;
+  MayUseShortThunk = llvm::isInt<26>(Offset);
+  return MayUseShortThunk;
+}
+
+void ARMThunk::writeTo(uint8_t *Buf) {
+  if (!mayUseShortThunk()) {
+    writeLong(Buf);
+    return;
+  }
+
+  uint64_t S = getARMThunkDestVA(Destination);
+  uint64_t P = getThunkTargetSym()->getVA();
+  int64_t Offset = S - P - 8;
+  const uint8_t Data[] = {
+    0x00, 0x00, 0x00, 0xea, // b S
+  };
+  memcpy(Buf, Data, sizeof(Data));
+  Target->relocateOne(Buf, R_ARM_JUMP24, Offset);
+}
+
+bool ARMThunk::isCompatibleWith(RelType Type) const {
+  // Thumb branch relocations can't use BLX
+  return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24;
+}
+
+// This function returns true if the target is Thumb and is within 2^25, and
+// it has not previously returned false (see comment for MayUseShortThunk).
+bool ThumbThunk::mayUseShortThunk() {
+  if (!MayUseShortThunk)
+    return false;
+  uint64_t S = getARMThunkDestVA(Destination);
+  if ((S & 1) == 0) {
+    MayUseShortThunk = false;
+    return false;
+  }
+  uint64_t P = getThunkTargetSym()->getVA() & ~1;
+  int64_t Offset = S - P - 4;
+  MayUseShortThunk = llvm::isInt<25>(Offset);
+  return MayUseShortThunk;
+}
+
+void ThumbThunk::writeTo(uint8_t *Buf) {
+  if (!mayUseShortThunk()) {
+    writeLong(Buf);
+    return;
+  }
+
+  uint64_t S = getARMThunkDestVA(Destination);
+  uint64_t P = getThunkTargetSym()->getVA();
+  int64_t Offset = S - P - 4;
+  const uint8_t Data[] = {
+      0x00, 0xf0, 0x00, 0xb0, // b.w S
+  };
+  memcpy(Buf, Data, sizeof(Data));
+  Target->relocateOne(Buf, R_ARM_THM_JUMP24, Offset);
+}
+
+bool ThumbThunk::isCompatibleWith(RelType Type) const {
+  // ARM branch relocations can't use BLX
+  return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32;
+}
+
+void ARMV7ABSLongThunk::writeLong(uint8_t *Buf) {
   const uint8_t Data[] = {
       0x00, 0xc0, 0x00, 0xe3, // movw         ip,:lower16:S
       0x00, 0xc0, 0x40, 0xe3, // movt         ip,:upper16:S
@@ -229,12 +356,7 @@ void ARMV7ABSLongThunk::addSymbols(Thunk
   addSymbol("$a", STT_NOTYPE, 0, IS);
 }
 
-bool ARMV7ABSLongThunk::isCompatibleWith(RelType Type) const {
-  // Thumb branch relocations can't use BLX
-  return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24;
-}
-
-void ThumbV7ABSLongThunk::writeTo(uint8_t *Buf) {
+void ThumbV7ABSLongThunk::writeLong(uint8_t *Buf) {
   const uint8_t Data[] = {
       0x40, 0xf2, 0x00, 0x0c, // movw         ip, :lower16:S
       0xc0, 0xf2, 0x00, 0x0c, // movt         ip, :upper16:S
@@ -252,12 +374,7 @@ void ThumbV7ABSLongThunk::addSymbols(Thu
   addSymbol("$t", STT_NOTYPE, 0, IS);
 }
 
-bool ThumbV7ABSLongThunk::isCompatibleWith(RelType Type) const {
-  // ARM branch relocations can't use BLX
-  return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32;
-}
-
-void ARMV7PILongThunk::writeTo(uint8_t *Buf) {
+void ARMV7PILongThunk::writeLong(uint8_t *Buf) {
   const uint8_t Data[] = {
       0xf0, 0xcf, 0x0f, 0xe3, // P:  movw ip,:lower16:S - (P + (L1-P) + 8)
       0x00, 0xc0, 0x40, 0xe3, //     movt ip,:upper16:S - (P + (L1-P) + 8)
@@ -278,12 +395,7 @@ void ARMV7PILongThunk::addSymbols(ThunkS
   addSymbol("$a", STT_NOTYPE, 0, IS);
 }
 
-bool ARMV7PILongThunk::isCompatibleWith(RelType Type) const {
-  // Thumb branch relocations can't use BLX
-  return Type != R_ARM_THM_JUMP19 && Type != R_ARM_THM_JUMP24;
-}
-
-void ThumbV7PILongThunk::writeTo(uint8_t *Buf) {
+void ThumbV7PILongThunk::writeLong(uint8_t *Buf) {
   const uint8_t Data[] = {
       0x4f, 0xf6, 0xf4, 0x7c, // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
       0xc0, 0xf2, 0x00, 0x0c, //     movt ip,:upper16:S - (P + (L1-P) + 4)
@@ -304,11 +416,6 @@ void ThumbV7PILongThunk::addSymbols(Thun
   addSymbol("$t", STT_NOTYPE, 0, IS);
 }
 
-bool ThumbV7PILongThunk::isCompatibleWith(RelType Type) const {
-  // ARM branch relocations can't use BLX
-  return Type != R_ARM_JUMP24 && Type != R_ARM_PC24 && Type != R_ARM_PLT32;
-}
-
 // Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
 void MipsThunk::writeTo(uint8_t *Buf) {
   uint64_t S = Destination.getVA();

Added: lld/trunk/test/ELF/Inputs/arm-long-thunk-converge.lds
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-long-thunk-converge.lds?rev=328846&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-long-thunk-converge.lds (added)
+++ lld/trunk/test/ELF/Inputs/arm-long-thunk-converge.lds Thu Mar 29 15:43:52 2018
@@ -0,0 +1,4 @@
+SECTIONS {
+  .foo : { *(.foo) }
+  .bar 0x2000000 : { *(.bar) }
+}

Added: lld/trunk/test/ELF/Inputs/far-long-arm-abs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/far-long-arm-abs.s?rev=328846&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/far-long-arm-abs.s (added)
+++ lld/trunk/test/ELF/Inputs/far-long-arm-abs.s Thu Mar 29 15:43:52 2018
@@ -0,0 +1,13 @@
+.global far
+.type far,%function
+far = 0x201001c
+
+.global too_far1
+.type too_far1,%function
+too_far1 = 0x2020014
+.global too_far2
+.type too_far2,%function
+too_far2 = 0x2020020
+.global too_far3
+.type too_far3,%function
+too_far3 = 0x202002c

Modified: lld/trunk/test/ELF/arm-branch-rangethunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-branch-rangethunk.s?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-branch-rangethunk.s (original)
+++ lld/trunk/test/ELF/arm-branch-rangethunk.s Thu Mar 29 15:43:52 2018
@@ -1,7 +1,10 @@
 // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
 // RUN: ld.lld  %t %tfar -o %t2 2>&1
-// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck --check-prefix=SHORT %s
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong
+// RUN: ld.lld  %t %tfarlong -o %t3 2>&1
+// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=LONG %s
 // REQUIRES: arm
  .syntax unified
  .section .text, "ax",%progbits
@@ -15,20 +18,32 @@ _start:
  b   too_far2
  beq too_far3
 
-// CHECK: Disassembly of section .text:
-// CHECK-NEXT: _start:
-// CHECK-NEXT:    20000:       01 00 00 eb     bl      #4 <__ARMv7ABSLongThunk_too_far1>
-// CHECK-NEXT:    20004:       03 00 00 ea     b       #12 <__ARMv7ABSLongThunk_too_far2>
-// CHECK-NEXT:    20008:       05 00 00 0a     beq     #20 <__ARMv7ABSLongThunk_too_far3>
-// CHECK: __ARMv7ABSLongThunk_too_far1:
-// CHECK-NEXT:    2000c:       08 c0 00 e3     movw    r12, #8
-// CHECK-NEXT:    20010:       02 c2 40 e3     movt    r12, #514
-// CHECK-NEXT:    20014:       1c ff 2f e1     bx      r12
-// CHECK: __ARMv7ABSLongThunk_too_far2:
-// CHECK-NEXT:    20018:       0c c0 00 e3     movw    r12, #12
-// CHECK-NEXT:    2001c:       02 c2 40 e3     movt    r12, #514
-// CHECK-NEXT:    20020:       1c ff 2f e1     bx      r12
-// CHECK: __ARMv7ABSLongThunk_too_far3:
-// CHECK-NEXT:    20024:       10 c0 00 e3     movw    r12, #16
-// CHECK-NEXT:    20028:       02 c2 40 e3     movt    r12, #514
-// CHECK-NEXT:    2002c:       1c ff 2f e1     bx      r12
+// SHORT: Disassembly of section .text:
+// SHORT-NEXT: _start:
+// SHORT-NEXT:    20000:       01 00 00 eb     bl      #4 <__ARMv7ABSLongThunk_too_far1>
+// SHORT-NEXT:    20004:       01 00 00 ea     b       #4 <__ARMv7ABSLongThunk_too_far2>
+// SHORT-NEXT:    20008:       01 00 00 0a     beq     #4 <__ARMv7ABSLongThunk_too_far3>
+// SHORT: __ARMv7ABSLongThunk_too_far1:
+// SHORT-NEXT:    2000c:       fd ff 7f ea     b       #33554420 <__ARMv7ABSLongThunk_too_far3+0x1fffff4>
+// SHORT: __ARMv7ABSLongThunk_too_far2:
+// SHORT-NEXT:    20010:       fd ff 7f ea     b       #33554420 <__ARMv7ABSLongThunk_too_far3+0x1fffff8>
+// SHORT: __ARMv7ABSLongThunk_too_far3:
+// SHORT-NEXT:    20014:       fd ff 7f ea     b       #33554420 <__ARMv7ABSLongThunk_too_far3+0x1fffffc>
+
+// LONG: Disassembly of section .text:
+// LONG-NEXT: _start:
+// LONG-NEXT:    20000:       01 00 00 eb     bl      #4 <__ARMv7ABSLongThunk_too_far1>
+// LONG-NEXT:    20004:       03 00 00 ea     b       #12 <__ARMv7ABSLongThunk_too_far2>
+// LONG-NEXT:    20008:       05 00 00 0a     beq     #20 <__ARMv7ABSLongThunk_too_far3>
+// LONG: __ARMv7ABSLongThunk_too_far1:
+// LONG-NEXT:    2000c:       14 c0 00 e3     movw    r12, #20
+// LONG-NEXT:    20010:       02 c2 40 e3     movt    r12, #514
+// LONG-NEXT:    20014:       1c ff 2f e1     bx      r12
+// LONG: __ARMv7ABSLongThunk_too_far2:
+// LONG-NEXT:    20018:       20 c0 00 e3     movw    r12, #32
+// LONG-NEXT:    2001c:       02 c2 40 e3     movt    r12, #514
+// LONG-NEXT:    20020:       1c ff 2f e1     bx      r12
+// LONG: __ARMv7ABSLongThunk_too_far3:
+// LONG-NEXT:    20024:       2c c0 00 e3     movw    r12, #44
+// LONG-NEXT:    20028:       02 c2 40 e3     movt    r12, #514
+// LONG-NEXT:    2002c:       1c ff 2f e1     bx      r12

Added: lld/trunk/test/ELF/arm-long-thunk-converge.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-long-thunk-converge.s?rev=328846&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-long-thunk-converge.s (added)
+++ lld/trunk/test/ELF/arm-long-thunk-converge.s Thu Mar 29 15:43:52 2018
@@ -0,0 +1,28 @@
+// RUN: llvm-mc -triple armv7-unknown-gnu -filetype=obj -o %t %s
+// RUN: ld.lld %t %S/Inputs/arm-long-thunk-converge.lds -o %t2
+// RUN: llvm-objdump -d -start-address=0x00000000 -stop-address=0x00000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK1 %s
+// RUN: llvm-objdump -d -start-address=0x02000000 -stop-address=0x02000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK2 %s
+// RUN: rm -f %t2
+
+// CHECK1: __ARMv7ABSLongThunk_bar:
+// CHECK1-NEXT:        0:       0c c0 00 e3     movw    r12, #12
+// CHECK1-NEXT:        4:       00 c2 40 e3     movt    r12, #512
+// CHECK1-NEXT:        8:       1c ff 2f e1     bx      r12
+// CHECK1: foo:
+// CHECK1-NEXT:        c:       fb ff ff eb     bl      #-20
+
+.section .foo,"ax",%progbits,unique,1
+foo:
+bl bar
+
+// CHECK2: __ARMv7ABSLongThunk_foo:
+// CHECK2-NEXT:  2000000:       0c c0 00 e3     movw    r12, #12
+// CHECK2-NEXT:  2000004:       00 c0 40 e3     movt    r12, #0
+// CHECK2-NEXT:  2000008:       1c ff 2f e1     bx      r12
+// CHECK2: bar:
+// CHECK2-NEXT:  200000c:       fb ff ff eb     bl      #-20 <__ARMv7ABSLongThunk_foo>
+
+.section .bar,"ax",%progbits,unique,1
+bar:
+bl foo
+.zero 0x1000000

Modified: lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s (original)
+++ lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s Thu Mar 29 15:43:52 2018
@@ -38,13 +38,9 @@ _start:
 // CHECK1-NEXT:    80000:       70 47   bx      lr
 // CHECK1-NEXT:    80002:       7f f3 ff d7     bl      #16252926
 // CHECK1: __Thumbv7ABSLongThunk_tfunc05:
-// CHECK1-NEXT:    80008:       40 f2 01 0c     movw    r12, #1
-// CHECK1-NEXT:    8000c:       c0 f2 30 0c     movt    r12, #48
-// CHECK1-NEXT:    80010:       60 47   bx      r12
+// CHECK1-NEXT:    80008:       7f f2 fa bf     b.w     #2621428 <tfunc05>
 // CHECK1: __Thumbv7ABSLongThunk_tfunc00:
-// CHECK1-NEXT:    80012:       40 f2 01 0c     movw    r12, #1
-// CHECK1-NEXT:    80016:       c0 f2 08 0c     movt    r12, #8
-// CHECK1-NEXT:    8001a:       60 47   bx      r12
+// CHECK1-NEXT:    8000c:       ff f7 f8 bf     b.w     #-16 <tfunc00>
  FUNCTION 01
 // tfunc02 is within range of tfunc02
  beq.w tfunc02
@@ -61,7 +57,7 @@ _start:
  beq.w tfunc00
 // CHECK3:   180000:       70 47   bx      lr
 // CHECK3-NEXT:   180002:       40 f4 01 80     bne.w   #-1048574 <__Thumbv7ABSLongThunk_tfunc05>
-// CHECK3-NEXT:   180006:       00 f4 04 80     beq.w   #-1048568 <__Thumbv7ABSLongThunk_tfunc00>
+// CHECK3-NEXT:   180006:       00 f4 01 80     beq.w   #-1048574 <__Thumbv7ABSLongThunk_tfunc00>
  FUNCTION 03
  FUNCTION 04
  FUNCTION 05
@@ -70,9 +66,7 @@ _start:
  FUNCTION 08
  FUNCTION 09
 // CHECK4:  __Thumbv7ABSLongThunk_tfunc03:
-// CHECK4-NEXT:   500004:       40 f2 01 0c     movw    r12, #1
-// CHECK4-NEXT:   500008:       c0 f2 20 0c     movt    r12, #32
-// CHECK4-NEXT:   50000c:       60 47   bx      r12
+// CHECK4-NEXT:   500004:       ff f4 fc bf     b.w     #-3145736 <tfunc03>
  FUNCTION 10
 // We can't reach any Thunk Section, create a new one
  beq.w tfunc03
@@ -101,17 +95,13 @@ _start:
  FUNCTION 30
  FUNCTION 31
 // CHECK6:  __Thumbv7ABSLongThunk_tfunc33:
-// CHECK6-NEXT:  1000004:       40 f2 01 0c     movw    r12, #1
-// CHECK6-NEXT:  1000008:       c0 f2 10 1c     movt    r12, #272
-// CHECK6-NEXT:  100000c:       60 47   bx      r12
+// CHECK6-NEXT:  1000004:       ff f0 fc bf     b.w     #1048568 <tfunc33>
 // CHECK6: __Thumbv7ABSLongThunk_tfunc00:
-// CHECK6-NEXT:  100000e:       40 f2 01 0c     movw    r12, #1
-// CHECK6-NEXT:  1000012:       c0 f2 08 0c     movt    r12, #8
-// CHECK6-NEXT:  1000016:       60 47   bx      r12
+// CHECK6-NEXT:  1000008:       7f f4 fa 97     b.w     #-16252940 <tfunc00>
  FUNCTION 32
  FUNCTION 33
  // We should be able to reach an existing ThunkSection.
  b.w tfunc00
 // CHECK7: tfunc33:
 // CHECK7-NEXT:  1100000:       70 47   bx      lr
-// CHECK7-NEXT:  1100002:       00 f7 04 b8     b.w     #-1048568 <__Thumbv7ABSLongThunk_tfunc00>
+// CHECK7-NEXT:  1100002:       00 f7 01 b8     b.w     #-1048574 <__Thumbv7ABSLongThunk_tfunc00>

Modified: lld/trunk/test/ELF/arm-thumb-range-thunk-os.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-range-thunk-os.s?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-range-thunk-os.s (original)
+++ lld/trunk/test/ELF/arm-thumb-range-thunk-os.s Thu Mar 29 15:43:52 2018
@@ -60,7 +60,7 @@ _start:
         b.w tfunc28
 // CHECK4: tfunc02:
 // CHECK4-NEXT:   400000:       70 47   bx      lr
-// CHECK4-NEXT:   400002:       00 f0 04 90     b.w     #12582920 <__Thumbv7ABSLongThunk_tfunc28>
+// CHECK4-NEXT:   400002:       00 f0 01 90     b.w     #12582914 <__Thumbv7ABSLongThunk_tfunc28>
  FUNCTION 03
  FUNCTION 04
  FUNCTION 05
@@ -75,25 +75,19 @@ _start:
  FUNCTION 14
 // Expect precreated ThunkSection here
 // CHECK5: __Thumbv7ABSLongThunk_tfunc16:
-// CHECK5-NEXT:  1000004:       40 f2 01 0c     movw    r12, #1
-// CHECK5-NEXT:  1000008:       c0 f2 20 1c     movt    r12, #288
-// CHECK5-NEXT:  100000c:       60 47   bx      r12
+// CHECK5-NEXT:  1000004:       ff f1 fc bf     b.w     #2097144 <tfunc16>
 // CHECK5: __Thumbv7ABSLongThunk_tfunc28:
-// CHECK5-NEXT:  100000e:       40 f2 01 0c     movw    r12, #1
-// CHECK5-NEXT:  1000012:       c0 f2 e0 1c     movt    r12, #480
-// CHECK5-NEXT:  1000016:       60 47   bx      r12
+// CHECK5-NEXT:  1000008:       ff f1 fa 97     b.w     #14680052 <tfunc28>
 // CHECK5: __Thumbv7ABSLongThunk_tfunc32:
-// CHECK5-NEXT:  1000018:       40 f2 01 0c     movw    r12, #1
-// CHECK5-NEXT:  100001c:       c0 f2 20 2c     movt    r12, #544
-// CHECK5-NEXT:  1000020:       60 47   bx      r12
+// CHECK5-NEXT:  100000c:       40 f2 01 0c     movw    r12, #1
+// CHECK5-NEXT:  1000010:       c0 f2 20 2c     movt    r12, #544
+// CHECK5-NEXT:  1000014:       60 47   bx      r12
 // CHECK5: __Thumbv7ABSLongThunk_tfunc33:
-// CHECK5-NEXT:  1000022:       40 f2 01 0c     movw    r12, #1
-// CHECK5-NEXT:  1000026:       c0 f2 30 2c     movt    r12, #560
-// CHECK5-NEXT:  100002a:       60 47   bx      r12
+// CHECK5-NEXT:  1000016:       40 f2 01 0c     movw    r12, #1
+// CHECK5-NEXT:  100001a:       c0 f2 30 2c     movt    r12, #560
+// CHECK5-NEXT:  100001e:       60 47   bx      r12
 // CHECK5: __Thumbv7ABSLongThunk_tfunc02:
-// CHECK5-NEXT:  100002c:       40 f2 01 0c     movw    r12, #1
-// CHECK5-NEXT:  1000030:       c0 f2 40 0c     movt    r12, #64
-// CHECK5-NEXT:  1000034:       60 47   bx      r12
+// CHECK5-NEXT:  1000020:       ff f7 ee 97     b.w     #-12582948 <tfunc02>
  FUNCTION 15
 // tfunc00 and tfunc01 are < 16Mb away, expect no range extension thunks
  bl tfunc00
@@ -106,8 +100,8 @@ _start:
 // CHECK6-NEXT:  1100000:       70 47   bx      lr
 // CHECK6-NEXT:  1100002:       ff f4 fd d7     bl      #-15728646
 // CHECK6-NEXT:  1100006:       ff f5 fb d7     bl      #-14680074
-// CHECK6-NEXT:  110000a:       00 f7 05 f8     bl      #-1048566
-// CHECK6-NEXT:  110000e:       00 f7 08 f8     bl      #-1048560
+// CHECK6-NEXT:  110000a:       ff f6 ff ff     bl      #-1048578
+// CHECK6-NEXT:  110000e:       00 f7 02 f8     bl      #-1048572
  FUNCTION 16
  FUNCTION 17
  FUNCTION 18
@@ -125,19 +119,15 @@ _start:
 // section
 // CHECK7:  tfunc28:
 // CHECK7-NEXT:  1e00000:       70 47   bx      lr
-// CHECK7-NEXT:  1e00002:       00 f6 13 90     b.w     #-14680026 <__Thumbv7ABSLongThunk_tfunc02>
+// CHECK7-NEXT:  1e00002:       00 f6 0d 90     b.w     #-14680038 <__Thumbv7ABSLongThunk_tfunc02>
 
  b.w tfunc02
  FUNCTION 29
 // Expect another precreated thunk section here
 // CHECK8: __Thumbv7ABSLongThunk_tfunc15:
-// CHECK8-NEXT:  1f00004:       40 f2 01 0c     movw    r12, #1
-// CHECK8-NEXT:  1f00008:       c0 f2 10 1c     movt    r12, #272
-// CHECK8-NEXT:  1f0000c:       60 47   bx      r12
+// CHECK8-NEXT:  1f00004:       ff f5 fc 97     b.w     #-14680072 <tfunc15>
 // CHECK8: __Thumbv7ABSLongThunk_tfunc16:
-// CHECK8-NEXT:  1f0000e:       40 f2 01 0c     movw    r12, #1
-// CHECK8-NEXT:  1f00012:       c0 f2 20 1c     movt    r12, #288
-// CHECK8-NEXT:  1f00016:       60 47   bx      r12
+// CHECK8-NEXT:  1f00008:       ff f6 fa 97     b.w     #-13631500 <tfunc16>
  FUNCTION 30
  FUNCTION 31
  FUNCTION 32
@@ -148,7 +138,7 @@ _start:
 // CHECK9: tfunc32:
 // CHECK9:  2200000:    70 47   bx      lr
 // CHECK9-NEXT:  2200002:       ff f4 ff ff     bl      #-3145730
-// CHECK9-NEXT:  2200006:       00 f5 02 f8     bl      #-3145724
+// CHECK9-NEXT:  2200006:       ff f4 ff ff     bl      #-3145730
 
  FUNCTION 33
  bl tfunc15
@@ -156,4 +146,4 @@ _start:
 // CHECK10: tfunc33:
 // CHECK10:  2300000:   70 47   bx      lr
 // CHECK10-NEXT:  2300002:      ff f7 ff f7     bl      #-4194306
-// CHECK10-NEXT:  2300006:      00 f4 02 f8     bl      #-4194300
+// CHECK10-NEXT:  2300006:      ff f7 ff f7     bl      #-4194306

Modified: lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s (original)
+++ lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s Thu Mar 29 15:43:52 2018
@@ -2,7 +2,7 @@
 // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
-// RUN: llvm-objdump -d %t2 -start-address=16846860 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
+// RUN: llvm-objdump -d %t2 -start-address=16846856 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
  .syntax unified
  .global _start, foo
  .type _start, %function
@@ -20,13 +20,11 @@ foo:
 // CHECK1-NEXT: _start:
 // CHECK1-NEXT:    11000:       ff f7 fe ff     bl      #-4
 // CHECK1: __Thumbv7ABSLongThunk__start:
-// CHECK1-NEXT:    11004:       41 f2 01 0c     movw    r12, #4097
-// CHECK1-NEXT:    11008:       c0 f2 01 0c     movt    r12, #1
-// CHECK1-NEXT:    1100c:       60 47   bx      r12
+// CHECK1-NEXT:    11004:       ff f7 fc bf     b.w     #-8 <_start>
 
 // CHECK2: __Thumbv7ABSLongThunk__start:
-// CHECK2:       101100c:       41 f2 01 0c     movw    r12, #4097
-// CHECK2-NEXT:  1011010:       c0 f2 01 0c     movt    r12, #1
-// CHECK2-NEXT:  1011014:       60 47   bx      r12
+// CHECK2:       1011008:       41 f2 01 0c     movw    r12, #4097
+// CHECK2-NEXT:  101100c:       c0 f2 01 0c     movt    r12, #1
+// CHECK2-NEXT:  1011010:       60 47   bx      r12
 // CHECK2: foo:
-// CHECK2-NEXT:  1011016:       ff f7 f9 ff     bl      #-14
+// CHECK2-NEXT:  1011012:       ff f7 f9 ff     bl      #-14

Modified: lld/trunk/test/ELF/arm-thunk-largesection.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-largesection.s?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-largesection.s (original)
+++ lld/trunk/test/ELF/arm-thunk-largesection.s Thu Mar 29 15:43:52 2018
@@ -2,9 +2,9 @@
 // RUN: ld.lld %t -o %t2 2>&1
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=73732 -stop-address=73742 %t2 | FileCheck -check-prefix=CHECK2 %s
-// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=16850944 -stop-address=16850948 %t2 | FileCheck -check-prefix=CHECK3 %s
-// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=33628160 -stop-address=33628164 %t2 | FileCheck -check-prefix=CHECK4 %s
-// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=50405364 -stop-address=50405376 %t2 | FileCheck -check-prefix=CHECK5 %s
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=16850936 -stop-address=16850940 %t2 | FileCheck -check-prefix=CHECK3 %s
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=33628152 -stop-address=33628156 %t2 | FileCheck -check-prefix=CHECK4 %s
+// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=50405356 -stop-address=50405376 %t2 | FileCheck -check-prefix=CHECK5 %s
 // REQUIRES: arm
  .syntax unified
  .balign 0x1000
@@ -21,9 +21,7 @@ _start:
 // CHECK1-NEXT:    11002:       00 00   movs    r0, r0
 
 // CHECK2: __Thumbv7ABSLongThunk__start:
-// CHECK2-NEXT:    12004:       41 f2 01 0c     movw    r12, #4097
-// CHECK2-NEXT:    12008:       c0 f2 01 0c     movt    r12, #1
-// CHECK2-NEXT:    1200c:       60 47   bx      r12
+// CHECK2-NEXT:    12004:       fe f7 fc bf     b.w     #-4104 <_start>
 
 // Gigantic section where we need a ThunkSection either side of it
  .section .text.large1, "ax", %progbits
@@ -33,10 +31,10 @@ _start:
  .space (16 * 1024 * 1024) - 4
  bl _start
  .space (16 * 1024 * 1024) - 16
-// CHECK3: 1012000:     00 f4 00 d0     bl      #-16777216
-// CHECK4: 2012000:     ff f3 f8 d7     bl      #16777200
+// CHECK3: 1011ff8:     00 f4 04 d0     bl      #-16777208
+// CHECK4: 2011ff8:     ff f3 f8 d7     bl      #16777200
 
 // CHECK5: __Thumbv7ABSLongThunk__start:
-// CHECK5-NEXT:  3011ff4:       41 f2 01 0c     movw    r12, #4097
-// CHECK5-NEXT:  3011ff8:       c0 f2 01 0c     movt    r12, #1
-// CHECK5-NEXT:  3011ffc:       60 47   bx      r12
+// CHECK5-NEXT:  3011fec:       41 f2 01 0c     movw    r12, #4097
+// CHECK5-NEXT:  3011ff0:       c0 f2 01 0c     movt    r12, #1
+// CHECK5-NEXT:  3011ff4:       60 47   bx      r12

Modified: lld/trunk/test/ELF/arm-thunk-linkerscript-large.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-linkerscript-large.s?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-linkerscript-large.s (original)
+++ lld/trunk/test/ELF/arm-thunk-linkerscript-large.s Thu Mar 29 15:43:52 2018
@@ -79,9 +79,7 @@ _start:
  FUNCTIONL 08
  FUNCTIONL 09
 // CHECK3: __Thumbv7ABSLongThunk_tfuncl24:
-// CHECK3-NEXT:   b00004:	40 f2 01 0c 	movw	r12, #1
-// CHECK3-NEXT:   b00008:	c0 f2 a0 1c 	movt	r12, #416
-// CHECK3-NEXT:   b0000c:	60 47 	bx	r12
+// CHECK3-NEXT:   b00004:      ff f2 fc 97     b.w     #15728632 <tfuncl24>
  FUNCTIONL 10
  FUNCTIONL 11
  FUNCTIONL 12

Modified: lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s (original)
+++ lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s Thu Mar 29 15:43:52 2018
@@ -41,9 +41,7 @@ tfunc\suff\():
  FUNCTION 16
  FUNCTION 15
 // CHECK2: __Thumbv7ABSLongThunk_tfunc31:
-// CHECK2-NEXT:  1000004:       40 f2 01 0c     movw    r12, #1
-// CHECK2-NEXT:  1000008:       c0 f2 00 2c     movt    r12, #512
-// CHECK2-NEXT:  100000c:       60 47   bx      r12
+// CHECK2-NEXT:  1000004:       ff f3 fc 97     b.w     #16777208 <tfunc31>
  FUNCTION 14
  FUNCTION 13
  FUNCTION 12

Modified: lld/trunk/test/ELF/arm-thunk-multipass.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-multipass.s?rev=328846&r1=328845&r2=328846&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-multipass.s (original)
+++ lld/trunk/test/ELF/arm-thunk-multipass.s Thu Mar 29 15:43:52 2018
@@ -5,7 +5,7 @@
 // parts we need to speed up the test and avoid a large output file
 // RUN: llvm-objdump -d %t2 -start-address=1048578 -stop-address=1048586 -triple=thumbv7a-linux-gnueabihf  | FileCheck -check-prefix=CHECK1 %s
 // RUN: llvm-objdump -d %t2 -start-address=16777224 -stop-address=16777254 -triple=thumbv7a-linux-gnueabihf  | FileCheck -check-prefix=CHECK2 %s
-// RUN: llvm-objdump -d %t2 -start-address=17825818 -stop-address=17825828 -triple=thumbv7a-linux-gnueabihf  | FileCheck -check-prefix=CHECK3 %s
+// RUN: llvm-objdump -d %t2 -start-address=17825812 -stop-address=17825826 -triple=thumbv7a-linux-gnueabihf  | FileCheck -check-prefix=CHECK3 %s
 // In this test case a branch that is in range and does not need its range
 // extended can be pushed out of range by another Thunk, necessitating another
 // pass
@@ -64,19 +64,15 @@ arm_target:
 // CHECK2-NEXT:  100000c:       c0 f2 00 1c     movt    r12, #256
 // CHECK2-NEXT:  1000010:       60 47   bx      r12
 // CHECK2: __Thumbv7ABSLongThunk_target:
-// CHECK2-NEXT:  1000012:       40 f2 1b 0c     movw    r12, #27
-// CHECK2-NEXT:  1000016:       c0 f2 10 1c     movt    r12, #272
-// CHECK2-NEXT:  100001a:       60 47   bx      r12
+// CHECK2-NEXT:  1000012:       ff f0 ff bf     b.w     #1048574 <target>
 // CHECK2: __Thumbv7ABSLongThunk_target2:
-// CHECK2-NEXT:  100001c:       40 f2 13 0c     movw    r12, #19
-// CHECK2-NEXT:  1000020:       c0 f2 10 0c     movt    r12, #16
-// CHECK2-NEXT:  1000024:       60 47   bx      r12
+// CHECK2-NEXT:  1000016:       ff f4 fc 97     b.w     #-15728648 <target2>
 
  .section .text.17, "ax", %progbits
 // Just enough space so that bl target is in range if no extension thunks are
 // generated.
 
- .space 0x100000 - 12
+ .space 0x100000 - 6
 
  .section .text.18, "ax", %progbits
  .thumb
@@ -90,7 +86,7 @@ target:
  nop
  bx lr
 // CHECK3: target:
-// CHECK3-NEXT:  110001a:       ff f6 ff ff     bl      #-1048578
-// CHECK3-NEXT:  110001e:       00 bf   nop
-// CHECK3-NEXT:  1100020:       00 bf   nop
-// CHECK3-NEXT:  1100022:       70 47   bx      lr
+// CHECK3-NEXT:  1100014:       ff f6 ff ff     bl      #-1048578
+// CHECK3-NEXT:  1100018:       00 bf   nop
+// CHECK3-NEXT:  110001a:       00 bf   nop
+// CHECK3-NEXT:  110001c:       70 47   bx      lr




More information about the llvm-commits mailing list