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