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 0x2000000 <tfunc31> 66// CHECK1-NEXT: 100008: fd ff 3b ea b 0x1000004 <__ARMv7ABSLongThunk_tfunc31> 67// CHECK1-NEXT: 10000c: fc ff 3b 0a beq 0x1000004 <__ARMv7ABSLongThunk_tfunc31> 68// CHECK1-NEXT: 100010: fa ff 7f eb bl 0x2100000 <afunc32> 69// CHECK1-NEXT: 100014: f9 ff 7f ea b 0x2100000 <afunc32> 70// CHECK1-NEXT: 100018: f8 ff 7f 1a bne 0x2100000 <afunc32> 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 0xf00000 <afunc14> 79// CHECK2-NEXT: 200006: 00 f2 03 90 b.w 0x1000010 <__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 0x1f00004 <__Thumbv7ABSLongThunk_afunc00> 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 0x1f00004 <__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 0x2400000 <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 0x2300000 <afunc34> 185// CHECK10-NEXT: 4100008: fd ff b3 ea b 0x2e00004 <__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 0x3300004 <__Thumbv7ABSLongThunk_afunc34> 193// CHECK11-NEXT: 4200006: 00 f5 02 d0 bl 0x330000e <__Thumbv7ABSLongThunk_tfunc35> 194