1@ RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o - \
2@ RUN:   | llvm-readobj -s -sd | FileCheck %s
3
4@ Check the .save directive
5
6@ The .save directive records the GPR registers which are pushed to the
7@ stack.  There are 4 different unwind opcodes:
8@
9@     0xB100: pop r[3:0]
10@     0xA0:   pop r[(4+x):4]		@ r[4+x]-r[4] must be consecutive.
11@     0xA8:   pop r14, r[(4+x):4]	@ r[4+x]-r[4] must be consecutive.
12@     0x8000: pop r[15:4]
13@
14@ If register list specifed by .save directive is possible to be encoded
15@ by 0xA0 or 0xA8, then the assembler should prefer them over 0x8000.
16
17
18	.syntax unified
19
20@-------------------------------------------------------------------------------
21@ TEST1
22@-------------------------------------------------------------------------------
23	.section	.TEST1
24	.globl	func1a
25	.align	2
26	.type	func1a,%function
27	.fnstart
28func1a:
29	.save	{r0}
30	push	{r0}
31	pop	{r0}
32	bx	lr
33	.personality __gxx_personality_v0
34	.handlerdata
35	.fnend
36
37	.globl	func1b
38	.align	2
39	.type	func1b,%function
40	.fnstart
41func1b:
42	.save	{r0, r1}
43	push	{r0, r1}
44	pop	{r0, r1}
45	bx	lr
46	.personality __gxx_personality_v0
47	.handlerdata
48	.fnend
49
50	.globl	func1c
51	.align	2
52	.type	func1c,%function
53	.fnstart
54func1c:
55	.save	{r0, r2}
56	push	{r0, r2}
57	pop	{r0, r2}
58	bx	lr
59	.personality __gxx_personality_v0
60	.handlerdata
61	.fnend
62
63	.globl	func1d
64	.align	2
65	.type	func1d,%function
66	.fnstart
67func1d:
68	.save	{r1, r2}
69	push	{r1, r2}
70	pop	{r1, r2}
71	bx	lr
72	.personality __gxx_personality_v0
73	.handlerdata
74	.fnend
75
76	.globl	func1e
77	.align	2
78	.type	func1e,%function
79	.fnstart
80func1e:
81	.save	{r0, r1, r2, r3}
82	push	{r0, r1, r2, r3}
83	pop	{r0, r1, r2, r3}
84	bx	lr
85	.personality __gxx_personality_v0
86	.handlerdata
87	.fnend
88
89@-------------------------------------------------------------------------------
90@ The assembler should emit 0xB000 unwind opcode.
91@-------------------------------------------------------------------------------
92@ CHECK: Section {
93@ CHECK:   Name: .ARM.extab.TEST1
94@ CHECK:   SectionData (
95@ CHECK:     0000: 00000000 B001B100 00000000 B003B100  |................|
96@ CHECK:     0010: 00000000 B005B100 00000000 B006B100  |................|
97@ CHECK:     0020: 00000000 B00FB100                    |........|
98@ CHECK:   )
99@ CHECK: }
100
101
102
103@-------------------------------------------------------------------------------
104@ TEST2
105@-------------------------------------------------------------------------------
106	.section	.TEST2
107	.globl	func2a
108	.align	2
109	.type	func2a,%function
110	.fnstart
111func2a:
112	.save	{r4}
113	push	{r4}
114	pop	{r4}
115	bx	lr
116	.personality __gxx_personality_v0
117	.handlerdata
118	.fnend
119
120	.globl	func2b
121	.align	2
122	.type	func2b,%function
123	.fnstart
124func2b:
125	.save	{r4, r5}
126	push	{r4, r5}
127	pop	{r4, r5}
128	bx	lr
129	.personality __gxx_personality_v0
130	.handlerdata
131	.fnend
132
133	.globl	func2c
134	.align	2
135	.type	func2c,%function
136	.fnstart
137func2c:
138	.save	{r4, r5, r6, r7, r8, r9, r10, r11}
139	push	{r4, r5, r6, r7, r8, r9, r10, r11}
140	pop	{r4, r5, r6, r7, r8, r9, r10, r11}
141	bx	lr
142	.personality __gxx_personality_v0
143	.handlerdata
144	.fnend
145
146@-------------------------------------------------------------------------------
147@ The assembler should emit 0xA0 unwind opcode.
148@-------------------------------------------------------------------------------
149@ CHECK: Section {
150@ CHECK:   Name: .ARM.extab.TEST2
151@ CHECK:   SectionData (
152@ CHECK:     0000: 00000000 B0B0A000 00000000 B0B0A100  |................|
153@ CHECK:     0010: 00000000 B0B0A700                    |........|
154@ CHECK:   )
155@ CHECK: }
156
157
158
159@-------------------------------------------------------------------------------
160@ TEST3
161@-------------------------------------------------------------------------------
162	.section	.TEST3
163	.globl	func3a
164	.align	2
165	.type	func3a,%function
166	.fnstart
167func3a:
168	.save	{r4, r14}
169	push	{r4, r14}
170	pop	{r4, r14}
171	bx	lr
172	.personality __gxx_personality_v0
173	.handlerdata
174	.fnend
175
176	.globl	func3b
177	.align	2
178	.type	func3b,%function
179	.fnstart
180func3b:
181	.save	{r4, r5, r14}
182	push	{r4, r5, r14}
183	pop	{r4, r5, r14}
184	bx	lr
185	.personality __gxx_personality_v0
186	.handlerdata
187	.fnend
188
189	.globl	func3c
190	.align	2
191	.type	func3c,%function
192	.fnstart
193func3c:
194	.save	{r4, r5, r6, r7, r8, r9, r10, r11, r14}
195	push	{r4, r5, r6, r7, r8, r9, r10, r11, r14}
196	pop	{r4, r5, r6, r7, r8, r9, r10, r11, r14}
197	bx	lr
198	.personality __gxx_personality_v0
199	.handlerdata
200	.fnend
201
202@-------------------------------------------------------------------------------
203@ The assembler should emit 0xA8 unwind opcode.
204@-------------------------------------------------------------------------------
205@ CHECK: Section {
206@ CHECK:   Name: .ARM.extab.TEST3
207@ CHECK:   SectionData (
208@ CHECK:     0000: 00000000 B0B0A800 00000000 B0B0A900  |................|
209@ CHECK:     0010: 00000000 B0B0AF00                    |........|
210@ CHECK:   )
211@ CHECK: }
212
213
214
215@-------------------------------------------------------------------------------
216@ TEST4
217@-------------------------------------------------------------------------------
218	.section	.TEST4
219	.globl	func4a
220	.align	2
221	.type	func4a,%function
222	.fnstart
223func4a:
224	.save	{r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
225	push	{r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
226	pop	{r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
227	bx	lr
228	.personality __gxx_personality_v0
229	.handlerdata
230	.fnend
231
232	.globl	func4b
233	.align	2
234	.type	func4b,%function
235	.fnstart
236func4b:
237	@ Note: r7 is missing intentionally.
238	.save	{r4, r5, r6, r8, r9, r10, r11}
239	push	{r4, r5, r6, r8, r9, r10, r11}
240	pop	{r4, r5, r6, r8, r9, r10, r11}
241	bx	lr
242	.personality __gxx_personality_v0
243	.handlerdata
244	.fnend
245
246	.globl	func4c
247	.align	2
248	.type	func4c,%function
249	.fnstart
250func4c:
251	@ Note: r7 is missing intentionally.
252	.save	{r4, r5, r6, r8, r9, r10, r11, r14}
253	push	{r4, r5, r6, r8, r9, r10, r11, r14}
254	pop	{r4, r5, r6, r8, r9, r10, r11, r14}
255	bx	lr
256	.personality __gxx_personality_v0
257	.handlerdata
258	.fnend
259
260	.globl	func4d
261	.align	2
262	.type	func4d,%function
263	.fnstart
264func4d:
265	@ Note: The register list is not start with r4.
266	.save	{r5, r6, r7}
267	push	{r5, r6, r7}
268	pop	{r5, r6, r7}
269	bx	lr
270	.personality __gxx_personality_v0
271	.handlerdata
272	.fnend
273
274	.globl	func4e
275	.align	2
276	.type	func4e,%function
277	.fnstart
278func4e:
279	@ Note: The register list is not start with r4.
280	.save	{r5, r6, r7, r14}
281	push	{r5, r6, r7, r14}
282	pop	{r5, r6, r7, r14}
283	bx	lr
284	.personality __gxx_personality_v0
285	.handlerdata
286	.fnend
287
288@-------------------------------------------------------------------------------
289@ The assembler should emit 0x8000 unwind opcode.
290@-------------------------------------------------------------------------------
291@ CHECK: Section {
292@ CHECK:   Name: .ARM.extab.TEST4
293@ CHECK:   SectionData (
294@ CHECK:     0000: 00000000 B0FF8500 00000000 B0F78000  |................|
295@ CHECK:     0010: 00000000 B0F78400 00000000 B00E8000  |................|
296@ CHECK:     0020: 00000000 B00E8400                    |........|
297@ CHECK:   )
298@ CHECK: }
299
300
301
302@-------------------------------------------------------------------------------
303@ TEST5
304@-------------------------------------------------------------------------------
305	.section	.TEST5
306	.globl	func5a
307	.align	2
308	.type	func5a,%function
309	.fnstart
310func5a:
311	.save	{r0, r1, r2, r3, r4, r5, r6}
312	push	{r0, r1, r2, r3, r4, r5, r6}
313	pop	{r0, r1, r2, r3, r4, r5, r6}
314	bx	lr
315	.personality __gxx_personality_v0
316	.handlerdata
317	.fnend
318
319	.globl	func5b
320	.align	2
321	.type	func5b,%function
322	.fnstart
323func5b:
324	.save	{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
325	push	{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
326	pop	{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
327	bx	lr
328	.personality __gxx_personality_v0
329	.handlerdata
330	.fnend
331
332@-------------------------------------------------------------------------------
333@ Check the order of unwind opcode to pop registers.
334@ 0xB10F "pop {r0-r3}" should be emitted before 0xA2 "pop {r4-r6}".
335@ 0xB10F "pop {r0-r3}" should be emitted before 0x85FF "pop {r4-r12, r14}".
336@-------------------------------------------------------------------------------
337@ CHECK: Section {
338@ CHECK:   Name: .ARM.extab.TEST5
339@ CHECK:   SectionData (
340@ CHECK:     0000: 00000000 A20FB100 00000000 850FB101  |................|
341@ CHECK:     0010: B0B0B0FF                             |....|
342@ CHECK:   )
343@ CHECK: }
344