1 ; RUN: llc -march=mips -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=MIPS32 %s
3 @v4i8 = global <4 x i8> <i8 0, i8 0, i8 0, i8 0>
4 @v16i8 = global <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>
5 @v8i16 = global <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>
6 @v4i32 = global <4 x i32> <i32 0, i32 0, i32 0, i32 0>
7 @v2i64 = global <2 x i64> <i64 0, i64 0>
10 define void @const_v16i8() nounwind {
11 ; MIPS32: const_v16i8:
13 store volatile <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>, <16 x i8>*@v16i8
14 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0
16 store volatile <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, <16 x i8>*@v16i8
17 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 1
19 store volatile <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 31>, <16 x i8>*@v16i8
20 ; MIPS32: ld.b [[R1:\$w[0-9]+]], %lo(
22 store volatile <16 x i8> <i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6>, <16 x i8>*@v16i8
23 ; MIPS32: ld.b [[R1:\$w[0-9]+]], %lo(
25 store volatile <16 x i8> <i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2>, <16 x i8>*@v16i8
26 ; MIPS32: ldi.h [[R1:\$w[0-9]+]], 258
28 store volatile <16 x i8> <i8 1, i8 2, i8 3, i8 4, i8 1, i8 2, i8 3, i8 4, i8 1, i8 2, i8 3, i8 4, i8 1, i8 2, i8 3, i8 4>, <16 x i8>*@v16i8
29 ; MIPS32-DAG: lui [[R2:\$[0-9]+]], 258
30 ; MIPS32-DAG: ori [[R2]], [[R2]], 772
31 ; MIPS32-DAG: fill.w [[R1:\$w[0-9]+]], [[R2]]
33 store volatile <16 x i8> <i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8>, <16 x i8>*@v16i8
34 ; MIPS32: ld.b [[R1:\$w[0-9]+]], %lo(
37 ; MIPS32: .size const_v16i8
40 define void @const_v8i16() nounwind {
41 ; MIPS32: const_v8i16:
43 store volatile <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, <8 x i16>*@v8i16
44 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0
46 store volatile <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16>*@v8i16
47 ; MIPS32: ldi.h [[R1:\$w[0-9]+]], 1
49 store volatile <8 x i16> <i16 1, i16 1, i16 1, i16 2, i16 1, i16 1, i16 1, i16 31>, <8 x i16>*@v8i16
50 ; MIPS32: ld.h [[R1:\$w[0-9]+]], %lo(
52 store volatile <8 x i16> <i16 1028, i16 1028, i16 1028, i16 1028, i16 1028, i16 1028, i16 1028, i16 1028>, <8 x i16>*@v8i16
53 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 4
55 store volatile <8 x i16> <i16 1, i16 2, i16 1, i16 2, i16 1, i16 2, i16 1, i16 2>, <8 x i16>*@v8i16
56 ; MIPS32-DAG: lui [[R2:\$[0-9]+]], 1
57 ; MIPS32-DAG: ori [[R2]], [[R2]], 2
58 ; MIPS32-DAG: fill.w [[R1:\$w[0-9]+]], [[R2]]
60 store volatile <8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 1, i16 2, i16 3, i16 4>, <8 x i16>*@v8i16
61 ; MIPS32: ld.h [[R1:\$w[0-9]+]], %lo(
64 ; MIPS32: .size const_v8i16
67 define void @const_v4i32() nounwind {
68 ; MIPS32: const_v4i32:
70 store volatile <4 x i32> <i32 0, i32 0, i32 0, i32 0>, <4 x i32>*@v4i32
71 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0
73 store volatile <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32>*@v4i32
74 ; MIPS32: ldi.w [[R1:\$w[0-9]+]], 1
76 store volatile <4 x i32> <i32 1, i32 1, i32 1, i32 31>, <4 x i32>*@v4i32
77 ; MIPS32: ld.w [[R1:\$w[0-9]+]], %lo(
79 store volatile <4 x i32> <i32 16843009, i32 16843009, i32 16843009, i32 16843009>, <4 x i32>*@v4i32
80 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 1
82 store volatile <4 x i32> <i32 65537, i32 65537, i32 65537, i32 65537>, <4 x i32>*@v4i32
83 ; MIPS32: ldi.h [[R1:\$w[0-9]+]], 1
85 store volatile <4 x i32> <i32 1, i32 2, i32 1, i32 2>, <4 x i32>*@v4i32
86 ; MIPS32: ld.w [[R1:\$w[0-9]+]], %lo(
88 store volatile <4 x i32> <i32 3, i32 4, i32 5, i32 6>, <4 x i32>*@v4i32
89 ; MIPS32: ld.w [[R1:\$w[0-9]+]], %lo(
92 ; MIPS32: .size const_v4i32
95 define void @const_v2i64() nounwind {
96 ; MIPS32: const_v2i64:
98 store volatile <2 x i64> <i64 0, i64 0>, <2 x i64>*@v2i64
99 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0
101 store volatile <2 x i64> <i64 72340172838076673, i64 72340172838076673>, <2 x i64>*@v2i64
102 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 1
104 store volatile <2 x i64> <i64 281479271743489, i64 281479271743489>, <2 x i64>*@v2i64
105 ; MIPS32: ldi.h [[R1:\$w[0-9]+]], 1
107 store volatile <2 x i64> <i64 4294967297, i64 4294967297>, <2 x i64>*@v2i64
108 ; MIPS32: ldi.w [[R1:\$w[0-9]+]], 1
110 store volatile <2 x i64> <i64 1, i64 1>, <2 x i64>*@v2i64
111 ; MIPS32: ldi.d [[R1:\$w[0-9]+]], 1
113 store volatile <2 x i64> <i64 1, i64 31>, <2 x i64>*@v2i64
114 ; MIPS32: ld.w [[R1:\$w[0-9]+]], %lo(
116 store volatile <2 x i64> <i64 3, i64 4>, <2 x i64>*@v2i64
117 ; MIPS32: ld.w [[R1:\$w[0-9]+]], %lo(
120 ; MIPS32: .size const_v2i64
123 define void @nonconst_v16i8(i8 %a, i8 %b, i8 %c, i8 %d, i8 %e, i8 %f, i8 %g, i8 %h) nounwind {
124 ; MIPS32: nonconst_v16i8:
126 %1 = insertelement <16 x i8> undef, i8 %a, i32 0
127 %2 = insertelement <16 x i8> %1, i8 %b, i32 1
128 %3 = insertelement <16 x i8> %2, i8 %c, i32 2
129 %4 = insertelement <16 x i8> %3, i8 %d, i32 3
130 %5 = insertelement <16 x i8> %4, i8 %e, i32 4
131 %6 = insertelement <16 x i8> %5, i8 %f, i32 5
132 %7 = insertelement <16 x i8> %6, i8 %g, i32 6
133 %8 = insertelement <16 x i8> %7, i8 %h, i32 7
134 %9 = insertelement <16 x i8> %8, i8 %h, i32 8
135 %10 = insertelement <16 x i8> %9, i8 %h, i32 9
136 %11 = insertelement <16 x i8> %10, i8 %h, i32 10
137 %12 = insertelement <16 x i8> %11, i8 %h, i32 11
138 %13 = insertelement <16 x i8> %12, i8 %h, i32 12
139 %14 = insertelement <16 x i8> %13, i8 %h, i32 13
140 %15 = insertelement <16 x i8> %14, i8 %h, i32 14
141 %16 = insertelement <16 x i8> %15, i8 %h, i32 15
142 ; MIPS32-DAG: insert.b [[R1:\$w[0-9]+]][0], $4
143 ; MIPS32-DAG: insert.b [[R1]][1], $5
144 ; MIPS32-DAG: insert.b [[R1]][2], $6
145 ; MIPS32-DAG: insert.b [[R1]][3], $7
146 ; MIPS32-DAG: lbu [[R2:\$[0-9]+]], 19($sp)
147 ; MIPS32-DAG: insert.b [[R1]][4], [[R2]]
148 ; MIPS32-DAG: lbu [[R3:\$[0-9]+]], 23($sp)
149 ; MIPS32-DAG: insert.b [[R1]][5], [[R3]]
150 ; MIPS32-DAG: lbu [[R4:\$[0-9]+]], 27($sp)
151 ; MIPS32-DAG: insert.b [[R1]][6], [[R4]]
152 ; MIPS32-DAG: lbu [[R5:\$[0-9]+]], 31($sp)
153 ; MIPS32-DAG: insert.b [[R1]][7], [[R5]]
154 ; MIPS32-DAG: insert.b [[R1]][8], [[R5]]
155 ; MIPS32-DAG: insert.b [[R1]][9], [[R5]]
156 ; MIPS32-DAG: insert.b [[R1]][10], [[R5]]
157 ; MIPS32-DAG: insert.b [[R1]][11], [[R5]]
158 ; MIPS32-DAG: insert.b [[R1]][12], [[R5]]
159 ; MIPS32-DAG: insert.b [[R1]][13], [[R5]]
160 ; MIPS32-DAG: insert.b [[R1]][14], [[R5]]
161 ; MIPS32-DAG: insert.b [[R1]][15], [[R5]]
163 store volatile <16 x i8> %16, <16 x i8>*@v16i8
166 ; MIPS32: .size nonconst_v16i8
169 define void @nonconst_v8i16(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f, i16 %g, i16 %h) nounwind {
170 ; MIPS32: nonconst_v8i16:
172 %1 = insertelement <8 x i16> undef, i16 %a, i32 0
173 %2 = insertelement <8 x i16> %1, i16 %b, i32 1
174 %3 = insertelement <8 x i16> %2, i16 %c, i32 2
175 %4 = insertelement <8 x i16> %3, i16 %d, i32 3
176 %5 = insertelement <8 x i16> %4, i16 %e, i32 4
177 %6 = insertelement <8 x i16> %5, i16 %f, i32 5
178 %7 = insertelement <8 x i16> %6, i16 %g, i32 6
179 %8 = insertelement <8 x i16> %7, i16 %h, i32 7
180 ; MIPS32-DAG: insert.h [[R1:\$w[0-9]+]][0], $4
181 ; MIPS32-DAG: insert.h [[R1]][1], $5
182 ; MIPS32-DAG: insert.h [[R1]][2], $6
183 ; MIPS32-DAG: insert.h [[R1]][3], $7
184 ; MIPS32-DAG: lhu [[R2:\$[0-9]+]], 18($sp)
185 ; MIPS32-DAG: insert.h [[R1]][4], [[R2]]
186 ; MIPS32-DAG: lhu [[R2:\$[0-9]+]], 22($sp)
187 ; MIPS32-DAG: insert.h [[R1]][5], [[R2]]
188 ; MIPS32-DAG: lhu [[R2:\$[0-9]+]], 26($sp)
189 ; MIPS32-DAG: insert.h [[R1]][6], [[R2]]
190 ; MIPS32-DAG: lhu [[R2:\$[0-9]+]], 30($sp)
191 ; MIPS32-DAG: insert.h [[R1]][7], [[R2]]
193 store volatile <8 x i16> %8, <8 x i16>*@v8i16
196 ; MIPS32: .size nonconst_v8i16
199 define void @nonconst_v4i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
200 ; MIPS32: nonconst_v4i32:
202 %1 = insertelement <4 x i32> undef, i32 %a, i32 0
203 %2 = insertelement <4 x i32> %1, i32 %b, i32 1
204 %3 = insertelement <4 x i32> %2, i32 %c, i32 2
205 %4 = insertelement <4 x i32> %3, i32 %d, i32 3
206 ; MIPS32: insert.w [[R1:\$w[0-9]+]][0], $4
207 ; MIPS32: insert.w [[R1]][1], $5
208 ; MIPS32: insert.w [[R1]][2], $6
209 ; MIPS32: insert.w [[R1]][3], $7
211 store volatile <4 x i32> %4, <4 x i32>*@v4i32
214 ; MIPS32: .size nonconst_v4i32
217 define void @nonconst_v2i64(i64 %a, i64 %b) nounwind {
218 ; MIPS32: nonconst_v2i64:
220 %1 = insertelement <2 x i64> undef, i64 %a, i32 0
221 %2 = insertelement <2 x i64> %1, i64 %b, i32 1
222 ; MIPS32: insert.w [[R1:\$w[0-9]+]][0], $4
223 ; MIPS32: insert.w [[R1]][1], $5
224 ; MIPS32: insert.w [[R1]][2], $6
225 ; MIPS32: insert.w [[R1]][3], $7
227 store volatile <2 x i64> %2, <2 x i64>*@v2i64
230 ; MIPS32: .size nonconst_v2i64
233 define i32 @extract_sext_v16i8() nounwind {
234 ; MIPS32: extract_sext_v16i8:
236 %1 = load <16 x i8>* @v16i8
237 ; MIPS32-DAG: ld.b [[R1:\$w[0-9]+]],
239 %2 = add <16 x i8> %1, %1
240 ; MIPS32-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]]
242 %3 = extractelement <16 x i8> %2, i32 1
243 %4 = sext i8 %3 to i32
244 ; MIPS32-DAG: copy_s.b [[R3:\$[0-9]+]], [[R1]][1]
249 ; MIPS32: .size extract_sext_v16i8
252 define i32 @extract_sext_v8i16() nounwind {
253 ; MIPS32: extract_sext_v8i16:
255 %1 = load <8 x i16>* @v8i16
256 ; MIPS32-DAG: ld.h [[R1:\$w[0-9]+]],
258 %2 = add <8 x i16> %1, %1
259 ; MIPS32-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]]
261 %3 = extractelement <8 x i16> %2, i32 1
262 %4 = sext i16 %3 to i32
263 ; MIPS32-DAG: copy_s.h [[R3:\$[0-9]+]], [[R1]][1]
268 ; MIPS32: .size extract_sext_v8i16
271 define i32 @extract_sext_v4i32() nounwind {
272 ; MIPS32: extract_sext_v4i32:
274 %1 = load <4 x i32>* @v4i32
275 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
277 %2 = add <4 x i32> %1, %1
278 ; MIPS32-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
280 %3 = extractelement <4 x i32> %2, i32 1
281 ; MIPS32-DAG: copy_s.w [[R3:\$[0-9]+]], [[R1]][1]
284 ; MIPS32: .size extract_sext_v4i32
287 define i64 @extract_sext_v2i64() nounwind {
288 ; MIPS32: extract_sext_v2i64:
290 %1 = load <2 x i64>* @v2i64
291 ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]],
293 %2 = add <2 x i64> %1, %1
294 ; MIPS32-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
296 %3 = extractelement <2 x i64> %2, i32 1
297 ; MIPS32-DAG: copy_s.w [[R3:\$[0-9]+]], [[R1]][2]
298 ; MIPS32-DAG: copy_s.w [[R4:\$[0-9]+]], [[R1]][3]
303 ; MIPS32: .size extract_sext_v2i64
306 define i32 @extract_zext_v16i8() nounwind {
307 ; MIPS32: extract_zext_v16i8:
309 %1 = load <16 x i8>* @v16i8
310 ; MIPS32-DAG: ld.b [[R1:\$w[0-9]+]],
312 %2 = add <16 x i8> %1, %1
313 ; MIPS32-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]]
315 %3 = extractelement <16 x i8> %2, i32 1
316 %4 = zext i8 %3 to i32
317 ; MIPS32-DAG: copy_u.b [[R3:\$[0-9]+]], [[R1]][1]
321 ; MIPS32: .size extract_zext_v16i8
324 define i32 @extract_zext_v8i16() nounwind {
325 ; MIPS32: extract_zext_v8i16:
327 %1 = load <8 x i16>* @v8i16
328 ; MIPS32-DAG: ld.h [[R1:\$w[0-9]+]],
330 %2 = add <8 x i16> %1, %1
331 ; MIPS32-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]]
333 %3 = extractelement <8 x i16> %2, i32 1
334 %4 = zext i16 %3 to i32
335 ; MIPS32-DAG: copy_u.h [[R3:\$[0-9]+]], [[R1]][1]
339 ; MIPS32: .size extract_zext_v8i16
342 define i32 @extract_zext_v4i32() nounwind {
343 ; MIPS32: extract_zext_v4i32:
345 %1 = load <4 x i32>* @v4i32
346 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
348 %2 = add <4 x i32> %1, %1
349 ; MIPS32-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
351 %3 = extractelement <4 x i32> %2, i32 1
352 ; MIPS32-DAG: copy_{{[su]}}.w [[R3:\$[0-9]+]], [[R1]][1]
355 ; MIPS32: .size extract_zext_v4i32
358 define i64 @extract_zext_v2i64() nounwind {
359 ; MIPS32: extract_zext_v2i64:
361 %1 = load <2 x i64>* @v2i64
362 ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]],
364 %2 = add <2 x i64> %1, %1
365 ; MIPS32-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
367 %3 = extractelement <2 x i64> %2, i32 1
368 ; MIPS32-DAG: copy_{{[su]}}.w [[R3:\$[0-9]+]], [[R1]][2]
369 ; MIPS32-DAG: copy_{{[su]}}.w [[R4:\$[0-9]+]], [[R1]][3]
373 ; MIPS32: .size extract_zext_v2i64
376 define void @insert_v16i8(i32 %a) nounwind {
377 ; MIPS32: insert_v16i8:
379 %1 = load <16 x i8>* @v16i8
380 ; MIPS32-DAG: ld.b [[R1:\$w[0-9]+]],
382 %a2 = trunc i32 %a to i8
383 %a3 = sext i8 %a2 to i32
384 %a4 = trunc i32 %a3 to i8
388 %2 = insertelement <16 x i8> %1, i8 %a4, i32 1
389 ; MIPS32-DAG: insert.b [[R1]][1], $4
391 store <16 x i8> %2, <16 x i8>* @v16i8
392 ; MIPS32-DAG: st.b [[R1]]
395 ; MIPS32: .size insert_v16i8
398 define void @insert_v8i16(i32 %a) nounwind {
399 ; MIPS32: insert_v8i16:
401 %1 = load <8 x i16>* @v8i16
402 ; MIPS32-DAG: ld.h [[R1:\$w[0-9]+]],
404 %a2 = trunc i32 %a to i16
405 %a3 = sext i16 %a2 to i32
406 %a4 = trunc i32 %a3 to i16
410 %2 = insertelement <8 x i16> %1, i16 %a4, i32 1
411 ; MIPS32-DAG: insert.h [[R1]][1], $4
413 store <8 x i16> %2, <8 x i16>* @v8i16
414 ; MIPS32-DAG: st.h [[R1]]
417 ; MIPS32: .size insert_v8i16
420 define void @insert_v4i32(i32 %a) nounwind {
421 ; MIPS32: insert_v4i32:
423 %1 = load <4 x i32>* @v4i32
424 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
429 %2 = insertelement <4 x i32> %1, i32 %a, i32 1
430 ; MIPS32-DAG: insert.w [[R1]][1], $4
432 store <4 x i32> %2, <4 x i32>* @v4i32
433 ; MIPS32-DAG: st.w [[R1]]
436 ; MIPS32: .size insert_v4i32
439 define void @insert_v2i64(i64 %a) nounwind {
440 ; MIPS32: insert_v2i64:
442 %1 = load <2 x i64>* @v2i64
443 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
448 %2 = insertelement <2 x i64> %1, i64 %a, i32 1
449 ; MIPS32-DAG: insert.w [[R1]][2], $4
450 ; MIPS32-DAG: insert.w [[R1]][3], $5
452 store <2 x i64> %2, <2 x i64>* @v2i64
453 ; MIPS32-DAG: st.w [[R1]]
456 ; MIPS32: .size insert_v2i64
459 define void @truncstore() nounwind {
460 ; MIPS32: truncstore:
462 store volatile <4 x i8> <i8 -1, i8 -1, i8 -1, i8 -1>, <4 x i8>*@v4i8
463 ; TODO: What code should be emitted?
466 ; MIPS32: .size truncstore