1 ; RUN: llc -march=mips -mattr=+msa,+fp64,+mips32r2 -relocation-model=pic < %s \
2 ; RUN: | FileCheck -check-prefixes=ALL,O32 %s
3 ; RUN: llc -march=mipsel -mattr=+msa,+fp64,+mips32r2 -relocation-model=pic < %s \
4 ; RUN: | FileCheck -check-prefixes=ALL,O32 %s
5 ; RUN: llc -march=mips64 -target-abi=n32 -mattr=+msa,+fp64 -relocation-model=pic < %s \
6 ; RUN: | FileCheck -check-prefixes=ALL,N32 %s
7 ; RUN: llc -march=mips64el -target-abi=n32 -mattr=+msa,+fp64 -relocation-model=pic < %s \
8 ; RUN: | FileCheck -check-prefixes=ALL,N32 %s
9 ; RUN: llc -march=mips64 -mattr=+msa,+fp64 -relocation-model=pic < %s \
10 ; RUN: | FileCheck -check-prefixes=ALL,N64 %s
11 ; RUN: llc -march=mips64el -mattr=+msa,+fp64 -relocation-model=pic < %s \
12 ; RUN: | FileCheck -check-prefixes=ALL,N64 %s
14 @v4f32 = global <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>
15 @v2f64 = global <2 x double> <double 0.0, double 0.0>
17 @f32 = global float 0.0
18 @f64 = global double 0.0
20 define void @const_v4f32() nounwind {
21 ; ALL-LABEL: const_v4f32:
23 store volatile <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, <4 x float>*@v4f32
24 ; ALL: ldi.b [[R1:\$w[0-9]+]], 0
26 store volatile <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, <4 x float>*@v4f32
27 ; ALL: lui [[R1:\$[0-9]+]], 16256
28 ; ALL: fill.w [[R2:\$w[0-9]+]], [[R1]]
30 store volatile <4 x float> <float 1.0, float 1.0, float 1.0, float 31.0>, <4 x float>*@v4f32
31 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
32 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
33 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
34 ; ALL: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]])
36 store volatile <4 x float> <float 65537.0, float 65537.0, float 65537.0, float 65537.0>, <4 x float>*@v4f32
37 ; ALL: lui [[R1:\$[0-9]+]], 18304
38 ; ALL: ori [[R2:\$[0-9]+]], [[R1]], 128
39 ; ALL: fill.w [[R3:\$w[0-9]+]], [[R2]]
41 store volatile <4 x float> <float 1.0, float 2.0, float 1.0, float 2.0>, <4 x float>*@v4f32
42 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
43 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
44 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
45 ; ALL: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]])
47 store volatile <4 x float> <float 3.0, float 4.0, float 5.0, float 6.0>, <4 x float>*@v4f32
48 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
49 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
50 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
51 ; ALL: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]])
56 define void @const_v2f64() nounwind {
57 ; ALL-LABEL: const_v2f64:
59 store volatile <2 x double> <double 0.0, double 0.0>, <2 x double>*@v2f64
60 ; ALL: ldi.b [[R1:\$w[0-9]+]], 0
62 store volatile <2 x double> <double 72340172838076673.0, double 72340172838076673.0>, <2 x double>*@v2f64
63 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
64 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
65 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
66 ; ALL: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]])
68 store volatile <2 x double> <double 281479271743489.0, double 281479271743489.0>, <2 x double>*@v2f64
69 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
70 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
71 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
72 ; ALL: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]])
74 store volatile <2 x double> <double 4294967297.0, double 4294967297.0>, <2 x double>*@v2f64
75 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
76 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
77 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
78 ; ALL: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]])
80 store volatile <2 x double> <double 1.0, double 1.0>, <2 x double>*@v2f64
81 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
82 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
83 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
84 ; ALL: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]])
86 store volatile <2 x double> <double 1.0, double 31.0>, <2 x double>*@v2f64
87 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
88 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
89 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
90 ; ALL: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]])
92 store volatile <2 x double> <double 3.0, double 4.0>, <2 x double>*@v2f64
93 ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
94 ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
95 ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst(.L
96 ; ALL: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]])
101 define void @nonconst_v4f32() nounwind {
102 ; ALL-LABEL: nonconst_v4f32:
104 %1 = load float , float *@f32
105 %2 = insertelement <4 x float> undef, float %1, i32 0
106 %3 = insertelement <4 x float> %2, float %1, i32 1
107 %4 = insertelement <4 x float> %3, float %1, i32 2
108 %5 = insertelement <4 x float> %4, float %1, i32 3
109 store volatile <4 x float> %5, <4 x float>*@v4f32
110 ; ALL: lwc1 $f[[R1:[0-9]+]], 0(
111 ; ALL: splati.w [[R2:\$w[0-9]+]], $w[[R1]]
116 define void @nonconst_v2f64() nounwind {
117 ; ALL-LABEL: nonconst_v2f64:
119 %1 = load double , double *@f64
120 %2 = insertelement <2 x double> undef, double %1, i32 0
121 %3 = insertelement <2 x double> %2, double %1, i32 1
122 store volatile <2 x double> %3, <2 x double>*@v2f64
123 ; ALL: ldc1 $f[[R1:[0-9]+]], 0(
124 ; ALL: splati.d [[R2:\$w[0-9]+]], $w[[R1]]
129 define float @extract_v4f32() nounwind {
130 ; ALL-LABEL: extract_v4f32:
132 %1 = load <4 x float>, <4 x float>* @v4f32
133 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
135 %2 = fadd <4 x float> %1, %1
136 ; ALL-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
138 %3 = extractelement <4 x float> %2, i32 1
139 ; Element 1 can be obtained by splatting it across the vector and extracting
141 ; ALL-DAG: splati.w $w0, [[R1]][1]
146 define float @extract_v4f32_elt0() nounwind {
147 ; ALL-LABEL: extract_v4f32_elt0:
149 %1 = load <4 x float>, <4 x float>* @v4f32
150 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
152 %2 = fadd <4 x float> %1, %1
153 ; ALL-DAG: fadd.w $w0, [[R1]], [[R1]]
155 %3 = extractelement <4 x float> %2, i32 0
156 ; Element 0 can be obtained by extracting $w0:sub_lo ($f0)
163 define float @extract_v4f32_elt2() nounwind {
164 ; ALL-LABEL: extract_v4f32_elt2:
166 %1 = load <4 x float>, <4 x float>* @v4f32
167 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
169 %2 = fadd <4 x float> %1, %1
170 ; ALL-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
172 %3 = extractelement <4 x float> %2, i32 2
173 ; Element 2 can be obtained by splatting it across the vector and extracting
175 ; ALL-DAG: splati.w $w0, [[R1]][2]
180 define float @extract_v4f32_vidx() nounwind {
181 ; ALL-LABEL: extract_v4f32_vidx:
183 %1 = load <4 x float>, <4 x float>* @v4f32
184 ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4f32)(
185 ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v4f32)(
186 ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v4f32)(
187 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]])
189 %2 = fadd <4 x float> %1, %1
190 ; ALL-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
192 %3 = load i32, i32* @i32
193 ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
194 ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
195 ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
196 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
198 %4 = extractelement <4 x float> %2, i32 %3
199 ; ALL-DAG: splat.w $w0, [[R1]]{{\[}}[[IDX]]]
204 define double @extract_v2f64() nounwind {
205 ; ALL-LABEL: extract_v2f64:
207 %1 = load <2 x double>, <2 x double>* @v2f64
208 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]],
210 %2 = fadd <2 x double> %1, %1
211 ; ALL-DAG: fadd.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
213 %3 = extractelement <2 x double> %2, i32 1
214 ; Element 1 can be obtained by splatting it across the vector and extracting
216 ; ALL-DAG: splati.d $w0, [[R1]][1]
226 define double @extract_v2f64_elt0() nounwind {
227 ; ALL-LABEL: extract_v2f64_elt0:
229 %1 = load <2 x double>, <2 x double>* @v2f64
230 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]],
232 %2 = fadd <2 x double> %1, %1
233 ; ALL-DAG: fadd.d $w0, [[R1]], [[R1]]
235 %3 = extractelement <2 x double> %2, i32 0
236 ; Element 0 can be obtained by extracting $w0:sub_64 ($f0)
246 define double @extract_v2f64_vidx() nounwind {
247 ; ALL-LABEL: extract_v2f64_vidx:
249 %1 = load <2 x double>, <2 x double>* @v2f64
250 ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2f64)(
251 ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v2f64)(
252 ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v2f64)(
253 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]])
255 %2 = fadd <2 x double> %1, %1
256 ; ALL-DAG: fadd.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
258 %3 = load i32, i32* @i32
259 ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
260 ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
261 ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
262 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
264 %4 = extractelement <2 x double> %2, i32 %3
265 ; ALL-DAG: splat.d $w0, [[R1]]{{\[}}[[IDX]]]
270 define void @insert_v4f32(float %a) nounwind {
271 ; ALL-LABEL: insert_v4f32:
273 %1 = load <4 x float>, <4 x float>* @v4f32
274 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
276 %2 = insertelement <4 x float> %1, float %a, i32 1
277 ; float argument passed in $f12
278 ; ALL-DAG: insve.w [[R1]][1], $w12[0]
280 store <4 x float> %2, <4 x float>* @v4f32
281 ; ALL-DAG: st.w [[R1]]
286 define void @insert_v2f64(double %a) nounwind {
287 ; ALL-LABEL: insert_v2f64:
289 %1 = load <2 x double>, <2 x double>* @v2f64
290 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]],
292 %2 = insertelement <2 x double> %1, double %a, i32 1
293 ; double argument passed in $f12
294 ; ALL-DAG: insve.d [[R1]][1], $w12[0]
296 store <2 x double> %2, <2 x double>* @v2f64
297 ; ALL-DAG: st.d [[R1]]
302 define void @insert_v4f32_vidx(float %a) nounwind {
303 ; ALL-LABEL: insert_v4f32_vidx:
305 %1 = load <4 x float>, <4 x float>* @v4f32
306 ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4f32)(
307 ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v4f32)(
308 ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v4f32)(
309 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]])
311 %2 = load i32, i32* @i32
312 ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
313 ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
314 ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
315 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
317 %3 = insertelement <4 x float> %1, float %a, i32 %2
318 ; float argument passed in $f12
319 ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 2
320 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
321 ; ALL-DAG: insve.w [[R1]][0], $w12[0]
322 ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
323 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
325 store <4 x float> %3, <4 x float>* @v4f32
326 ; ALL-DAG: st.w [[R1]]
331 define void @insert_v2f64_vidx(double %a) nounwind {
332 ; ALL-LABEL: insert_v2f64_vidx:
334 %1 = load <2 x double>, <2 x double>* @v2f64
335 ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2f64)(
336 ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v2f64)(
337 ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v2f64)(
338 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]])
340 %2 = load i32, i32* @i32
341 ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
342 ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
343 ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
344 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
346 %3 = insertelement <2 x double> %1, double %a, i32 %2
347 ; double argument passed in $f12
348 ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 3
349 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
350 ; ALL-DAG: insve.d [[R1]][0], $w12[0]
351 ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
352 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
354 store <2 x double> %3, <2 x double>* @v2f64
355 ; ALL-DAG: st.d [[R1]]