Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / Mips / cconv / arguments-varargs.ll
blob1f97b376c290be0b6c6c9026bb0a9591d35c5a7e
1 ; RUN: llc -mtriple=mips-linux -relocation-model=static < %s \
2 ; RUN:   | FileCheck --check-prefixes=ALL,O32 %s
3 ; RUN: llc -mtriple=mipsel-linux -relocation-model=static < %s \
4 ; RUN:   | FileCheck --check-prefixes=ALL,O32 %s
6 ; RUN-TODO: llc -mtriple=mips64 -relocation-model=static -target-abi o32 < %s \
7 ; RUN-TODO:   | FileCheck --check-prefixes=ALL,O32 %s
8 ; RUN-TODO: llc -mtriple=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 -mtriple=mips64 -relocation-model=static -target-abi n64 < %s \
17 ; RUN:   | FileCheck --check-prefixes=ALL,NEW,N64,NEW-BE %s
18 ; RUN: llc -mtriple=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 ptr, align 8
122   call void @llvm.va_start(ptr %ap)
124   call void asm sideeffect "teqi $$zero, 1", ""()
125   %arg1 = va_arg ptr %ap, i16
126   %e1 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 1
127   store volatile i16 %arg1, ptr %e1, align 2
129   call void asm sideeffect "teqi $$zero, 2", ""()
130   %arg2 = va_arg ptr %ap, i16
131   %e2 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 2
132   store volatile i16 %arg2, ptr %e2, align 2
134   call void @llvm.va_end(ptr %ap)
136   ret void
139 define void @fn_i16_dotdotdot_i32(i16 %a, ...) {
140 entry:
141 ; ALL-LABEL: fn_i16_dotdotdot_i32:
143 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
144 ; the argument save area (56 bytes).
145 ; O32:           addiu  [[SP:\$sp]], $sp, -8
146 ; N32:           addiu  [[SP:\$sp]], $sp, -64
147 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
149 ; Save variable argument portion on the stack
150 ; O32-DAG:       sw $7, 20([[SP]])
151 ; O32-DAG:       sw $6, 16([[SP]])
152 ; O32-DAG:       sw $5, 12([[SP]])
154 ; NEW-DAG:       sd $11, 56([[SP]])
155 ; NEW-DAG:       sd $10, 48([[SP]])
156 ; NEW-DAG:       sd $9, 40([[SP]])
157 ; NEW-DAG:       sd $8, 32([[SP]])
158 ; NEW-DAG:       sd $7, 24([[SP]])
159 ; NEW-DAG:       sd $6, 16([[SP]])
160 ; NEW-DAG:       sd $5, 8([[SP]])
162 ; Initialize variable argument pointer.
163 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
164 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
165 ; fixed argument.
166 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
167 ; space.
168 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
169 ; O32-DAG:       sw [[VA]], 0([[SP]])
171 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
172 ; N32-DAG:       sw [[VA]], 0([[SP]])
174 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
175 ; N64-DAG:       sd [[VA]], 0([[SP]])
177 ; ALL: teqi $zero, 1
179 ; Increment [[VA]]
180 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
181 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
182 ; O32-DAG:       sw [[VA2]], 0([[SP]])
184 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
185 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
186 ; N32-DAG:       sw [[VA2]], 0([[SP]])
188 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
189 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
190 ; N64-DAG:       sd [[VA2]], 0([[SP]])
192 ; Load the first argument from the variable portion.
193 ; This has used the stack pointer directly rather than the [[VA]] we just set
194 ; up.
195 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
196 ; order.
197 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
199 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
200 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
202 ; Copy the arg to the global
203 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
205 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
207 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
209 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
211 ; ALL: teqi $zero, 2
213 ; Increment [[VA]] again.
214 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
215 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
216 ; O32-DAG:       sw [[VA2]], 0([[SP]])
218 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
219 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
220 ; N32-DAG:       sw [[VA3]], 0([[SP]])
222 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
223 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
224 ; N64-DAG:       sd [[VA3]], 0([[SP]])
226 ; Load the second argument from the variable portion.
227 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
229 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
230 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
232 ; Copy the arg to the global
233 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
235   %ap = alloca ptr, align 8
236   call void @llvm.va_start(ptr %ap)
238   call void asm sideeffect "teqi $$zero, 1", ""()
239   %arg1 = va_arg ptr %ap, i32
240   %e1 = getelementptr [3 x i32], ptr @words, i32 0, i32 1
241   store volatile i32 %arg1, ptr %e1, align 4
243   call void asm sideeffect "teqi $$zero, 2", ""()
244   %arg2 = va_arg ptr %ap, i32
245   %e2 = getelementptr [3 x i32], ptr @words, i32 0, i32 2
246   store volatile i32 %arg2, ptr %e2, align 4
248   call void @llvm.va_end(ptr %ap)
250   ret void
253 define void @fn_i16_dotdotdot_i64(i16 %a, ...) {
254 entry:
255 ; ALL-LABEL: fn_i16_dotdotdot_i64:
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
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]])
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]])
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]])
285 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
286 ; N32-DAG:       sw [[VA]], 0([[SP]])
288 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
289 ; N64-DAG:       sd [[VA]], 0([[SP]])
291 ; ALL: teqi $zero, 1
293 ; Increment [[VA]] (and realign pointer for O32)
294 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
295 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
296 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
297 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
298 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
299 ; O32-DAG:       sw [[VA2]], 0([[SP]])
301 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
302 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
303 ; N32-DAG:       sw [[VA2]], 0([[SP]])
305 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
306 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
307 ; N64-DAG:       sd [[VA2]], 0([[SP]])
309 ; Load the first argument from the variable portion and copy it to the global.
310 ; This has used the stack pointer directly rather than the [[VA]] we just set
311 ; up.
312 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
313 ; order.
314 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
315 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]])
316 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
317 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8
318 ; O32-DAG:       sw [[VA3]], 0([[SP]])
319 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
320 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
322 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
323 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
324 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
325 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
327 ; ALL: teqi $zero, 2
329 ; Increment [[VA]] again.
330 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
331 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
332 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
333 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
334 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
335 ; O32-DAG:       sw [[VA2]], 0([[SP]])
337 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
338 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
339 ; N32-DAG:       sw [[VA3]], 0([[SP]])
341 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
342 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
343 ; N64-DAG:       sd [[VA3]], 0([[SP]])
345 ; Load the second argument from the variable portion and copy it to the global.
346 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
347 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
348 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8
349 ; O32-DAG:       sw [[VA3]], 0([[SP]])
350 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])
351 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
353 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
354 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
356   %ap = alloca ptr, align 8
357   call void @llvm.va_start(ptr %ap)
359   call void asm sideeffect "teqi $$zero, 1", ""()
360   %arg1 = va_arg ptr %ap, i64
361   %e1 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 1
362   store volatile i64 %arg1, ptr %e1, align 8
364   call void asm sideeffect "teqi $$zero, 2", ""()
365   %arg2 = va_arg ptr %ap, i64
366   %e2 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 2
367   store volatile i64 %arg2, ptr %e2, align 8
369   call void @llvm.va_end(ptr %ap)
371   ret void
374 define void @fn_i32_dotdotdot_i16(i32 %a, ...) {
375 entry:
376 ; ALL-LABEL: fn_i32_dotdotdot_i16:
378 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
379 ; the argument save area (56 bytes).
380 ; O32:           addiu  [[SP:\$sp]], $sp, -8
381 ; N32:           addiu  [[SP:\$sp]], $sp, -64
382 ; N64:           daddiu [[SP:\$sp]], $sp, -64
384 ; Save variable argument portion on the stack
385 ; O32-DAG:       sw $7, 20([[SP]])
386 ; O32-DAG:       sw $6, 16([[SP]])
387 ; O32-DAG:       sw $5, 12([[SP]])
389 ; NEW-DAG:       sd $11, 56([[SP]])
390 ; NEW-DAG:       sd $10, 48([[SP]])
391 ; NEW-DAG:       sd $9, 40([[SP]])
392 ; NEW-DAG:       sd $8, 32([[SP]])
393 ; NEW-DAG:       sd $7, 24([[SP]])
394 ; NEW-DAG:       sd $6, 16([[SP]])
395 ; NEW-DAG:       sd $5, 8([[SP]])
397 ; Initialize variable argument pointer.
398 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
399 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
400 ; fixed argument.
401 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
402 ; space.
403 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
404 ; O32-DAG:       sw [[VA]], 0([[SP]])
406 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
407 ; N32-DAG:       sw [[VA]], 0([[SP]])
409 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
410 ; N64-DAG:       sd [[VA]], 0([[SP]])
412 ; ALL: teqi $zero, 1
414 ; Increment [[VA]]
415 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
416 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
417 ; O32-DAG:       sw [[VA2]], 0([[SP]])
419 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
420 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
421 ; N32-DAG:       sw [[VA2]], 0([[SP]])
423 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
424 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
425 ; N64-DAG:       sd [[VA2]], 0([[SP]])
427 ; Load the first argument from the variable portion.
428 ; This has used the stack pointer directly rather than the [[VA]] we just set
429 ; up.
430 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
431 ; order.
432 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
434 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
435 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
437 ; Copy the arg to the global
438 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
440 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
442 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
444 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
446 ; ALL: teqi $zero, 2
448 ; Increment [[VA]] again.
449 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
450 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
451 ; O32-DAG:       sw [[VA2]], 0([[SP]])
453 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
454 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
455 ; N32-DAG:       sw [[VA3]], 0([[SP]])
457 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
458 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
459 ; N64-DAG:       sd [[VA3]], 0([[SP]])
461 ; Load the second argument from the variable portion.
462 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
464 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
465 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
467 ; Copy the arg to the global
468 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
470   %ap = alloca ptr, align 8
471   call void @llvm.va_start(ptr %ap)
473   call void asm sideeffect "teqi $$zero, 1", ""()
474   %arg1 = va_arg ptr %ap, i16
475   %e1 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 1
476   store volatile i16 %arg1, ptr %e1, align 2
478   call void asm sideeffect "teqi $$zero, 2", ""()
479   %arg2 = va_arg ptr %ap, i16
480   %e2 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 2
481   store volatile i16 %arg2, ptr %e2, align 2
483   call void @llvm.va_end(ptr %ap)
485   ret void
488 define void @fn_i32_dotdotdot_i32(i32 %a, ...) {
489 entry:
490 ; ALL-LABEL: fn_i32_dotdotdot_i32:
492 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
493 ; the argument save area (56 bytes).
494 ; O32:           addiu  [[SP:\$sp]], $sp, -8
495 ; N32:           addiu  [[SP:\$sp]], $sp, -64
496 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
498 ; Save variable argument portion on the stack
499 ; O32-DAG:       sw $7, 20([[SP]])
500 ; O32-DAG:       sw $6, 16([[SP]])
501 ; O32-DAG:       sw $5, 12([[SP]])
503 ; NEW-DAG:       sd $11, 56([[SP]])
504 ; NEW-DAG:       sd $10, 48([[SP]])
505 ; NEW-DAG:       sd $9, 40([[SP]])
506 ; NEW-DAG:       sd $8, 32([[SP]])
507 ; NEW-DAG:       sd $7, 24([[SP]])
508 ; NEW-DAG:       sd $6, 16([[SP]])
509 ; NEW-DAG:       sd $5, 8([[SP]])
511 ; Initialize variable argument pointer.
512 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
513 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
514 ; fixed argument.
515 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
516 ; space.
517 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
518 ; O32-DAG:       sw [[VA]], 0([[SP]])
520 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
521 ; N32-DAG:       sw [[VA]], 0([[SP]])
523 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
524 ; N64-DAG:       sd [[VA]], 0([[SP]])
526 ; ALL: teqi $zero, 1
528 ; Increment [[VA]]
529 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
530 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
531 ; O32-DAG:       sw [[VA2]], 0([[SP]])
533 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
534 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
535 ; N32-DAG:       sw [[VA2]], 0([[SP]])
537 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
538 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
539 ; N64-DAG:       sd [[VA2]], 0([[SP]])
541 ; Load the first argument from the variable portion.
542 ; This has used the stack pointer directly rather than the [[VA]] we just set
543 ; up.
544 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
545 ; order.
546 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
548 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
549 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
551 ; Copy the arg to the global
552 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
554 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
556 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
558 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
560 ; ALL: teqi $zero, 2
562 ; Increment [[VA]] again.
563 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
564 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
565 ; O32-DAG:       sw [[VA2]], 0([[SP]])
567 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
568 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
569 ; N32-DAG:       sw [[VA3]], 0([[SP]])
571 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
572 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
573 ; N64-DAG:       sd [[VA3]], 0([[SP]])
575 ; Load the second argument from the variable portion.
576 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
578 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
579 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
581 ; Copy the arg to the global
582 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
584   %ap = alloca ptr, align 8
585   call void @llvm.va_start(ptr %ap)
587   call void asm sideeffect "teqi $$zero, 1", ""()
588   %arg1 = va_arg ptr %ap, i32
589   %e1 = getelementptr [3 x i32], ptr @words, i32 0, i32 1
590   store volatile i32 %arg1, ptr %e1, align 4
592   call void asm sideeffect "teqi $$zero, 2", ""()
593   %arg2 = va_arg ptr %ap, i32
594   %e2 = getelementptr [3 x i32], ptr @words, i32 0, i32 2
595   store volatile i32 %arg2, ptr %e2, align 4
597   call void @llvm.va_end(ptr %ap)
599   ret void
602 define void @fn_i32_dotdotdot_i64(i32 %a, ...) {
603 entry:
604 ; ALL-LABEL: fn_i32_dotdotdot_i64:
606 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
607 ; the argument save area (56 bytes).
608 ; O32:           addiu  [[SP:\$sp]], $sp, -8
609 ; N32:           addiu  [[SP:\$sp]], $sp, -64
610 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
612 ; Save variable argument portion on the stack
613 ; O32-DAG:       sw $7, 20([[SP]])
614 ; O32-DAG:       sw $6, 16([[SP]])
615 ; O32-DAG:       sw $5, 12([[SP]])
617 ; NEW-DAG:       sd $11, 56([[SP]])
618 ; NEW-DAG:       sd $10, 48([[SP]])
619 ; NEW-DAG:       sd $9, 40([[SP]])
620 ; NEW-DAG:       sd $8, 32([[SP]])
621 ; NEW-DAG:       sd $7, 24([[SP]])
622 ; NEW-DAG:       sd $6, 16([[SP]])
623 ; NEW-DAG:       sd $5, 8([[SP]])
625 ; Initialize variable argument pointer.
626 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
627 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
628 ; fixed argument.
629 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
630 ; space.
631 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
632 ; O32-DAG:       sw [[VA]], 0([[SP]])
634 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
635 ; N32-DAG:       sw [[VA]], 0([[SP]])
637 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
638 ; N64-DAG:       sd [[VA]], 0([[SP]])
640 ; ALL: teqi $zero, 1
642 ; Increment [[VA]] (and realign pointer for O32)
643 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
644 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
645 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
646 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
647 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
648 ; O32-DAG:       sw [[VA2]], 0([[SP]])
650 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
651 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
652 ; N32-DAG:       sw [[VA2]], 0([[SP]])
654 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
655 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
656 ; N64-DAG:       sd [[VA2]], 0([[SP]])
658 ; Load the first argument from the variable portion and copy it to the global.
659 ; This has used the stack pointer directly rather than the [[VA]] we just set
660 ; up.
661 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
662 ; order.
663 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
664 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]])
665 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
666 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8
667 ; O32-DAG:       sw [[VA3]], 0([[SP]])
668 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
669 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
671 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
672 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
673 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
674 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
676 ; ALL: teqi $zero, 2
678 ; Increment [[VA]] again.
679 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
680 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
681 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
682 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
683 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
684 ; O32-DAG:       sw [[VA2]], 0([[SP]])
686 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
687 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
688 ; N32-DAG:       sw [[VA3]], 0([[SP]])
690 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
691 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
692 ; N64-DAG:       sd [[VA3]], 0([[SP]])
694 ; Load the second argument from the variable portion and copy it to the global.
695 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
696 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
697 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8
698 ; O32-DAG:       sw [[VA3]], 0([[SP]])
699 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])
700 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
702 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
703 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
705   %ap = alloca ptr, align 8
706   call void @llvm.va_start(ptr %ap)
708   call void asm sideeffect "teqi $$zero, 1", ""()
709   %arg1 = va_arg ptr %ap, i64
710   %e1 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 1
711   store volatile i64 %arg1, ptr %e1, align 8
713   call void asm sideeffect "teqi $$zero, 2", ""()
714   %arg2 = va_arg ptr %ap, i64
715   %e2 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 2
716   store volatile i64 %arg2, ptr %e2, align 8
718   call void @llvm.va_end(ptr %ap)
720   ret void
723 define void @fn_i64_dotdotdot_i16(i64 %a, ...) {
724 entry:
725 ; ALL-LABEL: fn_i64_dotdotdot_i16:
727 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
728 ; the argument save area (56 bytes).
729 ; O32:           addiu  [[SP:\$sp]], $sp, -8
730 ; N32:           addiu  [[SP:\$sp]], $sp, -64
731 ; N64:           daddiu [[SP:\$sp]], $sp, -64
733 ; Save variable argument portion on the stack
734 ; O32-DAG:       sw $7, 20([[SP]])
735 ; O32-DAG:       sw $6, 16([[SP]])
737 ; NEW-DAG:       sd $11, 56([[SP]])
738 ; NEW-DAG:       sd $10, 48([[SP]])
739 ; NEW-DAG:       sd $9, 40([[SP]])
740 ; NEW-DAG:       sd $8, 32([[SP]])
741 ; NEW-DAG:       sd $7, 24([[SP]])
742 ; NEW-DAG:       sd $6, 16([[SP]])
743 ; NEW-DAG:       sd $5, 8([[SP]])
745 ; Initialize variable argument pointer.
746 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
747 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
748 ; first fixed argument.
749 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
750 ; space.
751 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
752 ; O32-DAG:       sw [[VA]], 0([[SP]])
754 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
755 ; N32-DAG:       sw [[VA]], 0([[SP]])
757 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
758 ; N64-DAG:       sd [[VA]], 0([[SP]])
760 ; ALL: teqi $zero, 1
762 ; Increment [[VA]]
763 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
764 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
765 ; O32-DAG:       sw [[VA2]], 0([[SP]])
767 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
768 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
769 ; N32-DAG:       sw [[VA2]], 0([[SP]])
771 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
772 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
773 ; N64-DAG:       sd [[VA2]], 0([[SP]])
775 ; Load the first argument from the variable portion.
776 ; This has used the stack pointer directly rather than the [[VA]] we just set
777 ; up.
778 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
779 ; order.
780 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
782 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
783 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
785 ; Copy the arg to the global
786 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
788 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
790 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
792 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
794 ; ALL: teqi $zero, 2
796 ; Increment [[VA]] again.
797 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
798 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
799 ; O32-DAG:       sw [[VA2]], 0([[SP]])
801 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
802 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
803 ; N32-DAG:       sw [[VA3]], 0([[SP]])
805 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
806 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
807 ; N64-DAG:       sd [[VA3]], 0([[SP]])
809 ; Load the second argument from the variable portion.
810 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
812 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
813 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
815 ; Copy the arg to the global
816 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
818   %ap = alloca ptr, align 8
819   call void @llvm.va_start(ptr %ap)
821   call void asm sideeffect "teqi $$zero, 1", ""()
822   %arg1 = va_arg ptr %ap, i16
823   %e1 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 1
824   store volatile i16 %arg1, ptr %e1, align 2
826   call void asm sideeffect "teqi $$zero, 2", ""()
827   %arg2 = va_arg ptr %ap, i16
828   %e2 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 2
829   store volatile i16 %arg2, ptr %e2, align 2
831   call void @llvm.va_end(ptr %ap)
833   ret void
836 define void @fn_i64_dotdotdot_i32(i64 %a, ...) {
837 entry:
838 ; ALL-LABEL: fn_i64_dotdotdot_i32:
840 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
841 ; the argument save area (56 bytes).
842 ; O32:           addiu  [[SP:\$sp]], $sp, -8
843 ; N32:           addiu  [[SP:\$sp]], $sp, -64
844 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
846 ; Save variable argument portion on the stack
847 ; O32-DAG:       sw $7, 20([[SP]])
848 ; O32-DAG:       sw $6, 16([[SP]])
850 ; NEW-DAG:       sd $11, 56([[SP]])
851 ; NEW-DAG:       sd $10, 48([[SP]])
852 ; NEW-DAG:       sd $9, 40([[SP]])
853 ; NEW-DAG:       sd $8, 32([[SP]])
854 ; NEW-DAG:       sd $7, 24([[SP]])
855 ; NEW-DAG:       sd $6, 16([[SP]])
856 ; NEW-DAG:       sd $5, 8([[SP]])
858 ; Initialize variable argument pointer.
859 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
860 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
861 ; first fixed argument.
862 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
863 ; space.
864 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
865 ; O32-DAG:       sw [[VA]], 0([[SP]])
867 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
868 ; N32-DAG:       sw [[VA]], 0([[SP]])
870 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
871 ; N64-DAG:       sd [[VA]], 0([[SP]])
873 ; ALL: teqi $zero, 1
875 ; Increment [[VA]]
876 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
877 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
878 ; O32-DAG:       sw [[VA2]], 0([[SP]])
880 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
881 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
882 ; N32-DAG:       sw [[VA2]], 0([[SP]])
884 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
885 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
886 ; N64-DAG:       sd [[VA2]], 0([[SP]])
888 ; Load the first argument from the variable portion.
889 ; This has used the stack pointer directly rather than the [[VA]] we just set
890 ; up.
891 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
892 ; order.
893 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
895 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
896 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
898 ; Copy the arg to the global
899 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
901 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
903 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
905 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
907 ; ALL: teqi $zero, 2
909 ; Increment [[VA]] again.
910 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
911 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
912 ; O32-DAG:       sw [[VA2]], 0([[SP]])
914 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
915 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
916 ; N32-DAG:       sw [[VA3]], 0([[SP]])
918 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
919 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
920 ; N64-DAG:       sd [[VA3]], 0([[SP]])
922 ; Load the second argument from the variable portion.
923 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
925 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
926 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
928 ; Copy the arg to the global
929 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
931   %ap = alloca ptr, align 8
932   call void @llvm.va_start(ptr %ap)
934   call void asm sideeffect "teqi $$zero, 1", ""()
935   %arg1 = va_arg ptr %ap, i32
936   %e1 = getelementptr [3 x i32], ptr @words, i32 0, i32 1
937   store volatile i32 %arg1, ptr %e1, align 4
939   call void asm sideeffect "teqi $$zero, 2", ""()
940   %arg2 = va_arg ptr %ap, i32
941   %e2 = getelementptr [3 x i32], ptr @words, i32 0, i32 2
942   store volatile i32 %arg2, ptr %e2, align 4
944   call void @llvm.va_end(ptr %ap)
946   ret void
949 define void @fn_i64_dotdotdot_i64(i64 %a, ...) {
950 entry:
951 ; ALL-LABEL: fn_i64_dotdotdot_i64:
953 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
954 ; the argument save area (56 bytes).
955 ; O32:           addiu  [[SP:\$sp]], $sp, -8
956 ; N32:           addiu  [[SP:\$sp]], $sp, -64
957 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
959 ; Save variable argument portion on the stack
960 ; O32-DAG:       sw $7, 20([[SP]])
961 ; O32-DAG:       sw $6, 16([[SP]])
963 ; NEW-DAG:       sd $11, 56([[SP]])
964 ; NEW-DAG:       sd $10, 48([[SP]])
965 ; NEW-DAG:       sd $9, 40([[SP]])
966 ; NEW-DAG:       sd $8, 32([[SP]])
967 ; NEW-DAG:       sd $7, 24([[SP]])
968 ; NEW-DAG:       sd $6, 16([[SP]])
969 ; NEW-DAG:       sd $5, 8([[SP]])
971 ; Initialize variable argument pointer.
972 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
973 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
974 ; first fixed argument.
975 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
976 ; space.
977 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
978 ; O32-DAG:       sw [[VA]], 0([[SP]])
980 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
981 ; N32-DAG:       sw [[VA]], 0([[SP]])
983 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
984 ; N64-DAG:       sd [[VA]], 0([[SP]])
986 ; ALL: teqi $zero, 1
988 ; Increment [[VA]] (and realign pointer for O32)
989 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
990 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
991 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
992 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
993 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
994 ; O32-DAG:       sw [[VA2]], 0([[SP]])
996 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
997 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
998 ; N32-DAG:       sw [[VA2]], 0([[SP]])
1000 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
1001 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
1002 ; N64-DAG:       sd [[VA2]], 0([[SP]])
1004 ; Load the first argument from the variable portion and copy it to the global.
1005 ; This has used the stack pointer directly rather than the [[VA]] we just set
1006 ; up.
1007 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
1008 ; order.
1009 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
1010 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
1011 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
1012 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8
1013 ; O32-DAG:       sw [[VA3]], 0([[SP]])
1014 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
1015 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
1017 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
1018 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
1019 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
1020 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
1022 ; ALL: teqi $zero, 2
1024 ; Increment [[VA]] again.
1025 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
1026 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
1027 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
1028 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
1029 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
1030 ; O32-DAG:       sw [[VA2]], 0([[SP]])
1032 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
1033 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
1034 ; N32-DAG:       sw [[VA3]], 0([[SP]])
1036 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
1037 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
1038 ; N64-DAG:       sd [[VA3]], 0([[SP]])
1040 ; Load the second argument from the variable portion and copy it to the global.
1041 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
1042 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8
1043 ; O32-DAG:       sw [[VA3]], 0([[SP]])
1044 ; O32-DAG:       lw [[ARG3:\$[0-9]+]], 4([[VA_TMP2]])
1045 ; O32-DAG:       sw [[ARG3]], 20([[GV]])
1046 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
1048 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
1049 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
1051   %ap = alloca ptr, align 8
1052   call void @llvm.va_start(ptr %ap)
1054   call void asm sideeffect "teqi $$zero, 1", ""()
1055   %arg1 = va_arg ptr %ap, i64
1056   %e1 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 1
1057   store volatile i64 %arg1, ptr %e1, align 8
1059   call void asm sideeffect "teqi $$zero, 2", ""()
1060   %arg2 = va_arg ptr %ap, i64
1061   %e2 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 2
1062   store volatile i64 %arg2, ptr %e2, align 8
1064   call void @llvm.va_end(ptr %ap)
1066   ret void
1069 declare void @llvm.va_start(ptr)
1070 declare void @llvm.va_end(ptr)