1 ; RUN: llc -march=mips -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=MIPS32 %s 2 ; RUN: llc -march=mipsel -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=MIPS32 %s 3 4 @v4f32 = global <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0> 5 @v2f64 = global <2 x double> <double 0.0, double 0.0> 6 @i32 = global i32 0 7 @f32 = global float 0.0 8 @f64 = global double 0.0 9 10 define void @const_v4f32() nounwind { 11 ; MIPS32-LABEL: const_v4f32: 12 13 store volatile <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, <4 x float>*@v4f32 14 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0 15 16 store volatile <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, <4 x float>*@v4f32 17 ; MIPS32: lui [[R1:\$[0-9]+]], 16256 18 ; MIPS32: fill.w [[R2:\$w[0-9]+]], [[R1]] 19 20 store volatile <4 x float> <float 1.0, float 1.0, float 1.0, float 31.0>, <4 x float>*@v4f32 21 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 22 ; MIPS32: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]]) 23 24 store volatile <4 x float> <float 65537.0, float 65537.0, float 65537.0, float 65537.0>, <4 x float>*@v4f32 25 ; MIPS32: lui [[R1:\$[0-9]+]], 18304 26 ; MIPS32: ori [[R2:\$[0-9]+]], [[R1]], 128 27 ; MIPS32: fill.w [[R3:\$w[0-9]+]], [[R2]] 28 29 store volatile <4 x float> <float 1.0, float 2.0, float 1.0, float 2.0>, <4 x float>*@v4f32 30 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 31 ; MIPS32: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]]) 32 33 store volatile <4 x float> <float 3.0, float 4.0, float 5.0, float 6.0>, <4 x float>*@v4f32 34 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 35 ; MIPS32: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]]) 36 37 ret void 38 ; MIPS32: .size const_v4f32 39 } 40 41 define void @const_v2f64() nounwind { 42 ; MIPS32-LABEL: const_v2f64: 43 44 store volatile <2 x double> <double 0.0, double 0.0>, <2 x double>*@v2f64 45 ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0 46 47 store volatile <2 x double> <double 72340172838076673.0, double 72340172838076673.0>, <2 x double>*@v2f64 48 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 49 ; MIPS32: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]]) 50 51 store volatile <2 x double> <double 281479271743489.0, double 281479271743489.0>, <2 x double>*@v2f64 52 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 53 ; MIPS32: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]]) 54 55 store volatile <2 x double> <double 4294967297.0, double 4294967297.0>, <2 x double>*@v2f64 56 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 57 ; MIPS32: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]]) 58 59 store volatile <2 x double> <double 1.0, double 1.0>, <2 x double>*@v2f64 60 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 61 ; MIPS32: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]]) 62 63 store volatile <2 x double> <double 1.0, double 31.0>, <2 x double>*@v2f64 64 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 65 ; MIPS32: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]]) 66 67 store volatile <2 x double> <double 3.0, double 4.0>, <2 x double>*@v2f64 68 ; MIPS32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 69 ; MIPS32: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]]) 70 71 ret void 72 ; MIPS32: .size const_v2f64 73 } 74 75 define void @nonconst_v4f32() nounwind { 76 ; MIPS32-LABEL: nonconst_v4f32: 77 78 %1 = load float *@f32 79 %2 = insertelement <4 x float> undef, float %1, i32 0 80 %3 = insertelement <4 x float> %2, float %1, i32 1 81 %4 = insertelement <4 x float> %3, float %1, i32 2 82 %5 = insertelement <4 x float> %4, float %1, i32 3 83 store volatile <4 x float> %5, <4 x float>*@v4f32 84 ; MIPS32: lwc1 $f[[R1:[0-9]+]], 0( 85 ; MIPS32: splati.w [[R2:\$w[0-9]+]], $w[[R1]] 86 87 ret void 88 ; MIPS32: .size nonconst_v4f32 89 } 90 91 define void @nonconst_v2f64() nounwind { 92 ; MIPS32-LABEL: nonconst_v2f64: 93 94 %1 = load double *@f64 95 %2 = insertelement <2 x double> undef, double %1, i32 0 96 %3 = insertelement <2 x double> %2, double %1, i32 1 97 store volatile <2 x double> %3, <2 x double>*@v2f64 98 ; MIPS32: ldc1 $f[[R1:[0-9]+]], 0( 99 ; MIPS32: splati.d [[R2:\$w[0-9]+]], $w[[R1]] 100 101 ret void 102 ; MIPS32: .size nonconst_v2f64 103 } 104 105 define float @extract_v4f32() nounwind { 106 ; MIPS32-LABEL: extract_v4f32: 107 108 %1 = load <4 x float>* @v4f32 109 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]], 110 111 %2 = fadd <4 x float> %1, %1 112 ; MIPS32-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]] 113 114 %3 = extractelement <4 x float> %2, i32 1 115 ; Element 1 can be obtained by splatting it across the vector and extracting 116 ; $w0:sub_lo 117 ; MIPS32-DAG: splati.w $w0, [[R1]][1] 118 119 ret float %3 120 ; MIPS32: .size extract_v4f32 121 } 122 123 define float @extract_v4f32_elt0() nounwind { 124 ; MIPS32-LABEL: extract_v4f32_elt0: 125 126 %1 = load <4 x float>* @v4f32 127 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]], 128 129 %2 = fadd <4 x float> %1, %1 130 ; MIPS32-DAG: fadd.w $w0, [[R1]], [[R1]] 131 132 %3 = extractelement <4 x float> %2, i32 0 133 ; Element 0 can be obtained by extracting $w0:sub_lo ($f0) 134 ; MIPS32-NOT: copy_u.w 135 ; MIPS32-NOT: mtc1 136 137 ret float %3 138 ; MIPS32: .size extract_v4f32_elt0 139 } 140 141 define float @extract_v4f32_elt2() nounwind { 142 ; MIPS32-LABEL: extract_v4f32_elt2: 143 144 %1 = load <4 x float>* @v4f32 145 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]], 146 147 %2 = fadd <4 x float> %1, %1 148 ; MIPS32-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]] 149 150 %3 = extractelement <4 x float> %2, i32 2 151 ; Element 2 can be obtained by splatting it across the vector and extracting 152 ; $w0:sub_lo 153 ; MIPS32-DAG: splati.w $w0, [[R1]][2] 154 155 ret float %3 156 ; MIPS32: .size extract_v4f32_elt2 157 } 158 159 define float @extract_v4f32_vidx() nounwind { 160 ; MIPS32-LABEL: extract_v4f32_vidx: 161 162 %1 = load <4 x float>* @v4f32 163 ; MIPS32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4f32)( 164 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]]) 165 166 %2 = fadd <4 x float> %1, %1 167 ; MIPS32-DAG: fadd.w [[R2:\$w[0-9]+]], [[R1]], [[R1]] 168 169 %3 = load i32* @i32 170 ; MIPS32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 171 ; MIPS32-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 172 173 %4 = extractelement <4 x float> %2, i32 %3 174 ; MIPS32-DAG: splat.w $w0, [[R1]]{{\[}}[[IDX]]] 175 176 ret float %4 177 ; MIPS32: .size extract_v4f32_vidx 178 } 179 180 define double @extract_v2f64() nounwind { 181 ; MIPS32-LABEL: extract_v2f64: 182 183 %1 = load <2 x double>* @v2f64 184 ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]], 185 186 %2 = fadd <2 x double> %1, %1 187 ; MIPS32-DAG: fadd.d [[R2:\$w[0-9]+]], [[R1]], [[R1]] 188 189 %3 = extractelement <2 x double> %2, i32 1 190 ; Element 1 can be obtained by splatting it across the vector and extracting 191 ; $w0:sub_64 192 ; MIPS32-DAG: splati.d $w0, [[R1]][1] 193 ; MIPS32-NOT: copy_u.w 194 ; MIPS32-NOT: mtc1 195 ; MIPS32-NOT: mthc1 196 ; MIPS32-NOT: sll 197 ; MIPS32-NOT: sra 198 199 ret double %3 200 ; MIPS32: .size extract_v2f64 201 } 202 203 define double @extract_v2f64_elt0() nounwind { 204 ; MIPS32-LABEL: extract_v2f64_elt0: 205 206 %1 = load <2 x double>* @v2f64 207 ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]], 208 209 %2 = fadd <2 x double> %1, %1 210 ; MIPS32-DAG: fadd.d $w0, [[R1]], [[R1]] 211 212 %3 = extractelement <2 x double> %2, i32 0 213 ; Element 0 can be obtained by extracting $w0:sub_64 ($f0) 214 ; MIPS32-NOT: copy_u.w 215 ; MIPS32-NOT: mtc1 216 ; MIPS32-NOT: mthc1 217 ; MIPS32-NOT: sll 218 ; MIPS32-NOT: sra 219 220 ret double %3 221 ; MIPS32: .size extract_v2f64_elt0 222 } 223 224 define double @extract_v2f64_vidx() nounwind { 225 ; MIPS32-LABEL: extract_v2f64_vidx: 226 227 %1 = load <2 x double>* @v2f64 228 ; MIPS32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2f64)( 229 ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]]) 230 231 %2 = fadd <2 x double> %1, %1 232 ; MIPS32-DAG: fadd.d [[R2:\$w[0-9]+]], [[R1]], [[R1]] 233 234 %3 = load i32* @i32 235 ; MIPS32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 236 ; MIPS32-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 237 238 %4 = extractelement <2 x double> %2, i32 %3 239 ; MIPS32-DAG: splat.d $w0, [[R1]]{{\[}}[[IDX]]] 240 241 ret double %4 242 ; MIPS32: .size extract_v2f64_vidx 243 } 244 245 define void @insert_v4f32(float %a) nounwind { 246 ; MIPS32-LABEL: insert_v4f32: 247 248 %1 = load <4 x float>* @v4f32 249 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]], 250 251 %2 = insertelement <4 x float> %1, float %a, i32 1 252 ; float argument passed in $f12 253 ; MIPS32-DAG: insve.w [[R1]][1], $w12[0] 254 255 store <4 x float> %2, <4 x float>* @v4f32 256 ; MIPS32-DAG: st.w [[R1]] 257 258 ret void 259 ; MIPS32: .size insert_v4f32 260 } 261 262 define void @insert_v2f64(double %a) nounwind { 263 ; MIPS32-LABEL: insert_v2f64: 264 265 %1 = load <2 x double>* @v2f64 266 ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]], 267 268 %2 = insertelement <2 x double> %1, double %a, i32 1 269 ; double argument passed in $f12 270 ; MIPS32-DAG: insve.d [[R1]][1], $w12[0] 271 272 store <2 x double> %2, <2 x double>* @v2f64 273 ; MIPS32-DAG: st.d [[R1]] 274 275 ret void 276 ; MIPS32: .size insert_v2f64 277 } 278 279 define void @insert_v4f32_vidx(float %a) nounwind { 280 ; MIPS32-LABEL: insert_v4f32_vidx: 281 282 %1 = load <4 x float>* @v4f32 283 ; MIPS32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4f32)( 284 ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]]) 285 286 %2 = load i32* @i32 287 ; MIPS32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 288 ; MIPS32-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 289 290 %3 = insertelement <4 x float> %1, float %a, i32 %2 291 ; float argument passed in $f12 292 ; MIPS32-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 2 293 ; MIPS32-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]] 294 ; MIPS32-DAG: insve.w [[R1]][0], $w12[0] 295 ; MIPS32-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]] 296 ; MIPS32-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]] 297 298 store <4 x float> %3, <4 x float>* @v4f32 299 ; MIPS32-DAG: st.w [[R1]] 300 301 ret void 302 ; MIPS32: .size insert_v4f32_vidx 303 } 304 305 define void @insert_v2f64_vidx(double %a) nounwind { 306 ; MIPS32-LABEL: insert_v2f64_vidx: 307 308 %1 = load <2 x double>* @v2f64 309 ; MIPS32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2f64)( 310 ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]]) 311 312 %2 = load i32* @i32 313 ; MIPS32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 314 ; MIPS32-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 315 316 %3 = insertelement <2 x double> %1, double %a, i32 %2 317 ; double argument passed in $f12 318 ; MIPS32-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 3 319 ; MIPS32-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]] 320 ; MIPS32-DAG: insve.d [[R1]][0], $w12[0] 321 ; MIPS32-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]] 322 ; MIPS32-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]] 323 324 store <2 x double> %3, <2 x double>* @v2f64 325 ; MIPS32-DAG: st.d [[R1]] 326 327 ret void 328 ; MIPS32: .size insert_v2f64_vidx 329 } 330