Peter Smith | 3cec2ef | 2017-10-27 09:07:10 +0000 | [diff] [blame] | 1 | // REQUIRES: arm |
| 2 | // RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t |
| 3 | // RUN: ld.lld %t -o %t2 2>&1 |
| 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=524288 -stop-address=524316 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s |
| 7 | // RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048584 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s |
| 8 | // RUN: llvm-objdump -d %t2 -start-address=1572864 -stop-address=1572872 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s |
| 9 | // RUN: llvm-objdump -d %t2 -start-address=5242884 -stop-address=5242894 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s |
| 10 | // RUN: llvm-objdump -d %t2 -start-address=5767168 -stop-address=5767174 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s |
| 11 | // RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777240 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s |
| 12 | // RUN: llvm-objdump -d %t2 -start-address=17825792 -stop-address=17825798 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s |
| 13 | // Test Range extension Thunks for the Thumb conditional branch instruction. |
| 14 | // This instruction only has a range of 1Mb whereas all the other Thumb wide |
| 15 | // Branch instructions have 16Mb range. We still place our pre-created Thunk |
| 16 | // Sections at 16Mb intervals as conditional branches to a target defined |
| 17 | // in a different section are rare. |
| 18 | .syntax unified |
| 19 | // Define a function aligned on a half megabyte boundary |
| 20 | .macro FUNCTION suff |
| 21 | .section .text.\suff\(), "ax", %progbits |
| 22 | .thumb |
| 23 | .balign 0x80000 |
| 24 | .globl tfunc\suff\() |
| 25 | .type tfunc\suff\(), %function |
| 26 | tfunc\suff\(): |
| 27 | bx lr |
| 28 | .endm |
| 29 | |
| 30 | .globl _start |
| 31 | _start: |
| 32 | FUNCTION 00 |
| 33 | // Long Range Thunk needed for 16Mb range branch, can reach pre-created Thunk |
| 34 | // Section |
| 35 | bl tfunc33 |
| 36 | // CHECK1: Disassembly of section .text: |
| 37 | // CHECK1-NEXT: tfunc00: |
| 38 | // CHECK1-NEXT: 80000: 70 47 bx lr |
| 39 | // CHECK1-NEXT: 80002: 7f f3 ff d7 bl #16252926 |
| 40 | // CHECK1: __Thumbv7ABSLongThunk_tfunc05: |
| 41 | // CHECK1-NEXT: 80008: 40 f2 01 0c movw r12, #1 |
| 42 | // CHECK1-NEXT: 8000c: c0 f2 30 0c movt r12, #48 |
| 43 | // CHECK1-NEXT: 80010: 60 47 bx r12 |
| 44 | // CHECK1: __Thumbv7ABSLongThunk_tfunc00: |
| 45 | // CHECK1-NEXT: 80012: 40 f2 01 0c movw r12, #1 |
| 46 | // CHECK1-NEXT: 80016: c0 f2 08 0c movt r12, #8 |
| 47 | // CHECK1-NEXT: 8001a: 60 47 bx r12 |
| 48 | FUNCTION 01 |
| 49 | // tfunc02 is within range of tfunc02 |
| 50 | beq.w tfunc02 |
| 51 | // tfunc05 is out of range, and we can't reach the pre-created Thunk Section |
| 52 | // create a new one. |
| 53 | bne.w tfunc05 |
| 54 | // CHECK2: tfunc01: |
| 55 | // CHECK2-NEXT: 100000: 70 47 bx lr |
| 56 | // CHECK2-NEXT: 100002: 3f f0 fd a7 beq.w #524282 <tfunc02> |
| 57 | // CHECK2-NEXT: 100006: 7f f4 ff a7 bne.w #-524290 <__Thumbv7ABSLongThunk_tfunc05> |
| 58 | FUNCTION 02 |
| 59 | // We can reach the Thunk Section created for bne.w tfunc05 |
| 60 | bne.w tfunc05 |
| 61 | beq.w tfunc00 |
| 62 | // CHECK3: 180000: 70 47 bx lr |
| 63 | // CHECK3-NEXT: 180002: 40 f4 01 80 bne.w #-1048574 <__Thumbv7ABSLongThunk_tfunc05> |
| 64 | // CHECK3-NEXT: 180006: 00 f4 04 80 beq.w #-1048568 <__Thumbv7ABSLongThunk_tfunc00> |
| 65 | FUNCTION 03 |
| 66 | FUNCTION 04 |
| 67 | FUNCTION 05 |
| 68 | FUNCTION 06 |
| 69 | FUNCTION 07 |
| 70 | FUNCTION 08 |
| 71 | FUNCTION 09 |
| 72 | // CHECK4: __Thumbv7ABSLongThunk_tfunc03: |
| 73 | // CHECK4-NEXT: 500004: 40 f2 01 0c movw r12, #1 |
| 74 | // CHECK4-NEXT: 500008: c0 f2 20 0c movt r12, #32 |
| 75 | // CHECK4-NEXT: 50000c: 60 47 bx r12 |
| 76 | FUNCTION 10 |
| 77 | // We can't reach any Thunk Section, create a new one |
| 78 | beq.w tfunc03 |
| 79 | // CHECK5: tfunc10: |
| 80 | // CHECK5-NEXT: 580000: 70 47 bx lr |
| 81 | // CHECK5-NEXT: 580002: 3f f4 ff a7 beq.w #-524290 <__Thumbv7ABSLongThunk_tfunc03> |
| 82 | FUNCTION 11 |
| 83 | FUNCTION 12 |
| 84 | FUNCTION 13 |
| 85 | FUNCTION 14 |
| 86 | FUNCTION 15 |
| 87 | FUNCTION 16 |
| 88 | FUNCTION 17 |
| 89 | FUNCTION 18 |
| 90 | FUNCTION 19 |
| 91 | FUNCTION 20 |
| 92 | FUNCTION 21 |
| 93 | FUNCTION 22 |
| 94 | FUNCTION 23 |
| 95 | FUNCTION 24 |
| 96 | FUNCTION 25 |
| 97 | FUNCTION 26 |
| 98 | FUNCTION 27 |
| 99 | FUNCTION 28 |
| 100 | FUNCTION 29 |
| 101 | FUNCTION 30 |
| 102 | FUNCTION 31 |
| 103 | // CHECK6: __Thumbv7ABSLongThunk_tfunc33: |
| 104 | // CHECK6-NEXT: 1000004: 40 f2 01 0c movw r12, #1 |
| 105 | // CHECK6-NEXT: 1000008: c0 f2 10 1c movt r12, #272 |
| 106 | // CHECK6-NEXT: 100000c: 60 47 bx r12 |
| 107 | // CHECK6: __Thumbv7ABSLongThunk_tfunc00: |
| 108 | // CHECK6-NEXT: 100000e: 40 f2 01 0c movw r12, #1 |
| 109 | // CHECK6-NEXT: 1000012: c0 f2 08 0c movt r12, #8 |
| 110 | // CHECK6-NEXT: 1000016: 60 47 bx r12 |
| 111 | FUNCTION 32 |
| 112 | FUNCTION 33 |
| 113 | // We should be able to reach an existing ThunkSection. |
| 114 | b.w tfunc00 |
| 115 | // CHECK7: tfunc33: |
| 116 | // CHECK7-NEXT: 1100000: 70 47 bx lr |
| 117 | // CHECK7-NEXT: 1100002: 00 f7 04 b8 b.w #-1048568 <__Thumbv7ABSLongThunk_tfunc00> |