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