• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -march=mipsel -pre-RA-sched=source < %s | FileCheck %s
2
3
4; All test functions do the same thing - they return the first variable
5; argument.
6
7; All CHECK's do the same thing - they check whether variable arguments from
8; registers are placed on correct stack locations, and whether the first
9; variable argument is returned from the correct stack location.
10
11
12declare void @llvm.va_start(i8*) nounwind
13declare void @llvm.va_end(i8*) nounwind
14
15; return int
16define i32 @va1(i32 %a, ...) nounwind {
17entry:
18  %a.addr = alloca i32, align 4
19  %ap = alloca i8*, align 4
20  %b = alloca i32, align 4
21  store i32 %a, i32* %a.addr, align 4
22  %ap1 = bitcast i8** %ap to i8*
23  call void @llvm.va_start(i8* %ap1)
24  %0 = va_arg i8** %ap, i32
25  store i32 %0, i32* %b, align 4
26  %ap2 = bitcast i8** %ap to i8*
27  call void @llvm.va_end(i8* %ap2)
28  %tmp = load i32* %b, align 4
29  ret i32 %tmp
30
31; CHECK: va1:
32; CHECK: addiu   $sp, $sp, -16
33; CHECK: sw      $7, 28($sp)
34; CHECK: sw      $6, 24($sp)
35; CHECK: sw      $5, 20($sp)
36; CHECK: lw      $2, 20($sp)
37}
38
39; check whether the variable double argument will be accessed from the 8-byte
40; aligned location (i.e. whether the address is computed by adding 7 and
41; clearing lower 3 bits)
42define double @va2(i32 %a, ...) nounwind {
43entry:
44  %a.addr = alloca i32, align 4
45  %ap = alloca i8*, align 4
46  %b = alloca double, align 8
47  store i32 %a, i32* %a.addr, align 4
48  %ap1 = bitcast i8** %ap to i8*
49  call void @llvm.va_start(i8* %ap1)
50  %0 = va_arg i8** %ap, double
51  store double %0, double* %b, align 8
52  %ap2 = bitcast i8** %ap to i8*
53  call void @llvm.va_end(i8* %ap2)
54  %tmp = load double* %b, align 8
55  ret double %tmp
56
57; CHECK: va2:
58; CHECK: addiu   $sp, $sp, -16
59; CHECK: sw      $7, 28($sp)
60; CHECK: sw      $6, 24($sp)
61; CHECK: sw      $5, 20($sp)
62; CHECK: addiu   $[[R0:[0-9]+]], $sp, 20
63; CHECK: addiu   $[[R1:[0-9]+]], $[[R0]], 7
64; CHECK: addiu   $[[R2:[0-9]+]], $zero, -8
65; CHECK: and     $[[R3:[0-9]+]], $[[R1]], $[[R2]]
66; CHECK: ldc1    $f0, 0($[[R3]])
67}
68
69; int
70define i32 @va3(double %a, ...) nounwind {
71entry:
72  %a.addr = alloca double, align 8
73  %ap = alloca i8*, align 4
74  %b = alloca i32, align 4
75  store double %a, double* %a.addr, align 8
76  %ap1 = bitcast i8** %ap to i8*
77  call void @llvm.va_start(i8* %ap1)
78  %0 = va_arg i8** %ap, i32
79  store i32 %0, i32* %b, align 4
80  %ap2 = bitcast i8** %ap to i8*
81  call void @llvm.va_end(i8* %ap2)
82  %tmp = load i32* %b, align 4
83  ret i32 %tmp
84
85; CHECK: va3:
86; CHECK: addiu   $sp, $sp, -16
87; CHECK: sw      $7, 28($sp)
88; CHECK: sw      $6, 24($sp)
89; CHECK: lw      $2, 24($sp)
90}
91
92; double
93define double @va4(double %a, ...) nounwind {
94entry:
95  %a.addr = alloca double, align 8
96  %ap = alloca i8*, align 4
97  %b = alloca double, align 8
98  store double %a, double* %a.addr, align 8
99  %ap1 = bitcast i8** %ap to i8*
100  call void @llvm.va_start(i8* %ap1)
101  %0 = va_arg i8** %ap, double
102  store double %0, double* %b, align 8
103  %ap2 = bitcast i8** %ap to i8*
104  call void @llvm.va_end(i8* %ap2)
105  %tmp = load double* %b, align 8
106  ret double %tmp
107
108; CHECK: va4:
109; CHECK: addiu   $sp, $sp, -24
110; CHECK: sw      $7, 36($sp)
111; CHECK: sw      $6, 32($sp)
112; CHECK: addiu   ${{[0-9]+}}, $sp, 32
113; CHECK: ldc1    $f0, 32($sp)
114}
115
116; int
117define i32 @va5(i32 %a, i32 %b, i32 %c, ...) nounwind {
118entry:
119  %a.addr = alloca i32, align 4
120  %b.addr = alloca i32, align 4
121  %c.addr = alloca i32, align 4
122  %ap = alloca i8*, align 4
123  %d = alloca i32, align 4
124  store i32 %a, i32* %a.addr, align 4
125  store i32 %b, i32* %b.addr, align 4
126  store i32 %c, i32* %c.addr, align 4
127  %ap1 = bitcast i8** %ap to i8*
128  call void @llvm.va_start(i8* %ap1)
129  %0 = va_arg i8** %ap, i32
130  store i32 %0, i32* %d, align 4
131  %ap2 = bitcast i8** %ap to i8*
132  call void @llvm.va_end(i8* %ap2)
133  %tmp = load i32* %d, align 4
134  ret i32 %tmp
135
136; CHECK: va5:
137; CHECK: addiu   $sp, $sp, -24
138; CHECK: sw      $7, 36($sp)
139; CHECK: lw      $2, 36($sp)
140}
141
142; double
143define double @va6(i32 %a, i32 %b, i32 %c, ...) nounwind {
144entry:
145  %a.addr = alloca i32, align 4
146  %b.addr = alloca i32, align 4
147  %c.addr = alloca i32, align 4
148  %ap = alloca i8*, align 4
149  %d = alloca double, align 8
150  store i32 %a, i32* %a.addr, align 4
151  store i32 %b, i32* %b.addr, align 4
152  store i32 %c, i32* %c.addr, align 4
153  %ap1 = bitcast i8** %ap to i8*
154  call void @llvm.va_start(i8* %ap1)
155  %0 = va_arg i8** %ap, double
156  store double %0, double* %d, align 8
157  %ap2 = bitcast i8** %ap to i8*
158  call void @llvm.va_end(i8* %ap2)
159  %tmp = load double* %d, align 8
160  ret double %tmp
161
162; CHECK: va6:
163; CHECK: addiu   $sp, $sp, -24
164; CHECK: sw      $7, 36($sp)
165; CHECK: addiu   $[[R0:[0-9]+]], $sp, 36
166; CHECK: addiu   $[[R1:[0-9]+]], $[[R0]], 7
167; CHECK: addiu   $[[R2:[0-9]+]], $zero, -8
168; CHECK: and     $[[R3:[0-9]+]], $[[R1]], $[[R2]]
169; CHECK: ldc1    $f0, 0($[[R3]])
170}
171
172; int
173define i32 @va7(i32 %a, double %b, ...) nounwind {
174entry:
175  %a.addr = alloca i32, align 4
176  %b.addr = alloca double, align 8
177  %ap = alloca i8*, align 4
178  %c = alloca i32, align 4
179  store i32 %a, i32* %a.addr, align 4
180  store double %b, double* %b.addr, align 8
181  %ap1 = bitcast i8** %ap to i8*
182  call void @llvm.va_start(i8* %ap1)
183  %0 = va_arg i8** %ap, i32
184  store i32 %0, i32* %c, align 4
185  %ap2 = bitcast i8** %ap to i8*
186  call void @llvm.va_end(i8* %ap2)
187  %tmp = load i32* %c, align 4
188  ret i32 %tmp
189
190; CHECK: va7:
191; CHECK: addiu   $sp, $sp, -24
192; CHECK: lw      $2, 40($sp)
193}
194
195; double
196define double @va8(i32 %a, double %b, ...) nounwind {
197entry:
198  %a.addr = alloca i32, align 4
199  %b.addr = alloca double, align 8
200  %ap = alloca i8*, align 4
201  %c = alloca double, align 8
202  store i32 %a, i32* %a.addr, align 4
203  store double %b, double* %b.addr, align 8
204  %ap1 = bitcast i8** %ap to i8*
205  call void @llvm.va_start(i8* %ap1)
206  %0 = va_arg i8** %ap, double
207  store double %0, double* %c, align 8
208  %ap2 = bitcast i8** %ap to i8*
209  call void @llvm.va_end(i8* %ap2)
210  %tmp = load double* %c, align 8
211  ret double %tmp
212
213; CHECK: va8:
214; CHECK: addiu   $sp, $sp, -32
215; CHECK: addiu   ${{[0-9]+}}, $sp, 48
216; CHECK: ldc1    $f0, 48($sp)
217}
218
219; int
220define i32 @va9(double %a, double %b, i32 %c, ...) nounwind {
221entry:
222  %a.addr = alloca double, align 8
223  %b.addr = alloca double, align 8
224  %c.addr = alloca i32, align 4
225  %ap = alloca i8*, align 4
226  %d = alloca i32, align 4
227  store double %a, double* %a.addr, align 8
228  store double %b, double* %b.addr, align 8
229  store i32 %c, i32* %c.addr, align 4
230  %ap1 = bitcast i8** %ap to i8*
231  call void @llvm.va_start(i8* %ap1)
232  %0 = va_arg i8** %ap, i32
233  store i32 %0, i32* %d, align 4
234  %ap2 = bitcast i8** %ap to i8*
235  call void @llvm.va_end(i8* %ap2)
236  %tmp = load i32* %d, align 4
237  ret i32 %tmp
238
239; CHECK: va9:
240; CHECK: addiu   $sp, $sp, -32
241; CHECK: lw      $2, 52($sp)
242}
243
244; double
245define double @va10(double %a, double %b, i32 %c, ...) nounwind {
246entry:
247  %a.addr = alloca double, align 8
248  %b.addr = alloca double, align 8
249  %c.addr = alloca i32, align 4
250  %ap = alloca i8*, align 4
251  %d = alloca double, align 8
252  store double %a, double* %a.addr, align 8
253  store double %b, double* %b.addr, align 8
254  store i32 %c, i32* %c.addr, align 4
255  %ap1 = bitcast i8** %ap to i8*
256  call void @llvm.va_start(i8* %ap1)
257  %0 = va_arg i8** %ap, double
258  store double %0, double* %d, align 8
259  %ap2 = bitcast i8** %ap to i8*
260  call void @llvm.va_end(i8* %ap2)
261  %tmp = load double* %d, align 8
262  ret double %tmp
263
264; CHECK: va10:
265; CHECK: addiu   $sp, $sp, -32
266; CHECK: addiu   $[[R0:[0-9]+]], $sp, 52
267; CHECK: addiu   $[[R1:[0-9]+]], $[[R0]], 7
268; CHECK: addiu   $[[R2:[0-9]+]], $zero, -8
269; CHECK: and     $[[R3:[0-9]+]], $[[R1]], $[[R2]]
270; CHECK: ldc1    $f0, 0($[[R3]])
271}
272