1; RUN: llc -march=mips -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS32-BE %s 2; RUN: llc -march=mipsel -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS32-LE %s 3 4@v4i8 = global <4 x i8> <i8 0, i8 0, i8 0, i8 0> 5@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> 6@v8i16 = global <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0> 7@v4i32 = global <4 x i32> <i32 0, i32 0, i32 0, i32 0> 8@v2i64 = global <2 x i64> <i64 0, i64 0> 9@i32 = global i32 0 10@i64 = global i64 0 11 12define void @const_v16i8() nounwind { 13 ; ALL-LABEL: const_v16i8: 14 15 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 16 ; ALL: ldi.b [[R1:\$w[0-9]+]], 0 17 18 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 19 ; ALL: ldi.b [[R1:\$w[0-9]+]], 1 20 21 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 22 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 23 ; ALL: ld.b [[R1:\$w[0-9]+]], 0([[G_PTR]]) 24 25 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 26 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 27 ; ALL: ld.b [[R1:\$w[0-9]+]], 0([[G_PTR]]) 28 29 store volatile <16 x i8> <i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0>, <16 x i8>*@v16i8 30 ; MIPS32-BE: ldi.h [[R1:\$w[0-9]+]], 256 31 ; MIPS32-LE: ldi.h [[R1:\$w[0-9]+]], 1 32 33 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 34 ; MIPS32-BE-DAG: lui [[R2:\$[0-9]+]], 258 35 ; MIPS32-LE-DAG: lui [[R2:\$[0-9]+]], 1027 36 ; MIPS32-BE-DAG: ori [[R2]], [[R2]], 772 37 ; MIPS32-LE-DAG: ori [[R2]], [[R2]], 513 38 ; ALL-DAG: fill.w [[R1:\$w[0-9]+]], [[R2]] 39 40 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 41 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 42 ; ALL: ld.b [[R1:\$w[0-9]+]], 0([[G_PTR]]) 43 44 ret void 45} 46 47define void @const_v8i16() nounwind { 48 ; ALL-LABEL: const_v8i16: 49 50 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 51 ; ALL: ldi.b [[R1:\$w[0-9]+]], 0 52 53 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 54 ; ALL: ldi.h [[R1:\$w[0-9]+]], 1 55 56 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 57 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 58 ; ALL: ld.h [[R1:\$w[0-9]+]], 0([[G_PTR]]) 59 60 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 61 ; ALL: ldi.b [[R1:\$w[0-9]+]], 4 62 63 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 64 ; MIPS32-BE-DAG: lui [[R2:\$[0-9]+]], 1 65 ; MIPS32-LE-DAG: lui [[R2:\$[0-9]+]], 2 66 ; MIPS32-BE-DAG: ori [[R2]], [[R2]], 2 67 ; MIPS32-LE-DAG: ori [[R2]], [[R2]], 1 68 ; ALL-DAG: fill.w [[R1:\$w[0-9]+]], [[R2]] 69 70 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 71 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 72 ; ALL: ld.h [[R1:\$w[0-9]+]], 0([[G_PTR]]) 73 74 ret void 75} 76 77define void @const_v4i32() nounwind { 78 ; ALL-LABEL: const_v4i32: 79 80 store volatile <4 x i32> <i32 0, i32 0, i32 0, i32 0>, <4 x i32>*@v4i32 81 ; ALL: ldi.b [[R1:\$w[0-9]+]], 0 82 83 store volatile <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32>*@v4i32 84 ; ALL: ldi.w [[R1:\$w[0-9]+]], 1 85 86 store volatile <4 x i32> <i32 1, i32 1, i32 1, i32 31>, <4 x i32>*@v4i32 87 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 88 ; ALL: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]]) 89 90 store volatile <4 x i32> <i32 16843009, i32 16843009, i32 16843009, i32 16843009>, <4 x i32>*@v4i32 91 ; ALL: ldi.b [[R1:\$w[0-9]+]], 1 92 93 store volatile <4 x i32> <i32 65537, i32 65537, i32 65537, i32 65537>, <4 x i32>*@v4i32 94 ; ALL: ldi.h [[R1:\$w[0-9]+]], 1 95 96 store volatile <4 x i32> <i32 1, i32 2, i32 1, i32 2>, <4 x i32>*@v4i32 97 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 98 ; ALL: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]]) 99 100 store volatile <4 x i32> <i32 3, i32 4, i32 5, i32 6>, <4 x i32>*@v4i32 101 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 102 ; ALL: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]]) 103 104 ret void 105} 106 107define void @const_v2i64() nounwind { 108 ; ALL-LABEL: const_v2i64: 109 110 store volatile <2 x i64> <i64 0, i64 0>, <2 x i64>*@v2i64 111 ; ALL: ldi.b [[R1:\$w[0-9]+]], 0 112 113 store volatile <2 x i64> <i64 72340172838076673, i64 72340172838076673>, <2 x i64>*@v2i64 114 ; ALL: ldi.b [[R1:\$w[0-9]+]], 1 115 116 store volatile <2 x i64> <i64 281479271743489, i64 281479271743489>, <2 x i64>*@v2i64 117 ; ALL: ldi.h [[R1:\$w[0-9]+]], 1 118 119 store volatile <2 x i64> <i64 4294967297, i64 4294967297>, <2 x i64>*@v2i64 120 ; ALL: ldi.w [[R1:\$w[0-9]+]], 1 121 122 store volatile <2 x i64> <i64 1, i64 1>, <2 x i64>*@v2i64 123 ; ALL: ldi.d [[R1:\$w[0-9]+]], 1 124 125 store volatile <2 x i64> <i64 1, i64 31>, <2 x i64>*@v2i64 126 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 127 ; ALL: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]]) 128 129 store volatile <2 x i64> <i64 3, i64 4>, <2 x i64>*@v2i64 130 ; ALL: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($ 131 ; ALL: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]]) 132 133 ret void 134} 135 136define void @nonconst_v16i8(i8 signext %a, i8 signext %b, i8 signext %c, i8 signext %d, i8 signext %e, i8 signext %f, i8 signext %g, i8 signext %h) nounwind { 137 ; ALL-LABEL: nonconst_v16i8: 138 139 %1 = insertelement <16 x i8> undef, i8 %a, i32 0 140 %2 = insertelement <16 x i8> %1, i8 %b, i32 1 141 %3 = insertelement <16 x i8> %2, i8 %c, i32 2 142 %4 = insertelement <16 x i8> %3, i8 %d, i32 3 143 %5 = insertelement <16 x i8> %4, i8 %e, i32 4 144 %6 = insertelement <16 x i8> %5, i8 %f, i32 5 145 %7 = insertelement <16 x i8> %6, i8 %g, i32 6 146 %8 = insertelement <16 x i8> %7, i8 %h, i32 7 147 %9 = insertelement <16 x i8> %8, i8 %h, i32 8 148 %10 = insertelement <16 x i8> %9, i8 %h, i32 9 149 %11 = insertelement <16 x i8> %10, i8 %h, i32 10 150 %12 = insertelement <16 x i8> %11, i8 %h, i32 11 151 %13 = insertelement <16 x i8> %12, i8 %h, i32 12 152 %14 = insertelement <16 x i8> %13, i8 %h, i32 13 153 %15 = insertelement <16 x i8> %14, i8 %h, i32 14 154 %16 = insertelement <16 x i8> %15, i8 %h, i32 15 155 ; ALL-DAG: insert.b [[R1:\$w[0-9]+]][0], $4 156 ; ALL-DAG: insert.b [[R1]][1], $5 157 ; ALL-DAG: insert.b [[R1]][2], $6 158 ; ALL-DAG: insert.b [[R1]][3], $7 159 ; ALL-DAG: lw [[R2:\$[0-9]+]], 16($sp) 160 ; ALL-DAG: insert.b [[R1]][4], [[R2]] 161 ; ALL-DAG: lw [[R3:\$[0-9]+]], 20($sp) 162 ; ALL-DAG: insert.b [[R1]][5], [[R3]] 163 ; ALL-DAG: lw [[R4:\$[0-9]+]], 24($sp) 164 ; ALL-DAG: insert.b [[R1]][6], [[R4]] 165 ; ALL-DAG: lw [[R5:\$[0-9]+]], 28($sp) 166 ; ALL-DAG: insert.b [[R1]][7], [[R5]] 167 ; ALL-DAG: insert.b [[R1]][8], [[R5]] 168 ; ALL-DAG: insert.b [[R1]][9], [[R5]] 169 ; ALL-DAG: insert.b [[R1]][10], [[R5]] 170 ; ALL-DAG: insert.b [[R1]][11], [[R5]] 171 ; ALL-DAG: insert.b [[R1]][12], [[R5]] 172 ; ALL-DAG: insert.b [[R1]][13], [[R5]] 173 ; ALL-DAG: insert.b [[R1]][14], [[R5]] 174 ; ALL-DAG: insert.b [[R1]][15], [[R5]] 175 176 store volatile <16 x i8> %16, <16 x i8>*@v16i8 177 178 ret void 179} 180 181define void @nonconst_v8i16(i16 signext %a, i16 signext %b, i16 signext %c, i16 signext %d, i16 signext %e, i16 signext %f, i16 signext %g, i16 signext %h) nounwind { 182 ; ALL-LABEL: nonconst_v8i16: 183 184 %1 = insertelement <8 x i16> undef, i16 %a, i32 0 185 %2 = insertelement <8 x i16> %1, i16 %b, i32 1 186 %3 = insertelement <8 x i16> %2, i16 %c, i32 2 187 %4 = insertelement <8 x i16> %3, i16 %d, i32 3 188 %5 = insertelement <8 x i16> %4, i16 %e, i32 4 189 %6 = insertelement <8 x i16> %5, i16 %f, i32 5 190 %7 = insertelement <8 x i16> %6, i16 %g, i32 6 191 %8 = insertelement <8 x i16> %7, i16 %h, i32 7 192 ; ALL-DAG: insert.h [[R1:\$w[0-9]+]][0], $4 193 ; ALL-DAG: insert.h [[R1]][1], $5 194 ; ALL-DAG: insert.h [[R1]][2], $6 195 ; ALL-DAG: insert.h [[R1]][3], $7 196 ; ALL-DAG: lw [[R2:\$[0-9]+]], 16($sp) 197 ; ALL-DAG: insert.h [[R1]][4], [[R2]] 198 ; ALL-DAG: lw [[R2:\$[0-9]+]], 20($sp) 199 ; ALL-DAG: insert.h [[R1]][5], [[R2]] 200 ; ALL-DAG: lw [[R2:\$[0-9]+]], 24($sp) 201 ; ALL-DAG: insert.h [[R1]][6], [[R2]] 202 ; ALL-DAG: lw [[R2:\$[0-9]+]], 28($sp) 203 ; ALL-DAG: insert.h [[R1]][7], [[R2]] 204 205 store volatile <8 x i16> %8, <8 x i16>*@v8i16 206 207 ret void 208} 209 210define void @nonconst_v4i32(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d) nounwind { 211 ; ALL-LABEL: nonconst_v4i32: 212 213 %1 = insertelement <4 x i32> undef, i32 %a, i32 0 214 %2 = insertelement <4 x i32> %1, i32 %b, i32 1 215 %3 = insertelement <4 x i32> %2, i32 %c, i32 2 216 %4 = insertelement <4 x i32> %3, i32 %d, i32 3 217 ; ALL: insert.w [[R1:\$w[0-9]+]][0], $4 218 ; ALL: insert.w [[R1]][1], $5 219 ; ALL: insert.w [[R1]][2], $6 220 ; ALL: insert.w [[R1]][3], $7 221 222 store volatile <4 x i32> %4, <4 x i32>*@v4i32 223 224 ret void 225} 226 227define void @nonconst_v2i64(i64 signext %a, i64 signext %b) nounwind { 228 ; ALL-LABEL: nonconst_v2i64: 229 230 %1 = insertelement <2 x i64> undef, i64 %a, i32 0 231 %2 = insertelement <2 x i64> %1, i64 %b, i32 1 232 ; ALL: insert.w [[R1:\$w[0-9]+]][0], $4 233 ; ALL: insert.w [[R1]][1], $5 234 ; ALL: insert.w [[R1]][2], $6 235 ; ALL: insert.w [[R1]][3], $7 236 237 store volatile <2 x i64> %2, <2 x i64>*@v2i64 238 239 ret void 240} 241 242define i32 @extract_sext_v16i8() nounwind { 243 ; ALL-LABEL: extract_sext_v16i8: 244 245 %1 = load <16 x i8>, <16 x i8>* @v16i8 246 ; ALL-DAG: ld.b [[R1:\$w[0-9]+]], 247 248 %2 = add <16 x i8> %1, %1 249 ; ALL-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]] 250 251 %3 = extractelement <16 x i8> %2, i32 1 252 %4 = sext i8 %3 to i32 253 ; ALL-DAG: copy_s.b [[R3:\$[0-9]+]], [[R1]][1] 254 ; ALL-NOT: sll 255 ; ALL-NOT: sra 256 257 ret i32 %4 258} 259 260define i32 @extract_sext_v8i16() nounwind { 261 ; ALL-LABEL: extract_sext_v8i16: 262 263 %1 = load <8 x i16>, <8 x i16>* @v8i16 264 ; ALL-DAG: ld.h [[R1:\$w[0-9]+]], 265 266 %2 = add <8 x i16> %1, %1 267 ; ALL-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]] 268 269 %3 = extractelement <8 x i16> %2, i32 1 270 %4 = sext i16 %3 to i32 271 ; ALL-DAG: copy_s.h [[R3:\$[0-9]+]], [[R1]][1] 272 ; ALL-NOT: sll 273 ; ALL-NOT: sra 274 275 ret i32 %4 276} 277 278define i32 @extract_sext_v4i32() nounwind { 279 ; ALL-LABEL: extract_sext_v4i32: 280 281 %1 = load <4 x i32>, <4 x i32>* @v4i32 282 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 283 284 %2 = add <4 x i32> %1, %1 285 ; ALL-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]] 286 287 %3 = extractelement <4 x i32> %2, i32 1 288 ; ALL-DAG: copy_s.w [[R3:\$[0-9]+]], [[R1]][1] 289 290 ret i32 %3 291} 292 293define i64 @extract_sext_v2i64() nounwind { 294 ; ALL-LABEL: extract_sext_v2i64: 295 296 %1 = load <2 x i64>, <2 x i64>* @v2i64 297 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 298 299 %2 = add <2 x i64> %1, %1 300 ; ALL-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]] 301 302 %3 = extractelement <2 x i64> %2, i32 1 303 ; ALL-DAG: copy_s.w [[R3:\$[0-9]+]], [[R1]][2] 304 ; ALL-DAG: copy_s.w [[R4:\$[0-9]+]], [[R1]][3] 305 ; ALL-NOT: sll 306 ; ALL-NOT: sra 307 308 ret i64 %3 309} 310 311define i32 @extract_zext_v16i8() nounwind { 312 ; ALL-LABEL: extract_zext_v16i8: 313 314 %1 = load <16 x i8>, <16 x i8>* @v16i8 315 ; ALL-DAG: ld.b [[R1:\$w[0-9]+]], 316 317 %2 = add <16 x i8> %1, %1 318 ; ALL-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]] 319 320 %3 = extractelement <16 x i8> %2, i32 1 321 %4 = zext i8 %3 to i32 322 ; ALL-DAG: copy_u.b [[R3:\$[0-9]+]], [[R1]][1] 323 ; ALL-NOT: andi 324 325 ret i32 %4 326} 327 328define i32 @extract_zext_v8i16() nounwind { 329 ; ALL-LABEL: extract_zext_v8i16: 330 331 %1 = load <8 x i16>, <8 x i16>* @v8i16 332 ; ALL-DAG: ld.h [[R1:\$w[0-9]+]], 333 334 %2 = add <8 x i16> %1, %1 335 ; ALL-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]] 336 337 %3 = extractelement <8 x i16> %2, i32 1 338 %4 = zext i16 %3 to i32 339 ; ALL-DAG: copy_u.h [[R3:\$[0-9]+]], [[R1]][1] 340 ; ALL-NOT: andi 341 342 ret i32 %4 343} 344 345define i32 @extract_zext_v4i32() nounwind { 346 ; ALL-LABEL: extract_zext_v4i32: 347 348 %1 = load <4 x i32>, <4 x i32>* @v4i32 349 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 350 351 %2 = add <4 x i32> %1, %1 352 ; ALL-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]] 353 354 %3 = extractelement <4 x i32> %2, i32 1 355 ; ALL-DAG: copy_{{[su]}}.w [[R3:\$[0-9]+]], [[R1]][1] 356 357 ret i32 %3 358} 359 360define i64 @extract_zext_v2i64() nounwind { 361 ; ALL-LABEL: extract_zext_v2i64: 362 363 %1 = load <2 x i64>, <2 x i64>* @v2i64 364 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 365 366 %2 = add <2 x i64> %1, %1 367 ; ALL-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]] 368 369 %3 = extractelement <2 x i64> %2, i32 1 370 ; ALL-DAG: copy_{{[su]}}.w [[R3:\$[0-9]+]], [[R1]][2] 371 ; ALL-DAG: copy_{{[su]}}.w [[R4:\$[0-9]+]], [[R1]][3] 372 ; ALL-NOT: andi 373 374 ret i64 %3 375} 376 377define i32 @extract_sext_v16i8_vidx() nounwind { 378 ; ALL-LABEL: extract_sext_v16i8_vidx: 379 380 %1 = load <16 x i8>, <16 x i8>* @v16i8 381 ; ALL-DAG: lw [[PTR_V:\$[0-9]+]], %got(v16i8)( 382 ; ALL-DAG: ld.b [[R1:\$w[0-9]+]], 0([[PTR_V]]) 383 384 %2 = add <16 x i8> %1, %1 385 ; ALL-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]] 386 387 %3 = load i32, i32* @i32 388 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 389 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 390 391 %4 = extractelement <16 x i8> %2, i32 %3 392 %5 = sext i8 %4 to i32 393 ; ALL-DAG: splat.b $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 394 ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]] 395 ; ALL-DAG: sra [[R6:\$[0-9]+]], [[R5]], 24 396 397 ret i32 %5 398} 399 400define i32 @extract_sext_v8i16_vidx() nounwind { 401 ; ALL-LABEL: extract_sext_v8i16_vidx: 402 403 %1 = load <8 x i16>, <8 x i16>* @v8i16 404 ; ALL-DAG: lw [[PTR_V:\$[0-9]+]], %got(v8i16)( 405 ; ALL-DAG: ld.h [[R1:\$w[0-9]+]], 0([[PTR_V]]) 406 407 %2 = add <8 x i16> %1, %1 408 ; ALL-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]] 409 410 %3 = load i32, i32* @i32 411 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 412 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 413 414 %4 = extractelement <8 x i16> %2, i32 %3 415 %5 = sext i16 %4 to i32 416 ; ALL-DAG: splat.h $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 417 ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]] 418 ; ALL-DAG: sra [[R6:\$[0-9]+]], [[R5]], 16 419 420 ret i32 %5 421} 422 423define i32 @extract_sext_v4i32_vidx() nounwind { 424 ; ALL-LABEL: extract_sext_v4i32_vidx: 425 426 %1 = load <4 x i32>, <4 x i32>* @v4i32 427 ; ALL-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4i32)( 428 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]]) 429 430 %2 = add <4 x i32> %1, %1 431 ; ALL-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]] 432 433 %3 = load i32, i32* @i32 434 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 435 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 436 437 %4 = extractelement <4 x i32> %2, i32 %3 438 ; ALL-DAG: splat.w $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 439 ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]] 440 ; ALL-NOT: sra 441 442 ret i32 %4 443} 444 445define i64 @extract_sext_v2i64_vidx() nounwind { 446 ; ALL-LABEL: extract_sext_v2i64_vidx: 447 448 %1 = load <2 x i64>, <2 x i64>* @v2i64 449 ; ALL-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2i64)( 450 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]]) 451 452 %2 = add <2 x i64> %1, %1 453 ; ALL-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]] 454 455 %3 = load i32, i32* @i32 456 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 457 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 458 459 %4 = extractelement <2 x i64> %2, i32 %3 460 ; ALL-DAG: splat.w $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 461 ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]] 462 ; ALL-DAG: splat.w $w[[R4:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 463 ; ALL-DAG: mfc1 [[R6:\$[0-9]+]], $f[[R4]] 464 ; ALL-NOT: sra 465 466 ret i64 %4 467} 468 469define i32 @extract_zext_v16i8_vidx() nounwind { 470 ; ALL-LABEL: extract_zext_v16i8_vidx: 471 472 %1 = load <16 x i8>, <16 x i8>* @v16i8 473 ; ALL-DAG: lw [[PTR_V:\$[0-9]+]], %got(v16i8)( 474 ; ALL-DAG: ld.b [[R1:\$w[0-9]+]], 0([[PTR_V]]) 475 476 %2 = add <16 x i8> %1, %1 477 ; ALL-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]] 478 479 %3 = load i32, i32* @i32 480 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 481 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 482 483 %4 = extractelement <16 x i8> %2, i32 %3 484 %5 = zext i8 %4 to i32 485 ; ALL-DAG: splat.b $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 486 ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]] 487 ; ALL-DAG: srl [[R6:\$[0-9]+]], [[R5]], 24 488 489 ret i32 %5 490} 491 492define i32 @extract_zext_v8i16_vidx() nounwind { 493 ; ALL-LABEL: extract_zext_v8i16_vidx: 494 495 %1 = load <8 x i16>, <8 x i16>* @v8i16 496 ; ALL-DAG: lw [[PTR_V:\$[0-9]+]], %got(v8i16)( 497 ; ALL-DAG: ld.h [[R1:\$w[0-9]+]], 0([[PTR_V]]) 498 499 %2 = add <8 x i16> %1, %1 500 ; ALL-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]] 501 502 %3 = load i32, i32* @i32 503 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 504 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 505 506 %4 = extractelement <8 x i16> %2, i32 %3 507 %5 = zext i16 %4 to i32 508 ; ALL-DAG: splat.h $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 509 ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]] 510 ; ALL-DAG: srl [[R6:\$[0-9]+]], [[R5]], 16 511 512 ret i32 %5 513} 514 515define i32 @extract_zext_v4i32_vidx() nounwind { 516 ; ALL-LABEL: extract_zext_v4i32_vidx: 517 518 %1 = load <4 x i32>, <4 x i32>* @v4i32 519 ; ALL-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4i32)( 520 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]]) 521 522 %2 = add <4 x i32> %1, %1 523 ; ALL-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]] 524 525 %3 = load i32, i32* @i32 526 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 527 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 528 529 %4 = extractelement <4 x i32> %2, i32 %3 530 ; ALL-DAG: splat.w $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 531 ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]] 532 ; ALL-NOT: srl 533 534 ret i32 %4 535} 536 537define i64 @extract_zext_v2i64_vidx() nounwind { 538 ; ALL-LABEL: extract_zext_v2i64_vidx: 539 540 %1 = load <2 x i64>, <2 x i64>* @v2i64 541 ; ALL-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2i64)( 542 ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]]) 543 544 %2 = add <2 x i64> %1, %1 545 ; ALL-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]] 546 547 %3 = load i32, i32* @i32 548 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 549 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 550 551 %4 = extractelement <2 x i64> %2, i32 %3 552 ; ALL-DAG: splat.w $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 553 ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]] 554 ; ALL-DAG: splat.w $w[[R4:[0-9]+]], [[R1]]{{\[}}[[IDX]]] 555 ; ALL-DAG: mfc1 [[R6:\$[0-9]+]], $f[[R4]] 556 ; ALL-NOT: srl 557 558 ret i64 %4 559} 560 561define void @insert_v16i8(i32 signext %a) nounwind { 562 ; ALL-LABEL: insert_v16i8: 563 564 %1 = load <16 x i8>, <16 x i8>* @v16i8 565 ; ALL-DAG: ld.b [[R1:\$w[0-9]+]], 566 567 %a2 = trunc i32 %a to i8 568 %a3 = sext i8 %a2 to i32 569 %a4 = trunc i32 %a3 to i8 570 ; ALL-NOT: andi 571 ; ALL-NOT: sra 572 573 %2 = insertelement <16 x i8> %1, i8 %a4, i32 1 574 ; ALL-DAG: insert.b [[R1]][1], $4 575 576 store <16 x i8> %2, <16 x i8>* @v16i8 577 ; ALL-DAG: st.b [[R1]] 578 579 ret void 580} 581 582define void @insert_v8i16(i32 signext %a) nounwind { 583 ; ALL-LABEL: insert_v8i16: 584 585 %1 = load <8 x i16>, <8 x i16>* @v8i16 586 ; ALL-DAG: ld.h [[R1:\$w[0-9]+]], 587 588 %a2 = trunc i32 %a to i16 589 %a3 = sext i16 %a2 to i32 590 %a4 = trunc i32 %a3 to i16 591 ; ALL-NOT: andi 592 ; ALL-NOT: sra 593 594 %2 = insertelement <8 x i16> %1, i16 %a4, i32 1 595 ; ALL-DAG: insert.h [[R1]][1], $4 596 597 store <8 x i16> %2, <8 x i16>* @v8i16 598 ; ALL-DAG: st.h [[R1]] 599 600 ret void 601} 602 603define void @insert_v4i32(i32 signext %a) nounwind { 604 ; ALL-LABEL: insert_v4i32: 605 606 %1 = load <4 x i32>, <4 x i32>* @v4i32 607 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 608 609 ; ALL-NOT: andi 610 ; ALL-NOT: sra 611 612 %2 = insertelement <4 x i32> %1, i32 %a, i32 1 613 ; ALL-DAG: insert.w [[R1]][1], $4 614 615 store <4 x i32> %2, <4 x i32>* @v4i32 616 ; ALL-DAG: st.w [[R1]] 617 618 ret void 619} 620 621define void @insert_v2i64(i64 signext %a) nounwind { 622 ; ALL-LABEL: insert_v2i64: 623 624 %1 = load <2 x i64>, <2 x i64>* @v2i64 625 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 626 627 ; ALL-NOT: andi 628 ; ALL-NOT: sra 629 630 %2 = insertelement <2 x i64> %1, i64 %a, i32 1 631 ; ALL-DAG: insert.w [[R1]][2], $4 632 ; ALL-DAG: insert.w [[R1]][3], $5 633 634 store <2 x i64> %2, <2 x i64>* @v2i64 635 ; ALL-DAG: st.w [[R1]] 636 637 ret void 638} 639 640define void @insert_v16i8_vidx(i32 signext %a) nounwind { 641 ; ALL-LABEL: insert_v16i8_vidx: 642 643 %1 = load <16 x i8>, <16 x i8>* @v16i8 644 ; ALL-DAG: ld.b [[R1:\$w[0-9]+]], 645 646 %2 = load i32, i32* @i32 647 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 648 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 649 650 %a2 = trunc i32 %a to i8 651 %a3 = sext i8 %a2 to i32 652 %a4 = trunc i32 %a3 to i8 653 ; ALL-NOT: andi 654 ; ALL-NOT: sra 655 656 %3 = insertelement <16 x i8> %1, i8 %a4, i32 %2 657 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[IDX]]] 658 ; ALL-DAG: insert.b [[R1]][0], $4 659 ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[IDX]] 660 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]] 661 662 store <16 x i8> %3, <16 x i8>* @v16i8 663 ; ALL-DAG: st.b [[R1]] 664 665 ret void 666} 667 668define void @insert_v8i16_vidx(i32 %a) nounwind { 669 ; ALL-LABEL: insert_v8i16_vidx: 670 671 %1 = load <8 x i16>, <8 x i16>* @v8i16 672 ; ALL-DAG: ld.h [[R1:\$w[0-9]+]], 673 674 %2 = load i32, i32* @i32 675 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 676 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 677 678 %a2 = trunc i32 %a to i16 679 %a3 = sext i16 %a2 to i32 680 %a4 = trunc i32 %a3 to i16 681 ; ALL-NOT: andi 682 ; ALL-NOT: sra 683 684 %3 = insertelement <8 x i16> %1, i16 %a4, i32 %2 685 ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 1 686 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]] 687 ; ALL-DAG: insert.h [[R1]][0], $4 688 ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]] 689 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]] 690 691 store <8 x i16> %3, <8 x i16>* @v8i16 692 ; ALL-DAG: st.h [[R1]] 693 694 ret void 695} 696 697define void @insert_v4i32_vidx(i32 signext %a) nounwind { 698 ; ALL-LABEL: insert_v4i32_vidx: 699 700 %1 = load <4 x i32>, <4 x i32>* @v4i32 701 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 702 703 %2 = load i32, i32* @i32 704 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 705 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 706 707 ; ALL-NOT: andi 708 ; ALL-NOT: sra 709 710 %3 = insertelement <4 x i32> %1, i32 %a, i32 %2 711 ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 2 712 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]] 713 ; ALL-DAG: insert.w [[R1]][0], $4 714 ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]] 715 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]] 716 717 store <4 x i32> %3, <4 x i32>* @v4i32 718 ; ALL-DAG: st.w [[R1]] 719 720 ret void 721} 722 723define void @insert_v2i64_vidx(i64 signext %a) nounwind { 724 ; ALL-LABEL: insert_v2i64_vidx: 725 726 %1 = load <2 x i64>, <2 x i64>* @v2i64 727 ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 728 729 %2 = load i32, i32* @i32 730 ; ALL-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)( 731 ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]]) 732 733 ; ALL-NOT: andi 734 ; ALL-NOT: sra 735 736 %3 = insertelement <2 x i64> %1, i64 %a, i32 %2 737 ; TODO: This code could be a lot better but it works. The legalizer splits 738 ; 64-bit inserts into two 32-bit inserts because there is no i64 type on 739 ; MIPS32. The obvious optimisation is to perform both insert.w's at once while 740 ; the vector is rotated. 741 ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 2 742 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]] 743 ; ALL-DAG: insert.w [[R1]][0], $4 744 ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]] 745 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]] 746 ; ALL-DAG: addiu [[IDX2:\$[0-9]+]], [[IDX]], 1 747 ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX2]], 2 748 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]] 749 ; ALL-DAG: insert.w [[R1]][0], $5 750 ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]] 751 ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]] 752 753 store <2 x i64> %3, <2 x i64>* @v2i64 754 ; ALL-DAG: st.w [[R1]] 755 756 ret void 757} 758 759define void @truncstore() nounwind { 760 ; ALL-LABEL: truncstore: 761 762 store volatile <4 x i8> <i8 -1, i8 -1, i8 -1, i8 -1>, <4 x i8>*@v4i8 763 ; TODO: What code should be emitted? 764 765 ret void 766} 767