[llvm-objdump] - Remove one overload of reportError. NFCI.
[llvm-complete.git] / test / CodeGen / Mips / cconv / arguments-varargs.ll
blob275f6afbf774277cbfe946ca2d75e1b49e391321
1 ; RUN: llc -mtriple=mips-linux -relocation-model=static < %s \
2 ; RUN:   | FileCheck --check-prefixes=ALL,O32,O32-BE %s
3 ; RUN: llc -mtriple=mipsel-linux -relocation-model=static < %s \
4 ; RUN:   | FileCheck --check-prefixes=ALL,O32,O32-LE %s
6 ; RUN-TODO: llc -march=mips64 -relocation-model=static -target-abi o32 < %s \
7 ; RUN-TODO:   | FileCheck --check-prefixes=ALL,O32 %s
8 ; RUN-TODO: llc -march=mips64el -relocation-model=static -target-abi o32 < %s \
9 ; RUN-TODO:   | FileCheck --check-prefixes=ALL,O32 %s
11 ; RUN: llc -mtriple=mips64-linux -relocation-model=static -target-abi n32 < %s \
12 ; RUN:   | FileCheck --check-prefixes=ALL,NEW,N32,NEW-BE %s
13 ; RUN: llc -mtriple=mips64el-linux -relocation-model=static -target-abi n32 < %s \
14 ; RUN:   | FileCheck --check-prefixes=ALL,NEW,N32,NEW-LE %s
16 ; RUN: llc -march=mips64 -relocation-model=static -target-abi n64 < %s \
17 ; RUN:   | FileCheck --check-prefixes=ALL,NEW,N64,NEW-BE %s
18 ; RUN: llc -march=mips64el -relocation-model=static -target-abi n64 < %s \
19 ; RUN:   | FileCheck --check-prefixes=ALL,NEW,N64,NEW-LE %s
21 @hwords = global [3 x i16] zeroinitializer, align 1
22 @words  = global [3 x i32] zeroinitializer, align 1
23 @dwords = global [3 x i64] zeroinitializer, align 1
25 define void @fn_i16_dotdotdot_i16(i16 %a, ...) {
26 entry:
27 ; ALL-LABEL: fn_i16_dotdotdot_i16:
29 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
30 ; the argument save area (56 bytes).
31 ; O32:           addiu  [[SP:\$sp]], $sp, -8
32 ; N32:           addiu  [[SP:\$sp]], $sp, -64
33 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
35 ; Save variable argument portion on the stack
36 ; O32-DAG:       sw $7, 20([[SP]])
37 ; O32-DAG:       sw $6, 16([[SP]])
38 ; O32-DAG:       sw $5, 12([[SP]])
40 ; NEW-DAG:       sd $11, 56([[SP]])
41 ; NEW-DAG:       sd $10, 48([[SP]])
42 ; NEW-DAG:       sd $9, 40([[SP]])
43 ; NEW-DAG:       sd $8, 32([[SP]])
44 ; NEW-DAG:       sd $7, 24([[SP]])
45 ; NEW-DAG:       sd $6, 16([[SP]])
46 ; NEW-DAG:       sd $5, 8([[SP]])
48 ; Initialize variable argument pointer.
49 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
50 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
51 ; fixed argument.
52 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
53 ; space.
54 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
55 ; O32-DAG:       sw [[VA]], 0([[SP]])
57 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
58 ; N32-DAG:       sw [[VA]], 0([[SP]])
60 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
61 ; N64-DAG:       sd [[VA]], 0([[SP]])
63 ; ALL: teqi $zero, 1
65 ; Increment [[VA]]
66 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
67 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
68 ; O32-DAG:       sw [[VA2]], 0([[SP]])
70 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
71 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
72 ; N32-DAG:       sw [[VA2]], 0([[SP]])
74 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
75 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
76 ; N64-DAG:       sd [[VA2]], 0([[SP]])
78 ; Load the first argument from the variable portion.
79 ; This has used the stack pointer directly rather than the [[VA]] we just set
80 ; up.
81 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
82 ; order.
83 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
85 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
86 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
88 ; Copy the arg to the global
89 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
91 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
93 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
95 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
97 ; ALL: teqi $zero, 2
99 ; Increment [[VA]] again.
100 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
101 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
102 ; O32-DAG:       sw [[VA2]], 0([[SP]])
104 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
105 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
106 ; N32-DAG:       sw [[VA3]], 0([[SP]])
108 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
109 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
110 ; N64-DAG:       sd [[VA3]], 0([[SP]])
112 ; Load the second argument from the variable portion.
113 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
115 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
116 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
118 ; Copy the arg to the global
119 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
121   %ap = alloca i8*, align 8
122   %ap2 = bitcast i8** %ap to i8*
123   call void @llvm.va_start(i8* %ap2)
125   call void asm sideeffect "teqi $$zero, 1", ""()
126   %arg1 = va_arg i8** %ap, i16
127   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
128   store volatile i16 %arg1, i16* %e1, align 2
130   call void asm sideeffect "teqi $$zero, 2", ""()
131   %arg2 = va_arg i8** %ap, i16
132   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
133   store volatile i16 %arg2, i16* %e2, align 2
135   call void @llvm.va_end(i8* %ap2)
137   ret void
140 define void @fn_i16_dotdotdot_i32(i16 %a, ...) {
141 entry:
142 ; ALL-LABEL: fn_i16_dotdotdot_i32:
144 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
145 ; the argument save area (56 bytes).
146 ; O32:           addiu  [[SP:\$sp]], $sp, -8
147 ; N32:           addiu  [[SP:\$sp]], $sp, -64
148 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
150 ; Save variable argument portion on the stack
151 ; O32-DAG:       sw $7, 20([[SP]])
152 ; O32-DAG:       sw $6, 16([[SP]])
153 ; O32-DAG:       sw $5, 12([[SP]])
155 ; NEW-DAG:       sd $11, 56([[SP]])
156 ; NEW-DAG:       sd $10, 48([[SP]])
157 ; NEW-DAG:       sd $9, 40([[SP]])
158 ; NEW-DAG:       sd $8, 32([[SP]])
159 ; NEW-DAG:       sd $7, 24([[SP]])
160 ; NEW-DAG:       sd $6, 16([[SP]])
161 ; NEW-DAG:       sd $5, 8([[SP]])
163 ; Initialize variable argument pointer.
164 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
165 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
166 ; fixed argument.
167 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
168 ; space.
169 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
170 ; O32-DAG:       sw [[VA]], 0([[SP]])
172 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
173 ; N32-DAG:       sw [[VA]], 0([[SP]])
175 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
176 ; N64-DAG:       sd [[VA]], 0([[SP]])
178 ; ALL: teqi $zero, 1
180 ; Increment [[VA]]
181 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
182 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
183 ; O32-DAG:       sw [[VA2]], 0([[SP]])
185 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
186 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
187 ; N32-DAG:       sw [[VA2]], 0([[SP]])
189 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
190 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
191 ; N64-DAG:       sd [[VA2]], 0([[SP]])
193 ; Load the first argument from the variable portion.
194 ; This has used the stack pointer directly rather than the [[VA]] we just set
195 ; up.
196 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
197 ; order.
198 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
200 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
201 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
203 ; Copy the arg to the global
204 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
206 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
208 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
210 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
212 ; ALL: teqi $zero, 2
214 ; Increment [[VA]] again.
215 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
216 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
217 ; O32-DAG:       sw [[VA2]], 0([[SP]])
219 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
220 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
221 ; N32-DAG:       sw [[VA3]], 0([[SP]])
223 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
224 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
225 ; N64-DAG:       sd [[VA3]], 0([[SP]])
227 ; Load the second argument from the variable portion.
228 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
230 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
231 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
233 ; Copy the arg to the global
234 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
236   %ap = alloca i8*, align 8
237   %ap2 = bitcast i8** %ap to i8*
238   call void @llvm.va_start(i8* %ap2)
240   call void asm sideeffect "teqi $$zero, 1", ""()
241   %arg1 = va_arg i8** %ap, i32
242   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
243   store volatile i32 %arg1, i32* %e1, align 4
245   call void asm sideeffect "teqi $$zero, 2", ""()
246   %arg2 = va_arg i8** %ap, i32
247   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
248   store volatile i32 %arg2, i32* %e2, align 4
250   call void @llvm.va_end(i8* %ap2)
252   ret void
255 define void @fn_i16_dotdotdot_i64(i16 %a, ...) {
256 entry:
257 ; ALL-LABEL: fn_i16_dotdotdot_i64:
259 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
260 ; the argument save area (56 bytes).
261 ; O32:           addiu  [[SP:\$sp]], $sp, -8
262 ; N32:           addiu  [[SP:\$sp]], $sp, -64
263 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
265 ; Save variable argument portion on the stack
266 ; O32-DAG:       sw $7, 20([[SP]])
267 ; O32-DAG:       sw $6, 16([[SP]])
268 ; O32-DAG:       sw $5, 12([[SP]])
270 ; NEW-DAG:       sd $11, 56([[SP]])
271 ; NEW-DAG:       sd $10, 48([[SP]])
272 ; NEW-DAG:       sd $9, 40([[SP]])
273 ; NEW-DAG:       sd $8, 32([[SP]])
274 ; NEW-DAG:       sd $7, 24([[SP]])
275 ; NEW-DAG:       sd $6, 16([[SP]])
276 ; NEW-DAG:       sd $5, 8([[SP]])
278 ; Initialize variable argument pointer.
279 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
280 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
281 ; fixed argument.
282 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
283 ; space.
284 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
285 ; O32-DAG:       sw [[VA]], 0([[SP]])
287 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
288 ; N32-DAG:       sw [[VA]], 0([[SP]])
290 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
291 ; N64-DAG:       sd [[VA]], 0([[SP]])
293 ; ALL: teqi $zero, 1
295 ; Increment [[VA]] (and realign pointer for O32)
296 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
297 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
298 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
299 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
300 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
301 ; O32-DAG:       sw [[VA2]], 0([[SP]])
303 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
304 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
305 ; N32-DAG:       sw [[VA2]], 0([[SP]])
307 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
308 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
309 ; N64-DAG:       sd [[VA2]], 0([[SP]])
311 ; Load the first argument from the variable portion and copy it to the global.
312 ; This has used the stack pointer directly rather than the [[VA]] we just set
313 ; up.
314 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
315 ; order.
316 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
317 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]])
318 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
319 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
320 ; O32-DAG:       sw [[VA3]], 0([[SP]])
321 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
322 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
324 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
325 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
326 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
327 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
329 ; ALL: teqi $zero, 2
331 ; Increment [[VA]] again.
332 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
333 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
334 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
335 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
336 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
337 ; O32-DAG:       sw [[VA2]], 0([[SP]])
339 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
340 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
341 ; N32-DAG:       sw [[VA3]], 0([[SP]])
343 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
344 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
345 ; N64-DAG:       sd [[VA3]], 0([[SP]])
347 ; Load the second argument from the variable portion and copy it to the global.
348 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
349 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
350 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
351 ; O32-DAG:       sw [[VA3]], 0([[SP]])
352 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])
353 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
355 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
356 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
358   %ap = alloca i8*, align 8
359   %ap2 = bitcast i8** %ap to i8*
360   call void @llvm.va_start(i8* %ap2)
362   call void asm sideeffect "teqi $$zero, 1", ""()
363   %arg1 = va_arg i8** %ap, i64
364   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
365   store volatile i64 %arg1, i64* %e1, align 8
367   call void asm sideeffect "teqi $$zero, 2", ""()
368   %arg2 = va_arg i8** %ap, i64
369   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
370   store volatile i64 %arg2, i64* %e2, align 8
372   call void @llvm.va_end(i8* %ap2)
374   ret void
377 define void @fn_i32_dotdotdot_i16(i32 %a, ...) {
378 entry:
379 ; ALL-LABEL: fn_i32_dotdotdot_i16:
381 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
382 ; the argument save area (56 bytes).
383 ; O32:           addiu  [[SP:\$sp]], $sp, -8
384 ; N32:           addiu  [[SP:\$sp]], $sp, -64
385 ; N64:           daddiu [[SP:\$sp]], $sp, -64
387 ; Save variable argument portion on the stack
388 ; O32-DAG:       sw $7, 20([[SP]])
389 ; O32-DAG:       sw $6, 16([[SP]])
390 ; O32-DAG:       sw $5, 12([[SP]])
392 ; NEW-DAG:       sd $11, 56([[SP]])
393 ; NEW-DAG:       sd $10, 48([[SP]])
394 ; NEW-DAG:       sd $9, 40([[SP]])
395 ; NEW-DAG:       sd $8, 32([[SP]])
396 ; NEW-DAG:       sd $7, 24([[SP]])
397 ; NEW-DAG:       sd $6, 16([[SP]])
398 ; NEW-DAG:       sd $5, 8([[SP]])
400 ; Initialize variable argument pointer.
401 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
402 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
403 ; fixed argument.
404 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
405 ; space.
406 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
407 ; O32-DAG:       sw [[VA]], 0([[SP]])
409 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
410 ; N32-DAG:       sw [[VA]], 0([[SP]])
412 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
413 ; N64-DAG:       sd [[VA]], 0([[SP]])
415 ; ALL: teqi $zero, 1
417 ; Increment [[VA]]
418 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
419 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
420 ; O32-DAG:       sw [[VA2]], 0([[SP]])
422 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
423 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
424 ; N32-DAG:       sw [[VA2]], 0([[SP]])
426 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
427 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
428 ; N64-DAG:       sd [[VA2]], 0([[SP]])
430 ; Load the first argument from the variable portion.
431 ; This has used the stack pointer directly rather than the [[VA]] we just set
432 ; up.
433 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
434 ; order.
435 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
437 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
438 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
440 ; Copy the arg to the global
441 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
443 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
445 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
447 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
449 ; ALL: teqi $zero, 2
451 ; Increment [[VA]] again.
452 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
453 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
454 ; O32-DAG:       sw [[VA2]], 0([[SP]])
456 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
457 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
458 ; N32-DAG:       sw [[VA3]], 0([[SP]])
460 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
461 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
462 ; N64-DAG:       sd [[VA3]], 0([[SP]])
464 ; Load the second argument from the variable portion.
465 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
467 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
468 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
470 ; Copy the arg to the global
471 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
473   %ap = alloca i8*, align 8
474   %ap2 = bitcast i8** %ap to i8*
475   call void @llvm.va_start(i8* %ap2)
477   call void asm sideeffect "teqi $$zero, 1", ""()
478   %arg1 = va_arg i8** %ap, i16
479   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
480   store volatile i16 %arg1, i16* %e1, align 2
482   call void asm sideeffect "teqi $$zero, 2", ""()
483   %arg2 = va_arg i8** %ap, i16
484   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
485   store volatile i16 %arg2, i16* %e2, align 2
487   call void @llvm.va_end(i8* %ap2)
489   ret void
492 define void @fn_i32_dotdotdot_i32(i32 %a, ...) {
493 entry:
494 ; ALL-LABEL: fn_i32_dotdotdot_i32:
496 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
497 ; the argument save area (56 bytes).
498 ; O32:           addiu  [[SP:\$sp]], $sp, -8
499 ; N32:           addiu  [[SP:\$sp]], $sp, -64
500 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
502 ; Save variable argument portion on the stack
503 ; O32-DAG:       sw $7, 20([[SP]])
504 ; O32-DAG:       sw $6, 16([[SP]])
505 ; O32-DAG:       sw $5, 12([[SP]])
507 ; NEW-DAG:       sd $11, 56([[SP]])
508 ; NEW-DAG:       sd $10, 48([[SP]])
509 ; NEW-DAG:       sd $9, 40([[SP]])
510 ; NEW-DAG:       sd $8, 32([[SP]])
511 ; NEW-DAG:       sd $7, 24([[SP]])
512 ; NEW-DAG:       sd $6, 16([[SP]])
513 ; NEW-DAG:       sd $5, 8([[SP]])
515 ; Initialize variable argument pointer.
516 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
517 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
518 ; fixed argument.
519 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
520 ; space.
521 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
522 ; O32-DAG:       sw [[VA]], 0([[SP]])
524 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
525 ; N32-DAG:       sw [[VA]], 0([[SP]])
527 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
528 ; N64-DAG:       sd [[VA]], 0([[SP]])
530 ; ALL: teqi $zero, 1
532 ; Increment [[VA]]
533 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
534 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
535 ; O32-DAG:       sw [[VA2]], 0([[SP]])
537 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
538 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
539 ; N32-DAG:       sw [[VA2]], 0([[SP]])
541 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
542 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
543 ; N64-DAG:       sd [[VA2]], 0([[SP]])
545 ; Load the first argument from the variable portion.
546 ; This has used the stack pointer directly rather than the [[VA]] we just set
547 ; up.
548 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
549 ; order.
550 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
552 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
553 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
555 ; Copy the arg to the global
556 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
558 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
560 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
562 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
564 ; ALL: teqi $zero, 2
566 ; Increment [[VA]] again.
567 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
568 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
569 ; O32-DAG:       sw [[VA2]], 0([[SP]])
571 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
572 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
573 ; N32-DAG:       sw [[VA3]], 0([[SP]])
575 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
576 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
577 ; N64-DAG:       sd [[VA3]], 0([[SP]])
579 ; Load the second argument from the variable portion.
580 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
582 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
583 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
585 ; Copy the arg to the global
586 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
588   %ap = alloca i8*, align 8
589   %ap2 = bitcast i8** %ap to i8*
590   call void @llvm.va_start(i8* %ap2)
592   call void asm sideeffect "teqi $$zero, 1", ""()
593   %arg1 = va_arg i8** %ap, i32
594   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
595   store volatile i32 %arg1, i32* %e1, align 4
597   call void asm sideeffect "teqi $$zero, 2", ""()
598   %arg2 = va_arg i8** %ap, i32
599   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
600   store volatile i32 %arg2, i32* %e2, align 4
602   call void @llvm.va_end(i8* %ap2)
604   ret void
607 define void @fn_i32_dotdotdot_i64(i32 %a, ...) {
608 entry:
609 ; ALL-LABEL: fn_i32_dotdotdot_i64:
611 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
612 ; the argument save area (56 bytes).
613 ; O32:           addiu  [[SP:\$sp]], $sp, -8
614 ; N32:           addiu  [[SP:\$sp]], $sp, -64
615 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
617 ; Save variable argument portion on the stack
618 ; O32-DAG:       sw $7, 20([[SP]])
619 ; O32-DAG:       sw $6, 16([[SP]])
620 ; O32-DAG:       sw $5, 12([[SP]])
622 ; NEW-DAG:       sd $11, 56([[SP]])
623 ; NEW-DAG:       sd $10, 48([[SP]])
624 ; NEW-DAG:       sd $9, 40([[SP]])
625 ; NEW-DAG:       sd $8, 32([[SP]])
626 ; NEW-DAG:       sd $7, 24([[SP]])
627 ; NEW-DAG:       sd $6, 16([[SP]])
628 ; NEW-DAG:       sd $5, 8([[SP]])
630 ; Initialize variable argument pointer.
631 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
632 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
633 ; fixed argument.
634 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
635 ; space.
636 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
637 ; O32-DAG:       sw [[VA]], 0([[SP]])
639 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
640 ; N32-DAG:       sw [[VA]], 0([[SP]])
642 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
643 ; N64-DAG:       sd [[VA]], 0([[SP]])
645 ; ALL: teqi $zero, 1
647 ; Increment [[VA]] (and realign pointer for O32)
648 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
649 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
650 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
651 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
652 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
653 ; O32-DAG:       sw [[VA2]], 0([[SP]])
655 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
656 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
657 ; N32-DAG:       sw [[VA2]], 0([[SP]])
659 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
660 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
661 ; N64-DAG:       sd [[VA2]], 0([[SP]])
663 ; Load the first argument from the variable portion and copy it to the global.
664 ; This has used the stack pointer directly rather than the [[VA]] we just set
665 ; up.
666 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
667 ; order.
668 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
669 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]])
670 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
671 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
672 ; O32-DAG:       sw [[VA3]], 0([[SP]])
673 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
674 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
676 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
677 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
678 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
679 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
681 ; ALL: teqi $zero, 2
683 ; Increment [[VA]] again.
684 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
685 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
686 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
687 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
688 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
689 ; O32-DAG:       sw [[VA2]], 0([[SP]])
691 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
692 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
693 ; N32-DAG:       sw [[VA3]], 0([[SP]])
695 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
696 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
697 ; N64-DAG:       sd [[VA3]], 0([[SP]])
699 ; Load the second argument from the variable portion and copy it to the global.
700 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
701 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
702 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
703 ; O32-DAG:       sw [[VA2]], 0([[SP]])
704 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])
705 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
707 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
708 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
710   %ap = alloca i8*, align 8
711   %ap2 = bitcast i8** %ap to i8*
712   call void @llvm.va_start(i8* %ap2)
714   call void asm sideeffect "teqi $$zero, 1", ""()
715   %arg1 = va_arg i8** %ap, i64
716   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
717   store volatile i64 %arg1, i64* %e1, align 8
719   call void asm sideeffect "teqi $$zero, 2", ""()
720   %arg2 = va_arg i8** %ap, i64
721   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
722   store volatile i64 %arg2, i64* %e2, align 8
724   call void @llvm.va_end(i8* %ap2)
726   ret void
729 define void @fn_i64_dotdotdot_i16(i64 %a, ...) {
730 entry:
731 ; ALL-LABEL: fn_i64_dotdotdot_i16:
733 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
734 ; the argument save area (56 bytes).
735 ; O32:           addiu  [[SP:\$sp]], $sp, -8
736 ; N32:           addiu  [[SP:\$sp]], $sp, -64
737 ; N64:           daddiu [[SP:\$sp]], $sp, -64
739 ; Save variable argument portion on the stack
740 ; O32-DAG:       sw $7, 20([[SP]])
741 ; O32-DAG:       sw $6, 16([[SP]])
743 ; NEW-DAG:       sd $11, 56([[SP]])
744 ; NEW-DAG:       sd $10, 48([[SP]])
745 ; NEW-DAG:       sd $9, 40([[SP]])
746 ; NEW-DAG:       sd $8, 32([[SP]])
747 ; NEW-DAG:       sd $7, 24([[SP]])
748 ; NEW-DAG:       sd $6, 16([[SP]])
749 ; NEW-DAG:       sd $5, 8([[SP]])
751 ; Initialize variable argument pointer.
752 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
753 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
754 ; first fixed argument.
755 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
756 ; space.
757 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
758 ; O32-DAG:       sw [[VA]], 0([[SP]])
760 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
761 ; N32-DAG:       sw [[VA]], 0([[SP]])
763 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
764 ; N64-DAG:       sd [[VA]], 0([[SP]])
766 ; ALL: teqi $zero, 1
768 ; Increment [[VA]]
769 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
770 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
771 ; O32-DAG:       sw [[VA2]], 0([[SP]])
773 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
774 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
775 ; N32-DAG:       sw [[VA2]], 0([[SP]])
777 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
778 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
779 ; N64-DAG:       sd [[VA2]], 0([[SP]])
781 ; Load the first argument from the variable portion.
782 ; This has used the stack pointer directly rather than the [[VA]] we just set
783 ; up.
784 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
785 ; order.
786 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
788 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
789 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
791 ; Copy the arg to the global
792 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
794 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
796 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
798 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
800 ; ALL: teqi $zero, 2
802 ; Increment [[VA]] again.
803 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
804 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
805 ; O32-DAG:       sw [[VA2]], 0([[SP]])
807 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
808 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
809 ; N32-DAG:       sw [[VA3]], 0([[SP]])
811 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
812 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
813 ; N64-DAG:       sd [[VA3]], 0([[SP]])
815 ; Load the second argument from the variable portion.
816 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
818 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
819 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
821 ; Copy the arg to the global
822 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
824   %ap = alloca i8*, align 8
825   %ap2 = bitcast i8** %ap to i8*
826   call void @llvm.va_start(i8* %ap2)
828   call void asm sideeffect "teqi $$zero, 1", ""()
829   %arg1 = va_arg i8** %ap, i16
830   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
831   store volatile i16 %arg1, i16* %e1, align 2
833   call void asm sideeffect "teqi $$zero, 2", ""()
834   %arg2 = va_arg i8** %ap, i16
835   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
836   store volatile i16 %arg2, i16* %e2, align 2
838   call void @llvm.va_end(i8* %ap2)
840   ret void
843 define void @fn_i64_dotdotdot_i32(i64 %a, ...) {
844 entry:
845 ; ALL-LABEL: fn_i64_dotdotdot_i32:
847 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
848 ; the argument save area (56 bytes).
849 ; O32:           addiu  [[SP:\$sp]], $sp, -8
850 ; N32:           addiu  [[SP:\$sp]], $sp, -64
851 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
853 ; Save variable argument portion on the stack
854 ; O32-DAG:       sw $7, 20([[SP]])
855 ; O32-DAG:       sw $6, 16([[SP]])
857 ; NEW-DAG:       sd $11, 56([[SP]])
858 ; NEW-DAG:       sd $10, 48([[SP]])
859 ; NEW-DAG:       sd $9, 40([[SP]])
860 ; NEW-DAG:       sd $8, 32([[SP]])
861 ; NEW-DAG:       sd $7, 24([[SP]])
862 ; NEW-DAG:       sd $6, 16([[SP]])
863 ; NEW-DAG:       sd $5, 8([[SP]])
865 ; Initialize variable argument pointer.
866 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
867 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
868 ; first fixed argument.
869 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
870 ; space.
871 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
872 ; O32-DAG:       sw [[VA]], 0([[SP]])
874 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
875 ; N32-DAG:       sw [[VA]], 0([[SP]])
877 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
878 ; N64-DAG:       sd [[VA]], 0([[SP]])
880 ; ALL: teqi $zero, 1
882 ; Increment [[VA]]
883 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
884 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
885 ; O32-DAG:       sw [[VA2]], 0([[SP]])
887 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
888 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
889 ; N32-DAG:       sw [[VA2]], 0([[SP]])
891 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
892 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
893 ; N64-DAG:       sd [[VA2]], 0([[SP]])
895 ; Load the first argument from the variable portion.
896 ; This has used the stack pointer directly rather than the [[VA]] we just set
897 ; up.
898 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
899 ; order.
900 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
902 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
903 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
905 ; Copy the arg to the global
906 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
908 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
910 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
912 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
914 ; ALL: teqi $zero, 2
916 ; Increment [[VA]] again.
917 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
918 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
919 ; O32-DAG:       sw [[VA2]], 0([[SP]])
921 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
922 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
923 ; N32-DAG:       sw [[VA3]], 0([[SP]])
925 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
926 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
927 ; N64-DAG:       sd [[VA3]], 0([[SP]])
929 ; Load the second argument from the variable portion.
930 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
932 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
933 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
935 ; Copy the arg to the global
936 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
938   %ap = alloca i8*, align 8
939   %ap2 = bitcast i8** %ap to i8*
940   call void @llvm.va_start(i8* %ap2)
942   call void asm sideeffect "teqi $$zero, 1", ""()
943   %arg1 = va_arg i8** %ap, i32
944   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
945   store volatile i32 %arg1, i32* %e1, align 4
947   call void asm sideeffect "teqi $$zero, 2", ""()
948   %arg2 = va_arg i8** %ap, i32
949   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
950   store volatile i32 %arg2, i32* %e2, align 4
952   call void @llvm.va_end(i8* %ap2)
954   ret void
957 define void @fn_i64_dotdotdot_i64(i64 %a, ...) {
958 entry:
959 ; ALL-LABEL: fn_i64_dotdotdot_i64:
961 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
962 ; the argument save area (56 bytes).
963 ; O32:           addiu  [[SP:\$sp]], $sp, -8
964 ; N32:           addiu  [[SP:\$sp]], $sp, -64
965 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
967 ; Save variable argument portion on the stack
968 ; O32-DAG:       sw $7, 20([[SP]])
969 ; O32-DAG:       sw $6, 16([[SP]])
971 ; NEW-DAG:       sd $11, 56([[SP]])
972 ; NEW-DAG:       sd $10, 48([[SP]])
973 ; NEW-DAG:       sd $9, 40([[SP]])
974 ; NEW-DAG:       sd $8, 32([[SP]])
975 ; NEW-DAG:       sd $7, 24([[SP]])
976 ; NEW-DAG:       sd $6, 16([[SP]])
977 ; NEW-DAG:       sd $5, 8([[SP]])
979 ; Initialize variable argument pointer.
980 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
981 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
982 ; first fixed argument.
983 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
984 ; space.
985 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
986 ; O32-DAG:       sw [[VA]], 0([[SP]])
988 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
989 ; N32-DAG:       sw [[VA]], 0([[SP]])
991 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
992 ; N64-DAG:       sd [[VA]], 0([[SP]])
994 ; ALL: teqi $zero, 1
996 ; Increment [[VA]] (and realign pointer for O32)
997 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
998 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
999 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
1000 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
1001 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
1002 ; O32-DAG:       sw [[VA2]], 0([[SP]])
1004 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
1005 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
1006 ; N32-DAG:       sw [[VA2]], 0([[SP]])
1008 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
1009 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
1010 ; N64-DAG:       sd [[VA2]], 0([[SP]])
1012 ; Load the first argument from the variable portion and copy it to the global.
1013 ; This has used the stack pointer directly rather than the [[VA]] we just set
1014 ; up.
1015 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
1016 ; order.
1017 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
1018 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
1019 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
1020 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
1021 ; O32-DAG:       sw [[VA3]], 0([[SP]])
1022 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
1023 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
1025 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
1026 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
1027 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
1028 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
1030 ; ALL: teqi $zero, 2
1032 ; Increment [[VA]] again.
1033 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
1034 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
1035 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
1036 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
1037 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
1038 ; O32-DAG:       sw [[VA2]], 0([[SP]])
1040 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
1041 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
1042 ; N32-DAG:       sw [[VA3]], 0([[SP]])
1044 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
1045 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
1046 ; N64-DAG:       sd [[VA3]], 0([[SP]])
1048 ; Load the second argument from the variable portion and copy it to the global.
1049 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
1050 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
1051 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
1052 ; O32-DAG:       sw [[VA3]], 0([[SP]])
1053 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])
1054 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
1056 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
1057 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
1059   %ap = alloca i8*, align 8
1060   %ap2 = bitcast i8** %ap to i8*
1061   call void @llvm.va_start(i8* %ap2)
1063   call void asm sideeffect "teqi $$zero, 1", ""()
1064   %arg1 = va_arg i8** %ap, i64
1065   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
1066   store volatile i64 %arg1, i64* %e1, align 8
1068   call void asm sideeffect "teqi $$zero, 2", ""()
1069   %arg2 = va_arg i8** %ap, i64
1070   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
1071   store volatile i64 %arg2, i64* %e2, align 8
1073   call void @llvm.va_end(i8* %ap2)
1075   ret void
1078 declare void @llvm.va_start(i8*)
1079 declare void @llvm.va_end(i8*)