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