Mercurial > hg > CbC > CbC_llvm
comparison test/CodeGen/Mips/cconv/arguments-varargs.ll @ 77:54457678186b LLVM3.6
LLVM 3.6
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 08 Sep 2014 22:06:00 +0900 |
parents | |
children | 60c9769439b8 |
comparison
equal
deleted
inserted
replaced
34:e874dbf0ad9d | 77:54457678186b |
---|---|
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 -mattr=-n64,+o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s | |
5 ; RUN-TODO: llc -march=mips64el -relocation-model=static -mattr=-n64,+o32 < %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s | |
6 | |
7 ; RUN: llc -mtriple=mips64-linux -relocation-model=static -mattr=-n64,+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 -mattr=-n64,+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 -mattr=-n64,+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 -mattr=-n64,+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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
121 %arg1 = va_arg i8** %ap, i16 | |
122 %e1 = getelementptr [3 x i16]* @hwords, i32 0, i32 1 | |
123 store volatile i16 %arg1, i16* %e1, align 2 | |
124 | |
125 call void asm sideeffect "# ANCHOR2", ""() | |
126 %arg2 = va_arg i8** %ap, i16 | |
127 %e2 = getelementptr [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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
239 %arg1 = va_arg i8** %ap, i32 | |
240 %e1 = getelementptr [3 x i32]* @words, i32 0, i32 1 | |
241 store volatile i32 %arg1, i32* %e1, align 4 | |
242 | |
243 call void asm sideeffect "# ANCHOR2", ""() | |
244 %arg2 = va_arg i8** %ap, i32 | |
245 %e2 = getelementptr [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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
366 %arg1 = va_arg i8** %ap, i64 | |
367 %e1 = getelementptr [3 x i64]* @dwords, i32 0, i32 1 | |
368 store volatile i64 %arg1, i64* %e1, align 8 | |
369 | |
370 call void asm sideeffect "# ANCHOR2", ""() | |
371 %arg2 = va_arg i8** %ap, i64 | |
372 %e2 = getelementptr [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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
484 %arg1 = va_arg i8** %ap, i16 | |
485 %e1 = getelementptr [3 x i16]* @hwords, i32 0, i32 1 | |
486 store volatile i16 %arg1, i16* %e1, align 2 | |
487 | |
488 call void asm sideeffect "# ANCHOR2", ""() | |
489 %arg2 = va_arg i8** %ap, i16 | |
490 %e2 = getelementptr [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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
602 %arg1 = va_arg i8** %ap, i32 | |
603 %e1 = getelementptr [3 x i32]* @words, i32 0, i32 1 | |
604 store volatile i32 %arg1, i32* %e1, align 4 | |
605 | |
606 call void asm sideeffect "# ANCHOR2", ""() | |
607 %arg2 = va_arg i8** %ap, i32 | |
608 %e2 = getelementptr [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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
729 %arg1 = va_arg i8** %ap, i64 | |
730 %e1 = getelementptr [3 x i64]* @dwords, i32 0, i32 1 | |
731 store volatile i64 %arg1, i64* %e1, align 8 | |
732 | |
733 call void asm sideeffect "# ANCHOR2", ""() | |
734 %arg2 = va_arg i8** %ap, i64 | |
735 %e2 = getelementptr [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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
846 %arg1 = va_arg i8** %ap, i16 | |
847 %e1 = getelementptr [3 x i16]* @hwords, i32 0, i32 1 | |
848 store volatile i16 %arg1, i16* %e1, align 2 | |
849 | |
850 call void asm sideeffect "# ANCHOR2", ""() | |
851 %arg2 = va_arg i8** %ap, i16 | |
852 %e2 = getelementptr [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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
963 %arg1 = va_arg i8** %ap, i32 | |
964 %e1 = getelementptr [3 x i32]* @words, i32 0, i32 1 | |
965 store volatile i32 %arg1, i32* %e1, align 4 | |
966 | |
967 call void asm sideeffect "# ANCHOR2", ""() | |
968 %arg2 = va_arg i8** %ap, i32 | |
969 %e2 = getelementptr [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: # ANCHOR1 | |
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: # ANCHOR2 | |
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 "# ANCHOR1", ""() | |
1089 %arg1 = va_arg i8** %ap, i64 | |
1090 %e1 = getelementptr [3 x i64]* @dwords, i32 0, i32 1 | |
1091 store volatile i64 %arg1, i64* %e1, align 8 | |
1092 | |
1093 call void asm sideeffect "# ANCHOR2", ""() | |
1094 %arg2 = va_arg i8** %ap, i64 | |
1095 %e2 = getelementptr [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*) |