1;;- Instruction patterns for the System z vector facility 2;; Copyright (C) 2015-2021 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 for having two iterators expanding independently e.g. vcond. 31; It's similar to V_HW, but not fully identical: V1TI is not included, because 32; there are no 128-bit compares. 33(define_mode_iterator V_HW [V16QI V8HI V4SI V2DI (V1TI "TARGET_VXE") V2DF 34 (V4SF "TARGET_VXE") (V1TF "TARGET_VXE") 35 (TF "TARGET_VXE")]) 36(define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE") 37 (V1TF "TARGET_VXE") (TF "TARGET_VXE")]) 38 39(define_mode_iterator VT_HW_HSDT [V8HI V4SI V4SF V2DI V2DF V1TI V1TF TI TF]) 40(define_mode_iterator V_HW_HSD [V8HI V4SI (V4SF "TARGET_VXE") V2DI V2DF]) 41 42; Including TI for instructions that support it (va, vn, ...) 43(define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI (V4SF "TARGET_VXE") (V1TF "TARGET_VXE")]) 44 45; All full size integer vector modes supported in a vector register + TImode 46(define_mode_iterator VIT_HW [V16QI V8HI V4SI V2DI V1TI TI]) 47(define_mode_iterator VI_HW [V16QI V8HI V4SI V2DI]) 48(define_mode_iterator VI_HW_QHS [V16QI V8HI V4SI]) 49(define_mode_iterator VI_HW_HSD [V8HI V4SI V2DI]) 50(define_mode_iterator VI_HW_HS [V8HI V4SI]) 51(define_mode_iterator VI_HW_QH [V16QI V8HI]) 52 53; Directly supported vector modes with a certain number of elements 54(define_mode_iterator V_HW_2 [V2DI V2DF]) 55(define_mode_iterator V_HW_4 [V4SI V4SF]) 56 57; All integer vector modes supported in a vector register + TImode 58(define_mode_iterator VIT [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1TI TI]) 59(define_mode_iterator VI [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI]) 60(define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI]) 61 62(define_mode_iterator VFT [(V1SF "TARGET_VXE") (V2SF "TARGET_VXE") (V4SF "TARGET_VXE") 63 V1DF V2DF 64 (V1TF "TARGET_VXE") (TF "TARGET_VXE")]) 65 66; FP vector modes directly supported by the HW. This does not include 67; vector modes using only part of a vector register and should be used 68; for instructions which might trigger IEEE exceptions. 69(define_mode_iterator VF_HW [(V4SF "TARGET_VXE") V2DF (V1TF "TARGET_VXE") 70 (TF "TARGET_VXE")]) 71 72(define_mode_iterator V_8 [V1QI]) 73(define_mode_iterator V_16 [V2QI V1HI]) 74(define_mode_iterator V_32 [V4QI V2HI V1SI V1SF]) 75(define_mode_iterator V_64 [V8QI V4HI V2SI V2SF V1DI V1DF]) 76(define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF 77 (TF "TARGET_VXE")]) 78(define_mode_iterator V_128_NOSINGLE [V16QI V8HI V4SI V4SF V2DI V2DF]) 79 80; 32 bit int<->fp vector conversion instructions are available since VXE2 (z15). 81(define_mode_iterator VX_VEC_CONV_BFP [V2DF (V4SF "TARGET_VXE2")]) 82(define_mode_iterator VX_VEC_CONV_INT [V2DI (V4SI "TARGET_VXE2")]) 83 84; Empty string for all but TImode. This is used to hide the TImode 85; expander name in case it is defined already. See addti3 for an 86; example. 87(define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "") 88 (V1HI "") (V2HI "") (V4HI "") (V8HI "") 89 (V1SI "") (V2SI "") (V4SI "") 90 (V1DI "") (V2DI "") 91 (V1TI "") (TI "*") 92 (V1SF "") (V2SF "") (V4SF "") 93 (V1DF "") (V2DF "") 94 (V1TF "") (TF "")]) 95 96;; Facilitate dispatching TFmode expanders on z14+. 97(define_mode_attr tf_vr [(TF "_vr") (V4SF "") (V2DF "") (V1TF "") (V1SF "") 98 (V2SF "") (V1DF "") (V16QI "") (V8HI "") (V4SI "") 99 (V2DI "") (V1TI "")]) 100 101; The element type of the vector. 102(define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI") 103 (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI") 104 (V1SI "SI") (V2SI "SI") (V4SI "SI") 105 (V1DI "DI") (V2DI "DI") 106 (V1TI "TI") (TI "TI") 107 (V1SF "SF") (V2SF "SF") (V4SF "SF") 108 (V1DF "DF") (V2DF "DF") 109 (V1TF "TF") (TF "TF")]) 110 111; Like above, but in lower case. 112(define_mode_attr non_vec_l[(V1QI "qi") (V2QI "qi") (V4QI "qi") (V8QI "qi") 113 (V16QI "qi") 114 (V1HI "hi") (V2HI "hi") (V4HI "hi") (V8HI "hi") 115 (V1SI "si") (V2SI "si") (V4SI "si") 116 (V1DI "di") (V2DI "di") 117 (V1TI "ti") (TI "ti") 118 (V1SF "sf") (V2SF "sf") (V4SF "sf") 119 (V1DF "df") (V2DF "df") 120 (V1TF "tf") (TF "tf")]) 121 122; The instruction suffix for integer instructions and instructions 123; which do not care about whether it is floating point or integer. 124(define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b") 125 (V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h") 126 (V1SI "f") (V2SI "f") (V4SI "f") 127 (V1DI "g") (V2DI "g") 128 (V1TI "q") (TI "q") 129 (V1SF "f") (V2SF "f") (V4SF "f") 130 (V1DF "g") (V2DF "g") 131 (V1TF "q")]) 132 133; This is for vmalhw. It gets an 'w' attached to avoid confusion with 134; multiply and add logical high vmalh. 135(define_mode_attr w [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "") 136 (V1HI "w") (V2HI "w") (V4HI "w") (V8HI "w") 137 (V1SI "") (V2SI "") (V4SI "") 138 (V1DI "") (V2DI "")]) 139 140; Resulting mode of a vector comparison. For floating point modes an 141; integer vector mode with the same element size is picked. 142(define_mode_attr TOINTVEC [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI") 143 (V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI") 144 (V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI") 145 (V1DI "V1DI") (V2DI "V2DI") 146 (V1TI "V1TI") 147 (V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI") 148 (V1DF "V1DI") (V2DF "V2DI") 149 (V1TF "V1TI") (TF "V1TI")]) 150 151(define_mode_attr tointvec [(V1QI "v1qi") (V2QI "v2qi") (V4QI "v4qi") (V8QI "v8qi") (V16QI "v16qi") 152 (V1HI "v1hi") (V2HI "v2hi") (V4HI "v4hi") (V8HI "v8hi") 153 (V1SI "v1si") (V2SI "v2si") (V4SI "v4si") 154 (V1DI "v1di") (V2DI "v2di") 155 (V1TI "v1ti") 156 (V1SF "v1si") (V2SF "v2si") (V4SF "v4si") 157 (V1DF "v1di") (V2DF "v2di") 158 (V1TF "v1ti") (TF "v1ti")]) 159 160(define_mode_attr vw [(SF "w") (V1SF "w") (V2SF "v") (V4SF "v") 161 (DF "w") (V1DF "w") (V2DF "v") 162 (TF "w") (V1TF "w")]) 163 164(define_mode_attr sdx [(SF "s") (V1SF "s") (V2SF "s") (V4SF "s") 165 (DF "d") (V1DF "d") (V2DF "d") 166 (TF "x") (V1TF "x")]) 167 168; Vector with widened element size but half the number of elements. 169(define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI") 170 (V1HI "V1SI") (V2HI "V1SI") (V4HI "V2SI") (V8HI "V4SI") 171 (V1SI "V1DI") (V2SI "V1DI") (V4SI "V2DI") 172 (V1DI "V1TI") (V2DI "V1TI") 173 (V1SF "V1DF") (V2SF "V1DF") (V4SF "V2DF")]) 174 175; Vector with shrinked element size but twice the number of elements. 176(define_mode_attr vec_half [(V1HI "V2QI") (V2HI "V4QI") (V4HI "V8QI") (V8HI "V16QI") 177 (V1SI "V2HI") (V2SI "V4HI") (V4SI "V8HI") 178 (V1DI "V2SI") (V2DI "V4SI") 179 (V1TI "V2DI") 180 (V1DF "V2SF") (V2DF "V4SF") 181 (V1TF "V1DF")]) 182 183; Vector with twice the number of elements but same element size. 184(define_mode_attr vec_2x_nelts [(V1QI "V2QI") (V2QI "V4QI") (V4QI "V8QI") (V8QI "V16QI") (V16QI "V32QI") 185 (V1HI "V2HI") (V2HI "V4HI") (V4HI "V8HI") (V8HI "V16HI") 186 (V1SI "V2SI") (V2SI "V4SI") (V4SI "V8SI") 187 (V1DI "V2DI") (V2DI "V4DI") 188 (V1SF "V2SF") (V2SF "V4SF") (V4SF "V8SF") 189 (V1DF "V2DF") (V2DF "V4DF")]) 190 191; Vector with widened element size and the same number of elements. 192(define_mode_attr vec_2x_wide [(V1QI "V1HI") (V2QI "V2HI") (V4QI "V4HI") (V8QI "V8HI") (V16QI "V16HI") 193 (V1HI "V1SI") (V2HI "V2SI") (V4HI "V4SI") (V8HI "V8SI") 194 (V1SI "V1DI") (V2SI "V2DI") (V4SI "V4DI") 195 (V1DI "V1TI") (V2DI "V2TI") 196 (V1SF "V1DF") (V2SF "V2DF") (V4SF "V4DF") 197 (V1DF "V1TF") (V2DF "V2TF")]) 198 199; Vector with half the element size AND half the number of elements. 200(define_mode_attr vec_halfhalf 201 [(V2HI "V2QI") (V4HI "V4QI") (V8HI "V8QI") 202 (V2SI "V2HI") (V4SI "V4HI") 203 (V2DI "V2SI") 204 (V2DF "V2SF")]) 205 206(define_mode_attr vec_halfnumelts 207 [(V4SF "V2SF") (V4SI "V2SI")]) 208 209 210 211; Comparison operators on int and fp compares which are directly 212; supported by the HW. 213(define_code_iterator VICMP_HW_OP [eq gt gtu]) 214; For int insn_cmp_op can be used in the insn name as well as in the asm output. 215(define_code_attr insn_cmp_op [(eq "eq") (gt "h") (gtu "hl") (ge "he")]) 216 217; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4) 218(define_constants 219 [(VSTRING_FLAG_IN 8) ; invert result 220 (VSTRING_FLAG_RT 4) ; result type 221 (VSTRING_FLAG_ZS 2) ; zero search 222 (VSTRING_FLAG_CS 1)]) ; condition code set 223 224(include "vx-builtins.md") 225 226; Full HW vector size moves 227 228; We don't use lm/stm for 128 bit moves since these are slower than 229; splitting it into separate moves. 230 231; FIXME: More constants are possible by enabling jxx, jyy constraints 232; for TImode (use double-int for the calculations) 233 234; vgmb, vgmh, vgmf, vgmg, vrepib, vrepih, vrepif, vrepig 235(define_insn "mov<mode><tf_vr>" 236 [(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R, v, v, v, v, v,v,*d,*d,?o") 237 (match_operand:V_128 1 "general_operand" " v,R,v,j00,jm1,jyy,jxx,jKK,d, v,dT,*d"))] 238 "" 239 "@ 240 vlr\t%v0,%v1 241 vl\t%v0,%1%A1 242 vst\t%v1,%0%A0 243 vzero\t%v0 244 vone\t%v0 245 vgbm\t%v0,%t1 246 vgm<bhfgq>\t%v0,%s1,%e1 247 vrepi<bhfgq>\t%v0,%h1 248 vlvgp\t%v0,%1,%N1 249 # 250 # 251 #" 252 [(set_attr "cpu_facility" "vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*") 253 (set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRI,VRI,VRI,VRR,*,*,*")]) 254 255(define_expand "movtf" 256 [(match_operand:TF 0 "nonimmediate_operand" "") 257 (match_operand:TF 1 "general_operand" "")] 258 "" 259 { EXPAND_MOVTF(movtf); }) 260 261; VR -> GPR, no instruction so split it into 64 element sets. 262(define_split 263 [(set (match_operand:V_128 0 "register_operand" "") 264 (match_operand:V_128 1 "register_operand" ""))] 265 "TARGET_VX && GENERAL_REG_P (operands[0]) && VECTOR_REG_P (operands[1])" 266 [(set (match_dup 2) 267 (unspec:DI [(subreg:V2DI (match_dup 1) 0) 268 (const_int 0)] UNSPEC_VEC_EXTRACT)) 269 (set (match_dup 3) 270 (unspec:DI [(subreg:V2DI (match_dup 1) 0) 271 (const_int 1)] UNSPEC_VEC_EXTRACT))] 272{ 273 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 274 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode); 275}) 276 277; Split the 128 bit GPR move into two word mode moves 278; s390_split_ok_p decides which part needs to be moved first. 279 280(define_split 281 [(set (match_operand:V_128 0 "nonimmediate_operand" "") 282 (match_operand:V_128 1 "general_operand" ""))] 283 "reload_completed 284 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)" 285 [(set (match_dup 2) (match_dup 4)) 286 (set (match_dup 3) (match_dup 5))] 287{ 288 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 289 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode); 290 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode); 291 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode); 292}) 293 294(define_split 295 [(set (match_operand:V_128 0 "nonimmediate_operand" "") 296 (match_operand:V_128 1 "general_operand" ""))] 297 "reload_completed 298 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)" 299 [(set (match_dup 2) (match_dup 4)) 300 (set (match_dup 3) (match_dup 5))] 301{ 302 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode); 303 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode); 304 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode); 305 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode); 306}) 307 308; This is the vector equivalent to the TImode splitter in s390.md. It 309; is required if both target GPRs occur in the source address operand. 310 311; For non-s_operands at least one of the target GPRs does not conflict 312; with the address operand and one of the splitters above will take 313; over. 314(define_split 315 [(set (match_operand:V_128 0 "register_operand" "") 316 (match_operand:V_128 1 "memory_operand" ""))] 317 "TARGET_ZARCH && reload_completed 318 && !VECTOR_REG_P (operands[0]) 319 && !s_operand (operands[1], VOIDmode)" 320 [(set (match_dup 0) (match_dup 1))] 321{ 322 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode); 323 addr = gen_lowpart (Pmode, addr); 324 s390_load_address (addr, XEXP (operands[1], 0)); 325 operands[1] = replace_equiv_address (operands[1], addr); 326}) 327 328; Moves for smaller vector modes. 329 330; In these patterns only the vlr, vone, and vzero instructions write 331; VR bytes outside the mode. This should be ok since we disallow 332; formerly bigger modes being accessed with smaller modes via 333; subreg. Note: The vone, vzero instructions could easily be replaced 334; with vlei which would only access the bytes belonging to the mode. 335; However, this would probably be slower. 336 337(define_insn "mov<mode>" 338 [(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") 339 (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"))] 340 "TARGET_VX" 341 "@ 342 vlr\t%v0,%v1 343 vlvgb\t%v0,%1,0 344 vlgvb\t%0,%v1,0 345 vleb\t%v0,%1,0 346 vsteb\t%v1,%0,0 347 vzero\t%v0 348 vone\t%v0 349 vgbm\t%v0,%t1 350 vgm\t%v0,%s1,%e1 351 lr\t%0,%1 352 mvi\t%0,0 353 mviy\t%0,0 354 mvi\t%0,-1 355 mviy\t%0,-1 356 lhi\t%0,0 357 lhi\t%0,-1 358 llc\t%0,%1 359 stc\t%1,%0 360 stcy\t%1,%0" 361 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RXY,RX,RXY")]) 362 363(define_insn "mov<mode>" 364 [(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") 365 (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"))] 366 "" 367 "@ 368 vlr\t%v0,%v1 369 vlvgh\t%v0,%1,0 370 vlgvh\t%0,%v1,0 371 vleh\t%v0,%1,0 372 vsteh\t%v1,%0,0 373 vzero\t%v0 374 vone\t%v0 375 vgbm\t%v0,%t1 376 vgm\t%v0,%s1,%e1 377 lr\t%0,%1 378 mvhhi\t%0,0 379 mvhhi\t%0,-1 380 lhi\t%0,0 381 lhi\t%0,-1 382 lh\t%0,%1 383 lhy\t%0,%1 384 lhrl\t%0,%1 385 sth\t%1,%0 386 sthy\t%1,%0 387 sthrl\t%1,%0" 388 [(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")]) 389 390(define_insn "mov<mode>" 391 [(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") 392 (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"))] 393 "TARGET_VX" 394 "@ 395 ldr\t%v0,%v1 396 lde\t%0,%1 397 ley\t%0,%1 398 ste\t%1,%0 399 stey\t%1,%0 400 vlr\t%v0,%v1 401 vlvgf\t%v0,%1,0 402 vlgvf\t%0,%v1,0 403 vlef\t%v0,%1,0 404 vstef\t%1,%0,0 405 lzer\t%v0 406 vzero\t%v0 407 vone\t%v0 408 vgbm\t%v0,%t1 409 vgm\t%v0,%s1,%e1 410 mvhi\t%0,0 411 mvhi\t%0,-1 412 lhi\t%0,0 413 lhi\t%0,-1 414 lrl\t%0,%1 415 lr\t%0,%1 416 l\t%0,%1 417 ly\t%0,%1 418 st\t%1,%0 419 sty\t%1,%0 420 strl\t%1,%0" 421 [(set_attr "op_type" "RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI, 422 RIL,RR,RX,RXY,RX,RXY,RIL")]) 423 424(define_insn "mov<mode>" 425 [(set (match_operand:V_64 0 "nonimmediate_operand" 426 "=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") 427 (match_operand:V_64 1 "general_operand" 428 " 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"))] 429 "TARGET_ZARCH" 430 "@ 431 ldr\t%0,%1 432 ld\t%0,%1 433 ldy\t%0,%1 434 std\t%1,%0 435 stdy\t%1,%0 436 vlr\t%v0,%v1 437 vlvgg\t%v0,%1,0 438 vlgvg\t%0,%v1,0 439 vleg\t%v0,%1,0 440 vsteg\t%v1,%0,0 441 lzdr\t%0 442 vzero\t%v0 443 vone\t%v0 444 vgbm\t%v0,%t1 445 vgm\t%v0,%s1,%e1 446 mvghi\t%0,0 447 mvghi\t%0,-1 448 lghi\t%0,0 449 lghi\t%0,-1 450 ldgr\t%0,%1 451 lgdr\t%0,%1 452 lgrl\t%0,%1 453 lgr\t%0,%1 454 lg\t%0,%1 455 stg\t%1,%0 456 stgrl\t%1,%0" 457 [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI, 458 SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")]) 459 460 461; vec_load_lanes? 462 463; vec_store_lanes? 464 465; vec_set is supposed to *modify* an existing vector so operand 0 is 466; duplicated as input operand. 467(define_expand "vec_set<mode>" 468 [(set (match_operand:V 0 "register_operand" "") 469 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "") 470 (match_operand:SI 2 "nonmemory_operand" "") 471 (match_dup 0)] 472 UNSPEC_VEC_SET))] 473 "TARGET_VX") 474 475; FIXME: Support also vector mode operands for 1 476; FIXME: A target memory operand seems to be useful otherwise we end 477; up with vl vlvgg vst. Shouldn't the middle-end be able to handle 478; that itself? 479; vlvgb, vlvgh, vlvgf, vlvgg, vleb, vleh, vlef, vleg, vleib, vleih, vleif, vleig 480(define_insn "*vec_set<mode>" 481 [(set (match_operand:V 0 "register_operand" "=v,v,v") 482 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,R,K") 483 (match_operand:SI 2 "nonmemory_operand" "an,I,I") 484 (match_operand:V 3 "register_operand" "0,0,0")] 485 UNSPEC_VEC_SET))] 486 "TARGET_VX 487 && (!CONST_INT_P (operands[2]) 488 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))" 489 "@ 490 vlvg<bhfgq>\t%v0,%1,%Y2 491 vle<bhfgq>\t%v0,%1,%2 492 vlei<bhfgq>\t%v0,%1,%2" 493 [(set_attr "op_type" "VRS,VRX,VRI")]) 494 495; vlvgb, vlvgh, vlvgf, vlvgg 496(define_insn "*vec_set<mode>_plus" 497 [(set (match_operand:V 0 "register_operand" "=v") 498 (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d") 499 (plus:SI (match_operand:SI 2 "register_operand" "a") 500 (match_operand:SI 4 "const_int_operand" "n")) 501 (match_operand:V 3 "register_operand" "0")] 502 UNSPEC_VEC_SET))] 503 "TARGET_VX" 504 "vlvg<bhfgq>\t%v0,%1,%Y4(%2)" 505 [(set_attr "op_type" "VRS")]) 506 507 508; FIXME: Support also vector mode operands for 0 509; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :( 510; This is used via RTL standard name as well as for expanding the builtin 511(define_expand "vec_extract<mode><non_vec_l>" 512 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "") 513 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "") 514 (match_operand:SI 2 "nonmemory_operand" "")] 515 UNSPEC_VEC_EXTRACT))] 516 "TARGET_VX") 517 518; vlgvb, vlgvh, vlgvf, vlgvg, vsteb, vsteh, vstef, vsteg 519(define_insn "*vec_extract<mode>" 520 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,R") 521 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v,v") 522 (match_operand:SI 2 "nonmemory_operand" "an,I")] 523 UNSPEC_VEC_EXTRACT))] 524 "TARGET_VX 525 && (!CONST_INT_P (operands[2]) 526 || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))" 527 "@ 528 vlgv<bhfgq>\t%0,%v1,%Y2 529 vste<bhfgq>\t%v1,%0,%2" 530 [(set_attr "op_type" "VRS,VRX")]) 531 532; vlgvb, vlgvh, vlgvf, vlgvg 533(define_insn "*vec_extract<mode>_plus" 534 [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d") 535 (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v") 536 (plus:SI (match_operand:SI 2 "nonmemory_operand" "a") 537 (match_operand:SI 3 "const_int_operand" "n"))] 538 UNSPEC_VEC_EXTRACT))] 539 "TARGET_VX" 540 "vlgv<bhfgq>\t%0,%v1,%Y3(%2)" 541 [(set_attr "op_type" "VRS")]) 542 543(define_expand "vec_init<mode><non_vec_l>" 544 [(match_operand:V_128 0 "register_operand" "") 545 (match_operand:V_128 1 "nonmemory_operand" "")] 546 "TARGET_VX" 547{ 548 s390_expand_vec_init (operands[0], operands[1]); 549 DONE; 550}) 551 552(define_insn "*vec_vllezlf<mode>" 553 [(set (match_operand:V_HW_4 0 "register_operand" "=v") 554 (vec_concat:V_HW_4 555 (vec_concat:<vec_halfnumelts> 556 (match_operand:<non_vec> 1 "memory_operand" "R") 557 (const_int 0)) 558 (vec_concat:<vec_halfnumelts> 559 (const_int 0) 560 (const_int 0))))] 561 "TARGET_VXE" 562 "vllezlf\t%v0,%1" 563 [(set_attr "op_type" "VRX")]) 564 565; Replicate from vector element 566; vrepb, vreph, vrepf, vrepg 567(define_insn "*vec_splat<mode>" 568 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v") 569 (vec_duplicate:V_128_NOSINGLE 570 (vec_select:<non_vec> 571 (match_operand:V_128_NOSINGLE 1 "register_operand" "v") 572 (parallel 573 [(match_operand:QI 2 "const_mask_operand" "C")]))))] 574 "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<MODE>mode)" 575 "vrep<bhfgq>\t%v0,%v1,%2" 576 [(set_attr "op_type" "VRI")]) 577 578; vlrepb, vlreph, vlrepf, vlrepg, vrepib, vrepih, vrepif, vrepig, vrepb, vreph, vrepf, vrepg 579(define_insn "*vec_splats<mode>" 580 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v,v,v,v") 581 (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "general_operand" " R,K,v,d")))] 582 "TARGET_VX" 583 "@ 584 vlrep<bhfgq>\t%v0,%1 585 vrepi<bhfgq>\t%v0,%h1 586 vrep<bhfgq>\t%v0,%v1,0 587 #" 588 [(set_attr "op_type" "VRX,VRI,VRI,*")]) 589 590; vlbrreph, vlbrrepf, vlbrrepg 591(define_insn "*vec_splats_bswap_vec<mode>" 592 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v") 593 (bswap:V_HW_HSD 594 (vec_duplicate:V_HW_HSD (match_operand:<non_vec> 1 "memory_operand" "R")))) 595 (use (match_operand:V16QI 2 "permute_pattern_operand" "X"))] 596 "TARGET_VXE2" 597 "vlbrrep<bhfgq>\t%v0,%1" 598 [(set_attr "op_type" "VRX")]) 599 600; Why do we need both? Shouldn't there be a canonical form? 601; vlbrreph, vlbrrepf, vlbrrepg 602(define_insn "*vec_splats_bswap_elem<mode>" 603 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v") 604 (vec_duplicate:V_HW_HSD 605 (bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand" "R"))))] 606 "TARGET_VXE2" 607 "vlbrrep<bhfgq>\t%v0,%1" 608 [(set_attr "op_type" "VRX")]) 609 610; A TFmode operand resides in FPR register pairs while V1TF is in a 611; single vector register. 612(define_insn "*vec_tf_to_v1tf_fpr" 613 [(set (match_operand:V1TF 0 "nonimmediate_operand" "=v,v,R,v,v") 614 (vec_duplicate:V1TF (match_operand:TF 1 "general_operand" "f,R,f,G,d")))] 615 "TARGET_VX && !TARGET_VXE" 616 "@ 617 vmrhg\t%v0,%1,%N1 618 vl\t%v0,%1%A1 619 vst\t%v1,%0%A0 620 vzero\t%v0 621 vlvgp\t%v0,%1,%N1" 622 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRR")]) 623 624; Both TFmode and V1TFmode operands reside in vector registers. 625(define_insn "*vec_tf_to_v1tf_vr" 626 [(set (match_operand:V1TF 0 "nonimmediate_operand" "=v,v,R,v,v") 627 (vec_duplicate:V1TF (match_operand:TF 1 "general_operand" "v,R,v,G,d")))] 628 "TARGET_VXE" 629 "@ 630 vlr\t%v0,%1 631 vl\t%v0,%1%A1 632 vst\t%v1,%0%A0 633 vzero\t%v0 634 vlvgp\t%v0,%1,%N1" 635 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRR")]) 636 637(define_insn_and_split "fprx2_to_tf" 638 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,AR") 639 (subreg:TF (match_operand:FPRX2 1 "general_operand" "f,f") 0))] 640 "TARGET_VXE" 641 "@ 642 vmrhg\t%v0,%1,%N1 643 #" 644 "!(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))" 645 [(set (match_dup 2) (match_dup 3)) 646 (set (match_dup 4) (match_dup 5))] 647{ 648 operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0); 649 operands[3] = simplify_gen_subreg (DFmode, operands[1], FPRX2mode, 0); 650 operands[4] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8); 651 operands[5] = simplify_gen_subreg (DFmode, operands[1], FPRX2mode, 8); 652} 653 [(set_attr "op_type" "VRR,*")]) 654 655(define_insn "*vec_ti_to_v1ti" 656 [(set (match_operand:V1TI 0 "nonimmediate_operand" "=v,v,R, v, v,v") 657 (vec_duplicate:V1TI (match_operand:TI 1 "general_operand" "v,R,v,j00,jm1,d")))] 658 "TARGET_VX" 659 "@ 660 vlr\t%v0,%v1 661 vl\t%v0,%1%A1 662 vst\t%v1,%0%A0 663 vzero\t%v0 664 vone\t%v0 665 vlvgp\t%v0,%1,%N1" 666 [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRR")]) 667 668; vec_splats is supposed to replicate op1 into all elements of op0 669; This splitter first sets the rightmost element of op0 to op1 and 670; then does a vec_splat to replicate that element into all other 671; elements. 672(define_split 673 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "") 674 (vec_duplicate:V_128_NOSINGLE (match_operand:<non_vec> 1 "register_operand" "")))] 675 "TARGET_VX && GENERAL_REG_P (operands[1])" 676 [(set (match_dup 0) 677 (unspec:V_128_NOSINGLE [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET)) 678 (set (match_dup 0) 679 (vec_duplicate:V_128_NOSINGLE 680 (vec_select:<non_vec> 681 (match_dup 0) (parallel [(match_dup 2)]))))] 682{ 683 operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1); 684}) 685 686(define_predicate "vcond_comparison_operator" 687 (match_operand 0 "comparison_operator") 688{ 689 if (!HONOR_NANS (GET_MODE (XEXP (op, 0))) 690 && !HONOR_NANS (GET_MODE (XEXP (op, 1)))) 691 return true; 692 switch (GET_CODE (op)) 693 { 694 case LE: 695 case LT: 696 case GE: 697 case GT: 698 case LTGT: 699 /* Signaling vector comparisons are supported only on z14+. */ 700 return TARGET_VXE || TARGET_NONSIGNALING_VECTOR_COMPARE_OK; 701 default: 702 return true; 703 } 704}) 705 706(define_expand "vcond<V_HW:mode><V_HW2:mode>" 707 [(set (match_operand:V_HW 0 "register_operand" "") 708 (if_then_else:V_HW 709 (match_operator 3 "vcond_comparison_operator" 710 [(match_operand:V_HW2 4 "register_operand" "") 711 (match_operand:V_HW2 5 "nonmemory_operand" "")]) 712 (match_operand:V_HW 1 "nonmemory_operand" "") 713 (match_operand:V_HW 2 "nonmemory_operand" "")))] 714 "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)" 715{ 716 s390_expand_vcond (operands[0], operands[1], operands[2], 717 GET_CODE (operands[3]), operands[4], operands[5]); 718 DONE; 719}) 720 721(define_expand "vcondu<V_HW:mode><V_HW2:mode>" 722 [(set (match_operand:V_HW 0 "register_operand" "") 723 (if_then_else:V_HW 724 (match_operator 3 "comparison_operator" 725 [(match_operand:V_HW2 4 "register_operand" "") 726 (match_operand:V_HW2 5 "nonmemory_operand" "")]) 727 (match_operand:V_HW 1 "nonmemory_operand" "") 728 (match_operand:V_HW 2 "nonmemory_operand" "")))] 729 "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)" 730{ 731 s390_expand_vcond (operands[0], operands[1], operands[2], 732 GET_CODE (operands[3]), operands[4], operands[5]); 733 DONE; 734}) 735 736(define_expand "vcond_mask_<mode><tointvec>" 737 [(set (match_operand:V 0 "register_operand" "") 738 (if_then_else:V 739 (eq (match_operand:<TOINTVEC> 3 "register_operand" "") 740 (match_dup 4)) 741 (match_operand:V 2 "register_operand" "") 742 (match_operand:V 1 "register_operand" "")))] 743 "TARGET_VX" 744 "operands[4] = CONST0_RTX (<TOINTVEC>mode);") 745 746 747; We only have HW support for byte vectors. The middle-end is 748; supposed to lower the mode if required. 749(define_insn "vec_permv16qi" 750 [(set (match_operand:V16QI 0 "register_operand" "=v") 751 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") 752 (match_operand:V16QI 2 "register_operand" "v") 753 (match_operand:V16QI 3 "register_operand" "v")] 754 UNSPEC_VEC_PERM))] 755 "TARGET_VX" 756 "vperm\t%v0,%v1,%v2,%v3" 757 [(set_attr "op_type" "VRR")]) 758 759(define_insn "*vec_perm<mode>" 760 [(set (match_operand:VT_HW 0 "register_operand" "=v") 761 (subreg:VT_HW (unspec:V16QI [(subreg:V16QI (match_operand:VT_HW 1 "register_operand" "v") 0) 762 (subreg:V16QI (match_operand:VT_HW 2 "register_operand" "v") 0) 763 (match_operand:V16QI 3 "register_operand" "v")] 764 UNSPEC_VEC_PERM) 0))] 765 "TARGET_VX" 766 "vperm\t%v0,%v1,%v2,%v3" 767 [(set_attr "op_type" "VRR")]) 768 769 770; First DW of op1 and second DW of op2 771(define_insn "@vpdi1<mode>" 772 [(set (match_operand:V_HW_2 0 "register_operand" "=v") 773 (vec_select:V_HW_2 774 (vec_concat:<vec_2x_nelts> 775 (match_operand:V_HW_2 1 "register_operand" "v") 776 (match_operand:V_HW_2 2 "register_operand" "v")) 777 (parallel [(const_int 0) (const_int 3)])))] 778 "TARGET_VX" 779 "vpdi\t%v0,%v1,%v2,1" 780 [(set_attr "op_type" "VRR")]) 781 782; Second DW of op1 and first of op2 783(define_insn "@vpdi4<mode>" 784 [(set (match_operand:V_HW_2 0 "register_operand" "=v") 785 (vec_select:V_HW_2 786 (vec_concat:<vec_2x_nelts> 787 (match_operand:V_HW_2 1 "register_operand" "v") 788 (match_operand:V_HW_2 2 "register_operand" "v")) 789 (parallel [(const_int 1) (const_int 2)])))] 790 "TARGET_VX" 791 "vpdi\t%v0,%v1,%v2,4" 792 [(set_attr "op_type" "VRR")]) 793 794 795(define_insn "*vmrhb" 796 [(set (match_operand:V16QI 0 "register_operand" "=v") 797 (vec_select:V16QI 798 (vec_concat:V32QI (match_operand:V16QI 1 "register_operand" "v") 799 (match_operand:V16QI 2 "register_operand" "v")) 800 (parallel [(const_int 0) (const_int 16) 801 (const_int 1) (const_int 17) 802 (const_int 2) (const_int 18) 803 (const_int 3) (const_int 19) 804 (const_int 4) (const_int 20) 805 (const_int 5) (const_int 21) 806 (const_int 6) (const_int 22) 807 (const_int 7) (const_int 23)])))] 808 "TARGET_VX" 809 "vmrhb\t%0,%1,%2"; 810 [(set_attr "op_type" "VRR")]) 811 812(define_insn "*vmrlb" 813 [(set (match_operand:V16QI 0 "register_operand" "=v") 814 (vec_select:V16QI 815 (vec_concat:V32QI (match_operand:V16QI 1 "register_operand" "v") 816 (match_operand:V16QI 2 "register_operand" "v")) 817 (parallel [(const_int 8) (const_int 24) 818 (const_int 9) (const_int 25) 819 (const_int 10) (const_int 26) 820 (const_int 11) (const_int 27) 821 (const_int 12) (const_int 28) 822 (const_int 13) (const_int 29) 823 (const_int 14) (const_int 30) 824 (const_int 15) (const_int 31)])))] 825 "TARGET_VX" 826 "vmrlb\t%0,%1,%2"; 827 [(set_attr "op_type" "VRR")]) 828 829(define_insn "*vmrhh" 830 [(set (match_operand:V8HI 0 "register_operand" "=v") 831 (vec_select:V8HI 832 (vec_concat:V16HI (match_operand:V8HI 1 "register_operand" "v") 833 (match_operand:V8HI 2 "register_operand" "v")) 834 (parallel [(const_int 0) (const_int 8) 835 (const_int 1) (const_int 9) 836 (const_int 2) (const_int 10) 837 (const_int 3) (const_int 11)])))] 838 "TARGET_VX" 839 "vmrhh\t%0,%1,%2"; 840 [(set_attr "op_type" "VRR")]) 841 842(define_insn "*vmrlh" 843 [(set (match_operand:V8HI 0 "register_operand" "=v") 844 (vec_select:V8HI 845 (vec_concat:V16HI (match_operand:V8HI 1 "register_operand" "v") 846 (match_operand:V8HI 2 "register_operand" "v")) 847 (parallel [(const_int 4) (const_int 12) 848 (const_int 5) (const_int 13) 849 (const_int 6) (const_int 14) 850 (const_int 7) (const_int 15)])))] 851 "TARGET_VX" 852 "vmrlh\t%0,%1,%2"; 853 [(set_attr "op_type" "VRR")]) 854 855(define_insn "*vmrhf" 856 [(set (match_operand:V_HW_4 0 "register_operand" "=v") 857 (vec_select:V_HW_4 858 (vec_concat:<vec_2x_nelts> (match_operand:V_HW_4 1 "register_operand" "v") 859 (match_operand:V_HW_4 2 "register_operand" "v")) 860 (parallel [(const_int 0) (const_int 4) 861 (const_int 1) (const_int 5)])))] 862 "TARGET_VX" 863 "vmrhf\t%0,%1,%2"; 864 [(set_attr "op_type" "VRR")]) 865 866(define_insn "*vmrlf" 867 [(set (match_operand:V_HW_4 0 "register_operand" "=v") 868 (vec_select:V_HW_4 869 (vec_concat:<vec_2x_nelts> (match_operand:V_HW_4 1 "register_operand" "v") 870 (match_operand:V_HW_4 2 "register_operand" "v")) 871 (parallel [(const_int 2) (const_int 6) 872 (const_int 3) (const_int 7)])))] 873 "TARGET_VX" 874 "vmrlf\t%0,%1,%2"; 875 [(set_attr "op_type" "VRR")]) 876 877(define_insn "*vmrhg" 878 [(set (match_operand:V_HW_2 0 "register_operand" "=v") 879 (vec_select:V_HW_2 880 (vec_concat:<vec_2x_nelts> (match_operand:V_HW_2 1 "register_operand" "v") 881 (match_operand:V_HW_2 2 "register_operand" "v")) 882 (parallel [(const_int 0) (const_int 2)])))] 883 "TARGET_VX" 884 "vmrhg\t%0,%1,%2"; 885 [(set_attr "op_type" "VRR")]) 886 887(define_insn "*vmrlg" 888 [(set (match_operand:V_HW_2 0 "register_operand" "=v") 889 (vec_select:V_HW_2 890 (vec_concat:<vec_2x_nelts> (match_operand:V_HW_2 1 "register_operand" "v") 891 (match_operand:V_HW_2 2 "register_operand" "v")) 892 (parallel [(const_int 1) (const_int 3)])))] 893 "TARGET_VX" 894 "vmrlg\t%0,%1,%2"; 895 [(set_attr "op_type" "VRR")]) 896 897 898(define_insn "*tf_to_fprx2_0" 899 [(set (subreg:DF (match_operand:FPRX2 0 "nonimmediate_operand" "+f") 0) 900 (subreg:DF (match_operand:TF 1 "general_operand" "v") 0))] 901 "TARGET_VXE" 902 ; M4 == 1 corresponds to %v0[0] = %v1[0]; %v0[1] = %v0[1]; 903 "vpdi\t%v0,%v1,%v0,1" 904 [(set_attr "op_type" "VRR")]) 905 906(define_insn "*tf_to_fprx2_1" 907 [(set (subreg:DF (match_operand:FPRX2 0 "nonimmediate_operand" "+f") 8) 908 (subreg:DF (match_operand:TF 1 "general_operand" "v") 8))] 909 "TARGET_VXE" 910 ; M4 == 5 corresponds to %V0[0] = %v1[1]; %V0[1] = %V0[1]; 911 "vpdi\t%V0,%v1,%V0,5" 912 [(set_attr "op_type" "VRR")]) 913 914(define_insn_and_split "tf_to_fprx2" 915 [(set (match_operand:FPRX2 0 "nonimmediate_operand" "=f,f") 916 (subreg:FPRX2 (match_operand:TF 1 "general_operand" "v,AR") 0))] 917 "TARGET_VXE" 918 "#" 919 "!(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" 920 [(set (match_dup 2) (match_dup 3)) 921 (set (match_dup 4) (match_dup 5))] 922{ 923 operands[2] = simplify_gen_subreg (DFmode, operands[0], FPRX2mode, 0); 924 operands[3] = simplify_gen_subreg (DFmode, operands[1], TFmode, 0); 925 operands[4] = simplify_gen_subreg (DFmode, operands[0], FPRX2mode, 8); 926 operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, 8); 927}) 928 929 930;; 931;; Vector integer arithmetic instructions 932;; 933 934; vab, vah, vaf, vag, vaq 935 936; We use nonimmediate_operand instead of register_operand since it is 937; better to have the reloads into VRs instead of splitting the 938; operation into two DImode ADDs. 939(define_insn "<ti*>add<mode>3" 940 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v") 941 (plus:VIT (match_operand:VIT 1 "nonimmediate_operand" "v") 942 (match_operand:VIT 2 "general_operand" "v")))] 943 "TARGET_VX" 944 "va<bhfgq>\t%v0,%v1,%v2" 945 [(set_attr "op_type" "VRR")]) 946 947; vsb, vsh, vsf, vsg, vsq 948(define_insn "<ti*>sub<mode>3" 949 [(set (match_operand:VIT 0 "nonimmediate_operand" "=v") 950 (minus:VIT (match_operand:VIT 1 "nonimmediate_operand" "v") 951 (match_operand:VIT 2 "general_operand" "v")))] 952 "TARGET_VX" 953 "vs<bhfgq>\t%v0,%v1,%v2" 954 [(set_attr "op_type" "VRR")]) 955 956; vmlb, vmlhw, vmlf 957(define_insn "mul<mode>3" 958 [(set (match_operand:VI_QHS 0 "register_operand" "=v") 959 (mult:VI_QHS (match_operand:VI_QHS 1 "register_operand" "v") 960 (match_operand:VI_QHS 2 "register_operand" "v")))] 961 "TARGET_VX" 962 "vml<bhfgq><w>\t%v0,%v1,%v2" 963 [(set_attr "op_type" "VRR")]) 964 965; vlcb, vlch, vlcf, vlcg 966(define_insn "neg<mode>2" 967 [(set (match_operand:VI 0 "register_operand" "=v") 968 (neg:VI (match_operand:VI 1 "register_operand" "v")))] 969 "TARGET_VX" 970 "vlc<bhfgq>\t%v0,%v1" 971 [(set_attr "op_type" "VRR")]) 972 973; vlpb, vlph, vlpf, vlpg 974(define_insn "abs<mode>2" 975 [(set (match_operand:VI 0 "register_operand" "=v") 976 (abs:VI (match_operand:VI 1 "register_operand" "v")))] 977 "TARGET_VX" 978 "vlp<bhfgq>\t%v0,%v1" 979 [(set_attr "op_type" "VRR")]) 980 981 982; Vector sum across 983 984; Sum across DImode parts of the 1st operand and add the rightmost 985; element of 2nd operand 986; vsumgh, vsumgf 987(define_insn "*vec_sum2<mode>" 988 [(set (match_operand:V2DI 0 "register_operand" "=v") 989 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "v") 990 (match_operand:VI_HW_HS 2 "register_operand" "v")] 991 UNSPEC_VEC_VSUMG))] 992 "TARGET_VX" 993 "vsumg<bhfgq>\t%v0,%v1,%v2" 994 [(set_attr "op_type" "VRR")]) 995 996; vsumb, vsumh 997(define_insn "*vec_sum4<mode>" 998 [(set (match_operand:V4SI 0 "register_operand" "=v") 999 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "v") 1000 (match_operand:VI_HW_QH 2 "register_operand" "v")] 1001 UNSPEC_VEC_VSUM))] 1002 "TARGET_VX" 1003 "vsum<bhfgq>\t%v0,%v1,%v2" 1004 [(set_attr "op_type" "VRR")]) 1005 1006;; 1007;; Vector bit instructions (int + fp) 1008;; 1009 1010; Vector and 1011 1012(define_insn "and<mode>3" 1013 [(set (match_operand:VT 0 "register_operand" "=v") 1014 (and:VT (match_operand:VT 1 "register_operand" "v") 1015 (match_operand:VT 2 "register_operand" "v")))] 1016 "TARGET_VX" 1017 "vn\t%v0,%v1,%v2" 1018 [(set_attr "op_type" "VRR")]) 1019 1020; Vector not and 1021 1022(define_insn "notand<mode>3" 1023 [(set (match_operand:VT 0 "register_operand" "=v") 1024 (ior:VT (not:VT (match_operand:VT 1 "register_operand" "v")) 1025 (not:VT (match_operand:VT 2 "register_operand" "v"))))] 1026 "TARGET_VXE" 1027 "vnn\t%v0,%v1,%v2" 1028 [(set_attr "op_type" "VRR")]) 1029 1030; Vector or 1031 1032(define_insn "ior<mode>3" 1033 [(set (match_operand:VT 0 "register_operand" "=v") 1034 (ior:VT (match_operand:VT 1 "register_operand" "v") 1035 (match_operand:VT 2 "register_operand" "v")))] 1036 "TARGET_VX" 1037 "vo\t%v0,%v1,%v2" 1038 [(set_attr "op_type" "VRR")]) 1039 1040; Vector or with complement 1041 1042(define_insn "ior_not<mode>3" 1043 [(set (match_operand:VT 0 "register_operand" "=v") 1044 (ior:VT (not:VT (match_operand:VT 2 "register_operand" "v")) 1045 (match_operand:VT 1 "register_operand" "v")))] 1046 "TARGET_VXE" 1047 "voc\t%v0,%v1,%v2" 1048 [(set_attr "op_type" "VRR")]) 1049 1050; Vector xor 1051 1052(define_insn "xor<mode>3" 1053 [(set (match_operand:VT 0 "register_operand" "=v") 1054 (xor:VT (match_operand:VT 1 "register_operand" "v") 1055 (match_operand:VT 2 "register_operand" "v")))] 1056 "TARGET_VX" 1057 "vx\t%v0,%v1,%v2" 1058 [(set_attr "op_type" "VRR")]) 1059 1060; Vector not xor 1061 1062(define_insn "notxor<mode>3" 1063 [(set (match_operand:VT 0 "register_operand" "=v") 1064 (not:VT (xor:VT (match_operand:VT 1 "register_operand" "v") 1065 (match_operand:VT 2 "register_operand" "v"))))] 1066 "TARGET_VXE" 1067 "vnx\t%v0,%v1,%v2" 1068 [(set_attr "op_type" "VRR")]) 1069 1070; Bitwise inversion of a vector 1071(define_insn "one_cmpl<mode>2" 1072 [(set (match_operand:VT 0 "register_operand" "=v") 1073 (not:VT (match_operand:VT 1 "register_operand" "v")))] 1074 "TARGET_VX" 1075 "vnot\t%v0,%v1" 1076 [(set_attr "op_type" "VRR")]) 1077 1078; Vector population count 1079 1080(define_expand "popcount<mode>2" 1081 [(set (match_operand:VI_HW 0 "register_operand" "=v") 1082 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")] 1083 UNSPEC_POPCNT))] 1084 "TARGET_VX" 1085{ 1086 if (TARGET_VXE) 1087 emit_insn (gen_popcount<mode>2_vxe (operands[0], operands[1])); 1088 else 1089 emit_insn (gen_popcount<mode>2_vx (operands[0], operands[1])); 1090 DONE; 1091}) 1092 1093; vpopctb, vpopcth, vpopctf, vpopctg 1094(define_insn "popcount<mode>2_vxe" 1095 [(set (match_operand:VI_HW 0 "register_operand" "=v") 1096 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")] 1097 UNSPEC_POPCNT))] 1098 "TARGET_VXE" 1099 "vpopct<bhfgq>\t%v0,%v1" 1100 [(set_attr "op_type" "VRR")]) 1101 1102(define_insn "popcountv16qi2_vx" 1103 [(set (match_operand:V16QI 0 "register_operand" "=v") 1104 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] 1105 UNSPEC_POPCNT))] 1106 "TARGET_VX && !TARGET_VXE" 1107 "vpopct\t%v0,%v1,0" 1108 [(set_attr "op_type" "VRR")]) 1109 1110; vpopct only counts bits in byte elements. Bigger element sizes need 1111; to be emulated. Word and doubleword elements can use the sum across 1112; instructions. For halfword sized elements we do a shift of a copy 1113; of the result, add it to the result and extend it to halfword 1114; element size (unpack). 1115 1116(define_expand "popcountv8hi2_vx" 1117 [(set (match_dup 2) 1118 (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")] 1119 UNSPEC_POPCNT)) 1120 ; Make a copy of the result 1121 (set (match_dup 3) (match_dup 2)) 1122 ; Generate the shift count operand in a VR (8->byte 7) 1123 (set (match_dup 4) (match_dup 5)) 1124 (set (match_dup 4) (unspec:V16QI [(const_int 8) 1125 (const_int 7) 1126 (match_dup 4)] UNSPEC_VEC_SET)) 1127 ; Vector shift right logical by one byte 1128 (set (match_dup 3) 1129 (unspec:V16QI [(match_dup 3) (match_dup 4)] UNSPEC_VEC_SRLB)) 1130 ; Add the shifted and the original result 1131 (set (match_dup 2) 1132 (plus:V16QI (match_dup 2) (match_dup 3))) 1133 ; Generate mask for the odd numbered byte elements 1134 (set (match_dup 3) 1135 (const_vector:V16QI [(const_int 0) (const_int 255) 1136 (const_int 0) (const_int 255) 1137 (const_int 0) (const_int 255) 1138 (const_int 0) (const_int 255) 1139 (const_int 0) (const_int 255) 1140 (const_int 0) (const_int 255) 1141 (const_int 0) (const_int 255) 1142 (const_int 0) (const_int 255)])) 1143 ; Zero out the even indexed bytes 1144 (set (match_operand:V8HI 0 "register_operand" "=v") 1145 (and:V8HI (subreg:V8HI (match_dup 2) 0) 1146 (subreg:V8HI (match_dup 3) 0))) 1147] 1148 "TARGET_VX && !TARGET_VXE" 1149{ 1150 operands[1] = simplify_gen_subreg (V16QImode, operands[1], 1151 V8HImode, 0); 1152 operands[2] = gen_reg_rtx (V16QImode); 1153 operands[3] = gen_reg_rtx (V16QImode); 1154 operands[4] = gen_reg_rtx (V16QImode); 1155 operands[5] = CONST0_RTX (V16QImode); 1156}) 1157 1158(define_expand "popcountv4si2_vx" 1159 [(set (match_dup 2) 1160 (unspec:V16QI [(match_operand:V4SI 1 "register_operand" "v")] 1161 UNSPEC_POPCNT)) 1162 (set (match_operand:V4SI 0 "register_operand" "=v") 1163 (unspec:V4SI [(match_dup 2) (match_dup 3)] 1164 UNSPEC_VEC_VSUM))] 1165 "TARGET_VX && !TARGET_VXE" 1166{ 1167 operands[1] = simplify_gen_subreg (V16QImode, operands[1], V4SImode, 0); 1168 operands[2] = gen_reg_rtx (V16QImode); 1169 operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode)); 1170}) 1171 1172(define_expand "popcountv2di2_vx" 1173 [(set (match_dup 2) 1174 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")] 1175 UNSPEC_POPCNT)) 1176 (set (match_dup 3) 1177 (unspec:V4SI [(match_dup 2) (match_dup 4)] 1178 UNSPEC_VEC_VSUM)) 1179 (set (match_operand:V2DI 0 "register_operand" "=v") 1180 (unspec:V2DI [(match_dup 3) (match_dup 5)] 1181 UNSPEC_VEC_VSUMG))] 1182 "TARGET_VX && !TARGET_VXE" 1183{ 1184 operands[1] = simplify_gen_subreg (V16QImode, operands[1], V2DImode, 0); 1185 operands[2] = gen_reg_rtx (V16QImode); 1186 operands[3] = gen_reg_rtx (V4SImode); 1187 operands[4] = force_reg (V16QImode, CONST0_RTX (V16QImode)); 1188 operands[5] = force_reg (V4SImode, CONST0_RTX (V4SImode)); 1189}) 1190 1191; Count leading zeros 1192; vclzb, vclzh, vclzf, vclzg 1193(define_insn "clz<mode>2" 1194 [(set (match_operand:V 0 "register_operand" "=v") 1195 (clz:V (match_operand:V 1 "register_operand" "v")))] 1196 "TARGET_VX" 1197 "vclz<bhfgq>\t%v0,%v1" 1198 [(set_attr "op_type" "VRR")]) 1199 1200; Count trailing zeros 1201; vctzb, vctzh, vctzf, vctzg 1202(define_insn "ctz<mode>2" 1203 [(set (match_operand:V 0 "register_operand" "=v") 1204 (ctz:V (match_operand:V 1 "register_operand" "v")))] 1205 "TARGET_VX" 1206 "vctz<bhfgq>\t%v0,%v1" 1207 [(set_attr "op_type" "VRR")]) 1208 1209 1210 1211; Each vector element rotated by the corresponding vector element 1212; verllvb, verllvh, verllvf, verllvg 1213(define_insn "vrotl<mode>3" 1214 [(set (match_operand:VI 0 "register_operand" "=v") 1215 (rotate:VI (match_operand:VI 1 "register_operand" "v") 1216 (match_operand:VI 2 "register_operand" "v")))] 1217 "TARGET_VX" 1218 "verllv<bhfgq>\t%v0,%v1,%v2" 1219 [(set_attr "op_type" "VRR")]) 1220 1221 1222; Vector rotate and shift by scalar instructions 1223 1224(define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate]) 1225(define_code_attr vec_shifts_name [(ashift "ashl") (ashiftrt "ashr") 1226 (lshiftrt "lshr") (rotate "rotl")]) 1227(define_code_attr vec_shifts_mnem [(ashift "vesl") (ashiftrt "vesra") 1228 (lshiftrt "vesrl") (rotate "verll")]) 1229 1230; Each vector element rotated by a scalar 1231(define_expand "<vec_shifts_name><mode>3" 1232 [(set (match_operand:VI 0 "register_operand" "") 1233 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "") 1234 (match_operand:QI 2 "shift_count_operand" "")))] 1235 "TARGET_VX") 1236 1237; verllb, verllh, verllf, verllg 1238; veslb, veslh, veslf, veslg 1239; vesrab, vesrah, vesraf, vesrag 1240; vesrlb, vesrlh, vesrlf, vesrlg 1241(define_insn "*<vec_shifts_name><mode>3" 1242 [(set (match_operand:VI 0 "register_operand" "=v") 1243 (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v") 1244 (match_operand:QI 2 "shift_count_operand_vec" "jsc")))] 1245 "TARGET_VX 1246 && s390_valid_shift_count (operands[2], 1247 GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) - 1) 1248 " 1249 "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2" 1250 [(set_attr "op_type" "VRS")]) 1251 1252 1253; Shift each element by corresponding vector element 1254 1255; veslvb, veslvh, veslvf, veslvg 1256(define_insn "vashl<mode>3" 1257 [(set (match_operand:VI 0 "register_operand" "=v") 1258 (ashift:VI (match_operand:VI 1 "register_operand" "v") 1259 (match_operand:VI 2 "register_operand" "v")))] 1260 "TARGET_VX" 1261 "veslv<bhfgq>\t%v0,%v1,%v2" 1262 [(set_attr "op_type" "VRR")]) 1263 1264; vesravb, vesravh, vesravf, vesravg 1265(define_insn "vashr<mode>3" 1266 [(set (match_operand:VI 0 "register_operand" "=v") 1267 (ashiftrt:VI (match_operand:VI 1 "register_operand" "v") 1268 (match_operand:VI 2 "register_operand" "v")))] 1269 "TARGET_VX" 1270 "vesrav<bhfgq>\t%v0,%v1,%v2" 1271 [(set_attr "op_type" "VRR")]) 1272 1273; vesrlvb, vesrlvh, vesrlvf, vesrlvg 1274(define_insn "vlshr<mode>3" 1275 [(set (match_operand:VI 0 "register_operand" "=v") 1276 (lshiftrt:VI (match_operand:VI 1 "register_operand" "v") 1277 (match_operand:VI 2 "register_operand" "v")))] 1278 "TARGET_VX" 1279 "vesrlv<bhfgq>\t%v0,%v1,%v2" 1280 [(set_attr "op_type" "VRR")]) 1281 1282; Vector shift right logical by byte 1283 1284; Pattern used by e.g. popcount 1285(define_insn "*vec_srb<mode>" 1286 [(set (match_operand:V_128 0 "register_operand" "=v") 1287 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "v") 1288 (match_operand:V16QI 2 "register_operand" "v")] 1289 UNSPEC_VEC_SRLB))] 1290 "TARGET_VX" 1291 "vsrlb\t%v0,%v1,%v2" 1292 [(set_attr "op_type" "VRR")]) 1293 1294 1295; Vector shift left by byte 1296 1297(define_insn "*vec_slb<mode>" 1298 [(set (match_operand:V_128 0 "register_operand" "=v") 1299 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "v") 1300 (match_operand:V16QI 2 "register_operand" "v")] 1301 UNSPEC_VEC_SLB))] 1302 "TARGET_VX" 1303 "vslb\t%v0,%v1,%v2" 1304 [(set_attr "op_type" "VRR")]) 1305 1306; vec_shr is defined as shift towards element 0 1307; this means it is a left shift on BE targets! 1308(define_expand "vec_shr_<mode>" 1309 [(set (match_dup 3) 1310 (unspec:V16QI [(match_operand:SI 2 "const_shift_by_byte_operand" "") 1311 (const_int 7) 1312 (match_dup 3)] 1313 UNSPEC_VEC_SET)) 1314 (set (match_operand:V_128 0 "register_operand" "") 1315 (unspec:V_128 [(match_operand:V_128 1 "register_operand" "") 1316 (match_dup 3)] 1317 UNSPEC_VEC_SLB))] 1318 "TARGET_VX" 1319 { 1320 operands[3] = gen_reg_rtx(V16QImode); 1321 }) 1322 1323; vmnb, vmnh, vmnf, vmng 1324(define_insn "smin<mode>3" 1325 [(set (match_operand:VI 0 "register_operand" "=v") 1326 (smin:VI (match_operand:VI 1 "register_operand" "v") 1327 (match_operand:VI 2 "register_operand" "v")))] 1328 "TARGET_VX" 1329 "vmn<bhfgq>\t%v0,%v1,%v2" 1330 [(set_attr "op_type" "VRR")]) 1331 1332; vmxb, vmxh, vmxf, vmxg 1333(define_insn "smax<mode>3" 1334 [(set (match_operand:VI 0 "register_operand" "=v") 1335 (smax:VI (match_operand:VI 1 "register_operand" "v") 1336 (match_operand:VI 2 "register_operand" "v")))] 1337 "TARGET_VX" 1338 "vmx<bhfgq>\t%v0,%v1,%v2" 1339 [(set_attr "op_type" "VRR")]) 1340 1341; vmnlb, vmnlh, vmnlf, vmnlg 1342(define_insn "umin<mode>3" 1343 [(set (match_operand:VI 0 "register_operand" "=v") 1344 (umin:VI (match_operand:VI 1 "register_operand" "v") 1345 (match_operand:VI 2 "register_operand" "v")))] 1346 "TARGET_VX" 1347 "vmnl<bhfgq>\t%v0,%v1,%v2" 1348 [(set_attr "op_type" "VRR")]) 1349 1350; vmxlb, vmxlh, vmxlf, vmxlg 1351(define_insn "umax<mode>3" 1352 [(set (match_operand:VI 0 "register_operand" "=v") 1353 (umax:VI (match_operand:VI 1 "register_operand" "v") 1354 (match_operand:VI 2 "register_operand" "v")))] 1355 "TARGET_VX" 1356 "vmxl<bhfgq>\t%v0,%v1,%v2" 1357 [(set_attr "op_type" "VRR")]) 1358 1359; vmeb, vmeh, vmef 1360(define_insn "vec_widen_smult_even_<mode>" 1361 [(set (match_operand:<vec_double> 0 "register_operand" "=v") 1362 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v") 1363 (match_operand:VI_QHS 2 "register_operand" "v")] 1364 UNSPEC_VEC_SMULT_EVEN))] 1365 "TARGET_VX" 1366 "vme<bhfgq>\t%v0,%v1,%v2" 1367 [(set_attr "op_type" "VRR")]) 1368 1369; vmleb, vmleh, vmlef 1370(define_insn "vec_widen_umult_even_<mode>" 1371 [(set (match_operand:<vec_double> 0 "register_operand" "=v") 1372 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v") 1373 (match_operand:VI_QHS 2 "register_operand" "v")] 1374 UNSPEC_VEC_UMULT_EVEN))] 1375 "TARGET_VX" 1376 "vmle<bhfgq>\t%v0,%v1,%v2" 1377 [(set_attr "op_type" "VRR")]) 1378 1379; vmob, vmoh, vmof 1380(define_insn "vec_widen_smult_odd_<mode>" 1381 [(set (match_operand:<vec_double> 0 "register_operand" "=v") 1382 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v") 1383 (match_operand:VI_QHS 2 "register_operand" "v")] 1384 UNSPEC_VEC_SMULT_ODD))] 1385 "TARGET_VX" 1386 "vmo<bhfgq>\t%v0,%v1,%v2" 1387 [(set_attr "op_type" "VRR")]) 1388 1389; vmlob, vmloh, vmlof 1390(define_insn "vec_widen_umult_odd_<mode>" 1391 [(set (match_operand:<vec_double> 0 "register_operand" "=v") 1392 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "v") 1393 (match_operand:VI_QHS 2 "register_operand" "v")] 1394 UNSPEC_VEC_UMULT_ODD))] 1395 "TARGET_VX" 1396 "vmlo<bhfgq>\t%v0,%v1,%v2" 1397 [(set_attr "op_type" "VRR")]) 1398 1399 1400; Widening hi/lo multiplications 1401 1402; The S/390 instructions vml and vmh return the low or high parts of 1403; the double sized result elements in the corresponding elements of 1404; the target register. That's NOT what the vec_widen_umult_lo/hi 1405; patterns are expected to do. 1406 1407; We emulate the widening lo/hi multiplies with the even/odd versions 1408; followed by a vector merge 1409 1410 1411(define_expand "vec_widen_umult_lo_<mode>" 1412 [(set (match_dup 3) 1413 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "") 1414 (match_operand:VI_QHS 2 "register_operand" "")] 1415 UNSPEC_VEC_UMULT_EVEN)) 1416 (set (match_dup 4) 1417 (unspec:<vec_double> [(match_dup 1) (match_dup 2)] 1418 UNSPEC_VEC_UMULT_ODD)) 1419 (set (match_operand:<vec_double> 0 "register_operand" "") 1420 (vec_select:<vec_double> 1421 (vec_concat:<vec_2x_wide> (match_dup 3) (match_dup 4)) 1422 (match_dup 5)))] 1423 "TARGET_VX" 1424 { 1425 operands[3] = gen_reg_rtx (<vec_double>mode); 1426 operands[4] = gen_reg_rtx (<vec_double>mode); 1427 operands[5] = s390_expand_merge_perm_const (<vec_double>mode, false); 1428 }) 1429 1430(define_expand "vec_widen_umult_hi_<mode>" 1431 [(set (match_dup 3) 1432 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "") 1433 (match_operand:VI_QHS 2 "register_operand" "")] 1434 UNSPEC_VEC_UMULT_EVEN)) 1435 (set (match_dup 4) 1436 (unspec:<vec_double> [(match_dup 1) (match_dup 2)] 1437 UNSPEC_VEC_UMULT_ODD)) 1438 (set (match_operand:<vec_double> 0 "register_operand" "") 1439 (vec_select:<vec_double> 1440 (vec_concat:<vec_2x_wide> (match_dup 3) (match_dup 4)) 1441 (match_dup 5)))] 1442 "TARGET_VX" 1443 { 1444 operands[3] = gen_reg_rtx (<vec_double>mode); 1445 operands[4] = gen_reg_rtx (<vec_double>mode); 1446 operands[5] = s390_expand_merge_perm_const (<vec_double>mode, true); 1447 }) 1448 1449(define_expand "vec_widen_smult_lo_<mode>" 1450 [(set (match_dup 3) 1451 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "") 1452 (match_operand:VI_QHS 2 "register_operand" "")] 1453 UNSPEC_VEC_SMULT_EVEN)) 1454 (set (match_dup 4) 1455 (unspec:<vec_double> [(match_dup 1) (match_dup 2)] 1456 UNSPEC_VEC_SMULT_ODD)) 1457 (set (match_operand:<vec_double> 0 "register_operand" "") 1458 (vec_select:<vec_double> 1459 (vec_concat:<vec_2x_wide> (match_dup 3) (match_dup 4)) 1460 (match_dup 5)))] 1461 "TARGET_VX" 1462 { 1463 operands[3] = gen_reg_rtx (<vec_double>mode); 1464 operands[4] = gen_reg_rtx (<vec_double>mode); 1465 operands[5] = s390_expand_merge_perm_const (<vec_double>mode, false); 1466 }) 1467 1468(define_expand "vec_widen_smult_hi_<mode>" 1469 [(set (match_dup 3) 1470 (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "") 1471 (match_operand:VI_QHS 2 "register_operand" "")] 1472 UNSPEC_VEC_SMULT_EVEN)) 1473 (set (match_dup 4) 1474 (unspec:<vec_double> [(match_dup 1) (match_dup 2)] 1475 UNSPEC_VEC_SMULT_ODD)) 1476 (set (match_operand:<vec_double> 0 "register_operand" "") 1477 (vec_select:<vec_double> 1478 (vec_concat:<vec_2x_wide> (match_dup 3) (match_dup 4)) 1479 (match_dup 5)))] 1480 "TARGET_VX" 1481 { 1482 operands[3] = gen_reg_rtx (<vec_double>mode); 1483 operands[4] = gen_reg_rtx (<vec_double>mode); 1484 operands[5] = s390_expand_merge_perm_const (<vec_double>mode, true); 1485 }) 1486 1487; vec_widen_ushiftl_hi 1488; vec_widen_ushiftl_lo 1489; vec_widen_sshiftl_hi 1490; vec_widen_sshiftl_lo 1491 1492;; 1493;; Vector floating point arithmetic instructions 1494;; 1495 1496; vfasb, vfadb, wfasb, wfadb, wfaxb 1497(define_insn "add<mode>3<tf_vr>" 1498 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1499 (plus:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1500 (match_operand:VF_HW 2 "register_operand" "v")))] 1501 "TARGET_VX" 1502 "<vw>fa<sdx>b\t%v0,%v1,%v2" 1503 [(set_attr "op_type" "VRR")]) 1504 1505(define_expand "addtf3" 1506 [(match_operand:TF 0 "register_operand" "") 1507 (match_operand:TF 1 "nonimmediate_operand" "") 1508 (match_operand:TF 2 "general_operand" "")] 1509 "HAVE_TF (addtf3)" 1510 { EXPAND_TF (addtf3, 3); }) 1511 1512; vfssb, vfsdb, wfssb, wfsdb, wfsxb 1513(define_insn "sub<mode>3<tf_vr>" 1514 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1515 (minus:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1516 (match_operand:VF_HW 2 "register_operand" "v")))] 1517 "TARGET_VX" 1518 "<vw>fs<sdx>b\t%v0,%v1,%v2" 1519 [(set_attr "op_type" "VRR")]) 1520 1521(define_expand "subtf3" 1522 [(match_operand:TF 0 "register_operand" "") 1523 (match_operand:TF 1 "register_operand" "") 1524 (match_operand:TF 2 "general_operand" "")] 1525 "HAVE_TF (subtf3)" 1526 { EXPAND_TF (subtf3, 3); }) 1527 1528; vfmsb, vfmdb, wfmsb, wfmdb, wfmxb 1529(define_insn "mul<mode>3<tf_vr>" 1530 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1531 (mult:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1532 (match_operand:VF_HW 2 "register_operand" "v")))] 1533 "TARGET_VX" 1534 "<vw>fm<sdx>b\t%v0,%v1,%v2" 1535 [(set_attr "op_type" "VRR")]) 1536 1537(define_expand "multf3" 1538 [(match_operand:TF 0 "register_operand" "") 1539 (match_operand:TF 1 "nonimmediate_operand" "") 1540 (match_operand:TF 2 "general_operand" "")] 1541 "HAVE_TF (multf3)" 1542 { EXPAND_TF (multf3, 3); }) 1543 1544; vfdsb, vfddb, wfdsb, wfddb, wfdxb 1545(define_insn "div<mode>3<tf_vr>" 1546 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1547 (div:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1548 (match_operand:VF_HW 2 "register_operand" "v")))] 1549 "TARGET_VX" 1550 "<vw>fd<sdx>b\t%v0,%v1,%v2" 1551 [(set_attr "op_type" "VRR")]) 1552 1553(define_expand "divtf3" 1554 [(match_operand:TF 0 "register_operand" "") 1555 (match_operand:TF 1 "register_operand" "") 1556 (match_operand:TF 2 "general_operand" "")] 1557 "HAVE_TF (divtf3)" 1558 { EXPAND_TF (divtf3, 3); }) 1559 1560; vfsqsb, vfsqdb, wfsqsb, wfsqdb, wfsqxb 1561(define_insn "sqrt<mode>2<tf_vr>" 1562 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1563 (sqrt:VF_HW (match_operand:VF_HW 1 "register_operand" "v")))] 1564 "TARGET_VX" 1565 "<vw>fsq<sdx>b\t%v0,%v1" 1566 [(set_attr "op_type" "VRR")]) 1567 1568(define_expand "sqrttf2" 1569 [(match_operand:TF 0 "register_operand" "") 1570 (match_operand:TF 1 "general_operand" "")] 1571 "HAVE_TF (sqrttf2)" 1572 { EXPAND_TF (sqrttf2, 2); }) 1573 1574; vfmasb, vfmadb, wfmasb, wfmadb, wfmaxb 1575(define_insn "fma<mode>4" 1576 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1577 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1578 (match_operand:VF_HW 2 "register_operand" "v") 1579 (match_operand:VF_HW 3 "register_operand" "v")))] 1580 "TARGET_VX && s390_fma_allowed_p (<MODE>mode)" 1581 "<vw>fma<sdx>b\t%v0,%v1,%v2,%v3" 1582 [(set_attr "op_type" "VRR")]) 1583 1584; vfmssb, vfmsdb, wfmssb, wfmsdb, wfmsxb 1585(define_insn "fms<mode>4" 1586 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1587 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1588 (match_operand:VF_HW 2 "register_operand" "v") 1589 (neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v"))))] 1590 "TARGET_VX && s390_fma_allowed_p (<MODE>mode)" 1591 "<vw>fms<sdx>b\t%v0,%v1,%v2,%v3" 1592 [(set_attr "op_type" "VRR")]) 1593 1594; vfnmasb, vfnmadb, wfnmasb, wfnmadb, wfnmaxb 1595(define_insn "neg_fma<mode>4" 1596 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1597 (neg:VF_HW 1598 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1599 (match_operand:VF_HW 2 "register_operand" "v") 1600 (match_operand:VF_HW 3 "register_operand" "v"))))] 1601 "TARGET_VXE && s390_fma_allowed_p (<MODE>mode)" 1602 "<vw>fnma<sdx>b\t%v0,%v1,%v2,%v3" 1603 [(set_attr "op_type" "VRR")]) 1604 1605; vfnmssb, vfnmsdb, wfnmssb, wfnmsdb, wfnmsxb 1606(define_insn "neg_fms<mode>4" 1607 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1608 (neg:VF_HW 1609 (fma:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1610 (match_operand:VF_HW 2 "register_operand" "v") 1611 (neg:VF_HW (match_operand:VF_HW 3 "register_operand" "v")))))] 1612 "TARGET_VXE && s390_fma_allowed_p (<MODE>mode)" 1613 "<vw>fnms<sdx>b\t%v0,%v1,%v2,%v3" 1614 [(set_attr "op_type" "VRR")]) 1615 1616; vflcsb, vflcdb, wflcsb, wflcdb, wflcxb 1617(define_insn "neg<mode>2<tf_vr>" 1618 [(set (match_operand:VFT 0 "register_operand" "=v") 1619 (neg:VFT (match_operand:VFT 1 "register_operand" "v")))] 1620 "TARGET_VX" 1621 "<vw>flc<sdx>b\t%v0,%v1" 1622 [(set_attr "op_type" "VRR")]) 1623 1624(define_expand "negtf2" 1625 [(match_operand:TF 0 "register_operand" "") 1626 (match_operand:TF 1 "register_operand" "")] 1627 "HAVE_TF (negtf2)" 1628 { EXPAND_TF (negtf2, 2); }) 1629 1630; vflpsb, vflpdb, wflpsb, wflpdb, wflpxb 1631(define_insn "abs<mode>2<tf_vr>" 1632 [(set (match_operand:VFT 0 "register_operand" "=v") 1633 (abs:VFT (match_operand:VFT 1 "register_operand" "v")))] 1634 "TARGET_VX" 1635 "<vw>flp<sdx>b\t%v0,%v1" 1636 [(set_attr "op_type" "VRR")]) 1637 1638(define_expand "abstf2" 1639 [(match_operand:TF 0 "register_operand" "") 1640 (match_operand:TF 1 "register_operand" "")] 1641 "HAVE_TF (abstf2)" 1642 { EXPAND_TF (abstf2, 2); }) 1643 1644; vflnsb, vflndb, wflnsb, wflndb, wflnxb 1645(define_insn "negabs<mode>2" 1646 [(set (match_operand:VFT 0 "register_operand" "=v") 1647 (neg:VFT (abs:VFT (match_operand:VFT 1 "register_operand" "v"))))] 1648 "TARGET_VX" 1649 "<vw>fln<sdx>b\t%v0,%v1" 1650 [(set_attr "op_type" "VRR")]) 1651 1652(define_expand "smax<mode>3" 1653 [(set (match_operand:VF_HW 0 "register_operand") 1654 (smax:VF_HW (match_operand:VF_HW 1 "register_operand") 1655 (match_operand:VF_HW 2 "register_operand")))] 1656 "TARGET_VX") 1657 1658; vfmaxsb, vfmaxdb, wfmaxsb, wfmaxdb, wfmaxxb 1659(define_insn "*smax<mode>3_vxe" 1660 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1661 (smax:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1662 (match_operand:VF_HW 2 "register_operand" "v")))] 1663 "TARGET_VXE" 1664 "<vw>fmax<sdx>b\t%v0,%v1,%v2,4" 1665 [(set_attr "op_type" "VRR")]) 1666 1667; Emulate with compare + select 1668(define_insn_and_split "*smaxv2df3_vx" 1669 [(set (match_operand:V2DF 0 "register_operand" "=v") 1670 (smax:V2DF (match_operand:V2DF 1 "register_operand" "v") 1671 (match_operand:V2DF 2 "register_operand" "v")))] 1672 "TARGET_VX && !TARGET_VXE" 1673 "#" 1674 "&& 1" 1675 [(set (match_dup 3) 1676 (not:V2DI 1677 (unge:V2DI (match_dup 2) (match_dup 1)))) 1678 (set (match_dup 0) 1679 (if_then_else:V2DF 1680 (eq (match_dup 3) (match_dup 4)) 1681 (match_dup 2) 1682 (match_dup 1)))] 1683{ 1684 operands[3] = gen_reg_rtx (V2DImode); 1685 operands[4] = CONST0_RTX (V2DImode); 1686}) 1687 1688(define_expand "smin<mode>3" 1689 [(set (match_operand:VF_HW 0 "register_operand") 1690 (smin:VF_HW (match_operand:VF_HW 1 "register_operand") 1691 (match_operand:VF_HW 2 "register_operand")))] 1692 "TARGET_VX") 1693 1694; vfminsb, vfmindb, wfminsb, wfmindb, wfminxb 1695(define_insn "*smin<mode>3_vxe" 1696 [(set (match_operand:VF_HW 0 "register_operand" "=v") 1697 (smin:VF_HW (match_operand:VF_HW 1 "register_operand" "v") 1698 (match_operand:VF_HW 2 "register_operand" "v")))] 1699 "TARGET_VXE" 1700 "<vw>fmin<sdx>b\t%v0,%v1,%v2,4" 1701 [(set_attr "op_type" "VRR")]) 1702 1703; Emulate with compare + select 1704(define_insn_and_split "*sminv2df3_vx" 1705 [(set (match_operand:V2DF 0 "register_operand" "=v") 1706 (smin:V2DF (match_operand:V2DF 1 "register_operand" "v") 1707 (match_operand:V2DF 2 "register_operand" "v")))] 1708 "TARGET_VX && !TARGET_VXE" 1709 "#" 1710 "&& 1" 1711 [(set (match_dup 3) 1712 (not:V2DI 1713 (unge:V2DI (match_dup 2) (match_dup 1)))) 1714 (set (match_dup 0) 1715 (if_then_else:V2DF 1716 (eq (match_dup 3) (match_dup 4)) 1717 (match_dup 1) 1718 (match_dup 2)))] 1719{ 1720 operands[3] = gen_reg_rtx (V2DImode); 1721 operands[4] = CONST0_RTX (V2DImode); 1722}) 1723 1724; Vector copysign, implement using vector select 1725(define_expand "copysign<mode>3" 1726 [(set (match_operand:VFT 0 "register_operand" "") 1727 (ior:VFT 1728 (and:VFT (match_operand:VFT 2 "register_operand" "") 1729 (match_dup 3)) 1730 (and:VFT (not:VFT (match_dup 3)) 1731 (match_operand:VFT 1 "register_operand" ""))))] 1732 "TARGET_VX" 1733{ 1734 rtx mask = s390_build_signbit_mask (<MODE>mode); 1735 operands[3] = force_reg (<MODE>mode, mask); 1736}) 1737 1738;; 1739;; Compares 1740;; 1741 1742(define_expand "vec_cmp<mode><tointvec>" 1743 [(set (match_operand:<TOINTVEC> 0 "register_operand" "") 1744 (match_operator:<TOINTVEC> 1 "vcond_comparison_operator" 1745 [(match_operand:V_HW 2 "register_operand" "") 1746 (match_operand:V_HW 3 "nonmemory_operand" "")]))] 1747 "TARGET_VX" 1748{ 1749 s390_expand_vec_compare (operands[0], GET_CODE(operands[1]), operands[2], operands[3]); 1750 DONE; 1751}) 1752 1753(define_expand "vec_cmpu<VI_HW:mode><VI_HW:mode>" 1754 [(set (match_operand:VI_HW 0 "register_operand" "") 1755 (match_operator:VI_HW 1 "" 1756 [(match_operand:VI_HW 2 "register_operand" "") 1757 (match_operand:VI_HW 3 "register_operand" "")]))] 1758 "TARGET_VX" 1759{ 1760 s390_expand_vec_compare (operands[0], GET_CODE(operands[1]), operands[2], operands[3]); 1761 DONE; 1762}) 1763 1764(define_insn "*vec_cmp<VICMP_HW_OP:code><VI:mode><VI:mode>_nocc" 1765 [(set (match_operand:VI 2 "register_operand" "=v") 1766 (VICMP_HW_OP:VI (match_operand:VI 0 "register_operand" "v") 1767 (match_operand:VI 1 "register_operand" "v")))] 1768 "TARGET_VX" 1769 "vc<VICMP_HW_OP:insn_cmp_op><VI:bhfgq>\t%v2,%v0,%v1" 1770 [(set_attr "op_type" "VRR")]) 1771 1772 1773;; 1774;; Floating point compares 1775;; 1776 1777; vfcesb, vfcedb, wfcexb: non-signaling "==" comparison (a == b) 1778(define_insn "*vec_cmpeq<mode>_quiet_nocc" 1779 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1780 (eq:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1781 (match_operand:VFT 2 "register_operand" "v")))] 1782 "TARGET_VX" 1783 "<vw>fce<sdx>b\t%v0,%v1,%v2" 1784 [(set_attr "op_type" "VRR")]) 1785 1786; vfchsb, vfchdb, wfchxb: non-signaling > comparison (!(b u>= a)) 1787(define_insn "vec_cmpgt<mode>_quiet_nocc" 1788 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1789 (not:<TOINTVEC> 1790 (unge:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v") 1791 (match_operand:VFT 1 "register_operand" "v"))))] 1792 "TARGET_VX" 1793 "<vw>fch<sdx>b\t%v0,%v1,%v2" 1794 [(set_attr "op_type" "VRR")]) 1795 1796(define_expand "vec_cmplt<mode>_quiet_nocc" 1797 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1798 (not:<TOINTVEC> 1799 (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1800 (match_operand:VFT 2 "register_operand" "v"))))] 1801 "TARGET_VX") 1802 1803; vfchesb, vfchedb, wfchexb: non-signaling >= comparison (!(a u< b)) 1804(define_insn "vec_cmpge<mode>_quiet_nocc" 1805 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1806 (not:<TOINTVEC> 1807 (unlt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1808 (match_operand:VFT 2 "register_operand" "v"))))] 1809 "TARGET_VX" 1810 "<vw>fche<sdx>b\t%v0,%v1,%v2" 1811 [(set_attr "op_type" "VRR")]) 1812 1813(define_expand "vec_cmple<mode>_quiet_nocc" 1814 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1815 (not:<TOINTVEC> 1816 (unlt:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v") 1817 (match_operand:VFT 1 "register_operand" "v"))))] 1818 "TARGET_VX") 1819 1820; vfkesb, vfkedb, wfkexb: signaling == comparison ((a >= b) & (b >= a)) 1821(define_insn "*vec_cmpeq<mode>_signaling_nocc" 1822 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1823 (and:<TOINTVEC> 1824 (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1825 (match_operand:VFT 2 "register_operand" "v")) 1826 (ge:<TOINTVEC> (match_dup 2) 1827 (match_dup 1))))] 1828 "TARGET_VXE" 1829 "<vw>fke<sdx>b\t%v0,%v1,%v2" 1830 [(set_attr "op_type" "VRR")]) 1831 1832; vfkhsb, vfkhdb, wfkhxb: signaling > comparison (a > b) 1833(define_insn "*vec_cmpgt<mode>_signaling_nocc" 1834 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1835 (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1836 (match_operand:VFT 2 "register_operand" "v")))] 1837 "TARGET_VXE" 1838 "<vw>fkh<sdx>b\t%v0,%v1,%v2" 1839 [(set_attr "op_type" "VRR")]) 1840 1841(define_insn "*vec_cmpgt<mode>_signaling_finite_nocc" 1842 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1843 (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1844 (match_operand:VFT 2 "register_operand" "v")))] 1845 "TARGET_NONSIGNALING_VECTOR_COMPARE_OK" 1846 "<vw>fch<sdx>b\t%v0,%v1,%v2" 1847 [(set_attr "op_type" "VRR")]) 1848 1849; vfkhesb, vfkhedb, wfkhexb: signaling >= comparison (a >= b) 1850(define_insn "*vec_cmpge<mode>_signaling_nocc" 1851 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1852 (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1853 (match_operand:VFT 2 "register_operand" "v")))] 1854 "TARGET_VXE" 1855 "<vw>fkhe<sdx>b\t%v0,%v1,%v2" 1856 [(set_attr "op_type" "VRR")]) 1857 1858(define_insn "*vec_cmpge<mode>_signaling_finite_nocc" 1859 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1860 (ge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1861 (match_operand:VFT 2 "register_operand" "v")))] 1862 "TARGET_NONSIGNALING_VECTOR_COMPARE_OK" 1863 "<vw>fche<sdx>b\t%v0,%v1,%v2" 1864 [(set_attr "op_type" "VRR")]) 1865 1866; Expanders for not directly supported comparisons 1867; Signaling comparisons must be expressed via signaling rtxes only, 1868; and quiet comparisons must be expressed via quiet rtxes only. 1869 1870; UNGT a u> b -> !!(b u< a) 1871(define_expand "vec_cmpungt<mode>" 1872 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1873 (not:<TOINTVEC> 1874 (unlt:<TOINTVEC> (match_operand:VFT 2 "register_operand" "v") 1875 (match_operand:VFT 1 "register_operand" "v")))) 1876 (set (match_dup 0) 1877 (not:<TOINTVEC> (match_dup 0)))] 1878 "TARGET_VX") 1879 1880; UNGE a u>= b -> !!(a u>= b) 1881(define_expand "vec_cmpunge<mode>" 1882 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1883 (not:<TOINTVEC> 1884 (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1885 (match_operand:VFT 2 "register_operand" "v")))) 1886 (set (match_dup 0) 1887 (not:<TOINTVEC> (match_dup 0)))] 1888 "TARGET_VX") 1889 1890; UNEQ a u== b -> !(!(a u>= b) | !(b u>= a)) 1891(define_expand "vec_cmpuneq<mode>" 1892 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1893 (not:<TOINTVEC> 1894 (unge:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1895 (match_operand:VFT 2 "register_operand" "v")))) 1896 (set (match_dup 3) 1897 (not:<TOINTVEC> 1898 (unge:<TOINTVEC> (match_dup 2) 1899 (match_dup 1)))) 1900 (set (match_dup 0) 1901 (ior:<TOINTVEC> (match_dup 0) 1902 (match_dup 3))) 1903 (set (match_dup 0) 1904 (not:<TOINTVEC> (match_dup 0)))] 1905 "TARGET_VX" 1906{ 1907 operands[3] = gen_reg_rtx (<TOINTVEC>mode); 1908}) 1909 1910; LTGT a <> b -> a > b | b > a 1911(define_expand "vec_cmpltgt<mode>" 1912 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1913 (gt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1914 (match_operand:VFT 2 "register_operand" "v"))) 1915 (set (match_dup 3) (gt:<TOINTVEC> (match_dup 2) (match_dup 1))) 1916 (set (match_dup 0) (ior:<TOINTVEC> (match_dup 0) (match_dup 3)))] 1917 "TARGET_VXE" 1918{ 1919 operands[3] = gen_reg_rtx (<TOINTVEC>mode); 1920}) 1921 1922; ORDERED (a, b): !(a u< b) | !(a u>= b) 1923(define_expand "vec_cmpordered<mode>" 1924 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v") 1925 (not:<TOINTVEC> 1926 (unlt:<TOINTVEC> (match_operand:VFT 1 "register_operand" "v") 1927 (match_operand:VFT 2 "register_operand" "v")))) 1928 (set (match_dup 3) 1929 (not:<TOINTVEC> 1930 (unge:<TOINTVEC> (match_dup 1) 1931 (match_dup 2)))) 1932 (set (match_dup 0) 1933 (ior:<TOINTVEC> (match_dup 0) 1934 (match_dup 3)))] 1935 "TARGET_VX" 1936{ 1937 operands[3] = gen_reg_rtx (<TOINTVEC>mode); 1938}) 1939 1940; UNORDERED (a, b): !ORDERED (a, b) 1941(define_expand "vec_cmpunordered<mode>" 1942 [(match_operand:<TOINTVEC> 0 "register_operand" "=v") 1943 (match_operand:VFT 1 "register_operand" "v") 1944 (match_operand:VFT 2 "register_operand" "v")] 1945 "TARGET_VX" 1946{ 1947 emit_insn (gen_vec_cmpordered<mode> (operands[0], operands[1], operands[2])); 1948 emit_insn (gen_rtx_SET (operands[0], 1949 gen_rtx_NOT (<TOINTVEC>mode, operands[0]))); 1950 DONE; 1951}) 1952 1953(define_code_iterator VEC_CMP_EXPAND 1954 [ungt unge uneq ltgt ordered unordered]) 1955 1956(define_expand "vec_cmp<code>" 1957 [(match_operand 0 "register_operand" "") 1958 (VEC_CMP_EXPAND (match_operand 1 "register_operand" "") 1959 (match_operand 2 "register_operand" ""))] 1960 "TARGET_VX" 1961{ 1962 if (GET_MODE (operands[1]) == V4SFmode) 1963 emit_insn (gen_vec_cmp<code>v4sf (operands[0], operands[1], operands[2])); 1964 else if (GET_MODE (operands[1]) == V2DFmode) 1965 emit_insn (gen_vec_cmp<code>v2df (operands[0], operands[1], operands[2])); 1966 else 1967 gcc_unreachable (); 1968 1969 DONE; 1970}) 1971 1972(define_insn "*vec_load_pair<mode>" 1973 [(set (match_operand:V_HW_2 0 "register_operand" "=v,v") 1974 (vec_concat:V_HW_2 (match_operand:<non_vec> 1 "register_operand" "d,v") 1975 (match_operand:<non_vec> 2 "register_operand" "d,v")))] 1976 "TARGET_VX" 1977 "@ 1978 vlvgp\t%v0,%1,%2 1979 vmrhg\t%v0,%v1,%v2" 1980 [(set_attr "op_type" "VRR,VRR")]) 1981 1982(define_insn "vllv16qi" 1983 [(set (match_operand:V16QI 0 "register_operand" "=v") 1984 (unspec:V16QI [(match_operand:SI 1 "register_operand" "d") 1985 (match_operand:BLK 2 "memory_operand" "Q")] 1986 UNSPEC_VEC_LOAD_LEN))] 1987 "TARGET_VX" 1988 "vll\t%v0,%1,%2" 1989 [(set_attr "op_type" "VRS")]) 1990 1991; vfeebs, vfeehs, vfeefs 1992; vfeezbs, vfeezhs, vfeezfs 1993(define_insn "@vec_vfees<mode>" 1994 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") 1995 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") 1996 (match_operand:VI_HW_QHS 2 "register_operand" "v") 1997 (match_operand:QI 3 "const_mask_operand" "C")] 1998 UNSPEC_VEC_VFEE)) 1999 (set (reg:CCRAW CC_REGNUM) 2000 (unspec:CCRAW [(match_dup 1) 2001 (match_dup 2) 2002 (match_dup 3)] 2003 UNSPEC_VEC_VFEECC))] 2004 "TARGET_VX" 2005{ 2006 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]); 2007 2008 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS))); 2009 flags &= ~VSTRING_FLAG_CS; 2010 2011 if (flags == VSTRING_FLAG_ZS) 2012 return "vfeez<bhfgq>s\t%v0,%v1,%v2"; 2013 return "vfee<bhfgq>s\t%v0,%v1,%v2"; 2014} 2015 [(set_attr "op_type" "VRR")]) 2016 2017; vfenebs, vfenehs, vfenefs 2018; vfenezbs, vfenezhs, vfenezfs 2019(define_insn "vec_vfenes<mode>" 2020 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v") 2021 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v") 2022 (match_operand:VI_HW_QHS 2 "register_operand" "v") 2023 (match_operand:QI 3 "const_mask_operand" "C")] 2024 UNSPEC_VEC_VFENE)) 2025 (set (reg:CCRAW CC_REGNUM) 2026 (unspec:CCRAW [(match_dup 1) 2027 (match_dup 2) 2028 (match_dup 3)] 2029 UNSPEC_VEC_VFENECC))] 2030 "TARGET_VX" 2031{ 2032 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]); 2033 2034 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS))); 2035 flags &= ~VSTRING_FLAG_CS; 2036 2037 if (flags == VSTRING_FLAG_ZS) 2038 return "vfenez<bhfgq>s\t%v0,%v1,%v2"; 2039 return "vfene<bhfgq>s\t%v0,%v1,%v2"; 2040} 2041 [(set_attr "op_type" "VRR")]) 2042 2043 2044; Vector select 2045 2046; The following splitters simplify vec_sel for constant 0 or -1 2047; selection sources. This is required to generate efficient code for 2048; vcond. 2049 2050; a = b == c; 2051(define_split 2052 [(set (match_operand:V 0 "register_operand" "") 2053 (if_then_else:V 2054 (eq (match_operand:<TOINTVEC> 3 "register_operand" "") 2055 (match_operand:V 4 "const0_operand" "")) 2056 (match_operand:V 1 "const0_operand" "") 2057 (match_operand:V 2 "all_ones_operand" "")))] 2058 "TARGET_VX" 2059 [(set (match_dup 0) (match_dup 3))] 2060{ 2061 PUT_MODE (operands[3], <V:MODE>mode); 2062}) 2063 2064; a = ~(b == c) 2065(define_split 2066 [(set (match_operand:V 0 "register_operand" "") 2067 (if_then_else:V 2068 (eq (match_operand:<TOINTVEC> 3 "register_operand" "") 2069 (match_operand:V 4 "const0_operand" "")) 2070 (match_operand:V 1 "all_ones_operand" "") 2071 (match_operand:V 2 "const0_operand" "")))] 2072 "TARGET_VX" 2073 [(set (match_dup 0) (not:V (match_dup 3)))] 2074{ 2075 PUT_MODE (operands[3], <V:MODE>mode); 2076}) 2077 2078; a = b != c 2079(define_split 2080 [(set (match_operand:V 0 "register_operand" "") 2081 (if_then_else:V 2082 (ne (match_operand:<TOINTVEC> 3 "register_operand" "") 2083 (match_operand:V 4 "const0_operand" "")) 2084 (match_operand:V 1 "all_ones_operand" "") 2085 (match_operand:V 2 "const0_operand" "")))] 2086 "TARGET_VX" 2087 [(set (match_dup 0) (match_dup 3))] 2088{ 2089 PUT_MODE (operands[3], <V:MODE>mode); 2090}) 2091 2092; a = ~(b != c) 2093(define_split 2094 [(set (match_operand:V 0 "register_operand" "") 2095 (if_then_else:V 2096 (ne (match_operand:<TOINTVEC> 3 "register_operand" "") 2097 (match_operand:V 4 "const0_operand" "")) 2098 (match_operand:V 1 "const0_operand" "") 2099 (match_operand:V 2 "all_ones_operand" "")))] 2100 "TARGET_VX" 2101 [(set (match_dup 0) (not:V (match_dup 3)))] 2102{ 2103 PUT_MODE (operands[3], <V:MODE>mode); 2104}) 2105 2106; op0 = op3 == 0 ? op1 : op2 2107(define_insn "*vec_sel0<mode>" 2108 [(set (match_operand:V 0 "register_operand" "=v") 2109 (if_then_else:V 2110 (eq (match_operand:<TOINTVEC> 3 "register_operand" "v") 2111 (match_operand:<TOINTVEC> 4 "const0_operand" "")) 2112 (match_operand:V 1 "register_operand" "v") 2113 (match_operand:V 2 "register_operand" "v")))] 2114 "TARGET_VX" 2115 "vsel\t%v0,%2,%1,%3" 2116 [(set_attr "op_type" "VRR")]) 2117 2118; op0 = !op3 == 0 ? op1 : op2 2119(define_insn "*vec_sel0<mode>" 2120 [(set (match_operand:V 0 "register_operand" "=v") 2121 (if_then_else:V 2122 (eq (not:<TOINTVEC> (match_operand:<TOINTVEC> 3 "register_operand" "v")) 2123 (match_operand:<TOINTVEC> 4 "const0_operand" "")) 2124 (match_operand:V 1 "register_operand" "v") 2125 (match_operand:V 2 "register_operand" "v")))] 2126 "TARGET_VX" 2127 "vsel\t%v0,%1,%2,%3" 2128 [(set_attr "op_type" "VRR")]) 2129 2130; op0 = op3 == -1 ? op1 : op2 2131(define_insn "*vec_sel1<mode>" 2132 [(set (match_operand:V 0 "register_operand" "=v") 2133 (if_then_else:V 2134 (eq (match_operand:<TOINTVEC> 3 "register_operand" "v") 2135 (match_operand:<TOINTVEC> 4 "all_ones_operand" "")) 2136 (match_operand:V 1 "register_operand" "v") 2137 (match_operand:V 2 "register_operand" "v")))] 2138 "TARGET_VX" 2139 "vsel\t%v0,%1,%2,%3" 2140 [(set_attr "op_type" "VRR")]) 2141 2142; op0 = !op3 == -1 ? op1 : op2 2143(define_insn "*vec_sel1<mode>" 2144 [(set (match_operand:V 0 "register_operand" "=v") 2145 (if_then_else:V 2146 (eq (not:<TOINTVEC> (match_operand:<TOINTVEC> 3 "register_operand" "v")) 2147 (match_operand:<TOINTVEC> 4 "all_ones_operand" "")) 2148 (match_operand:V 1 "register_operand" "v") 2149 (match_operand:V 2 "register_operand" "v")))] 2150 "TARGET_VX" 2151 "vsel\t%v0,%2,%1,%3" 2152 [(set_attr "op_type" "VRR")]) 2153 2154; vec_pack_trunc 2155 2156; vpkh, vpkf, vpkg 2157(define_insn "vec_pack_trunc_<mode>" 2158 [(set (match_operand:<vec_half> 0 "register_operand" "=v") 2159 (vec_concat:<vec_half> 2160 (truncate:<vec_halfhalf> 2161 (match_operand:VI_HW_HSD 1 "register_operand" "v")) 2162 (truncate:<vec_halfhalf> 2163 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))] 2164 "TARGET_VX" 2165 "vpk<bhfgq>\t%0,%1,%2" 2166 [(set_attr "op_type" "VRR")]) 2167 2168; vpksh, vpksf, vpksg 2169(define_insn "vec_pack_ssat_<mode>" 2170 [(set (match_operand:<vec_half> 0 "register_operand" "=v") 2171 (vec_concat:<vec_half> 2172 (ss_truncate:<vec_halfhalf> 2173 (match_operand:VI_HW_HSD 1 "register_operand" "v")) 2174 (ss_truncate:<vec_halfhalf> 2175 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))] 2176 "TARGET_VX" 2177 "vpks<bhfgq>\t%0,%1,%2" 2178 [(set_attr "op_type" "VRR")]) 2179 2180; vpklsh, vpklsf, vpklsg 2181(define_insn "vec_pack_usat_<mode>" 2182 [(set (match_operand:<vec_half> 0 "register_operand" "=v") 2183 (vec_concat:<vec_half> 2184 (us_truncate:<vec_halfhalf> 2185 (match_operand:VI_HW_HSD 1 "register_operand" "v")) 2186 (us_truncate:<vec_halfhalf> 2187 (match_operand:VI_HW_HSD 2 "register_operand" "v"))))] 2188 "TARGET_VX" 2189 "vpkls<bhfgq>\t%0,%1,%2" 2190 [(set_attr "op_type" "VRR")]) 2191 2192;; vector unpack v16qi 2193 2194; signed 2195 2196(define_insn "vec_unpacks_hi_v16qi" 2197 [(set (match_operand:V8HI 0 "register_operand" "=v") 2198 (sign_extend:V8HI 2199 (vec_select:V8QI 2200 (match_operand:V16QI 1 "register_operand" "v") 2201 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3) 2202 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] 2203 "TARGET_VX" 2204 "vuphb\t%0,%1" 2205 [(set_attr "op_type" "VRR")]) 2206 2207(define_insn "vec_unpacks_lo_v16qi" 2208 [(set (match_operand:V8HI 0 "register_operand" "=v") 2209 (sign_extend:V8HI 2210 (vec_select:V8QI 2211 (match_operand:V16QI 1 "register_operand" "v") 2212 (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11) 2213 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))] 2214 "TARGET_VX" 2215 "vuplb\t%0,%1" 2216 [(set_attr "op_type" "VRR")]) 2217 2218; unsigned 2219 2220(define_insn "vec_unpacku_hi_v16qi" 2221 [(set (match_operand:V8HI 0 "register_operand" "=v") 2222 (zero_extend:V8HI 2223 (vec_select:V8QI 2224 (match_operand:V16QI 1 "register_operand" "v") 2225 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3) 2226 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] 2227 "TARGET_VX" 2228 "vuplhb\t%0,%1" 2229 [(set_attr "op_type" "VRR")]) 2230 2231(define_insn "vec_unpacku_lo_v16qi" 2232 [(set (match_operand:V8HI 0 "register_operand" "=v") 2233 (zero_extend:V8HI 2234 (vec_select:V8QI 2235 (match_operand:V16QI 1 "register_operand" "v") 2236 (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11) 2237 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))] 2238 "TARGET_VX" 2239 "vupllb\t%0,%1" 2240 [(set_attr "op_type" "VRR")]) 2241 2242;; vector unpack v8hi 2243 2244; signed 2245 2246(define_insn "vec_unpacks_hi_v8hi" 2247 [(set (match_operand:V4SI 0 "register_operand" "=v") 2248 (sign_extend:V4SI 2249 (vec_select:V4HI 2250 (match_operand:V8HI 1 "register_operand" "v") 2251 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))] 2252 "TARGET_VX" 2253 "vuphh\t%0,%1" 2254 [(set_attr "op_type" "VRR")]) 2255 2256(define_insn "vec_unpacks_lo_v8hi" 2257 [(set (match_operand:V4SI 0 "register_operand" "=v") 2258 (sign_extend:V4SI 2259 (vec_select:V4HI 2260 (match_operand:V8HI 1 "register_operand" "v") 2261 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] 2262 "TARGET_VX" 2263 "vuplhw\t%0,%1" 2264 [(set_attr "op_type" "VRR")]) 2265 2266; unsigned 2267 2268(define_insn "vec_unpacku_hi_v8hi" 2269 [(set (match_operand:V4SI 0 "register_operand" "=v") 2270 (zero_extend:V4SI 2271 (vec_select:V4HI 2272 (match_operand:V8HI 1 "register_operand" "v") 2273 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))] 2274 "TARGET_VX" 2275 "vuplhh\t%0,%1" 2276 [(set_attr "op_type" "VRR")]) 2277 2278(define_insn "vec_unpacku_lo_v8hi" 2279 [(set (match_operand:V4SI 0 "register_operand" "=v") 2280 (zero_extend:V4SI 2281 (vec_select:V4HI 2282 (match_operand:V8HI 1 "register_operand" "v") 2283 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] 2284 "TARGET_VX" 2285 "vupllh\t%0,%1" 2286 [(set_attr "op_type" "VRR")]) 2287 2288;; vector unpack v4si 2289 2290; signed 2291 2292(define_insn "vec_unpacks_hi_v4si" 2293 [(set (match_operand:V2DI 0 "register_operand" "=v") 2294 (sign_extend:V2DI 2295 (vec_select:V2SI 2296 (match_operand:V4SI 1 "register_operand" "v") 2297 (parallel [(const_int 0)(const_int 1)]))))] 2298 "TARGET_VX" 2299 "vuphf\t%0,%1" 2300 [(set_attr "op_type" "VRR")]) 2301 2302(define_insn "vec_unpacks_lo_v4si" 2303 [(set (match_operand:V2DI 0 "register_operand" "=v") 2304 (sign_extend:V2DI 2305 (vec_select:V2SI 2306 (match_operand:V4SI 1 "register_operand" "v") 2307 (parallel [(const_int 2)(const_int 3)]))))] 2308 "TARGET_VX" 2309 "vuplf\t%0,%1" 2310 [(set_attr "op_type" "VRR")]) 2311 2312; unsigned 2313 2314(define_insn "vec_unpacku_hi_v4si" 2315 [(set (match_operand:V2DI 0 "register_operand" "=v") 2316 (zero_extend:V2DI 2317 (vec_select:V2SI 2318 (match_operand:V4SI 1 "register_operand" "v") 2319 (parallel [(const_int 0)(const_int 1)]))))] 2320 "TARGET_VX" 2321 "vuplhf\t%0,%1" 2322 [(set_attr "op_type" "VRR")]) 2323 2324(define_insn "vec_unpacku_lo_v4si" 2325 [(set (match_operand:V2DI 0 "register_operand" "=v") 2326 (zero_extend:V2DI 2327 (vec_select:V2SI 2328 (match_operand:V4SI 1 "register_operand" "v") 2329 (parallel [(const_int 2)(const_int 3)]))))] 2330 "TARGET_VX" 2331 "vupllf\t%0,%1" 2332 [(set_attr "op_type" "VRR")]) 2333 2334;; vector load lengthened 2335 2336; vflls float -> double 2337(define_insn "*vec_extendv4sf" 2338 [(set (match_operand:V2DF 0 "register_operand" "=v") 2339 (float_extend:V2DF 2340 (vec_select:V2SF 2341 (match_operand:V4SF 1 "register_operand" "v") 2342 (parallel [(const_int 0) (const_int 2)]))))] 2343 "TARGET_VX" 2344 "vldeb\t%v0,%v1" 2345 [(set_attr "op_type" "VRR")]) 2346 2347(define_expand "vec_unpacks_lo_v4sf" 2348 [(set (match_dup 2) 2349 (vec_select:V4SF 2350 (vec_concat:V8SF (match_operand:V4SF 1 "register_operand" "") (match_dup 1)) 2351 (match_dup 3))) 2352 (set (match_operand:V2DF 0 "register_operand" "") 2353 (float_extend:V2DF 2354 (vec_select:V2SF 2355 (match_dup 2) 2356 (parallel [(const_int 0) (const_int 2)]))))] 2357 "TARGET_VX" 2358{ 2359 operands[2] = gen_reg_rtx(V4SFmode); 2360 operands[3] = s390_expand_merge_perm_const (V4SFmode, false); 2361}) 2362 2363(define_expand "vec_unpacks_hi_v4sf" 2364 [(set (match_dup 2) 2365 (vec_select:V4SF 2366 (vec_concat:V8SF (match_operand:V4SF 1 "register_operand" "") (match_dup 1)) 2367 (match_dup 3))) 2368 (set (match_operand:V2DF 0 "register_operand" "") 2369 (float_extend:V2DF 2370 (vec_select:V2SF 2371 (match_dup 2) 2372 (parallel [(const_int 0) (const_int 2)]))))] 2373 "TARGET_VX" 2374{ 2375 operands[2] = gen_reg_rtx(V4SFmode); 2376 operands[3] = s390_expand_merge_perm_const (V4SFmode, true); 2377}) 2378 2379 2380; double -> long double 2381(define_insn "*vec_extendv2df" 2382 [(set (match_operand:V1TF 0 "register_operand" "=v") 2383 (float_extend:V1TF 2384 (vec_select:V1DF 2385 (match_operand:V2DF 1 "register_operand" "v") 2386 (parallel [(const_int 0)]))))] 2387 "TARGET_VXE" 2388 "wflld\t%v0,%v1" 2389 [(set_attr "op_type" "VRR")]) 2390 2391(define_expand "vec_unpacks_lo_v2df" 2392 [(set (match_dup 2) 2393 (vec_select:V2DF 2394 (vec_concat:V4DF (match_operand:V2DF 1 "register_operand" "") (match_dup 1)) 2395 (match_dup 3))) 2396 (set (match_operand:V1TF 0 "register_operand" "") 2397 (float_extend:V1TF 2398 (vec_select:V1DF 2399 (match_dup 2) 2400 (parallel [(const_int 0)]))))] 2401 "TARGET_VXE" 2402{ 2403 operands[2] = gen_reg_rtx (V2DFmode); 2404 operands[3] = s390_expand_merge_perm_const (V2DFmode, false); 2405}) 2406 2407(define_expand "vec_unpacks_hi_v2df" 2408 [(set (match_dup 2) 2409 (vec_select:V2DF 2410 (vec_concat:V4DF (match_operand:V2DF 1 "register_operand" "") (match_dup 1)) 2411 (match_dup 3))) 2412 (set (match_operand:V1TF 0 "register_operand" "") 2413 (float_extend:V1TF 2414 (vec_select:V1DF 2415 (match_dup 2) 2416 (parallel [(const_int 0)]))))] 2417 "TARGET_VXE" 2418{ 2419 operands[2] = gen_reg_rtx (V2DFmode); 2420 operands[3] = s390_expand_merge_perm_const (V2DFmode, true); 2421}) 2422 2423 2424; 2 x v2df -> 1 x v4sf 2425(define_expand "vec_pack_trunc_v2df" 2426 [(set (match_dup 3) 2427 (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "") 2428 (const_int VEC_INEXACT) 2429 (const_int VEC_RND_CURRENT)] 2430 UNSPEC_VEC_VFLR)) 2431 (set (match_dup 4) 2432 (unspec:V4SF [(match_operand:V2DF 2 "register_operand" "") 2433 (const_int VEC_INEXACT) 2434 (const_int VEC_RND_CURRENT)] 2435 UNSPEC_VEC_VFLR)) 2436 (set (match_dup 6) 2437 (unspec:V16QI [(subreg:V16QI (match_dup 3) 0) 2438 (subreg:V16QI (match_dup 4) 0) 2439 (match_dup 5)] 2440 UNSPEC_VEC_PERM)) 2441 (set (match_operand:V4SF 0 "register_operand" "") 2442 (subreg:V4SF (match_dup 6) 0))] 2443 "TARGET_VX" 2444{ 2445 rtx constv, perm[16]; 2446 int i; 2447 2448 for (i = 0; i < 4; ++i) 2449 { 2450 perm[i] = GEN_INT (i); 2451 perm[i + 4] = GEN_INT (i + 8); 2452 perm[i + 8] = GEN_INT (i + 16); 2453 perm[i + 12] = GEN_INT (i + 24); 2454 } 2455 constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)); 2456 2457 operands[3] = gen_reg_rtx (V4SFmode); 2458 operands[4] = gen_reg_rtx (V4SFmode); 2459 operands[5] = force_reg (V16QImode, constv); 2460 operands[6] = gen_reg_rtx (V16QImode); 2461}) 2462 2463; 2464; BFP <-> integer conversions 2465; 2466 2467; signed integer to floating point 2468 2469; op2: inexact exception not suppressed (IEEE 754 2008) 2470; op3: according to current rounding mode 2471; vcdgb, vcefb 2472(define_insn "float<VX_VEC_CONV_INT:mode><VX_VEC_CONV_BFP:mode>2" 2473 [(set (match_operand:VX_VEC_CONV_BFP 0 "register_operand" "=v") 2474 (float:VX_VEC_CONV_BFP (match_operand:VX_VEC_CONV_INT 1 "register_operand" "v")))] 2475 "TARGET_VX 2476 && GET_MODE_UNIT_SIZE (<VX_VEC_CONV_INT:MODE>mode) == GET_MODE_UNIT_SIZE (<VX_VEC_CONV_BFP:MODE>mode)" 2477 "vc<VX_VEC_CONV_BFP:xde><VX_VEC_CONV_INT:bhfgq>b\t%v0,%v1,0,0" 2478 [(set_attr "op_type" "VRR")]) 2479 2480; There is no instruction for loading a signed integer into an extended BFP 2481; operand in a VR, therefore we need to load it into a FPR pair first. 2482(define_expand "float<mode>tf2_vr" 2483 [(set (match_dup 2) 2484 (float:FPRX2 (match_operand:DSI 1 "register_operand" ""))) 2485 (set (match_operand:TF 0 "register_operand" "") 2486 (subreg:TF (match_dup 2) 0))] 2487 "TARGET_VXE" 2488{ 2489 operands[2] = gen_reg_rtx (FPRX2mode); 2490}) 2491 2492(define_expand "float<mode>tf2" 2493 [(match_operand:TF 0 "register_operand" "") 2494 (match_operand:DSI 1 "register_operand" "")] 2495 "HAVE_TF (float<mode>tf2)" 2496 { EXPAND_TF (float<mode>tf2, 2); }) 2497 2498; unsigned integer to floating point 2499 2500; op2: inexact exception not suppressed (IEEE 754 2008) 2501; op3: according to current rounding mode 2502; vcdlgb, vcelfb 2503(define_insn "floatuns<VX_VEC_CONV_INT:mode><VX_VEC_CONV_BFP:mode>2" 2504 [(set (match_operand:VX_VEC_CONV_BFP 0 "register_operand" "=v") 2505 (unsigned_float:VX_VEC_CONV_BFP (match_operand:VX_VEC_CONV_INT 1 "register_operand" "v")))] 2506 "TARGET_VX 2507 && GET_MODE_UNIT_SIZE (<VX_VEC_CONV_INT:MODE>mode) == GET_MODE_UNIT_SIZE (<VX_VEC_CONV_BFP:MODE>mode)" 2508 "vc<VX_VEC_CONV_BFP:xde>l<VX_VEC_CONV_INT:bhfgq>b\t%v0,%v1,0,0" 2509 [(set_attr "op_type" "VRR")]) 2510 2511; There is no instruction for loading an unsigned integer into an extended BFP 2512; operand in a VR, therefore load it into a FPR pair first. 2513(define_expand "floatuns<mode>tf2_vr" 2514 [(set (match_dup 2) 2515 (unsigned_float:FPRX2 (match_operand:GPR 1 "register_operand" ""))) 2516 (set (match_operand:TF 0 "register_operand" "") 2517 (subreg:TF (match_dup 2) 0))] 2518 "TARGET_VXE" 2519{ 2520 operands[2] = gen_reg_rtx (FPRX2mode); 2521}) 2522 2523(define_expand "floatuns<mode>tf2" 2524 [(match_operand:TF 0 "register_operand" "") 2525 (match_operand:GPR 1 "register_operand" "")] 2526 "HAVE_TF (floatuns<mode>tf2)" 2527 { EXPAND_TF (floatuns<mode>tf2, 2); }) 2528 2529; floating point to signed integer 2530 2531; op2: inexact exception not suppressed (IEEE 754 2008) 2532; op3: rounding mode 5 (round towards 0 C11 6.3.1.4) 2533; vcgdb, vcfeb 2534(define_insn "fix_trunc<VX_VEC_CONV_BFP:mode><VX_VEC_CONV_INT:mode>2" 2535 [(set (match_operand:VX_VEC_CONV_INT 0 "register_operand" "=v") 2536 (fix:VX_VEC_CONV_INT (match_operand:VX_VEC_CONV_BFP 1 "register_operand" "v")))] 2537 "TARGET_VX 2538 && GET_MODE_UNIT_SIZE (<VX_VEC_CONV_INT:MODE>mode) == GET_MODE_UNIT_SIZE (<VX_VEC_CONV_BFP:MODE>mode)" 2539 "vc<VX_VEC_CONV_INT:bhfgq><VX_VEC_CONV_BFP:xde>b\t%v0,%v1,0,5" 2540 [(set_attr "op_type" "VRR")]) 2541 2542; There is no instruction for rounding an extended BFP operand in a VR into 2543; a signed integer, therefore copy it into a FPR pair first. 2544(define_expand "fix_trunctf<mode>2_vr" 2545 [(set (subreg:DF (match_dup 2) 0) 2546 (subreg:DF (match_operand:TF 1 "register_operand" "") 0)) 2547 (set (subreg:DF (match_dup 2) 8) (subreg:DF (match_dup 1) 8)) 2548 (parallel [(set (match_operand:GPR 0 "register_operand" "") 2549 (fix:GPR (match_dup 2))) 2550 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND) 2551 (clobber (reg:CC CC_REGNUM))])] 2552 "TARGET_VXE" 2553{ 2554 operands[2] = gen_reg_rtx (FPRX2mode); 2555}) 2556 2557(define_expand "fix_trunctf<mode>2" 2558 [(match_operand:GPR 0 "register_operand" "") 2559 (match_operand:TF 1 "register_operand" "")] 2560 "HAVE_TF (fix_trunctf<mode>2)" 2561 { EXPAND_TF (fix_trunctf<mode>2, 2); }) 2562 2563; floating point to unsigned integer 2564 2565; op2: inexact exception not suppressed (IEEE 754 2008) 2566; op3: rounding mode 5 (round towards 0 C11 6.3.1.4) 2567; vclgdb, vclfeb 2568(define_insn "fixuns_trunc<VX_VEC_CONV_BFP:mode><VX_VEC_CONV_INT:mode>2" 2569 [(set (match_operand:VX_VEC_CONV_INT 0 "register_operand" "=v") 2570 (unsigned_fix:VX_VEC_CONV_INT (match_operand:VX_VEC_CONV_BFP 1 "register_operand" "v")))] 2571 "TARGET_VX 2572 && GET_MODE_UNIT_SIZE (<VX_VEC_CONV_INT:MODE>mode) == GET_MODE_UNIT_SIZE (<VX_VEC_CONV_BFP:MODE>mode)" 2573 "vcl<VX_VEC_CONV_INT:bhfgq><VX_VEC_CONV_BFP:xde>b\t%v0,%v1,0,5" 2574 [(set_attr "op_type" "VRR")]) 2575 2576; There is no instruction for rounding an extended BFP operand in a VR into 2577; an unsigned integer, therefore copy it into a FPR pair first. 2578(define_expand "fixuns_trunctf<mode>2_vr" 2579 [(set (subreg:DF (match_dup 2) 0) 2580 (subreg:DF (match_operand:TF 1 "register_operand" "") 0)) 2581 (set (subreg:DF (match_dup 2) 8) (subreg:DF (match_dup 1) 8)) 2582 (parallel [(set (match_operand:GPR 0 "register_operand" "") 2583 (unsigned_fix:GPR (match_dup 2))) 2584 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND) 2585 (clobber (reg:CC CC_REGNUM))])] 2586 "TARGET_VXE" 2587{ 2588 operands[2] = gen_reg_rtx (FPRX2mode); 2589}) 2590 2591(define_expand "fixuns_trunctf<mode>2" 2592 [(match_operand:GPR 0 "register_operand" "") 2593 (match_operand:TF 1 "register_operand" "")] 2594 "HAVE_TF (fixuns_trunctf<mode>2)" 2595 { EXPAND_TF (fixuns_trunctf<mode>2, 2); }) 2596 2597; load fp integer 2598 2599; vfisb, wfisb, vfidb, wfidb, wfixb; suppress inexact exceptions 2600(define_insn "<FPINT:fpint_name><VF_HW:mode>2<VF_HW:tf_vr>" 2601 [(set (match_operand:VF_HW 0 "register_operand" "=v") 2602 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")] 2603 FPINT))] 2604 "TARGET_VX" 2605 "<vw>fi<VF_HW:sdx>b\t%v0,%v1,4,<FPINT:fpint_roundingmode>" 2606 [(set_attr "op_type" "VRR")]) 2607 2608(define_expand "<FPINT:fpint_name>tf2" 2609 [(match_operand:TF 0 "register_operand" "") 2610 (match_operand:TF 1 "register_operand" "") 2611 ; recognize FPINT as an iterator 2612 (unspec:TF [(match_dup 1)] FPINT)] 2613 "HAVE_TF (<FPINT:fpint_name>tf2)" 2614 { EXPAND_TF (<FPINT:fpint_name>tf2, 2); }) 2615 2616; vfisb, wfisb, vfidb, wfidb, wfixb; raise inexact exceptions 2617(define_insn "rint<mode>2<tf_vr>" 2618 [(set (match_operand:VF_HW 0 "register_operand" "=v") 2619 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")] 2620 UNSPEC_FPINT_RINT))] 2621 "TARGET_VX" 2622 "<vw>fi<sdx>b\t%v0,%v1,0,0" 2623 [(set_attr "op_type" "VRR")]) 2624 2625(define_expand "rinttf2" 2626 [(match_operand:TF 0 "register_operand" "") 2627 (match_operand:TF 1 "register_operand" "")] 2628 "HAVE_TF (rinttf2)" 2629 { EXPAND_TF (rinttf2, 2); }) 2630 2631; load rounded 2632 2633; wflrx 2634(define_insn "*trunctfdf2_vr" 2635 [(set (match_operand:DF 0 "register_operand" "=f") 2636 (float_truncate:DF (match_operand:TF 1 "register_operand" "v"))) 2637 (unspec:DF [(match_operand 2 "const_int_operand" "")] 2638 UNSPEC_ROUND)] 2639 "TARGET_VXE" 2640 "wflrx\t%v0,%v1,0,%2" 2641 [(set_attr "op_type" "VRR")]) 2642 2643(define_expand "trunctfdf2_vr" 2644 [(parallel [ 2645 (set (match_operand:DF 0 "register_operand" "") 2646 (float_truncate:DF (match_operand:TF 1 "register_operand" ""))) 2647 (unspec:DF [(const_int BFP_RND_CURRENT)] UNSPEC_ROUND)])] 2648 "TARGET_VXE") 2649 2650(define_expand "trunctfdf2" 2651 [(match_operand:DF 0 "register_operand" "") 2652 (match_operand:TF 1 "register_operand" "")] 2653 "HAVE_TF (trunctfdf2)" 2654 { EXPAND_TF (trunctfdf2, 2); }) 2655 2656; wflrx + (ledbr|wledb) 2657(define_expand "trunctfsf2_vr" 2658 [(parallel [ 2659 (set (match_dup 2) 2660 (float_truncate:DF (match_operand:TF 1 "register_operand" ""))) 2661 (unspec:DF [(const_int BFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)]) 2662 (set (match_operand:SF 0 "register_operand" "") 2663 (float_truncate:SF (match_dup 2)))] 2664 "TARGET_VXE" 2665{ 2666 operands[2] = gen_reg_rtx(DFmode); 2667}) 2668 2669(define_expand "trunctfsf2" 2670 [(match_operand:SF 0 "register_operand" "") 2671 (match_operand:TF 1 "register_operand" "")] 2672 "HAVE_TF (trunctfsf2)" 2673 { EXPAND_TF (trunctfsf2, 2); }) 2674 2675(define_expand "trunctf<DFP_ALL:mode>2_vr" 2676 [(match_operand:DFP_ALL 0 "nonimmediate_operand" "") 2677 (match_operand:TF 1 "nonimmediate_operand" "")] 2678 "TARGET_HARD_DFP 2679 && GET_MODE_SIZE (TFmode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode) 2680 && TARGET_VXE" 2681{ 2682 rtx fprx2 = gen_reg_rtx (FPRX2mode); 2683 emit_insn (gen_tf_to_fprx2 (fprx2, operands[1])); 2684 emit_insn (gen_truncfprx2<DFP_ALL:mode>2 (operands[0], fprx2)); 2685 DONE; 2686}) 2687 2688(define_expand "trunctf<DFP_ALL:mode>2" 2689 [(match_operand:DFP_ALL 0 "nonimmediate_operand" "") 2690 (match_operand:TF 1 "nonimmediate_operand" "")] 2691 "HAVE_TF (trunctf<DFP_ALL:mode>2)" 2692 { EXPAND_TF (trunctf<DFP_ALL:mode>2, 2); }) 2693 2694(define_expand "trunctdtf2_vr" 2695 [(match_operand:TF 0 "nonimmediate_operand" "") 2696 (match_operand:TD 1 "nonimmediate_operand" "")] 2697 "TARGET_HARD_DFP && TARGET_VXE" 2698{ 2699 rtx fprx2 = gen_reg_rtx (FPRX2mode); 2700 emit_insn (gen_trunctdfprx22 (fprx2, operands[1])); 2701 emit_insn (gen_fprx2_to_tf (operands[0], fprx2)); 2702 DONE; 2703}) 2704 2705(define_expand "trunctdtf2" 2706 [(match_operand:TF 0 "nonimmediate_operand" "") 2707 (match_operand:TD 1 "nonimmediate_operand" "")] 2708 "HAVE_TF (trunctdtf2)" 2709 { EXPAND_TF (trunctdtf2, 2); }) 2710 2711; load lengthened 2712 2713(define_insn "extenddftf2_vr" 2714 [(set (match_operand:TF 0 "register_operand" "=v") 2715 (float_extend:TF (match_operand:DF 1 "register_operand" "f")))] 2716 "TARGET_VXE" 2717 "wflld\t%v0,%v1" 2718 [(set_attr "op_type" "VRR")]) 2719 2720(define_expand "extenddftf2" 2721 [(match_operand:TF 0 "register_operand" "") 2722 (match_operand:DF 1 "nonimmediate_operand" "")] 2723 "HAVE_TF (extenddftf2)" 2724 { EXPAND_TF (extenddftf2, 2); }) 2725 2726(define_expand "extendsftf2_vr" 2727 [(set (match_dup 2) 2728 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" ""))) 2729 (set (match_operand:TF 0 "register_operand" "") 2730 (float_extend:TF (match_dup 2)))] 2731 "TARGET_VXE" 2732{ 2733 operands[2] = gen_reg_rtx(DFmode); 2734}) 2735 2736(define_expand "extendsftf2" 2737 [(match_operand:TF 0 "register_operand" "") 2738 (match_operand:SF 1 "nonimmediate_operand" "")] 2739 "HAVE_TF (extendsftf2)" 2740 { EXPAND_TF (extendsftf2, 2); }) 2741 2742(define_expand "extend<DFP_ALL:mode>tf2_vr" 2743 [(match_operand:TF 0 "nonimmediate_operand" "") 2744 (match_operand:DFP_ALL 1 "nonimmediate_operand" "")] 2745 "TARGET_HARD_DFP 2746 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (TFmode) 2747 && TARGET_VXE" 2748{ 2749 rtx fprx2 = gen_reg_rtx (FPRX2mode); 2750 emit_insn (gen_extend<DFP_ALL:mode>fprx22 (fprx2, operands[1])); 2751 emit_insn (gen_fprx2_to_tf (operands[0], fprx2)); 2752 DONE; 2753}) 2754 2755(define_expand "extend<DFP_ALL:mode>tf2" 2756 [(match_operand:TF 0 "nonimmediate_operand" "") 2757 (match_operand:DFP_ALL 1 "nonimmediate_operand" "")] 2758 "HAVE_TF (extend<DFP_ALL:mode>tf2)" 2759 { EXPAND_TF (extend<DFP_ALL:mode>tf2, 2); }) 2760 2761(define_expand "extendtftd2_vr" 2762 [(match_operand:TD 0 "nonimmediate_operand" "") 2763 (match_operand:TF 1 "nonimmediate_operand" "")] 2764 "TARGET_HARD_DFP && TARGET_VXE" 2765{ 2766 rtx fprx2 = gen_reg_rtx (FPRX2mode); 2767 emit_insn (gen_tf_to_fprx2 (fprx2, operands[1])); 2768 emit_insn (gen_extendfprx2td2 (operands[0], fprx2)); 2769 DONE; 2770}) 2771 2772(define_expand "extendtftd2" 2773 [(match_operand:TD 0 "nonimmediate_operand" "") 2774 (match_operand:TF 1 "nonimmediate_operand" "")] 2775 "HAVE_TF (extendtftd2)" 2776 { EXPAND_TF (extendtftd2, 2); }) 2777 2778; test data class 2779 2780(define_expand "signbittf2_vr" 2781 [(parallel 2782 [(set (reg:CCRAW CC_REGNUM) 2783 (unspec:CCRAW [(match_operand:TF 1 "register_operand" "") 2784 (match_dup 2)] 2785 UNSPEC_VEC_VFTCICC)) 2786 (clobber (scratch:V1TI))]) 2787 (set (match_operand:SI 0 "register_operand" "") 2788 (const_int 0)) 2789 (set (match_dup 0) 2790 (if_then_else:SI (eq (reg:CCRAW CC_REGNUM) (const_int 8)) 2791 (const_int 1) 2792 (match_dup 0)))] 2793 "TARGET_VXE" 2794{ 2795 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET); 2796}) 2797 2798(define_expand "signbittf2" 2799 [(match_operand:SI 0 "register_operand" "") 2800 (match_operand:TF 1 "register_operand" "")] 2801 "HAVE_TF (signbittf2)" 2802 { EXPAND_TF (signbittf2, 2); }) 2803 2804(define_expand "isinftf2_vr" 2805 [(parallel 2806 [(set (reg:CCRAW CC_REGNUM) 2807 (unspec:CCRAW [(match_operand:TF 1 "register_operand" "") 2808 (match_dup 2)] 2809 UNSPEC_VEC_VFTCICC)) 2810 (clobber (scratch:V1TI))]) 2811 (set (match_operand:SI 0 "register_operand" "") 2812 (const_int 0)) 2813 (set (match_dup 0) 2814 (if_then_else:SI (eq (reg:CCRAW CC_REGNUM) (const_int 8)) 2815 (const_int 1) 2816 (match_dup 0)))] 2817 "TARGET_VXE" 2818{ 2819 operands[2] = GEN_INT (S390_TDC_INFINITY); 2820}) 2821 2822(define_expand "isinftf2" 2823 [(match_operand:SI 0 "register_operand" "") 2824 (match_operand:TF 1 "register_operand" "")] 2825 "HAVE_TF (isinftf2)" 2826 { EXPAND_TF (isinftf2, 2); }) 2827 2828; 2829; Vector byte swap patterns 2830; 2831 2832; FIXME: The bswap rtl standard name currently does not appear to be 2833; used for vector modes. 2834(define_expand "bswap<mode>" 2835 [(parallel 2836 [(set (match_operand:VT_HW_HSDT 0 "nonimmediate_operand" "") 2837 (bswap:VT_HW_HSDT (match_operand:VT_HW_HSDT 1 "nonimmediate_operand" ""))) 2838 (use (match_dup 2))])] 2839 "TARGET_VX" 2840{ 2841 static char p[4][16] = 2842 { { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 }, /* H */ 2843 { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 }, /* S */ 2844 { 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 }, /* D */ 2845 { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 } }; /* T */ 2846 char *perm; 2847 rtx perm_rtx[16]; 2848 2849 switch (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode))) 2850 { 2851 case 2: perm = p[0]; break; 2852 case 4: perm = p[1]; break; 2853 case 8: perm = p[2]; break; 2854 case 16: perm = p[3]; break; 2855 default: gcc_unreachable (); 2856 } 2857 for (int i = 0; i < 16; i++) 2858 perm_rtx[i] = GEN_INT (perm[i]); 2859 2860 operands[2] = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm_rtx)); 2861 2862 /* Without vxe2 we do not have byte swap instructions dealing 2863 directly with memory operands. So instead of waiting until 2864 reload to fix that up switch over to vector permute right 2865 now. */ 2866 if (!TARGET_VXE2) 2867 { 2868 rtx in = force_reg (V16QImode, simplify_gen_subreg (V16QImode, operands[1], <MODE>mode, 0)); 2869 rtx permute = force_reg (V16QImode, force_const_mem (V16QImode, operands[2])); 2870 rtx out = gen_reg_rtx (V16QImode); 2871 2872 emit_insn (gen_vec_permv16qi (out, in, in, permute)); 2873 emit_move_insn (operands[0], simplify_gen_subreg (<MODE>mode, out, V16QImode, 0)); 2874 DONE; 2875 } 2876}) 2877 2878; Switching late to the reg-reg variant requires the vector permute 2879; pattern to be pushed into literal pool and allocating a vector 2880; register to load it into. We rely on both being provided by LRA 2881; when fixing up the v constraint for operand 2. 2882 2883; permute_pattern_operand: general_operand would reject the permute 2884; pattern constants since these are not accepted by 2885; s390_legimitate_constant_p 2886 2887; ^R: Prevent these alternatives from being chosen if it would require 2888; pushing the operand into memory first 2889 2890; vlbrh, vlbrf, vlbrg, vlbrq, vstbrh, vstbrf, vstbrg, vstbrq 2891(define_insn_and_split "*bswap<mode>" 2892 [(set (match_operand:VT_HW_HSDT 0 "nonimmediate_operand" "=v, v,^R") 2893 (bswap:VT_HW_HSDT (match_operand:VT_HW_HSDT 1 "nonimmediate_operand" "v,^R, v"))) 2894 (use (match_operand:V16QI 2 "permute_pattern_operand" "v, X, X"))] 2895 "TARGET_VXE2" 2896 "@ 2897 # 2898 vlbr<bhfgq>\t%v0,%v1 2899 vstbr<bhfgq>\t%v1,%v0" 2900 "&& reload_completed 2901 && !memory_operand (operands[0], <MODE>mode) 2902 && !memory_operand (operands[1], <MODE>mode)" 2903 [(set (match_dup 0) 2904 (subreg:VT_HW_HSDT 2905 (unspec:V16QI [(subreg:V16QI (match_dup 1) 0) 2906 (subreg:V16QI (match_dup 1) 0) 2907 (match_dup 2)] 2908 UNSPEC_VEC_PERM) 0))] 2909 "" 2910 [(set_attr "op_type" "*,VRX,VRX")]) 2911 2912; reduc_smin 2913; reduc_smax 2914; reduc_umin 2915; reduc_umax 2916 2917; vec_pack_sfix_trunc: convert + pack ? 2918; vec_pack_ufix_trunc 2919; vec_unpacks_float_hi 2920; vec_unpacks_float_lo 2921; vec_unpacku_float_hi 2922; vec_unpacku_float_lo 2923