S/390: Enable vrepi constants.
[official-gcc.git] / gcc / config / s390 / vector.md
blob9c1e6a6bd0ea36cc89b87f14c8447685695840d4
1 ;;- Instruction patterns for the System z vector facility
2 ;;  Copyright (C) 2015 Free Software Foundation, Inc.
3 ;;  Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
5 ;; This file is part of GCC.
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.
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.
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/>.
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])
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])
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])
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  [V2QI V4QI V8QI V16QI V2HI V4HI V8HI V2SI V4SI V2DI])
47 (define_mode_iterator VI_QHS [V4QI V8QI V16QI V4HI V8HI V4SI])
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])
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 "*")])
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")])
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")])
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 "")])
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")])
102 ; Vector with doubled element size.
103 (define_mode_attr vec_double [(V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI")
104                               (V2HI "V1SI") (V4HI "V2SI") (V8HI "V4SI")
105                               (V2SI "V1DI") (V4SI "V2DI")
106                               (V2DI "V1TI")
107                               (V2SF "V1DF") (V4SF "V2DF")])
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")])
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")])
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")])
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
136 (include "vx-builtins.md")
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,*")])
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))]
167   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
168   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
171 ; Moves for smaller vector modes.
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.
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")])
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")])
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")])
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")])
306 ; vec_load_lanes?
308 ; vec_store_lanes?
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:DI        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")])
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")
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")])
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"
356   s390_expand_vec_init (operands[0], operands[1]);
357   DONE;
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 "immediate_operand" "C")]))))]
368   "TARGET_VX"
369   "vrep<bhfgq>\t%v0,%v1,%2"
370   [(set_attr "op_type" "VRI")])
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,*")])
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)]))))]
398   operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1);
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)"
411   s390_expand_vcond (operands[0], operands[1], operands[2],
412                      GET_CODE (operands[3]), operands[4], operands[5]);
413   DONE;
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)"
426   s390_expand_vcond (operands[0], operands[1], operands[2],
427                      GET_CODE (operands[3]), operands[4], operands[5]);
428   DONE;
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")])
443 ; vec_perm_const for V2DI using vpdi?
446 ;; Vector integer arithmetic instructions
449 ; vab, vah, vaf, vag, vaq
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 "nonimmediate_operand"  "v")))]
458   "TARGET_VX"
459   "va<bhfgq>\t%v0,%v1,%v2"
460   [(set_attr "op_type" "VRR")])
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 "nonimmediate_operand"  "v")))]
467   "TARGET_VX"
468   "vs<bhfgq>\t%v0,%v1,%v2"
469   [(set_attr "op_type" "VRR")])
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")])
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")])
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")])
497 ; Vector sum across
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")])
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")])
522 ;; Vector bit instructions (int + fp)
525 ; Vector and
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")])
536 ; Vector or
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")])
547 ; Vector xor
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")])
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")])
566 ; Vector population count
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")])
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).
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)))
614   "TARGET_VX"
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);
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"
631   operands[2] = gen_reg_rtx (V16QImode);
632   operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode));
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"
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));
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")])
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")])
670 ; Vector rotate instructions
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")])
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")])
693 ; Shift each element by scalar value
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")])
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")])
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")])
723 ; Shift each element by corresponding vector element
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")])
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")])
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")])
752 ; Vector shift right logical by byte
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
841 ; vec_widen_umult_hi
842 ; vec_widen_umult_lo
843 ; vec_widen_smult_hi
844 ; vec_widen_smult_lo
846 ; vec_widen_ushiftl_hi
847 ; vec_widen_ushiftl_lo
848 ; vec_widen_sshiftl_hi
849 ; vec_widen_sshiftl_lo
852 ;; Vector floating point arithmetic instructions
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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)))]
949   operands[3] = gen_reg_rtx (V2DImode);
950   operands[4] = CONST0_RTX (V2DImode);
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)))]
969   operands[3] = gen_reg_rtx (V2DImode);
970   operands[4] = CONST0_RTX (V2DImode);
975 ;; Integer compares
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")])
988 ;; Floating point compares
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")])
1000 ; Expanders for not directly supported comparisons
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"
1013   operands[3] = gen_reg_rtx (V2DImode);
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"
1025   operands[3] = gen_reg_rtx (V2DImode);
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"
1037   operands[3] = gen_reg_rtx (V2DImode);
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"
1050   operands[3] = gen_reg_rtx (V2DImode);
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")])
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")])
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 "immediate_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"
1085   unsigned HOST_WIDE_INT flags = INTVAL (operands[3]);
1087   gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
1088   flags &= ~VSTRING_FLAG_CS;
1090   if (flags == VSTRING_FLAG_ZS)
1091     return "vfenez<bhfgq>s\t%v0,%v1,%v2";
1092   return "vfene<bhfgq>s\t%v0,%v1,%v2";
1094   [(set_attr "op_type" "VRR")])
1097 ; Vector select
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.
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 "constm1_operand" "")))]
1111   "TARGET_VX"
1112   [(set (match_dup 0) (match_dup 3))]
1114   PUT_MODE (operands[3], <V:MODE>mode);
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 "constm1_operand" "")
1124          (match_operand:V 2 "const0_operand" "")))]
1125   "TARGET_VX"
1126   [(set (match_dup 0) (not:V (match_dup 3)))]
1128   PUT_MODE (operands[3], <V:MODE>mode);
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 "constm1_operand" "")
1138          (match_operand:V 2 "const0_operand" "")))]
1139   "TARGET_VX"
1140   [(set (match_dup 0) (match_dup 3))]
1142   PUT_MODE (operands[3], <V:MODE>mode);
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 "constm1_operand" "")))]
1153   "TARGET_VX"
1154   [(set (match_dup 0) (not:V (match_dup 3)))]
1156   PUT_MODE (operands[3], <V:MODE>mode);
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")])
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")])
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 "constm1_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")])
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 "constm1_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")])
1209 ; reduc_smin
1210 ; reduc_smax
1211 ; reduc_umin
1212 ; reduc_umax
1214 ; vec_shl vrep + vsl
1215 ; vec_shr
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