1;; AltiVec patterns. 2;; Copyright (C) 2002-2019 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" "4,4,4,20,20,20,4,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,?wo") 2033 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") 2034 (match_operand:VM 2 "register_operand" "v,0") 2035 (match_operand:V16QI 3 "register_operand" "v,wo")] 2036 UNSPEC_VPERM))] 2037 "TARGET_ALTIVEC" 2038 "@ 2039 vperm %0,%1,%2,%3 2040 xxperm %x0,%x1,%x3" 2041 [(set_attr "type" "vecperm")]) 2042 2043(define_insn "altivec_vperm_v8hiv16qi" 2044 [(set (match_operand:V16QI 0 "register_operand" "=v,?wo") 2045 (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,wo") 2046 (match_operand:V8HI 2 "register_operand" "v,0") 2047 (match_operand:V16QI 3 "register_operand" "v,wo")] 2048 UNSPEC_VPERM))] 2049 "TARGET_ALTIVEC" 2050 "@ 2051 vperm %0,%1,%2,%3 2052 xxperm %x0,%x1,%x3" 2053 [(set_attr "type" "vecperm")]) 2054 2055(define_expand "altivec_vperm_<mode>_uns" 2056 [(set (match_operand:VM 0 "register_operand") 2057 (unspec:VM [(match_operand:VM 1 "register_operand") 2058 (match_operand:VM 2 "register_operand") 2059 (match_operand:V16QI 3 "register_operand")] 2060 UNSPEC_VPERM_UNS))] 2061 "TARGET_ALTIVEC" 2062{ 2063 if (!BYTES_BIG_ENDIAN) 2064 { 2065 altivec_expand_vec_perm_le (operands); 2066 DONE; 2067 } 2068}) 2069 2070(define_insn "*altivec_vperm_<mode>_uns_internal" 2071 [(set (match_operand:VM 0 "register_operand" "=v,?wo") 2072 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") 2073 (match_operand:VM 2 "register_operand" "v,0") 2074 (match_operand:V16QI 3 "register_operand" "v,wo")] 2075 UNSPEC_VPERM_UNS))] 2076 "TARGET_ALTIVEC" 2077 "@ 2078 vperm %0,%1,%2,%3 2079 xxperm %x0,%x1,%x3" 2080 [(set_attr "type" "vecperm")]) 2081 2082(define_expand "vec_permv16qi" 2083 [(set (match_operand:V16QI 0 "register_operand") 2084 (unspec:V16QI [(match_operand:V16QI 1 "register_operand") 2085 (match_operand:V16QI 2 "register_operand") 2086 (match_operand:V16QI 3 "register_operand")] 2087 UNSPEC_VPERM))] 2088 "TARGET_ALTIVEC" 2089{ 2090 if (!BYTES_BIG_ENDIAN) { 2091 altivec_expand_vec_perm_le (operands); 2092 DONE; 2093 } 2094}) 2095 2096(define_insn "*altivec_vpermr_<mode>_internal" 2097 [(set (match_operand:VM 0 "register_operand" "=v,?wo") 2098 (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") 2099 (match_operand:VM 2 "register_operand" "v,0") 2100 (match_operand:V16QI 3 "register_operand" "v,wo")] 2101 UNSPEC_VPERMR))] 2102 "TARGET_P9_VECTOR" 2103 "@ 2104 vpermr %0,%1,%2,%3 2105 xxpermr %x0,%x1,%x3" 2106 [(set_attr "type" "vecperm")]) 2107 2108(define_insn "altivec_vrfip" ; ceil 2109 [(set (match_operand:V4SF 0 "register_operand" "=v") 2110 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2111 UNSPEC_FRIP))] 2112 "TARGET_ALTIVEC" 2113 "vrfip %0,%1" 2114 [(set_attr "type" "vecfloat")]) 2115 2116(define_insn "altivec_vrfin" 2117 [(set (match_operand:V4SF 0 "register_operand" "=v") 2118 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2119 UNSPEC_VRFIN))] 2120 "TARGET_ALTIVEC" 2121 "vrfin %0,%1" 2122 [(set_attr "type" "vecfloat")]) 2123 2124(define_insn "*altivec_vrfim" ; floor 2125 [(set (match_operand:V4SF 0 "register_operand" "=v") 2126 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2127 UNSPEC_FRIM))] 2128 "TARGET_ALTIVEC" 2129 "vrfim %0,%1" 2130 [(set_attr "type" "vecfloat")]) 2131 2132(define_insn "altivec_vcfux" 2133 [(set (match_operand:V4SF 0 "register_operand" "=v") 2134 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") 2135 (match_operand:QI 2 "immediate_operand" "i")] 2136 UNSPEC_VCFUX))] 2137 "TARGET_ALTIVEC" 2138 "vcfux %0,%1,%2" 2139 [(set_attr "type" "vecfloat")]) 2140 2141(define_insn "altivec_vcfsx" 2142 [(set (match_operand:V4SF 0 "register_operand" "=v") 2143 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") 2144 (match_operand:QI 2 "immediate_operand" "i")] 2145 UNSPEC_VCFSX))] 2146 "TARGET_ALTIVEC" 2147 "vcfsx %0,%1,%2" 2148 [(set_attr "type" "vecfloat")]) 2149 2150(define_insn "altivec_vctuxs" 2151 [(set (match_operand:V4SI 0 "register_operand" "=v") 2152 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") 2153 (match_operand:QI 2 "immediate_operand" "i")] 2154 UNSPEC_VCTUXS)) 2155 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 2156 "TARGET_ALTIVEC" 2157 "vctuxs %0,%1,%2" 2158 [(set_attr "type" "vecfloat")]) 2159 2160(define_insn "altivec_vctsxs" 2161 [(set (match_operand:V4SI 0 "register_operand" "=v") 2162 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") 2163 (match_operand:QI 2 "immediate_operand" "i")] 2164 UNSPEC_VCTSXS)) 2165 (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] 2166 "TARGET_ALTIVEC" 2167 "vctsxs %0,%1,%2" 2168 [(set_attr "type" "vecfloat")]) 2169 2170(define_insn "altivec_vlogefp" 2171 [(set (match_operand:V4SF 0 "register_operand" "=v") 2172 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2173 UNSPEC_VLOGEFP))] 2174 "TARGET_ALTIVEC" 2175 "vlogefp %0,%1" 2176 [(set_attr "type" "vecfloat")]) 2177 2178(define_insn "altivec_vexptefp" 2179 [(set (match_operand:V4SF 0 "register_operand" "=v") 2180 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2181 UNSPEC_VEXPTEFP))] 2182 "TARGET_ALTIVEC" 2183 "vexptefp %0,%1" 2184 [(set_attr "type" "vecfloat")]) 2185 2186(define_insn "*altivec_vrsqrtefp" 2187 [(set (match_operand:V4SF 0 "register_operand" "=v") 2188 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2189 UNSPEC_RSQRT))] 2190 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2191 "vrsqrtefp %0,%1" 2192 [(set_attr "type" "vecfloat")]) 2193 2194(define_insn "altivec_vrefp" 2195 [(set (match_operand:V4SF 0 "register_operand" "=v") 2196 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 2197 UNSPEC_FRES))] 2198 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2199 "vrefp %0,%1" 2200 [(set_attr "type" "vecfloat")]) 2201 2202(define_expand "altivec_copysign_v4sf3" 2203 [(use (match_operand:V4SF 0 "register_operand")) 2204 (use (match_operand:V4SF 1 "register_operand")) 2205 (use (match_operand:V4SF 2 "register_operand"))] 2206 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2207{ 2208 rtx mask = gen_reg_rtx (V4SImode); 2209 rtvec v = rtvec_alloc (4); 2210 unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31; 2211 2212 RTVEC_ELT (v, 0) = GEN_INT (mask_val); 2213 RTVEC_ELT (v, 1) = GEN_INT (mask_val); 2214 RTVEC_ELT (v, 2) = GEN_INT (mask_val); 2215 RTVEC_ELT (v, 3) = GEN_INT (mask_val); 2216 2217 emit_insn (gen_vec_initv4sisi (mask, gen_rtx_PARALLEL (V4SImode, v))); 2218 emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2], 2219 gen_lowpart (V4SFmode, mask))); 2220 DONE; 2221}) 2222 2223(define_insn "altivec_vsldoi_<mode>" 2224 [(set (match_operand:VM 0 "register_operand" "=v") 2225 (unspec:VM [(match_operand:VM 1 "register_operand" "v") 2226 (match_operand:VM 2 "register_operand" "v") 2227 (match_operand:QI 3 "immediate_operand" "i")] 2228 UNSPEC_VSLDOI))] 2229 "TARGET_ALTIVEC" 2230 "vsldoi %0,%1,%2,%3" 2231 [(set_attr "type" "vecperm")]) 2232 2233(define_insn "altivec_vupkhs<VU_char>" 2234 [(set (match_operand:VP 0 "register_operand" "=v") 2235 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 2236 UNSPEC_VUNPACK_HI_SIGN))] 2237 "<VI_unit>" 2238{ 2239 if (BYTES_BIG_ENDIAN) 2240 return "vupkhs<VU_char> %0,%1"; 2241 else 2242 return "vupkls<VU_char> %0,%1"; 2243} 2244 [(set_attr "type" "vecperm")]) 2245 2246(define_insn "*altivec_vupkhs<VU_char>_direct" 2247 [(set (match_operand:VP 0 "register_operand" "=v") 2248 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 2249 UNSPEC_VUNPACK_HI_SIGN_DIRECT))] 2250 "<VI_unit>" 2251 "vupkhs<VU_char> %0,%1" 2252 [(set_attr "type" "vecperm")]) 2253 2254(define_insn "altivec_vupkls<VU_char>" 2255 [(set (match_operand:VP 0 "register_operand" "=v") 2256 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 2257 UNSPEC_VUNPACK_LO_SIGN))] 2258 "<VI_unit>" 2259{ 2260 if (BYTES_BIG_ENDIAN) 2261 return "vupkls<VU_char> %0,%1"; 2262 else 2263 return "vupkhs<VU_char> %0,%1"; 2264} 2265 [(set_attr "type" "vecperm")]) 2266 2267(define_insn "*altivec_vupkls<VU_char>_direct" 2268 [(set (match_operand:VP 0 "register_operand" "=v") 2269 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 2270 UNSPEC_VUNPACK_LO_SIGN_DIRECT))] 2271 "<VI_unit>" 2272 "vupkls<VU_char> %0,%1" 2273 [(set_attr "type" "vecperm")]) 2274 2275(define_insn "altivec_vupkhpx" 2276 [(set (match_operand:V4SI 0 "register_operand" "=v") 2277 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 2278 UNSPEC_VUPKHPX))] 2279 "TARGET_ALTIVEC" 2280{ 2281 if (BYTES_BIG_ENDIAN) 2282 return "vupkhpx %0,%1"; 2283 else 2284 return "vupklpx %0,%1"; 2285} 2286 [(set_attr "type" "vecperm")]) 2287 2288(define_insn "altivec_vupklpx" 2289 [(set (match_operand:V4SI 0 "register_operand" "=v") 2290 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 2291 UNSPEC_VUPKLPX))] 2292 "TARGET_ALTIVEC" 2293{ 2294 if (BYTES_BIG_ENDIAN) 2295 return "vupklpx %0,%1"; 2296 else 2297 return "vupkhpx %0,%1"; 2298} 2299 [(set_attr "type" "vecperm")]) 2300 2301;; Compare vectors producing a vector result and a predicate, setting CR6 to 2302;; indicate a combined status 2303(define_insn "altivec_vcmpequ<VI_char>_p" 2304 [(set (reg:CC CR6_REGNO) 2305 (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v") 2306 (match_operand:VI2 2 "register_operand" "v"))] 2307 UNSPEC_PREDICATE)) 2308 (set (match_operand:VI2 0 "register_operand" "=v") 2309 (eq:VI2 (match_dup 1) 2310 (match_dup 2)))] 2311 "<VI_unit>" 2312 "vcmpequ<VI_char>. %0,%1,%2" 2313 [(set_attr "type" "veccmpfx")]) 2314 2315(define_insn "*altivec_vcmpgts<VI_char>_p" 2316 [(set (reg:CC CR6_REGNO) 2317 (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v") 2318 (match_operand:VI2 2 "register_operand" "v"))] 2319 UNSPEC_PREDICATE)) 2320 (set (match_operand:VI2 0 "register_operand" "=v") 2321 (gt:VI2 (match_dup 1) 2322 (match_dup 2)))] 2323 "<VI_unit>" 2324 "vcmpgts<VI_char>. %0,%1,%2" 2325 [(set_attr "type" "veccmpfx")]) 2326 2327(define_insn "*altivec_vcmpgtu<VI_char>_p" 2328 [(set (reg:CC CR6_REGNO) 2329 (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v") 2330 (match_operand:VI2 2 "register_operand" "v"))] 2331 UNSPEC_PREDICATE)) 2332 (set (match_operand:VI2 0 "register_operand" "=v") 2333 (gtu:VI2 (match_dup 1) 2334 (match_dup 2)))] 2335 "<VI_unit>" 2336 "vcmpgtu<VI_char>. %0,%1,%2" 2337 [(set_attr "type" "veccmpfx")]) 2338 2339(define_insn "*altivec_vcmpeqfp_p" 2340 [(set (reg:CC CR6_REGNO) 2341 (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v") 2342 (match_operand:V4SF 2 "register_operand" "v"))] 2343 UNSPEC_PREDICATE)) 2344 (set (match_operand:V4SF 0 "register_operand" "=v") 2345 (eq:V4SF (match_dup 1) 2346 (match_dup 2)))] 2347 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2348 "vcmpeqfp. %0,%1,%2" 2349 [(set_attr "type" "veccmp")]) 2350 2351(define_insn "*altivec_vcmpgtfp_p" 2352 [(set (reg:CC CR6_REGNO) 2353 (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v") 2354 (match_operand:V4SF 2 "register_operand" "v"))] 2355 UNSPEC_PREDICATE)) 2356 (set (match_operand:V4SF 0 "register_operand" "=v") 2357 (gt:V4SF (match_dup 1) 2358 (match_dup 2)))] 2359 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2360 "vcmpgtfp. %0,%1,%2" 2361 [(set_attr "type" "veccmp")]) 2362 2363(define_insn "*altivec_vcmpgefp_p" 2364 [(set (reg:CC CR6_REGNO) 2365 (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v") 2366 (match_operand:V4SF 2 "register_operand" "v"))] 2367 UNSPEC_PREDICATE)) 2368 (set (match_operand:V4SF 0 "register_operand" "=v") 2369 (ge:V4SF (match_dup 1) 2370 (match_dup 2)))] 2371 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" 2372 "vcmpgefp. %0,%1,%2" 2373 [(set_attr "type" "veccmp")]) 2374 2375(define_insn "altivec_vcmpbfp_p" 2376 [(set (reg:CC CR6_REGNO) 2377 (unspec:CC [(match_operand:V4SF 1 "register_operand" "v") 2378 (match_operand:V4SF 2 "register_operand" "v")] 2379 UNSPEC_VCMPBFP)) 2380 (set (match_operand:V4SF 0 "register_operand" "=v") 2381 (unspec:V4SF [(match_dup 1) 2382 (match_dup 2)] 2383 UNSPEC_VCMPBFP))] 2384 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" 2385 "vcmpbfp. %0,%1,%2" 2386 [(set_attr "type" "veccmp")]) 2387 2388(define_insn "altivec_mtvscr" 2389 [(set (reg:SI VSCR_REGNO) 2390 (unspec_volatile:SI 2391 [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))] 2392 "TARGET_ALTIVEC" 2393 "mtvscr %0" 2394 [(set_attr "type" "vecsimple")]) 2395 2396(define_insn "altivec_mfvscr" 2397 [(set (match_operand:V8HI 0 "register_operand" "=v") 2398 (unspec_volatile:V8HI [(reg:SI VSCR_REGNO)] UNSPECV_MFVSCR))] 2399 "TARGET_ALTIVEC" 2400 "mfvscr %0" 2401 [(set_attr "type" "vecsimple")]) 2402 2403(define_insn "altivec_dssall" 2404 [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)] 2405 "TARGET_ALTIVEC" 2406 "dssall" 2407 [(set_attr "type" "vecsimple")]) 2408 2409(define_insn "altivec_dss" 2410 [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")] 2411 UNSPECV_DSS)] 2412 "TARGET_ALTIVEC" 2413 "dss %0" 2414 [(set_attr "type" "vecsimple")]) 2415 2416(define_insn "altivec_dst" 2417 [(unspec [(match_operand 0 "register_operand" "b") 2418 (match_operand:SI 1 "register_operand" "r") 2419 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)] 2420 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" 2421 "dst %0,%1,%2" 2422 [(set_attr "type" "vecsimple")]) 2423 2424(define_insn "altivec_dstt" 2425 [(unspec [(match_operand 0 "register_operand" "b") 2426 (match_operand:SI 1 "register_operand" "r") 2427 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)] 2428 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" 2429 "dstt %0,%1,%2" 2430 [(set_attr "type" "vecsimple")]) 2431 2432(define_insn "altivec_dstst" 2433 [(unspec [(match_operand 0 "register_operand" "b") 2434 (match_operand:SI 1 "register_operand" "r") 2435 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)] 2436 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" 2437 "dstst %0,%1,%2" 2438 [(set_attr "type" "vecsimple")]) 2439 2440(define_insn "altivec_dststt" 2441 [(unspec [(match_operand 0 "register_operand" "b") 2442 (match_operand:SI 1 "register_operand" "r") 2443 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)] 2444 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" 2445 "dststt %0,%1,%2" 2446 [(set_attr "type" "vecsimple")]) 2447 2448(define_expand "altivec_lvsl" 2449 [(use (match_operand:V16QI 0 "register_operand")) 2450 (use (match_operand:V16QI 1 "memory_operand"))] 2451 "TARGET_ALTIVEC" 2452{ 2453 if (BYTES_BIG_ENDIAN) 2454 emit_insn (gen_altivec_lvsl_direct (operands[0], operands[1])); 2455 else 2456 { 2457 rtx mask, constv, vperm; 2458 mask = gen_reg_rtx (V16QImode); 2459 emit_insn (gen_altivec_lvsl_direct (mask, operands[1])); 2460 constv = gen_const_vec_series (V16QImode, const0_rtx, const1_rtx); 2461 constv = force_reg (V16QImode, constv); 2462 vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv), 2463 UNSPEC_VPERM); 2464 emit_insn (gen_rtx_SET (operands[0], vperm)); 2465 } 2466 DONE; 2467}) 2468 2469(define_insn "altivec_lvsl_reg" 2470 [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") 2471 (unspec:V16QI 2472 [(match_operand:DI 1 "gpc_reg_operand" "b")] 2473 UNSPEC_LVSL_REG))] 2474 "TARGET_ALTIVEC" 2475 "lvsl %0,0,%1" 2476 [(set_attr "type" "vecload")]) 2477 2478(define_insn "altivec_lvsl_direct" 2479 [(set (match_operand:V16QI 0 "register_operand" "=v") 2480 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] 2481 UNSPEC_LVSL))] 2482 "TARGET_ALTIVEC" 2483 "lvsl %0,%y1" 2484 [(set_attr "type" "vecload")]) 2485 2486(define_expand "altivec_lvsr" 2487 [(use (match_operand:V16QI 0 "altivec_register_operand")) 2488 (use (match_operand:V16QI 1 "memory_operand"))] 2489 "TARGET_ALTIVEC" 2490{ 2491 if (BYTES_BIG_ENDIAN) 2492 emit_insn (gen_altivec_lvsr_direct (operands[0], operands[1])); 2493 else 2494 { 2495 rtx mask, constv, vperm; 2496 mask = gen_reg_rtx (V16QImode); 2497 emit_insn (gen_altivec_lvsr_direct (mask, operands[1])); 2498 constv = gen_const_vec_series (V16QImode, const0_rtx, const1_rtx); 2499 constv = force_reg (V16QImode, constv); 2500 vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv), 2501 UNSPEC_VPERM); 2502 emit_insn (gen_rtx_SET (operands[0], vperm)); 2503 } 2504 DONE; 2505}) 2506 2507(define_insn "altivec_lvsr_reg" 2508 [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") 2509 (unspec:V16QI 2510 [(match_operand:DI 1 "gpc_reg_operand" "b")] 2511 UNSPEC_LVSR_REG))] 2512 "TARGET_ALTIVEC" 2513 "lvsr %0,0,%1" 2514 [(set_attr "type" "vecload")]) 2515 2516(define_insn "altivec_lvsr_direct" 2517 [(set (match_operand:V16QI 0 "register_operand" "=v") 2518 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] 2519 UNSPEC_LVSR))] 2520 "TARGET_ALTIVEC" 2521 "lvsr %0,%y1" 2522 [(set_attr "type" "vecload")]) 2523 2524(define_expand "build_vector_mask_for_load" 2525 [(set (match_operand:V16QI 0 "register_operand") 2526 (unspec:V16QI [(match_operand 1 "memory_operand")] UNSPEC_LVSR))] 2527 "TARGET_ALTIVEC" 2528{ 2529 rtx addr; 2530 rtx temp; 2531 2532 gcc_assert (MEM_P (operands[1])); 2533 2534 addr = XEXP (operands[1], 0); 2535 temp = gen_reg_rtx (GET_MODE (addr)); 2536 emit_insn (gen_rtx_SET (temp, gen_rtx_NEG (GET_MODE (addr), addr))); 2537 emit_insn (gen_altivec_lvsr (operands[0], 2538 replace_equiv_address (operands[1], temp))); 2539 DONE; 2540}) 2541 2542;; Parallel some of the LVE* and STV*'s with unspecs because some have 2543;; identical rtl but different instructions-- and gcc gets confused. 2544 2545(define_insn "altivec_lve<VI_char>x" 2546 [(parallel 2547 [(set (match_operand:VI 0 "register_operand" "=v") 2548 (match_operand:VI 1 "memory_operand" "Z")) 2549 (unspec [(const_int 0)] UNSPEC_LVE)])] 2550 "TARGET_ALTIVEC" 2551 "lve<VI_char>x %0,%y1" 2552 [(set_attr "type" "vecload")]) 2553 2554(define_insn "*altivec_lvesfx" 2555 [(parallel 2556 [(set (match_operand:V4SF 0 "register_operand" "=v") 2557 (match_operand:V4SF 1 "memory_operand" "Z")) 2558 (unspec [(const_int 0)] UNSPEC_LVE)])] 2559 "TARGET_ALTIVEC" 2560 "lvewx %0,%y1" 2561 [(set_attr "type" "vecload")]) 2562 2563(define_insn "altivec_lvxl_<mode>" 2564 [(parallel 2565 [(set (match_operand:VM2 0 "register_operand" "=v") 2566 (match_operand:VM2 1 "memory_operand" "Z")) 2567 (unspec [(const_int 0)] UNSPEC_SET_VSCR)])] 2568 "TARGET_ALTIVEC" 2569 "lvxl %0,%y1" 2570 [(set_attr "type" "vecload")]) 2571 2572; This version of lvx is used only in cases where we need to force an lvx 2573; over any other load, and we don't care about losing CSE opportunities. 2574; Its primary use is for prologue register saves. 2575(define_insn "altivec_lvx_<mode>_internal" 2576 [(parallel 2577 [(set (match_operand:VM2 0 "register_operand" "=v") 2578 (match_operand:VM2 1 "memory_operand" "Z")) 2579 (unspec [(const_int 0)] UNSPEC_LVX)])] 2580 "TARGET_ALTIVEC" 2581 "lvx %0,%y1" 2582 [(set_attr "type" "vecload")]) 2583 2584; The following patterns embody what lvx should usually look like. 2585(define_expand "altivec_lvx_<VM2:mode>" 2586 [(set (match_operand:VM2 0 "register_operand") 2587 (match_operand:VM2 1 "altivec_indexed_or_indirect_operand"))] 2588 "TARGET_ALTIVEC" 2589{ 2590 rtx addr = XEXP (operand1, 0); 2591 if (rs6000_sum_of_two_registers_p (addr)) 2592 { 2593 rtx op1 = XEXP (addr, 0); 2594 rtx op2 = XEXP (addr, 1); 2595 if (TARGET_64BIT) 2596 emit_insn (gen_altivec_lvx_<VM2:mode>_2op_di (operand0, op1, op2)); 2597 else 2598 emit_insn (gen_altivec_lvx_<VM2:mode>_2op_si (operand0, op1, op2)); 2599 } 2600 else 2601 { 2602 if (TARGET_64BIT) 2603 emit_insn (gen_altivec_lvx_<VM2:mode>_1op_di (operand0, addr)); 2604 else 2605 emit_insn (gen_altivec_lvx_<VM2:mode>_1op_si (operand0, addr)); 2606 } 2607 DONE; 2608}) 2609 2610; The next two patterns embody what lvx should usually look like. 2611(define_insn "altivec_lvx_<VM2:mode>_2op_<P:mptrsize>" 2612 [(set (match_operand:VM2 0 "register_operand" "=v") 2613 (mem:VM2 (and:P (plus:P (match_operand:P 1 "register_operand" "b") 2614 (match_operand:P 2 "register_operand" "r")) 2615 (const_int -16))))] 2616 "TARGET_ALTIVEC" 2617 "lvx %0,%1,%2" 2618 [(set_attr "type" "vecload")]) 2619 2620(define_insn "altivec_lvx_<VM2:mode>_1op_<P:mptrsize>" 2621 [(set (match_operand:VM2 0 "register_operand" "=v") 2622 (mem:VM2 (and:P (match_operand:P 1 "register_operand" "r") 2623 (const_int -16))))] 2624 "TARGET_ALTIVEC" 2625 "lvx %0,0,%1" 2626 [(set_attr "type" "vecload")]) 2627 2628; This version of stvx is used only in cases where we need to force an stvx 2629; over any other store, and we don't care about losing CSE opportunities. 2630; Its primary use is for epilogue register restores. 2631(define_insn "altivec_stvx_<mode>_internal" 2632 [(parallel 2633 [(set (match_operand:VM2 0 "memory_operand" "=Z") 2634 (match_operand:VM2 1 "register_operand" "v")) 2635 (unspec [(const_int 0)] UNSPEC_STVX)])] 2636 "TARGET_ALTIVEC" 2637 "stvx %1,%y0" 2638 [(set_attr "type" "vecstore")]) 2639 2640; The following patterns embody what stvx should usually look like. 2641(define_expand "altivec_stvx_<VM2:mode>" 2642 [(set (match_operand:VM2 1 "altivec_indexed_or_indirect_operand") 2643 (match_operand:VM2 0 "register_operand"))] 2644 "TARGET_ALTIVEC" 2645{ 2646 rtx addr = XEXP (operand1, 0); 2647 if (rs6000_sum_of_two_registers_p (addr)) 2648 { 2649 rtx op1 = XEXP (addr, 0); 2650 rtx op2 = XEXP (addr, 1); 2651 if (TARGET_64BIT) 2652 emit_insn (gen_altivec_stvx_<VM2:mode>_2op_di (operand0, op1, op2)); 2653 else 2654 emit_insn (gen_altivec_stvx_<VM2:mode>_2op_si (operand0, op1, op2)); 2655 } 2656 else 2657 { 2658 if (TARGET_64BIT) 2659 emit_insn (gen_altivec_stvx_<VM2:mode>_1op_di (operand0, addr)); 2660 else 2661 emit_insn (gen_altivec_stvx_<VM2:mode>_1op_si (operand0, addr)); 2662 } 2663 DONE; 2664}) 2665 2666; The next two patterns embody what stvx should usually look like. 2667(define_insn "altivec_stvx_<VM2:mode>_2op_<P:mptrsize>" 2668 [(set (mem:VM2 (and:P (plus:P (match_operand:P 1 "register_operand" "b") 2669 (match_operand:P 2 "register_operand" "r")) 2670 (const_int -16))) 2671 (match_operand:VM2 0 "register_operand" "v"))] 2672 "TARGET_ALTIVEC" 2673 "stvx %0,%1,%2" 2674 [(set_attr "type" "vecstore")]) 2675 2676(define_insn "altivec_stvx_<VM2:mode>_1op_<P:mptrsize>" 2677 [(set (mem:VM2 (and:P (match_operand:P 1 "register_operand" "r") 2678 (const_int -16))) 2679 (match_operand:VM2 0 "register_operand" "v"))] 2680 "TARGET_ALTIVEC" 2681 "stvx %0,0,%1" 2682 [(set_attr "type" "vecstore")]) 2683 2684(define_insn "altivec_stvxl_<mode>" 2685 [(parallel 2686 [(set (match_operand:VM2 0 "memory_operand" "=Z") 2687 (match_operand:VM2 1 "register_operand" "v")) 2688 (unspec [(const_int 0)] UNSPEC_STVXL)])] 2689 "TARGET_ALTIVEC" 2690 "stvxl %1,%y0" 2691 [(set_attr "type" "vecstore")]) 2692 2693(define_insn "altivec_stve<VI_char>x" 2694 [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z") 2695 (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))] 2696 "TARGET_ALTIVEC" 2697 "stve<VI_char>x %1,%y0" 2698 [(set_attr "type" "vecstore")]) 2699 2700(define_insn "*altivec_stvesfx" 2701 [(set (match_operand:SF 0 "memory_operand" "=Z") 2702 (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))] 2703 "TARGET_ALTIVEC" 2704 "stvewx %1,%y0" 2705 [(set_attr "type" "vecstore")]) 2706 2707;; Generate doublee 2708;; signed int/float to double convert words 0 and 2 2709(define_expand "doublee<mode>2" 2710 [(set (match_operand:V2DF 0 "register_operand" "=v") 2711 (match_operand:VSX_W 1 "register_operand" "v"))] 2712 "TARGET_VSX" 2713{ 2714 machine_mode op_mode = GET_MODE (operands[1]); 2715 2716 if (BYTES_BIG_ENDIAN) 2717 { 2718 /* Big endian word numbering for words in operand is 0 1 2 3. 2719 Input words 0 and 2 are where they need to be. */ 2720 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], operands[1])); 2721 } 2722 else 2723 { 2724 /* Little endian word numbering for operand is 3 2 1 0. 2725 take (operand[1] operand[1]) and shift left one word 2726 3 2 1 0 3 2 1 0 => 2 1 0 3 2727 Input words 2 and 0 are now where they need to be for the 2728 conversion. */ 2729 rtx rtx_tmp; 2730 rtx rtx_val = GEN_INT (1); 2731 2732 rtx_tmp = gen_reg_rtx (op_mode); 2733 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2734 operands[1], rtx_val)); 2735 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2736 } 2737 DONE; 2738} 2739 [(set_attr "type" "veccomplex")]) 2740 2741;; Generate unsdoublee 2742;; unsigned int to double convert words 0 and 2 2743(define_expand "unsdoubleev4si2" 2744 [(set (match_operand:V2DF 0 "register_operand" "=v") 2745 (match_operand:V4SI 1 "register_operand" "v"))] 2746 "TARGET_VSX" 2747{ 2748 if (BYTES_BIG_ENDIAN) 2749 { 2750 /* Big endian word numbering for words in operand is 0 1 2 3. 2751 Input words 0 and 2 are where they need to be. */ 2752 emit_insn (gen_vsx_xvcvuxwdp (operands[0], operands[1])); 2753 } 2754 else 2755 { 2756 /* Little endian word numbering for operand is 3 2 1 0. 2757 take (operand[1] operand[1]) and shift left one word 2758 3 2 1 0 3 2 1 0 => 2 1 0 3 2759 Input words 2 and 0 are now where they need to be for the 2760 conversion. */ 2761 rtx rtx_tmp; 2762 rtx rtx_val = GEN_INT (1); 2763 2764 rtx_tmp = gen_reg_rtx (V4SImode); 2765 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2766 operands[1], rtx_val)); 2767 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 2768 } 2769 DONE; 2770} 2771 [(set_attr "type" "veccomplex")]) 2772 2773;; Generate doubleov 2774;; signed int/float to double convert words 1 and 3 2775(define_expand "doubleo<mode>2" 2776 [(set (match_operand:V2DF 0 "register_operand" "=v") 2777 (match_operand:VSX_W 1 "register_operand" "v"))] 2778 "TARGET_VSX" 2779{ 2780 machine_mode op_mode = GET_MODE (operands[1]); 2781 2782 if (BYTES_BIG_ENDIAN) 2783 { 2784 /* Big endian word numbering for words in operand is 0 1 2 3. 2785 take (operand[1] operand[1]) and shift left one word 2786 0 1 2 3 0 1 2 3 => 1 2 3 0 2787 Input words 1 and 3 are now where they need to be for the 2788 conversion. */ 2789 rtx rtx_tmp; 2790 rtx rtx_val = GEN_INT (1); 2791 2792 rtx_tmp = gen_reg_rtx (op_mode); 2793 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2794 operands[1], rtx_val)); 2795 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2796 } 2797 else 2798 { 2799 /* Little endian word numbering for operand is 3 2 1 0. 2800 Input words 3 and 1 are where they need to be. */ 2801 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], operands[1])); 2802 } 2803 DONE; 2804} 2805 [(set_attr "type" "veccomplex")]) 2806 2807;; Generate unsdoubleov 2808;; unsigned int to double convert words 1 and 3 2809(define_expand "unsdoubleov4si2" 2810 [(set (match_operand:V2DF 0 "register_operand" "=v") 2811 (match_operand:V4SI 1 "register_operand" "v"))] 2812 "TARGET_VSX" 2813{ 2814 if (BYTES_BIG_ENDIAN) 2815 { 2816 /* Big endian word numbering for words in operand is 0 1 2 3. 2817 take (operand[1] operand[1]) and shift left one word 2818 0 1 2 3 0 1 2 3 => 1 2 3 0 2819 Input words 1 and 3 are now where they need to be for the 2820 conversion. */ 2821 rtx rtx_tmp; 2822 rtx rtx_val = GEN_INT (1); 2823 2824 rtx_tmp = gen_reg_rtx (V4SImode); 2825 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2826 operands[1], rtx_val)); 2827 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 2828 } 2829 else 2830 { 2831 /* Want to convert the words 1 and 3. 2832 Little endian word numbering for operand is 3 2 1 0. 2833 Input words 3 and 1 are where they need to be. */ 2834 emit_insn (gen_vsx_xvcvuxwdp (operands[0], operands[1])); 2835 } 2836 DONE; 2837} 2838 [(set_attr "type" "veccomplex")]) 2839 2840;; Generate doublehv 2841;; signed int/float to double convert words 0 and 1 2842(define_expand "doubleh<mode>2" 2843 [(set (match_operand:V2DF 0 "register_operand" "=v") 2844 (match_operand:VSX_W 1 "register_operand" "v"))] 2845 "TARGET_VSX" 2846{ 2847 rtx rtx_tmp; 2848 rtx rtx_val; 2849 2850 machine_mode op_mode = GET_MODE (operands[1]); 2851 rtx_tmp = gen_reg_rtx (op_mode); 2852 2853 if (BYTES_BIG_ENDIAN) 2854 { 2855 /* Big endian word numbering for words in operand is 0 1 2 3. 2856 Shift operand left one word, rtx_tmp word order is now 1 2 3 0. 2857 take (rts_tmp operand[1]) and shift left three words 2858 1 2 3 0 0 1 2 3 => 0 0 1 2 2859 Input words 0 and 1 are now where they need to be for the 2860 conversion. */ 2861 rtx_val = GEN_INT (1); 2862 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2863 operands[1], rtx_val)); 2864 2865 rtx_val = GEN_INT (3); 2866 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, rtx_tmp, 2867 operands[1], rtx_val)); 2868 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2869 } 2870 else 2871 { 2872 /* Little endian word numbering for operand is 3 2 1 0. 2873 Shift operand left three words, rtx_tmp word order is now 0 3 2 1. 2874 take (operand[1] rts_tmp) and shift left two words 2875 3 2 1 0 0 3 2 1 => 1 0 0 3 2876 Input words 0 and 1 are now where they need to be for the 2877 conversion. */ 2878 rtx_val = GEN_INT (3); 2879 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2880 operands[1], rtx_val)); 2881 2882 rtx_val = GEN_INT (2); 2883 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2884 rtx_tmp, rtx_val)); 2885 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2886 } 2887 DONE; 2888} 2889 [(set_attr "type" "veccomplex")]) 2890 2891;; Generate unsdoublehv 2892;; unsigned int to double convert words 0 and 1 2893(define_expand "unsdoublehv4si2" 2894 [(set (match_operand:V2DF 0 "register_operand" "=v") 2895 (match_operand:V4SI 1 "register_operand" "v"))] 2896 "TARGET_VSX" 2897{ 2898 rtx rtx_tmp = gen_reg_rtx (V4SImode); 2899 rtx rtx_val = GEN_INT (12); 2900 2901 if (BYTES_BIG_ENDIAN) 2902 { 2903 /* Big endian word numbering for words in operand is 0 1 2 3. 2904 Shift operand left one word, rtx_tmp word order is now 1 2 3 0. 2905 take (rts_tmp operand[1]) and shift left three words 2906 1 2 3 0 0 1 2 3 => 0 0 1 2 2907 Input words 0 and 1 are now where they need to be for the 2908 conversion. */ 2909 rtx_val = GEN_INT (1); 2910 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2911 operands[1], rtx_val)); 2912 2913 rtx_val = GEN_INT (3); 2914 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, rtx_tmp, 2915 operands[1], rtx_val)); 2916 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 2917 } 2918 else 2919 { 2920 /* Little endian word numbering for operand is 3 2 1 0. 2921 Shift operand left three words, rtx_tmp word order is now 0 3 2 1. 2922 take (operand[1] rts_tmp) and shift left two words 2923 3 2 1 0 0 3 2 1 => 1 0 0 3 2924 Input words 1 and 0 are now where they need to be for the 2925 conversion. */ 2926 rtx_val = GEN_INT (3); 2927 2928 rtx_tmp = gen_reg_rtx (V4SImode); 2929 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2930 operands[1], rtx_val)); 2931 2932 rtx_val = GEN_INT (2); 2933 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 2934 rtx_tmp, rtx_val)); 2935 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 2936 } 2937 DONE; 2938} 2939 [(set_attr "type" "veccomplex")]) 2940 2941;; Generate doublelv 2942;; signed int/float to double convert words 2 and 3 2943(define_expand "doublel<mode>2" 2944 [(set (match_operand:V2DF 0 "register_operand" "=v") 2945 (match_operand:VSX_W 1 "register_operand" "v"))] 2946 "TARGET_VSX" 2947{ 2948 rtx rtx_tmp; 2949 rtx rtx_val = GEN_INT (3); 2950 2951 machine_mode op_mode = GET_MODE (operands[1]); 2952 rtx_tmp = gen_reg_rtx (op_mode); 2953 2954 if (BYTES_BIG_ENDIAN) 2955 { 2956 /* Big endian word numbering for operand is 0 1 2 3. 2957 Shift operand left three words, rtx_tmp word order is now 3 0 1 2. 2958 take (operand[1] rtx_tmp) and shift left two words 2959 0 1 2 3 3 0 1 2 => 2 3 3 0 2960 now use convert instruction to convert word 2 and 3 in the 2961 input vector. */ 2962 rtx_val = GEN_INT (3); 2963 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2964 operands[1], rtx_val)); 2965 2966 rtx_val = GEN_INT (2); 2967 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2968 rtx_tmp, rtx_val)); 2969 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2970 } 2971 else 2972 { 2973 /* Little endian word numbering for operand is 3 2 1 0. 2974 Shift operand left one word, rtx_tmp word order is now 2 1 0 3. 2975 take (rtx_tmp operand[1]) and shift left three words 2976 2 1 0 3 3 2 1 0 => 3 3 2 1 2977 now use convert instruction to convert word 3 and 2 in the 2978 input vector. */ 2979 rtx_val = GEN_INT (1); 2980 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1], 2981 operands[1], rtx_val)); 2982 2983 rtx_val = GEN_INT (3); 2984 emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, rtx_tmp, 2985 operands[1], rtx_val)); 2986 emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp)); 2987 } 2988 DONE; 2989} 2990 [(set_attr "type" "veccomplex")]) 2991 2992;; Generate unsdoublelv 2993;; unsigned int to double convert convert 2 and 3 2994(define_expand "unsdoublelv4si2" 2995 [(set (match_operand:V2DF 0 "register_operand" "=v") 2996 (match_operand:V4SI 1 "register_operand" "v"))] 2997 "TARGET_VSX" 2998{ 2999 rtx rtx_tmp = gen_reg_rtx (V4SImode); 3000 rtx rtx_val = GEN_INT (12); 3001 3002 if (BYTES_BIG_ENDIAN) 3003 { 3004 /* Big endian word numbering for operand is 0 1 2 3. 3005 Shift operand left three words, rtx_tmp word order is now 3 0 1 2. 3006 take (operand[1] rtx_tmp) and shift left two words 3007 0 1 2 3 3 0 1 2 => 2 3 3 0 3008 now use convert instruction to convert word 2 and 3 in the 3009 input vector. */ 3010 rtx_val = GEN_INT (3); 3011 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 3012 operands[1], rtx_val)); 3013 3014 rtx_val = GEN_INT (2); 3015 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1], 3016 rtx_tmp, rtx_val)); 3017 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 3018 } 3019 else 3020 { 3021 /* Little endian word numbering for operand is 3 2 1 0. 3022 Shift operand left one word, rtx_tmp word order is now 2 1 0 3. 3023 take (rtx_tmp operand[1]) and shift left three words 3024 2 1 0 3 3 2 1 0 => 3 3 2 1 3025 now use convert instruction to convert word 3 and 2 in the 3026 input vector. */ 3027 rtx_val = GEN_INT (1); 3028 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, 3029 operands[1], operands[1], rtx_val)); 3030 3031 rtx_val = GEN_INT (3); 3032 emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, rtx_tmp, 3033 operands[1], rtx_val)); 3034 emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp)); 3035 } 3036 DONE; 3037} 3038 [(set_attr "type" "veccomplex")]) 3039 3040;; Generate two vector F32 converted to packed vector I16 vector 3041(define_expand "convert_4f32_8i16" 3042 [(set (match_operand:V8HI 0 "register_operand" "=v") 3043 (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "v") 3044 (match_operand:V4SF 2 "register_operand" "v")] 3045 UNSPEC_CONVERT_4F32_8I16))] 3046 "TARGET_P9_VECTOR" 3047{ 3048 rtx rtx_tmp_hi = gen_reg_rtx (V4SImode); 3049 rtx rtx_tmp_lo = gen_reg_rtx (V4SImode); 3050 3051 emit_insn (gen_altivec_vctuxs (rtx_tmp_hi, operands[1], const0_rtx)); 3052 emit_insn (gen_altivec_vctuxs (rtx_tmp_lo, operands[2], const0_rtx)); 3053 emit_insn (gen_altivec_vpkswss (operands[0], rtx_tmp_hi, rtx_tmp_lo)); 3054 DONE; 3055}) 3056 3057;; Convert two vector F32 to packed vector F16. 3058;; This builtin packs 32-bit floating-point values into a packed 3059;; 16-bit floating point values (stored in 16bit integer type). 3060;; (vector unsigned short r = vec_pack_to_short_fp32 (a, b); 3061;; The expected codegen for this builtin is 3062;; xvcvsphp t, a 3063;; xvcvsphp u, b 3064;; if (little endian) 3065;; vpkuwum r, t, u 3066;; else 3067;; vpkuwum r, u, t 3068 3069(define_expand "convert_4f32_8f16" 3070 [(set (match_operand:V8HI 0 "register_operand" "=v") 3071 (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "v") 3072 (match_operand:V4SF 2 "register_operand" "v")] 3073 UNSPEC_CONVERT_4F32_8F16))] 3074 "TARGET_P9_VECTOR" 3075{ 3076 rtx rtx_tmp_hi = gen_reg_rtx (V4SImode); 3077 rtx rtx_tmp_lo = gen_reg_rtx (V4SImode); 3078 3079 emit_insn (gen_vsx_xvcvsphp (rtx_tmp_hi, operands[1])); 3080 emit_insn (gen_vsx_xvcvsphp (rtx_tmp_lo, operands[2])); 3081 if (!BYTES_BIG_ENDIAN) 3082 emit_insn (gen_altivec_vpkuwum (operands[0], rtx_tmp_hi, rtx_tmp_lo)); 3083 else 3084 emit_insn (gen_altivec_vpkuwum (operands[0], rtx_tmp_lo, rtx_tmp_hi)); 3085 DONE; 3086}) 3087 3088;; Generate 3089;; xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0 3090;; vsubu?m SCRATCH2,SCRATCH1,%1 3091;; vmaxs? %0,%1,SCRATCH2" 3092(define_expand "abs<mode>2" 3093 [(set (match_dup 2) (match_dup 3)) 3094 (set (match_dup 4) 3095 (minus:VI2 (match_dup 2) 3096 (match_operand:VI2 1 "register_operand" "v"))) 3097 (set (match_operand:VI2 0 "register_operand" "=v") 3098 (smax:VI2 (match_dup 1) (match_dup 4)))] 3099 "<VI_unit>" 3100{ 3101 operands[2] = gen_reg_rtx (<MODE>mode); 3102 operands[3] = CONST0_RTX (<MODE>mode); 3103 operands[4] = gen_reg_rtx (<MODE>mode); 3104}) 3105 3106;; Generate 3107;; vspltisw SCRATCH1,0 3108;; vsubu?m SCRATCH2,SCRATCH1,%1 3109;; vmins? %0,%1,SCRATCH2" 3110(define_expand "nabs<mode>2" 3111 [(set (match_dup 2) (match_dup 3)) 3112 (set (match_dup 4) 3113 (minus:VI2 (match_dup 2) 3114 (match_operand:VI2 1 "register_operand" "v"))) 3115 (set (match_operand:VI2 0 "register_operand" "=v") 3116 (smin:VI2 (match_dup 1) (match_dup 4)))] 3117 "<VI_unit>" 3118{ 3119 operands[2] = gen_reg_rtx (<MODE>mode); 3120 operands[3] = CONST0_RTX (<MODE>mode); 3121 operands[4] = gen_reg_rtx (<MODE>mode); 3122}) 3123 3124;; Generate 3125;; vspltisw SCRATCH1,-1 3126;; vslw SCRATCH2,SCRATCH1,SCRATCH1 3127;; vandc %0,%1,SCRATCH2 3128(define_expand "altivec_absv4sf2" 3129 [(set (match_dup 2) 3130 (vec_duplicate:V4SI (const_int -1))) 3131 (set (match_dup 3) 3132 (ashift:V4SI (match_dup 2) (match_dup 2))) 3133 (set (match_operand:V4SF 0 "register_operand" "=v") 3134 (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0)) 3135 (match_operand:V4SF 1 "register_operand" "v")))] 3136 "TARGET_ALTIVEC" 3137{ 3138 operands[2] = gen_reg_rtx (V4SImode); 3139 operands[3] = gen_reg_rtx (V4SImode); 3140}) 3141 3142;; Generate 3143;; vspltis? SCRATCH0,0 3144;; vsubs?s SCRATCH2,SCRATCH1,%1 3145;; vmaxs? %0,%1,SCRATCH2" 3146(define_expand "altivec_abss_<mode>" 3147 [(set (match_dup 2) (vec_duplicate:VI (const_int 0))) 3148 (parallel [(set (match_dup 3) 3149 (unspec:VI [(match_dup 2) 3150 (match_operand:VI 1 "register_operand" "v")] 3151 UNSPEC_VSUBS)) 3152 (set (reg:SI VSCR_REGNO) 3153 (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]) 3154 (set (match_operand:VI 0 "register_operand" "=v") 3155 (smax:VI (match_dup 1) (match_dup 3)))] 3156 "TARGET_ALTIVEC" 3157{ 3158 operands[2] = gen_reg_rtx (GET_MODE (operands[0])); 3159 operands[3] = gen_reg_rtx (GET_MODE (operands[0])); 3160}) 3161 3162(define_expand "reduc_plus_scal_<mode>" 3163 [(set (match_operand:<VI_scalar> 0 "register_operand" "=v") 3164 (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")] 3165 UNSPEC_REDUC_PLUS))] 3166 "TARGET_ALTIVEC" 3167{ 3168 rtx vzero = gen_reg_rtx (V4SImode); 3169 rtx vtmp1 = gen_reg_rtx (V4SImode); 3170 rtx vtmp2 = gen_reg_rtx (<MODE>mode); 3171 rtx dest = gen_lowpart (V4SImode, vtmp2); 3172 int elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (<MODE>mode) - 1 : 0; 3173 3174 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); 3175 emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero)); 3176 emit_insn (gen_altivec_vsumsws_direct (dest, vtmp1, vzero)); 3177 rs6000_expand_vector_extract (operands[0], vtmp2, GEN_INT (elt)); 3178 DONE; 3179}) 3180 3181(define_insn "*p9_neg<mode>2" 3182 [(set (match_operand:VNEG 0 "altivec_register_operand" "=v") 3183 (neg:VNEG (match_operand:VNEG 1 "altivec_register_operand" "v")))] 3184 "TARGET_P9_VECTOR" 3185 "vneg<VI_char> %0,%1" 3186 [(set_attr "type" "vecsimple")]) 3187 3188(define_expand "neg<mode>2" 3189 [(set (match_operand:VI2 0 "register_operand") 3190 (neg:VI2 (match_operand:VI2 1 "register_operand")))] 3191 "<VI_unit>" 3192{ 3193 if (!TARGET_P9_VECTOR || (<MODE>mode != V4SImode && <MODE>mode != V2DImode)) 3194 { 3195 rtx vzero; 3196 3197 vzero = gen_reg_rtx (GET_MODE (operands[0])); 3198 emit_move_insn (vzero, CONST0_RTX (<MODE>mode)); 3199 emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); 3200 DONE; 3201 } 3202}) 3203 3204(define_expand "udot_prod<mode>" 3205 [(set (match_operand:V4SI 0 "register_operand" "=v") 3206 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") 3207 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") 3208 (match_operand:VIshort 2 "register_operand" "v")] 3209 UNSPEC_VMSUMU)))] 3210 "TARGET_ALTIVEC" 3211{ 3212 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3])); 3213 DONE; 3214}) 3215 3216(define_expand "sdot_prodv8hi" 3217 [(set (match_operand:V4SI 0 "register_operand" "=v") 3218 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") 3219 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3220 (match_operand:V8HI 2 "register_operand" "v")] 3221 UNSPEC_VMSUMSHM)))] 3222 "TARGET_ALTIVEC" 3223{ 3224 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3])); 3225 DONE; 3226}) 3227 3228(define_expand "widen_usum<mode>3" 3229 [(set (match_operand:V4SI 0 "register_operand" "=v") 3230 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") 3231 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")] 3232 UNSPEC_VMSUMU)))] 3233 "TARGET_ALTIVEC" 3234{ 3235 rtx vones = gen_reg_rtx (GET_MODE (operands[1])); 3236 3237 emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx)); 3238 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2])); 3239 DONE; 3240}) 3241 3242(define_expand "widen_ssumv16qi3" 3243 [(set (match_operand:V4SI 0 "register_operand" "=v") 3244 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") 3245 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")] 3246 UNSPEC_VMSUMM)))] 3247 "TARGET_ALTIVEC" 3248{ 3249 rtx vones = gen_reg_rtx (V16QImode); 3250 3251 emit_insn (gen_altivec_vspltisb (vones, const1_rtx)); 3252 emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2])); 3253 DONE; 3254}) 3255 3256(define_expand "widen_ssumv8hi3" 3257 [(set (match_operand:V4SI 0 "register_operand" "=v") 3258 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") 3259 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 3260 UNSPEC_VMSUMSHM)))] 3261 "TARGET_ALTIVEC" 3262{ 3263 rtx vones = gen_reg_rtx (V8HImode); 3264 3265 emit_insn (gen_altivec_vspltish (vones, const1_rtx)); 3266 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2])); 3267 DONE; 3268}) 3269 3270(define_expand "vec_unpacks_hi_<VP_small_lc>" 3271 [(set (match_operand:VP 0 "register_operand" "=v") 3272 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 3273 UNSPEC_VUNPACK_HI_SIGN_DIRECT))] 3274 "<VI_unit>" 3275 "") 3276 3277(define_expand "vec_unpacks_lo_<VP_small_lc>" 3278 [(set (match_operand:VP 0 "register_operand" "=v") 3279 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")] 3280 UNSPEC_VUNPACK_LO_SIGN_DIRECT))] 3281 "<VI_unit>" 3282 "") 3283 3284(define_insn "vperm_v8hiv4si" 3285 [(set (match_operand:V4SI 0 "register_operand" "=v,?wo") 3286 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,wo") 3287 (match_operand:V4SI 2 "register_operand" "v,0") 3288 (match_operand:V16QI 3 "register_operand" "v,wo")] 3289 UNSPEC_VPERMSI))] 3290 "TARGET_ALTIVEC" 3291 "@ 3292 vperm %0,%1,%2,%3 3293 xxperm %x0,%x1,%x3" 3294 [(set_attr "type" "vecperm")]) 3295 3296(define_insn "vperm_v16qiv8hi" 3297 [(set (match_operand:V8HI 0 "register_operand" "=v,?wo") 3298 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,wo") 3299 (match_operand:V8HI 2 "register_operand" "v,0") 3300 (match_operand:V16QI 3 "register_operand" "v,wo")] 3301 UNSPEC_VPERMHI))] 3302 "TARGET_ALTIVEC" 3303 "@ 3304 vperm %0,%1,%2,%3 3305 xxperm %x0,%x1,%x3" 3306 [(set_attr "type" "vecperm")]) 3307 3308 3309(define_expand "vec_unpacku_hi_v16qi" 3310 [(set (match_operand:V8HI 0 "register_operand" "=v") 3311 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 3312 UNSPEC_VUPKHUB))] 3313 "TARGET_ALTIVEC" 3314{ 3315 rtx vzero = gen_reg_rtx (V8HImode); 3316 rtx mask = gen_reg_rtx (V16QImode); 3317 rtvec v = rtvec_alloc (16); 3318 bool be = BYTES_BIG_ENDIAN; 3319 3320 emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); 3321 3322 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); 3323 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 0 : 16); 3324 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 6); 3325 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); 3326 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); 3327 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 2 : 16); 3328 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 4); 3329 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); 3330 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); 3331 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 4 : 16); 3332 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 2); 3333 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); 3334 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); 3335 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 6 : 16); 3336 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 0); 3337 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); 3338 3339 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3340 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); 3341 DONE; 3342}) 3343 3344(define_expand "vec_unpacku_hi_v8hi" 3345 [(set (match_operand:V4SI 0 "register_operand" "=v") 3346 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 3347 UNSPEC_VUPKHUH))] 3348 "TARGET_ALTIVEC" 3349{ 3350 rtx vzero = gen_reg_rtx (V4SImode); 3351 rtx mask = gen_reg_rtx (V16QImode); 3352 rtvec v = rtvec_alloc (16); 3353 bool be = BYTES_BIG_ENDIAN; 3354 3355 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); 3356 3357 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); 3358 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 6); 3359 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 0 : 17); 3360 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); 3361 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); 3362 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 4); 3363 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 2 : 17); 3364 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); 3365 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); 3366 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 2); 3367 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 4 : 17); 3368 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); 3369 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); 3370 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 0); 3371 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 6 : 17); 3372 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); 3373 3374 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3375 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); 3376 DONE; 3377}) 3378 3379(define_expand "vec_unpacku_lo_v16qi" 3380 [(set (match_operand:V8HI 0 "register_operand" "=v") 3381 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 3382 UNSPEC_VUPKLUB))] 3383 "TARGET_ALTIVEC" 3384{ 3385 rtx vzero = gen_reg_rtx (V8HImode); 3386 rtx mask = gen_reg_rtx (V16QImode); 3387 rtvec v = rtvec_alloc (16); 3388 bool be = BYTES_BIG_ENDIAN; 3389 3390 emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); 3391 3392 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); 3393 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 8 : 16); 3394 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14); 3395 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); 3396 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); 3397 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16); 3398 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12); 3399 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); 3400 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); 3401 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16); 3402 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10); 3403 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); 3404 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); 3405 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16); 3406 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 8); 3407 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); 3408 3409 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3410 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); 3411 DONE; 3412}) 3413 3414(define_expand "vec_unpacku_lo_v8hi" 3415 [(set (match_operand:V4SI 0 "register_operand" "=v") 3416 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 3417 UNSPEC_VUPKLUH))] 3418 "TARGET_ALTIVEC" 3419{ 3420 rtx vzero = gen_reg_rtx (V4SImode); 3421 rtx mask = gen_reg_rtx (V16QImode); 3422 rtvec v = rtvec_alloc (16); 3423 bool be = BYTES_BIG_ENDIAN; 3424 3425 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); 3426 3427 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); 3428 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14); 3429 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 8 : 17); 3430 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); 3431 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); 3432 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12); 3433 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17); 3434 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); 3435 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); 3436 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10); 3437 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17); 3438 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); 3439 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); 3440 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 8); 3441 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17); 3442 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); 3443 3444 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3445 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); 3446 DONE; 3447}) 3448 3449(define_expand "vec_widen_umult_hi_v16qi" 3450 [(set (match_operand:V8HI 0 "register_operand" "=v") 3451 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 3452 (match_operand:V16QI 2 "register_operand" "v")] 3453 UNSPEC_VMULWHUB))] 3454 "TARGET_ALTIVEC" 3455{ 3456 rtx ve = gen_reg_rtx (V8HImode); 3457 rtx vo = gen_reg_rtx (V8HImode); 3458 3459 if (BYTES_BIG_ENDIAN) 3460 { 3461 emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2])); 3462 emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2])); 3463 emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo)); 3464 } 3465 else 3466 { 3467 emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2])); 3468 emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2])); 3469 emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve)); 3470 } 3471 DONE; 3472}) 3473 3474(define_expand "vec_widen_umult_lo_v16qi" 3475 [(set (match_operand:V8HI 0 "register_operand" "=v") 3476 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 3477 (match_operand:V16QI 2 "register_operand" "v")] 3478 UNSPEC_VMULWLUB))] 3479 "TARGET_ALTIVEC" 3480{ 3481 rtx ve = gen_reg_rtx (V8HImode); 3482 rtx vo = gen_reg_rtx (V8HImode); 3483 3484 if (BYTES_BIG_ENDIAN) 3485 { 3486 emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2])); 3487 emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2])); 3488 emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo)); 3489 } 3490 else 3491 { 3492 emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2])); 3493 emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2])); 3494 emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve)); 3495 } 3496 DONE; 3497}) 3498 3499(define_expand "vec_widen_smult_hi_v16qi" 3500 [(set (match_operand:V8HI 0 "register_operand" "=v") 3501 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 3502 (match_operand:V16QI 2 "register_operand" "v")] 3503 UNSPEC_VMULWHSB))] 3504 "TARGET_ALTIVEC" 3505{ 3506 rtx ve = gen_reg_rtx (V8HImode); 3507 rtx vo = gen_reg_rtx (V8HImode); 3508 3509 if (BYTES_BIG_ENDIAN) 3510 { 3511 emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2])); 3512 emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2])); 3513 emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo)); 3514 } 3515 else 3516 { 3517 emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2])); 3518 emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2])); 3519 emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve)); 3520 } 3521 DONE; 3522}) 3523 3524(define_expand "vec_widen_smult_lo_v16qi" 3525 [(set (match_operand:V8HI 0 "register_operand" "=v") 3526 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") 3527 (match_operand:V16QI 2 "register_operand" "v")] 3528 UNSPEC_VMULWLSB))] 3529 "TARGET_ALTIVEC" 3530{ 3531 rtx ve = gen_reg_rtx (V8HImode); 3532 rtx vo = gen_reg_rtx (V8HImode); 3533 3534 if (BYTES_BIG_ENDIAN) 3535 { 3536 emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2])); 3537 emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2])); 3538 emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo)); 3539 } 3540 else 3541 { 3542 emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2])); 3543 emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2])); 3544 emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve)); 3545 } 3546 DONE; 3547}) 3548 3549(define_expand "vec_widen_umult_hi_v8hi" 3550 [(set (match_operand:V4SI 0 "register_operand" "=v") 3551 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3552 (match_operand:V8HI 2 "register_operand" "v")] 3553 UNSPEC_VMULWHUH))] 3554 "TARGET_ALTIVEC" 3555{ 3556 rtx ve = gen_reg_rtx (V4SImode); 3557 rtx vo = gen_reg_rtx (V4SImode); 3558 3559 if (BYTES_BIG_ENDIAN) 3560 { 3561 emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2])); 3562 emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2])); 3563 emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo)); 3564 } 3565 else 3566 { 3567 emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2])); 3568 emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2])); 3569 emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve)); 3570 } 3571 DONE; 3572}) 3573 3574(define_expand "vec_widen_umult_lo_v8hi" 3575 [(set (match_operand:V4SI 0 "register_operand" "=v") 3576 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3577 (match_operand:V8HI 2 "register_operand" "v")] 3578 UNSPEC_VMULWLUH))] 3579 "TARGET_ALTIVEC" 3580{ 3581 rtx ve = gen_reg_rtx (V4SImode); 3582 rtx vo = gen_reg_rtx (V4SImode); 3583 3584 if (BYTES_BIG_ENDIAN) 3585 { 3586 emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2])); 3587 emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2])); 3588 emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo)); 3589 } 3590 else 3591 { 3592 emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2])); 3593 emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2])); 3594 emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve)); 3595 } 3596 DONE; 3597}) 3598 3599(define_expand "vec_widen_smult_hi_v8hi" 3600 [(set (match_operand:V4SI 0 "register_operand" "=v") 3601 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3602 (match_operand:V8HI 2 "register_operand" "v")] 3603 UNSPEC_VMULWHSH))] 3604 "TARGET_ALTIVEC" 3605{ 3606 rtx ve = gen_reg_rtx (V4SImode); 3607 rtx vo = gen_reg_rtx (V4SImode); 3608 3609 if (BYTES_BIG_ENDIAN) 3610 { 3611 emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2])); 3612 emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2])); 3613 emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo)); 3614 } 3615 else 3616 { 3617 emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2])); 3618 emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2])); 3619 emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve)); 3620 } 3621 DONE; 3622}) 3623 3624(define_expand "vec_widen_smult_lo_v8hi" 3625 [(set (match_operand:V4SI 0 "register_operand" "=v") 3626 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") 3627 (match_operand:V8HI 2 "register_operand" "v")] 3628 UNSPEC_VMULWLSH))] 3629 "TARGET_ALTIVEC" 3630{ 3631 rtx ve = gen_reg_rtx (V4SImode); 3632 rtx vo = gen_reg_rtx (V4SImode); 3633 3634 if (BYTES_BIG_ENDIAN) 3635 { 3636 emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2])); 3637 emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2])); 3638 emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo)); 3639 } 3640 else 3641 { 3642 emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2])); 3643 emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2])); 3644 emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve)); 3645 } 3646 DONE; 3647}) 3648 3649(define_expand "vec_pack_trunc_<mode>" 3650 [(set (match_operand:<VP_small> 0 "register_operand" "=v") 3651 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v") 3652 (match_operand:VP 2 "register_operand" "v")] 3653 UNSPEC_VPACK_UNS_UNS_MOD))] 3654 "<VI_unit>" 3655 "") 3656 3657(define_expand "mulv16qi3" 3658 [(set (match_operand:V16QI 0 "register_operand" "=v") 3659 (mult:V16QI (match_operand:V16QI 1 "register_operand" "v") 3660 (match_operand:V16QI 2 "register_operand" "v")))] 3661 "TARGET_ALTIVEC" 3662{ 3663 rtx even = gen_reg_rtx (V8HImode); 3664 rtx odd = gen_reg_rtx (V8HImode); 3665 rtx mask = gen_reg_rtx (V16QImode); 3666 rtvec v = rtvec_alloc (16); 3667 int i; 3668 3669 for (i = 0; i < 8; ++i) { 3670 RTVEC_ELT (v, 2 * i) 3671 = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 1 : 31 - 2 * i); 3672 RTVEC_ELT (v, 2 * i + 1) 3673 = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 17 : 15 - 2 * i); 3674 } 3675 3676 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3677 emit_insn (gen_altivec_vmulesb (even, operands[1], operands[2])); 3678 emit_insn (gen_altivec_vmulosb (odd, operands[1], operands[2])); 3679 emit_insn (gen_altivec_vperm_v8hiv16qi (operands[0], even, odd, mask)); 3680 DONE; 3681}) 3682 3683(define_expand "altivec_vpermxor" 3684 [(use (match_operand:V16QI 0 "register_operand")) 3685 (use (match_operand:V16QI 1 "register_operand")) 3686 (use (match_operand:V16QI 2 "register_operand")) 3687 (use (match_operand:V16QI 3 "register_operand"))] 3688 "TARGET_P8_VECTOR" 3689{ 3690 if (!BYTES_BIG_ENDIAN) 3691 { 3692 /* vpermxor indexes the bytes using Big Endian numbering. If LE, 3693 change indexing in operand[3] to BE index. */ 3694 rtx be_index = gen_reg_rtx (V16QImode); 3695 3696 emit_insn (gen_one_cmplv16qi2 (be_index, operands[3])); 3697 emit_insn (gen_crypto_vpermxor_v16qi (operands[0], operands[1], 3698 operands[2], be_index)); 3699 } 3700 else 3701 emit_insn (gen_crypto_vpermxor_v16qi (operands[0], operands[1], 3702 operands[2], operands[3])); 3703 DONE; 3704}) 3705 3706(define_expand "altivec_negv4sf2" 3707 [(use (match_operand:V4SF 0 "register_operand")) 3708 (use (match_operand:V4SF 1 "register_operand"))] 3709 "TARGET_ALTIVEC" 3710{ 3711 rtx neg0; 3712 3713 /* Generate [-0.0, -0.0, -0.0, -0.0]. */ 3714 neg0 = gen_reg_rtx (V4SImode); 3715 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); 3716 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); 3717 3718 /* XOR */ 3719 emit_insn (gen_xorv4sf3 (operands[0], 3720 gen_lowpart (V4SFmode, neg0), operands[1])); 3721 3722 DONE; 3723}) 3724 3725;; Vector reverse elements 3726(define_expand "altivec_vreve<mode>2" 3727 [(set (match_operand:VEC_A 0 "register_operand" "=v") 3728 (unspec:VEC_A [(match_operand:VEC_A 1 "register_operand" "v")] 3729 UNSPEC_VREVEV))] 3730 "TARGET_ALTIVEC" 3731{ 3732 int i, j, size, num_elements; 3733 rtvec v = rtvec_alloc (16); 3734 rtx mask = gen_reg_rtx (V16QImode); 3735 3736 size = GET_MODE_UNIT_SIZE (<MODE>mode); 3737 num_elements = GET_MODE_NUNITS (<MODE>mode); 3738 3739 for (j = 0; j < num_elements; j++) 3740 for (i = 0; i < size; i++) 3741 RTVEC_ELT (v, i + j * size) 3742 = GEN_INT (i + (num_elements - 1 - j) * size); 3743 3744 emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v))); 3745 emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], 3746 operands[1], mask)); 3747 DONE; 3748}) 3749 3750;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL, 3751;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell. 3752(define_insn "altivec_lvlx" 3753 [(set (match_operand:V16QI 0 "register_operand" "=v") 3754 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] 3755 UNSPEC_LVLX))] 3756 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3757 "lvlx %0,%y1" 3758 [(set_attr "type" "vecload")]) 3759 3760(define_insn "altivec_lvlxl" 3761 [(set (match_operand:V16QI 0 "register_operand" "=v") 3762 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] 3763 UNSPEC_LVLXL))] 3764 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3765 "lvlxl %0,%y1" 3766 [(set_attr "type" "vecload")]) 3767 3768(define_insn "altivec_lvrx" 3769 [(set (match_operand:V16QI 0 "register_operand" "=v") 3770 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] 3771 UNSPEC_LVRX))] 3772 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3773 "lvrx %0,%y1" 3774 [(set_attr "type" "vecload")]) 3775 3776(define_insn "altivec_lvrxl" 3777 [(set (match_operand:V16QI 0 "register_operand" "=v") 3778 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] 3779 UNSPEC_LVRXL))] 3780 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3781 "lvrxl %0,%y1" 3782 [(set_attr "type" "vecload")]) 3783 3784(define_insn "altivec_stvlx" 3785 [(parallel 3786 [(set (match_operand:V16QI 0 "memory_operand" "=Z") 3787 (match_operand:V16QI 1 "register_operand" "v")) 3788 (unspec [(const_int 0)] UNSPEC_STVLX)])] 3789 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3790 "stvlx %1,%y0" 3791 [(set_attr "type" "vecstore")]) 3792 3793(define_insn "altivec_stvlxl" 3794 [(parallel 3795 [(set (match_operand:V16QI 0 "memory_operand" "=Z") 3796 (match_operand:V16QI 1 "register_operand" "v")) 3797 (unspec [(const_int 0)] UNSPEC_STVLXL)])] 3798 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3799 "stvlxl %1,%y0" 3800 [(set_attr "type" "vecstore")]) 3801 3802(define_insn "altivec_stvrx" 3803 [(parallel 3804 [(set (match_operand:V16QI 0 "memory_operand" "=Z") 3805 (match_operand:V16QI 1 "register_operand" "v")) 3806 (unspec [(const_int 0)] UNSPEC_STVRX)])] 3807 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3808 "stvrx %1,%y0" 3809 [(set_attr "type" "vecstore")]) 3810 3811(define_insn "altivec_stvrxl" 3812 [(parallel 3813 [(set (match_operand:V16QI 0 "memory_operand" "=Z") 3814 (match_operand:V16QI 1 "register_operand" "v")) 3815 (unspec [(const_int 0)] UNSPEC_STVRXL)])] 3816 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" 3817 "stvrxl %1,%y0" 3818 [(set_attr "type" "vecstore")]) 3819 3820(define_expand "vec_unpacks_float_hi_v8hi" 3821 [(set (match_operand:V4SF 0 "register_operand") 3822 (unspec:V4SF [(match_operand:V8HI 1 "register_operand")] 3823 UNSPEC_VUPKHS_V4SF))] 3824 "TARGET_ALTIVEC" 3825{ 3826 rtx tmp = gen_reg_rtx (V4SImode); 3827 3828 emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1])); 3829 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); 3830 DONE; 3831}) 3832 3833(define_expand "vec_unpacks_float_lo_v8hi" 3834 [(set (match_operand:V4SF 0 "register_operand") 3835 (unspec:V4SF [(match_operand:V8HI 1 "register_operand")] 3836 UNSPEC_VUPKLS_V4SF))] 3837 "TARGET_ALTIVEC" 3838{ 3839 rtx tmp = gen_reg_rtx (V4SImode); 3840 3841 emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1])); 3842 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); 3843 DONE; 3844}) 3845 3846(define_expand "vec_unpacku_float_hi_v8hi" 3847 [(set (match_operand:V4SF 0 "register_operand") 3848 (unspec:V4SF [(match_operand:V8HI 1 "register_operand")] 3849 UNSPEC_VUPKHU_V4SF))] 3850 "TARGET_ALTIVEC" 3851{ 3852 rtx tmp = gen_reg_rtx (V4SImode); 3853 3854 emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1])); 3855 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); 3856 DONE; 3857}) 3858 3859(define_expand "vec_unpacku_float_lo_v8hi" 3860 [(set (match_operand:V4SF 0 "register_operand") 3861 (unspec:V4SF [(match_operand:V8HI 1 "register_operand")] 3862 UNSPEC_VUPKLU_V4SF))] 3863 "TARGET_ALTIVEC" 3864{ 3865 rtx tmp = gen_reg_rtx (V4SImode); 3866 3867 emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1])); 3868 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); 3869 DONE; 3870}) 3871 3872 3873;; Power8/power9 vector instructions encoded as Altivec instructions 3874 3875;; Vector count leading zeros 3876(define_insn "*p8v_clz<mode>2" 3877 [(set (match_operand:VI2 0 "register_operand" "=v") 3878 (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))] 3879 "TARGET_P8_VECTOR" 3880 "vclz<wd> %0,%1" 3881 [(set_attr "type" "vecsimple")]) 3882 3883;; Vector absolute difference unsigned 3884(define_expand "vadu<mode>3" 3885 [(set (match_operand:VI 0 "register_operand") 3886 (unspec:VI [(match_operand:VI 1 "register_operand") 3887 (match_operand:VI 2 "register_operand")] 3888 UNSPEC_VADU))] 3889 "TARGET_P9_VECTOR") 3890 3891;; Vector absolute difference unsigned 3892(define_insn "p9_vadu<mode>3" 3893 [(set (match_operand:VI 0 "register_operand" "=v") 3894 (unspec:VI [(match_operand:VI 1 "register_operand" "v") 3895 (match_operand:VI 2 "register_operand" "v")] 3896 UNSPEC_VADU))] 3897 "TARGET_P9_VECTOR" 3898 "vabsdu<wd> %0,%1,%2" 3899 [(set_attr "type" "vecsimple")]) 3900 3901;; Vector count trailing zeros 3902(define_insn "*p9v_ctz<mode>2" 3903 [(set (match_operand:VI2 0 "register_operand" "=v") 3904 (ctz:VI2 (match_operand:VI2 1 "register_operand" "v")))] 3905 "TARGET_P9_VECTOR" 3906 "vctz<wd> %0,%1" 3907 [(set_attr "type" "vecsimple")]) 3908 3909;; Vector population count 3910(define_insn "*p8v_popcount<mode>2" 3911 [(set (match_operand:VI2 0 "register_operand" "=v") 3912 (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))] 3913 "TARGET_P8_VECTOR" 3914 "vpopcnt<wd> %0,%1" 3915 [(set_attr "type" "vecsimple")]) 3916 3917;; Vector parity 3918(define_insn "*p9v_parity<mode>2" 3919 [(set (match_operand:VParity 0 "register_operand" "=v") 3920 (parity:VParity (match_operand:VParity 1 "register_operand" "v")))] 3921 "TARGET_P9_VECTOR" 3922 "vprtyb<wd> %0,%1" 3923 [(set_attr "type" "vecsimple")]) 3924 3925;; Vector Gather Bits by Bytes by Doubleword 3926(define_insn "p8v_vgbbd" 3927 [(set (match_operand:V16QI 0 "register_operand" "=v") 3928 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] 3929 UNSPEC_VGBBD))] 3930 "TARGET_P8_VECTOR" 3931 "vgbbd %0,%1" 3932 [(set_attr "type" "vecsimple")]) 3933 3934 3935;; 128-bit binary integer arithmetic 3936;; We have a special container type (V1TImode) to allow operations using the 3937;; ISA 2.07 128-bit binary support to target the VMX/altivec registers without 3938;; having to worry about the register allocator deciding GPRs are better. 3939 3940(define_insn "altivec_vadduqm" 3941 [(set (match_operand:V1TI 0 "register_operand" "=v") 3942 (plus:V1TI (match_operand:V1TI 1 "register_operand" "v") 3943 (match_operand:V1TI 2 "register_operand" "v")))] 3944 "TARGET_VADDUQM" 3945 "vadduqm %0,%1,%2" 3946 [(set_attr "type" "vecsimple")]) 3947 3948(define_insn "altivec_vaddcuq" 3949 [(set (match_operand:V1TI 0 "register_operand" "=v") 3950 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3951 (match_operand:V1TI 2 "register_operand" "v")] 3952 UNSPEC_VADDCUQ))] 3953 "TARGET_VADDUQM" 3954 "vaddcuq %0,%1,%2" 3955 [(set_attr "type" "vecsimple")]) 3956 3957(define_insn "altivec_vsubuqm" 3958 [(set (match_operand:V1TI 0 "register_operand" "=v") 3959 (minus:V1TI (match_operand:V1TI 1 "register_operand" "v") 3960 (match_operand:V1TI 2 "register_operand" "v")))] 3961 "TARGET_VADDUQM" 3962 "vsubuqm %0,%1,%2" 3963 [(set_attr "type" "vecsimple")]) 3964 3965(define_insn "altivec_vsubcuq" 3966 [(set (match_operand:V1TI 0 "register_operand" "=v") 3967 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3968 (match_operand:V1TI 2 "register_operand" "v")] 3969 UNSPEC_VSUBCUQ))] 3970 "TARGET_VADDUQM" 3971 "vsubcuq %0,%1,%2" 3972 [(set_attr "type" "vecsimple")]) 3973 3974(define_insn "altivec_vaddeuqm" 3975 [(set (match_operand:V1TI 0 "register_operand" "=v") 3976 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3977 (match_operand:V1TI 2 "register_operand" "v") 3978 (match_operand:V1TI 3 "register_operand" "v")] 3979 UNSPEC_VADDEUQM))] 3980 "TARGET_VADDUQM" 3981 "vaddeuqm %0,%1,%2,%3" 3982 [(set_attr "type" "vecsimple")]) 3983 3984(define_insn "altivec_vaddecuq" 3985 [(set (match_operand:V1TI 0 "register_operand" "=v") 3986 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3987 (match_operand:V1TI 2 "register_operand" "v") 3988 (match_operand:V1TI 3 "register_operand" "v")] 3989 UNSPEC_VADDECUQ))] 3990 "TARGET_VADDUQM" 3991 "vaddecuq %0,%1,%2,%3" 3992 [(set_attr "type" "vecsimple")]) 3993 3994(define_insn "altivec_vsubeuqm" 3995 [(set (match_operand:V1TI 0 "register_operand" "=v") 3996 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 3997 (match_operand:V1TI 2 "register_operand" "v") 3998 (match_operand:V1TI 3 "register_operand" "v")] 3999 UNSPEC_VSUBEUQM))] 4000 "TARGET_VADDUQM" 4001 "vsubeuqm %0,%1,%2,%3" 4002 [(set_attr "type" "vecsimple")]) 4003 4004(define_insn "altivec_vsubecuq" 4005 [(set (match_operand:V1TI 0 "register_operand" "=v") 4006 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 4007 (match_operand:V1TI 2 "register_operand" "v") 4008 (match_operand:V1TI 3 "register_operand" "v")] 4009 UNSPEC_VSUBECUQ))] 4010 "TARGET_VADDUQM" 4011 "vsubecuq %0,%1,%2,%3" 4012 [(set_attr "type" "vecsimple")]) 4013 4014;; We use V2DI as the output type to simplify converting the permute 4015;; bits into an integer 4016(define_insn "altivec_vbpermq" 4017 [(set (match_operand:V2DI 0 "register_operand" "=v") 4018 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v") 4019 (match_operand:V16QI 2 "register_operand" "v")] 4020 UNSPEC_VBPERMQ))] 4021 "TARGET_P8_VECTOR" 4022 "vbpermq %0,%1,%2" 4023 [(set_attr "type" "vecperm")]) 4024 4025; One of the vector API interfaces requires returning vector unsigned char. 4026(define_insn "altivec_vbpermq2" 4027 [(set (match_operand:V16QI 0 "register_operand" "=v") 4028 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 4029 (match_operand:V16QI 2 "register_operand" "v")] 4030 UNSPEC_VBPERMQ))] 4031 "TARGET_P8_VECTOR" 4032 "vbpermq %0,%1,%2" 4033 [(set_attr "type" "vecperm")]) 4034 4035(define_insn "altivec_vbpermd" 4036 [(set (match_operand:V2DI 0 "register_operand" "=v") 4037 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v") 4038 (match_operand:V16QI 2 "register_operand" "v")] 4039 UNSPEC_VBPERMD))] 4040 "TARGET_P9_VECTOR" 4041 "vbpermd %0,%1,%2" 4042 [(set_attr "type" "vecsimple")]) 4043 4044;; Support for SAD (sum of absolute differences). 4045 4046;; Due to saturating semantics, we can't combine the sum-across 4047;; with the vector accumulate in vsum4ubs. A vadduwm is needed. 4048(define_expand "usadv16qi" 4049 [(use (match_operand:V4SI 0 "register_operand")) 4050 (use (match_operand:V16QI 1 "register_operand")) 4051 (use (match_operand:V16QI 2 "register_operand")) 4052 (use (match_operand:V4SI 3 "register_operand"))] 4053 "TARGET_P9_VECTOR" 4054{ 4055 rtx absd = gen_reg_rtx (V16QImode); 4056 rtx zero = gen_reg_rtx (V4SImode); 4057 rtx psum = gen_reg_rtx (V4SImode); 4058 4059 emit_insn (gen_p9_vaduv16qi3 (absd, operands[1], operands[2])); 4060 emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); 4061 emit_insn (gen_altivec_vsum4ubs (psum, absd, zero)); 4062 emit_insn (gen_addv4si3 (operands[0], psum, operands[3])); 4063 DONE; 4064}) 4065 4066;; Since vsum4shs is saturating and further performs signed 4067;; arithmetic, we can't combine the sum-across with the vector 4068;; accumulate in vsum4shs. A vadduwm is needed. 4069(define_expand "usadv8hi" 4070 [(use (match_operand:V4SI 0 "register_operand")) 4071 (use (match_operand:V8HI 1 "register_operand")) 4072 (use (match_operand:V8HI 2 "register_operand")) 4073 (use (match_operand:V4SI 3 "register_operand"))] 4074 "TARGET_P9_VECTOR" 4075{ 4076 rtx absd = gen_reg_rtx (V8HImode); 4077 rtx zero = gen_reg_rtx (V4SImode); 4078 rtx psum = gen_reg_rtx (V4SImode); 4079 4080 emit_insn (gen_p9_vaduv8hi3 (absd, operands[1], operands[2])); 4081 emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); 4082 emit_insn (gen_altivec_vsum4shs (psum, absd, zero)); 4083 emit_insn (gen_addv4si3 (operands[0], psum, operands[3])); 4084 DONE; 4085}) 4086 4087;; Decimal Integer operations 4088(define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB]) 4089 4090(define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add") 4091 (UNSPEC_BCDSUB "sub")]) 4092 4093(define_code_iterator BCD_TEST [eq lt gt unordered]) 4094 4095(define_insn "bcd<bcd_add_sub>" 4096 [(set (match_operand:V1TI 0 "gpc_reg_operand" "=v") 4097 (unspec:V1TI [(match_operand:V1TI 1 "gpc_reg_operand" "v") 4098 (match_operand:V1TI 2 "gpc_reg_operand" "v") 4099 (match_operand:QI 3 "const_0_to_1_operand" "n")] 4100 UNSPEC_BCD_ADD_SUB)) 4101 (clobber (reg:CCFP CR6_REGNO))] 4102 "TARGET_P8_VECTOR" 4103 "bcd<bcd_add_sub>. %0,%1,%2,%3" 4104 [(set_attr "type" "vecsimple")]) 4105 4106;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we 4107;; can use the unordered test for BCD nans and add/subtracts that overflow. An 4108;; UNORDERED test on an integer type (like V1TImode) is not defined. The type 4109;; probably should be one that can go in the VMX (Altivec) registers, so we 4110;; can't use DDmode or DFmode. 4111(define_insn "*bcd<bcd_add_sub>_test" 4112 [(set (reg:CCFP CR6_REGNO) 4113 (compare:CCFP 4114 (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v") 4115 (match_operand:V1TI 2 "register_operand" "v") 4116 (match_operand:QI 3 "const_0_to_1_operand" "i")] 4117 UNSPEC_BCD_ADD_SUB) 4118 (match_operand:V2DF 4 "zero_constant" "j"))) 4119 (clobber (match_scratch:V1TI 0 "=v"))] 4120 "TARGET_P8_VECTOR" 4121 "bcd<bcd_add_sub>. %0,%1,%2,%3" 4122 [(set_attr "type" "vecsimple")]) 4123 4124(define_insn "*bcd<bcd_add_sub>_test2" 4125 [(set (match_operand:V1TI 0 "register_operand" "=v") 4126 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") 4127 (match_operand:V1TI 2 "register_operand" "v") 4128 (match_operand:QI 3 "const_0_to_1_operand" "i")] 4129 UNSPEC_BCD_ADD_SUB)) 4130 (set (reg:CCFP CR6_REGNO) 4131 (compare:CCFP 4132 (unspec:V2DF [(match_dup 1) 4133 (match_dup 2) 4134 (match_dup 3)] 4135 UNSPEC_BCD_ADD_SUB) 4136 (match_operand:V2DF 4 "zero_constant" "j")))] 4137 "TARGET_P8_VECTOR" 4138 "bcd<bcd_add_sub>. %0,%1,%2,%3" 4139 [(set_attr "type" "vecsimple")]) 4140 4141(define_expand "bcd<bcd_add_sub>_<code>" 4142 [(parallel [(set (reg:CCFP CR6_REGNO) 4143 (compare:CCFP 4144 (unspec:V2DF [(match_operand:V1TI 1 "register_operand") 4145 (match_operand:V1TI 2 "register_operand") 4146 (match_operand:QI 3 "const_0_to_1_operand")] 4147 UNSPEC_BCD_ADD_SUB) 4148 (match_dup 4))) 4149 (clobber (match_scratch:V1TI 5))]) 4150 (set (match_operand:SI 0 "register_operand") 4151 (BCD_TEST:SI (reg:CCFP CR6_REGNO) 4152 (const_int 0)))] 4153 "TARGET_P8_VECTOR" 4154{ 4155 operands[4] = CONST0_RTX (V2DFmode); 4156}) 4157 4158;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and 4159;; the bcdadd/bcdsub that tests the value. The combiner won't work since 4160;; CR6 is a hard coded register. Unfortunately, all of the Altivec predicate 4161;; support is hard coded to use the fixed register CR6 instead of creating 4162;; a register class for CR6. 4163 4164(define_peephole2 4165 [(parallel [(set (match_operand:V1TI 0 "register_operand") 4166 (unspec:V1TI [(match_operand:V1TI 1 "register_operand") 4167 (match_operand:V1TI 2 "register_operand") 4168 (match_operand:QI 3 "const_0_to_1_operand")] 4169 UNSPEC_BCD_ADD_SUB)) 4170 (clobber (reg:CCFP CR6_REGNO))]) 4171 (parallel [(set (reg:CCFP CR6_REGNO) 4172 (compare:CCFP 4173 (unspec:V2DF [(match_dup 1) 4174 (match_dup 2) 4175 (match_dup 3)] 4176 UNSPEC_BCD_ADD_SUB) 4177 (match_operand:V2DF 4 "zero_constant"))) 4178 (clobber (match_operand:V1TI 5 "register_operand"))])] 4179 "TARGET_P8_VECTOR" 4180 [(parallel [(set (match_dup 0) 4181 (unspec:V1TI [(match_dup 1) 4182 (match_dup 2) 4183 (match_dup 3)] 4184 UNSPEC_BCD_ADD_SUB)) 4185 (set (reg:CCFP CR6_REGNO) 4186 (compare:CCFP 4187 (unspec:V2DF [(match_dup 1) 4188 (match_dup 2) 4189 (match_dup 3)] 4190 UNSPEC_BCD_ADD_SUB) 4191 (match_dup 4)))])]) 4192