1// REQUIRES: arm
2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2
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
17
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
24 .syntax unified
25
26// Define a function aligned on a megabyte boundary
27 .macro ARMFUNCTION suff
28 .section .text.\suff\(), "ax", %progbits
29 .arm
30 .balign 0x100000
31 .globl afunc\suff\()
32 .type  afunc\suff\(), %function
33afunc\suff\():
34 bx lr
35 .endm
36
37// Define a function aligned on a megabyte boundary
38 .macro THUMBFUNCTION suff
39 .section .text.\suff\(), "ax", %progbits
40 .thumb
41 .balign 0x100000
42 .globl tfunc\suff\()
43 .type  tfunc\suff\(), %function
44tfunc\suff\():
45 bx lr
46 .endm
47
48 .section .text, "ax", %progbits
49 .thumb
50 .globl _start
51_start:
52
53 ARMFUNCTION 00
54// Expect ARM bl to be in range (can use blx to change state)
55 bl tfunc31
56// ARM b and beq are in range but need Thunk to change state to Thumb
57 b  tfunc31
58 beq tfunc31
59// afunc32 is out of range of ARM branch and branch and link
60 bl afunc32
61 b  afunc32
62 bne afunc32
63// CHECK1:  <afunc00>:
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
71 THUMBFUNCTION 01
72// Expect Thumb bl to be in range (can use blx to change state)
73 bl afunc14
74// In range but need thunk to change state to Thumb
75 b.w afunc14
76// CHECK2: <tfunc01>:
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>
80
81 ARMFUNCTION 02
82 THUMBFUNCTION 03
83 ARMFUNCTION 04
84 THUMBFUNCTION 05
85 ARMFUNCTION 06
86 THUMBFUNCTION 07
87 ARMFUNCTION 08
88 THUMBFUNCTION 09
89 ARMFUNCTION 10
90 THUMBFUNCTION 11
91 ARMFUNCTION 12
92 THUMBFUNCTION 13
93 ARMFUNCTION 14
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
102 THUMBFUNCTION 15
103 ARMFUNCTION 16
104 THUMBFUNCTION 17
105 ARMFUNCTION 18
106 THUMBFUNCTION 19
107 ARMFUNCTION 20
108 THUMBFUNCTION 21
109 ARMFUNCTION 22
110 THUMBFUNCTION 23
111 ARMFUNCTION 24
112 THUMBFUNCTION 25
113 ARMFUNCTION 26
114 THUMBFUNCTION 27
115 ARMFUNCTION 28
116 THUMBFUNCTION 29
117 ARMFUNCTION 30
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
123 THUMBFUNCTION 31
124 ARMFUNCTION 32
125 THUMBFUNCTION 33
126// Out of range, can only reach closest Thunk Section
127 bl afunc00
128// CHECK6:  <tfunc33>:
129// CHECK6-NEXT:  2200000:       70 47   bx      lr
130// CHECK6-NEXT:  2200002:       ff f4 ff ff     bl      #-3145730
131 ARMFUNCTION 34
132// Out of range, can reach earlier Thunk Section
133// CHECK7:  <afunc34>:
134// CHECK7-NEXT:  2300000:       1e ff 2f e1     bx      lr
135// CHECK7-NEXT:  2300004:       fe ff ef fa     blx     #-4194312 <__Thumbv7ABSLongThunk_afunc00
136 bl afunc00
137 THUMBFUNCTION 35
138 ARMFUNCTION 36
139 THUMBFUNCTION 37
140 ARMFUNCTION 38
141 THUMBFUNCTION 39
142 ARMFUNCTION 40
143 THUMBFUNCTION 41
144 ARMFUNCTION 42
145 THUMBFUNCTION 43
146 ARMFUNCTION 44
147 THUMBFUNCTION 45
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
153 ARMFUNCTION 46
154 THUMBFUNCTION 47
155 ARMFUNCTION 48
156 THUMBFUNCTION 49
157 ARMFUNCTION 50
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>
165 THUMBFUNCTION 51
166 ARMFUNCTION 52
167 THUMBFUNCTION 53
168 ARMFUNCTION 54
169 THUMBFUNCTION 55
170 ARMFUNCTION 56
171 THUMBFUNCTION 57
172 ARMFUNCTION 58
173 THUMBFUNCTION 59
174 ARMFUNCTION 60
175 THUMBFUNCTION 61
176 ARMFUNCTION 62
177 THUMBFUNCTION 63
178 ARMFUNCTION 64
179// afunc34 is in range, as is tfunc35 but a branch needs a state change Thunk
180 bl afunc34
181 b  tfunc35
182// CHECK10: <afunc64>:
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>
186 THUMBFUNCTION 65
187// afunc34 and tfunc35 are both out of range
188 bl afunc34
189 bl tfunc35
190// CHECK11: <tfunc65>:
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
194