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