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