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