Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / MC / ARM / seh.s
blob6cc4cf8ac076a2bd6e520d9a67c0137eaf63d360
1 // This test checks that the SEH directives emit the correct unwind data.
3 // RUN: llvm-mc -triple thumbv7-pc-win32 -filetype=obj %s | llvm-readobj -S -r -u - | FileCheck %s
5 // Check that the output assembler directives also can be parsed, and
6 // that they produce equivalent output:
8 // RUN: llvm-mc -triple thumbv7-pc-win32 -filetype=asm %s | llvm-mc -triple thumbv7-pc-win32 -filetype=obj - | llvm-readobj -S -r -u - | FileCheck %s
10 // CHECK: Sections [
11 // CHECK: Section {
12 // CHECK: Name: .text
13 // CHECK: RelocationCount: 1
14 // CHECK: Characteristics [
15 // CHECK-NEXT: ALIGN_4BYTES
16 // CHECK-NEXT: CNT_CODE
17 // CHECK-NEXT: MEM_16BIT
18 // CHECK-NEXT: MEM_EXECUTE
19 // CHECK-NEXT: MEM_PURGEABLE
20 // CHECK-NEXT: MEM_READ
21 // CHECK-NEXT: ]
22 // CHECK-NEXT: }
23 // CHECK: Section {
24 // CHECK: Name: .xdata
25 // CHECK: RawDataSize: 100
26 // CHECK: RelocationCount: 1
27 // CHECK: Characteristics [
28 // CHECK-NEXT: ALIGN_4BYTES
29 // CHECK-NEXT: CNT_INITIALIZED_DATA
30 // CHECK-NEXT: MEM_READ
31 // CHECK-NEXT: ]
32 // CHECK-NEXT: }
33 // CHECK: Section {
34 // CHECK: Name: .pdata
35 // CHECK: RelocationCount: 10
36 // CHECK: Characteristics [
37 // CHECK-NEXT: ALIGN_4BYTES
38 // CHECK-NEXT: CNT_INITIALIZED_DATA
39 // CHECK-NEXT: MEM_READ
40 // CHECK-NEXT: ]
41 // CHECK-NEXT: }
42 // CHECK-NEXT: ]
44 // CHECK-NEXT: Relocations [
45 // CHECK-NEXT: Section (1) .text {
46 // CHECK-NEXT: 0x5C IMAGE_REL_ARM_BRANCH24T tailcall
47 // CHECK-NEXT: }
48 // CHECK-NEXT: Section (4) .xdata {
49 // CHECK-NEXT: 0x34 IMAGE_REL_ARM_ADDR32NB __C_specific_handler
50 // CHECK-NEXT: }
51 // CHECK-NEXT: Section (5) .pdata {
52 // CHECK-NEXT: 0x0 IMAGE_REL_ARM_ADDR32NB .text
53 // CHECK-NEXT: 0x4 IMAGE_REL_ARM_ADDR32NB .xdata
54 // CHECK-NEXT: 0x8 IMAGE_REL_ARM_ADDR32NB .text
55 // CHECK-NEXT: 0xC IMAGE_REL_ARM_ADDR32NB .xdata
56 // CHECK-NEXT: 0x10 IMAGE_REL_ARM_ADDR32NB .text
57 // CHECK-NEXT: 0x14 IMAGE_REL_ARM_ADDR32NB .xdata
58 // CHECK-NEXT: 0x18 IMAGE_REL_ARM_ADDR32NB .text
59 // CHECK-NEXT: 0x1C IMAGE_REL_ARM_ADDR32NB .xdata
60 // CHECK-NEXT: 0x20 IMAGE_REL_ARM_ADDR32NB .text
61 // CHECK-NEXT: 0x24 IMAGE_REL_ARM_ADDR32NB .xdata
62 // CHECK-NEXT: }
63 // CHECK-NEXT: ]
65 // CHECK-NEXT: UnwindInformation [
66 // CHECK-NEXT: RuntimeFunction {
67 // CHECK-NEXT: Function: func
68 // CHECK-NEXT: ExceptionRecord: .xdata
69 // CHECK-NEXT: ExceptionData {
70 // CHECK-NEXT: FunctionLength: 86
71 // CHECK: EpiloguePacked: Yes
72 // CHECK: Fragment: No
73 // CHECK: EpilogueOffset: 31
74 // CHECK: Prologue [
75 // CHECK-NEXT: 0xed 0xf8 ; push {r3-r7, lr}
76 // CHECK-NEXT: 0xf6 0x27 ; vpush {d18-d23}
77 // CHECK-NEXT: 0xf5 0x7e ; vpush {d7-d14}
78 // CHECK-NEXT: 0xfb ; nop
79 // CHECK-NEXT: 0xce ; mov r14, sp
80 // CHECK-NEXT: 0xe3 ; vpush {d8-d11}
81 // CHECK-NEXT: 0xe6 ; vpush {d8-d14}
82 // CHECK-NEXT: 0xed 0xf8 ; push {r3-r7, lr}
83 // CHECK-NEXT: 0xbd 0x50 ; push.w {r4, r6, r8, r10-r12, lr}
84 // CHECK-NEXT: 0xd7 ; push {r4-r7, lr}
85 // CHECK-NEXT: 0xdd ; push.w {r4-r9, lr}
86 // CHECK-NEXT: 0xfa 0x01 0x00 0x00 ; sub.w sp, sp, #(65536 * 4)
87 // CHECK-NEXT: 0xfc ; nop.w
88 // CHECK-NEXT: 0xfc ; nop.w
89 // CHECK-NEXT: 0xf9 0x04 0x00 ; sub.w sp, sp, #(1024 * 4)
90 // CHECK-NEXT: 0xe8 0x80 ; sub.w sp, #(128 * 4)
91 // CHECK-NEXT: 0xe8 0x80 ; sub.w sp, #(128 * 4)
92 // CHECK-NEXT: 0x06 ; sub sp, #(6 * 4)
93 // CHECK-NEXT: ]
94 // CHECK-NEXT: Epilogue [
95 // CHECK-NEXT: 0xfc ; nop.w
96 // CHECK-NEXT: 0xf7 0x00 0x80 ; add sp, sp, #(128 * 4)
97 // CHECK-NEXT: 0xfc ; nop.w
98 // CHECK-NEXT: 0xfc ; nop.w
99 // CHECK-NEXT: 0xf8 0x01 0x00 0x00 ; add sp, sp, #(65536 * 4)
100 // CHECK-NEXT: 0x06 ; add sp, #(6 * 4)
101 // CHECK-NEXT: 0xef 0x04 ; ldr.w lr, [sp], #16
102 // CHECK-NEXT: 0xfd ; bx <reg>
103 // CHECK-NEXT: ]
104 // CHECK-NEXT: ExceptionHandler [
105 // CHECK-NEXT: Routine: __C_specific_handler
106 // CHECK-NEXT: Parameter: 0x0
107 // CHECK-NEXT: ]
108 // CHECK-NEXT: }
109 // CHECK-NEXT: }
110 // CHECK-NEXT: RuntimeFunction {
111 // CHECK-NEXT: Function: func2
112 // CHECK: Prologue [
113 // CHECK-NEXT: 0xd3 ; push {r4-r7}
114 // CHECK-NEXT: ]
115 // CHECK-NEXT: Epilogue [
116 // CHECK-NEXT: 0xd2 ; pop {r4-r6}
117 // CHECK-NEXT: 0xfe ; b.w <target>
118 // CHECK-NEXT: ]
119 // CHECK-NEXT: }
120 // CHECK-NEXT: }
121 // CHECK-NEXT: RuntimeFunction {
122 // CHECK-NEXT: Function: func3
123 // CHECK: FunctionLength: 8
124 // CHECK: EpilogueOffset: 2
125 // CHECK: Prologue [
126 // CHECK-NEXT: 0xd5 ; push {r4-r5, lr}
127 // CHECK-NEXT: ]
128 // CHECK-NEXT: Epilogue [
129 // CHECK-NEXT: 0xd6 ; pop {r4-r6, pc}
130 // CHECK-NEXT: ]
131 // CHECK-NEXT: }
132 // CHECK-NEXT: }
133 // CHECK-NEXT: RuntimeFunction {
134 // CHECK-NEXT: Function: fragment
135 // CHECK: FunctionLength: 6
136 // CHECK: Fragment: Yes
137 // CHECK: Prologue [
138 // CHECK-NEXT: 0xcb ; mov r11, sp
139 // CHECK-NEXT: 0x10 ; sub sp, #(16 * 4)
140 // CHECK-NEXT: 0xd5 ; push {r4-r5, lr}
141 // CHECK-NEXT: ]
142 // CHECK-NEXT: Epilogue [
143 // CHECK-NEXT: 0x10 ; add sp, #(16 * 4)
144 // CHECK-NEXT: 0xd5 ; pop {r4-r5, pc}
145 // CHECK-NEXT: ]
146 // CHECK-NEXT: }
147 // CHECK-NEXT: }
148 // CHECK-NEXT: RuntimeFunction {
149 // CHECK-NEXT: Function: condepilog
150 // CHECK: FunctionLength: 8
151 // CHECK: Prologue [
152 // CHECK-NEXT: 0xd5 ; push {r4-r5, lr}
153 // CHECK-NEXT: ]
154 // CHECK-NEXT: EpilogueScopes [
155 // CHECK-NEXT: EpilogueScope {
156 // CHECK-NEXT: StartOffset: 3
157 // CHECK-NEXT: Condition: 10
158 // CHECK-NEXT: EpilogueStartIndex: 0
159 // CHECK-NEXT: Opcodes [
160 // CHECK-NEXT: 0xd5 ; pop {r4-r5, pc}
161 // CHECK-NEXT: ]
162 // CHECK-NEXT: }
163 // CHECK-NEXT: ]
164 // CHECK-NEXT: }
165 // CHECK-NEXT: }
166 // CHECK-NEXT: ]
168 .text
169 .syntax unified
170 .globl func
171 .def func
172 .scl 2
173 .type 32
174 .endef
175 .seh_proc func
176 func:
177 sub sp, sp, #24
178 .seh_stackalloc 24
179 sub sp, sp, #512
180 .seh_stackalloc_w 512
181 sub sp, sp, #512
182 .seh_stackalloc_w 512
183 sub sp, sp, #4096
184 .seh_stackalloc_w 4096
185 movw r7, #0
186 .seh_nop_w
187 movt r7, #0x4 // 0x40000
188 .seh_nop_w
189 sub sp, sp, r7
190 .seh_stackalloc_w 0x40000
191 push {r4-r8,lr}
192 .seh_save_regs_w {r4-r9,lr}
193 push {r4-r7,lr}
194 .seh_save_regs {r4-r7,lr}
195 push {r4,r6,r8,r10,r11,r12,lr}
196 .seh_save_regs_w {r4,r6,r8,r10,r11,r12,lr}
197 push {r3-r7,lr}
198 .seh_save_regs {r3-r7,lr}
199 vpush {d8-d14}
200 .seh_save_fregs {d8-d14}
201 vpush {q4-q5}
202 .seh_save_fregs {q4-q5}
203 mov lr, sp
204 .seh_save_sp lr
206 .seh_nop
207 vpush {d7-d14}
208 .seh_save_fregs {d7-d14}
209 vpush {d18-d23}
210 .seh_save_fregs {d18-d23}
211 push {r3-r7,lr}
212 .seh_custom 0xed, 0xf8
213 .seh_endprologue
215 .seh_startepilogue
216 mov r7, #512
217 .seh_nop_w
218 add sp, sp, r7
219 .seh_stackalloc 512
220 movw r7, #0
221 .seh_nop_w
222 movt r7, #0x4 // 0x40000
223 .seh_nop_w
224 add sp, sp, r7
225 .seh_stackalloc 0x40000
226 add sp, sp, #24
227 .seh_stackalloc 24
228 ldr lr, [sp], #16
229 .seh_save_lr 16
230 bx lr
231 .seh_nop
232 .seh_endepilogue
233 .seh_handler __C_specific_handler, %except
234 .seh_handlerdata
235 .long 0
236 .text
237 .seh_endproc
239 .seh_proc func2
240 func2:
241 push {r4-r7}
242 .seh_save_regs {r4-r7}
243 .seh_endprologue
245 .seh_startepilogue
246 pop {r4-r6}
247 .seh_save_regs {r4-r6}
248 b.w tailcall
249 .seh_nop_w
250 .seh_endepilogue
251 .seh_endproc
253 .seh_proc func3
254 func3:
255 push {r4-r5,lr}
256 .seh_save_regs {r4-r5,lr}
257 .seh_endprologue
259 // The p2align causes the length of the function to be unknown.
260 .p2align 1
262 .seh_startepilogue
263 pop {r4-r6,pc}
264 .seh_save_regs {r4-r6,pc}
265 .seh_endepilogue
266 .seh_endproc
268 .seh_proc fragment
269 fragment:
270 // Prologue opcodes without matching instructions
271 .seh_save_regs {r4-r5,lr}
272 .seh_stackalloc 64
273 .seh_save_sp r11
274 .seh_endprologue_fragment
276 .seh_startepilogue
277 add sp, sp, #64
278 .seh_stackalloc 64
279 pop {r4-r5,pc}
280 .seh_save_regs {r4-r5,pc}
281 .seh_endepilogue
282 .seh_endproc
284 .seh_proc condepilog
285 condepilog:
286 push {r4-r5,lr}
287 .seh_save_regs {r4-r5,lr}
288 .seh_endprologue
290 it ge
291 .seh_startepilogue_cond ge
292 popge {r4-r5,pc}
293 .seh_save_regs {r4-r5,pc}
294 .seh_endepilogue
295 .seh_endproc
297 // Function with no .seh directives; no pdata/xdata entries are
298 // generated.
299 .globl smallFunc
300 .def smallFunc
301 .scl 2
302 .type 32
303 .endef
304 .seh_proc smallFunc
305 smallFunc:
306 bx lr
307 .seh_endproc
309 // Function with no .seh directives, but with .seh_handlerdata.
310 // No xdata/pdata entries are generated, but the custom handler data
311 // (the .long after .seh_handlerdata) is left orphaned in the xdata
312 // section.
313 .globl handlerFunc
314 .def handlerFunc
315 .scl 2
316 .type 32
317 .endef
318 .seh_proc handlerFunc
319 handlerFunc:
320 bx lr
321 .seh_handler __C_specific_handler, %except
322 .seh_handlerdata
323 .long 0
324 .text
325 .seh_endproc