arm-thumb-mix-range-thunk-os.s
7.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// REQUIRES: arm
// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o %t2
// The output file is large, most of it zeroes. We dissassemble only the
// parts we need to speed up the test and avoid a large output file
// RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048604 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
// RUN: llvm-objdump -d %t2 -start-address=2097152 -stop-address=2097162 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
// RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777232 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s
// RUN: llvm-objdump -d %t2 -start-address=16777232 -stop-address=16777242 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s
// RUN: llvm-objdump -d %t2 -start-address=32505860 -stop-address=32505870 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s
// RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651590 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s
// RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700168 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s
// RUN: llvm-objdump -d %t2 -start-address=48234500 -stop-address=48234512 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s
// RUN: llvm-objdump -d %t2 -start-address=53477380 -stop-address=53477392 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s
// RUN: llvm-objdump -d %t2 -start-address=68157440 -stop-address=68157452 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s
// RUN: llvm-objdump -d %t2 -start-address=69206016 -stop-address=69206024 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK11 %s
// Test the Range extension Thunks for ARM and Thumb when all the code is in a
// single OutputSection. The ARM branches and branch and link instructions
// have a range of 32Mb, the Thumb unconditional branch and
// branch and link instructions have . We create a series of Functions a
// megabyte apart. We expect range extension thunks to be created when a
// branch is out of range. Thunks will be reused whenever they are in range
.syntax unified
// Define a function aligned on a megabyte boundary
.macro ARMFUNCTION suff
.section .text.\suff\(), "ax", %progbits
.arm
.balign 0x100000
.globl afunc\suff\()
.type afunc\suff\(), %function
afunc\suff\():
bx lr
.endm
// Define a function aligned on a megabyte boundary
.macro THUMBFUNCTION suff
.section .text.\suff\(), "ax", %progbits
.thumb
.balign 0x100000
.globl tfunc\suff\()
.type tfunc\suff\(), %function
tfunc\suff\():
bx lr
.endm
.section .text, "ax", %progbits
.thumb
.globl _start
_start:
ARMFUNCTION 00
// Expect ARM bl to be in range (can use blx to change state)
bl tfunc31
// ARM b and beq are in range but need Thunk to change state to Thumb
b tfunc31
beq tfunc31
// afunc32 is out of range of ARM branch and branch and link
bl afunc32
b afunc32
bne afunc32
// CHECK1: afunc00:
// CHECK1-NEXT: 100000: 1e ff 2f e1 bx lr
// CHECK1-NEXT: 100004: fd ff 7b fa blx #32505844
// CHECK1-NEXT: 100008: fd ff 3b ea b #15728628
// CHECK1-NEXT: 10000c: fc ff 3b 0a beq #15728624
// CHECK1-NEXT: 100010: fa ff 7f eb bl #33554408
// CHECK1-NEXT: 100014: f9 ff 7f ea b #33554404
// CHECK1-NEXT: 100018: f8 ff 7f 1a bne #33554400
THUMBFUNCTION 01
// Expect Thumb bl to be in range (can use blx to change state)
bl afunc14
// In range but need thunk to change state to Thumb
b.w afunc14
// CHECK2: tfunc01:
// CHECK2-NEXT: 200000: 70 47 bx lr
// CHECK2-NEXT: 200002: ff f0 fe c7 blx #13631484
// CHECK2-NEXT: 200006: 00 f2 03 90 b.w #14680070 <__Thumbv7ABSLongThunk_afunc14>
ARMFUNCTION 02
THUMBFUNCTION 03
ARMFUNCTION 04
THUMBFUNCTION 05
ARMFUNCTION 06
THUMBFUNCTION 07
ARMFUNCTION 08
THUMBFUNCTION 09
ARMFUNCTION 10
THUMBFUNCTION 11
ARMFUNCTION 12
THUMBFUNCTION 13
ARMFUNCTION 14
// CHECK3: __ARMv7ABSLongThunk_tfunc31:
// CHECK3-NEXT: 1000004: 01 c0 00 e3 movw r12, #1
// CHECK3-NEXT: 1000008: 00 c2 40 e3 movt r12, #512
// CHECK3-NEXT: 100000c: 1c ff 2f e1 bx r12
// CHECK4: __Thumbv7ABSLongThunk_afunc14:
// CHECK4-NEXT: 1000010: 40 f2 00 0c movw r12, #0
// CHECK4-NEXT: 1000014: c0 f2 f0 0c movt r12, #240
// CHECK4-NEXT: 1000018: 60 47 bx r12
THUMBFUNCTION 15
ARMFUNCTION 16
THUMBFUNCTION 17
ARMFUNCTION 18
THUMBFUNCTION 19
ARMFUNCTION 20
THUMBFUNCTION 21
ARMFUNCTION 22
THUMBFUNCTION 23
ARMFUNCTION 24
THUMBFUNCTION 25
ARMFUNCTION 26
THUMBFUNCTION 27
ARMFUNCTION 28
THUMBFUNCTION 29
ARMFUNCTION 30
// Expect precreated Thunk Section here
// CHECK5: __Thumbv7ABSLongThunk_afunc00:
// CHECK5-NEXT: 1f00004: 40 f2 00 0c movw r12, #0
// CHECK5-NEXT: 1f00008: c0 f2 10 0c movt r12, #16
// CHECK5-NEXT: 1f0000c: 60 47 bx r12
THUMBFUNCTION 31
ARMFUNCTION 32
THUMBFUNCTION 33
// Out of range, can only reach closest Thunk Section
bl afunc00
// CHECK6: tfunc33:
// CHECK6-NEXT: 2200000: 70 47 bx lr
// CHECK6-NEXT: 2200002: ff f4 ff ff bl #-3145730
ARMFUNCTION 34
// Out of range, can reach earlier Thunk Section
// CHECK7: afunc34:
// CHECK7-NEXT: 2300000: 1e ff 2f e1 bx lr
// CHECK7-NEXT: 2300004: fe ff ef fa blx #-4194312 <__Thumbv7ABSLongThunk_afunc00
bl afunc00
THUMBFUNCTION 35
ARMFUNCTION 36
THUMBFUNCTION 37
ARMFUNCTION 38
THUMBFUNCTION 39
ARMFUNCTION 40
THUMBFUNCTION 41
ARMFUNCTION 42
THUMBFUNCTION 43
ARMFUNCTION 44
THUMBFUNCTION 45
// Expect precreated Thunk Section here
// CHECK8: __ARMv7ABSLongThunk_tfunc35:
// CHECK8-NEXT: 2e00004: 01 c0 00 e3 movw r12, #1
// CHECK8-NEXT: 2e00008: 40 c2 40 e3 movt r12, #576
// CHECK8-NEXT: 2e0000c: 1c ff 2f e1 bx r12
ARMFUNCTION 46
THUMBFUNCTION 47
ARMFUNCTION 48
THUMBFUNCTION 49
ARMFUNCTION 50
// Expect precreated Thunk Section here
// CHECK9: __Thumbv7ABSLongThunk_afunc34:
// CHECK9-NEXT: 3300004: 40 f2 00 0c movw r12, #0
// CHECK9-NEXT: 3300008: c0 f2 30 2c movt r12, #560
// CHECK9-NEXT: 330000c: 60 47 bx r12
// CHECK9: __Thumbv7ABSLongThunk_tfunc35:
// CHECK9-NEXT: 330000e: ff f4 f7 97 b.w #-15728658 <tfunc35>
THUMBFUNCTION 51
ARMFUNCTION 52
THUMBFUNCTION 53
ARMFUNCTION 54
THUMBFUNCTION 55
ARMFUNCTION 56
THUMBFUNCTION 57
ARMFUNCTION 58
THUMBFUNCTION 59
ARMFUNCTION 60
THUMBFUNCTION 61
ARMFUNCTION 62
THUMBFUNCTION 63
ARMFUNCTION 64
// afunc34 is in range, as is tfunc35 but a branch needs a state change Thunk
bl afunc34
b tfunc35
// CHECK10: afunc64:
// CHECK10-NEXT: 4100000: 1e ff 2f e1 bx lr
// CHECK10-NEXT: 4100004: fd ff 87 eb bl #-31457292 <afunc34>
// CHECK10-NEXT: 4100008: fd ff b3 ea b #-19922956 <__ARMv7ABSLongThunk_tfunc35>
THUMBFUNCTION 65
// afunc34 and tfunc35 are both out of range
bl afunc34
bl tfunc35
// CHECK11: tfunc65:
// CHECK11: 4200000: 70 47 bx lr
// CHECK11-NEXT: 4200002: ff f4 ff d7 bl #-15728642
// CHECK11-NEXT: 4200006: 00 f5 02 d0 bl #-15728636