2 // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3 // RUN: ld.lld %t -o %t2 2>&1
4 // The output file is large, most of it zeroes. We dissassemble only the
5 // parts we need to speed up the test and avoid a large output file
6 // RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048604 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
7 // RUN: llvm-objdump -d %t2 -start-address=2097152 -stop-address=2097162 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
8 // RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777232 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s
9 // RUN: llvm-objdump -d %t2 -start-address=16777232 -stop-address=16777242 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s
10 // RUN: llvm-objdump -d %t2 -start-address=32505860 -stop-address=32505870 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s
11 // RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651590 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s
12 // RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700168 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s
13 // RUN: llvm-objdump -d %t2 -start-address=48234500 -stop-address=48234512 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s
14 // RUN: llvm-objdump -d %t2 -start-address=53477380 -stop-address=53477392 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s
15 // RUN: llvm-objdump -d %t2 -start-address=68157440 -stop-address=68157452 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s
16 // RUN: llvm-objdump -d %t2 -start-address=69206016 -stop-address=69206024 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK11 %s
18 // Test the Range extension Thunks for ARM and Thumb when all the code is in a
19 // single OutputSection. The ARM branches and branch and link instructions
20 // have a range of 32Mb, the Thumb unconditional branch and
21 // branch and link instructions have . We create a series of Functions a
22 // megabyte apart. We expect range extension thunks to be created when a
23 // branch is out of range. Thunks will be reused whenever they are in range
26 // Define a function aligned on a megabyte boundary
27 .macro ARMFUNCTION suff
28 .section .text.\suff\(), "ax", %progbits
32 .type afunc\suff\(), %function
37 // Define a function aligned on a megabyte boundary
38 .macro THUMBFUNCTION suff
39 .section .text.\suff\(), "ax", %progbits
43 .type tfunc\suff\(), %function
48 .section .text, "ax", %progbits
54 // Expect ARM bl to be in range (can use blx to change state)
56 // ARM b and beq are in range but need Thunk to change state to Thumb
59 // afunc32 is out of range of ARM branch and branch and link
64 // CHECK1-NEXT: 100000: 1e ff 2f e1 bx lr
65 // CHECK1-NEXT: 100004: fd ff 7b fa blx #32505844
66 // CHECK1-NEXT: 100008: fd ff 3b ea b #15728628
67 // CHECK1-NEXT: 10000c: fc ff 3b 0a beq #15728624
68 // CHECK1-NEXT: 100010: fa ff 7f eb bl #33554408
69 // CHECK1-NEXT: 100014: f9 ff 7f ea b #33554404
70 // CHECK1-NEXT: 100018: f8 ff 7f 1a bne #33554400
72 // Expect Thumb bl to be in range (can use blx to change state)
74 // In range but need thunk to change state to Thumb
77 // CHECK2-NEXT: 200000: 70 47 bx lr
78 // CHECK2-NEXT: 200002: ff f0 fe c7 blx #13631484
79 // CHECK2-NEXT: 200006: 00 f2 03 90 b.w #14680070 <__Thumbv7ABSLongThunk_afunc14>
94 // CHECK3: __ARMv7ABSLongThunk_tfunc31:
95 // CHECK3-NEXT: 1000004: 01 c0 00 e3 movw r12, #1
96 // CHECK3-NEXT: 1000008: 00 c2 40 e3 movt r12, #512
97 // CHECK3-NEXT: 100000c: 1c ff 2f e1 bx r12
98 // CHECK4: __Thumbv7ABSLongThunk_afunc14:
99 // CHECK4-NEXT: 1000010: 40 f2 00 0c movw r12, #0
100 // CHECK4-NEXT: 1000014: c0 f2 f0 0c movt r12, #240
101 // CHECK4-NEXT: 1000018: 60 47 bx r12
118 // Expect precreated Thunk Section here
119 // CHECK5: __Thumbv7ABSLongThunk_afunc00:
120 // CHECK5-NEXT: 1f00004: 40 f2 00 0c movw r12, #0
121 // CHECK5-NEXT: 1f00008: c0 f2 10 0c movt r12, #16
122 // CHECK5-NEXT: 1f0000c: 60 47 bx r12
126 // Out of range, can only reach closest Thunk Section
129 // CHECK6-NEXT: 2200000: 70 47 bx lr
130 // CHECK6-NEXT: 2200002: ff f4 ff ff bl #-3145730
132 // Out of range, can reach earlier Thunk Section
134 // CHECK7-NEXT: 2300000: 1e ff 2f e1 bx lr
135 // CHECK7-NEXT: 2300004: fe ff ef fa blx #-4194312 <__Thumbv7ABSLongThunk_afunc00
148 // Expect precreated Thunk Section here
149 // CHECK8: __ARMv7ABSLongThunk_tfunc35:
150 // CHECK8-NEXT: 2e00004: 01 c0 00 e3 movw r12, #1
151 // CHECK8-NEXT: 2e00008: 40 c2 40 e3 movt r12, #576
152 // CHECK8-NEXT: 2e0000c: 1c ff 2f e1 bx r12
158 // Expect precreated Thunk Section here
159 // CHECK9: __Thumbv7ABSLongThunk_afunc34:
160 // CHECK9-NEXT: 3300004: 40 f2 00 0c movw r12, #0
161 // CHECK9-NEXT: 3300008: c0 f2 30 2c movt r12, #560
162 // CHECK9-NEXT: 330000c: 60 47 bx r12
163 // CHECK9: __Thumbv7ABSLongThunk_tfunc35:
164 // CHECK9-NEXT: 330000e: ff f4 f7 97 b.w #-15728658 <tfunc35>
179 // afunc34 is in range, as is tfunc35 but a branch needs a state change Thunk
183 // CHECK10-NEXT: 4100000: 1e ff 2f e1 bx lr
184 // CHECK10-NEXT: 4100004: fd ff 87 eb bl #-31457292 <afunc34>
185 // CHECK10-NEXT: 4100008: fd ff b3 ea b #-19922956 <__ARMv7ABSLongThunk_tfunc35>
187 // afunc34 and tfunc35 are both out of range
191 // CHECK11: 4200000: 70 47 bx lr
192 // CHECK11-NEXT: 4200002: ff f4 ff d7 bl #-15728642
193 // CHECK11-NEXT: 4200006: 00 f5 02 d0 bl #-15728636