134 lines · plain
1// REQUIRES: arm2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv4t-none-linux-gnueabi %s -o %t.o3// RUN: ld.lld %t.o -o %t24/// The output file is large, most of it zeroes. We dissassemble only the5/// parts we need to speed up the test and avoid a large output file.6// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0x100000 --stop-address=0x10000c | FileCheck --check-prefix=CHECK1 %s7// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0x200000 --stop-address=0x200002 | FileCheck --check-prefix=CHECK2 %s8// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0x300000 --stop-address=0x300002 | FileCheck --check-prefix=CHECK3 %s9// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0x400000 --stop-address=0x400028 | FileCheck --check-prefix=CHECK4 %s10// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0x700000 --stop-address=0x700014 | FileCheck --check-prefix=CHECK5 %s11// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0x800000 --stop-address=0x800004 | FileCheck --check-prefix=CHECK6 %s12// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0x900000 --stop-address=0x900004 | FileCheck --check-prefix=CHECK7 %s13// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0xa00000 --stop-address=0xa00018 | FileCheck --check-prefix=CHECK8 %s14// RUN: llvm-objdump --no-show-raw-insn -d %t2 --start-address=0xb00000 --stop-address=0xb00004 | FileCheck --check-prefix=CHECK9 %s15 16/// Test the Range extension Thunks for Thumb when all the code is in a single17/// OutputSection. The Thumb BL instruction has a range of 4Mb. We create a18/// series of functions a megabyte apart. We expect range extension thunks to be19/// created when a branch is out of range. Thunks will be reused whenever they20/// are in range.21.syntax unified22 23/// Define a function aligned on a megabyte boundary.24.macro FUNCTION suff25 .section .text.\suff\(), "ax", %progbits26 .thumb27 .balign 0x10000028 .globl tfunc\suff\()29 .type tfunc\suff\(), %function30 tfunc\suff\():31 bx lr32.endm33 34.section .text, "ax", %progbits35.thumb36.globl _start37_start:38 /// tfunc00 and tfunc03 are within 4MB, so no Range Thunks expected.39 bl tfunc0040 bl tfunc0341 /// tfunc04 is > 4MB away, expect a Range Thunk to be generated, to go into42 /// the first of the pre-created ThunkSections.43 bl tfunc0444 45// CHECK1-LABEL: <_start>:46// CHECK1-NEXT: 100000: bl 0x200000 <tfunc00> @ imm = #0xffffc47// CHECK1-NEXT: bl 0x500000 <tfunc03> @ imm = #0x3ffff848// CHECK1-NEXT: bl 0x400008 <__Thumbv4ABSLongThunk_tfunc04> @ imm = #0x2ffffc49 50FUNCTION 0051// CHECK2-LABEL: <tfunc00>:52// CHECK2-NEXT: 200000: bx lr53 54FUNCTION 0155// CHECK3-LABEL: <tfunc01>:56// CHECK3-NEXT: 300000: bx lr57 58FUNCTION 0259 bl tfunc0760 /// The thunks should not generate a v7-style short thunk.61// CHECK4-LABEL: <tfunc02>:62// CHECK4-NEXT: 400000: bx lr63// CHECK4-NEXT: bl 0x400018 <__Thumbv4ABSLongThunk_tfunc07> @ imm = #0x1264// CHECK4-NEXT: bmi 0x3fffb2 <tfunc01+0xfffb2> @ imm = #-0x5865// CHECK4-EMPTY:66// CHECK4-NEXT: <__Thumbv4ABSLongThunk_tfunc04>:67// CHECK4-NEXT: 400008: bx pc68// CHECK4-NEXT: b 0x400008 <__Thumbv4ABSLongThunk_tfunc04> @ imm = #-0x669// CHECK4-NEXT: 40000c: ldr r12, [pc] @ 0x400014 <__Thumbv4ABSLongThunk_tfunc04+0xc>70// CHECK4-NEXT: bx r1271// CHECK4-NEXT: 400014: 01 00 60 00 .word 0x0060000172// CHECK4-EMPTY:73// CHECK4-NEXT: <__Thumbv4ABSLongThunk_tfunc07>:74// CHECK4-NEXT: 400018: bx pc75// CHECK4-NEXT: b 0x400018 <__Thumbv4ABSLongThunk_tfunc07> @ imm = #-0x676// CHECK4-NEXT: 40001c: ldr r12, [pc] @ 0x400024 <__Thumbv4ABSLongThunk_tfunc07+0xc>77// CHECK4-NEXT: bx r1278// CHECK4-NEXT: 400024: 01 00 90 00 .word 0x0090000179 80FUNCTION 0381FUNCTION 0482FUNCTION 0583// CHECK5-LABEL: <tfunc05>:84// CHECK5-NEXT: 700000: bx lr85// CHECK5-NEXT: bmi 0x6fffae <tfunc04+0xfffae> @ imm = #-0x5886// CHECK5-EMPTY:87// CHECK5-NEXT: <__Thumbv4ABSLongThunk_tfunc03>:88// CHECK5-NEXT: 700004: bx pc89// CHECK5-NEXT: b 0x700004 <__Thumbv4ABSLongThunk_tfunc03> @ imm = #-0x690// CHECK5-NEXT: 700008: ldr r12, [pc] @ 0x700010 <__Thumbv4ABSLongThunk_tfunc03+0xc>91// CHECK5-NEXT: bx r1292// CHECK5-NEXT: 700010: 01 00 50 00 .word 0x0050000193 94FUNCTION 0695 /// The backwards branch is within range, so no range extension necessary.96 bl tfunc0497// CHECK6-LABEL: <tfunc06>:98// CHECK6-NEXT: 800000: bx lr99// CHECK6-NEXT: bl 0x600000 <tfunc04> @ imm = #-0x200006100 101FUNCTION 07102 /// The backwards branch is out of range.103 bl tfunc03104// CHECK7-LABEL: <tfunc07>:105// CHECK7-NEXT: 900000: bx lr106// CHECK7-NEXT: bl 0x700004 <__Thumbv4ABSLongThunk_tfunc03> @ imm = #-0x200002107 108FUNCTION 08109 /// 2nd backwards branch outside of range to same fn. Should share thunk with110 /// previous call.111 bl tfunc03112// CHECK8-LABEL: <tfunc08>:113// CHECK8-NEXT: a00000: bx lr114// CHECK8-NEXT: bl 0x700004 <__Thumbv4ABSLongThunk_tfunc03> @ imm = #-0x300002115// CHECK8-NEXT: bmi 0x9fffb2 <tfunc07+0xfffb2> @ imm = #-0x58116// CHECK8-EMPTY:117// CHECK8-NEXT: <__Thumbv4ABSLongThunk_tfunc03>:118// CHECK8-NEXT: a00008: bx pc119// CHECK8-NEXT: a0000a: b 0xa00008 <__Thumbv4ABSLongThunk_tfunc03> @ imm = #-0x6120// CHECK8-NEXT: a0000c: ldr r12, [pc] @ 0xa00014 <__Thumbv4ABSLongThunk_tfunc03+0xc>121// CHECK8-NEXT: a00010: bx r12122// CHECK8-NEXT: a00014: 01 00 50 00 .word 0x00500001123 124FUNCTION 09125 /// This call is out of range of ThunkSection at 0700004.126 /// These 3 calls to tfunc03 could have used the same thunk (section), but127 /// we are not that sophisticated.128 bl tfunc03129// CHECK9-LABEL: <tfunc09>:130// CHECK9-NEXT: b00000: bx lr131// CHECK9-NEXT: bl 0xa00008 <__Thumbv4ABSLongThunk_tfunc03> @ imm = #-0xffffe132FUNCTION 10133FUNCTION 11134