Home | History | Annotate | Line # | Download | only in s390
vector.md revision 1.1.1.1
      1 ;;- Instruction patterns for the System z vector facility
      2 ;;  Copyright (C) 2015 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 ; FIXME: Support also vector mode operands for 1
    311 ; FIXME: A target memory operand seems to be useful otherwise we end
    312 ; up with vl vlvgg vst.  Shouldn't the middle-end be able to handle
    313 ; that itself?
    314 (define_insn "*vec_set<mode>"
    315   [(set (match_operand:V                    0 "register_operand"             "=v, v,v")
    316 	(unspec:V [(match_operand:<non_vec> 1 "general_operand"               "d,QR,K")
    317 		   (match_operand:SI        2 "shift_count_or_setmem_operand" "Y, I,I")
    318 		   (match_operand:V         3 "register_operand"              "0, 0,0")]
    319 		  UNSPEC_VEC_SET))]
    320   "TARGET_VX"
    321   "@
    322    vlvg<bhfgq>\t%v0,%1,%Y2
    323    vle<bhfgq>\t%v0,%1,%2
    324    vlei<bhfgq>\t%v0,%1,%2"
    325   [(set_attr "op_type" "VRS,VRX,VRI")])
    326 
    327 ; vec_set is supposed to *modify* an existing vector so operand 0 is
    328 ; duplicated as input operand.
    329 (define_expand "vec_set<mode>"
    330   [(set (match_operand:V                    0 "register_operand"              "")
    331 	(unspec:V [(match_operand:<non_vec> 1 "general_operand"               "")
    332 		   (match_operand:SI        2 "shift_count_or_setmem_operand" "")
    333 		   (match_dup 0)]
    334 		   UNSPEC_VEC_SET))]
    335   "TARGET_VX")
    336 
    337 ; FIXME: Support also vector mode operands for 0
    338 ; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :(
    339 ; This is used via RTL standard name as well as for expanding the builtin
    340 (define_insn "vec_extract<mode>"
    341   [(set (match_operand:<non_vec> 0 "nonimmediate_operand"                        "=d,QR")
    342 	(unspec:<non_vec> [(match_operand:V  1 "register_operand"                " v, v")
    343 			   (match_operand:SI 2 "shift_count_or_setmem_operand"   " Y, I")]
    344 			  UNSPEC_VEC_EXTRACT))]
    345   "TARGET_VX"
    346   "@
    347    vlgv<bhfgq>\t%0,%v1,%Y2
    348    vste<bhfgq>\t%v1,%0,%2"
    349   [(set_attr "op_type" "VRS,VRX")])
    350 
    351 (define_expand "vec_init<V_HW:mode>"
    352   [(match_operand:V_HW 0 "register_operand" "")
    353    (match_operand:V_HW 1 "nonmemory_operand" "")]
    354   "TARGET_VX"
    355 {
    356   s390_expand_vec_init (operands[0], operands[1]);
    357   DONE;
    358 })
    359 
    360 ; Replicate from vector element
    361 (define_insn "*vec_splat<mode>"
    362   [(set (match_operand:V_HW   0 "register_operand" "=v")
    363 	(vec_duplicate:V_HW
    364 	 (vec_select:<non_vec>
    365 	  (match_operand:V_HW 1 "register_operand"  "v")
    366 	  (parallel
    367 	   [(match_operand:QI 2 "const_mask_operand" "C")]))))]
    368   "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW:MODE>mode)"
    369   "vrep<bhfgq>\t%v0,%v1,%2"
    370   [(set_attr "op_type" "VRI")])
    371 
    372 (define_insn "*vec_splats<mode>"
    373   [(set (match_operand:V_HW                          0 "register_operand" "=v,v,v,v")
    374 	(vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand"  "QR,K,v,d")))]
    375   "TARGET_VX"
    376   "@
    377    vlrep<bhfgq>\t%v0,%1
    378    vrepi<bhfgq>\t%v0,%h1
    379    vrep<bhfgq>\t%v0,%v1,0
    380    #"
    381   [(set_attr "op_type" "VRX,VRI,VRI,*")])
    382 
    383 ; vec_splats is supposed to replicate op1 into all elements of op0
    384 ; This splitter first sets the rightmost element of op0 to op1 and
    385 ; then does a vec_splat to replicate that element into all other
    386 ; elements.
    387 (define_split
    388   [(set (match_operand:V_HW                          0 "register_operand" "")
    389 	(vec_duplicate:V_HW (match_operand:<non_vec> 1 "register_operand" "")))]
    390   "TARGET_VX && GENERAL_REG_P (operands[1])"
    391   [(set (match_dup 0)
    392 	(unspec:V_HW [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET))
    393    (set (match_dup 0)
    394 	(vec_duplicate:V_HW
    395 	 (vec_select:<non_vec>
    396 	  (match_dup 0) (parallel [(match_dup 2)]))))]
    397 {
    398   operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1);
    399 })
    400 
    401 (define_expand "vcond<V_HW:mode><V_HW2:mode>"
    402   [(set (match_operand:V_HW 0 "register_operand" "")
    403 	(if_then_else:V_HW
    404 	 (match_operator 3 "comparison_operator"
    405 			 [(match_operand:V_HW2 4 "register_operand" "")
    406 			  (match_operand:V_HW2 5 "register_operand" "")])
    407 	 (match_operand:V_HW 1 "nonmemory_operand" "")
    408 	 (match_operand:V_HW 2 "nonmemory_operand" "")))]
    409   "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
    410 {
    411   s390_expand_vcond (operands[0], operands[1], operands[2],
    412 		     GET_CODE (operands[3]), operands[4], operands[5]);
    413   DONE;
    414 })
    415 
    416 (define_expand "vcondu<V_HW:mode><V_HW2:mode>"
    417   [(set (match_operand:V_HW 0 "register_operand" "")
    418 	(if_then_else:V_HW
    419 	 (match_operator 3 "comparison_operator"
    420 			 [(match_operand:V_HW2 4 "register_operand" "")
    421 			  (match_operand:V_HW2 5 "register_operand" "")])
    422 	 (match_operand:V_HW 1 "nonmemory_operand" "")
    423 	 (match_operand:V_HW 2 "nonmemory_operand" "")))]
    424   "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
    425 {
    426   s390_expand_vcond (operands[0], operands[1], operands[2],
    427 		     GET_CODE (operands[3]), operands[4], operands[5]);
    428   DONE;
    429 })
    430 
    431 ; We only have HW support for byte vectors.  The middle-end is
    432 ; supposed to lower the mode if required.
    433 (define_insn "vec_permv16qi"
    434   [(set (match_operand:V16QI 0 "register_operand"               "=v")
    435 	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
    436 		       (match_operand:V16QI 2 "register_operand" "v")
    437 		       (match_operand:V16QI 3 "register_operand" "v")]
    438 		      UNSPEC_VEC_PERM))]
    439   "TARGET_VX"
    440   "vperm\t%v0,%v1,%v2,%v3"
    441   [(set_attr "op_type" "VRR")])
    442 
    443 ; vec_perm_const for V2DI using vpdi?
    444 
    445 ;;
    446 ;; Vector integer arithmetic instructions
    447 ;;
    448 
    449 ; vab, vah, vaf, vag, vaq
    450 
    451 ; We use nonimmediate_operand instead of register_operand since it is
    452 ; better to have the reloads into VRs instead of splitting the
    453 ; operation into two DImode ADDs.
    454 (define_insn "<ti*>add<mode>3"
    455   [(set (match_operand:VIT           0 "nonimmediate_operand" "=v")
    456 	(plus:VIT (match_operand:VIT 1 "nonimmediate_operand" "%v")
    457 		  (match_operand:VIT 2 "general_operand"       "v")))]
    458   "TARGET_VX"
    459   "va<bhfgq>\t%v0,%v1,%v2"
    460   [(set_attr "op_type" "VRR")])
    461 
    462 ; vsb, vsh, vsf, vsg, vsq
    463 (define_insn "<ti*>sub<mode>3"
    464   [(set (match_operand:VIT            0 "nonimmediate_operand" "=v")
    465 	(minus:VIT (match_operand:VIT 1 "nonimmediate_operand"  "v")
    466 		   (match_operand:VIT 2 "general_operand"  "v")))]
    467   "TARGET_VX"
    468   "vs<bhfgq>\t%v0,%v1,%v2"
    469   [(set_attr "op_type" "VRR")])
    470 
    471 ; vmlb, vmlhw, vmlf
    472 (define_insn "mul<mode>3"
    473   [(set (match_operand:VI_QHS              0 "register_operand" "=v")
    474 	(mult:VI_QHS (match_operand:VI_QHS 1 "register_operand" "%v")
    475 		     (match_operand:VI_QHS 2 "register_operand"  "v")))]
    476   "TARGET_VX"
    477   "vml<bhfgq><w>\t%v0,%v1,%v2"
    478   [(set_attr "op_type" "VRR")])
    479 
    480 ; vlcb, vlch, vlcf, vlcg
    481 (define_insn "neg<mode>2"
    482   [(set (match_operand:VI         0 "register_operand" "=v")
    483 	(neg:VI (match_operand:VI 1 "register_operand"  "v")))]
    484   "TARGET_VX"
    485   "vlc<bhfgq>\t%v0,%v1"
    486   [(set_attr "op_type" "VRR")])
    487 
    488 ; vlpb, vlph, vlpf, vlpg
    489 (define_insn "abs<mode>2"
    490   [(set (match_operand:VI         0 "register_operand" "=v")
    491 	(abs:VI (match_operand:VI 1 "register_operand"  "v")))]
    492   "TARGET_VX"
    493   "vlp<bhfgq>\t%v0,%v1"
    494   [(set_attr "op_type" "VRR")])
    495 
    496 
    497 ; Vector sum across
    498 
    499 ; Sum across DImode parts of the 1st operand and add the rightmost
    500 ; element of 2nd operand
    501 ; vsumgh, vsumgf
    502 (define_insn "*vec_sum2<mode>"
    503   [(set (match_operand:V2DI 0 "register_operand" "=v")
    504 	(unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "v")
    505 		      (match_operand:VI_HW_HS 2 "register_operand" "v")]
    506 		     UNSPEC_VEC_VSUMG))]
    507   "TARGET_VX"
    508   "vsumg<bhfgq>\t%v0,%v1,%v2"
    509   [(set_attr "op_type" "VRR")])
    510 
    511 ; vsumb, vsumh
    512 (define_insn "*vec_sum4<mode>"
    513   [(set (match_operand:V4SI 0 "register_operand" "=v")
    514 	(unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "v")
    515 		      (match_operand:VI_HW_QH 2 "register_operand" "v")]
    516 		     UNSPEC_VEC_VSUM))]
    517   "TARGET_VX"
    518   "vsum<bhfgq>\t%v0,%v1,%v2"
    519   [(set_attr "op_type" "VRR")])
    520 
    521 ;;
    522 ;; Vector bit instructions (int + fp)
    523 ;;
    524 
    525 ; Vector and
    526 
    527 (define_insn "and<mode>3"
    528   [(set (match_operand:VT         0 "register_operand" "=v")
    529 	(and:VT (match_operand:VT 1 "register_operand" "%v")
    530 		(match_operand:VT 2 "register_operand"  "v")))]
    531   "TARGET_VX"
    532   "vn\t%v0,%v1,%v2"
    533   [(set_attr "op_type" "VRR")])
    534 
    535 
    536 ; Vector or
    537 
    538 (define_insn "ior<mode>3"
    539   [(set (match_operand:VT         0 "register_operand" "=v")
    540 	(ior:VT (match_operand:VT 1 "register_operand" "%v")
    541 		(match_operand:VT 2 "register_operand"  "v")))]
    542   "TARGET_VX"
    543   "vo\t%v0,%v1,%v2"
    544   [(set_attr "op_type" "VRR")])
    545 
    546 
    547 ; Vector xor
    548 
    549 (define_insn "xor<mode>3"
    550   [(set (match_operand:VT         0 "register_operand" "=v")
    551 	(xor:VT (match_operand:VT 1 "register_operand" "%v")
    552 		(match_operand:VT 2 "register_operand"  "v")))]
    553   "TARGET_VX"
    554   "vx\t%v0,%v1,%v2"
    555   [(set_attr "op_type" "VRR")])
    556 
    557 
    558 ; Bitwise inversion of a vector - used for vec_cmpne
    559 (define_insn "*not<mode>"
    560   [(set (match_operand:VT         0 "register_operand" "=v")
    561 	(not:VT (match_operand:VT 1 "register_operand"  "v")))]
    562   "TARGET_VX"
    563   "vnot\t%v0,%v1"
    564   [(set_attr "op_type" "VRR")])
    565 
    566 ; Vector population count
    567 
    568 (define_insn "popcountv16qi2"
    569   [(set (match_operand:V16QI                0 "register_operand" "=v")
    570 	(unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "v")]
    571 		      UNSPEC_POPCNT))]
    572   "TARGET_VX"
    573   "vpopct\t%v0,%v1,0"
    574   [(set_attr "op_type" "VRR")])
    575 
    576 ; vpopct only counts bits in byte elements.  Bigger element sizes need
    577 ; to be emulated.  Word and doubleword elements can use the sum across
    578 ; instructions.  For halfword sized elements we do a shift of a copy
    579 ; of the result, add it to the result and extend it to halfword
    580 ; element size (unpack).
    581 
    582 (define_expand "popcountv8hi2"
    583   [(set (match_dup 2)
    584 	(unspec:V16QI [(subreg:V16QI (match_operand:V8HI 1 "register_operand" "v") 0)]
    585 		      UNSPEC_POPCNT))
    586    ; Make a copy of the result
    587    (set (match_dup 3) (match_dup 2))
    588    ; Generate the shift count operand in a VR (8->byte 7)
    589    (set (match_dup 4) (match_dup 5))
    590    (set (match_dup 4) (unspec:V16QI [(const_int 8)
    591 				     (const_int 7)
    592 				     (match_dup 4)] UNSPEC_VEC_SET))
    593    ; Vector shift right logical by one byte
    594    (set (match_dup 3)
    595 	(unspec:V16QI [(match_dup 3) (match_dup 4)] UNSPEC_VEC_SRLB))
    596    ; Add the shifted and the original result
    597    (set (match_dup 2)
    598 	(plus:V16QI (match_dup 2) (match_dup 3)))
    599    ; Generate mask for the odd numbered byte elements
    600    (set (match_dup 3)
    601 	(const_vector:V16QI [(const_int 0) (const_int 255)
    602 			     (const_int 0) (const_int 255)
    603 			     (const_int 0) (const_int 255)
    604 			     (const_int 0) (const_int 255)
    605 			     (const_int 0) (const_int 255)
    606 			     (const_int 0) (const_int 255)
    607 			     (const_int 0) (const_int 255)
    608 			     (const_int 0) (const_int 255)]))
    609    ; Zero out the even indexed bytes
    610    (set (match_operand:V8HI 0 "register_operand" "=v")
    611 	(and:V8HI (subreg:V8HI (match_dup 2) 0)
    612 		  (subreg:V8HI (match_dup 3) 0)))
    613 ]
    614   "TARGET_VX"
    615 {
    616   operands[2] = gen_reg_rtx (V16QImode);
    617   operands[3] = gen_reg_rtx (V16QImode);
    618   operands[4] = gen_reg_rtx (V16QImode);
    619   operands[5] = CONST0_RTX (V16QImode);
    620 })
    621 
    622 (define_expand "popcountv4si2"
    623   [(set (match_dup 2)
    624 	(unspec:V16QI [(subreg:V16QI (match_operand:V4SI 1 "register_operand" "v") 0)]
    625 		      UNSPEC_POPCNT))
    626    (set (match_operand:V4SI 0 "register_operand" "=v")
    627 	(unspec:V4SI [(match_dup 2) (match_dup 3)]
    628 		     UNSPEC_VEC_VSUM))]
    629   "TARGET_VX"
    630 {
    631   operands[2] = gen_reg_rtx (V16QImode);
    632   operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode));
    633 })
    634 
    635 (define_expand "popcountv2di2"
    636   [(set (match_dup 2)
    637 	(unspec:V16QI [(subreg:V16QI (match_operand:V2DI 1 "register_operand" "v") 0)]
    638 		      UNSPEC_POPCNT))
    639    (set (match_dup 3)
    640 	(unspec:V4SI [(match_dup 2) (match_dup 4)]
    641 		     UNSPEC_VEC_VSUM))
    642    (set (match_operand:V2DI 0 "register_operand" "=v")
    643 	(unspec:V2DI [(match_dup 3) (match_dup 5)]
    644 		     UNSPEC_VEC_VSUMG))]
    645   "TARGET_VX"
    646 {
    647   operands[2] = gen_reg_rtx (V16QImode);
    648   operands[3] = gen_reg_rtx (V4SImode);
    649   operands[4] = force_reg (V16QImode, CONST0_RTX (V16QImode));
    650   operands[5] = force_reg (V4SImode, CONST0_RTX (V4SImode));
    651 })
    652 
    653 ; Count leading zeros
    654 (define_insn "clz<mode>2"
    655   [(set (match_operand:V        0 "register_operand" "=v")
    656 	(clz:V (match_operand:V 1 "register_operand"  "v")))]
    657   "TARGET_VX"
    658   "vclz<bhfgq>\t%v0,%v1"
    659   [(set_attr "op_type" "VRR")])
    660 
    661 ; Count trailing zeros
    662 (define_insn "ctz<mode>2"
    663   [(set (match_operand:V        0 "register_operand" "=v")
    664 	(ctz:V (match_operand:V 1 "register_operand"  "v")))]
    665   "TARGET_VX"
    666   "vctz<bhfgq>\t%v0,%v1"
    667   [(set_attr "op_type" "VRR")])
    668 
    669 
    670 ; Vector rotate instructions
    671 
    672 ; Each vector element rotated by a scalar
    673 ; verllb, verllh, verllf, verllg
    674 (define_insn "rotl<mode>3"
    675   [(set (match_operand:VI            0 "register_operand"             "=v")
    676 	(rotate:VI (match_operand:VI 1 "register_operand"              "v")
    677 		   (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
    678   "TARGET_VX"
    679   "verll<bhfgq>\t%v0,%v1,%Y2"
    680   [(set_attr "op_type" "VRS")])
    681 
    682 ; Each vector element rotated by the corresponding vector element
    683 ; verllvb, verllvh, verllvf, verllvg
    684 (define_insn "vrotl<mode>3"
    685   [(set (match_operand:VI            0 "register_operand" "=v")
    686 	(rotate:VI (match_operand:VI 1 "register_operand"  "v")
    687 		   (match_operand:VI 2 "register_operand"  "v")))]
    688   "TARGET_VX"
    689   "verllv<bhfgq>\t%v0,%v1,%v2"
    690   [(set_attr "op_type" "VRR")])
    691 
    692 
    693 ; Shift each element by scalar value
    694 
    695 ; veslb, veslh, veslf, veslg
    696 (define_insn "ashl<mode>3"
    697   [(set (match_operand:VI            0 "register_operand"             "=v")
    698 	(ashift:VI (match_operand:VI 1 "register_operand"              "v")
    699 		   (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
    700   "TARGET_VX"
    701   "vesl<bhfgq>\t%v0,%v1,%Y2"
    702   [(set_attr "op_type" "VRS")])
    703 
    704 ; vesrab, vesrah, vesraf, vesrag
    705 (define_insn "ashr<mode>3"
    706   [(set (match_operand:VI              0 "register_operand"             "=v")
    707 	(ashiftrt:VI (match_operand:VI 1 "register_operand"              "v")
    708 		     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
    709   "TARGET_VX"
    710   "vesra<bhfgq>\t%v0,%v1,%Y2"
    711   [(set_attr "op_type" "VRS")])
    712 
    713 ; vesrlb, vesrlh, vesrlf, vesrlg
    714 (define_insn "lshr<mode>3"
    715   [(set (match_operand:VI              0 "register_operand"             "=v")
    716 	(lshiftrt:VI (match_operand:VI 1 "register_operand"              "v")
    717 		     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
    718   "TARGET_VX"
    719   "vesrl<bhfgq>\t%v0,%v1,%Y2"
    720   [(set_attr "op_type" "VRS")])
    721 
    722 
    723 ; Shift each element by corresponding vector element
    724 
    725 ; veslvb, veslvh, veslvf, veslvg
    726 (define_insn "vashl<mode>3"
    727   [(set (match_operand:VI            0 "register_operand" "=v")
    728 	(ashift:VI (match_operand:VI 1 "register_operand"  "v")
    729 		   (match_operand:VI 2 "register_operand"  "v")))]
    730   "TARGET_VX"
    731   "veslv<bhfgq>\t%v0,%v1,%v2"
    732   [(set_attr "op_type" "VRR")])
    733 
    734 ; vesravb, vesravh, vesravf, vesravg
    735 (define_insn "vashr<mode>3"
    736   [(set (match_operand:VI              0 "register_operand" "=v")
    737 	(ashiftrt:VI (match_operand:VI 1 "register_operand"  "v")
    738 		     (match_operand:VI 2 "register_operand"  "v")))]
    739   "TARGET_VX"
    740   "vesrav<bhfgq>\t%v0,%v1,%v2"
    741   [(set_attr "op_type" "VRR")])
    742 
    743 ; vesrlvb, vesrlvh, vesrlvf, vesrlvg
    744 (define_insn "vlshr<mode>3"
    745   [(set (match_operand:VI              0 "register_operand" "=v")
    746 	(lshiftrt:VI (match_operand:VI 1 "register_operand"  "v")
    747 		     (match_operand:VI 2 "register_operand"  "v")))]
    748   "TARGET_VX"
    749   "vesrlv<bhfgq>\t%v0,%v1,%v2"
    750   [(set_attr "op_type" "VRR")])
    751 
    752 ; Vector shift right logical by byte
    753 
    754 ; Pattern used by e.g. popcount
    755 (define_insn "*vec_srb<mode>"
    756   [(set (match_operand:V_HW 0 "register_operand"                    "=v")
    757 	(unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "v")
    758 		      (match_operand:<tointvec> 2 "register_operand" "v")]
    759 		     UNSPEC_VEC_SRLB))]
    760   "TARGET_VX"
    761   "vsrlb\t%v0,%v1,%v2"
    762   [(set_attr "op_type" "VRR")])
    763 
    764 
    765 ; vmnb, vmnh, vmnf, vmng
    766 (define_insn "smin<mode>3"
    767   [(set (match_operand:VI          0 "register_operand" "=v")
    768 	(smin:VI (match_operand:VI 1 "register_operand" "%v")
    769 		 (match_operand:VI 2 "register_operand"  "v")))]
    770   "TARGET_VX"
    771   "vmn<bhfgq>\t%v0,%v1,%v2"
    772   [(set_attr "op_type" "VRR")])
    773 
    774 ; vmxb, vmxh, vmxf, vmxg
    775 (define_insn "smax<mode>3"
    776   [(set (match_operand:VI          0 "register_operand" "=v")
    777 	(smax:VI (match_operand:VI 1 "register_operand" "%v")
    778 		 (match_operand:VI 2 "register_operand"  "v")))]
    779   "TARGET_VX"
    780   "vmx<bhfgq>\t%v0,%v1,%v2"
    781   [(set_attr "op_type" "VRR")])
    782 
    783 ; vmnlb, vmnlh, vmnlf, vmnlg
    784 (define_insn "umin<mode>3"
    785   [(set (match_operand:VI          0 "register_operand" "=v")
    786 	(umin:VI (match_operand:VI 1 "register_operand" "%v")
    787 		 (match_operand:VI 2 "register_operand"  "v")))]
    788   "TARGET_VX"
    789   "vmnl<bhfgq>\t%v0,%v1,%v2"
    790   [(set_attr "op_type" "VRR")])
    791 
    792 ; vmxlb, vmxlh, vmxlf, vmxlg
    793 (define_insn "umax<mode>3"
    794   [(set (match_operand:VI          0 "register_operand" "=v")
    795 	(umax:VI (match_operand:VI 1 "register_operand" "%v")
    796 		 (match_operand:VI 2 "register_operand"  "v")))]
    797   "TARGET_VX"
    798   "vmxl<bhfgq>\t%v0,%v1,%v2"
    799   [(set_attr "op_type" "VRR")])
    800 
    801 ; vmeb, vmeh, vmef
    802 (define_insn "vec_widen_smult_even_<mode>"
    803   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
    804 	(unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
    805 			      (match_operand:VI_QHS 2 "register_operand"  "v")]
    806 			     UNSPEC_VEC_SMULT_EVEN))]
    807   "TARGET_VX"
    808   "vme<bhfgq>\t%v0,%v1,%v2"
    809   [(set_attr "op_type" "VRR")])
    810 
    811 ; vmleb, vmleh, vmlef
    812 (define_insn "vec_widen_umult_even_<mode>"
    813   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
    814 	(unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
    815 			      (match_operand:VI_QHS 2 "register_operand"  "v")]
    816 			     UNSPEC_VEC_UMULT_EVEN))]
    817   "TARGET_VX"
    818   "vmle<bhfgq>\t%v0,%v1,%v2"
    819   [(set_attr "op_type" "VRR")])
    820 
    821 ; vmob, vmoh, vmof
    822 (define_insn "vec_widen_smult_odd_<mode>"
    823   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
    824 	(unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
    825 			      (match_operand:VI_QHS 2 "register_operand"  "v")]
    826 			     UNSPEC_VEC_SMULT_ODD))]
    827   "TARGET_VX"
    828   "vmo<bhfgq>\t%v0,%v1,%v2"
    829   [(set_attr "op_type" "VRR")])
    830 
    831 ; vmlob, vmloh, vmlof
    832 (define_insn "vec_widen_umult_odd_<mode>"
    833   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
    834 	(unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
    835 			      (match_operand:VI_QHS 2 "register_operand"  "v")]
    836 			     UNSPEC_VEC_UMULT_ODD))]
    837   "TARGET_VX"
    838   "vmlo<bhfgq>\t%v0,%v1,%v2"
    839   [(set_attr "op_type" "VRR")])
    840 
    841 ; vec_widen_umult_hi
    842 ; vec_widen_umult_lo
    843 ; vec_widen_smult_hi
    844 ; vec_widen_smult_lo
    845 
    846 ; vec_widen_ushiftl_hi
    847 ; vec_widen_ushiftl_lo
    848 ; vec_widen_sshiftl_hi
    849 ; vec_widen_sshiftl_lo
    850 
    851 ;;
    852 ;; Vector floating point arithmetic instructions
    853 ;;
    854 
    855 (define_insn "addv2df3"
    856   [(set (match_operand:V2DF            0 "register_operand" "=v")
    857 	(plus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    858 		   (match_operand:V2DF 2 "register_operand"  "v")))]
    859   "TARGET_VX"
    860   "vfadb\t%v0,%v1,%v2"
    861   [(set_attr "op_type" "VRR")])
    862 
    863 (define_insn "subv2df3"
    864   [(set (match_operand:V2DF             0 "register_operand" "=v")
    865 	(minus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    866 		    (match_operand:V2DF 2 "register_operand"  "v")))]
    867   "TARGET_VX"
    868   "vfsdb\t%v0,%v1,%v2"
    869   [(set_attr "op_type" "VRR")])
    870 
    871 (define_insn "mulv2df3"
    872   [(set (match_operand:V2DF            0 "register_operand" "=v")
    873 	(mult:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    874 		   (match_operand:V2DF 2 "register_operand"  "v")))]
    875   "TARGET_VX"
    876   "vfmdb\t%v0,%v1,%v2"
    877   [(set_attr "op_type" "VRR")])
    878 
    879 (define_insn "divv2df3"
    880   [(set (match_operand:V2DF           0 "register_operand" "=v")
    881 	(div:V2DF (match_operand:V2DF 1 "register_operand"  "v")
    882 		  (match_operand:V2DF 2 "register_operand"  "v")))]
    883   "TARGET_VX"
    884   "vfddb\t%v0,%v1,%v2"
    885   [(set_attr "op_type" "VRR")])
    886 
    887 (define_insn "sqrtv2df2"
    888   [(set (match_operand:V2DF            0 "register_operand" "=v")
    889 	(sqrt:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
    890   "TARGET_VX"
    891   "vfsqdb\t%v0,%v1"
    892   [(set_attr "op_type" "VRR")])
    893 
    894 (define_insn "fmav2df4"
    895   [(set (match_operand:V2DF           0 "register_operand" "=v")
    896 	(fma:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    897 		  (match_operand:V2DF 2 "register_operand"  "v")
    898 		  (match_operand:V2DF 3 "register_operand"  "v")))]
    899   "TARGET_VX"
    900   "vfmadb\t%v0,%v1,%v2,%v3"
    901   [(set_attr "op_type" "VRR")])
    902 
    903 (define_insn "fmsv2df4"
    904   [(set (match_operand:V2DF                     0 "register_operand" "=v")
    905 	(fma:V2DF (match_operand:V2DF           1 "register_operand" "%v")
    906 		  (match_operand:V2DF           2 "register_operand"  "v")
    907 		  (neg:V2DF (match_operand:V2DF 3 "register_operand"  "v"))))]
    908   "TARGET_VX"
    909   "vfmsdb\t%v0,%v1,%v2,%v3"
    910   [(set_attr "op_type" "VRR")])
    911 
    912 (define_insn "negv2df2"
    913   [(set (match_operand:V2DF           0 "register_operand" "=v")
    914 	(neg:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
    915   "TARGET_VX"
    916   "vflcdb\t%v0,%v1"
    917   [(set_attr "op_type" "VRR")])
    918 
    919 (define_insn "absv2df2"
    920   [(set (match_operand:V2DF           0 "register_operand" "=v")
    921 	(abs:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
    922   "TARGET_VX"
    923   "vflpdb\t%v0,%v1"
    924   [(set_attr "op_type" "VRR")])
    925 
    926 (define_insn "*negabsv2df2"
    927   [(set (match_operand:V2DF                     0 "register_operand" "=v")
    928 	(neg:V2DF (abs:V2DF (match_operand:V2DF 1 "register_operand"  "v"))))]
    929   "TARGET_VX"
    930   "vflndb\t%v0,%v1"
    931   [(set_attr "op_type" "VRR")])
    932 
    933 ; Emulate with compare + select
    934 (define_insn_and_split "smaxv2df3"
    935   [(set (match_operand:V2DF            0 "register_operand" "=v")
    936 	(smax:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    937 		   (match_operand:V2DF 2 "register_operand"  "v")))]
    938   "TARGET_VX"
    939   "#"
    940   ""
    941   [(set (match_dup 3)
    942 	(gt:V2DI (match_dup 1) (match_dup 2)))
    943    (set (match_dup 0)
    944 	(if_then_else:V2DF
    945 	 (eq (match_dup 3) (match_dup 4))
    946 	 (match_dup 2)
    947 	 (match_dup 1)))]
    948 {
    949   operands[3] = gen_reg_rtx (V2DImode);
    950   operands[4] = CONST0_RTX (V2DImode);
    951 })
    952 
    953 ; Emulate with compare + select
    954 (define_insn_and_split "sminv2df3"
    955   [(set (match_operand:V2DF            0 "register_operand" "=v")
    956 	(smin:V2DF (match_operand:V2DF 1 "register_operand" "%v")
    957 		   (match_operand:V2DF 2 "register_operand"  "v")))]
    958   "TARGET_VX"
    959   "#"
    960   ""
    961   [(set (match_dup 3)
    962 	(gt:V2DI (match_dup 1) (match_dup 2)))
    963    (set (match_dup 0)
    964 	(if_then_else:V2DF
    965 	 (eq (match_dup 3) (match_dup 4))
    966 	 (match_dup 1)
    967 	 (match_dup 2)))]
    968 {
    969   operands[3] = gen_reg_rtx (V2DImode);
    970   operands[4] = CONST0_RTX (V2DImode);
    971 })
    972 
    973 
    974 ;;
    975 ;; Integer compares
    976 ;;
    977 
    978 (define_insn "*vec_cmp<VICMP_HW_OP:code><VI:mode>_nocc"
    979   [(set (match_operand:VI                 2 "register_operand" "=v")
    980 	(VICMP_HW_OP:VI (match_operand:VI 0 "register_operand"  "v")
    981 			(match_operand:VI 1 "register_operand"  "v")))]
    982   "TARGET_VX"
    983   "vc<VICMP_HW_OP:insn_cmp_op><VI:bhfgq>\t%v2,%v0,%v1"
    984   [(set_attr "op_type" "VRR")])
    985 
    986 
    987 ;;
    988 ;; Floating point compares
    989 ;;
    990 
    991 ; EQ, GT, GE
    992 (define_insn "*vec_cmp<VFCMP_HW_OP:code>v2df_nocc"
    993   [(set (match_operand:V2DI                   0 "register_operand" "=v")
    994 	(VFCMP_HW_OP:V2DI (match_operand:V2DF 1 "register_operand"  "v")
    995 			  (match_operand:V2DF 2 "register_operand"  "v")))]
    996    "TARGET_VX"
    997    "vfc<VFCMP_HW_OP:asm_fcmp_op>db\t%v0,%v1,%v2"
    998   [(set_attr "op_type" "VRR")])
    999 
   1000 ; Expanders for not directly supported comparisons
   1001 
   1002 ; UNEQ a u== b -> !(a > b | b > a)
   1003 (define_expand "vec_cmpuneqv2df"
   1004   [(set (match_operand:V2DI          0 "register_operand" "=v")
   1005 	(gt:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1006 		 (match_operand:V2DF 2 "register_operand"  "v")))
   1007    (set (match_dup 3)
   1008 	(gt:V2DI (match_dup 2) (match_dup 1)))
   1009    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
   1010    (set (match_dup 0) (not:V2DI (match_dup 0)))]
   1011   "TARGET_VX"
   1012 {
   1013   operands[3] = gen_reg_rtx (V2DImode);
   1014 })
   1015 
   1016 ; LTGT a <> b -> a > b | b > a
   1017 (define_expand "vec_cmpltgtv2df"
   1018   [(set (match_operand:V2DI          0 "register_operand" "=v")
   1019 	(gt:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1020 		 (match_operand:V2DF 2 "register_operand"  "v")))
   1021    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
   1022    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
   1023   "TARGET_VX"
   1024 {
   1025   operands[3] = gen_reg_rtx (V2DImode);
   1026 })
   1027 
   1028 ; ORDERED (a, b): a >= b | b > a
   1029 (define_expand "vec_orderedv2df"
   1030   [(set (match_operand:V2DI          0 "register_operand" "=v")
   1031 	(ge:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1032 		 (match_operand:V2DF 2 "register_operand"  "v")))
   1033    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
   1034    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
   1035   "TARGET_VX"
   1036 {
   1037   operands[3] = gen_reg_rtx (V2DImode);
   1038 })
   1039 
   1040 ; UNORDERED (a, b): !ORDERED (a, b)
   1041 (define_expand "vec_unorderedv2df"
   1042   [(set (match_operand:V2DI          0 "register_operand" "=v")
   1043 	(ge:V2DI (match_operand:V2DF 1 "register_operand"  "v")
   1044 		 (match_operand:V2DF 2 "register_operand"  "v")))
   1045    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
   1046    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
   1047    (set (match_dup 0) (not:V2DI (match_dup 0)))]
   1048   "TARGET_VX"
   1049 {
   1050   operands[3] = gen_reg_rtx (V2DImode);
   1051 })
   1052 
   1053 (define_insn "*vec_load_pairv2di"
   1054   [(set (match_operand:V2DI                0 "register_operand" "=v")
   1055 	(vec_concat:V2DI (match_operand:DI 1 "register_operand"  "d")
   1056 			 (match_operand:DI 2 "register_operand"  "d")))]
   1057   "TARGET_VX"
   1058   "vlvgp\t%v0,%1,%2"
   1059   [(set_attr "op_type" "VRR")])
   1060 
   1061 (define_insn "vllv16qi"
   1062   [(set (match_operand:V16QI              0 "register_operand" "=v")
   1063 	(unspec:V16QI [(match_operand:SI  1 "register_operand"  "d")
   1064 		       (match_operand:BLK 2 "memory_operand"    "Q")]
   1065 		      UNSPEC_VEC_LOAD_LEN))]
   1066   "TARGET_VX"
   1067   "vll\t%v0,%1,%2"
   1068   [(set_attr "op_type" "VRS")])
   1069 
   1070 ; vfenebs, vfenehs, vfenefs
   1071 ; vfenezbs, vfenezhs, vfenezfs
   1072 (define_insn "vec_vfenes<mode>"
   1073   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
   1074 	(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
   1075 			   (match_operand:VI_HW_QHS 2 "register_operand" "v")
   1076 			   (match_operand:QI 3 "const_mask_operand" "C")]
   1077 			  UNSPEC_VEC_VFENE))
   1078    (set (reg:CCRAW CC_REGNUM)
   1079 	(unspec:CCRAW [(match_dup 1)
   1080 		       (match_dup 2)
   1081 		       (match_dup 3)]
   1082 		      UNSPEC_VEC_VFENECC))]
   1083   "TARGET_VX"
   1084 {
   1085   unsigned HOST_WIDE_INT flags = INTVAL (operands[3]);
   1086 
   1087   gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
   1088   flags &= ~VSTRING_FLAG_CS;
   1089 
   1090   if (flags == VSTRING_FLAG_ZS)
   1091     return "vfenez<bhfgq>s\t%v0,%v1,%v2";
   1092   return "vfene<bhfgq>s\t%v0,%v1,%v2";
   1093 }
   1094   [(set_attr "op_type" "VRR")])
   1095 
   1096 
   1097 ; Vector select
   1098 
   1099 ; The following splitters simplify vec_sel for constant 0 or -1
   1100 ; selection sources.  This is required to generate efficient code for
   1101 ; vcond.
   1102 
   1103 ; a = b == c;
   1104 (define_split
   1105   [(set (match_operand:V 0 "register_operand" "")
   1106 	(if_then_else:V
   1107 	 (eq (match_operand:<tointvec> 3 "register_operand" "")
   1108 	     (match_operand:V 4 "const0_operand" ""))
   1109 	 (match_operand:V 1 "const0_operand" "")
   1110 	 (match_operand:V 2 "all_ones_operand" "")))]
   1111   "TARGET_VX"
   1112   [(set (match_dup 0) (match_dup 3))]
   1113 {
   1114   PUT_MODE (operands[3], <V:MODE>mode);
   1115 })
   1116 
   1117 ; a = ~(b == c)
   1118 (define_split
   1119   [(set (match_operand:V 0 "register_operand" "")
   1120 	(if_then_else:V
   1121 	 (eq (match_operand:<tointvec> 3 "register_operand" "")
   1122 	     (match_operand:V 4 "const0_operand" ""))
   1123 	 (match_operand:V 1 "all_ones_operand" "")
   1124 	 (match_operand:V 2 "const0_operand" "")))]
   1125   "TARGET_VX"
   1126   [(set (match_dup 0) (not:V (match_dup 3)))]
   1127 {
   1128   PUT_MODE (operands[3], <V:MODE>mode);
   1129 })
   1130 
   1131 ; a = b != c
   1132 (define_split
   1133   [(set (match_operand:V 0 "register_operand" "")
   1134 	(if_then_else:V
   1135 	 (ne (match_operand:<tointvec> 3 "register_operand" "")
   1136 	     (match_operand:V 4 "const0_operand" ""))
   1137 	 (match_operand:V 1 "all_ones_operand" "")
   1138 	 (match_operand:V 2 "const0_operand" "")))]
   1139   "TARGET_VX"
   1140   [(set (match_dup 0) (match_dup 3))]
   1141 {
   1142   PUT_MODE (operands[3], <V:MODE>mode);
   1143 })
   1144 
   1145 ; a = ~(b != c)
   1146 (define_split
   1147   [(set (match_operand:V 0 "register_operand" "")
   1148 	(if_then_else:V
   1149 	 (ne (match_operand:<tointvec> 3 "register_operand" "")
   1150 	     (match_operand:V 4 "const0_operand" ""))
   1151 	 (match_operand:V 1 "const0_operand" "")
   1152 	 (match_operand:V 2 "all_ones_operand" "")))]
   1153   "TARGET_VX"
   1154   [(set (match_dup 0) (not:V (match_dup 3)))]
   1155 {
   1156   PUT_MODE (operands[3], <V:MODE>mode);
   1157 })
   1158 
   1159 ; op0 = op3 == 0 ? op1 : op2
   1160 (define_insn "*vec_sel0<mode>"
   1161   [(set (match_operand:V 0 "register_operand" "=v")
   1162 	(if_then_else:V
   1163 	 (eq (match_operand:<tointvec> 3 "register_operand" "v")
   1164 	     (match_operand:<tointvec> 4 "const0_operand" ""))
   1165 	 (match_operand:V 1 "register_operand" "v")
   1166 	 (match_operand:V 2 "register_operand" "v")))]
   1167   "TARGET_VX"
   1168   "vsel\t%v0,%2,%1,%3"
   1169   [(set_attr "op_type" "VRR")])
   1170 
   1171 ; op0 = !op3 == 0 ? op1 : op2
   1172 (define_insn "*vec_sel0<mode>"
   1173   [(set (match_operand:V 0 "register_operand" "=v")
   1174 	(if_then_else:V
   1175 	 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
   1176 	     (match_operand:<tointvec> 4 "const0_operand" ""))
   1177 	 (match_operand:V 1 "register_operand" "v")
   1178 	 (match_operand:V 2 "register_operand" "v")))]
   1179   "TARGET_VX"
   1180   "vsel\t%v0,%1,%2,%3"
   1181   [(set_attr "op_type" "VRR")])
   1182 
   1183 ; op0 = op3 == -1 ? op1 : op2
   1184 (define_insn "*vec_sel1<mode>"
   1185   [(set (match_operand:V 0 "register_operand" "=v")
   1186 	(if_then_else:V
   1187 	 (eq (match_operand:<tointvec> 3 "register_operand" "v")
   1188 	     (match_operand:<tointvec> 4 "all_ones_operand" ""))
   1189 	 (match_operand:V 1 "register_operand" "v")
   1190 	 (match_operand:V 2 "register_operand" "v")))]
   1191   "TARGET_VX"
   1192   "vsel\t%v0,%1,%2,%3"
   1193   [(set_attr "op_type" "VRR")])
   1194 
   1195 ; op0 = !op3 == -1 ? op1 : op2
   1196 (define_insn "*vec_sel1<mode>"
   1197   [(set (match_operand:V 0 "register_operand" "=v")
   1198 	(if_then_else:V
   1199 	 (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
   1200 	     (match_operand:<tointvec> 4 "all_ones_operand" ""))
   1201 	 (match_operand:V 1 "register_operand" "v")
   1202 	 (match_operand:V 2 "register_operand" "v")))]
   1203   "TARGET_VX"
   1204   "vsel\t%v0,%2,%1,%3"
   1205   [(set_attr "op_type" "VRR")])
   1206 
   1207 
   1208 
   1209 ; reduc_smin
   1210 ; reduc_smax
   1211 ; reduc_umin
   1212 ; reduc_umax
   1213 
   1214 ; vec_shl vrep + vsl
   1215 ; vec_shr
   1216 
   1217 ; vec_pack_trunc
   1218 ; vec_pack_ssat
   1219 ; vec_pack_usat
   1220 ; vec_pack_sfix_trunc
   1221 ; vec_pack_ufix_trunc
   1222 ; vec_unpacks_hi
   1223 ; vec_unpacks_low
   1224 ; vec_unpacku_hi
   1225 ; vec_unpacku_low
   1226 ; vec_unpacks_float_hi
   1227 ; vec_unpacks_float_lo
   1228 ; vec_unpacku_float_hi
   1229 ; vec_unpacku_float_lo
   1230