1;; AltiVec patterns. 2;; Copyright (C) 2002-2020 Free Software Foundation, Inc. 3;; Contributed by Aldy Hernandez (aldy@quesejoda.com) 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21(define_c_enum "unspec" 22 [UNSPEC_VCMPBFP 23 UNSPEC_VMSUMU 24 UNSPEC_VMSUMUDM 25 UNSPEC_VMSUMM 26 UNSPEC_VMSUMSHM 27 UNSPEC_VMSUMUHS 28 UNSPEC_VMSUMSHS 29 UNSPEC_VMHADDSHS 30 UNSPEC_VMHRADDSHS 31 UNSPEC_VADDCUW 32 UNSPEC_VADDU 33 UNSPEC_VADDS 34 UNSPEC_VAVGU 35 UNSPEC_VAVGS 36 UNSPEC_VMULEUB 37 UNSPEC_VMULESB 38 UNSPEC_VMULEUH 39 UNSPEC_VMULESH 40 UNSPEC_VMULEUW 41 UNSPEC_VMULESW 42 UNSPEC_VMULOUB 43 UNSPEC_VMULOSB 44 UNSPEC_VMULOUH 45 UNSPEC_VMULOSH 46 UNSPEC_VMULOUW 47 UNSPEC_VMULOSW 48 UNSPEC_VPKPX 49 UNSPEC_VPACK_SIGN_SIGN_SAT 50 UNSPEC_VPACK_SIGN_UNS_SAT 51 UNSPEC_VPACK_UNS_UNS_SAT 52 UNSPEC_VPACK_UNS_UNS_MOD 53 UNSPEC_VPACK_UNS_UNS_MOD_DIRECT 54 UNSPEC_VREVEV 55 UNSPEC_VSLV4SI 56 UNSPEC_VSLO 57 UNSPEC_VSR 58 UNSPEC_VSRO 59 UNSPEC_VSUBCUW 60 UNSPEC_VSUBU 61 UNSPEC_VSUBS 62 UNSPEC_VSUM4UBS 63 UNSPEC_VSUM4S 64 UNSPEC_VSUM2SWS 65 UNSPEC_VSUMSWS 66 UNSPEC_VPERM 67 UNSPEC_VPERMR 68 UNSPEC_VPERM_UNS 69 UNSPEC_VRFIN 70 UNSPEC_VCFUX 71 UNSPEC_VCFSX 72 UNSPEC_VCTUXS 73 UNSPEC_VCTSXS 74 UNSPEC_VLOGEFP 75 UNSPEC_VEXPTEFP 76 UNSPEC_VSLDOI 77 UNSPEC_VUNPACK_HI_SIGN 78 UNSPEC_VUNPACK_LO_SIGN 79 UNSPEC_VUNPACK_HI_SIGN_DIRECT 80 UNSPEC_VUNPACK_LO_SIGN_DIRECT 81 UNSPEC_VUPKHPX 82 UNSPEC_VUPKLPX 83 UNSPEC_CONVERT_4F32_8I16 84 UNSPEC_CONVERT_4F32_8F16 85 UNSPEC_DST 86 UNSPEC_DSTT 87 UNSPEC_DSTST 88 UNSPEC_DSTSTT 89 UNSPEC_LVSL 90 UNSPEC_LVSR 91 UNSPEC_LVE 92 UNSPEC_STVX 93 UNSPEC_STVXL 94 UNSPEC_STVE 95 UNSPEC_SET_VSCR 96 UNSPEC_GET_VRSAVE 97 UNSPEC_LVX 98 UNSPEC_REDUC_PLUS 99 UNSPEC_VECSH 100 UNSPEC_EXTEVEN_V4SI 101 UNSPEC_EXTEVEN_V8HI 102 UNSPEC_EXTEVEN_V16QI 103 UNSPEC_EXTEVEN_V4SF 104 UNSPEC_EXTODD_V4SI 105 UNSPEC_EXTODD_V8HI 106 UNSPEC_EXTODD_V16QI 107 UNSPEC_EXTODD_V4SF 108 UNSPEC_INTERHI_V4SI 109 UNSPEC_INTERHI_V8HI 110 UNSPEC_INTERHI_V16QI 111 UNSPEC_INTERLO_V4SI 112 UNSPEC_INTERLO_V8HI 113 UNSPEC_INTERLO_V16QI 114 UNSPEC_LVLX 115 UNSPEC_LVLXL 116 UNSPEC_LVRX 117 UNSPEC_LVRXL 118 UNSPEC_STVLX 119 UNSPEC_STVLXL 120 UNSPEC_STVRX 121 UNSPEC_STVRXL 122 UNSPEC_VADU 123 UNSPEC_VSLV 124 UNSPEC_VSRV 125 UNSPEC_VMULWHUB 126 UNSPEC_VMULWLUB 127 UNSPEC_VMULWHSB 128 UNSPEC_VMULWLSB 129 UNSPEC_VMULWHUH 130 UNSPEC_VMULWLUH 131 UNSPEC_VMULWHSH 132 UNSPEC_VMULWLSH 133 UNSPEC_VUPKHUB 134 UNSPEC_VUPKHUH 135 UNSPEC_VUPKLUB 136 UNSPEC_VUPKLUH 137 UNSPEC_VPERMSI 138 UNSPEC_VPERMHI 139 UNSPEC_INTERHI 140 UNSPEC_INTERLO 141 UNSPEC_VUPKHS_V4SF 142 UNSPEC_VUPKLS_V4SF 143 UNSPEC_VUPKHU_V4SF 144 UNSPEC_VUPKLU_V4SF 145 UNSPEC_VGBBD 146 UNSPEC_VMRGH_DIRECT 147 UNSPEC_VMRGL_DIRECT 148 UNSPEC_VSPLT_DIRECT 149 UNSPEC_VMRGEW_DIRECT 150 UNSPEC_VMRGOW_DIRECT 151 UNSPEC_VSUMSWS_DIRECT 152 UNSPEC_VADDCUQ 153 UNSPEC_VADDEUQM 154 UNSPEC_VADDECUQ 155 UNSPEC_VSUBCUQ 156 UNSPEC_VSUBEUQM 157 UNSPEC_VSUBECUQ 158 UNSPEC_VBPERMQ 159 UNSPEC_VBPERMD 160 UNSPEC_BCDADD 161 UNSPEC_BCDSUB 162 UNSPEC_BCD_OVERFLOW 163 UNSPEC_VRLMI 164 UNSPEC_VRLNM 165]) 166 167(define_c_enum "unspecv" 168 [UNSPECV_SET_VRSAVE 169 UNSPECV_MTVSCR 170 UNSPECV_MFVSCR 171 UNSPECV_DSSALL 172 UNSPECV_DSS 173 ]) 174 175;; Like VI, defined in vector.md, but add ISA 2.07 integer vector ops 176(define_mode_iterator VI2 [V4SI V8HI V16QI V2DI]) 177;; Short vec int modes 178(define_mode_iterator VIshort [V8HI V16QI]) 179;; Longer vec int modes for rotate/mask ops 180(define_mode_iterator VIlong [V2DI V4SI]) 181;; Vec float modes 182(define_mode_iterator VF [V4SF]) 183;; Vec modes, pity mode iterators are not composable 184(define_mode_iterator V [V4SI V8HI V16QI V4SF]) 185;; Vec modes for move/logical/permute ops, include vector types for move not 186;; otherwise handled by altivec (v2df, v2di, ti) 187(define_mode_iterator VM [V4SI 188 V8HI 189 V16QI 190 V4SF 191 V2DF 192 V2DI 193 V1TI 194 TI 195 (KF "FLOAT128_VECTOR_P (KFmode)") 196 (TF "FLOAT128_VECTOR_P (TFmode)")]) 197 198;; Like VM, except don't do TImode 199(define_mode_iterator VM2 [V4SI 200 V8HI 201 V16QI 202 V4SF 203 V2DF 204 V2DI 205 V1TI 206 (KF "FLOAT128_VECTOR_P (KFmode)") 207 (TF "FLOAT128_VECTOR_P (TFmode)")]) 208 209;; Map the Vector convert single precision to double precision for integer 210;; versus floating point 211(define_mode_attr VS_sxwsp [(V4SI "sxw") (V4SF "sp")]) 212 213;; Specific iterator for parity which does not have a byte/half-word form, but 214;; does have a quad word form 215(define_mode_iterator VParity [V4SI 216 V2DI 217 V1TI 218 TI]) 219 220(define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")]) 221(define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")]) 222(define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)") 223 (V8HI "VECTOR_UNIT_ALTIVEC_P (V8HImode)") 224 (V4SI "VECTOR_UNIT_ALTIVEC_P (V4SImode)") 225 (V2DI "VECTOR_UNIT_P8_VECTOR_P (V2DImode)") 226 (V1TI "VECTOR_UNIT_ALTIVEC_P (V1TImode)")]) 227 228;; Vector pack/unpack 229(define_mode_iterator VP [V2DI V4SI V8HI]) 230(define_mode_attr VP_small [(V2DI "V4SI") (V4SI "V8HI") (V8HI "V16QI")]) 231(define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")]) 232(define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")]) 233 234;; Vector negate 235(define_mode_iterator VNEG [V4SI V2DI]) 236 237;; Vector move instructions. 238(define_insn "*altivec_mov<mode>" 239 [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,?Y,?*r,?*r,v,v,?*r") 240 (match_operand:VM2 1 "input_operand" "v,Z,v,*r,Y,*r,j,W,W"))] 241 "VECTOR_MEM_ALTIVEC_P (<MODE>mode) 242 && (register_operand (operands[0], <MODE>mode) 243 || register_operand (operands[1], <MODE>mode))" 244 "@ 245 stvx %1,%y0 246 lvx %0,%y1 247 vor %0,%1,%1 248 # 249 # 250 # 251 vxor %0,%0,%0 252 * return output_vec_const_move (operands); 253 #" 254 [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*,*") 255 (set_attr "length" "*,*,*,20,20,20,*,8,32")]) 256 257;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode 258;; is for unions. However for plain data movement, slightly favor the vector 259;; loads 260(define_insn "*altivec_movti" 261 [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?Y,?r,?r,v,v") 262 (match_operand:TI 1 "input_operand" "v,Z,v,r,Y,r,j,W"))] 263 "VECTOR_MEM_ALTIVEC_P (TImode) 264 && (register_operand (operands[0], TImode) 265 || register_operand (operands[1], TImode))" 266 "@ 267 stvx %1,%y0 268 lvx %0,%y1 269 vor %0,%1,%1 270 # 271 # 272 # 273 vxor %0,%0,%0 274 * return output_vec_const_move (operands);" 275 [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*")]) 276 277;; Load up a vector with the most significant bit set by loading up -1 and 278;; doing a shift left 279(define_split 280 [(set (match_operand:VM 0 "altivec_register_operand") 281 (match_operand:VM 1 "easy_vector_constant_msb"))] 282 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed" 283 [(const_int 0)] 284{ 285 rtx dest = operands[0]; 286 machine_mode mode = GET_MODE (operands[0]); 287 rtvec v; 288 int i, num_elements; 289 290 if (mode == V4SFmode) 291 { 292 mode = V4SImode; 293 dest = gen_lowpart (V4SImode, dest); 294 } 295 296 num_elements = GET_MODE_NUNITS (mode); 297 v = rtvec_alloc (num_elements); 298 for (i = 0; i < num_elements; i++) 299 RTVEC_ELT (v, i) = constm1_rtx; 300 301 emit_insn (gen_vec_initv4sisi (dest, gen_rtx_PARALLEL (mode, v))); 302 emit_insn (gen_rtx_SET (dest, gen_rtx_ASHIFT (mode, dest, dest))); 303 DONE; 304}) 305 306(define_split 307 [(set (match_operand:VM 0 "altivec_register_operand") 308 (match_operand:VM 1 "easy_vector_constant_add_self"))] 309 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed" 310 [(set (match_dup 0) (match_dup 3)) 311 (set (match_dup 0) (match_dup 4))] 312{ 313 rtx dup = gen_easy_altivec_constant (operands[1]); 314 rtx const_vec; 315 machine_mode op_mode = <MODE>mode; 316 317 /* Divide the operand of the resulting VEC_DUPLICATE, and use 318 simplify_rtx to make a CONST_VECTOR. */ 319 XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode, 320 XEXP (dup, 0), const1_rtx); 321 const_vec = simplify_rtx (dup); 322 323 if (op_mode == V4SFmode) 324 { 325 op_mode = V4SImode; 326 operands[0] = gen_lowpart (op_mode, operands[0]); 327 } 328 if (GET_MODE (const_vec) == op_mode) 329 operands[3] = const_vec; 330 else 331 operands[3] = gen_lowpart (op_mode, const_vec); 332 operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]); 333}) 334 335(define_split 336 [(set (match_operand:VM 0 "altivec_register_operand") 337 (match_operand:VM 1 "easy_vector_constant_vsldoi"))] 338 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && can_create_pseudo_p ()" 339 [(set (match_dup 2) (match_dup 3)) 340 (set (match_dup 4) (match_dup 5)) 341 (set (match_dup 0) 342 (unspec:VM [(match_dup 2) 343 (match_dup 4) 344 (match_dup 6)] 345 UNSPEC_VSLDOI))] 346{ 347 rtx op1 = operands[1]; 348 int elt = (BYTES_BIG_ENDIAN) ? 0 : GET_MODE_NUNITS (<MODE>mode) - 1; 349 HOST_WIDE_INT val = const_vector_elt_as_int (op1, elt); 350 rtx rtx_val = GEN_INT (val); 351 int shift = vspltis_shifted (op1); 352 353 gcc_assert (shift != 0); 354 operands[2] = gen_reg_rtx (<MODE>mode); 355 operands[3] = gen_const_vec_duplicate (<MODE>mode, rtx_val); 356 operands[4] = gen_reg_rtx (<MODE>mode); 357 358 if (shift < 0) 359 { 360 operands[5] = CONSTM1_RTX (<MODE>mode); 361 operands[6] = GEN_INT (-shift); 362 } 363 else 364 { 365 operands[5] = CONST0_RTX (<MODE>mode); 366 operands[6] = GEN_INT (shift); 367 } 368}) 369 370(define_insn "get_vrsave_internal" 371 [(set (match_operand:SI 0 "register_operand" "=r") 372 (unspec:SI [(reg:SI VRSAVE_REGNO)] UNSPEC_GET_VRSAVE))] 373 "TARGET_ALTIVEC" 374{ 375 if (TARGET_MACHO) 376 return "mfspr %0,256"; 377 else 378 return "mfvrsave %0"; 379} 380 [(set_attr "type" "*")]) 381 382(define_insn "*set_vrsave_internal" 383 [(match_parallel 0 "vrsave_operation" 384 [(set (reg:SI VRSAVE_REGNO) 385 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r") 386 (reg:SI VRSAVE_REGNO)] UNSPECV_SET_VRSAVE))])] 387 "TARGET_ALTIVEC" 388{ 389 if (TARGET_MACHO) 390 return "mtspr 256,%1"; 391 else 392 return "mtvrsave %1"; 393} 394 [(set_attr "type" "*")]) 395 396(define_insn "*save_world" 397 [(match_parallel 0 "save_world_operation" 398 [(clobber (reg:SI LR_REGNO)) 399 (use (match_operand:SI 1 "call_operand" "s"))])] 400 "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" 401 "bl %z1" 402 [(set_attr "type" "branch")]) 403 404(define_insn "*restore_world" 405 [(match_parallel 0 "restore_world_operation" 406 [(return) 407 (use (match_operand:SI 1 "call_operand" "s")) 408 (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])] 409 "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" 410 "b %z1") 411 412;; The save_vregs and restore_vregs patterns don't use memory_operand 413;; because (plus (reg) (const_int)) is not a valid vector address. 414;; This way is more compact than describing exactly what happens in 415;; the out-of-line functions, ie. loading the constant into r11/r12 416;; then using indexed addressing, and requires less editing of rtl 417;; to describe the operation to dwarf2out_frame_debug_expr. 418(define_insn "*save_vregs_<mode>_r11" 419 [(match_parallel 0 "any_parallel_operand" 420 [(clobber (reg:P LR_REGNO)) 421 (use (match_operand:P 1 "symbol_ref_operand" "s")) 422 (clobber (reg:P 11)) 423 (use (reg:P 0)) 424 (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b") 425 (match_operand:P 3 "short_cint_operand" "I"))) 426 (match_operand:V4SI 4 "altivec_register_operand" "v"))])] 427 "TARGET_ALTIVEC" 428 "bl %1" 429 [(set_attr "type" "branch")]) 430 431(define_insn "*save_vregs_<mode>_r12" 432 [(match_parallel 0 "any_parallel_operand" 433 [(clobber (reg:P LR_REGNO)) 434 (use (match_operand:P 1 "symbol_ref_operand" "s")) 435 (clobber (reg:P 12)) 436 (use (reg:P 0)) 437 (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b") 438 (match_operand:P 3 "short_cint_operand" "I"))) 439 (match_operand:V4SI 4 "altivec_register_operand" "v"))])] 440 "TARGET_ALTIVEC" 441 "bl %1" 442 [(set_attr "type" "branch")]) 443 444(define_insn "*restore_vregs_<mode>_r11" 445 [(match_parallel 0 "any_parallel_operand" 446 [(clobber (reg:P LR_REGNO)) 447 (use (match_operand:P 1 "symbol_ref_operand" "s")) 448 (clobber (reg:P 11)) 449 (use (reg:P 0)) 450 (set (match_operand:V4SI 2 "altivec_register_operand" "=v") 451 (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b") 452 (match_operand:P 4 "short_cint_operand" "I"))))])] 453 "TARGET_ALTIVEC" 454 "bl %1" 455 [(set_attr "type" "branch")]) 456 457(define_insn "*restore_vregs_<mode>_r12" 458 [(match_parallel 0 "any_parallel_operand" 459 [(clobber (reg:P LR_REGNO)) 460 (use (match_operand:P 1 "symbol_ref_operand" "s")) 461 (clobber (reg:P 12)) 462 (use (reg:P 0)) 463 (set (match_operand:V4SI 2 "altivec_register_operand" "=v") 464 (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b") 465 (match_operand:P 4 "short_cint_operand" "I"))))])] 466 "TARGET_ALTIVEC" 467 "bl %1" 468 [(set_attr "type" "branch")]) 469 470;; Simple binary operations. 471 472;; add 473(define_insn "add<mode>3" 474 [(set (match_operand:VI2 0 "register_operand" "=v") 475 (plus:VI2 (match_operand:VI2 1 "register_operand" "v") 476 (match_operand:VI2 2 "register_operand" "v")))] 477 "<VI_unit>" 478 "vaddu<VI_char>m %0,%1,%2" 479 [(set_attr "type" "vecsimple")]) 480 481(define_insn "*altivec_addv4sf3" 482 [(set (match_operand:V4SF 0 "register_operand" "=v") 483 (plus:V4SF (match_operand:V4SF 1 "register_operand" "v") 484 (match_operand:V4SF 2 "register_operand" "v")))] 485 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 486 "vaddfp %0,%1,%2" 487 [(set_attr "type" "vecfloat")]) 488 489(define_insn "altivec_vaddcuw" 490 [(set (match_operand:V4SI 0 "register_operand" "=v") 491 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 492 (match_operand:V4SI 2 "register_operand" "v")] 493 UNSPEC_VADDCUW))] 494 "VECTOR_UNIT_ALTIVEC_P (V4SImode)" 495 "vaddcuw %0,%1,%2" 496 [(set_attr "type" "vecsimple")]) 497 498(define_insn "altivec_vaddu<VI_char>s" 499 [(set (match_operand:VI 0 "register_operand" "=v") 500 (unspec:VI [(match_operand:VI 1 "register_operand" "v") 501 (match_operand:VI 2 "register_operand" "v")] 502 UNSPEC_VADDU)) 503 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 504 "<VI_unit>" 505 "vaddu<VI_char>s %0,%1,%2" 506 [(set_attr "type" "vecsimple")]) 507 508(define_insn "altivec_vadds<VI_char>s" 509 [(set (match_operand:VI 0 "register_operand" "=v") 510 (unspec:VI [(match_operand:VI 1 "register_operand" "v") 511 (match_operand:VI 2 "register_operand" "v")] 512 UNSPEC_VADDS)) 513 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 514 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 515 "vadds<VI_char>s %0,%1,%2" 516 [(set_attr "type" "vecsimple")]) 517 518;; sub 519(define_insn "sub<mode>3" 520 [(set (match_operand:VI2 0 "register_operand" "=v") 521 (minus:VI2 (match_operand:VI2 1 "register_operand" "v") 522 (match_operand:VI2 2 "register_operand" "v")))] 523 "<VI_unit>" 524 "vsubu<VI_char>m %0,%1,%2" 525 [(set_attr "type" "vecsimple")]) 526 527(define_insn "*altivec_subv4sf3" 528 [(set (match_operand:V4SF 0 "register_operand" "=v") 529 (minus:V4SF (match_operand:V4SF 1 "register_operand" "v") 530 (match_operand:V4SF 2 "register_operand" "v")))] 531 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 532 "vsubfp %0,%1,%2" 533 [(set_attr "type" "vecfloat")]) 534 535(define_insn "altivec_vsubcuw" 536 [(set (match_operand:V4SI 0 "register_operand" "=v") 537 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 538 (match_operand:V4SI 2 "register_operand" "v")] 539 UNSPEC_VSUBCUW))] 540 "VECTOR_UNIT_ALTIVEC_P (V4SImode)" 541 "vsubcuw %0,%1,%2" 542 [(set_attr "type" "vecsimple")]) 543 544(define_insn "altivec_vsubu<VI_char>s" 545 [(set (match_operand:VI 0 "register_operand" "=v") 546 (unspec:VI [(match_operand:VI 1 "register_operand" "v") 547 (match_operand:VI 2 "register_operand" "v")] 548 UNSPEC_VSUBU)) 549 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 550 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 551 "vsubu<VI_char>s %0,%1,%2" 552 [(set_attr "type" "vecsimple")]) 553 554(define_insn "altivec_vsubs<VI_char>s" 555 [(set (match_operand:VI 0 "register_operand" "=v") 556 (unspec:VI [(match_operand:VI 1 "register_operand" "v") 557 (match_operand:VI 2 "register_operand" "v")] 558 UNSPEC_VSUBS)) 559 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 560 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 561 "vsubs<VI_char>s %0,%1,%2" 562 [(set_attr "type" "vecsimple")]) 563 564;; 565(define_insn "uavg<mode>3_ceil" 566 [(set (match_operand:VI 0 "register_operand" "=v") 567 (unspec:VI [(match_operand:VI 1 "register_operand" "v") 568 (match_operand:VI 2 "register_operand" "v")] 569 UNSPEC_VAVGU))] 570 "TARGET_ALTIVEC" 571 "vavgu<VI_char> %0,%1,%2" 572 [(set_attr "type" "vecsimple")]) 573 574(define_insn "avg<mode>3_ceil" 575 [(set (match_operand:VI 0 "register_operand" "=v") 576 (unspec:VI [(match_operand:VI 1 "register_operand" "v") 577 (match_operand:VI 2 "register_operand" "v")] 578 UNSPEC_VAVGS))] 579 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 580 "vavgs<VI_char> %0,%1,%2" 581 [(set_attr "type" "vecsimple")]) 582 583(define_insn "altivec_vcmpbfp" 584 [(set (match_operand:V4SI 0 "register_operand" "=v") 585 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") 586 (match_operand:V4SF 2 "register_operand" "v")] 587 UNSPEC_VCMPBFP))] 588 "VECTOR_UNIT_ALTIVEC_P (V4SImode)" 589 "vcmpbfp %0,%1,%2" 590 [(set_attr "type" "veccmp")]) 591 592(define_insn "altivec_eq<mode>" 593 [(set (match_operand:VI2 0 "altivec_register_operand" "=v") 594 (eq:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") 595 (match_operand:VI2 2 "altivec_register_operand" "v")))] 596 "<VI_unit>" 597 "vcmpequ<VI_char> %0,%1,%2" 598 [(set_attr "type" "veccmpfx")]) 599 600(define_insn "*altivec_gt<mode>" 601 [(set (match_operand:VI2 0 "altivec_register_operand" "=v") 602 (gt:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") 603 (match_operand:VI2 2 "altivec_register_operand" "v")))] 604 "<VI_unit>" 605 "vcmpgts<VI_char> %0,%1,%2" 606 [(set_attr "type" "veccmpfx")]) 607 608(define_insn "*altivec_gtu<mode>" 609 [(set (match_operand:VI2 0 "altivec_register_operand" "=v") 610 (gtu:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") 611 (match_operand:VI2 2 "altivec_register_operand" "v")))] 612 "<VI_unit>" 613 "vcmpgtu<VI_char> %0,%1,%2" 614 [(set_attr "type" "veccmpfx")]) 615 616(define_insn "*altivec_eqv4sf" 617 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") 618 (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") 619 (match_operand:V4SF 2 "altivec_register_operand" "v")))] 620 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 621 "vcmpeqfp %0,%1,%2" 622 [(set_attr "type" "veccmp")]) 623 624(define_insn "*altivec_gtv4sf" 625 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") 626 (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") 627 (match_operand:V4SF 2 "altivec_register_operand" "v")))] 628 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 629 "vcmpgtfp %0,%1,%2" 630 [(set_attr "type" "veccmp")]) 631 632(define_insn "*altivec_gev4sf" 633 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") 634 (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") 635 (match_operand:V4SF 2 "altivec_register_operand" "v")))] 636 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 637 "vcmpgefp %0,%1,%2" 638 [(set_attr "type" "veccmp")]) 639 640(define_insn "*altivec_vsel<mode>" 641 [(set (match_operand:VM 0 "altivec_register_operand" "=v") 642 (if_then_else:VM 643 (ne:CC (match_operand:VM 1 "altivec_register_operand" "v") 644 (match_operand:VM 4 "zero_constant" "")) 645 (match_operand:VM 2 "altivec_register_operand" "v") 646 (match_operand:VM 3 "altivec_register_operand" "v")))] 647 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" 648 "vsel %0,%3,%2,%1" 649 [(set_attr "type" "vecmove")]) 650 651(define_insn "*altivec_vsel<mode>_uns" 652 [(set (match_operand:VM 0 "altivec_register_operand" "=v") 653 (if_then_else:VM 654 (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v") 655 (match_operand:VM 4 "zero_constant" "")) 656 (match_operand:VM 2 "altivec_register_operand" "v") 657 (match_operand:VM 3 "altivec_register_operand" "v")))] 658 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" 659 "vsel %0,%3,%2,%1" 660 [(set_attr "type" "vecmove")]) 661 662;; Fused multiply add. 663 664(define_insn "*altivec_fmav4sf4" 665 [(set (match_operand:V4SF 0 "register_operand" "=v") 666 (fma:V4SF (match_operand:V4SF 1 "register_operand" "v") 667 (match_operand:V4SF 2 "register_operand" "v") 668 (match_operand:V4SF 3 "register_operand" "v")))] 669 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 670 "vmaddfp %0,%1,%2,%3" 671 [(set_attr "type" "vecfloat")]) 672 673;; We do multiply as a fused multiply-add with an add of a -0.0 vector. 674 675(define_expand "altivec_mulv4sf3" 676 [(set (match_operand:V4SF 0 "register_operand") 677 (fma:V4SF (match_operand:V4SF 1 "register_operand") 678 (match_operand:V4SF 2 "register_operand") 679 (match_dup 3)))] 680 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 681{ 682 rtx neg0; 683 684 /* Generate [-0.0, -0.0, -0.0, -0.0]. */ 685 neg0 = gen_reg_rtx (V4SImode); 686 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); 687 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); 688 689 operands[3] = gen_lowpart (V4SFmode, neg0); 690}) 691 692;; 32-bit integer multiplication 693;; A_high = Operand_0 & 0xFFFF0000 >> 16 694;; A_low = Operand_0 & 0xFFFF 695;; B_high = Operand_1 & 0xFFFF0000 >> 16 696;; B_low = Operand_1 & 0xFFFF 697;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16 698 699;; (define_insn "mulv4si3" 700;; [(set (match_operand:V4SI 0 "register_operand" "=v") 701;; (mult:V4SI (match_operand:V4SI 1 "register_operand" "v") 702;; (match_operand:V4SI 2 "register_operand" "v")))] 703(define_insn "mulv4si3_p8" 704 [(set (match_operand:V4SI 0 "register_operand" "=v") 705 (mult:V4SI (match_operand:V4SI 1 "register_operand" "v") 706 (match_operand:V4SI 2 "register_operand" "v")))] 707 "TARGET_P8_VECTOR" 708 "vmuluwm %0,%1,%2" 709 [(set_attr "type" "veccomplex")]) 710 711(define_expand "mulv4si3" 712 [(use (match_operand:V4SI 0 "register_operand")) 713 (use (match_operand:V4SI 1 "register_operand")) 714 (use (match_operand:V4SI 2 "register_operand"))] 715 "TARGET_ALTIVEC" 716{ 717 rtx zero; 718 rtx swap; 719 rtx small_swap; 720 rtx sixteen; 721 rtx one; 722 rtx two; 723 rtx low_product; 724 rtx high_product; 725 726 if (TARGET_P8_VECTOR) 727 { 728 emit_insn (gen_mulv4si3_p8 (operands[0], operands[1], operands[2])); 729 DONE; 730 } 731 732 zero = gen_reg_rtx (V4SImode); 733 emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); 734 735 sixteen = gen_reg_rtx (V4SImode); 736 emit_insn (gen_altivec_vspltisw (sixteen, gen_rtx_CONST_INT (V4SImode, -16))); 737 738 swap = gen_reg_rtx (V4SImode); 739 emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen)); 740 741 one = gen_reg_rtx (V8HImode); 742 convert_move (one, operands[1], 0); 743 744 two = gen_reg_rtx (V8HImode); 745 convert_move (two, operands[2], 0); 746 747 small_swap = gen_reg_rtx (V8HImode); 748 convert_move (small_swap, swap, 0); 749 750 low_product = gen_reg_rtx (V4SImode); 751 emit_insn (gen_altivec_vmulouh (low_product, one, two)); 752 753 high_product = gen_reg_rtx (V4SImode); 754 emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero)); 755 756 emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen)); 757 758 emit_insn (gen_addv4si3 (operands[0], high_product, low_product)); 759 760 DONE; 761}) 762 763(define_expand "mulv8hi3" 764 [(use (match_operand:V8HI 0 "register_operand")) 765 (use (match_operand:V8HI 1 "register_operand")) 766 (use (match_operand:V8HI 2 "register_operand"))] 767 "TARGET_ALTIVEC" 768{ 769 rtx zero = gen_reg_rtx (V8HImode); 770 771 emit_insn (gen_altivec_vspltish (zero, const0_rtx)); 772 emit_insn (gen_fmav8hi4 (operands[0], operands[1], operands[2], zero)); 773 774 DONE; 775}) 776 777 778;; Fused multiply subtract 779(define_insn "*altivec_vnmsubfp" 780 [(set (match_operand:V4SF 0 "register_operand" "=v") 781 (neg:V4SF 782 (fma:V4SF (match_operand:V4SF 1 "register_operand" "v") 783 (match_operand:V4SF 2 "register_operand" "v") 784 (neg:V4SF 785 (match_operand:V4SF 3 "register_operand" "v")))))] 786 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 787 "vnmsubfp %0,%1,%2,%3" 788 [(set_attr "type" "vecfloat")]) 789 790(define_insn "altivec_vmsumu<VI_char>m" 791 [(set (match_operand:V4SI 0 "register_operand" "=v") 792 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") 793 (match_operand:VIshort 2 "register_operand" "v") 794 (match_operand:V4SI 3 "register_operand" "v")] 795 UNSPEC_VMSUMU))] 796 "TARGET_ALTIVEC" 797 "vmsumu<VI_char>m %0,%1,%2,%3" 798 [(set_attr "type" "veccomplex")]) 799 800(define_insn "altivec_vmsumudm" 801 [(set (match_operand:V1TI 0 "register_operand" "=v") 802 (unspec:V1TI [(match_operand:V2DI 1 "register_operand" "v") 803 (match_operand:V2DI 2 "register_operand" "v") 804 (match_operand:V1TI 3 "register_operand" "v")] 805 UNSPEC_VMSUMUDM))] 806 "TARGET_P8_VECTOR" 807 "vmsumudm %0,%1,%2,%3" 808 [(set_attr "type" "veccomplex")]) 809 810(define_insn "altivec_vmsumm<VI_char>m" 811 [(set (match_operand:V4SI 0 "register_operand" "=v") 812 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") 813 (match_operand:VIshort 2 "register_operand" "v") 814 (match_operand:V4SI 3 "register_operand" "v")] 815 UNSPEC_VMSUMM))] 816 "TARGET_ALTIVEC" 817 "vmsumm<VI_char>m %0,%1,%2,%3" 818 [(set_attr "type" "veccomplex")]) 819 820(define_insn "altivec_vmsumshm" 821 [(set (match_operand:V4SI 0 "register_operand" "=v") 822 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 823 (match_operand:V8HI 2 "register_operand" "v") 824 (match_operand:V4SI 3 "register_operand" "v")] 825 UNSPEC_VMSUMSHM))] 826 "TARGET_ALTIVEC" 827 "vmsumshm %0,%1,%2,%3" 828 [(set_attr "type" "veccomplex")]) 829 830(define_insn "altivec_vmsumuhs" 831 [(set (match_operand:V4SI 0 "register_operand" "=v") 832 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 833 (match_operand:V8HI 2 "register_operand" "v") 834 (match_operand:V4SI 3 "register_operand" "v")] 835 UNSPEC_VMSUMUHS)) 836 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 837 "TARGET_ALTIVEC" 838 "vmsumuhs %0,%1,%2,%3" 839 [(set_attr "type" "veccomplex")]) 840 841(define_insn "altivec_vmsumshs" 842 [(set (match_operand:V4SI 0 "register_operand" "=v") 843 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 844 (match_operand:V8HI 2 "register_operand" "v") 845 (match_operand:V4SI 3 "register_operand" "v")] 846 UNSPEC_VMSUMSHS)) 847 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 848 "TARGET_ALTIVEC" 849 "vmsumshs %0,%1,%2,%3" 850 [(set_attr "type" "veccomplex")]) 851 852;; max 853 854(define_insn "umax<mode>3" 855 [(set (match_operand:VI2 0 "register_operand" "=v") 856 (umax:VI2 (match_operand:VI2 1 "register_operand" "v") 857 (match_operand:VI2 2 "register_operand" "v")))] 858 "<VI_unit>" 859 "vmaxu<VI_char> %0,%1,%2" 860 [(set_attr "type" "vecsimple")]) 861 862(define_insn "smax<mode>3" 863 [(set (match_operand:VI2 0 "register_operand" "=v") 864 (smax:VI2 (match_operand:VI2 1 "register_operand" "v") 865 (match_operand:VI2 2 "register_operand" "v")))] 866 "<VI_unit>" 867 "vmaxs<VI_char> %0,%1,%2" 868 [(set_attr "type" "vecsimple")]) 869 870(define_insn "*altivec_smaxv4sf3" 871 [(set (match_operand:V4SF 0 "register_operand" "=v") 872 (smax:V4SF (match_operand:V4SF 1 "register_operand" "v") 873 (match_operand:V4SF 2 "register_operand" "v")))] 874 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 875 "vmaxfp %0,%1,%2" 876 [(set_attr "type" "veccmp")]) 877 878(define_insn "umin<mode>3" 879 [(set (match_operand:VI2 0 "register_operand" "=v") 880 (umin:VI2 (match_operand:VI2 1 "register_operand" "v") 881 (match_operand:VI2 2 "register_operand" "v")))] 882 "<VI_unit>" 883 "vminu<VI_char> %0,%1,%2" 884 [(set_attr "type" "vecsimple")]) 885 886(define_insn "smin<mode>3" 887 [(set (match_operand:VI2 0 "register_operand" "=v") 888 (smin:VI2 (match_operand:VI2 1 "register_operand" "v") 889 (match_operand:VI2 2 "register_operand" "v")))] 890 "<VI_unit>" 891 "vmins<VI_char> %0,%1,%2" 892 [(set_attr "type" "vecsimple")]) 893 894(define_insn "*altivec_sminv4sf3" 895 [(set (match_operand:V4SF 0 "register_operand" "=v") 896 (smin:V4SF (match_operand:V4SF 1 "register_operand" "v") 897 (match_operand:V4SF 2 "register_operand" "v")))] 898 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 899 "vminfp %0,%1,%2" 900 [(set_attr "type" "veccmp")]) 901 902(define_insn "altivec_vmhaddshs" 903 [(set (match_operand:V8HI 0 "register_operand" "=v") 904 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") 905 (match_operand:V8HI 2 "register_operand" "v") 906 (match_operand:V8HI 3 "register_operand" "v")] 907 UNSPEC_VMHADDSHS)) 908 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 909 "TARGET_ALTIVEC" 910 "vmhaddshs %0,%1,%2,%3" 911 [(set_attr "type" "veccomplex")]) 912 913(define_insn "altivec_vmhraddshs" 914 [(set (match_operand:V8HI 0 "register_operand" "=v") 915 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") 916 (match_operand:V8HI 2 "register_operand" "v") 917 (match_operand:V8HI 3 "register_operand" "v")] 918 UNSPEC_VMHRADDSHS)) 919 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 920 "TARGET_ALTIVEC" 921 "vmhraddshs %0,%1,%2,%3" 922 [(set_attr "type" "veccomplex")]) 923 924(define_insn "fmav8hi4" 925 [(set (match_operand:V8HI 0 "register_operand" "=v") 926 (plus:V8HI (mult:V8HI (match_operand:V8HI 1 "register_operand" "v") 927 (match_operand:V8HI 2 "register_operand" "v")) 928 (match_operand:V8HI 3 "register_operand" "v")))] 929 "TARGET_ALTIVEC" 930 "vmladduhm %0,%1,%2,%3" 931 [(set_attr "type" "veccomplex")]) 932 933(define_expand "altivec_vmrghb" 934 [(use (match_operand:V16QI 0 "register_operand")) 935 (use (match_operand:V16QI 1 "register_operand")) 936 (use (match_operand:V16QI 2 "register_operand"))] 937 "TARGET_ALTIVEC" 938{ 939 rtvec v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17), 940 GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19), 941 GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21), 942 GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23)); 943 rtx x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]); 944 x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v)); 945 emit_insn (gen_rtx_SET (operands[0], x)); 946 DONE; 947}) 948 949(define_insn "*altivec_vmrghb_internal" 950 [(set (match_operand:V16QI 0 "register_operand" "=v") 951 (vec_select:V16QI 952 (vec_concat:V32QI 953 (match_operand:V16QI 1 "register_operand" "v") 954 (match_operand:V16QI 2 "register_operand" "v")) 955 (parallel [(const_int 0) (const_int 16) 956 (const_int 1) (const_int 17) 957 (const_int 2) (const_int 18) 958 (const_int 3) (const_int 19) 959 (const_int 4) (const_int 20) 960 (const_int 5) (const_int 21) 961 (const_int 6) (const_int 22) 962 (const_int 7) (const_int 23)])))] 963 "TARGET_ALTIVEC" 964{ 965 if (BYTES_BIG_ENDIAN) 966 return "vmrghb %0,%1,%2"; 967 else 968 return "vmrglb %0,%2,%1"; 969} 970 [(set_attr "type" "vecperm")]) 971 972(define_insn "altivec_vmrghb_direct" 973 [(set (match_operand:V16QI 0 "register_operand" "=v") 974 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 975 (match_operand:V16QI 2 "register_operand" "v")] 976 UNSPEC_VMRGH_DIRECT))] 977 "TARGET_ALTIVEC" 978 "vmrghb %0,%1,%2" 979 [(set_attr "type" "vecperm")]) 980 981(define_expand "altivec_vmrghh" 982 [(use (match_operand:V8HI 0 "register_operand")) 983 (use (match_operand:V8HI 1 "register_operand")) 984 (use (match_operand:V8HI 2 "register_operand"))] 985 "TARGET_ALTIVEC" 986{ 987 rtvec v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9), 988 GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11)); 989 rtx x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]); 990 991 x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v)); 992 emit_insn (gen_rtx_SET (operands[0], x)); 993 DONE; 994}) 995 996(define_insn "*altivec_vmrghh_internal" 997 [(set (match_operand:V8HI 0 "register_operand" "=v") 998 (vec_select:V8HI 999 (vec_concat:V16HI 1000 (match_operand:V8HI 1 "register_operand" "v") 1001 (match_operand:V8HI 2 "register_operand" "v")) 1002 (parallel [(const_int 0) (const_int 8) 1003 (const_int 1) (const_int 9) 1004 (const_int 2) (const_int 10) 1005 (const_int 3) (const_int 11)])))] 1006 "TARGET_ALTIVEC" 1007{ 1008 if (BYTES_BIG_ENDIAN) 1009 return "vmrghh %0,%1,%2"; 1010 else 1011 return "vmrglh %0,%2,%1"; 1012} 1013 [(set_attr "type" "vecperm")]) 1014 1015(define_insn "altivec_vmrghh_direct" 1016 [(set (match_operand:V8HI 0 "register_operand" "=v") 1017 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") 1018 (match_operand:V8HI 2 "register_operand" "v")] 1019 UNSPEC_VMRGH_DIRECT))] 1020 "TARGET_ALTIVEC" 1021 "vmrghh %0,%1,%2" 1022 [(set_attr "type" "vecperm")]) 1023 1024(define_expand "altivec_vmrghw" 1025 [(use (match_operand:V4SI 0 "register_operand")) 1026 (use (match_operand:V4SI 1 "register_operand")) 1027 (use (match_operand:V4SI 2 "register_operand"))] 1028 "VECTOR_MEM_ALTIVEC_P (V4SImode)" 1029{ 1030 rtvec v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5)); 1031 rtx x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]); 1032 x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v)); 1033 emit_insn (gen_rtx_SET (operands[0], x)); 1034 DONE; 1035}) 1036 1037(define_insn "*altivec_vmrghw_internal" 1038 [(set (match_operand:V4SI 0 "register_operand" "=v") 1039 (vec_select:V4SI 1040 (vec_concat:V8SI 1041 (match_operand:V4SI 1 "register_operand" "v") 1042 (match_operand:V4SI 2 "register_operand" "v")) 1043 (parallel [(const_int 0) (const_int 4) 1044 (const_int 1) (const_int 5)])))] 1045 "VECTOR_MEM_ALTIVEC_P (V4SImode)" 1046{ 1047 if (BYTES_BIG_ENDIAN) 1048 return "vmrghw %0,%1,%2"; 1049 else 1050 return "vmrglw %0,%2,%1"; 1051} 1052 [(set_attr "type" "vecperm")]) 1053 1054(define_insn "altivec_vmrghw_direct" 1055 [(set (match_operand:V4SI 0 "register_operand" "=v,wa") 1056 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v,wa") 1057 (match_operand:V4SI 2 "register_operand" "v,wa")] 1058 UNSPEC_VMRGH_DIRECT))] 1059 "TARGET_ALTIVEC" 1060 "@ 1061 vmrghw %0,%1,%2 1062 xxmrghw %x0,%x1,%x2" 1063 [(set_attr "type" "vecperm")]) 1064 1065(define_insn "*altivec_vmrghsf" 1066 [(set (match_operand:V4SF 0 "register_operand" "=v") 1067 (vec_select:V4SF 1068 (vec_concat:V8SF 1069 (match_operand:V4SF 1 "register_operand" "v") 1070 (match_operand:V4SF 2 "register_operand" "v")) 1071 (parallel [(const_int 0) (const_int 4) 1072 (const_int 1) (const_int 5)])))] 1073 "VECTOR_MEM_ALTIVEC_P (V4SFmode)" 1074{ 1075 if (BYTES_BIG_ENDIAN) 1076 return "vmrghw %0,%1,%2"; 1077 else 1078 return "vmrglw %0,%2,%1"; 1079} 1080 [(set_attr "type" "vecperm")]) 1081 1082(define_expand "altivec_vmrglb" 1083 [(use (match_operand:V16QI 0 "register_operand")) 1084 (use (match_operand:V16QI 1 "register_operand")) 1085 (use (match_operand:V16QI 2 "register_operand"))] 1086 "TARGET_ALTIVEC" 1087{ 1088 rtvec v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25), 1089 GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27), 1090 GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29), 1091 GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31)); 1092 rtx x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]); 1093 x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v)); 1094 emit_insn (gen_rtx_SET (operands[0], x)); 1095 DONE; 1096}) 1097 1098(define_insn "*altivec_vmrglb_internal" 1099 [(set (match_operand:V16QI 0 "register_operand" "=v") 1100 (vec_select:V16QI 1101 (vec_concat:V32QI 1102 (match_operand:V16QI 1 "register_operand" "v") 1103 (match_operand:V16QI 2 "register_operand" "v")) 1104 (parallel [(const_int 8) (const_int 24) 1105 (const_int 9) (const_int 25) 1106 (const_int 10) (const_int 26) 1107 (const_int 11) (const_int 27) 1108 (const_int 12) (const_int 28) 1109 (const_int 13) (const_int 29) 1110 (const_int 14) (const_int 30) 1111 (const_int 15) (const_int 31)])))] 1112 "TARGET_ALTIVEC" 1113{ 1114 if (BYTES_BIG_ENDIAN) 1115 return "vmrglb %0,%1,%2"; 1116 else 1117 return "vmrghb %0,%2,%1"; 1118} 1119 [(set_attr "type" "vecperm")]) 1120 1121(define_insn "altivec_vmrglb_direct" 1122 [(set (match_operand:V16QI 0 "register_operand" "=v") 1123 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 1124 (match_operand:V16QI 2 "register_operand" "v")] 1125 UNSPEC_VMRGL_DIRECT))] 1126 "TARGET_ALTIVEC" 1127 "vmrglb %0,%1,%2" 1128 [(set_attr "type" "vecperm")]) 1129 1130(define_expand "altivec_vmrglh" 1131 [(use (match_operand:V8HI 0 "register_operand")) 1132 (use (match_operand:V8HI 1 "register_operand")) 1133 (use (match_operand:V8HI 2 "register_operand"))] 1134 "TARGET_ALTIVEC" 1135{ 1136 rtvec v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13), 1137 GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15)); 1138 rtx x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]); 1139 x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v)); 1140 emit_insn (gen_rtx_SET (operands[0], x)); 1141 DONE; 1142}) 1143 1144(define_insn "*altivec_vmrglh_internal" 1145 [(set (match_operand:V8HI 0 "register_operand" "=v") 1146 (vec_select:V8HI 1147 (vec_concat:V16HI 1148 (match_operand:V8HI 1 "register_operand" "v") 1149 (match_operand:V8HI 2 "register_operand" "v")) 1150 (parallel [(const_int 4) (const_int 12) 1151 (const_int 5) (const_int 13) 1152 (const_int 6) (const_int 14) 1153 (const_int 7) (const_int 15)])))] 1154 "TARGET_ALTIVEC" 1155{ 1156 if (BYTES_BIG_ENDIAN) 1157 return "vmrglh %0,%1,%2"; 1158 else 1159 return "vmrghh %0,%2,%1"; 1160} 1161 [(set_attr "type" "vecperm")]) 1162 1163(define_insn "altivec_vmrglh_direct" 1164 [(set (match_operand:V8HI 0 "register_operand" "=v") 1165 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") 1166 (match_operand:V8HI 2 "register_operand" "v")] 1167 UNSPEC_VMRGL_DIRECT))] 1168 "TARGET_ALTIVEC" 1169 "vmrglh %0,%1,%2" 1170 [(set_attr "type" "vecperm")]) 1171 1172(define_expand "altivec_vmrglw" 1173 [(use (match_operand:V4SI 0 "register_operand")) 1174 (use (match_operand:V4SI 1 "register_operand")) 1175 (use (match_operand:V4SI 2 "register_operand"))] 1176 "VECTOR_MEM_ALTIVEC_P (V4SImode)" 1177{ 1178 rtvec v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7)); 1179 rtx x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]); 1180 x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v)); 1181 emit_insn (gen_rtx_SET (operands[0], x)); 1182 DONE; 1183}) 1184 1185(define_insn "*altivec_vmrglw_internal" 1186 [(set (match_operand:V4SI 0 "register_operand" "=v") 1187 (vec_select:V4SI 1188 (vec_concat:V8SI 1189 (match_operand:V4SI 1 "register_operand" "v") 1190 (match_operand:V4SI 2 "register_operand" "v")) 1191 (parallel [(const_int 2) (const_int 6) 1192 (const_int 3) (const_int 7)])))] 1193 "VECTOR_MEM_ALTIVEC_P (V4SImode)" 1194{ 1195 if (BYTES_BIG_ENDIAN) 1196 return "vmrglw %0,%1,%2"; 1197 else 1198 return "vmrghw %0,%2,%1"; 1199} 1200 [(set_attr "type" "vecperm")]) 1201 1202(define_insn "altivec_vmrglw_direct" 1203 [(set (match_operand:V4SI 0 "register_operand" "=v,wa") 1204 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v,wa") 1205 (match_operand:V4SI 2 "register_operand" "v,wa")] 1206 UNSPEC_VMRGL_DIRECT))] 1207 "TARGET_ALTIVEC" 1208 "@ 1209 vmrglw %0,%1,%2 1210 xxmrglw %x0,%x1,%x2" 1211 [(set_attr "type" "vecperm")]) 1212 1213(define_insn "*altivec_vmrglsf" 1214 [(set (match_operand:V4SF 0 "register_operand" "=v") 1215 (vec_select:V4SF 1216 (vec_concat:V8SF 1217 (match_operand:V4SF 1 "register_operand" "v") 1218 (match_operand:V4SF 2 "register_operand" "v")) 1219 (parallel [(const_int 2) (const_int 6) 1220 (const_int 3) (const_int 7)])))] 1221 "VECTOR_MEM_ALTIVEC_P (V4SFmode)" 1222{ 1223 if (BYTES_BIG_ENDIAN) 1224 return "vmrglw %0,%1,%2"; 1225 else 1226 return "vmrghw %0,%2,%1"; 1227} 1228 [(set_attr "type" "vecperm")]) 1229 1230;; Power8 vector merge two V2DF/V2DI even words to V2DF 1231(define_expand "p8_vmrgew_<mode>" 1232 [(use (match_operand:VSX_D 0 "vsx_register_operand")) 1233 (use (match_operand:VSX_D 1 "vsx_register_operand")) 1234 (use (match_operand:VSX_D 2 "vsx_register_operand"))] 1235 "VECTOR_MEM_VSX_P (<MODE>mode)" 1236{ 1237 rtvec v; 1238 rtx x; 1239 1240 v = gen_rtvec (2, GEN_INT (0), GEN_INT (2)); 1241 x = gen_rtx_VEC_CONCAT (<VS_double>mode, operands[1], operands[2]); 1242 1243 x = gen_rtx_VEC_SELECT (<MODE>mode, x, gen_rtx_PARALLEL (VOIDmode, v)); 1244 emit_insn (gen_rtx_SET (operands[0], x)); 1245 DONE; 1246}) 1247 1248;; Power8 vector merge two V4SF/V4SI even words to V4SF 1249(define_insn "p8_vmrgew_<mode>" 1250 [(set (match_operand:VSX_W 0 "register_operand" "=v") 1251 (vec_select:VSX_W 1252 (vec_concat:<VS_double> 1253 (match_operand:VSX_W 1 "register_operand" "v") 1254 (match_operand:VSX_W 2 "register_operand" "v")) 1255 (parallel [(const_int 0) (const_int 4) 1256 (const_int 2) (const_int 6)])))] 1257 "TARGET_P8_VECTOR" 1258{ 1259 if (BYTES_BIG_ENDIAN) 1260 return "vmrgew %0,%1,%2"; 1261 else 1262 return "vmrgow %0,%2,%1"; 1263} 1264 [(set_attr "type" "vecperm")]) 1265 1266(define_insn "p8_vmrgow_<mode>" 1267 [(set (match_operand:VSX_W 0 "register_operand" "=v") 1268 (vec_select:VSX_W 1269 (vec_concat:<VS_double> 1270 (match_operand:VSX_W 1 "register_operand" "v") 1271 (match_operand:VSX_W 2 "register_operand" "v")) 1272 (parallel [(const_int 1) (const_int 5) 1273 (const_int 3) (const_int 7)])))] 1274 "TARGET_P8_VECTOR" 1275{ 1276 if (BYTES_BIG_ENDIAN) 1277 return "vmrgow %0,%1,%2"; 1278 else 1279 return "vmrgew %0,%2,%1"; 1280} 1281 [(set_attr "type" "vecperm")]) 1282 1283(define_expand "p8_vmrgow_<mode>" 1284 [(use (match_operand:VSX_D 0 "vsx_register_operand")) 1285 (use (match_operand:VSX_D 1 "vsx_register_operand")) 1286 (use (match_operand:VSX_D 2 "vsx_register_operand"))] 1287 "VECTOR_MEM_VSX_P (<MODE>mode)" 1288{ 1289 rtvec v; 1290 rtx x; 1291 1292 v = gen_rtvec (2, GEN_INT (1), GEN_INT (3)); 1293 x = gen_rtx_VEC_CONCAT (<VS_double>mode, operands[1], operands[2]); 1294 1295 x = gen_rtx_VEC_SELECT (<MODE>mode, x, gen_rtx_PARALLEL (VOIDmode, v)); 1296 emit_insn (gen_rtx_SET (operands[0], x)); 1297 DONE; 1298}) 1299 1300(define_insn "p8_vmrgew_<mode>_direct" 1301 [(set (match_operand:VSX_W 0 "register_operand" "=v") 1302 (unspec:VSX_W [(match_operand:VSX_W 1 "register_operand" "v") 1303 (match_operand:VSX_W 2 "register_operand" "v")] 1304 UNSPEC_VMRGEW_DIRECT))] 1305 "TARGET_P8_VECTOR" 1306 "vmrgew %0,%1,%2" 1307 [(set_attr "type" "vecperm")]) 1308 1309(define_insn "p8_vmrgow_<mode>_direct" 1310 [(set (match_operand:VSX_W 0 "register_operand" "=v") 1311 (unspec:VSX_W [(match_operand:VSX_W 1 "register_operand" "v") 1312 (match_operand:VSX_W 2 "register_operand" "v")] 1313 UNSPEC_VMRGOW_DIRECT))] 1314 "TARGET_P8_VECTOR" 1315 "vmrgow %0,%1,%2" 1316 [(set_attr "type" "vecperm")]) 1317 1318(define_expand "vec_widen_umult_even_v16qi" 1319 [(use (match_operand:V8HI 0 "register_operand")) 1320 (use (match_operand:V16QI 1 "register_operand")) 1321 (use (match_operand:V16QI 2 "register_operand"))] 1322 "TARGET_ALTIVEC" 1323{ 1324 if (BYTES_BIG_ENDIAN) 1325 emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2])); 1326 else 1327 emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2])); 1328 DONE; 1329}) 1330 1331(define_expand "vec_widen_smult_even_v16qi" 1332 [(use (match_operand:V8HI 0 "register_operand")) 1333 (use (match_operand:V16QI 1 "register_operand")) 1334 (use (match_operand:V16QI 2 "register_operand"))] 1335 "TARGET_ALTIVEC" 1336{ 1337 if (BYTES_BIG_ENDIAN) 1338 emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2])); 1339 else 1340 emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2])); 1341 DONE; 1342}) 1343 1344(define_expand "vec_widen_umult_even_v8hi" 1345 [(use (match_operand:V4SI 0 "register_operand")) 1346 (use (match_operand:V8HI 1 "register_operand")) 1347 (use (match_operand:V8HI 2 "register_operand"))] 1348 "TARGET_ALTIVEC" 1349{ 1350 if (BYTES_BIG_ENDIAN) 1351 emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2])); 1352 else 1353 emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2])); 1354 DONE; 1355}) 1356 1357(define_expand "vec_widen_smult_even_v8hi" 1358 [(use (match_operand:V4SI 0 "register_operand")) 1359 (use (match_operand:V8HI 1 "register_operand")) 1360 (use (match_operand:V8HI 2 "register_operand"))] 1361 "TARGET_ALTIVEC" 1362{ 1363 if (BYTES_BIG_ENDIAN) 1364 emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2])); 1365 else 1366 emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2])); 1367 DONE; 1368}) 1369 1370(define_expand "vec_widen_umult_even_v4si" 1371 [(use (match_operand:V2DI 0 "register_operand")) 1372 (use (match_operand:V4SI 1 "register_operand")) 1373 (use (match_operand:V4SI 2 "register_operand"))] 1374 "TARGET_P8_VECTOR" 1375{ 1376 if (BYTES_BIG_ENDIAN) 1377 emit_insn (gen_altivec_vmuleuw (operands[0], operands[1], operands[2])); 1378 else 1379 emit_insn (gen_altivec_vmulouw (operands[0], operands[1], operands[2])); 1380 DONE; 1381}) 1382 1383(define_expand "vec_widen_smult_even_v4si" 1384 [(use (match_operand:V2DI 0 "register_operand")) 1385 (use (match_operand:V4SI 1 "register_operand")) 1386 (use (match_operand:V4SI 2 "register_operand"))] 1387 "TARGET_P8_VECTOR" 1388{ 1389 if (BYTES_BIG_ENDIAN) 1390 emit_insn (gen_altivec_vmulesw (operands[0], operands[1], operands[2])); 1391 else 1392 emit_insn (gen_altivec_vmulosw (operands[0], operands[1], operands[2])); 1393 DONE; 1394}) 1395 1396(define_expand "vec_widen_umult_odd_v16qi" 1397 [(use (match_operand:V8HI 0 "register_operand")) 1398 (use (match_operand:V16QI 1 "register_operand")) 1399 (use (match_operand:V16QI 2 "register_operand"))] 1400 "TARGET_ALTIVEC" 1401{ 1402 if (BYTES_BIG_ENDIAN) 1403 emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2])); 1404 else 1405 emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2])); 1406 DONE; 1407}) 1408 1409(define_expand "vec_widen_smult_odd_v16qi" 1410 [(use (match_operand:V8HI 0 "register_operand")) 1411 (use (match_operand:V16QI 1 "register_operand")) 1412 (use (match_operand:V16QI 2 "register_operand"))] 1413 "TARGET_ALTIVEC" 1414{ 1415 if (BYTES_BIG_ENDIAN) 1416 emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2])); 1417 else 1418 emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2])); 1419 DONE; 1420}) 1421 1422(define_expand "vec_widen_umult_odd_v8hi" 1423 [(use (match_operand:V4SI 0 "register_operand")) 1424 (use (match_operand:V8HI 1 "register_operand")) 1425 (use (match_operand:V8HI 2 "register_operand"))] 1426 "TARGET_ALTIVEC" 1427{ 1428 if (BYTES_BIG_ENDIAN) 1429 emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2])); 1430 else 1431 emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2])); 1432 DONE; 1433}) 1434 1435(define_expand "vec_widen_smult_odd_v8hi" 1436 [(use (match_operand:V4SI 0 "register_operand")) 1437 (use (match_operand:V8HI 1 "register_operand")) 1438 (use (match_operand:V8HI 2 "register_operand"))] 1439 "TARGET_ALTIVEC" 1440{ 1441 if (BYTES_BIG_ENDIAN) 1442 emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2])); 1443 else 1444 emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2])); 1445 DONE; 1446}) 1447 1448(define_expand "vec_widen_umult_odd_v4si" 1449 [(use (match_operand:V2DI 0 "register_operand")) 1450 (use (match_operand:V4SI 1 "register_operand")) 1451 (use (match_operand:V4SI 2 "register_operand"))] 1452 "TARGET_P8_VECTOR" 1453{ 1454 if (BYTES_BIG_ENDIAN) 1455 emit_insn (gen_altivec_vmulouw (operands[0], operands[1], operands[2])); 1456 else 1457 emit_insn (gen_altivec_vmuleuw (operands[0], operands[1], operands[2])); 1458 DONE; 1459}) 1460 1461(define_expand "vec_widen_smult_odd_v4si" 1462 [(use (match_operand:V2DI 0 "register_operand")) 1463 (use (match_operand:V4SI 1 "register_operand")) 1464 (use (match_operand:V4SI 2 "register_operand"))] 1465 "TARGET_P8_VECTOR" 1466{ 1467 if (BYTES_BIG_ENDIAN) 1468 emit_insn (gen_altivec_vmulosw (operands[0], operands[1], operands[2])); 1469 else 1470 emit_insn (gen_altivec_vmulesw (operands[0], operands[1], operands[2])); 1471 DONE; 1472}) 1473 1474(define_insn "altivec_vmuleub" 1475 [(set (match_operand:V8HI 0 "register_operand" "=v") 1476 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 1477 (match_operand:V16QI 2 "register_operand" "v")] 1478 UNSPEC_VMULEUB))] 1479 "TARGET_ALTIVEC" 1480 "vmuleub %0,%1,%2" 1481 [(set_attr "type" "veccomplex")]) 1482 1483(define_insn "altivec_vmuloub" 1484 [(set (match_operand:V8HI 0 "register_operand" "=v") 1485 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 1486 (match_operand:V16QI 2 "register_operand" "v")] 1487 UNSPEC_VMULOUB))] 1488 "TARGET_ALTIVEC" 1489 "vmuloub %0,%1,%2" 1490 [(set_attr "type" "veccomplex")]) 1491 1492(define_insn "altivec_vmulesb" 1493 [(set (match_operand:V8HI 0 "register_operand" "=v") 1494 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 1495 (match_operand:V16QI 2 "register_operand" "v")] 1496 UNSPEC_VMULESB))] 1497 "TARGET_ALTIVEC" 1498 "vmulesb %0,%1,%2" 1499 [(set_attr "type" "veccomplex")]) 1500 1501(define_insn "altivec_vmulosb" 1502 [(set (match_operand:V8HI 0 "register_operand" "=v") 1503 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 1504 (match_operand:V16QI 2 "register_operand" "v")] 1505 UNSPEC_VMULOSB))] 1506 "TARGET_ALTIVEC" 1507 "vmulosb %0,%1,%2" 1508 [(set_attr "type" "veccomplex")]) 1509 1510(define_insn "altivec_vmuleuh" 1511 [(set (match_operand:V4SI 0 "register_operand" "=v") 1512 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 1513 (match_operand:V8HI 2 "register_operand" "v")] 1514 UNSPEC_VMULEUH))] 1515 "TARGET_ALTIVEC" 1516 "vmuleuh %0,%1,%2" 1517 [(set_attr "type" "veccomplex")]) 1518 1519(define_insn "altivec_vmulouh" 1520 [(set (match_operand:V4SI 0 "register_operand" "=v") 1521 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 1522 (match_operand:V8HI 2 "register_operand" "v")] 1523 UNSPEC_VMULOUH))] 1524 "TARGET_ALTIVEC" 1525 "vmulouh %0,%1,%2" 1526 [(set_attr "type" "veccomplex")]) 1527 1528(define_insn "altivec_vmulesh" 1529 [(set (match_operand:V4SI 0 "register_operand" "=v") 1530 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 1531 (match_operand:V8HI 2 "register_operand" "v")] 1532 UNSPEC_VMULESH))] 1533 "TARGET_ALTIVEC" 1534 "vmulesh %0,%1,%2" 1535 [(set_attr "type" "veccomplex")]) 1536 1537(define_insn "altivec_vmulosh" 1538 [(set (match_operand:V4SI 0 "register_operand" "=v") 1539 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 1540 (match_operand:V8HI 2 "register_operand" "v")] 1541 UNSPEC_VMULOSH))] 1542 "TARGET_ALTIVEC" 1543 "vmulosh %0,%1,%2" 1544 [(set_attr "type" "veccomplex")]) 1545 1546(define_insn "altivec_vmuleuw" 1547 [(set (match_operand:V2DI 0 "register_operand" "=v") 1548 (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "v") 1549 (match_operand:V4SI 2 "register_operand" "v")] 1550 UNSPEC_VMULEUW))] 1551 "TARGET_P8_VECTOR" 1552 "vmuleuw %0,%1,%2" 1553 [(set_attr "type" "veccomplex")]) 1554 1555(define_insn "altivec_vmulouw" 1556 [(set (match_operand:V2DI 0 "register_operand" "=v") 1557 (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "v") 1558 (match_operand:V4SI 2 "register_operand" "v")] 1559 UNSPEC_VMULOUW))] 1560 "TARGET_P8_VECTOR" 1561 "vmulouw %0,%1,%2" 1562 [(set_attr "type" "veccomplex")]) 1563 1564(define_insn "altivec_vmulesw" 1565 [(set (match_operand:V2DI 0 "register_operand" "=v") 1566 (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "v") 1567 (match_operand:V4SI 2 "register_operand" "v")] 1568 UNSPEC_VMULESW))] 1569 "TARGET_P8_VECTOR" 1570 "vmulesw %0,%1,%2" 1571 [(set_attr "type" "veccomplex")]) 1572 1573(define_insn "altivec_vmulosw" 1574 [(set (match_operand:V2DI 0 "register_operand" "=v") 1575 (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "v") 1576 (match_operand:V4SI 2 "register_operand" "v")] 1577 UNSPEC_VMULOSW))] 1578 "TARGET_P8_VECTOR" 1579 "vmulosw %0,%1,%2" 1580 [(set_attr "type" "veccomplex")]) 1581 1582;; Vector pack/unpack 1583(define_insn "altivec_vpkpx" 1584 [(set (match_operand:V8HI 0 "register_operand" "=v") 1585 (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") 1586 (match_operand:V4SI 2 "register_operand" "v")] 1587 UNSPEC_VPKPX))] 1588 "TARGET_ALTIVEC" 1589{ 1590 if (BYTES_BIG_ENDIAN) 1591 return "vpkpx %0,%1,%2"; 1592 else 1593 return "vpkpx %0,%2,%1"; 1594} 1595 [(set_attr "type" "vecperm")]) 1596 1597(define_insn "altivec_vpks<VI_char>ss" 1598 [(set (match_operand:<VP_small> 0 "register_operand" "=v") 1599 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") 1600 (match_operand:VP 2 "register_operand" "v")] 1601 UNSPEC_VPACK_SIGN_SIGN_SAT))] 1602 "<VI_unit>" 1603{ 1604 if (BYTES_BIG_ENDIAN) 1605 return "vpks<VI_char>ss %0,%1,%2"; 1606 else 1607 return "vpks<VI_char>ss %0,%2,%1"; 1608} 1609 [(set_attr "type" "vecperm")]) 1610 1611(define_insn "altivec_vpks<VI_char>us" 1612 [(set (match_operand:<VP_small> 0 "register_operand" "=v") 1613 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") 1614 (match_operand:VP 2 "register_operand" "v")] 1615 UNSPEC_VPACK_SIGN_UNS_SAT))] 1616 "<VI_unit>" 1617{ 1618 if (BYTES_BIG_ENDIAN) 1619 return "vpks<VI_char>us %0,%1,%2"; 1620 else 1621 return "vpks<VI_char>us %0,%2,%1"; 1622} 1623 [(set_attr "type" "vecperm")]) 1624 1625(define_insn "altivec_vpku<VI_char>us" 1626 [(set (match_operand:<VP_small> 0 "register_operand" "=v") 1627 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") 1628 (match_operand:VP 2 "register_operand" "v")] 1629 UNSPEC_VPACK_UNS_UNS_SAT))] 1630 "<VI_unit>" 1631{ 1632 if (BYTES_BIG_ENDIAN) 1633 return "vpku<VI_char>us %0,%1,%2"; 1634 else 1635 return "vpku<VI_char>us %0,%2,%1"; 1636} 1637 [(set_attr "type" "vecperm")]) 1638 1639(define_insn "altivec_vpku<VI_char>um" 1640 [(set (match_operand:<VP_small> 0 "register_operand" "=v") 1641 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") 1642 (match_operand:VP 2 "register_operand" "v")] 1643 UNSPEC_VPACK_UNS_UNS_MOD))] 1644 "<VI_unit>" 1645{ 1646 if (BYTES_BIG_ENDIAN) 1647 return "vpku<VI_char>um %0,%1,%2"; 1648 else 1649 return "vpku<VI_char>um %0,%2,%1"; 1650} 1651 [(set_attr "type" "vecperm")]) 1652 1653(define_insn "altivec_vpku<VI_char>um_direct" 1654 [(set (match_operand:<VP_small> 0 "register_operand" "=v") 1655 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") 1656 (match_operand:VP 2 "register_operand" "v")] 1657 UNSPEC_VPACK_UNS_UNS_MOD_DIRECT))] 1658 "<VI_unit>" 1659{ 1660 if (BYTES_BIG_ENDIAN) 1661 return "vpku<VI_char>um %0,%1,%2"; 1662 else 1663 return "vpku<VI_char>um %0,%2,%1"; 1664} 1665 [(set_attr "type" "vecperm")]) 1666 1667(define_insn "*altivec_vrl<VI_char>" 1668 [(set (match_operand:VI2 0 "register_operand" "=v") 1669 (rotate:VI2 (match_operand:VI2 1 "register_operand" "v") 1670 (match_operand:VI2 2 "register_operand" "v")))] 1671 "<VI_unit>" 1672 "vrl<VI_char> %0,%1,%2" 1673 [(set_attr "type" "vecsimple")]) 1674 1675(define_insn "altivec_vrl<VI_char>mi" 1676 [(set (match_operand:VIlong 0 "register_operand" "=v") 1677 (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "0") 1678 (match_operand:VIlong 2 "register_operand" "v") 1679 (match_operand:VIlong 3 "register_operand" "v")] 1680 UNSPEC_VRLMI))] 1681 "TARGET_P9_VECTOR" 1682 "vrl<VI_char>mi %0,%2,%3" 1683 [(set_attr "type" "veclogical")]) 1684 1685(define_insn "altivec_vrl<VI_char>nm" 1686 [(set (match_operand:VIlong 0 "register_operand" "=v") 1687 (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "v") 1688 (match_operand:VIlong 2 "register_operand" "v")] 1689 UNSPEC_VRLNM))] 1690 "TARGET_P9_VECTOR" 1691 "vrl<VI_char>nm %0,%1,%2" 1692 [(set_attr "type" "veclogical")]) 1693 1694(define_insn "altivec_vsl" 1695 [(set (match_operand:V4SI 0 "register_operand" "=v") 1696 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 1697 (match_operand:V4SI 2 "register_operand" "v")] 1698 UNSPEC_VSLV4SI))] 1699 "TARGET_ALTIVEC" 1700 "vsl %0,%1,%2" 1701 [(set_attr "type" "vecperm")]) 1702 1703(define_insn "altivec_vslo" 1704 [(set (match_operand:V4SI 0 "register_operand" "=v") 1705 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 1706 (match_operand:V4SI 2 "register_operand" "v")] 1707 UNSPEC_VSLO))] 1708 "TARGET_ALTIVEC" 1709 "vslo %0,%1,%2" 1710 [(set_attr "type" "vecperm")]) 1711 1712(define_insn "vslv" 1713 [(set (match_operand:V16QI 0 "register_operand" "=v") 1714 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 1715 (match_operand:V16QI 2 "register_operand" "v")] 1716 UNSPEC_VSLV))] 1717 "TARGET_P9_VECTOR" 1718 "vslv %0,%1,%2" 1719 [(set_attr "type" "vecsimple")]) 1720 1721(define_insn "vsrv" 1722 [(set (match_operand:V16QI 0 "register_operand" "=v") 1723 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 1724 (match_operand:V16QI 2 "register_operand" "v")] 1725 UNSPEC_VSRV))] 1726 "TARGET_P9_VECTOR" 1727 "vsrv %0,%1,%2" 1728 [(set_attr "type" "vecsimple")]) 1729 1730(define_insn "*altivec_vsl<VI_char>" 1731 [(set (match_operand:VI2 0 "register_operand" "=v") 1732 (ashift:VI2 (match_operand:VI2 1 "register_operand" "v") 1733 (match_operand:VI2 2 "register_operand" "v")))] 1734 "<VI_unit>" 1735 "vsl<VI_char> %0,%1,%2" 1736 [(set_attr "type" "vecsimple")]) 1737 1738(define_insn "*altivec_vsr<VI_char>" 1739 [(set (match_operand:VI2 0 "register_operand" "=v") 1740 (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v") 1741 (match_operand:VI2 2 "register_operand" "v")))] 1742 "<VI_unit>" 1743 "vsr<VI_char> %0,%1,%2" 1744 [(set_attr "type" "vecsimple")]) 1745 1746(define_insn "*altivec_vsra<VI_char>" 1747 [(set (match_operand:VI2 0 "register_operand" "=v") 1748 (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v") 1749 (match_operand:VI2 2 "register_operand" "v")))] 1750 "<VI_unit>" 1751 "vsra<VI_char> %0,%1,%2" 1752 [(set_attr "type" "vecsimple")]) 1753 1754(define_insn "altivec_vsr" 1755 [(set (match_operand:V4SI 0 "register_operand" "=v") 1756 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 1757 (match_operand:V4SI 2 "register_operand" "v")] 1758 UNSPEC_VSR))] 1759 "TARGET_ALTIVEC" 1760 "vsr %0,%1,%2" 1761 [(set_attr "type" "vecperm")]) 1762 1763(define_insn "altivec_vsro" 1764 [(set (match_operand:V4SI 0 "register_operand" "=v") 1765 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 1766 (match_operand:V4SI 2 "register_operand" "v")] 1767 UNSPEC_VSRO))] 1768 "TARGET_ALTIVEC" 1769 "vsro %0,%1,%2" 1770 [(set_attr "type" "vecperm")]) 1771 1772(define_insn "altivec_vsum4ubs" 1773 [(set (match_operand:V4SI 0 "register_operand" "=v") 1774 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") 1775 (match_operand:V4SI 2 "register_operand" "v")] 1776 UNSPEC_VSUM4UBS)) 1777 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 1778 "TARGET_ALTIVEC" 1779 "vsum4ubs %0,%1,%2" 1780 [(set_attr "type" "veccomplex")]) 1781 1782(define_insn "altivec_vsum4s<VI_char>s" 1783 [(set (match_operand:V4SI 0 "register_operand" "=v") 1784 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") 1785 (match_operand:V4SI 2 "register_operand" "v")] 1786 UNSPEC_VSUM4S)) 1787 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 1788 "TARGET_ALTIVEC" 1789 "vsum4s<VI_char>s %0,%1,%2" 1790 [(set_attr "type" "veccomplex")]) 1791 1792(define_expand "altivec_vsum2sws" 1793 [(use (match_operand:V4SI 0 "register_operand")) 1794 (use (match_operand:V4SI 1 "register_operand")) 1795 (use (match_operand:V4SI 2 "register_operand"))] 1796 "TARGET_ALTIVEC" 1797{ 1798 if (BYTES_BIG_ENDIAN) 1799 emit_insn (gen_altivec_vsum2sws_direct (operands[0], operands[1], 1800 operands[2])); 1801 else 1802 { 1803 rtx tmp1 = gen_reg_rtx (V4SImode); 1804 rtx tmp2 = gen_reg_rtx (V4SImode); 1805 emit_insn (gen_altivec_vsldoi_v4si (tmp1, operands[2], 1806 operands[2], GEN_INT (12))); 1807 emit_insn (gen_altivec_vsum2sws_direct (tmp2, operands[1], tmp1)); 1808 emit_insn (gen_altivec_vsldoi_v4si (operands[0], tmp2, tmp2, 1809 GEN_INT (4))); 1810 } 1811 DONE; 1812}) 1813 1814; FIXME: This can probably be expressed without an UNSPEC. 1815(define_insn "altivec_vsum2sws_direct" 1816 [(set (match_operand:V4SI 0 "register_operand" "=v") 1817 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 1818 (match_operand:V4SI 2 "register_operand" "v")] 1819 UNSPEC_VSUM2SWS)) 1820 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 1821 "TARGET_ALTIVEC" 1822 "vsum2sws %0,%1,%2" 1823 [(set_attr "type" "veccomplex")]) 1824 1825(define_expand "altivec_vsumsws" 1826 [(use (match_operand:V4SI 0 "register_operand")) 1827 (use (match_operand:V4SI 1 "register_operand")) 1828 (use (match_operand:V4SI 2 "register_operand"))] 1829 "TARGET_ALTIVEC" 1830{ 1831 if (BYTES_BIG_ENDIAN) 1832 emit_insn (gen_altivec_vsumsws_direct (operands[0], operands[1], 1833 operands[2])); 1834 else 1835 { 1836 rtx tmp1 = gen_reg_rtx (V4SImode); 1837 rtx tmp2 = gen_reg_rtx (V4SImode); 1838 emit_insn (gen_altivec_vspltw_direct (tmp1, operands[2], const0_rtx)); 1839 emit_insn (gen_altivec_vsumsws_direct (tmp2, operands[1], tmp1)); 1840 emit_insn (gen_altivec_vsldoi_v4si (operands[0], tmp2, tmp2, 1841 GEN_INT (12))); 1842 } 1843 DONE; 1844}) 1845 1846; FIXME: This can probably be expressed without an UNSPEC. 1847(define_insn "altivec_vsumsws_direct" 1848 [(set (match_operand:V4SI 0 "register_operand" "=v") 1849 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 1850 (match_operand:V4SI 2 "register_operand" "v")] 1851 UNSPEC_VSUMSWS_DIRECT)) 1852 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 1853 "TARGET_ALTIVEC" 1854 "vsumsws %0,%1,%2" 1855 [(set_attr "type" "veccomplex")]) 1856 1857(define_expand "altivec_vspltb" 1858 [(use (match_operand:V16QI 0 "register_operand")) 1859 (use (match_operand:V16QI 1 "register_operand")) 1860 (use (match_operand:QI 2 "const_0_to_15_operand"))] 1861 "TARGET_ALTIVEC" 1862{ 1863 rtvec v = gen_rtvec (1, operands[2]); 1864 rtx x; 1865 x = gen_rtx_VEC_SELECT (QImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); 1866 x = gen_rtx_VEC_DUPLICATE (V16QImode, x); 1867 emit_insn (gen_rtx_SET (operands[0], x)); 1868 DONE; 1869}) 1870 1871(define_insn "*altivec_vspltb_internal" 1872 [(set (match_operand:V16QI 0 "register_operand" "=v") 1873 (vec_duplicate:V16QI 1874 (vec_select:QI (match_operand:V16QI 1 "register_operand" "v") 1875 (parallel 1876 [(match_operand:QI 2 "const_0_to_15_operand" "")]))))] 1877 "TARGET_ALTIVEC" 1878{ 1879 if (!BYTES_BIG_ENDIAN) 1880 operands[2] = GEN_INT (15 - INTVAL (operands[2])); 1881 1882 return "vspltb %0,%1,%2"; 1883} 1884 [(set_attr "type" "vecperm")]) 1885 1886(define_insn "altivec_vspltb_direct" 1887 [(set (match_operand:V16QI 0 "register_operand" "=v") 1888 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 1889 (match_operand:QI 2 "const_0_to_15_operand" "i")] 1890 UNSPEC_VSPLT_DIRECT))] 1891 "TARGET_ALTIVEC" 1892 "vspltb %0,%1,%2" 1893 [(set_attr "type" "vecperm")]) 1894 1895(define_expand "altivec_vsplth" 1896 [(use (match_operand:V8HI 0 "register_operand")) 1897 (use (match_operand:V8HI 1 "register_operand")) 1898 (use (match_operand:QI 2 "const_0_to_7_operand"))] 1899 "TARGET_ALTIVEC" 1900{ 1901 rtvec v = gen_rtvec (1, operands[2]); 1902 rtx x; 1903 x = gen_rtx_VEC_SELECT (HImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); 1904 x = gen_rtx_VEC_DUPLICATE (V8HImode, x); 1905 emit_insn (gen_rtx_SET (operands[0], x)); 1906 DONE; 1907}) 1908 1909(define_insn "*altivec_vsplth_internal" 1910 [(set (match_operand:V8HI 0 "register_operand" "=v") 1911 (vec_duplicate:V8HI 1912 (vec_select:HI (match_operand:V8HI 1 "register_operand" "v") 1913 (parallel 1914 [(match_operand:QI 2 "const_0_to_7_operand" "")]))))] 1915 "TARGET_ALTIVEC" 1916{ 1917 if (!BYTES_BIG_ENDIAN) 1918 operands[2] = GEN_INT (7 - INTVAL (operands[2])); 1919 1920 return "vsplth %0,%1,%2"; 1921} 1922 [(set_attr "type" "vecperm")]) 1923 1924(define_insn "altivec_vsplth_direct" 1925 [(set (match_operand:V8HI 0 "register_operand" "=v") 1926 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") 1927 (match_operand:QI 2 "const_0_to_7_operand" "i")] 1928 UNSPEC_VSPLT_DIRECT))] 1929 "TARGET_ALTIVEC" 1930 "vsplth %0,%1,%2" 1931 [(set_attr "type" "vecperm")]) 1932 1933(define_expand "altivec_vspltw" 1934 [(use (match_operand:V4SI 0 "register_operand")) 1935 (use (match_operand:V4SI 1 "register_operand")) 1936 (use (match_operand:QI 2 "const_0_to_3_operand"))] 1937 "TARGET_ALTIVEC" 1938{ 1939 rtvec v = gen_rtvec (1, operands[2]); 1940 rtx x; 1941 x = gen_rtx_VEC_SELECT (SImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); 1942 x = gen_rtx_VEC_DUPLICATE (V4SImode, x); 1943 emit_insn (gen_rtx_SET (operands[0], x)); 1944 DONE; 1945}) 1946 1947(define_insn "*altivec_vspltw_internal" 1948 [(set (match_operand:V4SI 0 "register_operand" "=v") 1949 (vec_duplicate:V4SI 1950 (vec_select:SI (match_operand:V4SI 1 "register_operand" "v") 1951 (parallel 1952 [(match_operand:QI 2 "const_0_to_3_operand" "i")]))))] 1953 "TARGET_ALTIVEC" 1954{ 1955 if (!BYTES_BIG_ENDIAN) 1956 operands[2] = GEN_INT (3 - INTVAL (operands[2])); 1957 1958 return "vspltw %0,%1,%2"; 1959} 1960 [(set_attr "type" "vecperm")]) 1961 1962(define_insn "altivec_vspltw_direct" 1963 [(set (match_operand:V4SI 0 "register_operand" "=v") 1964 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") 1965 (match_operand:QI 2 "const_0_to_3_operand" "i")] 1966 UNSPEC_VSPLT_DIRECT))] 1967 "TARGET_ALTIVEC" 1968 "vspltw %0,%1,%2" 1969 [(set_attr "type" "vecperm")]) 1970 1971(define_expand "altivec_vspltsf" 1972 [(use (match_operand:V4SF 0 "register_operand")) 1973 (use (match_operand:V4SF 1 "register_operand")) 1974 (use (match_operand:QI 2 "const_0_to_3_operand"))] 1975 "TARGET_ALTIVEC" 1976{ 1977 rtvec v = gen_rtvec (1, operands[2]); 1978 rtx x; 1979 x = gen_rtx_VEC_SELECT (SFmode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); 1980 x = gen_rtx_VEC_DUPLICATE (V4SFmode, x); 1981 emit_insn (gen_rtx_SET (operands[0], x)); 1982 DONE; 1983}) 1984 1985(define_insn "*altivec_vspltsf_internal" 1986 [(set (match_operand:V4SF 0 "register_operand" "=v") 1987 (vec_duplicate:V4SF 1988 (vec_select:SF (match_operand:V4SF 1 "register_operand" "v") 1989 (parallel 1990 [(match_operand:QI 2 "const_0_to_3_operand" "i")]))))] 1991 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 1992{ 1993 if (!BYTES_BIG_ENDIAN) 1994 operands[2] = GEN_INT (3 - INTVAL (operands[2])); 1995 1996 return "vspltw %0,%1,%2"; 1997} 1998 [(set_attr "type" "vecperm")]) 1999 2000(define_insn "altivec_vspltis<VI_char>" 2001 [(set (match_operand:VI 0 "register_operand" "=v") 2002 (vec_duplicate:VI 2003 (match_operand:QI 1 "s5bit_cint_operand" "i")))] 2004 "TARGET_ALTIVEC" 2005 "vspltis<VI_char> %0,%1" 2006 [(set_attr "type" "vecperm")]) 2007 2008(define_insn "*altivec_vrfiz" 2009 [(set (match_operand:V4SF 0 "register_operand" "=v") 2010 (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))] 2011 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2012 "vrfiz %0,%1" 2013 [(set_attr "type" "vecfloat")]) 2014 2015(define_expand "altivec_vperm_<mode>" 2016 [(set (match_operand:VM 0 "register_operand") 2017 (unspec:VM [(match_operand:VM 1 "register_operand") 2018 (match_operand:VM 2 "register_operand") 2019 (match_operand:V16QI 3 "register_operand")] 2020 UNSPEC_VPERM))] 2021 "TARGET_ALTIVEC" 2022{ 2023 if (!BYTES_BIG_ENDIAN) 2024 { 2025 altivec_expand_vec_perm_le (operands); 2026 DONE; 2027 } 2028}) 2029 2030;; Slightly prefer vperm, since the target does not overlap the source 2031(define_insn "altivec_vperm_<mode>_direct" 2032 [(set (match_operand:VM 0 "register_operand" "=v,?wa") 2033 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wa") 2034 (match_operand:VM 2 "register_operand" "v,0") 2035 (match_operand:V16QI 3 "register_operand" "v,wa")] 2036 UNSPEC_VPERM))] 2037 "TARGET_ALTIVEC" 2038 "@ 2039 vperm %0,%1,%2,%3 2040 xxperm %x0,%x1,%x3" 2041 [(set_attr "type" "vecperm") 2042 (set_attr "isa" "*,p9v")]) 2043 2044(define_insn "altivec_vperm_v8hiv16qi" 2045 [(set (match_operand:V16QI 0 "register_operand" "=v,?wa") 2046 (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,wa") 2047 (match_operand:V8HI 2 "register_operand" "v,0") 2048 (match_operand:V16QI 3 "register_operand" "v,wa")] 2049 UNSPEC_VPERM))] 2050 "TARGET_ALTIVEC" 2051 "@ 2052 vperm %0,%1,%2,%3 2053 xxperm %x0,%x1,%x3" 2054 [(set_attr "type" "vecperm") 2055 (set_attr "isa" "*,p9v")]) 2056 2057(define_expand "altivec_vperm_<mode>_uns" 2058 [(set (match_operand:VM 0 "register_operand") 2059 (unspec:VM [(match_operand:VM 1 "register_operand") 2060 (match_operand:VM 2 "register_operand") 2061 (match_operand:V16QI 3 "register_operand")] 2062 UNSPEC_VPERM_UNS))] 2063 "TARGET_ALTIVEC" 2064{ 2065 if (!BYTES_BIG_ENDIAN) 2066 { 2067 altivec_expand_vec_perm_le (operands); 2068 DONE; 2069 } 2070}) 2071 2072(define_insn "*altivec_vperm_<mode>_uns_internal" 2073 [(set (match_operand:VM 0 "register_operand" "=v,?wa") 2074 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wa") 2075 (match_operand:VM 2 "register_operand" "v,0") 2076 (match_operand:V16QI 3 "register_operand" "v,wa")] 2077 UNSPEC_VPERM_UNS))] 2078 "TARGET_ALTIVEC" 2079 "@ 2080 vperm %0,%1,%2,%3 2081 xxperm %x0,%x1,%x3" 2082 [(set_attr "type" "vecperm") 2083 (set_attr "isa" "*,p9v")]) 2084 2085(define_expand "vec_permv16qi" 2086 [(set (match_operand:V16QI 0 "register_operand") 2087 (unspec:V16QI [(match_operand:V16QI 1 "register_operand") 2088 (match_operand:V16QI 2 "register_operand") 2089 (match_operand:V16QI 3 "register_operand")] 2090 UNSPEC_VPERM))] 2091 "TARGET_ALTIVEC" 2092{ 2093 if (!BYTES_BIG_ENDIAN) { 2094 altivec_expand_vec_perm_le (operands); 2095 DONE; 2096 } 2097}) 2098 2099(define_insn "*altivec_vpermr_<mode>_internal" 2100 [(set (match_operand:VM 0 "register_operand" "=v,?wa") 2101 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wa") 2102 (match_operand:VM 2 "register_operand" "v,0") 2103 (match_operand:V16QI 3 "register_operand" "v,wa")] 2104 UNSPEC_VPERMR))] 2105 "TARGET_P9_VECTOR" 2106 "@ 2107 vpermr %0,%1,%2,%3 2108 xxpermr %x0,%x1,%x3" 2109 [(set_attr "type" "vecperm") 2110 (set_attr "isa" "*,p9v")]) 2111 2112(define_insn "altivec_vrfip" ; ceil 2113 [(set (match_operand:V4SF 0 "register_operand" "=v") 2114 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2115 UNSPEC_FRIP))] 2116 "TARGET_ALTIVEC" 2117 "vrfip %0,%1" 2118 [(set_attr "type" "vecfloat")]) 2119 2120(define_insn "altivec_vrfin" 2121 [(set (match_operand:V4SF 0 "register_operand" "=v") 2122 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2123 UNSPEC_VRFIN))] 2124 "TARGET_ALTIVEC" 2125 "vrfin %0,%1" 2126 [(set_attr "type" "vecfloat")]) 2127 2128(define_insn "*altivec_vrfim" ; floor 2129 [(set (match_operand:V4SF 0 "register_operand" "=v") 2130 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2131 UNSPEC_FRIM))] 2132 "TARGET_ALTIVEC" 2133 "vrfim %0,%1" 2134 [(set_attr "type" "vecfloat")]) 2135 2136(define_insn "altivec_vcfux" 2137 [(set (match_operand:V4SF 0 "register_operand" "=v") 2138 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") 2139 (match_operand:QI 2 "immediate_operand" "i")] 2140 UNSPEC_VCFUX))] 2141 "TARGET_ALTIVEC" 2142 "vcfux %0,%1,%2" 2143 [(set_attr "type" "vecfloat")]) 2144 2145(define_insn "altivec_vcfsx" 2146 [(set (match_operand:V4SF 0 "register_operand" "=v") 2147 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") 2148 (match_operand:QI 2 "immediate_operand" "i")] 2149 UNSPEC_VCFSX))] 2150 "TARGET_ALTIVEC" 2151 "vcfsx %0,%1,%2" 2152 [(set_attr "type" "vecfloat")]) 2153 2154(define_insn "altivec_vctuxs" 2155 [(set (match_operand:V4SI 0 "register_operand" "=v") 2156 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") 2157 (match_operand:QI 2 "immediate_operand" "i")] 2158 UNSPEC_VCTUXS)) 2159 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 2160 "TARGET_ALTIVEC" 2161 "vctuxs %0,%1,%2" 2162 [(set_attr "type" "vecfloat")]) 2163 2164(define_insn "altivec_vctsxs" 2165 [(set (match_operand:V4SI 0 "register_operand" "=v") 2166 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") 2167 (match_operand:QI 2 "immediate_operand" "i")] 2168 UNSPEC_VCTSXS)) 2169 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 2170 "TARGET_ALTIVEC" 2171 "vctsxs %0,%1,%2" 2172 [(set_attr "type" "vecfloat")]) 2173 2174(define_insn "altivec_vlogefp" 2175 [(set (match_operand:V4SF 0 "register_operand" "=v") 2176 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2177 UNSPEC_VLOGEFP))] 2178 "TARGET_ALTIVEC" 2179 "vlogefp %0,%1" 2180 [(set_attr "type" "vecfloat")]) 2181 2182(define_insn "altivec_vexptefp" 2183 [(set (match_operand:V4SF 0 "register_operand" "=v") 2184 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2185 UNSPEC_VEXPTEFP))] 2186 "TARGET_ALTIVEC" 2187 "vexptefp %0,%1" 2188 [(set_attr "type" "vecfloat")]) 2189 2190(define_insn "*altivec_vrsqrtefp" 2191 [(set (match_operand:V4SF 0 "register_operand" "=v") 2192 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2193 UNSPEC_RSQRT))] 2194 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2195 "vrsqrtefp %0,%1" 2196 [(set_attr "type" "vecfloat")]) 2197 2198(define_insn "altivec_vrefp" 2199 [(set (match_operand:V4SF 0 "register_operand" "=v") 2200 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2201 UNSPEC_FRES))] 2202 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2203 "vrefp %0,%1" 2204 [(set_attr "type" "vecfloat")]) 2205 2206(define_expand "altivec_copysign_v4sf3" 2207 [(use (match_operand:V4SF 0 "register_operand")) 2208 (use (match_operand:V4SF 1 "register_operand")) 2209 (use (match_operand:V4SF 2 "register_operand"))] 2210 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2211{ 2212 rtx mask = gen_reg_rtx (V4SImode); 2213 rtx mask_val = gen_int_mode (HOST_WIDE_INT_1U << 31, SImode); 2214 rtvec v = gen_rtvec (4, mask_val, mask_val, mask_val, mask_val); 2215 2216 emit_insn (gen_vec_initv4sisi (mask, gen_rtx_PARALLEL (V4SImode, v))); 2217 emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2], 2218 gen_lowpart (V4SFmode, mask))); 2219 DONE; 2220}) 2221 2222(define_insn "altivec_vsldoi_<mode>" 2223 [(set (match_operand:VM 0 "register_operand" "=v") 2224 (unspec:VM [(match_operand:VM 1 "register_operand" "v") 2225 (match_operand:VM 2 "register_operand" "v") 2226 (match_operand:QI 3 "immediate_operand" "i")] 2227 UNSPEC_VSLDOI))] 2228 "TARGET_ALTIVEC" 2229 "vsldoi %0,%1,%2,%3" 2230 [(set_attr "type" "vecperm")]) 2231 2232(define_insn "altivec_vupkhs<VU_char>" 2233 [(set (match_operand:VP 0 "register_operand" "=v") 2234 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 2235 UNSPEC_VUNPACK_HI_SIGN))] 2236 "<VI_unit>" 2237{ 2238 if (BYTES_BIG_ENDIAN) 2239 return "vupkhs<VU_char> %0,%1"; 2240 else 2241 return "vupkls<VU_char> %0,%1"; 2242} 2243 [(set_attr "type" "vecperm")]) 2244 2245(define_insn "*altivec_vupkhs<VU_char>_direct" 2246 [(set (match_operand:VP 0 "register_operand" "=v") 2247 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 2248 UNSPEC_VUNPACK_HI_SIGN_DIRECT))] 2249 "<VI_unit>" 2250 "vupkhs<VU_char> %0,%1" 2251 [(set_attr "type" "vecperm")]) 2252 2253(define_insn "altivec_vupkls<VU_char>" 2254 [(set (match_operand:VP 0 "register_operand" "=v") 2255 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 2256 UNSPEC_VUNPACK_LO_SIGN))] 2257 "<VI_unit>" 2258{ 2259 if (BYTES_BIG_ENDIAN) 2260 return "vupkls<VU_char> %0,%1"; 2261 else 2262 return "vupkhs<VU_char> %0,%1"; 2263} 2264 [(set_attr "type" "vecperm")]) 2265 2266(define_insn "*altivec_vupkls<VU_char>_direct" 2267 [(set (match_operand:VP 0 "register_operand" "=v") 2268 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 2269 UNSPEC_VUNPACK_LO_SIGN_DIRECT))] 2270 "<VI_unit>" 2271 "vupkls<VU_char> %0,%1" 2272 [(set_attr "type" "vecperm")]) 2273 2274(define_insn "altivec_vupkhpx" 2275 [(set (match_operand:V4SI 0 "register_operand" "=v") 2276 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 2277 UNSPEC_VUPKHPX))] 2278 "TARGET_ALTIVEC" 2279{ 2280 if (BYTES_BIG_ENDIAN) 2281 return "vupkhpx %0,%1"; 2282 else 2283 return "vupklpx %0,%1"; 2284} 2285 [(set_attr "type" "vecperm")]) 2286 2287(define_insn "altivec_vupklpx" 2288 [(set (match_operand:V4SI 0 "register_operand" "=v") 2289 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 2290 UNSPEC_VUPKLPX))] 2291 "TARGET_ALTIVEC" 2292{ 2293 if (BYTES_BIG_ENDIAN) 2294 return "vupklpx %0,%1"; 2295 else 2296 return "vupkhpx %0,%1"; 2297} 2298 [(set_attr "type" "vecperm")]) 2299 2300;; Compare vectors producing a vector result and a predicate, setting CR6 to 2301;; indicate a combined status 2302(define_insn "altivec_vcmpequ<VI_char>_p" 2303 [(set (reg:CC CR6_REGNO) 2304 (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v") 2305 (match_operand:VI2 2 "register_operand" "v"))] 2306 UNSPEC_PREDICATE)) 2307 (set (match_operand:VI2 0 "register_operand" "=v") 2308 (eq:VI2 (match_dup 1) 2309 (match_dup 2)))] 2310 "<VI_unit>" 2311 "vcmpequ<VI_char>. %0,%1,%2" 2312 [(set_attr "type" "veccmpfx")]) 2313 2314(define_insn "*altivec_vcmpgts<VI_char>_p" 2315 [(set (reg:CC CR6_REGNO) 2316 (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v") 2317 (match_operand:VI2 2 "register_operand" "v"))] 2318 UNSPEC_PREDICATE)) 2319 (set (match_operand:VI2 0 "register_operand" "=v") 2320 (gt:VI2 (match_dup 1) 2321 (match_dup 2)))] 2322 "<VI_unit>" 2323 "vcmpgts<VI_char>. %0,%1,%2" 2324 [(set_attr "type" "veccmpfx")]) 2325 2326(define_insn "*altivec_vcmpgtu<VI_char>_p" 2327 [(set (reg:CC CR6_REGNO) 2328 (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v") 2329 (match_operand:VI2 2 "register_operand" "v"))] 2330 UNSPEC_PREDICATE)) 2331 (set (match_operand:VI2 0 "register_operand" "=v") 2332 (gtu:VI2 (match_dup 1) 2333 (match_dup 2)))] 2334 "<VI_unit>" 2335 "vcmpgtu<VI_char>. %0,%1,%2" 2336 [(set_attr "type" "veccmpfx")]) 2337 2338(define_insn "*altivec_vcmpeqfp_p" 2339 [(set (reg:CC CR6_REGNO) 2340 (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v") 2341 (match_operand:V4SF 2 "register_operand" "v"))] 2342 UNSPEC_PREDICATE)) 2343 (set (match_operand:V4SF 0 "register_operand" "=v") 2344 (eq:V4SF (match_dup 1) 2345 (match_dup 2)))] 2346 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2347 "vcmpeqfp. %0,%1,%2" 2348 [(set_attr "type" "veccmp")]) 2349 2350(define_insn "*altivec_vcmpgtfp_p" 2351 [(set (reg:CC CR6_REGNO) 2352 (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v") 2353 (match_operand:V4SF 2 "register_operand" "v"))] 2354 UNSPEC_PREDICATE)) 2355 (set (match_operand:V4SF 0 "register_operand" "=v") 2356 (gt:V4SF (match_dup 1) 2357 (match_dup 2)))] 2358 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2359 "vcmpgtfp. %0,%1,%2" 2360 [(set_attr "type" "veccmp")]) 2361 2362(define_insn "*altivec_vcmpgefp_p" 2363 [(set (reg:CC CR6_REGNO) 2364 (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v") 2365 (match_operand:V4SF 2 "register_operand" "v"))] 2366 UNSPEC_PREDICATE)) 2367 (set (match_operand:V4SF 0 "register_operand" "=v") 2368 (ge:V4SF (match_dup 1) 2369 (match_dup 2)))] 2370 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2371 "vcmpgefp. %0,%1,%2" 2372 [(set_attr "type" "veccmp")]) 2373 2374(define_insn "altivec_vcmpbfp_p" 2375 [(set (reg:CC CR6_REGNO) 2376 (unspec:CC [(match_operand:V4SF 1 "register_operand" "v") 2377 (match_operand:V4SF 2 "register_operand" "v")] 2378 UNSPEC_VCMPBFP)) 2379 (set (match_operand:V4SF 0 "register_operand" "=v") 2380 (unspec:V4SF [(match_dup 1) 2381 (match_dup 2)] 2382 UNSPEC_VCMPBFP))] 2383 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" 2384 "vcmpbfp. %0,%1,%2" 2385 [(set_attr "type" "veccmp")]) 2386 2387(define_insn "altivec_mtvscr" 2388 [(set (reg:SI VSCR_REGNO) 2389 (unspec_volatile:SI 2390 [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))] 2391 "TARGET_ALTIVEC" 2392 "mtvscr %0" 2393 [(set_attr "type" "vecsimple")]) 2394 2395(define_insn "altivec_mfvscr" 2396 [(set (match_operand:V8HI 0 "register_operand" "=v") 2397 (unspec_volatile:V8HI [(reg:SI VSCR_REGNO)] UNSPECV_MFVSCR))] 2398 "TARGET_ALTIVEC" 2399 "mfvscr %0" 2400 [(set_attr "type" "vecsimple")]) 2401 2402(define_insn "altivec_dssall" 2403 [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)] 2404 "TARGET_ALTIVEC" 2405 "dssall" 2406 [(set_attr "type" "vecsimple")]) 2407 2408(define_insn "altivec_dss" 2409 [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")] 2410 UNSPECV_DSS)] 2411 "TARGET_ALTIVEC" 2412 "dss %0" 2413 [(set_attr "type" "vecsimple")]) 2414 2415(define_insn "altivec_dst" 2416 [(unspec [(match_operand 0 "register_operand" "b") 2417 (match_operand:SI 1 "register_operand" "r") 2418 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)] 2419 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" 2420 "dst %0,%1,%2" 2421 [(set_attr "type" "vecsimple")]) 2422 2423(define_insn "altivec_dstt" 2424 [(unspec [(match_operand 0 "register_operand" "b") 2425 (match_operand:SI 1 "register_operand" "r") 2426 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)] 2427 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" 2428 "dstt %0,%1,%2" 2429 [(set_attr "type" "vecsimple")]) 2430 2431(define_insn "altivec_dstst" 2432 [(unspec [(match_operand 0 "register_operand" "b") 2433 (match_operand:SI 1 "register_operand" "r") 2434 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)] 2435 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" 2436 "dstst %0,%1,%2" 2437 [(set_attr "type" "vecsimple")]) 2438 2439(define_insn "altivec_dststt" 2440 [(unspec [(match_operand 0 "register_operand" "b") 2441 (match_operand:SI 1 "register_operand" "r") 2442 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)] 2443 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" 2444 "dststt %0,%1,%2" 2445 [(set_attr "type" "vecsimple")]) 2446 2447(define_expand "altivec_lvsl" 2448 [(use (match_operand:V16QI 0 "register_operand")) 2449 (use (match_operand:V16QI 1 "memory_operand"))] 2450 "TARGET_ALTIVEC" 2451{ 2452 if (BYTES_BIG_ENDIAN) 2453 emit_insn (gen_altivec_lvsl_direct (operands[0], operands[1])); 2454 else 2455 { 2456 rtx mask, constv, vperm; 2457 mask = gen_reg_rtx (V16QImode); 2458 emit_insn (gen_altivec_lvsl_direct (mask, operands[1])); 2459 constv = gen_const_vec_series (V16QImode, const0_rtx, const1_rtx); 2460 constv = force_reg (V16QImode, constv); 2461 vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv), 2462 UNSPEC_VPERM); 2463 emit_insn (gen_rtx_SET (operands[0], vperm)); 2464 } 2465 DONE; 2466}) 2467 2468(define_insn "altivec_lvsl_reg" 2469 [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") 2470 (unspec:V16QI 2471 [(match_operand:DI 1 "gpc_reg_operand" "b")] 2472 UNSPEC_LVSL_REG))] 2473 "TARGET_ALTIVEC" 2474 "lvsl %0,0,%1" 2475 [(set_attr "type" "vecload")]) 2476 2477(define_insn "altivec_lvsl_direct" 2478 [(set (match_operand:V16QI 0 "register_operand" "=v") 2479 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] 2480 UNSPEC_LVSL))] 2481 "TARGET_ALTIVEC" 2482 "lvsl %0,%y1" 2483 [(set_attr "type" "vecload")]) 2484 2485(define_expand "altivec_lvsr" 2486 [(use (match_operand:V16QI 0 "altivec_register_operand")) 2487 (use (match_operand:V16QI 1 "memory_operand"))] 2488 "TARGET_ALTIVEC" 2489{ 2490 if (BYTES_BIG_ENDIAN) 2491 emit_insn (gen_altivec_lvsr_direct (operands[0], operands[1])); 2492 else 2493 { 2494 rtx mask, constv, vperm; 2495 mask = gen_reg_rtx (V16QImode); 2496 emit_insn (gen_altivec_lvsr_direct (mask, operands[1])); 2497 constv = gen_const_vec_series (V16QImode, const0_rtx, const1_rtx); 2498 constv = force_reg (V16QImode, constv); 2499 vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv), 2500 UNSPEC_VPERM); 2501 emit_insn (gen_rtx_SET (operands[0], vperm)); 2502 } 2503 DONE; 2504}) 2505 2506(define_insn "altivec_lvsr_reg" 2507 [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") 2508 (unspec:V16QI 2509 [(match_operand:DI 1 "gpc_reg_operand" "b")] 2510 UNSPEC_LVSR_REG))] 2511 "TARGET_ALTIVEC" 2512 "lvsr %0,0,%1" 2513 [(set_attr "type" "vecload")]) 2514 2515(define_insn "altivec_lvsr_direct" 2516 [(set (match_operand:V16QI 0 "register_operand" "=v") 2517 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] 2518 UNSPEC_LVSR))] 2519 "TARGET_ALTIVEC" 2520 "lvsr %0,%y1" 2521 [(set_attr "type" "vecload")]) 2522 2523(define_expand "build_vector_mask_for_load" 2524 [(set (match_operand:V16QI 0 "register_operand") 2525 (unspec:V16QI [(match_operand 1 "memory_operand")] UNSPEC_LVSR))] 2526 "TARGET_ALTIVEC" 2527{ 2528 rtx addr; 2529 rtx temp; 2530 2531 gcc_assert (MEM_P (operands[1])); 2532 2533 addr = XEXP (operands[1], 0); 2534 temp = gen_reg_rtx (GET_MODE (addr)); 2535 emit_insn (gen_rtx_SET (temp, gen_rtx_NEG (GET_MODE (addr), addr))); 2536 emit_insn (gen_altivec_lvsr (operands[0], 2537 replace_equiv_address (operands[1], temp))); 2538 DONE; 2539}) 2540 2541;; Parallel some of the LVE* and STV*'s with unspecs because some have 2542;; identical rtl but different instructions-- and gcc gets confused. 2543 2544(define_insn "altivec_lve<VI_char>x" 2545 [(parallel 2546 [(set (match_operand:VI 0 "register_operand" "=v") 2547 (match_operand:VI 1 "memory_operand" "Z")) 2548 (unspec [(const_int 0)] UNSPEC_LVE)])] 2549 "TARGET_ALTIVEC" 2550 "lve<VI_char>x %0,%y1" 2551 [(set_attr "type" "vecload")]) 2552 2553(define_insn "*altivec_lvesfx" 2554 [(parallel 2555 [(set (match_operand:V4SF 0 "register_operand" "=v") 2556 (match_operand:V4SF 1 "memory_operand" "Z")) 2557 (unspec [(const_int 0)] UNSPEC_LVE)])] 2558 "TARGET_ALTIVEC" 2559 "lvewx %0,%y1" 2560 [(set_attr "type" "vecload")]) 2561 2562(define_insn "altivec_lvxl_<mode>" 2563 [(parallel 2564 [(set (match_operand:VM2 0 "register_operand" "=v") 2565 (match_operand:VM2 1 "memory_operand" "Z")) 2566 (unspec [(const_int 0)] UNSPEC_SET_VSCR)])] 2567 "TARGET_ALTIVEC" 2568 "lvxl %0,%y1" 2569 [(set_attr "type" "vecload")]) 2570 2571; This version of lvx is used only in cases where we need to force an lvx 2572; over any other load, and we don't care about losing CSE opportunities. 2573; Its primary use is for prologue register saves. 2574(define_insn "altivec_lvx_<mode>_internal" 2575 [(parallel 2576 [(set (match_operand:VM2 0 "register_operand" "=v") 2577 (match_operand:VM2 1 "memory_operand" "Z")) 2578 (unspec [(const_int 0)] UNSPEC_LVX)])] 2579 "TARGET_ALTIVEC" 2580 "lvx %0,%y1" 2581 [(set_attr "type" "vecload")]) 2582 2583; The following patterns embody what lvx should usually look like. 2584(define_expand "altivec_lvx_<VM2:mode>" 2585 [(set (match_operand:VM2 0 "register_operand") 2586 (match_operand:VM2 1 "altivec_indexed_or_indirect_operand"))] 2587 "TARGET_ALTIVEC" 2588{ 2589 rtx addr = XEXP (operand1, 0); 2590 if (rs6000_sum_of_two_registers_p (addr)) 2591 { 2592 rtx op1 = XEXP (addr, 0); 2593 rtx op2 = XEXP (addr, 1); 2594 if (TARGET_64BIT) 2595 emit_insn (gen_altivec_lvx_<VM2:mode>_2op_di (operand0, op1, op2)); 2596 else 2597 emit_insn (gen_altivec_lvx_<VM2:mode>_2op_si (operand0, op1, op2)); 2598 } 2599 else 2600 { 2601 if (TARGET_64BIT) 2602 emit_insn (gen_altivec_lvx_<VM2:mode>_1op_di (operand0, addr)); 2603 else 2604 emit_insn (gen_altivec_lvx_<VM2:mode>_1op_si (operand0, addr)); 2605 } 2606 DONE; 2607}) 2608 2609; The next two patterns embody what lvx should usually look like. 2610(define_insn "altivec_lvx_<VM2:mode>_2op_<P:mptrsize>" 2611 [(set (match_operand:VM2 0 "register_operand" "=v") 2612 (mem:VM2 (and:P (plus:P (match_operand:P 1 "register_operand" "b") 2613 (match_operand:P 2 "register_operand" "r")) 2614 (const_int -16))))] 2615 "TARGET_ALTIVEC" 2616 "lvx %0,%1,%2" 2617 [(set_attr "type" "vecload")]) 2618 2619(define_insn "altivec_lvx_<VM2:mode>_1op_<P:mptrsize>" 2620 [(set (match_operand:VM2 0 "register_operand" "=v") 2621 (mem:VM2 (and:P (match_operand:P 1 "register_operand" "r") 2622 (const_int -16))))] 2623 "TARGET_ALTIVEC" 2624 "lvx %0,0,%1" 2625 [(set_attr "type" "vecload")]) 2626 2627; This version of stvx is used only in cases where we need to force an stvx 2628; over any other store, and we don't care about losing CSE opportunities. 2629; Its primary use is for epilogue register restores. 2630(define_insn "altivec_stvx_<mode>_internal" 2631 [(parallel 2632 [(set (match_operand:VM2 0 "memory_operand" "=Z") 2633 (match_operand:VM2 1 "register_operand" "v")) 2634 (unspec [(const_int 0)] UNSPEC_STVX)])] 2635 "TARGET_ALTIVEC" 2636 "stvx %1,%y0" 2637 [(set_attr "type" "vecstore")]) 2638 2639; The following patterns embody what stvx should usually look like. 2640(define_expand "altivec_stvx_<VM2:mode>" 2641 [(set (match_operand:VM2 1 "altivec_indexed_or_indirect_operand") 2642 (match_operand:VM2 0 "register_operand"))] 2643 "TARGET_ALTIVEC" 2644{ 2645 rtx addr = XEXP (operand1, 0); 2646 if (rs6000_sum_of_two_registers_p (addr)) 2647 { 2648 rtx op1 = XEXP (addr, 0); 2649 rtx op2 = XEXP (addr, 1); 2650 if (TARGET_64BIT) 2651 emit_insn (gen_altivec_stvx_<VM2:mode>_2op_di (operand0, op1, op2)); 2652 else 2653 emit_insn (gen_altivec_stvx_<VM2:mode>_2op_si (operand0, op1, op2)); 2654 } 2655 else 2656 { 2657 if (TARGET_64BIT) 2658 emit_insn (gen_altivec_stvx_<VM2:mode>_1op_di (operand0, addr)); 2659 else 2660 emit_insn (gen_altivec_stvx_<VM2:mode>_1op_si (operand0, addr)); 2661 } 2662 DONE; 2663}) 2664 2665; The next two patterns embody what stvx should usually look like. 2666(define_insn "altivec_stvx_<VM2:mode>_2op_<P:mptrsize>" 2667 [(set (mem:VM2 (and:P (plus:P (match_operand:P 1 "register_operand" "b") 2668 (match_operand:P 2 "register_operand" "r")) 2669 (const_int -16))) 2670 (match_operand:VM2 0 "register_operand" "v"))] 2671 "TARGET_ALTIVEC" 2672 "stvx %0,%1,%2" 2673 [(set_attr "type" "vecstore")]) 2674 2675(define_insn "altivec_stvx_<VM2:mode>_1op_<P:mptrsize>" 2676 [(set (mem:VM2 (and:P (match_operand:P 1 "register_operand" "r") 2677 (const_int -16))) 2678 (match_operand:VM2 0 "register_operand" "v"))] 2679 "TARGET_ALTIVEC" 2680 "stvx %0,0,%1" 2681 [(set_attr "type" "vecstore")]) 2682 2683(define_insn "altivec_stvxl_<mode>" 2684 [(parallel 2685 [(set (match_operand:VM2 0 "memory_operand" "=Z") 2686 (match_operand:VM2 1 "register_operand" "v")) 2687 (unspec [(const_int 0)] UNSPEC_STVXL)])] 2688 "TARGET_ALTIVEC" 2689 "stvxl %1,%y0" 2690 [(set_attr "type" "vecstore")]) 2691 2692(define_insn "altivec_stve<VI_char>x" 2693 [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z") 2694 (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))] 2695 "TARGET_ALTIVEC" 2696 "stve<VI_char>x %1,%y0" 2697 [(set_attr "type" "vecstore")]) 2698 2699(define_insn "*altivec_stvesfx" 2700 [(set (match_operand:SF 0 "memory_operand" "=Z") 2701 (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))] 2702 "TARGET_ALTIVEC" 2703 "stvewx %1,%y0" 2704 [(set_attr "type" "vecstore")]) 2705 2706;; Generate doublee 2707;; signed int/float to double convert words 0 and 2 2708(define_expand "doublee<mode>2" 2709 [(set (match_operand:V2DF 0 "register_operand" "=v") 2710 (match_operand:VSX_W 1 "register_operand" "v"))] 2711 "TARGET_VSX" 2712{ 2713 machine_mode op_mode = GET_MODE (operands[1]); 2714 2715 if (BYTES_BIG_ENDIAN) 2716 { 2717 /* Big endian word numbering for words in operand is 0 1 2 3. 2718 Input words 0 and 2 are where they need to be. */ 2719 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], operands[1])); 2720 } 2721 else 2722 { 2723 /* Little endian word numbering for operand is 3 2 1 0. 2724 take (operand[1] operand[1]) and shift left one word 2725 3 2 1 0 3 2 1 0 => 2 1 0 3 2726 Input words 2 and 0 are now where they need to be for the 2727 conversion. */ 2728 rtx rtx_tmp; 2729 rtx rtx_val = GEN_INT (1); 2730 2731 rtx_tmp = gen_reg_rtx (op_mode); 2732 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2733 operands[1], rtx_val)); 2734 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2735 } 2736 DONE; 2737} 2738 [(set_attr "type" "veccomplex")]) 2739 2740;; Generate unsdoublee 2741;; unsigned int to double convert words 0 and 2 2742(define_expand "unsdoubleev4si2" 2743 [(set (match_operand:V2DF 0 "register_operand" "=v") 2744 (match_operand:V4SI 1 "register_operand" "v"))] 2745 "TARGET_VSX" 2746{ 2747 if (BYTES_BIG_ENDIAN) 2748 { 2749 /* Big endian word numbering for words in operand is 0 1 2 3. 2750 Input words 0 and 2 are where they need to be. */ 2751 emit_insn (gen_vsx_xvcvuxwdp (operands[0], operands[1])); 2752 } 2753 else 2754 { 2755 /* Little endian word numbering for operand is 3 2 1 0. 2756 take (operand[1] operand[1]) and shift left one word 2757 3 2 1 0 3 2 1 0 => 2 1 0 3 2758 Input words 2 and 0 are now where they need to be for the 2759 conversion. */ 2760 rtx rtx_tmp; 2761 rtx rtx_val = GEN_INT (1); 2762 2763 rtx_tmp = gen_reg_rtx (V4SImode); 2764 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2765 operands[1], rtx_val)); 2766 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 2767 } 2768 DONE; 2769} 2770 [(set_attr "type" "veccomplex")]) 2771 2772;; Generate doubleov 2773;; signed int/float to double convert words 1 and 3 2774(define_expand "doubleo<mode>2" 2775 [(set (match_operand:V2DF 0 "register_operand" "=v") 2776 (match_operand:VSX_W 1 "register_operand" "v"))] 2777 "TARGET_VSX" 2778{ 2779 machine_mode op_mode = GET_MODE (operands[1]); 2780 2781 if (BYTES_BIG_ENDIAN) 2782 { 2783 /* Big endian word numbering for words in operand is 0 1 2 3. 2784 take (operand[1] operand[1]) and shift left one word 2785 0 1 2 3 0 1 2 3 => 1 2 3 0 2786 Input words 1 and 3 are now where they need to be for the 2787 conversion. */ 2788 rtx rtx_tmp; 2789 rtx rtx_val = GEN_INT (1); 2790 2791 rtx_tmp = gen_reg_rtx (op_mode); 2792 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2793 operands[1], rtx_val)); 2794 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2795 } 2796 else 2797 { 2798 /* Little endian word numbering for operand is 3 2 1 0. 2799 Input words 3 and 1 are where they need to be. */ 2800 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], operands[1])); 2801 } 2802 DONE; 2803} 2804 [(set_attr "type" "veccomplex")]) 2805 2806;; Generate unsdoubleov 2807;; unsigned int to double convert words 1 and 3 2808(define_expand "unsdoubleov4si2" 2809 [(set (match_operand:V2DF 0 "register_operand" "=v") 2810 (match_operand:V4SI 1 "register_operand" "v"))] 2811 "TARGET_VSX" 2812{ 2813 if (BYTES_BIG_ENDIAN) 2814 { 2815 /* Big endian word numbering for words in operand is 0 1 2 3. 2816 take (operand[1] operand[1]) and shift left one word 2817 0 1 2 3 0 1 2 3 => 1 2 3 0 2818 Input words 1 and 3 are now where they need to be for the 2819 conversion. */ 2820 rtx rtx_tmp; 2821 rtx rtx_val = GEN_INT (1); 2822 2823 rtx_tmp = gen_reg_rtx (V4SImode); 2824 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2825 operands[1], rtx_val)); 2826 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 2827 } 2828 else 2829 { 2830 /* Want to convert the words 1 and 3. 2831 Little endian word numbering for operand is 3 2 1 0. 2832 Input words 3 and 1 are where they need to be. */ 2833 emit_insn (gen_vsx_xvcvuxwdp (operands[0], operands[1])); 2834 } 2835 DONE; 2836} 2837 [(set_attr "type" "veccomplex")]) 2838 2839;; Generate doublehv 2840;; signed int/float to double convert words 0 and 1 2841(define_expand "doubleh<mode>2" 2842 [(set (match_operand:V2DF 0 "register_operand" "=v") 2843 (match_operand:VSX_W 1 "register_operand" "v"))] 2844 "TARGET_VSX" 2845{ 2846 rtx rtx_tmp; 2847 rtx rtx_val; 2848 2849 machine_mode op_mode = GET_MODE (operands[1]); 2850 rtx_tmp = gen_reg_rtx (op_mode); 2851 2852 if (BYTES_BIG_ENDIAN) 2853 { 2854 /* Big endian word numbering for words in operand is 0 1 2 3. 2855 Shift operand left one word, rtx_tmp word order is now 1 2 3 0. 2856 take (rts_tmp operand[1]) and shift left three words 2857 1 2 3 0 0 1 2 3 => 0 0 1 2 2858 Input words 0 and 1 are now where they need to be for the 2859 conversion. */ 2860 rtx_val = GEN_INT (1); 2861 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2862 operands[1], rtx_val)); 2863 2864 rtx_val = GEN_INT (3); 2865 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, rtx_tmp, 2866 operands[1], rtx_val)); 2867 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2868 } 2869 else 2870 { 2871 /* Little endian word numbering for operand is 3 2 1 0. 2872 Shift operand left three words, rtx_tmp word order is now 0 3 2 1. 2873 take (operand[1] rts_tmp) and shift left two words 2874 3 2 1 0 0 3 2 1 => 1 0 0 3 2875 Input words 0 and 1 are now where they need to be for the 2876 conversion. */ 2877 rtx_val = GEN_INT (3); 2878 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2879 operands[1], rtx_val)); 2880 2881 rtx_val = GEN_INT (2); 2882 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2883 rtx_tmp, rtx_val)); 2884 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2885 } 2886 DONE; 2887} 2888 [(set_attr "type" "veccomplex")]) 2889 2890;; Generate unsdoublehv 2891;; unsigned int to double convert words 0 and 1 2892(define_expand "unsdoublehv4si2" 2893 [(set (match_operand:V2DF 0 "register_operand" "=v") 2894 (match_operand:V4SI 1 "register_operand" "v"))] 2895 "TARGET_VSX" 2896{ 2897 rtx rtx_tmp = gen_reg_rtx (V4SImode); 2898 rtx rtx_val = GEN_INT (12); 2899 2900 if (BYTES_BIG_ENDIAN) 2901 { 2902 /* Big endian word numbering for words in operand is 0 1 2 3. 2903 Shift operand left one word, rtx_tmp word order is now 1 2 3 0. 2904 take (rts_tmp operand[1]) and shift left three words 2905 1 2 3 0 0 1 2 3 => 0 0 1 2 2906 Input words 0 and 1 are now where they need to be for the 2907 conversion. */ 2908 rtx_val = GEN_INT (1); 2909 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2910 operands[1], rtx_val)); 2911 2912 rtx_val = GEN_INT (3); 2913 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, rtx_tmp, 2914 operands[1], rtx_val)); 2915 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 2916 } 2917 else 2918 { 2919 /* Little endian word numbering for operand is 3 2 1 0. 2920 Shift operand left three words, rtx_tmp word order is now 0 3 2 1. 2921 take (operand[1] rts_tmp) and shift left two words 2922 3 2 1 0 0 3 2 1 => 1 0 0 3 2923 Input words 1 and 0 are now where they need to be for the 2924 conversion. */ 2925 rtx_val = GEN_INT (3); 2926 2927 rtx_tmp = gen_reg_rtx (V4SImode); 2928 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2929 operands[1], rtx_val)); 2930 2931 rtx_val = GEN_INT (2); 2932 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2933 rtx_tmp, rtx_val)); 2934 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 2935 } 2936 DONE; 2937} 2938 [(set_attr "type" "veccomplex")]) 2939 2940;; Generate doublelv 2941;; signed int/float to double convert words 2 and 3 2942(define_expand "doublel<mode>2" 2943 [(set (match_operand:V2DF 0 "register_operand" "=v") 2944 (match_operand:VSX_W 1 "register_operand" "v"))] 2945 "TARGET_VSX" 2946{ 2947 rtx rtx_tmp; 2948 rtx rtx_val = GEN_INT (3); 2949 2950 machine_mode op_mode = GET_MODE (operands[1]); 2951 rtx_tmp = gen_reg_rtx (op_mode); 2952 2953 if (BYTES_BIG_ENDIAN) 2954 { 2955 /* Big endian word numbering for operand is 0 1 2 3. 2956 Shift operand left three words, rtx_tmp word order is now 3 0 1 2. 2957 take (operand[1] rtx_tmp) and shift left two words 2958 0 1 2 3 3 0 1 2 => 2 3 3 0 2959 now use convert instruction to convert word 2 and 3 in the 2960 input vector. */ 2961 rtx_val = GEN_INT (3); 2962 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2963 operands[1], rtx_val)); 2964 2965 rtx_val = GEN_INT (2); 2966 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2967 rtx_tmp, rtx_val)); 2968 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2969 } 2970 else 2971 { 2972 /* Little endian word numbering for operand is 3 2 1 0. 2973 Shift operand left one word, rtx_tmp word order is now 2 1 0 3. 2974 take (rtx_tmp operand[1]) and shift left three words 2975 2 1 0 3 3 2 1 0 => 3 3 2 1 2976 now use convert instruction to convert word 3 and 2 in the 2977 input vector. */ 2978 rtx_val = GEN_INT (1); 2979 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2980 operands[1], rtx_val)); 2981 2982 rtx_val = GEN_INT (3); 2983 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, rtx_tmp, 2984 operands[1], rtx_val)); 2985 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2986 } 2987 DONE; 2988} 2989 [(set_attr "type" "veccomplex")]) 2990 2991;; Generate unsdoublelv 2992;; unsigned int to double convert convert 2 and 3 2993(define_expand "unsdoublelv4si2" 2994 [(set (match_operand:V2DF 0 "register_operand" "=v") 2995 (match_operand:V4SI 1 "register_operand" "v"))] 2996 "TARGET_VSX" 2997{ 2998 rtx rtx_tmp = gen_reg_rtx (V4SImode); 2999 rtx rtx_val = GEN_INT (12); 3000 3001 if (BYTES_BIG_ENDIAN) 3002 { 3003 /* Big endian word numbering for operand is 0 1 2 3. 3004 Shift operand left three words, rtx_tmp word order is now 3 0 1 2. 3005 take (operand[1] rtx_tmp) and shift left two words 3006 0 1 2 3 3 0 1 2 => 2 3 3 0 3007 now use convert instruction to convert word 2 and 3 in the 3008 input vector. */ 3009 rtx_val = GEN_INT (3); 3010 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 3011 operands[1], rtx_val)); 3012 3013 rtx_val = GEN_INT (2); 3014 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 3015 rtx_tmp, rtx_val)); 3016 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 3017 } 3018 else 3019 { 3020 /* Little endian word numbering for operand is 3 2 1 0. 3021 Shift operand left one word, rtx_tmp word order is now 2 1 0 3. 3022 take (rtx_tmp operand[1]) and shift left three words 3023 2 1 0 3 3 2 1 0 => 3 3 2 1 3024 now use convert instruction to convert word 3 and 2 in the 3025 input vector. */ 3026 rtx_val = GEN_INT (1); 3027 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, 3028 operands[1], operands[1], rtx_val)); 3029 3030 rtx_val = GEN_INT (3); 3031 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, rtx_tmp, 3032 operands[1], rtx_val)); 3033 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 3034 } 3035 DONE; 3036} 3037 [(set_attr "type" "veccomplex")]) 3038 3039;; Generate two vector F32 converted to packed vector I16 vector 3040(define_expand "convert_4f32_8i16" 3041 [(set (match_operand:V8HI 0 "register_operand" "=v") 3042 (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "v") 3043 (match_operand:V4SF 2 "register_operand" "v")] 3044 UNSPEC_CONVERT_4F32_8I16))] 3045 "TARGET_P9_VECTOR" 3046{ 3047 rtx rtx_tmp_hi = gen_reg_rtx (V4SImode); 3048 rtx rtx_tmp_lo = gen_reg_rtx (V4SImode); 3049 3050 emit_insn (gen_altivec_vctuxs (rtx_tmp_hi, operands[1], const0_rtx)); 3051 emit_insn (gen_altivec_vctuxs (rtx_tmp_lo, operands[2], const0_rtx)); 3052 emit_insn (gen_altivec_vpkswss (operands[0], rtx_tmp_hi, rtx_tmp_lo)); 3053 DONE; 3054}) 3055 3056;; Convert two vector F32 to packed vector F16. 3057;; This builtin packs 32-bit floating-point values into a packed 3058;; 16-bit floating point values (stored in 16bit integer type). 3059;; (vector unsigned short r = vec_pack_to_short_fp32 (a, b); 3060;; The expected codegen for this builtin is 3061;; xvcvsphp t, a 3062;; xvcvsphp u, b 3063;; if (little endian) 3064;; vpkuwum r, t, u 3065;; else 3066;; vpkuwum r, u, t 3067 3068(define_expand "convert_4f32_8f16" 3069 [(set (match_operand:V8HI 0 "register_operand" "=v") 3070 (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "v") 3071 (match_operand:V4SF 2 "register_operand" "v")] 3072 UNSPEC_CONVERT_4F32_8F16))] 3073 "TARGET_P9_VECTOR" 3074{ 3075 rtx rtx_tmp_hi = gen_reg_rtx (V4SImode); 3076 rtx rtx_tmp_lo = gen_reg_rtx (V4SImode); 3077 3078 emit_insn (gen_vsx_xvcvsphp (rtx_tmp_hi, operands[1])); 3079 emit_insn (gen_vsx_xvcvsphp (rtx_tmp_lo, operands[2])); 3080 if (!BYTES_BIG_ENDIAN) 3081 emit_insn (gen_altivec_vpkuwum (operands[0], rtx_tmp_hi, rtx_tmp_lo)); 3082 else 3083 emit_insn (gen_altivec_vpkuwum (operands[0], rtx_tmp_lo, rtx_tmp_hi)); 3084 DONE; 3085}) 3086 3087;; Generate 3088;; xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0 3089;; vsubu?m SCRATCH2,SCRATCH1,%1 3090;; vmaxs? %0,%1,SCRATCH2" 3091(define_expand "abs<mode>2" 3092 [(set (match_dup 2) (match_dup 3)) 3093 (set (match_dup 4) 3094 (minus:VI2 (match_dup 2) 3095 (match_operand:VI2 1 "register_operand" "v"))) 3096 (set (match_operand:VI2 0 "register_operand" "=v") 3097 (smax:VI2 (match_dup 1) (match_dup 4)))] 3098 "<VI_unit>" 3099{ 3100 operands[2] = gen_reg_rtx (<MODE>mode); 3101 operands[3] = CONST0_RTX (<MODE>mode); 3102 operands[4] = gen_reg_rtx (<MODE>mode); 3103}) 3104 3105;; Generate 3106;; vspltisw SCRATCH1,0 3107;; vsubu?m SCRATCH2,SCRATCH1,%1 3108;; vmins? %0,%1,SCRATCH2" 3109(define_expand "nabs<mode>2" 3110 [(set (match_dup 2) (match_dup 3)) 3111 (set (match_dup 4) 3112 (minus:VI2 (match_dup 2) 3113 (match_operand:VI2 1 "register_operand" "v"))) 3114 (set (match_operand:VI2 0 "register_operand" "=v") 3115 (smin:VI2 (match_dup 1) (match_dup 4)))] 3116 "<VI_unit>" 3117{ 3118 operands[2] = gen_reg_rtx (<MODE>mode); 3119 operands[3] = CONST0_RTX (<MODE>mode); 3120 operands[4] = gen_reg_rtx (<MODE>mode); 3121}) 3122 3123;; Generate 3124;; vspltisw SCRATCH1,-1 3125;; vslw SCRATCH2,SCRATCH1,SCRATCH1 3126;; vandc %0,%1,SCRATCH2 3127(define_expand "altivec_absv4sf2" 3128 [(set (match_dup 2) 3129 (vec_duplicate:V4SI (const_int -1))) 3130 (set (match_dup 3) 3131 (ashift:V4SI (match_dup 2) (match_dup 2))) 3132 (set (match_operand:V4SF 0 "register_operand" "=v") 3133 (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0)) 3134 (match_operand:V4SF 1 "register_operand" "v")))] 3135 "TARGET_ALTIVEC" 3136{ 3137 operands[2] = gen_reg_rtx (V4SImode); 3138 operands[3] = gen_reg_rtx (V4SImode); 3139}) 3140 3141;; Generate 3142;; vspltis? SCRATCH0,0 3143;; vsubs?s SCRATCH2,SCRATCH1,%1 3144;; vmaxs? %0,%1,SCRATCH2" 3145(define_expand "altivec_abss_<mode>" 3146 [(set (match_dup 2) (vec_duplicate:VI (const_int 0))) 3147 (parallel [(set (match_dup 3) 3148 (unspec:VI [(match_dup 2) 3149 (match_operand:VI 1 "register_operand" "v")] 3150 UNSPEC_VSUBS)) 3151 (set (reg:SI VSCR_REGNO) 3152 (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]) 3153 (set (match_operand:VI 0 "register_operand" "=v") 3154 (smax:VI (match_dup 1) (match_dup 3)))] 3155 "TARGET_ALTIVEC" 3156{ 3157 operands[2] = gen_reg_rtx (GET_MODE (operands[0])); 3158 operands[3] = gen_reg_rtx (GET_MODE (operands[0])); 3159}) 3160 3161(define_expand "reduc_plus_scal_<mode>" 3162 [(set (match_operand:<VI_scalar> 0 "register_operand" "=v") 3163 (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")] 3164 UNSPEC_REDUC_PLUS))] 3165 "TARGET_ALTIVEC" 3166{ 3167 rtx vzero = gen_reg_rtx (V4SImode); 3168 rtx vtmp1 = gen_reg_rtx (V4SImode); 3169 rtx vtmp2 = gen_reg_rtx (<MODE>mode); 3170 rtx dest = gen_lowpart (V4SImode, vtmp2); 3171 int elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (<MODE>mode) - 1 : 0; 3172 3173 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); 3174 emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero)); 3175 emit_insn (gen_altivec_vsumsws_direct (dest, vtmp1, vzero)); 3176 rs6000_expand_vector_extract (operands[0], vtmp2, GEN_INT (elt)); 3177 DONE; 3178}) 3179 3180(define_insn "*p9_neg<mode>2" 3181 [(set (match_operand:VNEG 0 "altivec_register_operand" "=v") 3182 (neg:VNEG (match_operand:VNEG 1 "altivec_register_operand" "v")))] 3183 "TARGET_P9_VECTOR" 3184 "vneg<VI_char> %0,%1" 3185 [(set_attr "type" "vecsimple")]) 3186 3187(define_expand "neg<mode>2" 3188 [(set (match_operand:VI2 0 "register_operand") 3189 (neg:VI2 (match_operand:VI2 1 "register_operand")))] 3190 "<VI_unit>" 3191{ 3192 if (!TARGET_P9_VECTOR || (<MODE>mode != V4SImode && <MODE>mode != V2DImode)) 3193 { 3194 rtx vzero; 3195 3196 vzero = gen_reg_rtx (GET_MODE (operands[0])); 3197 emit_move_insn (vzero, CONST0_RTX (<MODE>mode)); 3198 emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); 3199 DONE; 3200 } 3201}) 3202 3203(define_expand "udot_prod<mode>" 3204 [(set (match_operand:V4SI 0 "register_operand" "=v") 3205 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") 3206 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") 3207 (match_operand:VIshort 2 "register_operand" "v")] 3208 UNSPEC_VMSUMU)))] 3209 "TARGET_ALTIVEC" 3210{ 3211 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3])); 3212 DONE; 3213}) 3214 3215(define_expand "sdot_prodv8hi" 3216 [(set (match_operand:V4SI 0 "register_operand" "=v") 3217 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") 3218 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3219 (match_operand:V8HI 2 "register_operand" "v")] 3220 UNSPEC_VMSUMSHM)))] 3221 "TARGET_ALTIVEC" 3222{ 3223 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3])); 3224 DONE; 3225}) 3226 3227(define_expand "widen_usum<mode>3" 3228 [(set (match_operand:V4SI 0 "register_operand" "=v") 3229 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") 3230 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")] 3231 UNSPEC_VMSUMU)))] 3232 "TARGET_ALTIVEC" 3233{ 3234 rtx vones = gen_reg_rtx (GET_MODE (operands[1])); 3235 3236 emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx)); 3237 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2])); 3238 DONE; 3239}) 3240 3241(define_expand "widen_ssumv16qi3" 3242 [(set (match_operand:V4SI 0 "register_operand" "=v") 3243 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") 3244 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")] 3245 UNSPEC_VMSUMM)))] 3246 "TARGET_ALTIVEC" 3247{ 3248 rtx vones = gen_reg_rtx (V16QImode); 3249 3250 emit_insn (gen_altivec_vspltisb (vones, const1_rtx)); 3251 emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2])); 3252 DONE; 3253}) 3254 3255(define_expand "widen_ssumv8hi3" 3256 [(set (match_operand:V4SI 0 "register_operand" "=v") 3257 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") 3258 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 3259 UNSPEC_VMSUMSHM)))] 3260 "TARGET_ALTIVEC" 3261{ 3262 rtx vones = gen_reg_rtx (V8HImode); 3263 3264 emit_insn (gen_altivec_vspltish (vones, const1_rtx)); 3265 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2])); 3266 DONE; 3267}) 3268 3269(define_expand "vec_unpacks_hi_<VP_small_lc>" 3270 [(set (match_operand:VP 0 "register_operand" "=v") 3271 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 3272 UNSPEC_VUNPACK_HI_SIGN_DIRECT))] 3273 "<VI_unit>" 3274 "") 3275 3276(define_expand "vec_unpacks_lo_<VP_small_lc>" 3277 [(set (match_operand:VP 0 "register_operand" "=v") 3278 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 3279 UNSPEC_VUNPACK_LO_SIGN_DIRECT))] 3280 "<VI_unit>" 3281 "") 3282 3283(define_insn "vperm_v8hiv4si" 3284 [(set (match_operand:V4SI 0 "register_operand" "=v,?wa") 3285 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,wa") 3286 (match_operand:V4SI 2 "register_operand" "v,0") 3287 (match_operand:V16QI 3 "register_operand" "v,wa")] 3288 UNSPEC_VPERMSI))] 3289 "TARGET_ALTIVEC" 3290 "@ 3291 vperm %0,%1,%2,%3 3292 xxperm %x0,%x1,%x3" 3293 [(set_attr "type" "vecperm") 3294 (set_attr "isa" "*,p9v")]) 3295 3296(define_insn "vperm_v16qiv8hi" 3297 [(set (match_operand:V8HI 0 "register_operand" "=v,?wa") 3298 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,wa") 3299 (match_operand:V8HI 2 "register_operand" "v,0") 3300 (match_operand:V16QI 3 "register_operand" "v,wa")] 3301 UNSPEC_VPERMHI))] 3302 "TARGET_ALTIVEC" 3303 "@ 3304 vperm %0,%1,%2,%3 3305 xxperm %x0,%x1,%x3" 3306 [(set_attr "type" "vecperm") 3307 (set_attr "isa" "*,p9v")]) 3308 3309 3310(define_expand "vec_unpacku_hi_v16qi" 3311 [(set (match_operand:V8HI 0 "register_operand" "=v") 3312 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 3313 UNSPEC_VUPKHUB))] 3314 "TARGET_ALTIVEC" 3315{ 3316 rtx vzero = gen_reg_rtx (V8HImode); 3317 rtx mask = gen_reg_rtx (V16QImode); 3318 rtvec v = rtvec_alloc (16); 3319 bool be = BYTES_BIG_ENDIAN; 3320 3321 emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); 3322 3323 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); 3324 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 0 : 16); 3325 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 6); 3326 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); 3327 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); 3328 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 2 : 16); 3329 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 4); 3330 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); 3331 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); 3332 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 4 : 16); 3333 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 2); 3334 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); 3335 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); 3336 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 6 : 16); 3337 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 0); 3338 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); 3339 3340 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3341 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); 3342 DONE; 3343}) 3344 3345(define_expand "vec_unpacku_hi_v8hi" 3346 [(set (match_operand:V4SI 0 "register_operand" "=v") 3347 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 3348 UNSPEC_VUPKHUH))] 3349 "TARGET_ALTIVEC" 3350{ 3351 rtx vzero = gen_reg_rtx (V4SImode); 3352 rtx mask = gen_reg_rtx (V16QImode); 3353 rtvec v = rtvec_alloc (16); 3354 bool be = BYTES_BIG_ENDIAN; 3355 3356 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); 3357 3358 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); 3359 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 6); 3360 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 0 : 17); 3361 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); 3362 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); 3363 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 4); 3364 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 2 : 17); 3365 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); 3366 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); 3367 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 2); 3368 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 4 : 17); 3369 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); 3370 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); 3371 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 0); 3372 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 6 : 17); 3373 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); 3374 3375 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3376 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); 3377 DONE; 3378}) 3379 3380(define_expand "vec_unpacku_lo_v16qi" 3381 [(set (match_operand:V8HI 0 "register_operand" "=v") 3382 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 3383 UNSPEC_VUPKLUB))] 3384 "TARGET_ALTIVEC" 3385{ 3386 rtx vzero = gen_reg_rtx (V8HImode); 3387 rtx mask = gen_reg_rtx (V16QImode); 3388 rtvec v = rtvec_alloc (16); 3389 bool be = BYTES_BIG_ENDIAN; 3390 3391 emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); 3392 3393 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); 3394 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 8 : 16); 3395 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14); 3396 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); 3397 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); 3398 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16); 3399 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12); 3400 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); 3401 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); 3402 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16); 3403 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10); 3404 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); 3405 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); 3406 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16); 3407 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 8); 3408 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); 3409 3410 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3411 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); 3412 DONE; 3413}) 3414 3415(define_expand "vec_unpacku_lo_v8hi" 3416 [(set (match_operand:V4SI 0 "register_operand" "=v") 3417 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 3418 UNSPEC_VUPKLUH))] 3419 "TARGET_ALTIVEC" 3420{ 3421 rtx vzero = gen_reg_rtx (V4SImode); 3422 rtx mask = gen_reg_rtx (V16QImode); 3423 rtvec v = rtvec_alloc (16); 3424 bool be = BYTES_BIG_ENDIAN; 3425 3426 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); 3427 3428 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); 3429 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14); 3430 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 8 : 17); 3431 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); 3432 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); 3433 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12); 3434 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17); 3435 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); 3436 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); 3437 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10); 3438 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17); 3439 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); 3440 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); 3441 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 8); 3442 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17); 3443 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); 3444 3445 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3446 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); 3447 DONE; 3448}) 3449 3450(define_expand "vec_widen_umult_hi_v16qi" 3451 [(set (match_operand:V8HI 0 "register_operand" "=v") 3452 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 3453 (match_operand:V16QI 2 "register_operand" "v")] 3454 UNSPEC_VMULWHUB))] 3455 "TARGET_ALTIVEC" 3456{ 3457 rtx ve = gen_reg_rtx (V8HImode); 3458 rtx vo = gen_reg_rtx (V8HImode); 3459 3460 if (BYTES_BIG_ENDIAN) 3461 { 3462 emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2])); 3463 emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2])); 3464 emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo)); 3465 } 3466 else 3467 { 3468 emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2])); 3469 emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2])); 3470 emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve)); 3471 } 3472 DONE; 3473}) 3474 3475(define_expand "vec_widen_umult_lo_v16qi" 3476 [(set (match_operand:V8HI 0 "register_operand" "=v") 3477 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 3478 (match_operand:V16QI 2 "register_operand" "v")] 3479 UNSPEC_VMULWLUB))] 3480 "TARGET_ALTIVEC" 3481{ 3482 rtx ve = gen_reg_rtx (V8HImode); 3483 rtx vo = gen_reg_rtx (V8HImode); 3484 3485 if (BYTES_BIG_ENDIAN) 3486 { 3487 emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2])); 3488 emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2])); 3489 emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo)); 3490 } 3491 else 3492 { 3493 emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2])); 3494 emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2])); 3495 emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve)); 3496 } 3497 DONE; 3498}) 3499 3500(define_expand "vec_widen_smult_hi_v16qi" 3501 [(set (match_operand:V8HI 0 "register_operand" "=v") 3502 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 3503 (match_operand:V16QI 2 "register_operand" "v")] 3504 UNSPEC_VMULWHSB))] 3505 "TARGET_ALTIVEC" 3506{ 3507 rtx ve = gen_reg_rtx (V8HImode); 3508 rtx vo = gen_reg_rtx (V8HImode); 3509 3510 if (BYTES_BIG_ENDIAN) 3511 { 3512 emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2])); 3513 emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2])); 3514 emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo)); 3515 } 3516 else 3517 { 3518 emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2])); 3519 emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2])); 3520 emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve)); 3521 } 3522 DONE; 3523}) 3524 3525(define_expand "vec_widen_smult_lo_v16qi" 3526 [(set (match_operand:V8HI 0 "register_operand" "=v") 3527 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 3528 (match_operand:V16QI 2 "register_operand" "v")] 3529 UNSPEC_VMULWLSB))] 3530 "TARGET_ALTIVEC" 3531{ 3532 rtx ve = gen_reg_rtx (V8HImode); 3533 rtx vo = gen_reg_rtx (V8HImode); 3534 3535 if (BYTES_BIG_ENDIAN) 3536 { 3537 emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2])); 3538 emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2])); 3539 emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo)); 3540 } 3541 else 3542 { 3543 emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2])); 3544 emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2])); 3545 emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve)); 3546 } 3547 DONE; 3548}) 3549 3550(define_expand "vec_widen_umult_hi_v8hi" 3551 [(set (match_operand:V4SI 0 "register_operand" "=v") 3552 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3553 (match_operand:V8HI 2 "register_operand" "v")] 3554 UNSPEC_VMULWHUH))] 3555 "TARGET_ALTIVEC" 3556{ 3557 rtx ve = gen_reg_rtx (V4SImode); 3558 rtx vo = gen_reg_rtx (V4SImode); 3559 3560 if (BYTES_BIG_ENDIAN) 3561 { 3562 emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2])); 3563 emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2])); 3564 emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo)); 3565 } 3566 else 3567 { 3568 emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2])); 3569 emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2])); 3570 emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve)); 3571 } 3572 DONE; 3573}) 3574 3575(define_expand "vec_widen_umult_lo_v8hi" 3576 [(set (match_operand:V4SI 0 "register_operand" "=v") 3577 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3578 (match_operand:V8HI 2 "register_operand" "v")] 3579 UNSPEC_VMULWLUH))] 3580 "TARGET_ALTIVEC" 3581{ 3582 rtx ve = gen_reg_rtx (V4SImode); 3583 rtx vo = gen_reg_rtx (V4SImode); 3584 3585 if (BYTES_BIG_ENDIAN) 3586 { 3587 emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2])); 3588 emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2])); 3589 emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo)); 3590 } 3591 else 3592 { 3593 emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2])); 3594 emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2])); 3595 emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve)); 3596 } 3597 DONE; 3598}) 3599 3600(define_expand "vec_widen_smult_hi_v8hi" 3601 [(set (match_operand:V4SI 0 "register_operand" "=v") 3602 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3603 (match_operand:V8HI 2 "register_operand" "v")] 3604 UNSPEC_VMULWHSH))] 3605 "TARGET_ALTIVEC" 3606{ 3607 rtx ve = gen_reg_rtx (V4SImode); 3608 rtx vo = gen_reg_rtx (V4SImode); 3609 3610 if (BYTES_BIG_ENDIAN) 3611 { 3612 emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2])); 3613 emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2])); 3614 emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo)); 3615 } 3616 else 3617 { 3618 emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2])); 3619 emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2])); 3620 emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve)); 3621 } 3622 DONE; 3623}) 3624 3625(define_expand "vec_widen_smult_lo_v8hi" 3626 [(set (match_operand:V4SI 0 "register_operand" "=v") 3627 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3628 (match_operand:V8HI 2 "register_operand" "v")] 3629 UNSPEC_VMULWLSH))] 3630 "TARGET_ALTIVEC" 3631{ 3632 rtx ve = gen_reg_rtx (V4SImode); 3633 rtx vo = gen_reg_rtx (V4SImode); 3634 3635 if (BYTES_BIG_ENDIAN) 3636 { 3637 emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2])); 3638 emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2])); 3639 emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo)); 3640 } 3641 else 3642 { 3643 emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2])); 3644 emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2])); 3645 emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve)); 3646 } 3647 DONE; 3648}) 3649 3650(define_expand "vec_pack_trunc_<mode>" 3651 [(set (match_operand:<VP_small> 0 "register_operand" "=v") 3652 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") 3653 (match_operand:VP 2 "register_operand" "v")] 3654 UNSPEC_VPACK_UNS_UNS_MOD))] 3655 "<VI_unit>" 3656 "") 3657 3658(define_expand "mulv16qi3" 3659 [(set (match_operand:V16QI 0 "register_operand" "=v") 3660 (mult:V16QI (match_operand:V16QI 1 "register_operand" "v") 3661 (match_operand:V16QI 2 "register_operand" "v")))] 3662 "TARGET_ALTIVEC" 3663{ 3664 rtx even = gen_reg_rtx (V8HImode); 3665 rtx odd = gen_reg_rtx (V8HImode); 3666 rtx mask = gen_reg_rtx (V16QImode); 3667 rtvec v = rtvec_alloc (16); 3668 int i; 3669 3670 for (i = 0; i < 8; ++i) { 3671 RTVEC_ELT (v, 2 * i) 3672 = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 1 : 31 - 2 * i); 3673 RTVEC_ELT (v, 2 * i + 1) 3674 = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 17 : 15 - 2 * i); 3675 } 3676 3677 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3678 emit_insn (gen_altivec_vmulesb (even, operands[1], operands[2])); 3679 emit_insn (gen_altivec_vmulosb (odd, operands[1], operands[2])); 3680 emit_insn (gen_altivec_vperm_v8hiv16qi (operands[0], even, odd, mask)); 3681 DONE; 3682}) 3683 3684(define_expand "altivec_vpermxor" 3685 [(use (match_operand:V16QI 0 "register_operand")) 3686 (use (match_operand:V16QI 1 "register_operand")) 3687 (use (match_operand:V16QI 2 "register_operand")) 3688 (use (match_operand:V16QI 3 "register_operand"))] 3689 "TARGET_P8_VECTOR" 3690{ 3691 if (!BYTES_BIG_ENDIAN) 3692 { 3693 /* vpermxor indexes the bytes using Big Endian numbering. If LE, 3694 change indexing in operand[3] to BE index. */ 3695 rtx be_index = gen_reg_rtx (V16QImode); 3696 3697 emit_insn (gen_one_cmplv16qi2 (be_index, operands[3])); 3698 emit_insn (gen_crypto_vpermxor_v16qi (operands[0], operands[1], 3699 operands[2], be_index)); 3700 } 3701 else 3702 emit_insn (gen_crypto_vpermxor_v16qi (operands[0], operands[1], 3703 operands[2], operands[3])); 3704 DONE; 3705}) 3706 3707(define_expand "altivec_negv4sf2" 3708 [(use (match_operand:V4SF 0 "register_operand")) 3709 (use (match_operand:V4SF 1 "register_operand"))] 3710 "TARGET_ALTIVEC" 3711{ 3712 rtx neg0; 3713 3714 /* Generate [-0.0, -0.0, -0.0, -0.0]. */ 3715 neg0 = gen_reg_rtx (V4SImode); 3716 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); 3717 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); 3718 3719 /* XOR */ 3720 emit_insn (gen_xorv4sf3 (operands[0], 3721 gen_lowpart (V4SFmode, neg0), operands[1])); 3722 3723 DONE; 3724}) 3725 3726;; Vector reverse elements 3727(define_expand "altivec_vreve<mode>2" 3728 [(set (match_operand:VEC_A 0 "register_operand" "=v") 3729 (unspec:VEC_A [(match_operand:VEC_A 1 "register_operand" "v")] 3730 UNSPEC_VREVEV))] 3731 "TARGET_ALTIVEC" 3732{ 3733 int i, j, size, num_elements; 3734 rtvec v = rtvec_alloc (16); 3735 rtx mask = gen_reg_rtx (V16QImode); 3736 3737 size = GET_MODE_UNIT_SIZE (<MODE>mode); 3738 num_elements = GET_MODE_NUNITS (<MODE>mode); 3739 3740 for (j = 0; j < num_elements; j++) 3741 for (i = 0; i < size; i++) 3742 RTVEC_ELT (v, i + j * size) 3743 = GEN_INT (i + (num_elements - 1 - j) * size); 3744 3745 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3746 emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], 3747 operands[1], mask)); 3748 DONE; 3749}) 3750 3751;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL, 3752;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell. 3753(define_insn "altivec_lvlx" 3754 [(set (match_operand:V16QI 0 "register_operand" "=v") 3755 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] 3756 UNSPEC_LVLX))] 3757 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3758 "lvlx %0,%y1" 3759 [(set_attr "type" "vecload")]) 3760 3761(define_insn "altivec_lvlxl" 3762 [(set (match_operand:V16QI 0 "register_operand" "=v") 3763 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] 3764 UNSPEC_LVLXL))] 3765 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3766 "lvlxl %0,%y1" 3767 [(set_attr "type" "vecload")]) 3768 3769(define_insn "altivec_lvrx" 3770 [(set (match_operand:V16QI 0 "register_operand" "=v") 3771 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] 3772 UNSPEC_LVRX))] 3773 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3774 "lvrx %0,%y1" 3775 [(set_attr "type" "vecload")]) 3776 3777(define_insn "altivec_lvrxl" 3778 [(set (match_operand:V16QI 0 "register_operand" "=v") 3779 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] 3780 UNSPEC_LVRXL))] 3781 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3782 "lvrxl %0,%y1" 3783 [(set_attr "type" "vecload")]) 3784 3785(define_insn "altivec_stvlx" 3786 [(parallel 3787 [(set (match_operand:V16QI 0 "memory_operand" "=Z") 3788 (match_operand:V16QI 1 "register_operand" "v")) 3789 (unspec [(const_int 0)] UNSPEC_STVLX)])] 3790 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3791 "stvlx %1,%y0" 3792 [(set_attr "type" "vecstore")]) 3793 3794(define_insn "altivec_stvlxl" 3795 [(parallel 3796 [(set (match_operand:V16QI 0 "memory_operand" "=Z") 3797 (match_operand:V16QI 1 "register_operand" "v")) 3798 (unspec [(const_int 0)] UNSPEC_STVLXL)])] 3799 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3800 "stvlxl %1,%y0" 3801 [(set_attr "type" "vecstore")]) 3802 3803(define_insn "altivec_stvrx" 3804 [(parallel 3805 [(set (match_operand:V16QI 0 "memory_operand" "=Z") 3806 (match_operand:V16QI 1 "register_operand" "v")) 3807 (unspec [(const_int 0)] UNSPEC_STVRX)])] 3808 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3809 "stvrx %1,%y0" 3810 [(set_attr "type" "vecstore")]) 3811 3812(define_insn "altivec_stvrxl" 3813 [(parallel 3814 [(set (match_operand:V16QI 0 "memory_operand" "=Z") 3815 (match_operand:V16QI 1 "register_operand" "v")) 3816 (unspec [(const_int 0)] UNSPEC_STVRXL)])] 3817 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3818 "stvrxl %1,%y0" 3819 [(set_attr "type" "vecstore")]) 3820 3821(define_expand "vec_unpacks_float_hi_v8hi" 3822 [(set (match_operand:V4SF 0 "register_operand") 3823 (unspec:V4SF [(match_operand:V8HI 1 "register_operand")] 3824 UNSPEC_VUPKHS_V4SF))] 3825 "TARGET_ALTIVEC" 3826{ 3827 rtx tmp = gen_reg_rtx (V4SImode); 3828 3829 emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1])); 3830 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); 3831 DONE; 3832}) 3833 3834(define_expand "vec_unpacks_float_lo_v8hi" 3835 [(set (match_operand:V4SF 0 "register_operand") 3836 (unspec:V4SF [(match_operand:V8HI 1 "register_operand")] 3837 UNSPEC_VUPKLS_V4SF))] 3838 "TARGET_ALTIVEC" 3839{ 3840 rtx tmp = gen_reg_rtx (V4SImode); 3841 3842 emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1])); 3843 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); 3844 DONE; 3845}) 3846 3847(define_expand "vec_unpacku_float_hi_v8hi" 3848 [(set (match_operand:V4SF 0 "register_operand") 3849 (unspec:V4SF [(match_operand:V8HI 1 "register_operand")] 3850 UNSPEC_VUPKHU_V4SF))] 3851 "TARGET_ALTIVEC" 3852{ 3853 rtx tmp = gen_reg_rtx (V4SImode); 3854 3855 emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1])); 3856 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); 3857 DONE; 3858}) 3859 3860(define_expand "vec_unpacku_float_lo_v8hi" 3861 [(set (match_operand:V4SF 0 "register_operand") 3862 (unspec:V4SF [(match_operand:V8HI 1 "register_operand")] 3863 UNSPEC_VUPKLU_V4SF))] 3864 "TARGET_ALTIVEC" 3865{ 3866 rtx tmp = gen_reg_rtx (V4SImode); 3867 3868 emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1])); 3869 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); 3870 DONE; 3871}) 3872 3873 3874;; Power8/power9 vector instructions encoded as Altivec instructions 3875 3876;; Vector count leading zeros 3877(define_insn "*p8v_clz<mode>2" 3878 [(set (match_operand:VI2 0 "register_operand" "=v") 3879 (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))] 3880 "TARGET_P8_VECTOR" 3881 "vclz<wd> %0,%1" 3882 [(set_attr "type" "vecsimple")]) 3883 3884;; Vector absolute difference unsigned 3885(define_expand "vadu<mode>3" 3886 [(set (match_operand:VI 0 "register_operand") 3887 (unspec:VI [(match_operand:VI 1 "register_operand") 3888 (match_operand:VI 2 "register_operand")] 3889 UNSPEC_VADU))] 3890 "TARGET_P9_VECTOR") 3891 3892;; Vector absolute difference unsigned 3893(define_insn "p9_vadu<mode>3" 3894 [(set (match_operand:VI 0 "register_operand" "=v") 3895 (unspec:VI [(match_operand:VI 1 "register_operand" "v") 3896 (match_operand:VI 2 "register_operand" "v")] 3897 UNSPEC_VADU))] 3898 "TARGET_P9_VECTOR" 3899 "vabsdu<wd> %0,%1,%2" 3900 [(set_attr "type" "vecsimple")]) 3901 3902;; Vector count trailing zeros 3903(define_insn "*p9v_ctz<mode>2" 3904 [(set (match_operand:VI2 0 "register_operand" "=v") 3905 (ctz:VI2 (match_operand:VI2 1 "register_operand" "v")))] 3906 "TARGET_P9_VECTOR" 3907 "vctz<wd> %0,%1" 3908 [(set_attr "type" "vecsimple")]) 3909 3910;; Vector population count 3911(define_insn "*p8v_popcount<mode>2" 3912 [(set (match_operand:VI2 0 "register_operand" "=v") 3913 (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))] 3914 "TARGET_P8_VECTOR" 3915 "vpopcnt<wd> %0,%1" 3916 [(set_attr "type" "vecsimple")]) 3917 3918;; Vector parity 3919(define_insn "rs6000_vprtyb<mode>2" 3920 [(set (match_operand:VEC_IP 0 "register_operand" "=v") 3921 (unspec:VEC_IP 3922 [(match_operand:VEC_IP 1 "register_operand" "v")] 3923 UNSPEC_PARITY))] 3924 "TARGET_P9_VECTOR" 3925 "vprtyb<wd> %0,%1" 3926 [(set_attr "type" "vecsimple")]) 3927 3928;; Vector Gather Bits by Bytes by Doubleword 3929(define_insn "p8v_vgbbd" 3930 [(set (match_operand:V16QI 0 "register_operand" "=v") 3931 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] 3932 UNSPEC_VGBBD))] 3933 "TARGET_P8_VECTOR" 3934 "vgbbd %0,%1" 3935 [(set_attr "type" "vecsimple")]) 3936 3937 3938;; 128-bit binary integer arithmetic 3939;; We have a special container type (V1TImode) to allow operations using the 3940;; ISA 2.07 128-bit binary support to target the VMX/altivec registers without 3941;; having to worry about the register allocator deciding GPRs are better. 3942 3943(define_insn "altivec_vadduqm" 3944 [(set (match_operand:V1TI 0 "register_operand" "=v") 3945 (plus:V1TI (match_operand:V1TI 1 "register_operand" "v") 3946 (match_operand:V1TI 2 "register_operand" "v")))] 3947 "TARGET_VADDUQM" 3948 "vadduqm %0,%1,%2" 3949 [(set_attr "type" "vecsimple")]) 3950 3951(define_insn "altivec_vaddcuq" 3952 [(set (match_operand:V1TI 0 "register_operand" "=v") 3953 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3954 (match_operand:V1TI 2 "register_operand" "v")] 3955 UNSPEC_VADDCUQ))] 3956 "TARGET_VADDUQM" 3957 "vaddcuq %0,%1,%2" 3958 [(set_attr "type" "vecsimple")]) 3959 3960(define_insn "altivec_vsubuqm" 3961 [(set (match_operand:V1TI 0 "register_operand" "=v") 3962 (minus:V1TI (match_operand:V1TI 1 "register_operand" "v") 3963 (match_operand:V1TI 2 "register_operand" "v")))] 3964 "TARGET_VADDUQM" 3965 "vsubuqm %0,%1,%2" 3966 [(set_attr "type" "vecsimple")]) 3967 3968(define_insn "altivec_vsubcuq" 3969 [(set (match_operand:V1TI 0 "register_operand" "=v") 3970 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3971 (match_operand:V1TI 2 "register_operand" "v")] 3972 UNSPEC_VSUBCUQ))] 3973 "TARGET_VADDUQM" 3974 "vsubcuq %0,%1,%2" 3975 [(set_attr "type" "vecsimple")]) 3976 3977(define_insn "altivec_vaddeuqm" 3978 [(set (match_operand:V1TI 0 "register_operand" "=v") 3979 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3980 (match_operand:V1TI 2 "register_operand" "v") 3981 (match_operand:V1TI 3 "register_operand" "v")] 3982 UNSPEC_VADDEUQM))] 3983 "TARGET_VADDUQM" 3984 "vaddeuqm %0,%1,%2,%3" 3985 [(set_attr "type" "vecsimple")]) 3986 3987(define_insn "altivec_vaddecuq" 3988 [(set (match_operand:V1TI 0 "register_operand" "=v") 3989 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3990 (match_operand:V1TI 2 "register_operand" "v") 3991 (match_operand:V1TI 3 "register_operand" "v")] 3992 UNSPEC_VADDECUQ))] 3993 "TARGET_VADDUQM" 3994 "vaddecuq %0,%1,%2,%3" 3995 [(set_attr "type" "vecsimple")]) 3996 3997(define_insn "altivec_vsubeuqm" 3998 [(set (match_operand:V1TI 0 "register_operand" "=v") 3999 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 4000 (match_operand:V1TI 2 "register_operand" "v") 4001 (match_operand:V1TI 3 "register_operand" "v")] 4002 UNSPEC_VSUBEUQM))] 4003 "TARGET_VADDUQM" 4004 "vsubeuqm %0,%1,%2,%3" 4005 [(set_attr "type" "vecsimple")]) 4006 4007(define_insn "altivec_vsubecuq" 4008 [(set (match_operand:V1TI 0 "register_operand" "=v") 4009 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 4010 (match_operand:V1TI 2 "register_operand" "v") 4011 (match_operand:V1TI 3 "register_operand" "v")] 4012 UNSPEC_VSUBECUQ))] 4013 "TARGET_VADDUQM" 4014 "vsubecuq %0,%1,%2,%3" 4015 [(set_attr "type" "vecsimple")]) 4016 4017;; We use V2DI as the output type to simplify converting the permute 4018;; bits into an integer 4019(define_insn "altivec_vbpermq" 4020 [(set (match_operand:V2DI 0 "register_operand" "=v") 4021 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v") 4022 (match_operand:V16QI 2 "register_operand" "v")] 4023 UNSPEC_VBPERMQ))] 4024 "TARGET_P8_VECTOR" 4025 "vbpermq %0,%1,%2" 4026 [(set_attr "type" "vecperm")]) 4027 4028; One of the vector API interfaces requires returning vector unsigned char. 4029(define_insn "altivec_vbpermq2" 4030 [(set (match_operand:V16QI 0 "register_operand" "=v") 4031 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 4032 (match_operand:V16QI 2 "register_operand" "v")] 4033 UNSPEC_VBPERMQ))] 4034 "TARGET_P8_VECTOR" 4035 "vbpermq %0,%1,%2" 4036 [(set_attr "type" "vecperm")]) 4037 4038(define_insn "altivec_vbpermd" 4039 [(set (match_operand:V2DI 0 "register_operand" "=v") 4040 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v") 4041 (match_operand:V16QI 2 "register_operand" "v")] 4042 UNSPEC_VBPERMD))] 4043 "TARGET_P9_VECTOR" 4044 "vbpermd %0,%1,%2" 4045 [(set_attr "type" "vecsimple")]) 4046 4047;; Support for SAD (sum of absolute differences). 4048 4049;; Due to saturating semantics, we can't combine the sum-across 4050;; with the vector accumulate in vsum4ubs. A vadduwm is needed. 4051(define_expand "usadv16qi" 4052 [(use (match_operand:V4SI 0 "register_operand")) 4053 (use (match_operand:V16QI 1 "register_operand")) 4054 (use (match_operand:V16QI 2 "register_operand")) 4055 (use (match_operand:V4SI 3 "register_operand"))] 4056 "TARGET_P9_VECTOR" 4057{ 4058 rtx absd = gen_reg_rtx (V16QImode); 4059 rtx zero = gen_reg_rtx (V4SImode); 4060 rtx psum = gen_reg_rtx (V4SImode); 4061 4062 emit_insn (gen_p9_vaduv16qi3 (absd, operands[1], operands[2])); 4063 emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); 4064 emit_insn (gen_altivec_vsum4ubs (psum, absd, zero)); 4065 emit_insn (gen_addv4si3 (operands[0], psum, operands[3])); 4066 DONE; 4067}) 4068 4069;; Since vsum4shs is saturating and further performs signed 4070;; arithmetic, we can't combine the sum-across with the vector 4071;; accumulate in vsum4shs. A vadduwm is needed. 4072(define_expand "usadv8hi" 4073 [(use (match_operand:V4SI 0 "register_operand")) 4074 (use (match_operand:V8HI 1 "register_operand")) 4075 (use (match_operand:V8HI 2 "register_operand")) 4076 (use (match_operand:V4SI 3 "register_operand"))] 4077 "TARGET_P9_VECTOR" 4078{ 4079 rtx absd = gen_reg_rtx (V8HImode); 4080 rtx zero = gen_reg_rtx (V4SImode); 4081 rtx psum = gen_reg_rtx (V4SImode); 4082 4083 emit_insn (gen_p9_vaduv8hi3 (absd, operands[1], operands[2])); 4084 emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); 4085 emit_insn (gen_altivec_vsum4shs (psum, absd, zero)); 4086 emit_insn (gen_addv4si3 (operands[0], psum, operands[3])); 4087 DONE; 4088}) 4089 4090;; Decimal Integer operations 4091(define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB]) 4092 4093(define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add") 4094 (UNSPEC_BCDSUB "sub")]) 4095 4096(define_code_iterator BCD_TEST [eq lt gt unordered]) 4097 4098(define_insn "bcd<bcd_add_sub>" 4099 [(set (match_operand:V1TI 0 "gpc_reg_operand" "=v") 4100 (unspec:V1TI [(match_operand:V1TI 1 "gpc_reg_operand" "v") 4101 (match_operand:V1TI 2 "gpc_reg_operand" "v") 4102 (match_operand:QI 3 "const_0_to_1_operand" "n")] 4103 UNSPEC_BCD_ADD_SUB)) 4104 (clobber (reg:CCFP CR6_REGNO))] 4105 "TARGET_P8_VECTOR" 4106 "bcd<bcd_add_sub>. %0,%1,%2,%3" 4107 [(set_attr "type" "vecsimple")]) 4108 4109;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we 4110;; can use the unordered test for BCD nans and add/subtracts that overflow. An 4111;; UNORDERED test on an integer type (like V1TImode) is not defined. The type 4112;; probably should be one that can go in the VMX (Altivec) registers, so we 4113;; can't use DDmode or DFmode. 4114(define_insn "*bcd<bcd_add_sub>_test" 4115 [(set (reg:CCFP CR6_REGNO) 4116 (compare:CCFP 4117 (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v") 4118 (match_operand:V1TI 2 "register_operand" "v") 4119 (match_operand:QI 3 "const_0_to_1_operand" "i")] 4120 UNSPEC_BCD_ADD_SUB) 4121 (match_operand:V2DF 4 "zero_constant" "j"))) 4122 (clobber (match_scratch:V1TI 0 "=v"))] 4123 "TARGET_P8_VECTOR" 4124 "bcd<bcd_add_sub>. %0,%1,%2,%3" 4125 [(set_attr "type" "vecsimple")]) 4126 4127(define_insn "*bcd<bcd_add_sub>_test2" 4128 [(set (match_operand:V1TI 0 "register_operand" "=v") 4129 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 4130 (match_operand:V1TI 2 "register_operand" "v") 4131 (match_operand:QI 3 "const_0_to_1_operand" "i")] 4132 UNSPEC_BCD_ADD_SUB)) 4133 (set (reg:CCFP CR6_REGNO) 4134 (compare:CCFP 4135 (unspec:V2DF [(match_dup 1) 4136 (match_dup 2) 4137 (match_dup 3)] 4138 UNSPEC_BCD_ADD_SUB) 4139 (match_operand:V2DF 4 "zero_constant" "j")))] 4140 "TARGET_P8_VECTOR" 4141 "bcd<bcd_add_sub>. %0,%1,%2,%3" 4142 [(set_attr "type" "vecsimple")]) 4143 4144(define_expand "bcd<bcd_add_sub>_<code>" 4145 [(parallel [(set (reg:CCFP CR6_REGNO) 4146 (compare:CCFP 4147 (unspec:V2DF [(match_operand:V1TI 1 "register_operand") 4148 (match_operand:V1TI 2 "register_operand") 4149 (match_operand:QI 3 "const_0_to_1_operand")] 4150 UNSPEC_BCD_ADD_SUB) 4151 (match_dup 4))) 4152 (clobber (match_scratch:V1TI 5))]) 4153 (set (match_operand:SI 0 "register_operand") 4154 (BCD_TEST:SI (reg:CCFP CR6_REGNO) 4155 (const_int 0)))] 4156 "TARGET_P8_VECTOR" 4157{ 4158 operands[4] = CONST0_RTX (V2DFmode); 4159}) 4160 4161;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and 4162;; the bcdadd/bcdsub that tests the value. The combiner won't work since 4163;; CR6 is a hard coded register. Unfortunately, all of the Altivec predicate 4164;; support is hard coded to use the fixed register CR6 instead of creating 4165;; a register class for CR6. 4166 4167(define_peephole2 4168 [(parallel [(set (match_operand:V1TI 0 "register_operand") 4169 (unspec:V1TI [(match_operand:V1TI 1 "register_operand") 4170 (match_operand:V1TI 2 "register_operand") 4171 (match_operand:QI 3 "const_0_to_1_operand")] 4172 UNSPEC_BCD_ADD_SUB)) 4173 (clobber (reg:CCFP CR6_REGNO))]) 4174 (parallel [(set (reg:CCFP CR6_REGNO) 4175 (compare:CCFP 4176 (unspec:V2DF [(match_dup 1) 4177 (match_dup 2) 4178 (match_dup 3)] 4179 UNSPEC_BCD_ADD_SUB) 4180 (match_operand:V2DF 4 "zero_constant"))) 4181 (clobber (match_operand:V1TI 5 "register_operand"))])] 4182 "TARGET_P8_VECTOR" 4183 [(parallel [(set (match_dup 0) 4184 (unspec:V1TI [(match_dup 1) 4185 (match_dup 2) 4186 (match_dup 3)] 4187 UNSPEC_BCD_ADD_SUB)) 4188 (set (reg:CCFP CR6_REGNO) 4189 (compare:CCFP 4190 (unspec:V2DF [(match_dup 1) 4191 (match_dup 2) 4192 (match_dup 3)] 4193 UNSPEC_BCD_ADD_SUB) 4194 (match_dup 4)))])]) 4195