1; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -verify-machineinstrs | FileCheck %s -check-prefix=X32-Linux
2; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux  -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux
3; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X32-Darwin
4; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X64-Darwin
5; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -verify-machineinstrs | FileCheck %s -check-prefix=X32-MinGW
6; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -verify-machineinstrs | FileCheck %s -check-prefix=X64-FreeBSD
7; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -verify-machineinstrs | FileCheck %s -check-prefix=X64-MinGW
8
9; We used to crash with filetype=obj
10; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -filetype=obj
11; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -filetype=obj
12; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -filetype=obj
13; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -filetype=obj
14; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -filetype=obj
15; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -filetype=obj
16; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -filetype=obj
17
18; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-solaris 2> %t.log
19; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-Solaris
20; RUN: not llc < %s -mcpu=generic -mtriple=i686-freebsd 2> %t.log
21; RUN: FileCheck %s -input-file=%t.log -check-prefix=X32-FreeBSD
22
23; X64-Solaris: Segmented stacks not supported on this platform
24; X32-FreeBSD: Segmented stacks not supported on FreeBSD i386
25
26; Just to prevent the alloca from being optimized away
27declare void @dummy_use(i32*, i32)
28
29define void @test_basic() #0 {
30        %mem = alloca i32, i32 10
31        call void @dummy_use (i32* %mem, i32 10)
32	ret void
33
34; X32-Linux-LABEL:       test_basic:
35
36; X32-Linux:       cmpl %gs:48, %esp
37; X32-Linux-NEXT:  ja      .LBB0_2
38
39; X32-Linux:       pushl $0
40; X32-Linux-NEXT:  pushl $60
41; X32-Linux-NEXT:  calll __morestack
42; X32-Linux-NEXT:  ret
43
44; X64-Linux-LABEL:       test_basic:
45
46; X64-Linux:       cmpq %fs:112, %rsp
47; X64-Linux-NEXT:  ja      .LBB0_2
48
49; X64-Linux:       movabsq $40, %r10
50; X64-Linux-NEXT:  movabsq $0, %r11
51; X64-Linux-NEXT:  callq __morestack
52; X64-Linux-NEXT:  ret
53
54; X32-Darwin-LABEL:      test_basic:
55
56; X32-Darwin:      movl $432, %ecx
57; X32-Darwin-NEXT: cmpl %gs:(%ecx), %esp
58; X32-Darwin-NEXT: ja      LBB0_2
59
60; X32-Darwin:      pushl $0
61; X32-Darwin-NEXT: pushl $60
62; X32-Darwin-NEXT: calll ___morestack
63; X32-Darwin-NEXT: ret
64
65; X64-Darwin-LABEL:      test_basic:
66
67; X64-Darwin:      cmpq %gs:816, %rsp
68; X64-Darwin-NEXT: ja      LBB0_2
69
70; X64-Darwin:      movabsq $40, %r10
71; X64-Darwin-NEXT: movabsq $0, %r11
72; X64-Darwin-NEXT: callq ___morestack
73; X64-Darwin-NEXT: ret
74
75; X32-MinGW-LABEL:       test_basic:
76
77; X32-MinGW:       cmpl %fs:20, %esp
78; X32-MinGW-NEXT:  ja      LBB0_2
79
80; X32-MinGW:       pushl $0
81; X32-MinGW-NEXT:  pushl $48
82; X32-MinGW-NEXT:  calll ___morestack
83; X32-MinGW-NEXT:  ret
84
85; X64-MinGW-LABEL:       test_basic:
86
87; X64-MinGW:       cmpq %gs:40, %rsp
88; X64-MinGW-NEXT:  ja      .LBB0_2
89
90; X64-MinGW:       movabsq $72, %r10
91; X64-MinGW-NEXT:  movabsq $32, %r11
92; X64-MinGW-NEXT:  callq __morestack
93; X64-MinGW-NEXT:  retq
94
95; X64-FreeBSD-LABEL:       test_basic:
96
97; X64-FreeBSD:       cmpq %fs:24, %rsp
98; X64-FreeBSD-NEXT:  ja      .LBB0_2
99
100; X64-FreeBSD:       movabsq $40, %r10
101; X64-FreeBSD-NEXT:  movabsq $0, %r11
102; X64-FreeBSD-NEXT:  callq __morestack
103; X64-FreeBSD-NEXT:  ret
104
105}
106
107define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
108       %addend = load i32 * %closure
109       %result = add i32 %other, %addend
110       ret i32 %result
111
112; X32-Linux:       cmpl %gs:48, %esp
113; X32-Linux-NEXT:  ja      .LBB1_2
114
115; X32-Linux:       pushl $4
116; X32-Linux-NEXT:  pushl $0
117; X32-Linux-NEXT:  calll __morestack
118; X32-Linux-NEXT:  ret
119
120; X64-Linux:       cmpq %fs:112, %rsp
121; X64-Linux-NEXT:  ja      .LBB1_2
122
123; X64-Linux:       movq %r10, %rax
124; X64-Linux-NEXT:  movabsq $0, %r10
125; X64-Linux-NEXT:  movabsq $0, %r11
126; X64-Linux-NEXT:  callq __morestack
127; X64-Linux-NEXT:  ret
128; X64-Linux-NEXT:  movq %rax, %r10
129
130; X32-Darwin:      movl $432, %edx
131; X32-Darwin-NEXT: cmpl %gs:(%edx), %esp
132; X32-Darwin-NEXT: ja      LBB1_2
133
134; X32-Darwin:      pushl $4
135; X32-Darwin-NEXT: pushl $0
136; X32-Darwin-NEXT: calll ___morestack
137; X32-Darwin-NEXT: ret
138
139; X64-Darwin:      cmpq %gs:816, %rsp
140; X64-Darwin-NEXT: ja      LBB1_2
141
142; X64-Darwin:      movq %r10, %rax
143; X64-Darwin-NEXT: movabsq $0, %r10
144; X64-Darwin-NEXT: movabsq $0, %r11
145; X64-Darwin-NEXT: callq ___morestack
146; X64-Darwin-NEXT: ret
147; X64-Darwin-NEXT: movq %rax, %r10
148
149; X32-MinGW:       cmpl %fs:20, %esp
150; X32-MinGW-NEXT:  ja      LBB1_2
151
152; X32-MinGW:       pushl $4
153; X32-MinGW-NEXT:  pushl $0
154; X32-MinGW-NEXT:  calll ___morestack
155; X32-MinGW-NEXT:  ret
156
157; X64-MinGW-LABEL: test_nested:
158; X64-MinGW:       cmpq %gs:40, %rsp
159; X64-MinGW-NEXT:  ja      .LBB1_2
160
161; X64-MinGW:       movq %r10, %rax
162; X64-MinGW-NEXT:  movabsq $0, %r10
163; X64-MinGW-NEXT:  movabsq $32, %r11
164; X64-MinGW-NEXT:  callq __morestack
165; X64-MinGW-NEXT:  retq
166; X64-MinGW-NEXT:  movq %rax, %r10
167
168; X64-FreeBSD:       cmpq %fs:24, %rsp
169; X64-FreeBSD-NEXT:  ja      .LBB1_2
170
171; X64-FreeBSD:       movq %r10, %rax
172; X64-FreeBSD-NEXT:  movabsq $0, %r10
173; X64-FreeBSD-NEXT:  movabsq $0, %r11
174; X64-FreeBSD-NEXT:  callq __morestack
175; X64-FreeBSD-NEXT:  ret
176; X64-FreeBSD-NEXT:  movq %rax, %r10
177
178}
179
180define void @test_large() #0 {
181        %mem = alloca i32, i32 10000
182        call void @dummy_use (i32* %mem, i32 0)
183        ret void
184
185; X32-Linux:       leal -40012(%esp), %ecx
186; X32-Linux-NEXT:  cmpl %gs:48, %ecx
187; X32-Linux-NEXT:  ja      .LBB2_2
188
189; X32-Linux:       pushl $0
190; X32-Linux-NEXT:  pushl $40012
191; X32-Linux-NEXT:  calll __morestack
192; X32-Linux-NEXT:  ret
193
194; X64-Linux:       leaq -40008(%rsp), %r11
195; X64-Linux-NEXT:  cmpq %fs:112, %r11
196; X64-Linux-NEXT:  ja      .LBB2_2
197
198; X64-Linux:       movabsq $40008, %r10
199; X64-Linux-NEXT:  movabsq $0, %r11
200; X64-Linux-NEXT:  callq __morestack
201; X64-Linux-NEXT:  ret
202
203; X32-Darwin:      leal -40012(%esp), %ecx
204; X32-Darwin-NEXT: movl $432, %eax
205; X32-Darwin-NEXT: cmpl %gs:(%eax), %ecx
206; X32-Darwin-NEXT: ja      LBB2_2
207
208; X32-Darwin:      pushl $0
209; X32-Darwin-NEXT: pushl $40012
210; X32-Darwin-NEXT: calll ___morestack
211; X32-Darwin-NEXT: ret
212
213; X64-Darwin:      leaq -40008(%rsp), %r11
214; X64-Darwin-NEXT: cmpq %gs:816, %r11
215; X64-Darwin-NEXT: ja      LBB2_2
216
217; X64-Darwin:      movabsq $40008, %r10
218; X64-Darwin-NEXT: movabsq $0, %r11
219; X64-Darwin-NEXT: callq ___morestack
220; X64-Darwin-NEXT: ret
221
222; X32-MinGW:       leal -40008(%esp), %ecx
223; X32-MinGW-NEXT:  cmpl %fs:20, %ecx
224; X32-MinGW-NEXT:  ja      LBB2_2
225
226; X32-MinGW:       pushl $0
227; X32-MinGW-NEXT:  pushl $40008
228; X32-MinGW-NEXT:  calll ___morestack
229; X32-MinGW-NEXT:  ret
230
231; X64-MinGW-LABEL: test_large:
232; X64-MinGW:       leaq -40040(%rsp), %r11
233; X64-MinGW-NEXT:  cmpq %gs:40, %r11
234; X64-MinGW-NEXT:  ja      .LBB2_2
235
236; X64-MinGW:       movabsq $40040, %r10
237; X64-MinGW-NEXT:  movabsq $32, %r11
238; X64-MinGW-NEXT:  callq __morestack
239; X64-MinGW-NEXT:  retq
240
241; X64-FreeBSD:       leaq -40008(%rsp), %r11
242; X64-FreeBSD-NEXT:  cmpq %fs:24, %r11
243; X64-FreeBSD-NEXT:  ja      .LBB2_2
244
245; X64-FreeBSD:       movabsq $40008, %r10
246; X64-FreeBSD-NEXT:  movabsq $0, %r11
247; X64-FreeBSD-NEXT:  callq __morestack
248; X64-FreeBSD-NEXT:  ret
249
250}
251
252define fastcc void @test_fastcc() #0 {
253        %mem = alloca i32, i32 10
254        call void @dummy_use (i32* %mem, i32 10)
255        ret void
256
257; X32-Linux-LABEL:       test_fastcc:
258
259; X32-Linux:       cmpl %gs:48, %esp
260; X32-Linux-NEXT:  ja      .LBB3_2
261
262; X32-Linux:       pushl $0
263; X32-Linux-NEXT:  pushl $60
264; X32-Linux-NEXT:  calll __morestack
265; X32-Linux-NEXT:  ret
266
267; X64-Linux-LABEL:       test_fastcc:
268
269; X64-Linux:       cmpq %fs:112, %rsp
270; X64-Linux-NEXT:  ja      .LBB3_2
271
272; X64-Linux:       movabsq $40, %r10
273; X64-Linux-NEXT:  movabsq $0, %r11
274; X64-Linux-NEXT:  callq __morestack
275; X64-Linux-NEXT:  ret
276
277; X32-Darwin-LABEL:      test_fastcc:
278
279; X32-Darwin:      movl $432, %eax
280; X32-Darwin-NEXT: cmpl %gs:(%eax), %esp
281; X32-Darwin-NEXT: ja      LBB3_2
282
283; X32-Darwin:      pushl $0
284; X32-Darwin-NEXT: pushl $60
285; X32-Darwin-NEXT: calll ___morestack
286; X32-Darwin-NEXT: ret
287
288; X64-Darwin-LABEL:      test_fastcc:
289
290; X64-Darwin:      cmpq %gs:816, %rsp
291; X64-Darwin-NEXT: ja      LBB3_2
292
293; X64-Darwin:      movabsq $40, %r10
294; X64-Darwin-NEXT: movabsq $0, %r11
295; X64-Darwin-NEXT: callq ___morestack
296; X64-Darwin-NEXT: ret
297
298; X32-MinGW-LABEL:       test_fastcc:
299
300; X32-MinGW:       cmpl %fs:20, %esp
301; X32-MinGW-NEXT:  ja      LBB3_2
302
303; X32-MinGW:       pushl $0
304; X32-MinGW-NEXT:  pushl $48
305; X32-MinGW-NEXT:  calll ___morestack
306; X32-MinGW-NEXT:  ret
307
308; X64-MinGW-LABEL:       test_fastcc:
309
310; X64-MinGW:       cmpq %gs:40, %rsp
311; X64-MinGW-NEXT:  ja      .LBB3_2
312
313; X64-MinGW:       movabsq $72, %r10
314; X64-MinGW-NEXT:  movabsq $32, %r11
315; X64-MinGW-NEXT:  callq __morestack
316; X64-MinGW-NEXT:  retq
317
318; X64-FreeBSD-LABEL:       test_fastcc:
319
320; X64-FreeBSD:       cmpq %fs:24, %rsp
321; X64-FreeBSD-NEXT:  ja      .LBB3_2
322
323; X64-FreeBSD:       movabsq $40, %r10
324; X64-FreeBSD-NEXT:  movabsq $0, %r11
325; X64-FreeBSD-NEXT:  callq __morestack
326; X64-FreeBSD-NEXT:  ret
327
328}
329
330define fastcc void @test_fastcc_large() #0 {
331        %mem = alloca i32, i32 10000
332        call void @dummy_use (i32* %mem, i32 0)
333        ret void
334
335; X32-Linux-LABEL:       test_fastcc_large:
336
337; X32-Linux:       leal -40012(%esp), %eax
338; X32-Linux-NEXT:  cmpl %gs:48, %eax
339; X32-Linux-NEXT:  ja      .LBB4_2
340
341; X32-Linux:       pushl $0
342; X32-Linux-NEXT:  pushl $40012
343; X32-Linux-NEXT:  calll __morestack
344; X32-Linux-NEXT:  ret
345
346; X64-Linux-LABEL:       test_fastcc_large:
347
348; X64-Linux:       leaq -40008(%rsp), %r11
349; X64-Linux-NEXT:  cmpq %fs:112, %r11
350; X64-Linux-NEXT:  ja      .LBB4_2
351
352; X64-Linux:       movabsq $40008, %r10
353; X64-Linux-NEXT:  movabsq $0, %r11
354; X64-Linux-NEXT:  callq __morestack
355; X64-Linux-NEXT:  ret
356
357; X32-Darwin-LABEL:      test_fastcc_large:
358
359; X32-Darwin:      leal -40012(%esp), %eax
360; X32-Darwin-NEXT: movl $432, %ecx
361; X32-Darwin-NEXT: cmpl %gs:(%ecx), %eax
362; X32-Darwin-NEXT: ja      LBB4_2
363
364; X32-Darwin:      pushl $0
365; X32-Darwin-NEXT: pushl $40012
366; X32-Darwin-NEXT: calll ___morestack
367; X32-Darwin-NEXT: ret
368
369; X64-Darwin-LABEL:      test_fastcc_large:
370
371; X64-Darwin:      leaq -40008(%rsp), %r11
372; X64-Darwin-NEXT: cmpq %gs:816, %r11
373; X64-Darwin-NEXT: ja      LBB4_2
374
375; X64-Darwin:      movabsq $40008, %r10
376; X64-Darwin-NEXT: movabsq $0, %r11
377; X64-Darwin-NEXT: callq ___morestack
378; X64-Darwin-NEXT: ret
379
380; X32-MinGW-LABEL:       test_fastcc_large:
381
382; X32-MinGW:       leal -40008(%esp), %eax
383; X32-MinGW-NEXT:  cmpl %fs:20, %eax
384; X32-MinGW-NEXT:  ja      LBB4_2
385
386; X32-MinGW:       pushl $0
387; X32-MinGW-NEXT:  pushl $40008
388; X32-MinGW-NEXT:  calll ___morestack
389; X32-MinGW-NEXT:  ret
390
391; X64-MinGW-LABEL:       test_fastcc_large:
392
393; X64-MinGW:       leaq -40040(%rsp), %r11
394; X64-MinGW-NEXT:  cmpq %gs:40, %r11
395; X64-MinGW-NEXT:  ja      .LBB4_2
396
397; X64-MinGW:       movabsq $40040, %r10
398; X64-MinGW-NEXT:  movabsq $32, %r11
399; X64-MinGW-NEXT:  callq __morestack
400; X64-MinGW-NEXT:  retq
401
402; X64-FreeBSD-LABEL:       test_fastcc_large:
403
404; X64-FreeBSD:       leaq -40008(%rsp), %r11
405; X64-FreeBSD-NEXT:  cmpq %fs:24, %r11
406; X64-FreeBSD-NEXT:  ja      .LBB4_2
407
408; X64-FreeBSD:       movabsq $40008, %r10
409; X64-FreeBSD-NEXT:  movabsq $0, %r11
410; X64-FreeBSD-NEXT:  callq __morestack
411; X64-FreeBSD-NEXT:  ret
412
413}
414
415define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) #0 {
416        %mem = alloca i32, i32 10000
417        call void @dummy_use (i32* %mem, i32 %a)
418        ret void
419
420; This is testing that the Mac implementation preserves ecx
421
422; X32-Darwin-LABEL:      test_fastcc_large_with_ecx_arg:
423
424; X32-Darwin:      leal -40012(%esp), %eax
425; X32-Darwin-NEXT: pushl %ecx
426; X32-Darwin-NEXT: movl $432, %ecx
427; X32-Darwin-NEXT: cmpl %gs:(%ecx), %eax
428; X32-Darwin-NEXT: popl %ecx
429; X32-Darwin-NEXT: ja      LBB5_2
430
431; X32-Darwin:      pushl $0
432; X32-Darwin-NEXT: pushl $40012
433; X32-Darwin-NEXT: calll ___morestack
434; X32-Darwin-NEXT: ret
435
436}
437
438attributes #0 = { "split-stack" }
439