1;;- Instruction patterns for the System z vector facility 2;; Copyright (C) 2015-2020 Free Software Foundation, Inc. 3;; Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com) 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it under 8;; the terms of the GNU General Public License as published by the Free 9;; Software Foundation; either version 3, or (at your option) any later 10;; version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13;; WARRANTY; without even the implied warranty of MERCHANTABILITY or 14;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15;; 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; All vector modes supported in a vector register 22(define_mode_iterator V 23 [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF 24 V2SF V4SF V1DF V2DF]) 25(define_mode_iterator VT 26 [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF 27 V2SF V4SF V1DF V2DF V1TF V1TI TI]) 28 29; All modes directly supported by the hardware having full vector reg size 30; V_HW2 is duplicate of V_HW for having two iterators expanding 31; independently e.g. vcond 32(define_mode_iterator V_HW [V16QI V8HI V4SI V2DI (V1TI "TARGET_VXE") V2DF (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")]) 33(define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")]) 34 35(define_mode_iterator V_HW_64 [V2DI V2DF]) 36(define_mode_iterator VT_HW_HSDT [V8HI V4SI V4SF V2DI V2DF V1TI V1TF TI TF]) 37(define_mode_iterator V_HW_HSD [V8HI V4SI (V4SF "TARGET_VXE") V2DI V2DF]) 38 39; Including TI for instructions that support it (va, vn, ...) 40(define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")]) 41 42; All full size integer vector modes supported in a vector register + TImode 43(define_mode_iterator VIT_HW [V16QI V8HI V4SI V2DI V1TI TI]) 44(define_mode_iterator VI_HW [V16QI V8HI V4SI V2DI]) 45(define_mode_iterator VI_HW_QHS [V16QI V8HI V4SI]) 46(define_mode_iterator VI_HW_HSD [V8HI V4SI V2DI]) 47(define_mode_iterator VI_HW_HS [V8HI V4SI]) 48(define_mode_iterator VI_HW_QH [V16QI V8HI]) 49(define_mode_iterator VI_HW_4 [V4SI V4SF]) 50 51; All integer vector modes supported in a vector register + TImode 52(define_mode_iterator VIT [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1TI TI]) 53(define_mode_iterator VI [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI]) 54(define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI]) 55 56(define_mode_iterator VFT [(V1SF "TARGET_VXE") (V2SF "TARGET_VXE") (V4SF "TARGET_VXE") 57 V1DF V2DF 58 (V1TF "TARGET_VXE")]) 59 60; FP vector modes directly supported by the HW. This does not include 61; vector modes using only part of a vector register and should be used 62; for instructions which might trigger IEEE exceptions. 63(define_mode_iterator VF_HW [(V4SF "TARGET_VXE") V2DF (V1TF "TARGET_VXE")]) 64 65(define_mode_iterator V_8 [V1QI]) 66(define_mode_iterator V_16 [V2QI V1HI]) 67(define_mode_iterator V_32 [V4QI V2HI V1SI V1SF]) 68(define_mode_iterator V_64 [V8QI V4HI V2SI V2SF V1DI V1DF]) 69(define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF]) 70 71(define_mode_iterator V_128_NOSINGLE [V16QI V8HI V4SI V4SF V2DI V2DF]) 72 73; 32 bit int<->fp vector conversion instructions are available since VXE2 (z15). 74(define_mode_iterator VX_VEC_CONV_BFP [V2DF (V4SF "TARGET_VXE2")]) 75(define_mode_iterator VX_VEC_CONV_INT [V2DI (V4SI "TARGET_VXE2")]) 76 77; Empty string for all but TImode. This is used to hide the TImode 78; expander name in case it is defined already. See addti3 for an 79; example. 80(define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "") 81 (V1HI "") (V2HI "") (V4HI "") (V8HI "") 82 (V1SI "") (V2SI "") (V4SI "") 83 (V1DI "") (V2DI "") 84 (V1TI "") (TI "*") 85 (V1SF "") (V2SF "") (V4SF "") 86 (V1DF "") (V2DF "") 87 (V1TF "") (TF "")]) 88 89; The element type of the vector. 90(define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI") 91 (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI") 92 (V1SI "SI") (V2SI "SI") (V4SI "SI") 93 (V1DI "DI") (V2DI "DI") 94 (V1TI "TI") (TI "TI") 95 (V1SF "SF") (V2SF "SF") (V4SF "SF") 96 (V1DF "DF") (V2DF "DF") 97 (V1TF "TF") (TF "TF")]) 98 99; Like above, but in lower case. 100(define_mode_attr non_vec_l[(V1QI "qi") (V2QI "qi") (V4QI "qi") (V8QI "qi") 101 (V16QI "qi") 102 (V1HI "hi") (V2HI "hi") (V4HI "hi") (V8HI "hi") 103 (V1SI "si") (V2SI "si") (V4SI "si") 104 (V1DI "di") (V2DI "di") 105 (V1TI "ti") (TI "ti") 106 (V1SF "sf") (V2SF "sf") (V4SF "sf") 107 (V1DF "df") (V2DF "df") 108 (V1TF "tf") (TF "tf")]) 109 110; The instruction suffix for integer instructions and instructions 111; which do not care about whether it is floating point or integer. 112(define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b") 113 (V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h") 114 (V1SI "f") (V2SI "f") (V4SI "f") 115 (V1DI "g") (V2DI "g") 116 (V1TI "q") (TI "q") 117 (V1SF "f") (V2SF "f") (V4SF "f") 118 (V1DF "g") (V2DF "g") 119 (V1TF "q")]) 120 121; This is for vmalhw. It gets an 'w' attached to avoid confusion with 122; multiply and add logical high vmalh. 123(define_mode_attr w [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "") 124 (V1HI "w") (V2HI "w") (V4HI "w") (V8HI "w") 125 (V1SI "") (V2SI "") (V4SI "") 126 (V1DI "") (V2DI "")]) 127 128; Resulting mode of a vector comparison. For floating point modes an 129; integer vector mode with the same element size is picked. 130(define_mode_attr tointvec [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI") 131 (V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI") 132 (V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI") 133 (V1DI "V1DI") (V2DI "V2DI") 134 (V1TI "V1TI") 135 (V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI") 136 (V1DF "V1DI") (V2DF "V2DI") 137 (V1TF "V1TI")]) 138(define_mode_attr vw [(SF "w") (V1SF "w") (V2SF "v") (V4SF "v") 139 (DF "w") (V1DF "w") (V2DF "v") 140 (TF "w") (V1TF "w")]) 141 142(define_mode_attr sdx [(SF "s") (V1SF "s") (V2SF "s") (V4SF "s") 143 (DF "d") (V1DF "d") (V2DF "d") 144 (TF "x") (V1TF "x")]) 145 146; Vector with doubled element size. 147(define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI") 148 (V1HI "V1SI") (V2HI "V1SI") (V4HI "V2SI") (V8HI "V4SI") 149 (V1SI "V1DI") (V2SI "V1DI") (V4SI "V2DI") 150 (V1DI "V1TI") (V2DI "V1TI") 151 (V1SF "V1DF") (V2SF "V1DF") (V4SF "V2DF")]) 152 153; Vector with half the element size. 154(define_mode_attr vec_half [(V1HI "V2QI") (V2HI "V4QI") (V4HI "V8QI") (V8HI "V16QI") 155 (V1SI "V2HI") (V2SI "V4HI") (V4SI "V8HI") 156 (V1DI "V2SI") (V2DI "V4SI") 157 (V1TI "V2DI") 158 (V1DF "V2SF") (V2DF "V4SF") 159 (V1TF "V1DF")]) 160 161; Vector with half the element size AND half the number of elements. 162(define_mode_attr vec_halfhalf 163 [(V2HI "V2QI") (V4HI "V4QI") (V8HI "V8QI") 164 (V2SI "V2HI") (V4SI "V4HI") 165 (V2DI "V2SI") 166 (V2DF "V2SF")]) 167 168(define_mode_attr vec_halfnumelts 169 [(V4SF "V2SF") (V4SI "V2SI")]) 170 171 172 173; Comparison operators on int and fp compares which are directly 174; supported by the HW. 175(define_code_iterator VICMP_HW_OP [eq gt gtu]) 176; For int insn_cmp_op can be used in the insn name as well as in the asm output. 177(define_code_attr insn_cmp_op [(eq "eq") (gt "h") (gtu "hl") (ge "he")]) 178 179; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4) 180(define_constants 181 [(VSTRING_FLAG_IN 8) ; invert result 182 (VSTRING_FLAG_RT 4) ; result type 183 (VSTRING_FLAG_ZS 2) ; zero search 184 (VSTRING_FLAG_CS 1)]) ; condition code set 185 186(include "vx-builtins.md") 187 188; Full HW vector size moves 189 190; We don't use lm/stm for 128 bit moves since these are slower than 191; splitting it into separate moves. 192 193; FIXME: More constants are possible by enabling jxx, jyy constraints 194; for TImode (use double-int for the calculations) 195 196; vgmb, vgmh, vgmf, vgmg, vrepib, vrepih, vrepif, vrepig 197(define_insn "mov<mode>" 198 [(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R, v, v, v, v, v,v,*d,*d,?o") 199 (match_operand:V_128 1 "general_operand" " v,R,v,j00,jm1,jyy,jxx,jKK,d, v,dT,*d"))] 200 "" 201 "@ 202 vlr\t%v0,%v1 203 vl\t%v0,%1%A1 204 vst\t%v1,%0%A0 205 vzero\t%v0 206 vone\t%v0 207 vgbm\t%v0,%t1 208 vgm<bhfgq>\t%v0,%s1,%e1 209 vrepi<bhfgq>\t%v0,%h1 210 vlvgp\t%v0,%1,%N1 211 # 212 # 213 #" 214 [(set_attr "cpu_facility" "vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*") 215 (set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRI,VRI,VRI,VRR,*,*,*")]) 216 217; VR -> GPR, no instruction so split it into 64 element sets. 218(define_split 219 [(set (match_operand:V_128 0 "register_operand" "") 220 (match_operand:V_128 1 "register_operand" ""))] 221 "TARGET_VX && GENERAL_REG_P (operands[0]) && VECTOR_REG_P (operands[1])" 222 [(set (match_dup 2) 223 (unspec:DI [(subreg:V2DI (match_dup 1) 0) 224 (const_int 0)] UNSPEC_VEC_EXTRACT)) 225 (set (match_dup 3) 226 (unspec:DI [(subreg:V2DI (match_dup 1) 0) 227 (const_int 1)] UNSPEC_VEC_EXTRACT))] 228{ 229 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 230 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode); 231}) 232 233; Split the 128 bit GPR move into two word mode moves 234; s390_split_ok_p decides which part needs to be moved first. 235 236(define_split 237 [(set (match_operand:V_128 0 "nonimmediate_operand" "") 238 (match_operand:V_128 1 "general_operand" ""))] 239 "reload_completed 240 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)" 241 [(set (match_dup 2) (match_dup 4)) 242 (set (match_dup 3) (match_dup 5))] 243{ 244 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 245 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode); 246 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode); 247 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode); 248}) 249 250(define_split 251 [(set (match_operand:V_128 0 "nonimmediate_operand" "") 252 (match_operand:V_128 1 "general_operand" ""))] 253 "reload_completed 254 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)" 255 [(set (match_dup 2) (match_dup 4)) 256 (set (match_dup 3) (match_dup 5))] 257{ 258 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode); 259 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode); 260 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode); 261 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode); 262}) 263 264; This is the vector equivalent to the TImode splitter in s390.md. It 265; is required if both target GPRs occur in the source address operand. 266 267; For non-s_operands at least one of the target GPRs does not conflict 268; with the address operand and one of the splitters above will take 269; over. 270(define_split 271 [(set (match_operand:V_128 0 "register_operand" "") 272 (match_operand:V_128 1 "memory_operand" ""))] 273 "TARGET_ZARCH && reload_completed 274 && !VECTOR_REG_P (operands[0]) 275 && !s_operand (operands[1], VOIDmode)" 276 [(set (match_dup 0) (match_dup 1))] 277{ 278 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode); 279 addr = gen_lowpart (Pmode, addr); 280 s390_load_address (addr, XEXP (operands[1], 0)); 281 operands[1] = replace_equiv_address (operands[1], addr); 282}) 283 284; Moves for smaller vector modes. 285 286; In these patterns only the vlr, vone, and vzero instructions write 287; VR bytes outside the mode. This should be ok since we disallow 288; formerly bigger modes being accessed with smaller modes via 289; subreg. Note: The vone, vzero instructions could easily be replaced 290; with vlei which would only access the bytes belonging to the mode. 291; However, this would probably be slower. 292 293(define_insn "mov<mode>" 294 [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v,d, Q, S, Q, S, d, d,d,R,T") 295 (match_operand:V_8 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,T,d,d"))] 296 "TARGET_VX" 297 "@ 298 vlr\t%v0,%v1 299 vlvgb\t%v0,%1,0 300 vlgvb\t%0,%v1,0 301 vleb\t%v0,%1,0 302 vsteb\t%v1,%0,0 303 vzero\t%v0 304 vone\t%v0 305 vgbm\t%v0,%t1 306 vgm\t%v0,%s1,%e1 307 lr\t%0,%1 308 mvi\t%0,0 309 mviy\t%0,0 310 mvi\t%0,-1 311 mviy\t%0,-1 312 lhi\t%0,0 313 lhi\t%0,-1 314 llc\t%0,%1 315 stc\t%1,%0 316 stcy\t%1,%0" 317 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RXY,RX,RXY")]) 318 319(define_insn "mov<mode>" 320 [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v,d, Q, Q, d, d,d,d,d,R,T,b") 321 (match_operand:V_16 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))] 322 "" 323 "@ 324 vlr\t%v0,%v1 325 vlvgh\t%v0,%1,0 326 vlgvh\t%0,%v1,0 327 vleh\t%v0,%1,0 328 vsteh\t%v1,%0,0 329 vzero\t%v0 330 vone\t%v0 331 vgbm\t%v0,%t1 332 vgm\t%v0,%s1,%e1 333 lr\t%0,%1 334 mvhhi\t%0,0 335 mvhhi\t%0,-1 336 lhi\t%0,0 337 lhi\t%0,-1 338 lh\t%0,%1 339 lhy\t%0,%1 340 lhrl\t%0,%1 341 sth\t%1,%0 342 sthy\t%1,%0 343 sthrl\t%1,%0" 344 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")]) 345 346(define_insn "mov<mode>" 347 [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, Q, Q, d, d,d,d,d,d,R,T,b") 348 (match_operand:V_32 1 "general_operand" " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))] 349 "TARGET_VX" 350 "@ 351 ldr\t%v0,%v1 352 lde\t%0,%1 353 ley\t%0,%1 354 ste\t%1,%0 355 stey\t%1,%0 356 vlr\t%v0,%v1 357 vlvgf\t%v0,%1,0 358 vlgvf\t%0,%v1,0 359 vlef\t%v0,%1,0 360 vstef\t%1,%0,0 361 lzer\t%v0 362 vzero\t%v0 363 vone\t%v0 364 vgbm\t%v0,%t1 365 vgm\t%v0,%s1,%e1 366 mvhi\t%0,0 367 mvhi\t%0,-1 368 lhi\t%0,0 369 lhi\t%0,-1 370 lrl\t%0,%1 371 lr\t%0,%1 372 l\t%0,%1 373 ly\t%0,%1 374 st\t%1,%0 375 sty\t%1,%0 376 strl\t%1,%0" 377 [(set_attr "op_type" "RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI, 378 RIL,RR,RX,RXY,RX,RXY,RIL")]) 379 380(define_insn "mov<mode>" 381 [(set (match_operand:V_64 0 "nonimmediate_operand" 382 "=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, Q, Q, d, d,f,d,d,d,d,T,b") 383 (match_operand:V_64 1 "general_operand" 384 " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))] 385 "TARGET_ZARCH" 386 "@ 387 ldr\t%0,%1 388 ld\t%0,%1 389 ldy\t%0,%1 390 std\t%1,%0 391 stdy\t%1,%0 392 vlr\t%v0,%v1 393 vlvgg\t%v0,%1,0 394 vlgvg\t%0,%v1,0 395 vleg\t%v0,%1,0 396 vsteg\t%v1,%0,0 397 lzdr\t%0 398 vzero\t%v0 399 vone\t%v0 400 vgbm\t%v0,%t1 401 vgm\t%v0,%s1,%e1 402 mvghi\t%0,0 403 mvghi\t%0,-1 404 lghi\t%0,0 405 lghi\t%0,-1 406 ldgr\t%0,%1 407 lgdr\t%0,%1 408 lgrl\t%0,%1 409 lgr\t%0,%1 410 lg\t%0,%1 411 stg\t%1,%0 412 stgrl\t%1,%0" 413 [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI, 414 SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")]) 415 416 417; vec_load_lanes? 418 419; vec_store_lanes? 420 421; vec_set is supposed to *modify* an existing vector so operand 0 is 422; duplicated as input operand. 423(define_expand "vec_set<mode>" 424 [(set (match_operand:V 0 "register_operand" "") 425 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "") 426 (match_operand:SI 2 "nonmemory_operand" "") 427 (match_dup 0)] 428 UNSPEC_VEC_SET))] 429 "TARGET_VX") 430 431; FIXME: Support also vector mode operands for 1 432; FIXME: A target memory operand seems to be useful otherwise we end 433; up with vl vlvgg vst. Shouldn't the middle-end be able to handle 434; that itself? 435; vlvgb, vlvgh, vlvgf, vlvgg, vleb, vleh, vlef, vleg, vleib, vleih, vleif, vleig 436(define_insn "*vec_set<mode>" 437 [(set (match_operand:V 0 "register_operand" "=v,v,v") 438 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,R,K") 439 (match_operand:SI 2 "nonmemory_operand" "an,I,I") 440 (match_operand:V 3 "register_operand" "0,0,0")] 441 UNSPEC_VEC_SET))] 442 "TARGET_VX 443 && (!CONST_INT_P (operands[2]) 444 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))" 445 "@ 446 vlvg<bhfgq>\t%v0,%1,%Y2 447 vle<bhfgq>\t%v0,%1,%2 448 vlei<bhfgq>\t%v0,%1,%2" 449 [(set_attr "op_type" "VRS,VRX,VRI")]) 450 451; vlvgb, vlvgh, vlvgf, vlvgg 452(define_insn "*vec_set<mode>_plus" 453 [(set (match_operand:V 0 "register_operand" "=v") 454 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d") 455 (plus:SI (match_operand:SI 2 "register_operand" "a") 456 (match_operand:SI 4 "const_int_operand" "n")) 457 (match_operand:V 3 "register_operand" "0")] 458 UNSPEC_VEC_SET))] 459 "TARGET_VX" 460 "vlvg<bhfgq>\t%v0,%1,%Y4(%2)" 461 [(set_attr "op_type" "VRS")]) 462 463 464; FIXME: Support also vector mode operands for 0 465; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :( 466; This is used via RTL standard name as well as for expanding the builtin 467(define_expand "vec_extract<mode><non_vec_l>" 468 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "") 469 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "") 470 (match_operand:SI 2 "nonmemory_operand" "")] 471 UNSPEC_VEC_EXTRACT))] 472 "TARGET_VX") 473 474; vlgvb, vlgvh, vlgvf, vlgvg, vsteb, vsteh, vstef, vsteg 475(define_insn "*vec_extract<mode>" 476 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,R") 477 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v,v") 478 (match_operand:SI 2 "nonmemory_operand" "an,I")] 479 UNSPEC_VEC_EXTRACT))] 480 "TARGET_VX 481 && (!CONST_INT_P (operands[2]) 482 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))" 483 "@ 484 vlgv<bhfgq>\t%0,%v1,%Y2 485 vste<bhfgq>\t%v1,%0,%2" 486 [(set_attr "op_type" "VRS,VRX")]) 487 488; vlgvb, vlgvh, vlgvf, vlgvg 489(define_insn "*vec_extract<mode>_plus" 490 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d") 491 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v") 492 (plus:SI (match_operand:SI 2 "nonmemory_operand" "a") 493 (match_operand:SI 3 "const_int_operand" "n"))] 494 UNSPEC_VEC_EXTRACT))] 495 "TARGET_VX" 496 "vlgv<bhfgq>\t%0,%v1,%Y3(%2)" 497 [(set_attr "op_type" "VRS")]) 498 499(define_expand "vec_init<mode><non_vec_l>" 500 [(match_operand:V_128 0 "register_operand" "") 501 (match_operand:V_128 1 "nonmemory_operand" "")] 502 "TARGET_VX" 503{ 504 s390_expand_vec_init (operands[0], operands[1]); 505 DONE; 506}) 507 508(define_insn "*vec_vllezlf<mode>" 509 [(set (match_operand:VI_HW_4 0 "register_operand" "=v") 510 (vec_concat:VI_HW_4 511 (vec_concat:<vec_halfnumelts> 512 (match_operand:<non_vec> 1 "memory_operand" "R") 513 (const_int 0)) 514 (vec_concat:<vec_halfnumelts> 515 (const_int 0) 516 (const_int 0))))] 517 "TARGET_VXE" 518 "vllezlf\t%v0,%1" 519 [(set_attr "op_type" "VRX")]) 520 521; Replicate from vector element 522; vrepb, vreph, vrepf, vrepg 523(define_insn "*vec_splat<mode>" 524 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v") 525 (vec_duplicate:V_128_NOSINGLE 526 (vec_select:<non_vec> 527 (match_operand:V_128_NOSINGLE 1 "register_operand" "v") 528 (parallel 529 [(match_operand:QI 2 "const_mask_operand" "C")]))))] 530 "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<MODE>mode)" 531 "vrep<bhfgq>\t%v0,%v1,%2" 532 [(set_attr "op_type" "VRI")]) 533 534; vlrepb, vlreph, vlrepf, vlrepg, vrepib, vrepih, vrepif, vrepig, vrepb, vreph, vrepf, vrepg 535(define_insn "*vec_splats<mode>" 536 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v,v,v,v") 537 (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "general_operand" " R,K,v,d")))] 538 "TARGET_VX" 539 "@ 540 vlrep<bhfgq>\t%v0,%1 541 vrepi<bhfgq>\t%v0,%h1 542 vrep<bhfgq>\t%v0,%v1,0 543 #" 544 [(set_attr "op_type" "VRX,VRI,VRI,*")]) 545 546; vlbrreph, vlbrrepf, vlbrrepg 547(define_insn "*vec_splats_bswap_vec<mode>" 548 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v") 549 (bswap:V_HW_HSD 550 (vec_duplicate:V_HW_HSD (match_operand:<non_vec> 1 "memory_operand" "R")))) 551 (use (match_operand:V16QI 2 "permute_pattern_operand" "X"))] 552 "TARGET_VXE2" 553 "vlbrrep<bhfgq>\t%v0,%1" 554 [(set_attr "op_type" "VRX")]) 555 556; Why do we need both? Shouldn't there be a canonical form? 557; vlbrreph, vlbrrepf, vlbrrepg 558(define_insn "*vec_splats_bswap_elem<mode>" 559 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v") 560 (vec_duplicate:V_HW_HSD 561 (bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand" "R"))))] 562 "TARGET_VXE2" 563 "vlbrrep<bhfgq>\t%v0,%1" 564 [(set_attr "op_type" "VRX")]) 565 566; A TFmode operand resides in FPR register pairs while V1TF is in a 567; single vector register. 568(define_insn "*vec_tf_to_v1tf" 569 [(set (match_operand:V1TF 0 "nonimmediate_operand" "=v,v,R,v,v") 570 (vec_duplicate:V1TF (match_operand:TF 1 "general_operand" "v,R,v,G,d")))] 571 "TARGET_VX" 572 "@ 573 vmrhg\t%v0,%1,%N1 574 vl\t%v0,%1%A1 575 vst\t%v1,%0%A0 576 vzero\t%v0 577 vlvgp\t%v0,%1,%N1" 578 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRR")]) 579 580(define_insn "*vec_ti_to_v1ti" 581 [(set (match_operand:V1TI 0 "nonimmediate_operand" "=v,v,R, v, v,v") 582 (vec_duplicate:V1TI (match_operand:TI 1 "general_operand" "v,R,v,j00,jm1,d")))] 583 "TARGET_VX" 584 "@ 585 vlr\t%v0,%v1 586 vl\t%v0,%1%A1 587 vst\t%v1,%0%A0 588 vzero\t%v0 589 vone\t%v0 590 vlvgp\t%v0,%1,%N1" 591 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRR")]) 592 593; vec_splats is supposed to replicate op1 into all elements of op0 594; This splitter first sets the rightmost element of op0 to op1 and 595; then does a vec_splat to replicate that element into all other 596; elements. 597(define_split 598 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "") 599 (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "register_operand" "")))] 600 "TARGET_VX && GENERAL_REG_P (operands[1])" 601 [(set (match_dup 0) 602 (unspec:V_128_NOSINGLE [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET)) 603 (set (match_dup 0) 604 (vec_duplicate:V_128_NOSINGLE 605 (vec_select:<non_vec> 606 (match_dup 0) (parallel [(match_dup 2)]))))] 607{ 608 operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1); 609}) 610 611(define_predicate "vcond_comparison_operator" 612 (match_operand 0 "comparison_operator") 613{ 614 if (!HONOR_NANS (GET_MODE (XEXP (op, 0))) 615 && !HONOR_NANS (GET_MODE (XEXP (op, 1)))) 616 return true; 617 switch (GET_CODE (op)) 618 { 619 case LE: 620 case LT: 621 case GE: 622 case GT: 623 case LTGT: 624 /* Signaling vector comparisons are supported only on z14+. */ 625 return TARGET_VXE || TARGET_NONSIGNALING_VECTOR_COMPARE_OK; 626 default: 627 return true; 628 } 629}) 630 631(define_expand "vcond<V_HW:mode><V_HW2:mode>" 632 [(set (match_operand:V_HW 0 "register_operand" "") 633 (if_then_else:V_HW 634 (match_operator 3 "vcond_comparison_operator" 635 [(match_operand:V_HW2 4 "register_operand" "") 636 (match_operand:V_HW2 5 "nonmemory_operand" "")]) 637 (match_operand:V_HW 1 "nonmemory_operand" "") 638 (match_operand:V_HW 2 "nonmemory_operand" "")))] 639 "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)" 640{ 641 s390_expand_vcond (operands[0], operands[1], operands[2], 642 GET_CODE (operands[3]), operands[4], operands[5]); 643 DONE; 644}) 645 646(define_expand "vcondu<V_HW:mode><V_HW2:mode>" 647 [(set (match_operand:V_HW 0 "register_operand" "") 648 (if_then_else:V_HW 649 (match_operator 3 "comparison_operator" 650 [(match_operand:V_HW2 4 "register_operand" "") 651 (match_operand:V_HW2 5 "nonmemory_operand" "")]) 652 (match_operand:V_HW 1 "nonmemory_operand" "") 653 (match_operand:V_HW 2 "nonmemory_operand" "")))] 654 "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)" 655{ 656 s390_expand_vcond (operands[0], operands[1], operands[2], 657 GET_CODE (operands[3]), operands[4], operands[5]); 658 DONE; 659}) 660 661; We only have HW support for byte vectors. The middle-end is 662; supposed to lower the mode if required. 663(define_insn "vec_permv16qi" 664 [(set (match_operand:V16QI 0 "register_operand" "=v") 665 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 666 (match_operand:V16QI 2 "register_operand" "v") 667 (match_operand:V16QI 3 "register_operand" "v")] 668 UNSPEC_VEC_PERM))] 669 "TARGET_VX" 670 "vperm\t%v0,%v1,%v2,%v3" 671 [(set_attr "op_type" "VRR")]) 672 673(define_insn "*vec_perm<mode>" 674 [(set (match_operand:VT_HW 0 "register_operand" "=v") 675 (subreg:VT_HW (unspec:V16QI [(subreg:V16QI (match_operand:VT_HW 1 "register_operand" "v") 0) 676 (subreg:V16QI (match_operand:VT_HW 2 "register_operand" "v") 0) 677 (match_operand:V16QI 3 "register_operand" "v")] 678 UNSPEC_VEC_PERM) 0))] 679 "TARGET_VX" 680 "vperm\t%v0,%v1,%v2,%v3" 681 [(set_attr "op_type" "VRR")]) 682 683 684; vec_perm_const for V2DI using vpdi? 685 686;; 687;; Vector integer arithmetic instructions 688;; 689 690; vab, vah, vaf, vag, vaq 691 692; We use nonimmediate_operand instead of register_operand since it is 693; better to have the reloads into VRs instead of splitting the 694; operation into two DImode ADDs. 695(define_insn "<ti*>add<mode>3" 696 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v") 697 (plus:VIT (match_operand:VIT 1 "nonimmediate_operand" "v") 698 (match_operand:VIT 2 "general_operand" "v")))] 699 "TARGET_VX" 700 "va<bhfgq>\t%v0,%v1,%v2" 701 [(set_attr "op_type" "VRR")]) 702 703; vsb, vsh, vsf, vsg, vsq 704(define_insn "<ti*>sub<mode>3" 705 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v") 706 (minus:VIT (match_operand:VIT 1 "nonimmediate_operand" "v") 707 (match_operand:VIT 2 "general_operand" "v")))] 708 "TARGET_VX" 709 "vs<bhfgq>\t%v0,%v1,%v2" 710 [(set_attr "op_type" "VRR")]) 711 712; vmlb, vmlhw, vmlf 713(define_insn "mul<mode>3" 714 [(set (match_operand:VI_QHS 0 "register_operand" "=v") 715 (mult:VI_QHS (match_operand:VI_QHS 1 "register_operand" "v") 716 (match_operand:VI_QHS 2 "register_operand" "v")))] 717 "TARGET_VX" 718 "vml<bhfgq><w>\t%v0,%v1,%v2" 719 [(set_attr "op_type" "VRR")]) 720 721; vlcb, vlch, vlcf, vlcg 722(define_insn "neg<mode>2" 723 [(set (match_operand:VI 0 "register_operand" "=v") 724 (neg:VI (match_operand:VI 1 "register_operand" "v")))] 725 "TARGET_VX" 726 "vlc<bhfgq>\t%v0,%v1" 727 [(set_attr "op_type" "VRR")]) 728 729; vlpb, vlph, vlpf, vlpg 730(define_insn "abs<mode>2" 731 [(set (match_operand:VI 0 "register_operand" "=v") 732 (abs:VI (match_operand:VI 1 "register_operand" "v")))] 733 "TARGET_VX" 734 "vlp<bhfgq>\t%v0,%v1" 735 [(set_attr "op_type" "VRR")]) 736 737 738; Vector sum across 739 740; Sum across DImode parts of the 1st operand and add the rightmost 741; element of 2nd operand 742; vsumgh, vsumgf 743(define_insn "*vec_sum2<mode>" 744 [(set (match_operand:V2DI 0 "register_operand" "=v") 745 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "v") 746 (match_operand:VI_HW_HS 2 "register_operand" "v")] 747 UNSPEC_VEC_VSUMG))] 748 "TARGET_VX" 749 "vsumg<bhfgq>\t%v0,%v1,%v2" 750 [(set_attr "op_type" "VRR")]) 751 752; vsumb, vsumh 753(define_insn "*vec_sum4<mode>" 754 [(set (match_operand:V4SI 0 "register_operand" "=v") 755 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "v") 756 (match_operand:VI_HW_QH 2 "register_operand" "v")] 757 UNSPEC_VEC_VSUM))] 758 "TARGET_VX" 759 "vsum<bhfgq>\t%v0,%v1,%v2" 760 [(set_attr "op_type" "VRR")]) 761 762;; 763;; Vector bit instructions (int + fp) 764;; 765 766; Vector and 767 768(define_insn "and<mode>3" 769 [(set (match_operand:VT 0 "register_operand" "=v") 770 (and:VT (match_operand:VT 1 "register_operand" "v") 771 (match_operand:VT 2 "register_operand" "v")))] 772 "TARGET_VX" 773 "vn\t%v0,%v1,%v2" 774 [(set_attr "op_type" "VRR")]) 775 776; Vector not and 777 778(define_insn "notand<mode>3" 779 [(set (match_operand:VT 0 "register_operand" "=v") 780 (ior:VT (not:VT (match_operand:VT 1 "register_operand" "v")) 781 (not:VT (match_operand:VT 2 "register_operand" "v"))))] 782 "TARGET_VXE" 783 "vnn\t%v0,%v1,%v2" 784 [(set_attr "op_type" "VRR")]) 785 786; Vector or 787 788(define_insn "ior<mode>3" 789 [(set (match_operand:VT 0 "register_operand" "=v") 790 (ior:VT (match_operand:VT 1 "register_operand" "v") 791 (match_operand:VT 2 "register_operand" "v")))] 792 "TARGET_VX" 793 "vo\t%v0,%v1,%v2" 794 [(set_attr "op_type" "VRR")]) 795 796; Vector or with complement 797 798(define_insn "ior_not<mode>3" 799 [(set (match_operand:VT 0 "register_operand" "=v") 800 (ior:VT (not:VT (match_operand:VT 2 "register_operand" "v")) 801 (match_operand:VT 1 "register_operand" "v")))] 802 "TARGET_VXE" 803 "voc\t%v0,%v1,%v2" 804 [(set_attr "op_type" "VRR")]) 805 806; Vector xor 807 808(define_insn "xor<mode>3" 809 [(set (match_operand:VT 0 "register_operand" "=v") 810 (xor:VT (match_operand:VT 1 "register_operand" "v") 811 (match_operand:VT 2 "register_operand" "v")))] 812 "TARGET_VX" 813 "vx\t%v0,%v1,%v2" 814 [(set_attr "op_type" "VRR")]) 815 816; Vector not xor 817 818(define_insn "notxor<mode>3" 819 [(set (match_operand:VT 0 "register_operand" "=v") 820 (not:VT (xor:VT (match_operand:VT 1 "register_operand" "v") 821 (match_operand:VT 2 "register_operand" "v"))))] 822 "TARGET_VXE" 823 "vnx\t%v0,%v1,%v2" 824 [(set_attr "op_type" "VRR")]) 825 826; Bitwise inversion of a vector 827(define_insn "one_cmpl<mode>2" 828 [(set (match_operand:VT 0 "register_operand" "=v") 829 (not:VT (match_operand:VT 1 "register_operand" "v")))] 830 "TARGET_VX" 831 "vnot\t%v0,%v1" 832 [(set_attr "op_type" "VRR")]) 833 834; Vector population count 835 836(define_expand "popcount<mode>2" 837 [(set (match_operand:VI_HW 0 "register_operand" "=v") 838 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")] 839 UNSPEC_POPCNT))] 840 "TARGET_VX" 841{ 842 if (TARGET_VXE) 843 emit_insn (gen_popcount<mode>2_vxe (operands[0], operands[1])); 844 else 845 emit_insn (gen_popcount<mode>2_vx (operands[0], operands[1])); 846 DONE; 847}) 848 849; vpopctb, vpopcth, vpopctf, vpopctg 850(define_insn "popcount<mode>2_vxe" 851 [(set (match_operand:VI_HW 0 "register_operand" "=v") 852 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")] 853 UNSPEC_POPCNT))] 854 "TARGET_VXE" 855 "vpopct<bhfgq>\t%v0,%v1" 856 [(set_attr "op_type" "VRR")]) 857 858(define_insn "popcountv16qi2_vx" 859 [(set (match_operand:V16QI 0 "register_operand" "=v") 860 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] 861 UNSPEC_POPCNT))] 862 "TARGET_VX && !TARGET_VXE" 863 "vpopct\t%v0,%v1,0" 864 [(set_attr "op_type" "VRR")]) 865 866; vpopct only counts bits in byte elements. Bigger element sizes need 867; to be emulated. Word and doubleword elements can use the sum across 868; instructions. For halfword sized elements we do a shift of a copy 869; of the result, add it to the result and extend it to halfword 870; element size (unpack). 871 872(define_expand "popcountv8hi2_vx" 873 [(set (match_dup 2) 874 (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")] 875 UNSPEC_POPCNT)) 876 ; Make a copy of the result 877 (set (match_dup 3) (match_dup 2)) 878 ; Generate the shift count operand in a VR (8->byte 7) 879 (set (match_dup 4) (match_dup 5)) 880 (set (match_dup 4) (unspec:V16QI [(const_int 8) 881 (const_int 7) 882 (match_dup 4)] UNSPEC_VEC_SET)) 883 ; Vector shift right logical by one byte 884 (set (match_dup 3) 885 (unspec:V16QI [(match_dup 3) (match_dup 4)] UNSPEC_VEC_SRLB)) 886 ; Add the shifted and the original result 887 (set (match_dup 2) 888 (plus:V16QI (match_dup 2) (match_dup 3))) 889 ; Generate mask for the odd numbered byte elements 890 (set (match_dup 3) 891 (const_vector:V16QI [(const_int 0) (const_int 255) 892 (const_int 0) (const_int 255) 893 (const_int 0) (const_int 255) 894 (const_int 0) (const_int 255) 895 (const_int 0) (const_int 255) 896 (const_int 0) (const_int 255) 897 (const_int 0) (const_int 255) 898 (const_int 0) (const_int 255)])) 899 ; Zero out the even indexed bytes 900 (set (match_operand:V8HI 0 "register_operand" "=v") 901 (and:V8HI (subreg:V8HI (match_dup 2) 0) 902 (subreg:V8HI (match_dup 3) 0))) 903] 904 "TARGET_VX && !TARGET_VXE" 905{ 906 operands[1] = simplify_gen_subreg (V16QImode, operands[1], 907 V8HImode, 0); 908 operands[2] = gen_reg_rtx (V16QImode); 909 operands[3] = gen_reg_rtx (V16QImode); 910 operands[4] = gen_reg_rtx (V16QImode); 911 operands[5] = CONST0_RTX (V16QImode); 912}) 913 914(define_expand "popcountv4si2_vx" 915 [(set (match_dup 2) 916 (unspec:V16QI [(match_operand:V4SI 1 "register_operand" "v")] 917 UNSPEC_POPCNT)) 918 (set (match_operand:V4SI 0 "register_operand" "=v") 919 (unspec:V4SI [(match_dup 2) (match_dup 3)] 920 UNSPEC_VEC_VSUM))] 921 "TARGET_VX && !TARGET_VXE" 922{ 923 operands[1] = simplify_gen_subreg (V16QImode, operands[1], V4SImode, 0); 924 operands[2] = gen_reg_rtx (V16QImode); 925 operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode)); 926}) 927 928(define_expand "popcountv2di2_vx" 929 [(set (match_dup 2) 930 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")] 931 UNSPEC_POPCNT)) 932 (set (match_dup 3) 933 (unspec:V4SI [(match_dup 2) (match_dup 4)] 934 UNSPEC_VEC_VSUM)) 935 (set (match_operand:V2DI 0 "register_operand" "=v") 936 (unspec:V2DI [(match_dup 3) (match_dup 5)] 937 UNSPEC_VEC_VSUMG))] 938 "TARGET_VX && !TARGET_VXE" 939{ 940 operands[1] = simplify_gen_subreg (V16QImode, operands[1], V2DImode, 0); 941 operands[2] = gen_reg_rtx (V16QImode); 942 operands[3] = gen_reg_rtx (V4SImode); 943 operands[4] = force_reg (V16QImode, CONST0_RTX (V16QImode)); 944 operands[5] = force_reg (V4SImode, CONST0_RTX (V4SImode)); 945}) 946 947; Count leading zeros 948; vclzb, vclzh, vclzf, vclzg 949(define_insn "clz<mode>2" 950 [(set (match_operand:V 0 "register_operand" "=v") 951 (clz:V (match_operand:V 1 "register_operand" "v")))] 952 "TARGET_VX" 953 "vclz<bhfgq>\t%v0,%v1" 954 [(set_attr "op_type" "VRR")]) 955 956; Count trailing zeros 957; vctzb, vctzh, vctzf, vctzg 958(define_insn "ctz<mode>2" 959 [(set (match_operand:V 0 "register_operand" "=v") 960 (ctz:V (match_operand:V 1 "register_operand" "v")))] 961 "TARGET_VX" 962 "vctz<bhfgq>\t%v0,%v1" 963 [(set_attr "op_type" "VRR")]) 964 965 966 967; Each vector element rotated by the corresponding vector element 968; verllvb, verllvh, verllvf, verllvg 969(define_insn "vrotl<mode>3" 970 [(set (match_operand:VI 0 "register_operand" "=v") 971 (rotate:VI (match_operand:VI 1 "register_operand" "v") 972 (match_operand:VI 2 "register_operand" "v")))] 973 "TARGET_VX" 974 "verllv<bhfgq>\t%v0,%v1,%v2" 975 [(set_attr "op_type" "VRR")]) 976 977 978; Vector rotate and shift by scalar instructions 979 980(define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate]) 981(define_code_attr vec_shifts_name [(ashift "ashl") (ashiftrt "ashr") 982 (lshiftrt "lshr") (rotate "rotl")]) 983(define_code_attr vec_shifts_mnem [(ashift "vesl") (ashiftrt "vesra") 984 (lshiftrt "vesrl") (rotate "verll")]) 985 986; Each vector element rotated by a scalar 987(define_expand "<vec_shifts_name><mode>3" 988 [(set (match_operand:VI 0 "register_operand" "") 989 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "") 990 (match_operand:QI 2 "shift_count_operand" "")))] 991 "TARGET_VX") 992 993; verllb, verllh, verllf, verllg 994; veslb, veslh, veslf, veslg 995; vesrab, vesrah, vesraf, vesrag 996; vesrlb, vesrlh, vesrlf, vesrlg 997(define_insn "*<vec_shifts_name><mode>3" 998 [(set (match_operand:VI 0 "register_operand" "=v") 999 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v") 1000 (match_operand:QI 2 "shift_count_operand_vec" "jsc")))] 1001 "TARGET_VX 1002 && s390_valid_shift_count (operands[2], 1003 GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) - 1) 1004 " 1005 "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2" 1006 [(set_attr "op_type" "VRS")]) 1007 1008 1009; Shift each element by corresponding vector element 1010 1011; veslvb, veslvh, veslvf, veslvg 1012(define_insn "vashl<mode>3" 1013 [(set (match_operand:VI 0 "register_operand" "=v") 1014 (ashift:VI (match_operand:VI 1 "register_operand" "v") 1015 (match_operand:VI 2 "register_operand" "v")))] 1016 "TARGET_VX" 1017 "veslv<bhfgq>\t%v0,%v1,%v2" 1018 [(set_attr "op_type" "VRR")]) 1019 1020; vesravb, vesravh, vesravf, vesravg 1021(define_insn "vashr<mode>3" 1022 [(set (match_operand:VI 0 "register_operand" "=v") 1023 (ashiftrt:VI (match_operand:VI 1 "register_operand" "v") 1024 (match_operand:VI 2 "register_operand" "v")))] 1025 "TARGET_VX" 1026 "vesrav<bhfgq>\t%v0,%v1,%v2" 1027 [(set_attr "op_type" "VRR")]) 1028 1029; vesrlvb, vesrlvh, vesrlvf, vesrlvg 1030(define_insn "vlshr<mode>3" 1031 [(set (match_operand:VI 0 "register_operand" "=v") 1032 (lshiftrt:VI (match_operand:VI 1 "register_operand" "v") 1033 (match_operand:VI 2 "register_operand" "v")))] 1034 "TARGET_VX" 1035 "vesrlv<bhfgq>\t%v0,%v1,%v2" 1036 [(set_attr "op_type" "VRR")]) 1037 1038; Vector shift right logical by byte 1039 1040; Pattern used by e.g. popcount 1041(define_insn "*vec_srb<mode>" 1042 [(set (match_operand:V_128 0 "register_operand" "=v") 1043 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "v") 1044 (match_operand:V16QI 2 "register_operand" "v")] 1045 UNSPEC_VEC_SRLB))] 1046 "TARGET_VX" 1047 "vsrlb\t%v0,%v1,%v2" 1048 [(set_attr "op_type" "VRR")]) 1049 1050 1051; Vector shift left by byte 1052 1053(define_insn "*vec_slb<mode>" 1054 [(set (match_operand:V_128 0 "register_operand" "=v") 1055 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "v") 1056 (match_operand:V16QI 2 "register_operand" "v")] 1057 UNSPEC_VEC_SLB))] 1058 "TARGET_VX" 1059 "vslb\t%v0,%v1,%v2" 1060 [(set_attr "op_type" "VRR")]) 1061 1062; vec_shr is defined as shift towards element 0 1063; this means it is a left shift on BE targets! 1064(define_expand "vec_shr_<mode>" 1065 [(set (match_dup 3) 1066 (unspec:V16QI [(match_operand:SI 2 "const_shift_by_byte_operand" "") 1067 (const_int 7) 1068 (match_dup 3)] 1069 UNSPEC_VEC_SET)) 1070 (set (match_operand:V_128 0 "register_operand" "") 1071 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "") 1072 (match_dup 3)] 1073 UNSPEC_VEC_SLB))] 1074 "TARGET_VX" 1075 { 1076 operands[3] = gen_reg_rtx(V16QImode); 1077 }) 1078 1079; vmnb, vmnh, vmnf, vmng 1080(define_insn "smin<mode>3" 1081 [(set (match_operand:VI 0 "register_operand" "=v") 1082 (smin:VI (match_operand:VI 1 "register_operand" "v") 1083 (match_operand:VI 2 "register_operand" "v")))] 1084 "TARGET_VX" 1085 "vmn<bhfgq>\t%v0,%v1,%v2" 1086 [(set_attr "op_type" "VRR")]) 1087 1088; vmxb, vmxh, vmxf, vmxg 1089(define_insn "smax<mode>3" 1090 [(set (match_operand:VI 0 "register_operand" "=v") 1091 (smax:VI (match_operand:VI 1 "register_operand" "v") 1092 (match_operand:VI 2 "register_operand" "v")))] 1093 "TARGET_VX" 1094 "vmx<bhfgq>\t%v0,%v1,%v2" 1095 [(set_attr "op_type" "VRR")]) 1096 1097; vmnlb, vmnlh, vmnlf, vmnlg 1098(define_insn "umin<mode>3" 1099 [(set (match_operand:VI 0 "register_operand" "=v") 1100 (umin:VI (match_operand:VI 1 "register_operand" "v") 1101 (match_operand:VI 2 "register_operand" "v")))] 1102 "TARGET_VX" 1103 "vmnl<bhfgq>\t%v0,%v1,%v2" 1104 [(set_attr "op_type" "VRR")]) 1105 1106; vmxlb, vmxlh, vmxlf, vmxlg 1107(define_insn "umax<mode>3" 1108 [(set (match_operand:VI 0 "register_operand" "=v") 1109 (umax:VI (match_operand:VI 1 "register_operand" "v") 1110 (match_operand:VI 2 "register_operand" "v")))] 1111 "TARGET_VX" 1112 "vmxl<bhfgq>\t%v0,%v1,%v2" 1113 [(set_attr "op_type" "VRR")]) 1114 1115; vmeb, vmeh, vmef 1116(define_insn "vec_widen_smult_even_<mode>" 1117 [(set (match_operand:<vec_double> 0 "register_operand" "=v") 1118 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v") 1119 (match_operand:VI_QHS 2 "register_operand" "v")] 1120 UNSPEC_VEC_SMULT_EVEN))] 1121 "TARGET_VX" 1122 "vme<bhfgq>\t%v0,%v1,%v2" 1123 [(set_attr "op_type" "VRR")]) 1124 1125; vmleb, vmleh, vmlef 1126(define_insn "vec_widen_umult_even_<mode>" 1127 [(set (match_operand:<vec_double> 0 "register_operand" "=v") 1128 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v") 1129 (match_operand:VI_QHS 2 "register_operand" "v")] 1130 UNSPEC_VEC_UMULT_EVEN))] 1131 "TARGET_VX" 1132 "vmle<bhfgq>\t%v0,%v1,%v2" 1133 [(set_attr "op_type" "VRR")]) 1134 1135; vmob, vmoh, vmof 1136(define_insn "vec_widen_smult_odd_<mode>" 1137 [(set (match_operand:<vec_double> 0 "register_operand" "=v") 1138 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v") 1139 (match_operand:VI_QHS 2 "register_operand" "v")] 1140 UNSPEC_VEC_SMULT_ODD))] 1141 "TARGET_VX" 1142 "vmo<bhfgq>\t%v0,%v1,%v2" 1143 [(set_attr "op_type" "VRR")]) 1144 1145; vmlob, vmloh, vmlof 1146(define_insn "vec_widen_umult_odd_<mode>" 1147 [(set (match_operand:<vec_double> 0 "register_operand" "=v") 1148 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v") 1149 (match_operand:VI_QHS 2 "register_operand" "v")] 1150 UNSPEC_VEC_UMULT_ODD))] 1151 "TARGET_VX" 1152 "vmlo<bhfgq>\t%v0,%v1,%v2" 1153 [(set_attr "op_type" "VRR")]) 1154 1155 1156; Widening hi/lo multiplications 1157 1158; The S/390 instructions vml and vmh return the low or high parts of 1159; the double sized result elements in the corresponding elements of 1160; the target register. That's NOT what the vec_widen_umult_lo/hi 1161; patterns are expected to do. 1162 1163; We emulate the widening lo/hi multiplies with the even/odd versions 1164; followed by a vector merge 1165 1166 1167(define_expand "vec_widen_umult_lo_<mode>" 1168 [(set (match_dup 3) 1169 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "") 1170 (match_operand:VI_QHS 2 "register_operand" "")] 1171 UNSPEC_VEC_UMULT_EVEN)) 1172 (set (match_dup 4) 1173 (unspec:<vec_double> [(match_dup 1) (match_dup 2)] 1174 UNSPEC_VEC_UMULT_ODD)) 1175 (set (match_operand:<vec_double> 0 "register_operand" "") 1176 (unspec:<vec_double> [(match_dup 3) (match_dup 4)] 1177 UNSPEC_VEC_MERGEL))] 1178 "TARGET_VX" 1179 { 1180 operands[3] = gen_reg_rtx (<vec_double>mode); 1181 operands[4] = gen_reg_rtx (<vec_double>mode); 1182 }) 1183 1184(define_expand "vec_widen_umult_hi_<mode>" 1185 [(set (match_dup 3) 1186 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "") 1187 (match_operand:VI_QHS 2 "register_operand" "")] 1188 UNSPEC_VEC_UMULT_EVEN)) 1189 (set (match_dup 4) 1190 (unspec:<vec_double> [(match_dup 1) (match_dup 2)] 1191 UNSPEC_VEC_UMULT_ODD)) 1192 (set (match_operand:<vec_double> 0 "register_operand" "") 1193 (unspec:<vec_double> [(match_dup 3) (match_dup 4)] 1194 UNSPEC_VEC_MERGEH))] 1195 "TARGET_VX" 1196 { 1197 operands[3] = gen_reg_rtx (<vec_double>mode); 1198 operands[4] = gen_reg_rtx (<vec_double>mode); 1199 }) 1200 1201(define_expand "vec_widen_smult_lo_<mode>" 1202 [(set (match_dup 3) 1203 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "") 1204 (match_operand:VI_QHS 2 "register_operand" "")] 1205 UNSPEC_VEC_SMULT_EVEN)) 1206 (set (match_dup 4) 1207 (unspec:<vec_double> [(match_dup 1) (match_dup 2)] 1208 UNSPEC_VEC_SMULT_ODD)) 1209 (set (match_operand:<vec_double> 0 "register_operand" "") 1210 (unspec:<vec_double> [(match_dup 3) (match_dup 4)] 1211 UNSPEC_VEC_MERGEL))] 1212 "TARGET_VX" 1213 { 1214 operands[3] = gen_reg_rtx (<vec_double>mode); 1215 operands[4] = gen_reg_rtx (<vec_double>mode); 1216 }) 1217 1218(define_expand "vec_widen_smult_hi_<mode>" 1219 [(set (match_dup 3) 1220 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "") 1221 (match_operand:VI_QHS 2 "register_operand" "")] 1222 UNSPEC_VEC_SMULT_EVEN)) 1223 (set (match_dup 4) 1224 (unspec:<vec_double> [(match_dup 1) (match_dup 2)] 1225 UNSPEC_VEC_SMULT_ODD)) 1226 (set (match_operand:<vec_double> 0 "register_operand" "") 1227 (unspec:<vec_double> [(match_dup 3) (match_dup 4)] 1228 UNSPEC_VEC_MERGEH))] 1229 "TARGET_VX" 1230 { 1231 operands[3] = gen_reg_rtx (<vec_double>mode); 1232 operands[4] = gen_reg_rtx (<vec_double>mode); 1233 }) 1234 1235; vec_widen_ushiftl_hi 1236; vec_widen_ushiftl_lo 1237; vec_widen_sshiftl_hi 1238; vec_widen_sshiftl_lo 1239 1240;; 1241;; Vector floating point arithmetic instructions 1242;; 1243 1244; vfasb, vfadb, wfasb, wfadb, wfaxb 1245(define_insn "add<mode>3" 1246 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1247 (plus:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1248 (match_operand:VF_HW 2 "register_operand" "v")))] 1249 "TARGET_VX" 1250 "<vw>fa<sdx>b\t%v0,%v1,%v2" 1251 [(set_attr "op_type" "VRR")]) 1252 1253; vfssb, vfsdb, wfssb, wfsdb, wfsxb 1254(define_insn "sub<mode>3" 1255 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1256 (minus:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1257 (match_operand:VF_HW 2 "register_operand" "v")))] 1258 "TARGET_VX" 1259 "<vw>fs<sdx>b\t%v0,%v1,%v2" 1260 [(set_attr "op_type" "VRR")]) 1261 1262; vfmsb, vfmdb, wfmsb, wfmdb, wfmxb 1263(define_insn "mul<mode>3" 1264 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1265 (mult:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1266 (match_operand:VF_HW 2 "register_operand" "v")))] 1267 "TARGET_VX" 1268 "<vw>fm<sdx>b\t%v0,%v1,%v2" 1269 [(set_attr "op_type" "VRR")]) 1270 1271; vfdsb, vfddb, wfdsb, wfddb, wfdxb 1272(define_insn "div<mode>3" 1273 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1274 (div:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1275 (match_operand:VF_HW 2 "register_operand" "v")))] 1276 "TARGET_VX" 1277 "<vw>fd<sdx>b\t%v0,%v1,%v2" 1278 [(set_attr "op_type" "VRR")]) 1279 1280; vfsqsb, vfsqdb, wfsqsb, wfsqdb, wfsqxb 1281(define_insn "sqrt<mode>2" 1282 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1283 (sqrt:VF_HW (match_operand:VF_HW 1 "register_operand" "v")))] 1284 "TARGET_VX" 1285 "<vw>fsq<sdx>b\t%v0,%v1" 1286 [(set_attr "op_type" "VRR")]) 1287 1288; vfmasb, vfmadb, wfmasb, wfmadb, wfmaxb 1289(define_insn "fma<mode>4" 1290 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1291 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1292 (match_operand:VF_HW 2 "register_operand" "v") 1293 (match_operand:VF_HW 3 "register_operand" "v")))] 1294 "TARGET_VX" 1295 "<vw>fma<sdx>b\t%v0,%v1,%v2,%v3" 1296 [(set_attr "op_type" "VRR")]) 1297 1298; vfmssb, vfmsdb, wfmssb, wfmsdb, wfmsxb 1299(define_insn "fms<mode>4" 1300 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1301 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1302 (match_operand:VF_HW 2 "register_operand" "v") 1303 (neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v"))))] 1304 "TARGET_VX" 1305 "<vw>fms<sdx>b\t%v0,%v1,%v2,%v3" 1306 [(set_attr "op_type" "VRR")]) 1307 1308; vfnmasb, vfnmadb, wfnmasb, wfnmadb, wfnmaxb 1309(define_insn "neg_fma<mode>4" 1310 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1311 (neg:VF_HW 1312 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1313 (match_operand:VF_HW 2 "register_operand" "v") 1314 (match_operand:VF_HW 3 "register_operand" "v"))))] 1315 "TARGET_VXE" 1316 "<vw>fnma<sdx>b\t%v0,%v1,%v2,%v3" 1317 [(set_attr "op_type" "VRR")]) 1318 1319; vfnmssb, vfnmsdb, wfnmssb, wfnmsdb, wfnmsxb 1320(define_insn "neg_fms<mode>4" 1321 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1322 (neg:VF_HW 1323 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1324 (match_operand:VF_HW 2 "register_operand" "v") 1325 (neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v")))))] 1326 "TARGET_VXE" 1327 "<vw>fnms<sdx>b\t%v0,%v1,%v2,%v3" 1328 [(set_attr "op_type" "VRR")]) 1329 1330; vflcsb, vflcdb, wflcsb, wflcdb, wflcxb 1331(define_insn "neg<mode>2" 1332 [(set (match_operand:VFT 0 "register_operand" "=v") 1333 (neg:VFT (match_operand:VFT 1 "register_operand" "v")))] 1334 "TARGET_VX" 1335 "<vw>flc<sdx>b\t%v0,%v1" 1336 [(set_attr "op_type" "VRR")]) 1337 1338; vflpsb, vflpdb, wflpsb, wflpdb, wflpxb 1339(define_insn "abs<mode>2" 1340 [(set (match_operand:VFT 0 "register_operand" "=v") 1341 (abs:VFT (match_operand:VFT 1 "register_operand" "v")))] 1342 "TARGET_VX" 1343 "<vw>flp<sdx>b\t%v0,%v1" 1344 [(set_attr "op_type" "VRR")]) 1345 1346; vflnsb, vflndb, wflnsb, wflndb, wflnxb 1347(define_insn "negabs<mode>2" 1348 [(set (match_operand:VFT 0 "register_operand" "=v") 1349 (neg:VFT (abs:VFT (match_operand:VFT 1 "register_operand" "v"))))] 1350 "TARGET_VX" 1351 "<vw>fln<sdx>b\t%v0,%v1" 1352 [(set_attr "op_type" "VRR")]) 1353 1354(define_expand "smax<mode>3" 1355 [(set (match_operand:VF_HW 0 "register_operand") 1356 (smax:VF_HW (match_operand:VF_HW 1 "register_operand") 1357 (match_operand:VF_HW 2 "register_operand")))] 1358 "TARGET_VX") 1359 1360; vfmaxsb, vfmaxdb, wfmaxsb, wfmaxdb, wfmaxxb 1361(define_insn "*smax<mode>3_vxe" 1362 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1363 (smax:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1364 (match_operand:VF_HW 2 "register_operand" "v")))] 1365 "TARGET_VXE" 1366 "<vw>fmax<sdx>b\t%v0,%v1,%v2,4" 1367 [(set_attr "op_type" "VRR")]) 1368 1369; Emulate with compare + select 1370(define_insn_and_split "*smaxv2df3_vx" 1371 [(set (match_operand:V2DF 0 "register_operand" "=v") 1372 (smax:V2DF (match_operand:V2DF 1 "register_operand" "v") 1373 (match_operand:V2DF 2 "register_operand" "v")))] 1374 "TARGET_VX && !TARGET_VXE" 1375 "#" 1376 "&& 1" 1377 [(set (match_dup 3) 1378 (not:V2DI 1379 (unge:V2DI (match_dup 2) (match_dup 1)))) 1380 (set (match_dup 0) 1381 (if_then_else:V2DF 1382 (eq (match_dup 3) (match_dup 4)) 1383 (match_dup 2) 1384 (match_dup 1)))] 1385{ 1386 operands[3] = gen_reg_rtx (V2DImode); 1387 operands[4] = CONST0_RTX (V2DImode); 1388}) 1389 1390(define_expand "smin<mode>3" 1391 [(set (match_operand:VF_HW 0 "register_operand") 1392 (smin:VF_HW (match_operand:VF_HW 1 "register_operand") 1393 (match_operand:VF_HW 2 "register_operand")))] 1394 "TARGET_VX") 1395 1396; vfminsb, vfmindb, wfminsb, wfmindb, wfminxb 1397(define_insn "*smin<mode>3_vxe" 1398 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1399 (smin:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1400 (match_operand:VF_HW 2 "register_operand" "v")))] 1401 "TARGET_VXE" 1402 "<vw>fmin<sdx>b\t%v0,%v1,%v2,4" 1403 [(set_attr "op_type" "VRR")]) 1404 1405; Emulate with compare + select 1406(define_insn_and_split "*sminv2df3_vx" 1407 [(set (match_operand:V2DF 0 "register_operand" "=v") 1408 (smin:V2DF (match_operand:V2DF 1 "register_operand" "v") 1409 (match_operand:V2DF 2 "register_operand" "v")))] 1410 "TARGET_VX && !TARGET_VXE" 1411 "#" 1412 "&& 1" 1413 [(set (match_dup 3) 1414 (not:V2DI 1415 (unge:V2DI (match_dup 2) (match_dup 1)))) 1416 (set (match_dup 0) 1417 (if_then_else:V2DF 1418 (eq (match_dup 3) (match_dup 4)) 1419 (match_dup 1) 1420 (match_dup 2)))] 1421{ 1422 operands[3] = gen_reg_rtx (V2DImode); 1423 operands[4] = CONST0_RTX (V2DImode); 1424}) 1425 1426; Vector copysign, implement using vector select 1427(define_expand "copysign<mode>3" 1428 [(set (match_operand:VFT 0 "register_operand" "") 1429 (if_then_else:VFT 1430 (eq (match_dup 3) 1431 (match_dup 4)) 1432 (match_operand:VFT 1 "register_operand" "") 1433 (match_operand:VFT 2 "register_operand" "")))] 1434 "TARGET_VX" 1435{ 1436 int sz = GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)); 1437 int prec = GET_MODE_PRECISION (GET_MODE_INNER (<tointvec>mode)); 1438 wide_int mask_val = wi::shwi (1l << (sz - 1), prec); 1439 1440 rtx mask = gen_reg_rtx (<tointvec>mode); 1441 1442 int nunits = GET_MODE_NUNITS (<tointvec>mode); 1443 rtvec v = rtvec_alloc (nunits); 1444 for (int i = 0; i < nunits; i++) 1445 RTVEC_ELT (v, i) = GEN_INT (mask_val.to_shwi ()); 1446 1447 mask = gen_rtx_CONST_VECTOR (<tointvec>mode, v); 1448 operands[3] = force_reg (<tointvec>mode, mask); 1449 operands[4] = CONST0_RTX (<tointvec>mode); 1450}) 1451 1452;; 1453;; Integer compares 1454;; 1455 1456(define_insn "*vec_cmp<VICMP_HW_OP:code><VI:mode>_nocc" 1457 [(set (match_operand:VI 2 "register_operand" "=v") 1458 (VICMP_HW_OP:VI (match_operand:VI 0 "register_operand" "v") 1459 (match_operand:VI 1 "register_operand" "v")))] 1460 "TARGET_VX" 1461 "vc<VICMP_HW_OP:insn_cmp_op><VI:bhfgq>\t%v2,%v0,%v1" 1462 [(set_attr "op_type" "VRR")]) 1463 1464 1465;; 1466;; Floating point compares 1467;; 1468 1469; vfcesb, vfcedb, wfcexb: non-signaling "==" comparison (a == b) 1470(define_insn "*vec_cmpeq<mode>_quiet_nocc" 1471 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1472 (eq:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1473 (match_operand:VFT 2 "register_operand" "v")))] 1474 "TARGET_VX" 1475 "<vw>fce<sdx>b\t%v0,%v1,%v2" 1476 [(set_attr "op_type" "VRR")]) 1477 1478; vfchsb, vfchdb, wfchxb: non-signaling > comparison (!(b u>= a)) 1479(define_insn "vec_cmpgt<mode>_quiet_nocc" 1480 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1481 (not:<tointvec> 1482 (unge:<tointvec> (match_operand:VFT 2 "register_operand" "v") 1483 (match_operand:VFT 1 "register_operand" "v"))))] 1484 "TARGET_VX" 1485 "<vw>fch<sdx>b\t%v0,%v1,%v2" 1486 [(set_attr "op_type" "VRR")]) 1487 1488(define_expand "vec_cmplt<mode>_quiet_nocc" 1489 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1490 (not:<tointvec> 1491 (unge:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1492 (match_operand:VFT 2 "register_operand" "v"))))] 1493 "TARGET_VX") 1494 1495; vfchesb, vfchedb, wfchexb: non-signaling >= comparison (!(a u< b)) 1496(define_insn "vec_cmpge<mode>_quiet_nocc" 1497 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1498 (not:<tointvec> 1499 (unlt:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1500 (match_operand:VFT 2 "register_operand" "v"))))] 1501 "TARGET_VX" 1502 "<vw>fche<sdx>b\t%v0,%v1,%v2" 1503 [(set_attr "op_type" "VRR")]) 1504 1505(define_expand "vec_cmple<mode>_quiet_nocc" 1506 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1507 (not:<tointvec> 1508 (unlt:<tointvec> (match_operand:VFT 2 "register_operand" "v") 1509 (match_operand:VFT 1 "register_operand" "v"))))] 1510 "TARGET_VX") 1511 1512; vfkesb, vfkedb, wfkexb: signaling == comparison ((a >= b) & (b >= a)) 1513(define_insn "*vec_cmpeq<mode>_signaling_nocc" 1514 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1515 (and:<tointvec> 1516 (ge:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1517 (match_operand:VFT 2 "register_operand" "v")) 1518 (ge:<tointvec> (match_dup 2) 1519 (match_dup 1))))] 1520 "TARGET_VXE" 1521 "<vw>fke<sdx>b\t%v0,%v1,%v2" 1522 [(set_attr "op_type" "VRR")]) 1523 1524; vfkhsb, vfkhdb, wfkhxb: signaling > comparison (a > b) 1525(define_insn "*vec_cmpgt<mode>_signaling_nocc" 1526 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1527 (gt:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1528 (match_operand:VFT 2 "register_operand" "v")))] 1529 "TARGET_VXE" 1530 "<vw>fkh<sdx>b\t%v0,%v1,%v2" 1531 [(set_attr "op_type" "VRR")]) 1532 1533(define_insn "*vec_cmpgt<mode>_signaling_finite_nocc" 1534 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1535 (gt:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1536 (match_operand:VFT 2 "register_operand" "v")))] 1537 "TARGET_NONSIGNALING_VECTOR_COMPARE_OK" 1538 "<vw>fch<sdx>b\t%v0,%v1,%v2" 1539 [(set_attr "op_type" "VRR")]) 1540 1541; vfkhesb, vfkhedb, wfkhexb: signaling >= comparison (a >= b) 1542(define_insn "*vec_cmpge<mode>_signaling_nocc" 1543 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1544 (ge:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1545 (match_operand:VFT 2 "register_operand" "v")))] 1546 "TARGET_VXE" 1547 "<vw>fkhe<sdx>b\t%v0,%v1,%v2" 1548 [(set_attr "op_type" "VRR")]) 1549 1550(define_insn "*vec_cmpge<mode>_signaling_finite_nocc" 1551 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1552 (ge:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1553 (match_operand:VFT 2 "register_operand" "v")))] 1554 "TARGET_NONSIGNALING_VECTOR_COMPARE_OK" 1555 "<vw>fche<sdx>b\t%v0,%v1,%v2" 1556 [(set_attr "op_type" "VRR")]) 1557 1558; Expanders for not directly supported comparisons 1559; Signaling comparisons must be expressed via signaling rtxes only, 1560; and quiet comparisons must be expressed via quiet rtxes only. 1561 1562; UNGT a u> b -> !!(b u< a) 1563(define_expand "vec_cmpungt<mode>" 1564 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1565 (not:<tointvec> 1566 (unlt:<tointvec> (match_operand:VFT 2 "register_operand" "v") 1567 (match_operand:VFT 1 "register_operand" "v")))) 1568 (set (match_dup 0) 1569 (not:<tointvec> (match_dup 0)))] 1570 "TARGET_VX") 1571 1572; UNGE a u>= b -> !!(a u>= b) 1573(define_expand "vec_cmpunge<mode>" 1574 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1575 (not:<tointvec> 1576 (unge:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1577 (match_operand:VFT 2 "register_operand" "v")))) 1578 (set (match_dup 0) 1579 (not:<tointvec> (match_dup 0)))] 1580 "TARGET_VX") 1581 1582; UNEQ a u== b -> !(!(a u>= b) | !(b u>= a)) 1583(define_expand "vec_cmpuneq<mode>" 1584 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1585 (not:<tointvec> 1586 (unge:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1587 (match_operand:VFT 2 "register_operand" "v")))) 1588 (set (match_dup 3) 1589 (not:<tointvec> 1590 (unge:<tointvec> (match_dup 2) 1591 (match_dup 1)))) 1592 (set (match_dup 0) 1593 (ior:<tointvec> (match_dup 0) 1594 (match_dup 3))) 1595 (set (match_dup 0) 1596 (not:<tointvec> (match_dup 0)))] 1597 "TARGET_VX" 1598{ 1599 operands[3] = gen_reg_rtx (<tointvec>mode); 1600}) 1601 1602; LTGT a <> b -> a > b | b > a 1603(define_expand "vec_cmpltgt<mode>" 1604 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1605 (gt:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1606 (match_operand:VFT 2 "register_operand" "v"))) 1607 (set (match_dup 3) (gt:<tointvec> (match_dup 2) (match_dup 1))) 1608 (set (match_dup 0) (ior:<tointvec> (match_dup 0) (match_dup 3)))] 1609 "TARGET_VXE" 1610{ 1611 operands[3] = gen_reg_rtx (<tointvec>mode); 1612}) 1613 1614; ORDERED (a, b): !(a u< b) | !(a u>= b) 1615(define_expand "vec_cmpordered<mode>" 1616 [(set (match_operand:<tointvec> 0 "register_operand" "=v") 1617 (not:<tointvec> 1618 (unlt:<tointvec> (match_operand:VFT 1 "register_operand" "v") 1619 (match_operand:VFT 2 "register_operand" "v")))) 1620 (set (match_dup 3) 1621 (not:<tointvec> 1622 (unge:<tointvec> (match_dup 1) 1623 (match_dup 2)))) 1624 (set (match_dup 0) 1625 (ior:<tointvec> (match_dup 0) 1626 (match_dup 3)))] 1627 "TARGET_VX" 1628{ 1629 operands[3] = gen_reg_rtx (<tointvec>mode); 1630}) 1631 1632; UNORDERED (a, b): !ORDERED (a, b) 1633(define_expand "vec_cmpunordered<mode>" 1634 [(match_operand:<tointvec> 0 "register_operand" "=v") 1635 (match_operand:VFT 1 "register_operand" "v") 1636 (match_operand:VFT 2 "register_operand" "v")] 1637 "TARGET_VX" 1638{ 1639 emit_insn (gen_vec_cmpordered<mode> (operands[0], operands[1], operands[2])); 1640 emit_insn (gen_rtx_SET (operands[0], 1641 gen_rtx_NOT (<tointvec>mode, operands[0]))); 1642 DONE; 1643}) 1644 1645(define_code_iterator VEC_CMP_EXPAND 1646 [ungt unge uneq ltgt ordered unordered]) 1647 1648(define_expand "vec_cmp<code>" 1649 [(match_operand 0 "register_operand" "") 1650 (VEC_CMP_EXPAND (match_operand 1 "register_operand" "") 1651 (match_operand 2 "register_operand" ""))] 1652 "TARGET_VX" 1653{ 1654 if (GET_MODE (operands[1]) == V4SFmode) 1655 emit_insn (gen_vec_cmp<code>v4sf (operands[0], operands[1], operands[2])); 1656 else if (GET_MODE (operands[1]) == V2DFmode) 1657 emit_insn (gen_vec_cmp<code>v2df (operands[0], operands[1], operands[2])); 1658 else 1659 gcc_unreachable (); 1660 1661 DONE; 1662}) 1663 1664(define_insn "*vec_load_pair<mode>" 1665 [(set (match_operand:V_HW_64 0 "register_operand" "=v,v") 1666 (vec_concat:V_HW_64 (match_operand:<non_vec> 1 "register_operand" "d,v") 1667 (match_operand:<non_vec> 2 "register_operand" "d,v")))] 1668 "TARGET_VX" 1669 "@ 1670 vlvgp\t%v0,%1,%2 1671 vmrhg\t%v0,%v1,%v2" 1672 [(set_attr "op_type" "VRR,VRR")]) 1673 1674(define_insn "vllv16qi" 1675 [(set (match_operand:V16QI 0 "register_operand" "=v") 1676 (unspec:V16QI [(match_operand:SI 1 "register_operand" "d") 1677 (match_operand:BLK 2 "memory_operand" "Q")] 1678 UNSPEC_VEC_LOAD_LEN))] 1679 "TARGET_VX" 1680 "vll\t%v0,%1,%2" 1681 [(set_attr "op_type" "VRS")]) 1682 1683; vfenebs, vfenehs, vfenefs 1684; vfenezbs, vfenezhs, vfenezfs 1685(define_insn "vec_vfenes<mode>" 1686 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") 1687 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") 1688 (match_operand:VI_HW_QHS 2 "register_operand" "v") 1689 (match_operand:QI 3 "const_mask_operand" "C")] 1690 UNSPEC_VEC_VFENE)) 1691 (set (reg:CCRAW CC_REGNUM) 1692 (unspec:CCRAW [(match_dup 1) 1693 (match_dup 2) 1694 (match_dup 3)] 1695 UNSPEC_VEC_VFENECC))] 1696 "TARGET_VX" 1697{ 1698 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]); 1699 1700 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS))); 1701 flags &= ~VSTRING_FLAG_CS; 1702 1703 if (flags == VSTRING_FLAG_ZS) 1704 return "vfenez<bhfgq>s\t%v0,%v1,%v2"; 1705 return "vfene<bhfgq>s\t%v0,%v1,%v2"; 1706} 1707 [(set_attr "op_type" "VRR")]) 1708 1709 1710; Vector select 1711 1712; The following splitters simplify vec_sel for constant 0 or -1 1713; selection sources. This is required to generate efficient code for 1714; vcond. 1715 1716; a = b == c; 1717(define_split 1718 [(set (match_operand:V 0 "register_operand" "") 1719 (if_then_else:V 1720 (eq (match_operand:<tointvec> 3 "register_operand" "") 1721 (match_operand:V 4 "const0_operand" "")) 1722 (match_operand:V 1 "const0_operand" "") 1723 (match_operand:V 2 "all_ones_operand" "")))] 1724 "TARGET_VX" 1725 [(set (match_dup 0) (match_dup 3))] 1726{ 1727 PUT_MODE (operands[3], <V:MODE>mode); 1728}) 1729 1730; a = ~(b == c) 1731(define_split 1732 [(set (match_operand:V 0 "register_operand" "") 1733 (if_then_else:V 1734 (eq (match_operand:<tointvec> 3 "register_operand" "") 1735 (match_operand:V 4 "const0_operand" "")) 1736 (match_operand:V 1 "all_ones_operand" "") 1737 (match_operand:V 2 "const0_operand" "")))] 1738 "TARGET_VX" 1739 [(set (match_dup 0) (not:V (match_dup 3)))] 1740{ 1741 PUT_MODE (operands[3], <V:MODE>mode); 1742}) 1743 1744; a = b != c 1745(define_split 1746 [(set (match_operand:V 0 "register_operand" "") 1747 (if_then_else:V 1748 (ne (match_operand:<tointvec> 3 "register_operand" "") 1749 (match_operand:V 4 "const0_operand" "")) 1750 (match_operand:V 1 "all_ones_operand" "") 1751 (match_operand:V 2 "const0_operand" "")))] 1752 "TARGET_VX" 1753 [(set (match_dup 0) (match_dup 3))] 1754{ 1755 PUT_MODE (operands[3], <V:MODE>mode); 1756}) 1757 1758; a = ~(b != c) 1759(define_split 1760 [(set (match_operand:V 0 "register_operand" "") 1761 (if_then_else:V 1762 (ne (match_operand:<tointvec> 3 "register_operand" "") 1763 (match_operand:V 4 "const0_operand" "")) 1764 (match_operand:V 1 "const0_operand" "") 1765 (match_operand:V 2 "all_ones_operand" "")))] 1766 "TARGET_VX" 1767 [(set (match_dup 0) (not:V (match_dup 3)))] 1768{ 1769 PUT_MODE (operands[3], <V:MODE>mode); 1770}) 1771 1772; op0 = op3 == 0 ? op1 : op2 1773(define_insn "*vec_sel0<mode>" 1774 [(set (match_operand:V 0 "register_operand" "=v") 1775 (if_then_else:V 1776 (eq (match_operand:<tointvec> 3 "register_operand" "v") 1777 (match_operand:<tointvec> 4 "const0_operand" "")) 1778 (match_operand:V 1 "register_operand" "v") 1779 (match_operand:V 2 "register_operand" "v")))] 1780 "TARGET_VX" 1781 "vsel\t%v0,%2,%1,%3" 1782 [(set_attr "op_type" "VRR")]) 1783 1784; op0 = !op3 == 0 ? op1 : op2 1785(define_insn "*vec_sel0<mode>" 1786 [(set (match_operand:V 0 "register_operand" "=v") 1787 (if_then_else:V 1788 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v")) 1789 (match_operand:<tointvec> 4 "const0_operand" "")) 1790 (match_operand:V 1 "register_operand" "v") 1791 (match_operand:V 2 "register_operand" "v")))] 1792 "TARGET_VX" 1793 "vsel\t%v0,%1,%2,%3" 1794 [(set_attr "op_type" "VRR")]) 1795 1796; op0 = op3 == -1 ? op1 : op2 1797(define_insn "*vec_sel1<mode>" 1798 [(set (match_operand:V 0 "register_operand" "=v") 1799 (if_then_else:V 1800 (eq (match_operand:<tointvec> 3 "register_operand" "v") 1801 (match_operand:<tointvec> 4 "all_ones_operand" "")) 1802 (match_operand:V 1 "register_operand" "v") 1803 (match_operand:V 2 "register_operand" "v")))] 1804 "TARGET_VX" 1805 "vsel\t%v0,%1,%2,%3" 1806 [(set_attr "op_type" "VRR")]) 1807 1808; op0 = !op3 == -1 ? op1 : op2 1809(define_insn "*vec_sel1<mode>" 1810 [(set (match_operand:V 0 "register_operand" "=v") 1811 (if_then_else:V 1812 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v")) 1813 (match_operand:<tointvec> 4 "all_ones_operand" "")) 1814 (match_operand:V 1 "register_operand" "v") 1815 (match_operand:V 2 "register_operand" "v")))] 1816 "TARGET_VX" 1817 "vsel\t%v0,%2,%1,%3" 1818 [(set_attr "op_type" "VRR")]) 1819 1820; vec_pack_trunc 1821 1822; vpkh, vpkf, vpkg 1823(define_insn "vec_pack_trunc_<mode>" 1824 [(set (match_operand:<vec_half> 0 "register_operand" "=v") 1825 (vec_concat:<vec_half> 1826 (truncate:<vec_halfhalf> 1827 (match_operand:VI_HW_HSD 1 "register_operand" "v")) 1828 (truncate:<vec_halfhalf> 1829 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))] 1830 "TARGET_VX" 1831 "vpk<bhfgq>\t%0,%1,%2" 1832 [(set_attr "op_type" "VRR")]) 1833 1834; vpksh, vpksf, vpksg 1835(define_insn "vec_pack_ssat_<mode>" 1836 [(set (match_operand:<vec_half> 0 "register_operand" "=v") 1837 (vec_concat:<vec_half> 1838 (ss_truncate:<vec_halfhalf> 1839 (match_operand:VI_HW_HSD 1 "register_operand" "v")) 1840 (ss_truncate:<vec_halfhalf> 1841 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))] 1842 "TARGET_VX" 1843 "vpks<bhfgq>\t%0,%1,%2" 1844 [(set_attr "op_type" "VRR")]) 1845 1846; vpklsh, vpklsf, vpklsg 1847(define_insn "vec_pack_usat_<mode>" 1848 [(set (match_operand:<vec_half> 0 "register_operand" "=v") 1849 (vec_concat:<vec_half> 1850 (us_truncate:<vec_halfhalf> 1851 (match_operand:VI_HW_HSD 1 "register_operand" "v")) 1852 (us_truncate:<vec_halfhalf> 1853 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))] 1854 "TARGET_VX" 1855 "vpkls<bhfgq>\t%0,%1,%2" 1856 [(set_attr "op_type" "VRR")]) 1857 1858;; vector unpack v16qi 1859 1860; signed 1861 1862(define_insn "vec_unpacks_hi_v16qi" 1863 [(set (match_operand:V8HI 0 "register_operand" "=v") 1864 (sign_extend:V8HI 1865 (vec_select:V8QI 1866 (match_operand:V16QI 1 "register_operand" "v") 1867 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3) 1868 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] 1869 "TARGET_VX" 1870 "vuphb\t%0,%1" 1871 [(set_attr "op_type" "VRR")]) 1872 1873(define_insn "vec_unpacks_lo_v16qi" 1874 [(set (match_operand:V8HI 0 "register_operand" "=v") 1875 (sign_extend:V8HI 1876 (vec_select:V8QI 1877 (match_operand:V16QI 1 "register_operand" "v") 1878 (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11) 1879 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))] 1880 "TARGET_VX" 1881 "vuplb\t%0,%1" 1882 [(set_attr "op_type" "VRR")]) 1883 1884; unsigned 1885 1886(define_insn "vec_unpacku_hi_v16qi" 1887 [(set (match_operand:V8HI 0 "register_operand" "=v") 1888 (zero_extend:V8HI 1889 (vec_select:V8QI 1890 (match_operand:V16QI 1 "register_operand" "v") 1891 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3) 1892 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] 1893 "TARGET_VX" 1894 "vuplhb\t%0,%1" 1895 [(set_attr "op_type" "VRR")]) 1896 1897(define_insn "vec_unpacku_lo_v16qi" 1898 [(set (match_operand:V8HI 0 "register_operand" "=v") 1899 (zero_extend:V8HI 1900 (vec_select:V8QI 1901 (match_operand:V16QI 1 "register_operand" "v") 1902 (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11) 1903 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))] 1904 "TARGET_VX" 1905 "vupllb\t%0,%1" 1906 [(set_attr "op_type" "VRR")]) 1907 1908;; vector unpack v8hi 1909 1910; signed 1911 1912(define_insn "vec_unpacks_hi_v8hi" 1913 [(set (match_operand:V4SI 0 "register_operand" "=v") 1914 (sign_extend:V4SI 1915 (vec_select:V4HI 1916 (match_operand:V8HI 1 "register_operand" "v") 1917 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))] 1918 "TARGET_VX" 1919 "vuphh\t%0,%1" 1920 [(set_attr "op_type" "VRR")]) 1921 1922(define_insn "vec_unpacks_lo_v8hi" 1923 [(set (match_operand:V4SI 0 "register_operand" "=v") 1924 (sign_extend:V4SI 1925 (vec_select:V4HI 1926 (match_operand:V8HI 1 "register_operand" "v") 1927 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] 1928 "TARGET_VX" 1929 "vuplhw\t%0,%1" 1930 [(set_attr "op_type" "VRR")]) 1931 1932; unsigned 1933 1934(define_insn "vec_unpacku_hi_v8hi" 1935 [(set (match_operand:V4SI 0 "register_operand" "=v") 1936 (zero_extend:V4SI 1937 (vec_select:V4HI 1938 (match_operand:V8HI 1 "register_operand" "v") 1939 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))] 1940 "TARGET_VX" 1941 "vuplhh\t%0,%1" 1942 [(set_attr "op_type" "VRR")]) 1943 1944(define_insn "vec_unpacku_lo_v8hi" 1945 [(set (match_operand:V4SI 0 "register_operand" "=v") 1946 (zero_extend:V4SI 1947 (vec_select:V4HI 1948 (match_operand:V8HI 1 "register_operand" "v") 1949 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] 1950 "TARGET_VX" 1951 "vupllh\t%0,%1" 1952 [(set_attr "op_type" "VRR")]) 1953 1954;; vector unpack v4si 1955 1956; signed 1957 1958(define_insn "vec_unpacks_hi_v4si" 1959 [(set (match_operand:V2DI 0 "register_operand" "=v") 1960 (sign_extend:V2DI 1961 (vec_select:V2SI 1962 (match_operand:V4SI 1 "register_operand" "v") 1963 (parallel [(const_int 0)(const_int 1)]))))] 1964 "TARGET_VX" 1965 "vuphf\t%0,%1" 1966 [(set_attr "op_type" "VRR")]) 1967 1968(define_insn "vec_unpacks_lo_v4si" 1969 [(set (match_operand:V2DI 0 "register_operand" "=v") 1970 (sign_extend:V2DI 1971 (vec_select:V2SI 1972 (match_operand:V4SI 1 "register_operand" "v") 1973 (parallel [(const_int 2)(const_int 3)]))))] 1974 "TARGET_VX" 1975 "vuplf\t%0,%1" 1976 [(set_attr "op_type" "VRR")]) 1977 1978; unsigned 1979 1980(define_insn "vec_unpacku_hi_v4si" 1981 [(set (match_operand:V2DI 0 "register_operand" "=v") 1982 (zero_extend:V2DI 1983 (vec_select:V2SI 1984 (match_operand:V4SI 1 "register_operand" "v") 1985 (parallel [(const_int 0)(const_int 1)]))))] 1986 "TARGET_VX" 1987 "vuplhf\t%0,%1" 1988 [(set_attr "op_type" "VRR")]) 1989 1990(define_insn "vec_unpacku_lo_v4si" 1991 [(set (match_operand:V2DI 0 "register_operand" "=v") 1992 (zero_extend:V2DI 1993 (vec_select:V2SI 1994 (match_operand:V4SI 1 "register_operand" "v") 1995 (parallel [(const_int 2)(const_int 3)]))))] 1996 "TARGET_VX" 1997 "vupllf\t%0,%1" 1998 [(set_attr "op_type" "VRR")]) 1999 2000;; vector load lengthened 2001 2002; vflls float -> double 2003(define_insn "*vec_extendv4sf" 2004 [(set (match_operand:V2DF 0 "register_operand" "=v") 2005 (float_extend:V2DF 2006 (vec_select:V2SF 2007 (match_operand:V4SF 1 "register_operand" "v") 2008 (parallel [(const_int 0) (const_int 2)]))))] 2009 "TARGET_VX" 2010 "vldeb\t%v0,%v1" 2011 [(set_attr "op_type" "VRR")]) 2012 2013(define_expand "vec_unpacks_lo_v4sf" 2014 [(set (match_dup 2) 2015 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") 2016 (match_dup 1)] 2017 UNSPEC_VEC_MERGEL)) 2018 (set (match_operand:V2DF 0 "register_operand" "=v") 2019 (float_extend:V2DF 2020 (vec_select:V2SF 2021 (match_dup 2) 2022 (parallel [(const_int 0) (const_int 2)]))))] 2023 "TARGET_VX" 2024{ operands[2] = gen_reg_rtx(V4SFmode); }) 2025 2026(define_expand "vec_unpacks_hi_v4sf" 2027 [(set (match_dup 2) 2028 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") 2029 (match_dup 1)] 2030 UNSPEC_VEC_MERGEH)) 2031 (set (match_operand:V2DF 0 "register_operand" "=v") 2032 (float_extend:V2DF 2033 (vec_select:V2SF 2034 (match_dup 2) 2035 (parallel [(const_int 0) (const_int 2)]))))] 2036 "TARGET_VX" 2037{ operands[2] = gen_reg_rtx(V4SFmode); }) 2038 2039 2040; double -> long double 2041(define_insn "*vec_extendv2df" 2042 [(set (match_operand:V1TF 0 "register_operand" "=v") 2043 (float_extend:V1TF 2044 (vec_select:V1DF 2045 (match_operand:V2DF 1 "register_operand" "v") 2046 (parallel [(const_int 0)]))))] 2047 "TARGET_VXE" 2048 "wflld\t%v0,%v1" 2049 [(set_attr "op_type" "VRR")]) 2050 2051(define_expand "vec_unpacks_lo_v2df" 2052 [(set (match_dup 2) 2053 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "v") 2054 (match_dup 1)] 2055 UNSPEC_VEC_MERGEL)) 2056 (set (match_operand:V1TF 0 "register_operand" "=v") 2057 (float_extend:V1TF 2058 (vec_select:V1DF 2059 (match_dup 2) 2060 (parallel [(const_int 0)]))))] 2061 "TARGET_VXE" 2062{ operands[2] = gen_reg_rtx (V2DFmode); }) 2063 2064(define_expand "vec_unpacks_hi_v2df" 2065 [(set (match_dup 2) 2066 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "v") 2067 (match_dup 1)] 2068 UNSPEC_VEC_MERGEH)) 2069 (set (match_operand:V1TF 0 "register_operand" "=v") 2070 (float_extend:V1TF 2071 (vec_select:V1DF 2072 (match_dup 2) 2073 (parallel [(const_int 0)]))))] 2074 "TARGET_VXE" 2075{ operands[2] = gen_reg_rtx (V2DFmode); }) 2076 2077 2078; 2 x v2df -> 1 x v4sf 2079(define_expand "vec_pack_trunc_v2df" 2080 [(set (match_dup 3) 2081 (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "") 2082 (const_int VEC_INEXACT) 2083 (const_int VEC_RND_CURRENT)] 2084 UNSPEC_VEC_VFLR)) 2085 (set (match_dup 4) 2086 (unspec:V4SF [(match_operand:V2DF 2 "register_operand" "") 2087 (const_int VEC_INEXACT) 2088 (const_int VEC_RND_CURRENT)] 2089 UNSPEC_VEC_VFLR)) 2090 (set (match_dup 6) 2091 (unspec:V16QI [(subreg:V16QI (match_dup 3) 0) 2092 (subreg:V16QI (match_dup 4) 0) 2093 (match_dup 5)] 2094 UNSPEC_VEC_PERM)) 2095 (set (match_operand:V4SF 0 "register_operand" "") 2096 (subreg:V4SF (match_dup 6) 0))] 2097 "TARGET_VX" 2098{ 2099 rtx constv, perm[16]; 2100 int i; 2101 2102 for (i = 0; i < 4; ++i) 2103 { 2104 perm[i] = GEN_INT (i); 2105 perm[i + 4] = GEN_INT (i + 8); 2106 perm[i + 8] = GEN_INT (i + 16); 2107 perm[i + 12] = GEN_INT (i + 24); 2108 } 2109 constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)); 2110 2111 operands[3] = gen_reg_rtx (V4SFmode); 2112 operands[4] = gen_reg_rtx (V4SFmode); 2113 operands[5] = force_reg (V16QImode, constv); 2114 operands[6] = gen_reg_rtx (V16QImode); 2115}) 2116 2117; 2118; BFP <-> integer conversions 2119; 2120 2121; signed integer to floating point 2122 2123; op2: inexact exception not suppressed (IEEE 754 2008) 2124; op3: according to current rounding mode 2125; vcdgb, vcefb 2126(define_insn "float<VX_VEC_CONV_INT:mode><VX_VEC_CONV_BFP:mode>2" 2127 [(set (match_operand:VX_VEC_CONV_BFP 0 "register_operand" "=v") 2128 (float:VX_VEC_CONV_BFP (match_operand:VX_VEC_CONV_INT 1 "register_operand" "v")))] 2129 "TARGET_VX 2130 && GET_MODE_UNIT_SIZE (<VX_VEC_CONV_INT:MODE>mode) == GET_MODE_UNIT_SIZE (<VX_VEC_CONV_BFP:MODE>mode)" 2131 "vc<VX_VEC_CONV_BFP:xde><VX_VEC_CONV_INT:bhfgq>b\t%v0,%v1,0,0" 2132 [(set_attr "op_type" "VRR")]) 2133 2134; unsigned integer to floating point 2135 2136; op2: inexact exception not suppressed (IEEE 754 2008) 2137; op3: according to current rounding mode 2138; vcdlgb, vcelfb 2139(define_insn "floatuns<VX_VEC_CONV_INT:mode><VX_VEC_CONV_BFP:mode>2" 2140 [(set (match_operand:VX_VEC_CONV_BFP 0 "register_operand" "=v") 2141 (unsigned_float:VX_VEC_CONV_BFP (match_operand:VX_VEC_CONV_INT 1 "register_operand" "v")))] 2142 "TARGET_VX 2143 && GET_MODE_UNIT_SIZE (<VX_VEC_CONV_INT:MODE>mode) == GET_MODE_UNIT_SIZE (<VX_VEC_CONV_BFP:MODE>mode)" 2144 "vc<VX_VEC_CONV_BFP:xde>l<VX_VEC_CONV_INT:bhfgq>b\t%v0,%v1,0,0" 2145 [(set_attr "op_type" "VRR")]) 2146 2147; floating point to signed integer 2148 2149; op2: inexact exception not suppressed (IEEE 754 2008) 2150; op3: rounding mode 5 (round towards 0 C11 6.3.1.4) 2151; vcgdb, vcfeb 2152(define_insn "fix_trunc<VX_VEC_CONV_BFP:mode><VX_VEC_CONV_INT:mode>2" 2153 [(set (match_operand:VX_VEC_CONV_INT 0 "register_operand" "=v") 2154 (fix:VX_VEC_CONV_INT (match_operand:VX_VEC_CONV_BFP 1 "register_operand" "v")))] 2155 "TARGET_VX 2156 && GET_MODE_UNIT_SIZE (<VX_VEC_CONV_INT:MODE>mode) == GET_MODE_UNIT_SIZE (<VX_VEC_CONV_BFP:MODE>mode)" 2157 "vc<VX_VEC_CONV_INT:bhfgq><VX_VEC_CONV_BFP:xde>b\t%v0,%v1,0,5" 2158 [(set_attr "op_type" "VRR")]) 2159 2160; floating point to unsigned integer 2161 2162; op2: inexact exception not suppressed (IEEE 754 2008) 2163; op3: rounding mode 5 (round towards 0 C11 6.3.1.4) 2164; vclgdb, vclfeb 2165(define_insn "fixuns_trunc<VX_VEC_CONV_BFP:mode><VX_VEC_CONV_INT:mode>2" 2166 [(set (match_operand:VX_VEC_CONV_INT 0 "register_operand" "=v") 2167 (unsigned_fix:VX_VEC_CONV_INT (match_operand:VX_VEC_CONV_BFP 1 "register_operand" "v")))] 2168 "TARGET_VX 2169 && GET_MODE_UNIT_SIZE (<VX_VEC_CONV_INT:MODE>mode) == GET_MODE_UNIT_SIZE (<VX_VEC_CONV_BFP:MODE>mode)" 2170 "vcl<VX_VEC_CONV_INT:bhfgq><VX_VEC_CONV_BFP:xde>b\t%v0,%v1,0,5" 2171 [(set_attr "op_type" "VRR")]) 2172 2173; 2174; Vector byte swap patterns 2175; 2176 2177; FIXME: The bswap rtl standard name currently does not appear to be 2178; used for vector modes. 2179(define_expand "bswap<mode>" 2180 [(parallel 2181 [(set (match_operand:VT_HW_HSDT 0 "nonimmediate_operand" "") 2182 (bswap:VT_HW_HSDT (match_operand:VT_HW_HSDT 1 "nonimmediate_operand" ""))) 2183 (use (match_dup 2))])] 2184 "TARGET_VX" 2185{ 2186 static char p[4][16] = 2187 { { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 }, /* H */ 2188 { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 }, /* S */ 2189 { 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 }, /* D */ 2190 { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 } }; /* T */ 2191 char *perm; 2192 rtx perm_rtx[16]; 2193 2194 switch (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode))) 2195 { 2196 case 2: perm = p[0]; break; 2197 case 4: perm = p[1]; break; 2198 case 8: perm = p[2]; break; 2199 case 16: perm = p[3]; break; 2200 default: gcc_unreachable (); 2201 } 2202 for (int i = 0; i < 16; i++) 2203 perm_rtx[i] = GEN_INT (perm[i]); 2204 2205 operands[2] = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm_rtx)); 2206 2207 /* Without vxe2 we do not have byte swap instructions dealing 2208 directly with memory operands. So instead of waiting until 2209 reload to fix that up switch over to vector permute right 2210 now. */ 2211 if (!TARGET_VXE2) 2212 { 2213 rtx in = force_reg (V16QImode, simplify_gen_subreg (V16QImode, operands[1], <MODE>mode, 0)); 2214 rtx permute = force_reg (V16QImode, force_const_mem (V16QImode, operands[2])); 2215 rtx out = gen_reg_rtx (V16QImode); 2216 2217 emit_insn (gen_vec_permv16qi (out, in, in, permute)); 2218 emit_move_insn (operands[0], simplify_gen_subreg (<MODE>mode, out, V16QImode, 0)); 2219 DONE; 2220 } 2221}) 2222 2223; Switching late to the reg-reg variant requires the vector permute 2224; pattern to be pushed into literal pool and allocating a vector 2225; register to load it into. We rely on both being provided by LRA 2226; when fixing up the v constraint for operand 2. 2227 2228; permute_pattern_operand: general_operand would reject the permute 2229; pattern constants since these are not accepted by 2230; s390_legimitate_constant_p 2231 2232; ^R: Prevent these alternatives from being chosen if it would require 2233; pushing the operand into memory first 2234 2235; vlbrh, vlbrf, vlbrg, vlbrq, vstbrh, vstbrf, vstbrg, vstbrq 2236(define_insn_and_split "*bswap<mode>" 2237 [(set (match_operand:VT_HW_HSDT 0 "nonimmediate_operand" "=v, v,^R") 2238 (bswap:VT_HW_HSDT (match_operand:VT_HW_HSDT 1 "nonimmediate_operand" "v,^R, v"))) 2239 (use (match_operand:V16QI 2 "permute_pattern_operand" "v, X, X"))] 2240 "TARGET_VXE2" 2241 "@ 2242 # 2243 vlbr<bhfgq>\t%v0,%v1 2244 vstbr<bhfgq>\t%v1,%v0" 2245 "&& reload_completed 2246 && !memory_operand (operands[0], <MODE>mode) 2247 && !memory_operand (operands[1], <MODE>mode)" 2248 [(set (match_dup 0) 2249 (subreg:VT_HW_HSDT 2250 (unspec:V16QI [(subreg:V16QI (match_dup 1) 0) 2251 (subreg:V16QI (match_dup 1) 0) 2252 (match_dup 2)] 2253 UNSPEC_VEC_PERM) 0))] 2254 "" 2255 [(set_attr "op_type" "*,VRX,VRX")]) 2256 2257; reduc_smin 2258; reduc_smax 2259; reduc_umin 2260; reduc_umax 2261 2262; vec_pack_sfix_trunc: convert + pack ? 2263; vec_pack_ufix_trunc 2264; vec_unpacks_float_hi 2265; vec_unpacks_float_lo 2266; vec_unpacku_float_hi 2267; vec_unpacku_float_lo 2268