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