194 lines
7.3 KiB
ArmAsm
194 lines
7.3 KiB
ArmAsm
// REQUIRES: arm
|
|
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
|
|
// RUN: ld.lld %t -o %t2 2>&1
|
|
// 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
|