Home | History | Annotate | Line # | Download | only in s390
vector.md revision 1.1.1.1.2.1
      1 ;;- Instruction patterns for the System z vector facility
      2 ;;  Copyright (C) 2015-2016 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 vector modes directly supported by the hardware having full vector reg size
     30 ; V_HW2 is duplicate of V_HW for having two iterators expanding
     31 ; independently e.g. vcond
     32 (define_mode_iterator V_HW  [V16QI V8HI V4SI V2DI V2DF])
     33 (define_mode_iterator V_HW2 [V16QI V8HI V4SI V2DI V2DF])
     34 ; Including TI for instructions that support it (va, vn, ...)
     35 (define_mode_iterator VT_HW [V16QI V8HI V4SI V2DI V2DF V1TI TI])
     36 
     37 ; All full size integer vector modes supported in a vector register + TImode
     38 (define_mode_iterator VIT_HW    [V16QI V8HI V4SI V2DI V1TI TI])
     39 (define_mode_iterator VI_HW     [V16QI V8HI V4SI V2DI])
     40 (define_mode_iterator VI_HW_QHS [V16QI V8HI V4SI])
     41 (define_mode_iterator VI_HW_HS  [V8HI V4SI])
     42 (define_mode_iterator VI_HW_QH  [V16QI V8HI])
     43 
     44 ; All integer vector modes supported in a vector register + TImode
     45 (define_mode_iterator VIT [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1TI TI])
     46 (define_mode_iterator VI  [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI])
     47 (define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI])
     48 
     49 (define_mode_iterator V_8   [V1QI])
     50 (define_mode_iterator V_16  [V2QI  V1HI])
     51 (define_mode_iterator V_32  [V4QI  V2HI V1SI V1SF])
     52 (define_mode_iterator V_64  [V8QI  V4HI V2SI V2SF V1DI V1DF])
     53 (define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF])
     54 
     55 ; A blank for vector modes and a * for TImode.  This is used to hide
     56 ; the TImode expander name in case it is defined already.  See addti3
     57 ; for an example.
     58 (define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
     59 		       (V1HI "") (V2HI "") (V4HI "") (V8HI "")
     60 		       (V1SI "") (V2SI "") (V4SI "")
     61 		       (V1DI "") (V2DI "")
     62 		       (V1TI "*") (TI "*")])
     63 
     64 ; The element type of the vector.
     65 (define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
     66 			  (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
     67 			  (V1SI "SI") (V2SI "SI") (V4SI "SI")
     68 			  (V1DI "DI") (V2DI "DI")
     69 			  (V1TI "TI")
     70 			  (V1SF "SF") (V2SF "SF") (V4SF "SF")
     71 			  (V1DF "DF") (V2DF "DF")
     72 			  (V1TF "TF")])
     73 
     74 ; The instruction suffix
     75 (define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b")
     76 			(V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h")
     77 			(V1SI "f") (V2SI "f") (V4SI "f")
     78 			(V1DI "g") (V2DI "g")
     79 			(V1TI "q") (TI "q")
     80 			(V1SF "f") (V2SF "f") (V4SF "f")
     81 			(V1DF "g") (V2DF "g")
     82 			(V1TF "q")])
     83 
     84 ; This is for vmalhw. It gets an 'w' attached to avoid confusion with
     85 ; multiply and add logical high vmalh.
     86 (define_mode_attr w [(V1QI "")  (V2QI "")  (V4QI "")  (V8QI "") (V16QI "")
     87 		     (V1HI "w") (V2HI "w") (V4HI "w") (V8HI "w")
     88 		     (V1SI "")  (V2SI "")  (V4SI "")
     89 		     (V1DI "")  (V2DI "")])
     90 
     91 ; Resulting mode of a vector comparison.  For floating point modes an
     92 ; integer vector mode with the same element size is picked.
     93 (define_mode_attr tointvec [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI")
     94 			    (V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI")
     95 			    (V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI")
     96 			    (V1DI "V1DI") (V2DI "V2DI")
     97 			    (V1TI "V1TI")
     98 			    (V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI")
     99 			    (V1DF "V1DI") (V2DF "V2DI")
    100 			    (V1TF "V1TI")])
    101 
    102 ; Vector with doubled element size.
    103 (define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI")
    104 			      (V1HI "V1SI") (V2HI "V1SI") (V4HI "V2SI") (V8HI "V4SI")
    105 			      (V1SI "V1DI") (V2SI "V1DI") (V4SI "V2DI")
    106 			      (V1DI "V1TI") (V2DI "V1TI")
    107 			      (V1SF "V1DF") (V2SF "V1DF") (V4SF "V2DF")])
    108 
    109 ; Vector with half the element size.
    110 (define_mode_attr vec_half [(V1HI "V2QI") (V2HI "V4QI") (V4HI "V8QI") (V8HI "V16QI")
    111 			    (V1SI "V2HI") (V2SI "V4HI") (V4SI "V8HI")
    112 			    (V1DI "V2SI") (V2DI "V4SI")
    113 			    (V1TI "V2DI")
    114 			    (V1DF "V2SF") (V2DF "V4SF")
    115 			    (V1TF "V1DF")])
    116 
    117 ; The comparisons not setting CC iterate over the rtx code.
    118 (define_code_iterator VFCMP_HW_OP [eq gt ge])
    119 (define_code_attr asm_fcmp_op [(eq "e") (gt "h") (ge "he")])
    120 
    121 
    122 
    123 ; Comparison operators on int and fp compares which are directly
    124 ; supported by the HW.
    125 (define_code_iterator VICMP_HW_OP [eq gt gtu])
    126 ; For int insn_cmp_op can be used in the insn name as well as in the asm output.
    127 (define_code_attr insn_cmp_op [(eq "eq") (gt "h") (gtu "hl") (ge "he")])
    128 
    129 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4)
    130 (define_constants
    131   [(VSTRING_FLAG_IN         8)   ; invert result
    132    (VSTRING_FLAG_RT         4)   ; result type
    133    (VSTRING_FLAG_ZS         2)   ; zero search
    134    (VSTRING_FLAG_CS         1)]) ; condition code set
    135 
    136 (include "vx-builtins.md")
    137 
    138 ; Full HW vector size moves
    139 (define_insn "mov<mode>"
    140   [(set (match_operand:V_128 0 "nonimmediate_operand" "=v, v,QR,  v,  v,  v,  v,  v,v,d")
    141 	(match_operand:V_128 1 "general_operand"      " v,QR, v,j00,jm1,jyy,jxx,jKK,d,v"))]
    142   "TARGET_VX"
    143   "@
    144    vlr\t%v0,%v1
    145    vl\t%v0,%1
    146    vst\t%v1,%0
    147    vzero\t%v0
    148    vone\t%v0
    149    vgbm\t%v0,%t1
    150    vgm<bhfgq>\t%v0,%s1,%e1
    151    vrepi<bhfgq>\t%v0,%h1
    152    vlvgp\t%v0,%1,%N1
    153    #"
    154   [(set_attr "op_type" "VRR,VRX,VRX,VRI,VRI,VRI,VRI,VRI,VRR,*")])
    155 
    156 (define_split
    157   [(set (match_operand:V_128 0 "register_operand" "")
    158 	(match_operand:V_128 1 "register_operand" ""))]
    159   "TARGET_VX && GENERAL_REG_P (operands[0]) && VECTOR_REG_P (operands[1])"
    160   [(set (match_dup 2)
    161 	(unspec:DI [(subreg:V2DI (match_dup 1) 0)
    162 		    (const_int 0)] UNSPEC_VEC_EXTRACT))
    163    (set (match_dup 3)
    164 	(unspec:DI [(subreg:V2DI (match_dup 1) 0)
    165 		    (const_int 1)] UNSPEC_VEC_EXTRACT))]
    166 {
    167   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
    168   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
    169 })
    170 
    171 ; Moves for smaller vector modes.
    172 
    173 ; In these patterns only the vlr, vone, and vzero instructions write
    174 ; VR bytes outside the mode.  This should be ok since we disallow
    175 ; formerly bigger modes being accessed with smaller modes via
    176 ; subreg. Note: The vone, vzero instructions could easily be replaced
    177 ; with vlei which would only access the bytes belonging to the mode.
    178 ; However, this would probably be slower.
    179 
    180 (define_insn "mov<mode>"
    181   [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d, v,QR,  v,  v,  v,  v,d,  Q,  S,  Q,  S,  d,  d,d,d,d,R,T")
    182         (match_operand:V_8 1 "general_operand"      " v,d,v,QR, v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
    183   ""
    184   "@
    185    vlr\t%v0,%v1
    186    vlvgb\t%v0,%1,0
    187    vlgvb\t%0,%v1,0
    188    vleb\t%v0,%1,0
    189    vsteb\t%v1,%0,0
    190    vzero\t%v0
    191    vone\t%v0
    192    vgbm\t%v0,%t1
    193    vgm\t%v0,%s1,%e1
    194    lr\t%0,%1
    195    mvi\t%0,0
    196    mviy\t%0,0
    197    mvi\t%0,-1
    198    mviy\t%0,-1
    199    lhi\t%0,0
    200    lhi\t%0,-1
    201    lh\t%0,%1
    202    lhy\t%0,%1
    203    lhrl\t%0,%1
    204    stc\t%1,%0
    205    stcy\t%1,%0"
    206   [(set_attr "op_type"      "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RX,RXY,RIL,RX,RXY")])
    207 
    208 (define_insn "mov<mode>"
    209   [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d, v,QR,  v,  v,  v,  v,d,  Q,  Q,  d,  d,d,d,d,R,T,b")
    210         (match_operand:V_16 1 "general_operand"      " v,d,v,QR, v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
    211   ""
    212   "@
    213    vlr\t%v0,%v1
    214    vlvgh\t%v0,%1,0
    215    vlgvh\t%0,%v1,0
    216    vleh\t%v0,%1,0
    217    vsteh\t%v1,%0,0
    218    vzero\t%v0
    219    vone\t%v0
    220    vgbm\t%v0,%t1
    221    vgm\t%v0,%s1,%e1
    222    lr\t%0,%1
    223    mvhhi\t%0,0
    224    mvhhi\t%0,-1
    225    lhi\t%0,0
    226    lhi\t%0,-1
    227    lh\t%0,%1
    228    lhy\t%0,%1
    229    lhrl\t%0,%1
    230    sth\t%1,%0
    231    sthy\t%1,%0
    232    sthrl\t%1,%0"
    233   [(set_attr "op_type"      "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
    234 
    235 (define_insn "mov<mode>"
    236   [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d, v,QR,  f,  v,  v,  v,  v,  Q,  Q,  d,  d,d,d,d,d,R,T,b")
    237 	(match_operand:V_32 1 "general_operand"      " f,R,T,f,f,v,d,v,QR, v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
    238   "TARGET_VX"
    239   "@
    240    lder\t%v0,%v1
    241    lde\t%0,%1
    242    ley\t%0,%1
    243    ste\t%1,%0
    244    stey\t%1,%0
    245    vlr\t%v0,%v1
    246    vlvgf\t%v0,%1,0
    247    vlgvf\t%0,%v1,0
    248    vlef\t%v0,%1,0
    249    vstef\t%1,%0,0
    250    lzer\t%v0
    251    vzero\t%v0
    252    vone\t%v0
    253    vgbm\t%v0,%t1
    254    vgm\t%v0,%s1,%e1
    255    mvhi\t%0,0
    256    mvhi\t%0,-1
    257    lhi\t%0,0
    258    lhi\t%0,-1
    259    lrl\t%0,%1
    260    lr\t%0,%1
    261    l\t%0,%1
    262    ly\t%0,%1
    263    st\t%1,%0
    264    sty\t%1,%0
    265    strl\t%1,%0"
    266   [(set_attr "op_type" "RRE,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
    267                         RIL,RR,RX,RXY,RX,RXY,RIL")])
    268 
    269 (define_insn "mov<mode>"
    270   [(set (match_operand:V_64 0 "nonimmediate_operand"
    271          "=f,f,f,R,T,v,v,d, v,QR,  f,  v,  v,  v,  v,  Q,  Q,  d,  d,f,d,d,d, d,RT,b")
    272         (match_operand:V_64 1 "general_operand"
    273          " f,R,T,f,f,v,d,v,QR, v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,RT, d,d"))]
    274   "TARGET_ZARCH"
    275   "@
    276    ldr\t%0,%1
    277    ld\t%0,%1
    278    ldy\t%0,%1
    279    std\t%1,%0
    280    stdy\t%1,%0
    281    vlr\t%v0,%v1
    282    vlvgg\t%v0,%1,0
    283    vlgvg\t%0,%v1,0
    284    vleg\t%v0,%1,0
    285    vsteg\t%v1,%0,0
    286    lzdr\t%0
    287    vzero\t%v0
    288    vone\t%v0
    289    vgbm\t%v0,%t1
    290    vgm\t%v0,%s1,%e1
    291    mvghi\t%0,0
    292    mvghi\t%0,-1
    293    lghi\t%0,0
    294    lghi\t%0,-1
    295    ldgr\t%0,%1
    296    lgdr\t%0,%1
    297    lgrl\t%0,%1
    298    lgr\t%0,%1
    299    lg\t%0,%1
    300    stg\t%1,%0
    301    stgrl\t%1,%0"
    302   [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,
    303                         SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")])
    304 
    305 
    306 ; vec_load_lanes?
    307 
    308 ; vec_store_lanes?
    309 
    310 ; vec_set is supposed to *modify* an existing vector so operand 0 is
    311 ; duplicated as input operand.
    312 (define_expand "vec_set<mode>"
    313   [(set (match_operand:V                    0 "register_operand"  "")
    314 	(unspec:V [(match_operand:<non_vec> 1 "general_operand"   "")
    315 		   (match_operand:SI        2 "nonmemory_operand" "")
    316 		   (match_dup 0)]
    317 		   UNSPEC_VEC_SET))]
    318   "TARGET_VX")
    319 
    320 ; FIXME: Support also vector mode operands for 1
    321 ; FIXME: A target memory operand seems to be useful otherwise we end
    322 ; up with vl vlvgg vst.  Shouldn't the middle-end be able to handle
    323 ; that itself?
    324 (define_insn "*vec_set<mode>"
    325   [(set (match_operand:V                    0 "register_operand"  "=v, v,v")
    326 	(unspec:V [(match_operand:<non_vec> 1 "general_operand"    "d,QR,K")
    327 		   (match_operand:SI        2 "nonmemory_operand" "an, I,I")
    328 		   (match_operand:V         3 "register_operand"   "0, 0,0")]
    329 		  UNSPEC_VEC_SET))]
    330   "TARGET_VX
    331    && (!CONST_INT_P (operands[2])
    332        || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
    333   "@
    334    vlvg<bhfgq>\t%v0,%1,%Y2
    335    vle<bhfgq>\t%v0,%1,%2
    336    vlei<bhfgq>\t%v0,%1,%2"
    337   [(set_attr "op_type" "VRS,VRX,VRI")])
    338 
    339 (define_insn "*vec_set<mode>_plus"
    340   [(set (match_operand:V                      0 "register_operand" "=v")
    341 	(unspec:V [(match_operand:<non_vec>   1 "general_operand"   "d")
    342 		   (plus:SI (match_operand:SI 2 "register_operand"  "a")
    343 			    (match_operand:SI 4 "const_int_operand" "n"))
    344 		   (match_operand:V           3 "register_operand"  "0")]
    345 		  UNSPEC_VEC_SET))]
    346   "TARGET_VX"
    347   "vlvg<bhfgq>\t%v0,%1,%Y4(%2)"
    348   [(set_attr "op_type" "VRS")])
    349 
    350 
    351 ; FIXME: Support also vector mode operands for 0
    352 ; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :(
    353 ; This is used via RTL standard name as well as for expanding the builtin
    354 (define_expand "vec_extract<mode>"
    355   [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "")
    356 	(unspec:<non_vec> [(match_operand:V  1 "register_operand" "")
    357 			   (match_operand:SI 2 "nonmemory_operand" "")]
    358 			  UNSPEC_VEC_EXTRACT))]
    359   "TARGET_VX")
    360 
    361 (define_insn "*vec_extract<mode>"
    362   [(set (match_operand:<non_vec> 0 "nonimmediate_operand"          "=d,QR")
    363 	(unspec:<non_vec> [(match_operand:V  1 "register_operand"   "v, v")
    364 			   (match_operand:SI 2 "nonmemory_operand" "an, I")]
    365 			  UNSPEC_VEC_EXTRACT))]
    366   "TARGET_VX
    367    && (!CONST_INT_P (operands[2])
    368        || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
    369   "@
    370    vlgv<bhfgq>\t%0,%v1,%Y2
    371    vste<bhfgq>\t%v1,%0,%2"
    372   [(set_attr "op_type" "VRS,VRX")])
    373 
    374 (define_insn "*vec_extract<mode>_plus"
    375   [(set (match_operand:<non_vec>                      0 "nonimmediate_operand" "=d")
    376 	(unspec:<non_vec> [(match_operand:V           1 "register_operand"      "v")
    377 			   (plus:SI (match_operand:SI 2 "nonmemory_operand"     "a")
    378 				    (match_operand:SI 3 "const_int_operand"     "n"))]
    379 			   UNSPEC_VEC_EXTRACT))]
    380   "TARGET_VX"
    381   "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
    382   [(set_attr "op_type" "VRS")])
    383 
    384 (define_expand "vec_init<V_HW:mode>"
    385   [(match_operand:V_HW 0 "register_operand" "")
    386    (match_operand:V_HW 1 "nonmemory_operand" "")]
    387   "TARGET_VX"
    388 {
    389   s390_expand_vec_init (operands[0], operands[1]);
    390   DONE;
    391 })
    392 
    393 ; Replicate from vector element
    394 (define_insn "*vec_splat<mode>"
    395   [(set (match_operand:V_HW   0 "register_operand" "=v")
    396 	(vec_duplicate:V_HW
    397 	 (vec_select:<non_vec>
    398 	  (match_operand:V_HW 1 "register_operand"  "v")
    399 	  (parallel
    400 	   [(match_operand:QI 2 "const_mask_operand" "C")]))))]
    401   "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW:MODE>mode)"
    402   "vrep<bhfgq>\t%v0,%v1,%2"
    403   [(set_attr "op_type" "VRI")])
    404 
    405 (define_insn "*vec_splats<mode>"
    406   [(set (match_operand:V_HW                          0 "register_operand" "=v,v,v,v")
    407 	(vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand"  "QR,K,v,d")))]
    408   "TARGET_VX"
    409   "@
    410    vlrep<bhfgq>\t%v0,%1
    411    vrepi<bhfgq>\t%v0,%h1
    412    vrep<bhfgq>\t%v0,%v1,0
    413    #"
    414   [(set_attr "op_type" "VRX,VRI,VRI,*")])
    415 
    416 ; vec_splats is supposed to replicate op1 into all elements of op0
    417 ; This splitter first sets the rightmost element of op0 to op1 and
    418 ; then does a vec_splat to replicate that element into all other
    419 ; elements.
    420 (define_split
    421   [(set (match_operand:V_HW                          0 "register_operand" "")
    422 	(vec_duplicate:V_HW (match_operand:<non_vec> 1 "register_operand" "")))]
    423   "TARGET_VX && GENERAL_REG_P (operands[1])"
    424   [(set (match_dup 0)
    425 	(unspec:V_HW [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET))
    426    (set (match_dup 0)
    427 	(vec_duplicate:V_HW
    428 	 (vec_select:<non_vec>
    429 	  (match_dup 0) (parallel [(match_dup 2)]))))]
    430 {
    431   operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1);
    432 })
    433 
    434 (define_expand "vcond<V_HW:mode><V_HW2:mode>"
    435   [(set (match_operand:V_HW 0 "register_operand" "")
    436 	(if_then_else:V_HW
    437 	 (match_operator 3 "comparison_operator"
    438 			 [(match_operand:V_HW2 4 "register_operand" "")
    439 			  (match_operand:V_HW2 5 "nonmemory_operand" "")])
    440 	 (match_operand:V_HW 1 "nonmemory_operand" "")
    441 	 (match_operand:V_HW 2 "nonmemory_operand" "")))]
    442   "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
    443 {
    444   s390_expand_vcond (operands[0], operands[1], operands[2],
    445 		     GET_CODE (operands[3]), operands[4], operands[5]);
    446   DONE;
    447 })
    448 
    449 (define_expand "vcondu<V_HW:mode><V_HW2:mode>"
    450   [(set (match_operand:V_HW 0 "register_operand" "")
    451 	(if_then_else:V_HW
    452 	 (match_operator 3 "comparison_operator"
    453 			 [(match_operand:V_HW2 4 "register_operand" "")
    454 			  (match_operand:V_HW2 5 "nonmemory_operand" "")])
    455 	 (match_operand:V_HW 1 "nonmemory_operand" "")
    456 	 (match_operand:V_HW 2 "nonmemory_operand" "")))]
    457   "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
    458 {
    459   s390_expand_vcond (operands[0], operands[1], operands[2],
    460 		     GET_CODE (operands[3]), operands[4], operands[5]);
    461   DONE;
    462 })
    463 
    464 ; We only have HW support for byte vectors.  The middle-end is
    465 ; supposed to lower the mode if required.
    466 (define_insn "vec_permv16qi"
    467   [(set (match_operand:V16QI 0 "register_operand"               "=v")
    468 	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
    469 		       (match_operand:V16QI 2 "register_operand" "v")
    470 		       (match_operand:V16QI 3 "register_operand" "v")]
    471 		      UNSPEC_VEC_PERM))]
    472   "TARGET_VX"
    473   "vperm\t%v0,%v1,%v2,%v3"
    474   [(set_attr "op_type" "VRR")])
    475 
    476 ; vec_perm_const for V2DI using vpdi?
    477 
    478 ;;
    479 ;; Vector integer arithmetic instructions
    480 ;;
    481 
    482 ; vab, vah, vaf, vag, vaq
    483 
    484 ; We use nonimmediate_operand instead of register_operand since it is
    485 ; better to have the reloads into VRs instead of splitting the
    486 ; operation into two DImode ADDs.
    487 (define_insn "<ti*>add<mode>3"
    488   [(set (match_operand:VIT           0 "nonimmediate_operand" "=v")
    489 	(plus:VIT (match_operand:VIT 1 "nonimmediate_operand" "%v")
    490 		  (match_operand:VIT 2 "general_operand"       "v")))]
    491   "TARGET_VX"
    492   "va<bhfgq>\t%v0,%v1,%v2"
    493   [(set_attr "op_type" "VRR")])
    494 
    495 ; vsb, vsh, vsf, vsg, vsq
    496 (define_insn "<ti*>sub<mode>3"
    497   [(set (match_operand:VIT            0 "nonimmediate_operand" "=v")
    498 	(minus:VIT (match_operand:VIT 1 "nonimmediate_operand"  "v")
    499 		   (match_operand:VIT 2 "general_operand"  "v")))]
    500   "TARGET_VX"
    501   "vs<bhfgq>\t%v0,%v1,%v2"
    502   [(set_attr "op_type" "VRR")])
    503 
    504 ; vmlb, vmlhw, vmlf
    505 (define_insn "mul<mode>3"
    506   [(set (match_operand:VI_QHS              0 "register_operand" "=v")
    507 	(mult:VI_QHS (match_operand:VI_QHS 1 "register_operand" "%v")
    508 		     (match_operand:VI_QHS 2 "register_operand"  "v")))]
    509   "TARGET_VX"
    510   "vml<bhfgq><w>\t%v0,%v1,%v2"
    511   [(set_attr "op_type" "VRR")])
    512 
    513 ; vlcb, vlch, vlcf, vlcg
    514 (define_insn "neg<mode>2"
    515   [(set (match_operand:VI         0 "register_operand" "=v")
    516 	(neg:VI (match_operand:VI 1 "register_operand"  "v")))]
    517   "TARGET_VX"
    518   "vlc<bhfgq>\t%v0,%v1"
    519   [(set_attr "op_type" "VRR")])
    520 
    521 ; vlpb, vlph, vlpf, vlpg
    522 (define_insn "abs<mode>2"
    523   [(set (match_operand:VI         0 "register_operand" "=v")
    524 	(abs:VI (match_operand:VI 1 "register_operand"  "v")))]
    525   "TARGET_VX"
    526   "vlp<bhfgq>\t%v0,%v1"
    527   [(set_attr "op_type" "VRR")])
    528 
    529 
    530 ; Vector sum across
    531 
    532 ; Sum across DImode parts of the 1st operand and add the rightmost
    533 ; element of 2nd operand
    534 ; vsumgh, vsumgf
    535 (define_insn "*vec_sum2<mode>"
    536   [(set (match_operand:V2DI 0 "register_operand" "=v")
    537 	(unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "v")
    538 		      (match_operand:VI_HW_HS 2 "register_operand" "v")]
    539 		     UNSPEC_VEC_VSUMG))]
    540   "TARGET_VX"
    541   "vsumg<bhfgq>\t%v0,%v1,%v2"
    542   [(set_attr "op_type" "VRR")])
    543 
    544 ; vsumb, vsumh
    545 (define_insn "*vec_sum4<mode>"
    546   [(set (match_operand:V4SI 0 "register_operand" "=v")
    547 	(unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "v")
    548 		      (match_operand:VI_HW_QH 2 "register_operand" "v")]
    549 		     UNSPEC_VEC_VSUM))]
    550   "TARGET_VX"
    551   "vsum<bhfgq>\t%v0,%v1,%v2"
    552   [(set_attr "op_type" "VRR")])
    553 
    554 ;;
    555 ;; Vector bit instructions (int + fp)
    556 ;;
    557 
    558 ; Vector and
    559 
    560 (define_insn "and<mode>3"
    561   [(set (match_operand:VT         0 "register_operand" "=v")
    562 	(and:VT (match_operand:VT 1 "register_operand" "%v")
    563 		(match_operand:VT 2 "register_operand"  "v")))]
    564   "TARGET_VX"
    565   "vn\t%v0,%v1,%v2"
    566   [(set_attr "op_type" "VRR")])
    567 
    568 
    569 ; Vector or
    570 
    571 (define_insn "ior<mode>3"
    572   [(set (match_operand:VT         0 "register_operand" "=v")
    573 	(ior:VT (match_operand:VT 1 "register_operand" "%v")
    574 		(match_operand:VT 2 "register_operand"  "v")))]
    575   "TARGET_VX"
    576   "vo\t%v0,%v1,%v2"
    577   [(set_attr "op_type" "VRR")])
    578 
    579 
    580 ; Vector xor
    581 
    582 (define_insn "xor<mode>3"
    583   [(set (match_operand:VT         0 "register_operand" "=v")
    584 	(xor:VT (match_operand:VT 1 "register_operand" "%v")
    585 		(match_operand:VT 2 "register_operand"  "v")))]
    586   "TARGET_VX"
    587   "vx\t%v0,%v1,%v2"
    588   [(set_attr "op_type" "VRR")])
    589 
    590 
    591 ; Bitwise inversion of a vector - used for vec_cmpne
    592 (define_insn "*not<mode>"
    593   [(set (match_operand:VT         0 "register_operand" "=v")
    594 	(not:VT (match_operand:VT 1 "register_operand"  "v")))]
    595   "TARGET_VX"
    596   "vnot\t%v0,%v1"
    597   [(set_attr "op_type" "VRR")])
    598 
    599 ; Vector population count
    600 
    601 (define_insn "popcountv16qi2"
    602   [(set (match_operand:V16QI                0 "register_operand" "=v")
    603 	(unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "v")]
    604 		      UNSPEC_POPCNT))]
    605   "TARGET_VX"
    606   "vpopct\t%v0,%v1,0"
    607   [(set_attr "op_type" "VRR")])
    608 
    609 ; vpopct only counts bits in byte elements.  Bigger element sizes need
    610 ; to be emulated.  Word and doubleword elements can use the sum across
    611 ; instructions.  For halfword sized elements we do a shift of a copy
    612 ; of the result, add it to the result and extend it to halfword
    613 ; element size (unpack).
    614 
    615 (define_expand "popcountv8hi2"
    616   [(set (match_dup 2)
    617 	(unspec:V16QI [(subreg:V16QI (match_operand:V8HI 1 "register_operand" "v") 0)]
    618 		      UNSPEC_POPCNT))
    619    ; Make a copy of the result
    620    (set (match_dup 3) (match_dup 2))
    621    ; Generate the shift count operand in a VR (8->byte 7)
    622    (set (match_dup 4) (match_dup 5))
    623    (set (match_dup 4) (unspec:V16QI [(const_int 8)
    624 				     (const_int 7)
    625 				     (match_dup 4)] UNSPEC_VEC_SET))
    626    ; Vector shift right logical by one byte
    627    (set (match_dup 3)
    628 	(unspec:V16QI [(match_dup 3) (match_dup 4)] UNSPEC_VEC_SRLB))
    629    ; Add the shifted and the original result
    630    (set (match_dup 2)
    631 	(plus:V16QI (match_dup 2) (match_dup 3)))
    632    ; Generate mask for the odd numbered byte elements
    633    (set (match_dup 3)
    634 	(const_vector:V16QI [(const_int 0) (const_int 255)
    635 			     (const_int 0) (const_int 255)
    636 			     (const_int 0) (const_int 255)
    637 			     (const_int 0) (const_int 255)
    638 			     (const_int 0) (const_int 255)
    639 			     (const_int 0) (const_int 255)
    640 			     (const_int 0) (const_int 255)
    641 			     (const_int 0) (const_int 255)]))
    642    ; Zero out the even indexed bytes
    643    (set (match_operand:V8HI 0 "register_operand" "=v")
    644 	(and:V8HI (subreg:V8HI (match_dup 2) 0)
    645 		  (subreg:V8HI (match_dup 3) 0)))
    646 ]
    647   "TARGET_VX"
    648 {
    649   operands[2] = gen_reg_rtx (V16QImode);
    650   operands[3] = gen_reg_rtx (V16QImode);
    651   operands[4] = gen_reg_rtx (V16QImode);
    652   operands[5] = CONST0_RTX (V16QImode);
    653 })
    654 
    655 (define_expand "popcountv4si2"
    656   [(set (match_dup 2)
    657 	(unspec:V16QI [(subreg:V16QI (match_operand:V4SI 1 "register_operand" "v") 0)]
    658 		      UNSPEC_POPCNT))
    659    (set (match_operand:V4SI 0 "register_operand" "=v")
    660 	(unspec:V4SI [(match_dup 2) (match_dup 3)]
    661 		     UNSPEC_VEC_VSUM))]
    662   "TARGET_VX"
    663 {
    664   operands[2] = gen_reg_rtx (V16QImode);
    665   operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode));
    666 })
    667 
    668 (define_expand "popcountv2di2"
    669   [(set (match_dup 2)
    670 	(unspec:V16QI [(subreg:V16QI (match_operand:V2DI 1 "register_operand" "v") 0)]
    671 		      UNSPEC_POPCNT))
    672    (set (match_dup 3)
    673 	(unspec:V4SI [(match_dup 2) (match_dup 4)]
    674 		     UNSPEC_VEC_VSUM))
    675    (set (match_operand:V2DI 0 "register_operand" "=v")
    676 	(unspec:V2DI [(match_dup 3) (match_dup 5)]
    677 		     UNSPEC_VEC_VSUMG))]
    678   "TARGET_VX"
    679 {
    680   operands[2] = gen_reg_rtx (V16QImode);
    681   operands[3] = gen_reg_rtx (V4SImode);
    682   operands[4] = force_reg (V16QImode, CONST0_RTX (V16QImode));
    683   operands[5] = force_reg (V4SImode, CONST0_RTX (V4SImode));
    684 })
    685 
    686 ; Count leading zeros
    687 (define_insn "clz<mode>2"
    688   [(set (match_operand:V        0 "register_operand" "=v")
    689 	(clz:V (match_operand:V 1 "register_operand"  "v")))]
    690   "TARGET_VX"
    691   "vclz<bhfgq>\t%v0,%v1"
    692   [(set_attr "op_type" "VRR")])
    693 
    694 ; Count trailing zeros
    695 (define_insn "ctz<mode>2"
    696   [(set (match_operand:V        0 "register_operand" "=v")
    697 	(ctz:V (match_operand:V 1 "register_operand"  "v")))]
    698   "TARGET_VX"
    699   "vctz<bhfgq>\t%v0,%v1"
    700   [(set_attr "op_type" "VRR")])
    701 
    702 
    703 
    704 ; Each vector element rotated by the corresponding vector element
    705 ; verllvb, verllvh, verllvf, verllvg
    706 (define_insn "vrotl<mode>3"
    707   [(set (match_operand:VI            0 "register_operand" "=v")
    708 	(rotate:VI (match_operand:VI 1 "register_operand"  "v")
    709 		   (match_operand:VI 2 "register_operand"  "v")))]
    710   "TARGET_VX"
    711   "verllv<bhfgq>\t%v0,%v1,%v2"
    712   [(set_attr "op_type" "VRR")])
    713 
    714 
    715 ; Vector rotate and shift by scalar instructions
    716 
    717 (define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate])
    718 (define_code_attr vec_shifts_name [(ashift "ashl")    (ashiftrt "ashr")
    719 				   (lshiftrt "lshr")  (rotate "rotl")])
    720 (define_code_attr vec_shifts_mnem [(ashift "vesl")    (ashiftrt "vesra")
    721 				   (lshiftrt "vesrl") (rotate "verll")])
    722 
    723 ; Each vector element rotated by a scalar
    724 (define_expand "<vec_shifts_name><mode>3"
    725   [(set (match_operand:VI 0 "register_operand" "")
    726 	(VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "")
    727 		       (match_operand:SI 2 "nonmemory_operand" "")))]
    728   "TARGET_VX")
    729 
    730 ; verllb, verllh, verllf, verllg
    731 ; veslb,  veslh,  veslf,  veslg
    732 ; vesrab, vesrah, vesraf, vesrag
    733 ; vesrlb, vesrlh, vesrlf, vesrlg
    734 (define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
    735   [(set (match_operand:VI                0 "register_operand"  "=v")
    736 	(VEC_SHIFTS:VI (match_operand:VI 1 "register_operand"   "v")
    737 		       (match_operand:SI 2 "nonmemory_operand" "an")))]
    738   "TARGET_VX"
    739   "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
    740   [(set_attr "op_type" "VRS")])
    741 
    742 ; Shift each element by corresponding vector element
    743 
    744 ; veslvb, veslvh, veslvf, veslvg
    745 (define_insn "vashl<mode>3"
    746   [(set (match_operand:VI            0 "register_operand" "=v")
    747 	(ashift:VI (match_operand:VI 1 "register_operand"  "v")
    748 		   (match_operand:VI 2 "register_operand"  "v")))]
    749   "TARGET_VX"
    750   "veslv<bhfgq>\t%v0,%v1,%v2"
    751   [(set_attr "op_type" "VRR")])
    752 
    753 ; vesravb, vesravh, vesravf, vesravg
    754 (define_insn "vashr<mode>3"
    755   [(set (match_operand:VI              0 "register_operand" "=v")
    756 	(ashiftrt:VI (match_operand:VI 1 "register_operand"  "v")
    757 		     (match_operand:VI 2 "register_operand"  "v")))]
    758   "TARGET_VX"
    759   "vesrav<bhfgq>\t%v0,%v1,%v2"
    760   [(set_attr "op_type" "VRR")])
    761 
    762 ; vesrlvb, vesrlvh, vesrlvf, vesrlvg
    763 (define_insn "vlshr<mode>3"
    764   [(set (match_operand:VI              0 "register_operand" "=v")
    765 	(lshiftrt:VI (match_operand:VI 1 "register_operand"  "v")
    766 		     (match_operand:VI 2 "register_operand"  "v")))]
    767   "TARGET_VX"
    768   "vesrlv<bhfgq>\t%v0,%v1,%v2"
    769   [(set_attr "op_type" "VRR")])
    770 
    771 ; Vector shift right logical by byte
    772 
    773 ; Pattern used by e.g. popcount
    774 (define_insn "*vec_srb<mode>"
    775   [(set (match_operand:V_HW 0 "register_operand"                    "=v")
    776 	(unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "v")
    777 		      (match_operand:<tointvec> 2 "register_operand" "v")]
    778 		     UNSPEC_VEC_SRLB))]
    779   "TARGET_VX"
    780   "vsrlb\t%v0,%v1,%v2"
    781   [(set_attr "op_type" "VRR")])
    782 
    783 
    784 ; vmnb, vmnh, vmnf, vmng
    785 (define_insn "smin<mode>3"
    786   [(set (match_operand:VI          0 "register_operand" "=v")
    787 	(smin:VI (match_operand:VI 1 "register_operand" "%v")
    788 		 (match_operand:VI 2 "register_operand"  "v")))]
    789   "TARGET_VX"
    790   "vmn<bhfgq>\t%v0,%v1,%v2"
    791   [(set_attr "op_type" "VRR")])
    792 
    793 ; vmxb, vmxh, vmxf, vmxg
    794 (define_insn "smax<mode>3"
    795   [(set (match_operand:VI          0 "register_operand" "=v")
    796 	(smax:VI (match_operand:VI 1 "register_operand" "%v")
    797 		 (match_operand:VI 2 "register_operand"  "v")))]
    798   "TARGET_VX"
    799   "vmx<bhfgq>\t%v0,%v1,%v2"
    800   [(set_attr "op_type" "VRR")])
    801 
    802 ; vmnlb, vmnlh, vmnlf, vmnlg
    803 (define_insn "umin<mode>3"
    804   [(set (match_operand:VI          0 "register_operand" "=v")
    805 	(umin:VI (match_operand:VI 1 "register_operand" "%v")
    806 		 (match_operand:VI 2 "register_operand"  "v")))]
    807   "TARGET_VX"
    808   "vmnl<bhfgq>\t%v0,%v1,%v2"
    809   [(set_attr "op_type" "VRR")])
    810 
    811 ; vmxlb, vmxlh, vmxlf, vmxlg
    812 (define_insn "umax<mode>3"
    813   [(set (match_operand:VI          0 "register_operand" "=v")
    814 	(umax:VI (match_operand:VI 1 "register_operand" "%v")
    815 		 (match_operand:VI 2 "register_operand"  "v")))]
    816   "TARGET_VX"
    817   "vmxl<bhfgq>\t%v0,%v1,%v2"
    818   [(set_attr "op_type" "VRR")])
    819 
    820 ; vmeb, vmeh, vmef
    821 (define_insn "vec_widen_smult_even_<mode>"
    822   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
    823 	(unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
    824 			      (match_operand:VI_QHS 2 "register_operand"  "v")]
    825 			     UNSPEC_VEC_SMULT_EVEN))]
    826   "TARGET_VX"
    827   "vme<bhfgq>\t%v0,%v1,%v2"
    828   [(set_attr "op_type" "VRR")])
    829 
    830 ; vmleb, vmleh, vmlef
    831 (define_insn "vec_widen_umult_even_<mode>"
    832   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
    833 	(unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
    834 			      (match_operand:VI_QHS 2 "register_operand"  "v")]
    835 			     UNSPEC_VEC_UMULT_EVEN))]
    836   "TARGET_VX"
    837   "vmle<bhfgq>\t%v0,%v1,%v2"
    838   [(set_attr "op_type" "VRR")])
    839 
    840 ; vmob, vmoh, vmof
    841 (define_insn "vec_widen_smult_odd_<mode>"
    842   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
    843 	(unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
    844 			      (match_operand:VI_QHS 2 "register_operand"  "v")]
    845 			     UNSPEC_VEC_SMULT_ODD))]
    846   "TARGET_VX"
    847   "vmo<bhfgq>\t%v0,%v1,%v2"
    848   [(set_attr "op_type" "VRR")])
    849 
    850 ; vmlob, vmloh, vmlof
    851 (define_insn "vec_widen_umult_odd_<mode>"
    852   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
    853 	(unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
    854 			      (match_operand:VI_QHS 2 "register_operand"  "v")]
    855 			     UNSPEC_VEC_UMULT_ODD))]
    856   "TARGET_VX"
    857   "vmlo<bhfgq>\t%v0,%v1,%v2"
    858   [(set_attr "op_type" "VRR")])
    859 
    860 ; vec_widen_umult_hi
    861 ; vec_widen_umult_lo
    862 ; vec_widen_smult_hi
    863 ; vec_widen_smult_lo
    864 
    865 ; vec_widen_ushiftl_hi
    866 ; vec_widen_ushiftl_lo
    867 ; vec_widen_sshiftl_hi
    868 ; vec_widen_sshiftl_lo
    869 
    870 ;;
    871 ;; Vector floating point arithmetic instructions
    872 ;;
    873 
    874 (define_insn "addv2df3"
    875   [(set (match_operand:V2DF            0 "register_operand" "=v")
    876 	(plus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    877 		   (match_operand:V2DF 2 "register_operand"  "v")))]
    878   "TARGET_VX"
    879   "vfadb\t%v0,%v1,%v2"
    880   [(set_attr "op_type" "VRR")])
    881 
    882 (define_insn "subv2df3"
    883   [(set (match_operand:V2DF             0 "register_operand" "=v")
    884 	(minus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    885 		    (match_operand:V2DF 2 "register_operand"  "v")))]
    886   "TARGET_VX"
    887   "vfsdb\t%v0,%v1,%v2"
    888   [(set_attr "op_type" "VRR")])
    889 
    890 (define_insn "mulv2df3"
    891   [(set (match_operand:V2DF            0 "register_operand" "=v")
    892 	(mult:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    893 		   (match_operand:V2DF 2 "register_operand"  "v")))]
    894   "TARGET_VX"
    895   "vfmdb\t%v0,%v1,%v2"
    896   [(set_attr "op_type" "VRR")])
    897 
    898 (define_insn "divv2df3"
    899   [(set (match_operand:V2DF           0 "register_operand" "=v")
    900 	(div:V2DF (match_operand:V2DF 1 "register_operand"  "v")
    901 		  (match_operand:V2DF 2 "register_operand"  "v")))]
    902   "TARGET_VX"
    903   "vfddb\t%v0,%v1,%v2"
    904   [(set_attr "op_type" "VRR")])
    905 
    906 (define_insn "sqrtv2df2"
    907   [(set (match_operand:V2DF            0 "register_operand" "=v")
    908 	(sqrt:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
    909   "TARGET_VX"
    910   "vfsqdb\t%v0,%v1"
    911   [(set_attr "op_type" "VRR")])
    912 
    913 (define_insn "fmav2df4"
    914   [(set (match_operand:V2DF           0 "register_operand" "=v")
    915 	(fma:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    916 		  (match_operand:V2DF 2 "register_operand"  "v")
    917 		  (match_operand:V2DF 3 "register_operand"  "v")))]
    918   "TARGET_VX"
    919   "vfmadb\t%v0,%v1,%v2,%v3"
    920   [(set_attr "op_type" "VRR")])
    921 
    922 (define_insn "fmsv2df4"
    923   [(set (match_operand:V2DF                     0 "register_operand" "=v")
    924 	(fma:V2DF (match_operand:V2DF           1 "register_operand" "%v")
    925 		  (match_operand:V2DF           2 "register_operand"  "v")
    926 		  (neg:V2DF (match_operand:V2DF 3 "register_operand"  "v"))))]
    927   "TARGET_VX"
    928   "vfmsdb\t%v0,%v1,%v2,%v3"
    929   [(set_attr "op_type" "VRR")])
    930 
    931 (define_insn "negv2df2"
    932   [(set (match_operand:V2DF           0 "register_operand" "=v")
    933 	(neg:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
    934   "TARGET_VX"
    935   "vflcdb\t%v0,%v1"
    936   [(set_attr "op_type" "VRR")])
    937 
    938 (define_insn "absv2df2"
    939   [(set (match_operand:V2DF           0 "register_operand" "=v")
    940 	(abs:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
    941   "TARGET_VX"
    942   "vflpdb\t%v0,%v1"
    943   [(set_attr "op_type" "VRR")])
    944 
    945 (define_insn "*negabsv2df2"
    946   [(set (match_operand:V2DF                     0 "register_operand" "=v")
    947 	(neg:V2DF (abs:V2DF (match_operand:V2DF 1 "register_operand"  "v"))))]
    948   "TARGET_VX"
    949   "vflndb\t%v0,%v1"
    950   [(set_attr "op_type" "VRR")])
    951 
    952 ; Emulate with compare + select
    953 (define_insn_and_split "smaxv2df3"
    954   [(set (match_operand:V2DF            0 "register_operand" "=v")
    955 	(smax:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    956 		   (match_operand:V2DF 2 "register_operand"  "v")))]
    957   "TARGET_VX"
    958   "#"
    959   ""
    960   [(set (match_dup 3)
    961 	(gt:V2DI (match_dup 1) (match_dup 2)))
    962    (set (match_dup 0)
    963 	(if_then_else:V2DF
    964 	 (eq (match_dup 3) (match_dup 4))
    965 	 (match_dup 2)
    966 	 (match_dup 1)))]
    967 {
    968   operands[3] = gen_reg_rtx (V2DImode);
    969   operands[4] = CONST0_RTX (V2DImode);
    970 })
    971 
    972 ; Emulate with compare + select
    973 (define_insn_and_split "sminv2df3"
    974   [(set (match_operand:V2DF            0 "register_operand" "=v")
    975 	(smin:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    976 		   (match_operand:V2DF 2 "register_operand"  "v")))]
    977   "TARGET_VX"
    978   "#"
    979   ""
    980   [(set (match_dup 3)
    981 	(gt:V2DI (match_dup 1) (match_dup 2)))
    982    (set (match_dup 0)
    983 	(if_then_else:V2DF
    984 	 (eq (match_dup 3) (match_dup 4))
    985 	 (match_dup 1)
    986 	 (match_dup 2)))]
    987 {
    988   operands[3] = gen_reg_rtx (V2DImode);
    989   operands[4] = CONST0_RTX (V2DImode);
    990 })
    991 
    992 
    993 ;;
    994 ;; Integer compares
    995 ;;
    996 
    997 (define_insn "*vec_cmp<VICMP_HW_OP:code><VI:mode>_nocc"
    998   [(set (match_operand:VI                 2 "register_operand" "=v")
    999 	(VICMP_HW_OP:VI (match_operand:VI 0 "register_operand"  "v")
   1000 			(match_operand:VI 1 "register_operand"  "v")))]
   1001   "TARGET_VX"
   1002   "vc<VICMP_HW_OP:insn_cmp_op><VI:bhfgq>\t%v2,%v0,%v1"
   1003   [(set_attr "op_type" "VRR")])
   1004 
   1005 
   1006 ;;
   1007 ;; Floating point compares
   1008 ;;
   1009 
   1010 ; EQ, GT, GE
   1011 (define_insn "*vec_cmp<VFCMP_HW_OP:code>v2df_nocc"
   1012   [(set (match_operand:V2DI                   0 "register_operand" "=v")
   1013 	(VFCMP_HW_OP:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1014 			  (match_operand:V2DF 2 "register_operand"  "v")))]
   1015    "TARGET_VX"
   1016    "vfc<VFCMP_HW_OP:asm_fcmp_op>db\t%v0,%v1,%v2"
   1017   [(set_attr "op_type" "VRR")])
   1018 
   1019 ; Expanders for not directly supported comparisons
   1020 
   1021 ; UNEQ a u== b -> !(a > b | b > a)
   1022 (define_expand "vec_cmpuneqv2df"
   1023   [(set (match_operand:V2DI          0 "register_operand" "=v")
   1024 	(gt:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1025 		 (match_operand:V2DF 2 "register_operand"  "v")))
   1026    (set (match_dup 3)
   1027 	(gt:V2DI (match_dup 2) (match_dup 1)))
   1028    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
   1029    (set (match_dup 0) (not:V2DI (match_dup 0)))]
   1030   "TARGET_VX"
   1031 {
   1032   operands[3] = gen_reg_rtx (V2DImode);
   1033 })
   1034 
   1035 ; LTGT a <> b -> a > b | b > a
   1036 (define_expand "vec_cmpltgtv2df"
   1037   [(set (match_operand:V2DI          0 "register_operand" "=v")
   1038 	(gt:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1039 		 (match_operand:V2DF 2 "register_operand"  "v")))
   1040    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
   1041    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
   1042   "TARGET_VX"
   1043 {
   1044   operands[3] = gen_reg_rtx (V2DImode);
   1045 })
   1046 
   1047 ; ORDERED (a, b): a >= b | b > a
   1048 (define_expand "vec_orderedv2df"
   1049   [(set (match_operand:V2DI          0 "register_operand" "=v")
   1050 	(ge:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1051 		 (match_operand:V2DF 2 "register_operand"  "v")))
   1052    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
   1053    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
   1054   "TARGET_VX"
   1055 {
   1056   operands[3] = gen_reg_rtx (V2DImode);
   1057 })
   1058 
   1059 ; UNORDERED (a, b): !ORDERED (a, b)
   1060 (define_expand "vec_unorderedv2df"
   1061   [(set (match_operand:V2DI          0 "register_operand" "=v")
   1062 	(ge:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1063 		 (match_operand:V2DF 2 "register_operand"  "v")))
   1064    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
   1065    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
   1066    (set (match_dup 0) (not:V2DI (match_dup 0)))]
   1067   "TARGET_VX"
   1068 {
   1069   operands[3] = gen_reg_rtx (V2DImode);
   1070 })
   1071 
   1072 (define_insn "*vec_load_pairv2di"
   1073   [(set (match_operand:V2DI                0 "register_operand" "=v")
   1074 	(vec_concat:V2DI (match_operand:DI 1 "register_operand"  "d")
   1075 			 (match_operand:DI 2 "register_operand"  "d")))]
   1076   "TARGET_VX"
   1077   "vlvgp\t%v0,%1,%2"
   1078   [(set_attr "op_type" "VRR")])
   1079 
   1080 (define_insn "vllv16qi"
   1081   [(set (match_operand:V16QI              0 "register_operand" "=v")
   1082 	(unspec:V16QI [(match_operand:SI  1 "register_operand"  "d")
   1083 		       (match_operand:BLK 2 "memory_operand"    "Q")]
   1084 		      UNSPEC_VEC_LOAD_LEN))]
   1085   "TARGET_VX"
   1086   "vll\t%v0,%1,%2"
   1087   [(set_attr "op_type" "VRS")])
   1088 
   1089 ; vfenebs, vfenehs, vfenefs
   1090 ; vfenezbs, vfenezhs, vfenezfs
   1091 (define_insn "vec_vfenes<mode>"
   1092   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
   1093 	(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
   1094 			   (match_operand:VI_HW_QHS 2 "register_operand" "v")
   1095 			   (match_operand:QI 3 "const_mask_operand" "C")]
   1096 			  UNSPEC_VEC_VFENE))
   1097    (set (reg:CCRAW CC_REGNUM)
   1098 	(unspec:CCRAW [(match_dup 1)
   1099 		       (match_dup 2)
   1100 		       (match_dup 3)]
   1101 		      UNSPEC_VEC_VFENECC))]
   1102   "TARGET_VX"
   1103 {
   1104   unsigned HOST_WIDE_INT flags = INTVAL (operands[3]);
   1105 
   1106   gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
   1107   flags &= ~VSTRING_FLAG_CS;
   1108 
   1109   if (flags == VSTRING_FLAG_ZS)
   1110     return "vfenez<bhfgq>s\t%v0,%v1,%v2";
   1111   return "vfene<bhfgq>s\t%v0,%v1,%v2";
   1112 }
   1113   [(set_attr "op_type" "VRR")])
   1114 
   1115 
   1116 ; Vector select
   1117 
   1118 ; The following splitters simplify vec_sel for constant 0 or -1
   1119 ; selection sources.  This is required to generate efficient code for
   1120 ; vcond.
   1121 
   1122 ; a = b == c;
   1123 (define_split
   1124   [(set (match_operand:V 0 "register_operand" "")
   1125 	(if_then_else:V
   1126 	 (eq (match_operand:<tointvec> 3 "register_operand" "")
   1127 	     (match_operand:V 4 "const0_operand" ""))
   1128 	 (match_operand:V 1 "const0_operand" "")
   1129 	 (match_operand:V 2 "all_ones_operand" "")))]
   1130   "TARGET_VX"
   1131   [(set (match_dup 0) (match_dup 3))]
   1132 {
   1133   PUT_MODE (operands[3], <V:MODE>mode);
   1134 })
   1135 
   1136 ; a = ~(b == c)
   1137 (define_split
   1138   [(set (match_operand:V 0 "register_operand" "")
   1139 	(if_then_else:V
   1140 	 (eq (match_operand:<tointvec> 3 "register_operand" "")
   1141 	     (match_operand:V 4 "const0_operand" ""))
   1142 	 (match_operand:V 1 "all_ones_operand" "")
   1143 	 (match_operand:V 2 "const0_operand" "")))]
   1144   "TARGET_VX"
   1145   [(set (match_dup 0) (not:V (match_dup 3)))]
   1146 {
   1147   PUT_MODE (operands[3], <V:MODE>mode);
   1148 })
   1149 
   1150 ; a = b != c
   1151 (define_split
   1152   [(set (match_operand:V 0 "register_operand" "")
   1153 	(if_then_else:V
   1154 	 (ne (match_operand:<tointvec> 3 "register_operand" "")
   1155 	     (match_operand:V 4 "const0_operand" ""))
   1156 	 (match_operand:V 1 "all_ones_operand" "")
   1157 	 (match_operand:V 2 "const0_operand" "")))]
   1158   "TARGET_VX"
   1159   [(set (match_dup 0) (match_dup 3))]
   1160 {
   1161   PUT_MODE (operands[3], <V:MODE>mode);
   1162 })
   1163 
   1164 ; a = ~(b != c)
   1165 (define_split
   1166   [(set (match_operand:V 0 "register_operand" "")
   1167 	(if_then_else:V
   1168 	 (ne (match_operand:<tointvec> 3 "register_operand" "")
   1169 	     (match_operand:V 4 "const0_operand" ""))
   1170 	 (match_operand:V 1 "const0_operand" "")
   1171 	 (match_operand:V 2 "all_ones_operand" "")))]
   1172   "TARGET_VX"
   1173   [(set (match_dup 0) (not:V (match_dup 3)))]
   1174 {
   1175   PUT_MODE (operands[3], <V:MODE>mode);
   1176 })
   1177 
   1178 ; op0 = op3 == 0 ? op1 : op2
   1179 (define_insn "*vec_sel0<mode>"
   1180   [(set (match_operand:V 0 "register_operand" "=v")
   1181 	(if_then_else:V
   1182 	 (eq (match_operand:<tointvec> 3 "register_operand" "v")
   1183 	     (match_operand:<tointvec> 4 "const0_operand" ""))
   1184 	 (match_operand:V 1 "register_operand" "v")
   1185 	 (match_operand:V 2 "register_operand" "v")))]
   1186   "TARGET_VX"
   1187   "vsel\t%v0,%2,%1,%3"
   1188   [(set_attr "op_type" "VRR")])
   1189 
   1190 ; op0 = !op3 == 0 ? op1 : op2
   1191 (define_insn "*vec_sel0<mode>"
   1192   [(set (match_operand:V 0 "register_operand" "=v")
   1193 	(if_then_else:V
   1194 	 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
   1195 	     (match_operand:<tointvec> 4 "const0_operand" ""))
   1196 	 (match_operand:V 1 "register_operand" "v")
   1197 	 (match_operand:V 2 "register_operand" "v")))]
   1198   "TARGET_VX"
   1199   "vsel\t%v0,%1,%2,%3"
   1200   [(set_attr "op_type" "VRR")])
   1201 
   1202 ; op0 = op3 == -1 ? op1 : op2
   1203 (define_insn "*vec_sel1<mode>"
   1204   [(set (match_operand:V 0 "register_operand" "=v")
   1205 	(if_then_else:V
   1206 	 (eq (match_operand:<tointvec> 3 "register_operand" "v")
   1207 	     (match_operand:<tointvec> 4 "all_ones_operand" ""))
   1208 	 (match_operand:V 1 "register_operand" "v")
   1209 	 (match_operand:V 2 "register_operand" "v")))]
   1210   "TARGET_VX"
   1211   "vsel\t%v0,%1,%2,%3"
   1212   [(set_attr "op_type" "VRR")])
   1213 
   1214 ; op0 = !op3 == -1 ? op1 : op2
   1215 (define_insn "*vec_sel1<mode>"
   1216   [(set (match_operand:V 0 "register_operand" "=v")
   1217 	(if_then_else:V
   1218 	 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
   1219 	     (match_operand:<tointvec> 4 "all_ones_operand" ""))
   1220 	 (match_operand:V 1 "register_operand" "v")
   1221 	 (match_operand:V 2 "register_operand" "v")))]
   1222   "TARGET_VX"
   1223   "vsel\t%v0,%2,%1,%3"
   1224   [(set_attr "op_type" "VRR")])
   1225 
   1226 
   1227 
   1228 ; reduc_smin
   1229 ; reduc_smax
   1230 ; reduc_umin
   1231 ; reduc_umax
   1232 
   1233 ; vec_shl vrep + vsl
   1234 ; vec_shr
   1235 
   1236 ; vec_pack_trunc
   1237 ; vec_pack_ssat
   1238 ; vec_pack_usat
   1239 ; vec_pack_sfix_trunc
   1240 ; vec_pack_ufix_trunc
   1241 ; vec_unpacks_hi
   1242 ; vec_unpacks_low
   1243 ; vec_unpacku_hi
   1244 ; vec_unpacku_low
   1245 ; vec_unpacks_float_hi
   1246 ; vec_unpacks_float_lo
   1247 ; vec_unpacku_float_hi
   1248 ; vec_unpacku_float_lo
   1249