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=1048578 --stop-address=1048586 --triple=thumbv7a-linux-gnueabihf  | FileCheck --check-prefix=CHECK1 %s
7// RUN: llvm-objdump -d %t2 --start-address=16777224 --stop-address=16777254 --triple=thumbv7a-linux-gnueabihf  | FileCheck --check-prefix=CHECK2 %s
8// RUN: llvm-objdump -d %t2 --start-address=17825812 --stop-address=17825826 --triple=thumbv7a-linux-gnueabihf  | FileCheck --check-prefix=CHECK3 %s
9// In this test case a branch that is in range and does not need its range
10// extended can be pushed out of range by another Thunk, necessitating another
11// pass
12
13 .macro FUNCTION suff
14 .section .text.\suff\(), "ax", %progbits
15 .thumb
16 .balign 0x100000
17 .globl tfunc\suff\()
18 .type  tfunc\suff\(), %function
19tfunc\suff\():
20 bx lr
21 .endm
22
23 FUNCTION 00
24 .globl _start
25_start:
26 bl target
27 b.w arm_target
28// arm_target is in range but needs an interworking thunk
29// CHECK1: <_start>:
30// CHECK1-NEXT:   100002:       00 f3 06 d0     bl      0x1000012 <__Thumbv7ABSLongThunk_target>
31// CHECK1-NEXT:   100006:       ff f2 ff 97     b.w     0x1000008 <__Thumbv7ABSLongThunk_arm_target>
32 nop
33 nop
34 nop
35 .globl target2
36 .type target2, %function
37        nop
38
39target2:
40 FUNCTION 01
41 FUNCTION 02
42 FUNCTION 03
43 FUNCTION 04
44 FUNCTION 05
45 FUNCTION 06
46 FUNCTION 07
47 FUNCTION 08
48 FUNCTION 09
49 FUNCTION 10
50 FUNCTION 11
51 FUNCTION 12
52 FUNCTION 13
53 FUNCTION 14
54 FUNCTION 15
55
56 .section .text.16, "ax", %progbits
57 .arm
58 .globl arm_target
59 .type arm_target, %function
60arm_target:
61 bx lr
62// CHECK2: <__Thumbv7ABSLongThunk_arm_target>:
63// CHECK2-NEXT:  1000008:       40 f2 02 0c     movw    r12, #2
64// CHECK2-NEXT:  100000c:       c0 f2 00 1c     movt    r12, #256
65// CHECK2-NEXT:  1000010:       60 47   bx      r12
66// CHECK2: <__Thumbv7ABSLongThunk_target>:
67// CHECK2-NEXT:  1000012:       ff f0 ff bf     b.w     0x1100014 <target>
68// CHECK2: <__Thumbv7ABSLongThunk_target2>:
69// CHECK2-NEXT:  1000016:       ff f4 fc 97     b.w     0x100012 <target2>
70
71 .section .text.17, "ax", %progbits
72// Just enough space so that bl target is in range if no extension thunks are
73// generated.
74
75 .space 0x100000 - 6
76
77 .section .text.18, "ax", %progbits
78 .thumb
79 .globl target
80 .type target, %function
81// target is at maximum ARM branch range away from caller.
82target:
83// Similar case in the backwards direction
84 bl target2
85 nop
86 nop
87 bx lr
88// CHECK3: <target>:
89// CHECK3-NEXT:  1100014:       ff f6 ff ff     bl      0x1000016 <__Thumbv7ABSLongThunk_target2>
90// CHECK3-NEXT:  1100018:       00 bf   nop
91// CHECK3-NEXT:  110001a:       00 bf   nop
92// CHECK3-NEXT:  110001c:       70 47   bx      lr
93