Codegen: [PPC] Handle weighted comparisons when inserting selects.
[oota-llvm.git] / test / CodeGen / Mips / cconv / arguments-varargs.ll
1 ; RUN: llc -mtriple=mips-linux -relocation-model=static < %s | FileCheck --check-prefix=ALL --check-prefix=O32 --check-prefix=O32-BE %s
2 ; RUN: llc -mtriple=mipsel-linux -relocation-model=static < %s | FileCheck --check-prefix=ALL --check-prefix=O32 --check-prefix=O32-LE %s
3
4 ; RUN-TODO: llc -march=mips64 -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
5 ; RUN-TODO: llc -march=mips64el -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
6
7 ; RUN: llc -mtriple=mips64-linux -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefix=ALL --check-prefix=NEW --check-prefix=N32 --check-prefix=NEW-BE %s
8 ; RUN: llc -mtriple=mips64el-linux -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefix=ALL --check-prefix=NEW --check-prefix=N32 --check-prefix=NEW-LE %s
9
10 ; RUN: llc -march=mips64 -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefix=ALL --check-prefix=NEW --check-prefix=N64 --check-prefix=NEW-BE %s
11 ; RUN: llc -march=mips64el -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefix=ALL --check-prefix=NEW --check-prefix=N64 --check-prefix=NEW-LE %s
12
13 @hwords = global [3 x i16] zeroinitializer, align 1
14 @words  = global [3 x i32] zeroinitializer, align 1
15 @dwords = global [3 x i64] zeroinitializer, align 1
16
17 define void @fn_i16_dotdotdot_i16(i16 %a, ...) {
18 entry:
19 ; ALL-LABEL: fn_i16_dotdotdot_i16:
20
21 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
22 ; the argument save area (56 bytes).
23 ; O32:           addiu  [[SP:\$sp]], $sp, -8
24 ; N32:           addiu  [[SP:\$sp]], $sp, -64
25 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
26
27 ; Save variable argument portion on the stack
28 ; O32-DAG:       sw $7, 20([[SP]])
29 ; O32-DAG:       sw $6, 16([[SP]])
30 ; O32-DAG:       sw $5, 12([[SP]])
31
32 ; NEW-DAG:       sd $11, 56([[SP]])
33 ; NEW-DAG:       sd $10, 48([[SP]])
34 ; NEW-DAG:       sd $9, 40([[SP]])
35 ; NEW-DAG:       sd $8, 32([[SP]])
36 ; NEW-DAG:       sd $7, 24([[SP]])
37 ; NEW-DAG:       sd $6, 16([[SP]])
38 ; NEW-DAG:       sd $5, 8([[SP]])
39
40 ; Initialize variable argument pointer.
41 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
42 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
43 ; fixed argument.
44 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
45 ; space.
46 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
47 ; O32-DAG:       sw [[VA]], 0([[SP]])
48
49 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
50 ; N32-DAG:       sw [[VA]], 0([[SP]])
51
52 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
53 ; N64-DAG:       sd [[VA]], 0([[SP]])
54
55 ; Store [[VA]]
56 ; O32-DAG:       sw [[VA]], 0([[SP]])
57
58 ; ALL: teqi $zero, 1
59
60 ; Increment [[VA]]
61 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
62 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
63 ; O32-DAG:       sw [[VA2]], 0([[SP]])
64
65 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
66 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
67 ; N32-DAG:       sw [[VA2]], 0([[SP]])
68
69 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
70 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
71 ; N64-DAG:       sd [[VA2]], 0([[SP]])
72
73 ; Load the first argument from the variable portion.
74 ; This has used the stack pointer directly rather than the [[VA]] we just set
75 ; up.
76 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
77 ; order.
78 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
79
80 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
81 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
82
83 ; Copy the arg to the global
84 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
85
86 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
87
88 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(hwords)(
89
90 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
91
92 ; ALL: teqi $zero, 2
93
94 ; Increment [[VA]] again.
95 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
96 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
97 ; O32-DAG:       sw [[VA2]], 0([[SP]])
98
99 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
100 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
101 ; N32-DAG:       sw [[VA3]], 0([[SP]])
102
103 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
104 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
105 ; N64-DAG:       sd [[VA3]], 0([[SP]])
106
107 ; Load the second argument from the variable portion.
108 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
109
110 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
111 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
112
113 ; Copy the arg to the global
114 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
115
116   %ap = alloca i8*, align 8
117   %ap2 = bitcast i8** %ap to i8*
118   call void @llvm.va_start(i8* %ap2)
119
120   call void asm sideeffect "teqi $$zero, 1", ""()
121   %arg1 = va_arg i8** %ap, i16
122   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
123   store volatile i16 %arg1, i16* %e1, align 2
124
125   call void asm sideeffect "teqi $$zero, 2", ""()
126   %arg2 = va_arg i8** %ap, i16
127   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
128   store volatile i16 %arg2, i16* %e2, align 2
129
130   call void @llvm.va_end(i8* %ap2)
131
132   ret void
133 }
134
135 define void @fn_i16_dotdotdot_i32(i16 %a, ...) {
136 entry:
137 ; ALL-LABEL: fn_i16_dotdotdot_i32:
138
139 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
140 ; the argument save area (56 bytes).
141 ; O32:           addiu  [[SP:\$sp]], $sp, -8
142 ; N32:           addiu  [[SP:\$sp]], $sp, -64
143 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
144
145 ; Save variable argument portion on the stack
146 ; O32-DAG:       sw $7, 20([[SP]])
147 ; O32-DAG:       sw $6, 16([[SP]])
148 ; O32-DAG:       sw $5, 12([[SP]])
149
150 ; NEW-DAG:       sd $11, 56([[SP]])
151 ; NEW-DAG:       sd $10, 48([[SP]])
152 ; NEW-DAG:       sd $9, 40([[SP]])
153 ; NEW-DAG:       sd $8, 32([[SP]])
154 ; NEW-DAG:       sd $7, 24([[SP]])
155 ; NEW-DAG:       sd $6, 16([[SP]])
156 ; NEW-DAG:       sd $5, 8([[SP]])
157
158 ; Initialize variable argument pointer.
159 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
160 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
161 ; fixed argument.
162 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
163 ; space.
164 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
165 ; O32-DAG:       sw [[VA]], 0([[SP]])
166
167 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
168 ; N32-DAG:       sw [[VA]], 0([[SP]])
169
170 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
171 ; N64-DAG:       sd [[VA]], 0([[SP]])
172
173 ; Store [[VA]]
174 ; O32-DAG:       sw [[VA]], 0([[SP]])
175
176 ; ALL: teqi $zero, 1
177
178 ; Increment [[VA]]
179 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
180 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
181 ; O32-DAG:       sw [[VA2]], 0([[SP]])
182
183 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
184 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
185 ; N32-DAG:       sw [[VA2]], 0([[SP]])
186
187 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
188 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
189 ; N64-DAG:       sd [[VA2]], 0([[SP]])
190
191 ; Load the first argument from the variable portion.
192 ; This has used the stack pointer directly rather than the [[VA]] we just set
193 ; up.
194 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
195 ; order.
196 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
197
198 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
199 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
200
201 ; Copy the arg to the global
202 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
203
204 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
205
206 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(words)(
207
208 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
209
210 ; ALL: teqi $zero, 2
211
212 ; Increment [[VA]] again.
213 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
214 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
215 ; O32-DAG:       sw [[VA2]], 0([[SP]])
216
217 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
218 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
219 ; N32-DAG:       sw [[VA3]], 0([[SP]])
220
221 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
222 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
223 ; N64-DAG:       sd [[VA3]], 0([[SP]])
224
225 ; Load the second argument from the variable portion.
226 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
227
228 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
229 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
230
231 ; Copy the arg to the global
232 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
233
234   %ap = alloca i8*, align 8
235   %ap2 = bitcast i8** %ap to i8*
236   call void @llvm.va_start(i8* %ap2)
237
238   call void asm sideeffect "teqi $$zero, 1", ""()
239   %arg1 = va_arg i8** %ap, i32
240   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
241   store volatile i32 %arg1, i32* %e1, align 4
242
243   call void asm sideeffect "teqi $$zero, 2", ""()
244   %arg2 = va_arg i8** %ap, i32
245   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
246   store volatile i32 %arg2, i32* %e2, align 4
247
248   call void @llvm.va_end(i8* %ap2)
249
250   ret void
251 }
252
253 define void @fn_i16_dotdotdot_i64(i16 %a, ...) {
254 entry:
255 ; ALL-LABEL: fn_i16_dotdotdot_i64:
256
257 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
258 ; the argument save area (56 bytes).
259 ; O32:           addiu  [[SP:\$sp]], $sp, -8
260 ; N32:           addiu  [[SP:\$sp]], $sp, -64
261 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
262
263 ; Save variable argument portion on the stack
264 ; O32-DAG:       sw $7, 20([[SP]])
265 ; O32-DAG:       sw $6, 16([[SP]])
266 ; O32-DAG:       sw $5, 12([[SP]])
267
268 ; NEW-DAG:       sd $11, 56([[SP]])
269 ; NEW-DAG:       sd $10, 48([[SP]])
270 ; NEW-DAG:       sd $9, 40([[SP]])
271 ; NEW-DAG:       sd $8, 32([[SP]])
272 ; NEW-DAG:       sd $7, 24([[SP]])
273 ; NEW-DAG:       sd $6, 16([[SP]])
274 ; NEW-DAG:       sd $5, 8([[SP]])
275
276 ; Initialize variable argument pointer.
277 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
278 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
279 ; fixed argument.
280 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
281 ; space.
282 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
283 ; O32-DAG:       sw [[VA]], 0([[SP]])
284
285 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
286 ; N32-DAG:       sw [[VA]], 0([[SP]])
287
288 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
289 ; N64-DAG:       sd [[VA]], 0([[SP]])
290
291 ; Store [[VA]]
292 ; O32-DAG:       sw [[VA]], 0([[SP]])
293
294 ; ALL: teqi $zero, 1
295
296 ; Increment [[VA]] (and realign pointer for O32)
297 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
298 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
299 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
300 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
301 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
302 ; O32-DAG:       sw [[VA2]], 0([[SP]])
303
304 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
305 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
306 ; N32-DAG:       sw [[VA2]], 0([[SP]])
307
308 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
309 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
310 ; N64-DAG:       sd [[VA2]], 0([[SP]])
311
312 ; Load the first argument from the variable portion and copy it to the global.
313 ; This has used the stack pointer directly rather than the [[VA]] we just set
314 ; up.
315 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
316 ; order.
317 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
318 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
319 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
320 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
321 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
322 ; O32-DAG:       sw [[VA2]], 0([[SP]])
323 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
324 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
325
326 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
327 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
328 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
329 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
330
331 ; ALL: teqi $zero, 2
332
333 ; Increment [[VA]] again.
334 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
335 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
336 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
337 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
338 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
339 ; O32-DAG:       sw [[VA2]], 0([[SP]])
340
341 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
342 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
343 ; N32-DAG:       sw [[VA3]], 0([[SP]])
344
345 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
346 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
347 ; N64-DAG:       sd [[VA3]], 0([[SP]])
348
349 ; Load the second argument from the variable portion and copy it to the global.
350 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
351 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
352 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
353 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
354 ; O32-DAG:       sw [[VA2]], 0([[SP]])
355 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
356 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
357
358 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
359 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
360
361   %ap = alloca i8*, align 8
362   %ap2 = bitcast i8** %ap to i8*
363   call void @llvm.va_start(i8* %ap2)
364
365   call void asm sideeffect "teqi $$zero, 1", ""()
366   %arg1 = va_arg i8** %ap, i64
367   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
368   store volatile i64 %arg1, i64* %e1, align 8
369
370   call void asm sideeffect "teqi $$zero, 2", ""()
371   %arg2 = va_arg i8** %ap, i64
372   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
373   store volatile i64 %arg2, i64* %e2, align 8
374
375   call void @llvm.va_end(i8* %ap2)
376
377   ret void
378 }
379
380 define void @fn_i32_dotdotdot_i16(i32 %a, ...) {
381 entry:
382 ; ALL-LABEL: fn_i32_dotdotdot_i16:
383
384 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
385 ; the argument save area (56 bytes).
386 ; O32:           addiu  [[SP:\$sp]], $sp, -8
387 ; N32:           addiu  [[SP:\$sp]], $sp, -64
388 ; N64:           daddiu [[SP:\$sp]], $sp, -64
389
390 ; Save variable argument portion on the stack
391 ; O32-DAG:       sw $7, 20([[SP]])
392 ; O32-DAG:       sw $6, 16([[SP]])
393 ; O32-DAG:       sw $5, 12([[SP]])
394
395 ; NEW-DAG:       sd $11, 56([[SP]])
396 ; NEW-DAG:       sd $10, 48([[SP]])
397 ; NEW-DAG:       sd $9, 40([[SP]])
398 ; NEW-DAG:       sd $8, 32([[SP]])
399 ; NEW-DAG:       sd $7, 24([[SP]])
400 ; NEW-DAG:       sd $6, 16([[SP]])
401 ; NEW-DAG:       sd $5, 8([[SP]])
402
403 ; Initialize variable argument pointer.
404 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
405 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
406 ; fixed argument.
407 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
408 ; space.
409 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
410 ; O32-DAG:       sw [[VA]], 0([[SP]])
411
412 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
413 ; N32-DAG:       sw [[VA]], 0([[SP]])
414
415 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
416 ; N64-DAG:       sd [[VA]], 0([[SP]])
417
418 ; Store [[VA]]
419 ; O32-DAG:       sw [[VA]], 0([[SP]])
420
421 ; ALL: teqi $zero, 1
422
423 ; Increment [[VA]]
424 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
425 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
426 ; O32-DAG:       sw [[VA2]], 0([[SP]])
427
428 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
429 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
430 ; N32-DAG:       sw [[VA2]], 0([[SP]])
431
432 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
433 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
434 ; N64-DAG:       sd [[VA2]], 0([[SP]])
435
436 ; Load the first argument from the variable portion.
437 ; This has used the stack pointer directly rather than the [[VA]] we just set
438 ; up.
439 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
440 ; order.
441 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
442
443 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
444 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
445
446 ; Copy the arg to the global
447 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
448
449 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
450
451 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(hwords)(
452
453 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
454
455 ; ALL: teqi $zero, 2
456
457 ; Increment [[VA]] again.
458 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
459 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
460 ; O32-DAG:       sw [[VA2]], 0([[SP]])
461
462 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
463 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
464 ; N32-DAG:       sw [[VA3]], 0([[SP]])
465
466 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
467 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
468 ; N64-DAG:       sd [[VA3]], 0([[SP]])
469
470 ; Load the second argument from the variable portion.
471 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
472
473 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
474 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
475
476 ; Copy the arg to the global
477 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
478
479   %ap = alloca i8*, align 8
480   %ap2 = bitcast i8** %ap to i8*
481   call void @llvm.va_start(i8* %ap2)
482
483   call void asm sideeffect "teqi $$zero, 1", ""()
484   %arg1 = va_arg i8** %ap, i16
485   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
486   store volatile i16 %arg1, i16* %e1, align 2
487
488   call void asm sideeffect "teqi $$zero, 2", ""()
489   %arg2 = va_arg i8** %ap, i16
490   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
491   store volatile i16 %arg2, i16* %e2, align 2
492
493   call void @llvm.va_end(i8* %ap2)
494
495   ret void
496 }
497
498 define void @fn_i32_dotdotdot_i32(i32 %a, ...) {
499 entry:
500 ; ALL-LABEL: fn_i32_dotdotdot_i32:
501
502 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
503 ; the argument save area (56 bytes).
504 ; O32:           addiu  [[SP:\$sp]], $sp, -8
505 ; N32:           addiu  [[SP:\$sp]], $sp, -64
506 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
507
508 ; Save variable argument portion on the stack
509 ; O32-DAG:       sw $7, 20([[SP]])
510 ; O32-DAG:       sw $6, 16([[SP]])
511 ; O32-DAG:       sw $5, 12([[SP]])
512
513 ; NEW-DAG:       sd $11, 56([[SP]])
514 ; NEW-DAG:       sd $10, 48([[SP]])
515 ; NEW-DAG:       sd $9, 40([[SP]])
516 ; NEW-DAG:       sd $8, 32([[SP]])
517 ; NEW-DAG:       sd $7, 24([[SP]])
518 ; NEW-DAG:       sd $6, 16([[SP]])
519 ; NEW-DAG:       sd $5, 8([[SP]])
520
521 ; Initialize variable argument pointer.
522 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
523 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
524 ; fixed argument.
525 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
526 ; space.
527 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
528 ; O32-DAG:       sw [[VA]], 0([[SP]])
529
530 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
531 ; N32-DAG:       sw [[VA]], 0([[SP]])
532
533 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
534 ; N64-DAG:       sd [[VA]], 0([[SP]])
535
536 ; Store [[VA]]
537 ; O32-DAG:       sw [[VA]], 0([[SP]])
538
539 ; ALL: teqi $zero, 1
540
541 ; Increment [[VA]]
542 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
543 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
544 ; O32-DAG:       sw [[VA2]], 0([[SP]])
545
546 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
547 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
548 ; N32-DAG:       sw [[VA2]], 0([[SP]])
549
550 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
551 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
552 ; N64-DAG:       sd [[VA2]], 0([[SP]])
553
554 ; Load the first argument from the variable portion.
555 ; This has used the stack pointer directly rather than the [[VA]] we just set
556 ; up.
557 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
558 ; order.
559 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
560
561 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
562 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
563
564 ; Copy the arg to the global
565 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
566
567 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
568
569 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(words)(
570
571 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
572
573 ; ALL: teqi $zero, 2
574
575 ; Increment [[VA]] again.
576 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
577 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
578 ; O32-DAG:       sw [[VA2]], 0([[SP]])
579
580 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
581 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
582 ; N32-DAG:       sw [[VA3]], 0([[SP]])
583
584 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
585 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
586 ; N64-DAG:       sd [[VA3]], 0([[SP]])
587
588 ; Load the second argument from the variable portion.
589 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
590
591 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
592 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
593
594 ; Copy the arg to the global
595 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
596
597   %ap = alloca i8*, align 8
598   %ap2 = bitcast i8** %ap to i8*
599   call void @llvm.va_start(i8* %ap2)
600
601   call void asm sideeffect "teqi $$zero, 1", ""()
602   %arg1 = va_arg i8** %ap, i32
603   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
604   store volatile i32 %arg1, i32* %e1, align 4
605
606   call void asm sideeffect "teqi $$zero, 2", ""()
607   %arg2 = va_arg i8** %ap, i32
608   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
609   store volatile i32 %arg2, i32* %e2, align 4
610
611   call void @llvm.va_end(i8* %ap2)
612
613   ret void
614 }
615
616 define void @fn_i32_dotdotdot_i64(i32 %a, ...) {
617 entry:
618 ; ALL-LABEL: fn_i32_dotdotdot_i64:
619
620 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
621 ; the argument save area (56 bytes).
622 ; O32:           addiu  [[SP:\$sp]], $sp, -8
623 ; N32:           addiu  [[SP:\$sp]], $sp, -64
624 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
625
626 ; Save variable argument portion on the stack
627 ; O32-DAG:       sw $7, 20([[SP]])
628 ; O32-DAG:       sw $6, 16([[SP]])
629 ; O32-DAG:       sw $5, 12([[SP]])
630
631 ; NEW-DAG:       sd $11, 56([[SP]])
632 ; NEW-DAG:       sd $10, 48([[SP]])
633 ; NEW-DAG:       sd $9, 40([[SP]])
634 ; NEW-DAG:       sd $8, 32([[SP]])
635 ; NEW-DAG:       sd $7, 24([[SP]])
636 ; NEW-DAG:       sd $6, 16([[SP]])
637 ; NEW-DAG:       sd $5, 8([[SP]])
638
639 ; Initialize variable argument pointer.
640 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
641 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
642 ; fixed argument.
643 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
644 ; space.
645 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
646 ; O32-DAG:       sw [[VA]], 0([[SP]])
647
648 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
649 ; N32-DAG:       sw [[VA]], 0([[SP]])
650
651 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
652 ; N64-DAG:       sd [[VA]], 0([[SP]])
653
654 ; Store [[VA]]
655 ; O32-DAG:       sw [[VA]], 0([[SP]])
656
657 ; ALL: teqi $zero, 1
658
659 ; Increment [[VA]] (and realign pointer for O32)
660 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
661 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
662 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
663 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
664 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
665 ; O32-DAG:       sw [[VA2]], 0([[SP]])
666
667 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
668 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
669 ; N32-DAG:       sw [[VA2]], 0([[SP]])
670
671 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
672 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
673 ; N64-DAG:       sd [[VA2]], 0([[SP]])
674
675 ; Load the first argument from the variable portion and copy it to the global.
676 ; This has used the stack pointer directly rather than the [[VA]] we just set
677 ; up.
678 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
679 ; order.
680 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
681 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
682 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
683 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
684 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
685 ; O32-DAG:       sw [[VA2]], 0([[SP]])
686 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
687 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
688
689 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
690 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
691 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
692 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
693
694 ; ALL: teqi $zero, 2
695
696 ; Increment [[VA]] again.
697 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
698 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
699 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
700 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
701 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
702 ; O32-DAG:       sw [[VA2]], 0([[SP]])
703
704 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
705 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
706 ; N32-DAG:       sw [[VA3]], 0([[SP]])
707
708 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
709 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
710 ; N64-DAG:       sd [[VA3]], 0([[SP]])
711
712 ; Load the second argument from the variable portion and copy it to the global.
713 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
714 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
715 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
716 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
717 ; O32-DAG:       sw [[VA2]], 0([[SP]])
718 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
719 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
720
721 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
722 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
723
724   %ap = alloca i8*, align 8
725   %ap2 = bitcast i8** %ap to i8*
726   call void @llvm.va_start(i8* %ap2)
727
728   call void asm sideeffect "teqi $$zero, 1", ""()
729   %arg1 = va_arg i8** %ap, i64
730   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
731   store volatile i64 %arg1, i64* %e1, align 8
732
733   call void asm sideeffect "teqi $$zero, 2", ""()
734   %arg2 = va_arg i8** %ap, i64
735   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
736   store volatile i64 %arg2, i64* %e2, align 8
737
738   call void @llvm.va_end(i8* %ap2)
739
740   ret void
741 }
742
743 define void @fn_i64_dotdotdot_i16(i64 %a, ...) {
744 entry:
745 ; ALL-LABEL: fn_i64_dotdotdot_i16:
746
747 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
748 ; the argument save area (56 bytes).
749 ; O32:           addiu  [[SP:\$sp]], $sp, -8
750 ; N32:           addiu  [[SP:\$sp]], $sp, -64
751 ; N64:           daddiu [[SP:\$sp]], $sp, -64
752
753 ; Save variable argument portion on the stack
754 ; O32-DAG:       sw $7, 20([[SP]])
755 ; O32-DAG:       sw $6, 16([[SP]])
756
757 ; NEW-DAG:       sd $11, 56([[SP]])
758 ; NEW-DAG:       sd $10, 48([[SP]])
759 ; NEW-DAG:       sd $9, 40([[SP]])
760 ; NEW-DAG:       sd $8, 32([[SP]])
761 ; NEW-DAG:       sd $7, 24([[SP]])
762 ; NEW-DAG:       sd $6, 16([[SP]])
763 ; NEW-DAG:       sd $5, 8([[SP]])
764
765 ; Initialize variable argument pointer.
766 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
767 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
768 ; first fixed argument.
769 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
770 ; space.
771 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
772 ; O32-DAG:       sw [[VA]], 0([[SP]])
773
774 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
775 ; N32-DAG:       sw [[VA]], 0([[SP]])
776
777 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
778 ; N64-DAG:       sd [[VA]], 0([[SP]])
779
780 ; Store [[VA]]
781 ; O32-DAG:       sw [[VA]], 0([[SP]])
782
783 ; ALL: teqi $zero, 1
784
785 ; Increment [[VA]]
786 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
787 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
788 ; O32-DAG:       sw [[VA2]], 0([[SP]])
789
790 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
791 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
792 ; N32-DAG:       sw [[VA2]], 0([[SP]])
793
794 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
795 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
796 ; N64-DAG:       sd [[VA2]], 0([[SP]])
797
798 ; Load the first argument from the variable portion.
799 ; This has used the stack pointer directly rather than the [[VA]] we just set
800 ; up.
801 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
802 ; order.
803 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
804
805 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
806 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
807
808 ; Copy the arg to the global
809 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
810
811 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
812
813 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(hwords)(
814
815 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
816
817 ; ALL: teqi $zero, 2
818
819 ; Increment [[VA]] again.
820 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
821 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
822 ; O32-DAG:       sw [[VA2]], 0([[SP]])
823
824 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
825 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
826 ; N32-DAG:       sw [[VA3]], 0([[SP]])
827
828 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
829 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
830 ; N64-DAG:       sd [[VA3]], 0([[SP]])
831
832 ; Load the second argument from the variable portion.
833 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
834
835 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
836 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
837
838 ; Copy the arg to the global
839 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
840
841   %ap = alloca i8*, align 8
842   %ap2 = bitcast i8** %ap to i8*
843   call void @llvm.va_start(i8* %ap2)
844
845   call void asm sideeffect "teqi $$zero, 1", ""()
846   %arg1 = va_arg i8** %ap, i16
847   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
848   store volatile i16 %arg1, i16* %e1, align 2
849
850   call void asm sideeffect "teqi $$zero, 2", ""()
851   %arg2 = va_arg i8** %ap, i16
852   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
853   store volatile i16 %arg2, i16* %e2, align 2
854
855   call void @llvm.va_end(i8* %ap2)
856
857   ret void
858 }
859
860 define void @fn_i64_dotdotdot_i32(i64 %a, ...) {
861 entry:
862 ; ALL-LABEL: fn_i64_dotdotdot_i32:
863
864 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
865 ; the argument save area (56 bytes).
866 ; O32:           addiu  [[SP:\$sp]], $sp, -8
867 ; N32:           addiu  [[SP:\$sp]], $sp, -64
868 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
869
870 ; Save variable argument portion on the stack
871 ; O32-DAG:       sw $7, 20([[SP]])
872 ; O32-DAG:       sw $6, 16([[SP]])
873
874 ; NEW-DAG:       sd $11, 56([[SP]])
875 ; NEW-DAG:       sd $10, 48([[SP]])
876 ; NEW-DAG:       sd $9, 40([[SP]])
877 ; NEW-DAG:       sd $8, 32([[SP]])
878 ; NEW-DAG:       sd $7, 24([[SP]])
879 ; NEW-DAG:       sd $6, 16([[SP]])
880 ; NEW-DAG:       sd $5, 8([[SP]])
881
882 ; Initialize variable argument pointer.
883 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
884 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
885 ; first fixed argument.
886 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
887 ; space.
888 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
889 ; O32-DAG:       sw [[VA]], 0([[SP]])
890
891 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
892 ; N32-DAG:       sw [[VA]], 0([[SP]])
893
894 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
895 ; N64-DAG:       sd [[VA]], 0([[SP]])
896
897 ; Store [[VA]]
898 ; O32-DAG:       sw [[VA]], 0([[SP]])
899
900 ; ALL: teqi $zero, 1
901
902 ; Increment [[VA]]
903 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
904 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
905 ; O32-DAG:       sw [[VA2]], 0([[SP]])
906
907 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
908 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
909 ; N32-DAG:       sw [[VA2]], 0([[SP]])
910
911 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
912 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
913 ; N64-DAG:       sd [[VA2]], 0([[SP]])
914
915 ; Load the first argument from the variable portion.
916 ; This has used the stack pointer directly rather than the [[VA]] we just set
917 ; up.
918 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
919 ; order.
920 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
921
922 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
923 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
924
925 ; Copy the arg to the global
926 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
927
928 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
929
930 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(words)(
931
932 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
933
934 ; ALL: teqi $zero, 2
935
936 ; Increment [[VA]] again.
937 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
938 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
939 ; O32-DAG:       sw [[VA2]], 0([[SP]])
940
941 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
942 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
943 ; N32-DAG:       sw [[VA3]], 0([[SP]])
944
945 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
946 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
947 ; N64-DAG:       sd [[VA3]], 0([[SP]])
948
949 ; Load the second argument from the variable portion.
950 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
951
952 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
953 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
954
955 ; Copy the arg to the global
956 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
957
958   %ap = alloca i8*, align 8
959   %ap2 = bitcast i8** %ap to i8*
960   call void @llvm.va_start(i8* %ap2)
961
962   call void asm sideeffect "teqi $$zero, 1", ""()
963   %arg1 = va_arg i8** %ap, i32
964   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
965   store volatile i32 %arg1, i32* %e1, align 4
966
967   call void asm sideeffect "teqi $$zero, 2", ""()
968   %arg2 = va_arg i8** %ap, i32
969   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
970   store volatile i32 %arg2, i32* %e2, align 4
971
972   call void @llvm.va_end(i8* %ap2)
973
974   ret void
975 }
976
977 define void @fn_i64_dotdotdot_i64(i64 %a, ...) {
978 entry:
979 ; ALL-LABEL: fn_i64_dotdotdot_i64:
980
981 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
982 ; the argument save area (56 bytes).
983 ; O32:           addiu  [[SP:\$sp]], $sp, -8
984 ; N32:           addiu  [[SP:\$sp]], $sp, -64
985 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
986
987 ; Save variable argument portion on the stack
988 ; O32-DAG:       sw $7, 20([[SP]])
989 ; O32-DAG:       sw $6, 16([[SP]])
990
991 ; NEW-DAG:       sd $11, 56([[SP]])
992 ; NEW-DAG:       sd $10, 48([[SP]])
993 ; NEW-DAG:       sd $9, 40([[SP]])
994 ; NEW-DAG:       sd $8, 32([[SP]])
995 ; NEW-DAG:       sd $7, 24([[SP]])
996 ; NEW-DAG:       sd $6, 16([[SP]])
997 ; NEW-DAG:       sd $5, 8([[SP]])
998
999 ; Initialize variable argument pointer.
1000 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
1001 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
1002 ; first fixed argument.
1003 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
1004 ; space.
1005 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
1006 ; O32-DAG:       sw [[VA]], 0([[SP]])
1007
1008 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
1009 ; N32-DAG:       sw [[VA]], 0([[SP]])
1010
1011 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
1012 ; N64-DAG:       sd [[VA]], 0([[SP]])
1013
1014 ; Store [[VA]]
1015 ; O32-DAG:       sw [[VA]], 0([[SP]])
1016
1017 ; ALL: teqi $zero, 1
1018
1019 ; Increment [[VA]] (and realign pointer for O32)
1020 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
1021 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
1022 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
1023 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
1024 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
1025 ; O32-DAG:       sw [[VA2]], 0([[SP]])
1026
1027 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
1028 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
1029 ; N32-DAG:       sw [[VA2]], 0([[SP]])
1030
1031 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
1032 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
1033 ; N64-DAG:       sd [[VA2]], 0([[SP]])
1034
1035 ; Load the first argument from the variable portion and copy it to the global.
1036 ; This has used the stack pointer directly rather than the [[VA]] we just set
1037 ; up.
1038 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
1039 ; order.
1040 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
1041 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
1042 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
1043 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
1044 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
1045 ; O32-DAG:       sw [[VA2]], 0([[SP]])
1046 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
1047 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
1048
1049 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
1050 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
1051 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
1052 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
1053
1054 ; ALL: teqi $zero, 2
1055
1056 ; Increment [[VA]] again.
1057 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
1058 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
1059 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
1060 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
1061 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
1062 ; O32-DAG:       sw [[VA2]], 0([[SP]])
1063
1064 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
1065 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
1066 ; N32-DAG:       sw [[VA3]], 0([[SP]])
1067
1068 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
1069 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
1070 ; N64-DAG:       sd [[VA3]], 0([[SP]])
1071
1072 ; Load the second argument from the variable portion and copy it to the global.
1073 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
1074 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
1075 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
1076 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
1077 ; O32-DAG:       sw [[VA2]], 0([[SP]])
1078 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
1079 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
1080
1081 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
1082 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
1083
1084   %ap = alloca i8*, align 8
1085   %ap2 = bitcast i8** %ap to i8*
1086   call void @llvm.va_start(i8* %ap2)
1087
1088   call void asm sideeffect "teqi $$zero, 1", ""()
1089   %arg1 = va_arg i8** %ap, i64
1090   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
1091   store volatile i64 %arg1, i64* %e1, align 8
1092
1093   call void asm sideeffect "teqi $$zero, 2", ""()
1094   %arg2 = va_arg i8** %ap, i64
1095   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
1096   store volatile i64 %arg2, i64* %e2, align 8
1097
1098   call void @llvm.va_end(i8* %ap2)
1099
1100   ret void
1101 }
1102
1103 declare void @llvm.va_start(i8*)
1104 declare void @llvm.va_end(i8*)