S/390: Improve support of 128 bit vectors in GPRs
[official-gcc.git] / gcc / config / s390 / vector.md
blob38905e86b099fbeff9d2d22b87af1942c54ea864
1 ;;- Instruction patterns for the System z vector facility
2 ;;  Copyright (C) 2015-2017 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_HSD [V8HI  V4SI V2DI])
42 (define_mode_iterator VI_HW_HS  [V8HI  V4SI])
43 (define_mode_iterator VI_HW_QH  [V16QI V8HI])
45 ; All integer vector modes supported in a vector register + TImode
46 (define_mode_iterator VIT [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1TI TI])
47 (define_mode_iterator VI  [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI])
48 (define_mode_iterator VI_QHS [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI])
50 (define_mode_iterator V_8   [V1QI])
51 (define_mode_iterator V_16  [V2QI  V1HI])
52 (define_mode_iterator V_32  [V4QI  V2HI V1SI V1SF])
53 (define_mode_iterator V_64  [V8QI  V4HI V2SI V2SF V1DI V1DF])
54 (define_mode_iterator V_128 [V16QI V8HI V4SI V4SF V2DI V2DF V1TI V1TF])
56 ; A blank for vector modes and a * for TImode.  This is used to hide
57 ; the TImode expander name in case it is defined already.  See addti3
58 ; for an example.
59 (define_mode_attr ti* [(V1QI "") (V2QI "") (V4QI "") (V8QI "") (V16QI "")
60                        (V1HI "") (V2HI "") (V4HI "") (V8HI "")
61                        (V1SI "") (V2SI "") (V4SI "")
62                        (V1DI "") (V2DI "")
63                        (V1TI "*") (TI "*")])
65 ; The element type of the vector.
66 (define_mode_attr non_vec[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
67                           (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
68                           (V1SI "SI") (V2SI "SI") (V4SI "SI")
69                           (V1DI "DI") (V2DI "DI")
70                           (V1TI "TI")
71                           (V1SF "SF") (V2SF "SF") (V4SF "SF")
72                           (V1DF "DF") (V2DF "DF")
73                           (V1TF "TF")])
75 ; The instruction suffix
76 (define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b")
77                         (V1HI "h") (V2HI "h") (V4HI "h") (V8HI "h")
78                         (V1SI "f") (V2SI "f") (V4SI "f")
79                         (V1DI "g") (V2DI "g")
80                         (V1TI "q") (TI "q")
81                         (V1SF "f") (V2SF "f") (V4SF "f")
82                         (V1DF "g") (V2DF "g")
83                         (V1TF "q")])
85 ; This is for vmalhw. It gets an 'w' attached to avoid confusion with
86 ; multiply and add logical high vmalh.
87 (define_mode_attr w [(V1QI "")  (V2QI "")  (V4QI "")  (V8QI "") (V16QI "")
88                      (V1HI "w") (V2HI "w") (V4HI "w") (V8HI "w")
89                      (V1SI "")  (V2SI "")  (V4SI "")
90                      (V1DI "")  (V2DI "")])
92 ; Resulting mode of a vector comparison.  For floating point modes an
93 ; integer vector mode with the same element size is picked.
94 (define_mode_attr tointvec [(V1QI "V1QI") (V2QI "V2QI") (V4QI "V4QI") (V8QI "V8QI") (V16QI "V16QI")
95                             (V1HI "V1HI") (V2HI "V2HI") (V4HI "V4HI") (V8HI "V8HI")
96                             (V1SI "V1SI") (V2SI "V2SI") (V4SI "V4SI")
97                             (V1DI "V1DI") (V2DI "V2DI")
98                             (V1TI "V1TI")
99                             (V1SF "V1SI") (V2SF "V2SI") (V4SF "V4SI")
100                             (V1DF "V1DI") (V2DF "V2DI")
101                             (V1TF "V1TI")])
103 ; Vector with doubled element size.
104 (define_mode_attr vec_double [(V1QI "V1HI") (V2QI "V1HI") (V4QI "V2HI") (V8QI "V4HI") (V16QI "V8HI")
105                               (V1HI "V1SI") (V2HI "V1SI") (V4HI "V2SI") (V8HI "V4SI")
106                               (V1SI "V1DI") (V2SI "V1DI") (V4SI "V2DI")
107                               (V1DI "V1TI") (V2DI "V1TI")
108                               (V1SF "V1DF") (V2SF "V1DF") (V4SF "V2DF")])
110 ; Vector with half the element size.
111 (define_mode_attr vec_half [(V1HI "V2QI") (V2HI "V4QI") (V4HI "V8QI") (V8HI "V16QI")
112                             (V1SI "V2HI") (V2SI "V4HI") (V4SI "V8HI")
113                             (V1DI "V2SI") (V2DI "V4SI")
114                             (V1TI "V2DI")
115                             (V1DF "V2SF") (V2DF "V4SF")
116                             (V1TF "V1DF")])
118 ; Vector with half the element size AND half the number of elements.
119 (define_mode_attr vec_halfhalf
120   [(V2HI "V2QI") (V4HI "V4QI") (V8HI "V8QI")
121    (V2SI "V2HI") (V4SI "V4HI")
122    (V2DI "V2SI")
123    (V2DF "V2SF")])
125 ; The comparisons not setting CC iterate over the rtx code.
126 (define_code_iterator VFCMP_HW_OP [eq gt ge])
127 (define_code_attr asm_fcmp_op [(eq "e") (gt "h") (ge "he")])
131 ; Comparison operators on int and fp compares which are directly
132 ; supported by the HW.
133 (define_code_iterator VICMP_HW_OP [eq gt gtu])
134 ; For int insn_cmp_op can be used in the insn name as well as in the asm output.
135 (define_code_attr insn_cmp_op [(eq "eq") (gt "h") (gtu "hl") (ge "he")])
137 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4)
138 (define_constants
139   [(VSTRING_FLAG_IN         8)   ; invert result
140    (VSTRING_FLAG_RT         4)   ; result type
141    (VSTRING_FLAG_ZS         2)   ; zero search
142    (VSTRING_FLAG_CS         1)]) ; condition code set
144 (include "vx-builtins.md")
146 ; Full HW vector size moves
148 ; We don't use lm/stm for 128 bit moves since these are slower than
149 ; splitting it into separate moves.
151 ; FIXME: More constants are possible by enabling jxx, jyy constraints
152 ; for TImode (use double-int for the calculations)
154 ; vgmb, vgmh, vgmf, vgmg, vrepib, vrepih, vrepif, vrepig
155 (define_insn "mov<mode>"
156   [(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R,  v,  v,  v,  v,  v,v,*d,*d,?o")
157         (match_operand:V_128 1 "general_operand"      " v,R,v,j00,jm1,jyy,jxx,jKK,d, v,dT,*d"))]
158   ""
159   "@
160    vlr\t%v0,%v1
161    vl\t%v0,%1
162    vst\t%v1,%0
163    vzero\t%v0
164    vone\t%v0
165    vgbm\t%v0,%t1
166    vgm<bhfgq>\t%v0,%s1,%e1
167    vrepi<bhfgq>\t%v0,%h1
168    vlvgp\t%v0,%1,%N1
169    #
170    #
171    #"
172   [(set_attr "cpu_facility" "vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*")
173    (set_attr "op_type"      "VRR,VRX,VRX,VRI,VRI,VRI,VRI,VRI,VRR,*,*,*")])
175 ; VR -> GPR, no instruction so split it into 64 element sets.
176 (define_split
177   [(set (match_operand:V_128 0 "register_operand" "")
178         (match_operand:V_128 1 "register_operand" ""))]
179   "TARGET_VX && GENERAL_REG_P (operands[0]) && VECTOR_REG_P (operands[1])"
180   [(set (match_dup 2)
181         (unspec:DI [(subreg:V2DI (match_dup 1) 0)
182                     (const_int 0)] UNSPEC_VEC_EXTRACT))
183    (set (match_dup 3)
184         (unspec:DI [(subreg:V2DI (match_dup 1) 0)
185                     (const_int 1)] UNSPEC_VEC_EXTRACT))]
187   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
188   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
191 ; Split the 128 bit GPR move into two word mode moves
192 ; s390_split_ok_p decides which part needs to be moved first.
194 (define_split
195   [(set (match_operand:V_128 0 "nonimmediate_operand" "")
196         (match_operand:V_128 1 "general_operand" ""))]
197   "reload_completed
198    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
199   [(set (match_dup 2) (match_dup 4))
200    (set (match_dup 3) (match_dup 5))]
202   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
203   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
204   operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
205   operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
208 (define_split
209   [(set (match_operand:V_128 0 "nonimmediate_operand" "")
210         (match_operand:V_128 1 "general_operand" ""))]
211   "reload_completed
212    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
213   [(set (match_dup 2) (match_dup 4))
214    (set (match_dup 3) (match_dup 5))]
216   operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
217   operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
218   operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
219   operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
223 ; Moves for smaller vector modes.
225 ; In these patterns only the vlr, vone, and vzero instructions write
226 ; VR bytes outside the mode.  This should be ok since we disallow
227 ; formerly bigger modes being accessed with smaller modes via
228 ; subreg. Note: The vone, vzero instructions could easily be replaced
229 ; with vlei which would only access the bytes belonging to the mode.
230 ; However, this would probably be slower.
232 (define_insn "mov<mode>"
233   [(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  v,d,  Q,  S,  Q,  S,  d,  d,d,d,d,R,T")
234         (match_operand:V_8 1 "general_operand"      " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
235   ""
236   "@
237    vlr\t%v0,%v1
238    vlvgb\t%v0,%1,0
239    vlgvb\t%0,%v1,0
240    vleb\t%v0,%1,0
241    vsteb\t%v1,%0,0
242    vzero\t%v0
243    vone\t%v0
244    vgbm\t%v0,%t1
245    vgm\t%v0,%s1,%e1
246    lr\t%0,%1
247    mvi\t%0,0
248    mviy\t%0,0
249    mvi\t%0,-1
250    mviy\t%0,-1
251    lhi\t%0,0
252    lhi\t%0,-1
253    lh\t%0,%1
254    lhy\t%0,%1
255    lhrl\t%0,%1
256    stc\t%1,%0
257    stcy\t%1,%0"
258   [(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")])
260 (define_insn "mov<mode>"
261   [(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R,  v,  v,  v,  v,d,  Q,  Q,  d,  d,d,d,d,R,T,b")
262         (match_operand:V_16 1 "general_operand"      " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
263   ""
264   "@
265    vlr\t%v0,%v1
266    vlvgh\t%v0,%1,0
267    vlgvh\t%0,%v1,0
268    vleh\t%v0,%1,0
269    vsteh\t%v1,%0,0
270    vzero\t%v0
271    vone\t%v0
272    vgbm\t%v0,%t1
273    vgm\t%v0,%s1,%e1
274    lr\t%0,%1
275    mvhhi\t%0,0
276    mvhhi\t%0,-1
277    lhi\t%0,0
278    lhi\t%0,-1
279    lh\t%0,%1
280    lhy\t%0,%1
281    lhrl\t%0,%1
282    sth\t%1,%0
283    sthy\t%1,%0
284    sthrl\t%1,%0"
285   [(set_attr "op_type"      "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
287 (define_insn "mov<mode>"
288   [(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R,  f,  v,  v,  v,  v,  Q,  Q,  d,  d,d,d,d,d,R,T,b")
289         (match_operand:V_32 1 "general_operand"      " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
290   "TARGET_VX"
291   "@
292    ldr\t%v0,%v1
293    lde\t%0,%1
294    ley\t%0,%1
295    ste\t%1,%0
296    stey\t%1,%0
297    vlr\t%v0,%v1
298    vlvgf\t%v0,%1,0
299    vlgvf\t%0,%v1,0
300    vlef\t%v0,%1,0
301    vstef\t%1,%0,0
302    lzer\t%v0
303    vzero\t%v0
304    vone\t%v0
305    vgbm\t%v0,%t1
306    vgm\t%v0,%s1,%e1
307    mvhi\t%0,0
308    mvhi\t%0,-1
309    lhi\t%0,0
310    lhi\t%0,-1
311    lrl\t%0,%1
312    lr\t%0,%1
313    l\t%0,%1
314    ly\t%0,%1
315    st\t%1,%0
316    sty\t%1,%0
317    strl\t%1,%0"
318   [(set_attr "op_type" "RR,RXE,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,SIL,SIL,RI,RI,
319                         RIL,RR,RX,RXY,RX,RXY,RIL")])
321 (define_insn "mov<mode>"
322   [(set (match_operand:V_64 0 "nonimmediate_operand"
323          "=f,f,f,R,T,v,v,d,v,R,  f,  v,  v,  v,  v,  Q,  Q,  d,  d,f,d,d,d,d,T,b")
324         (match_operand:V_64 1 "general_operand"
325          " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
326   "TARGET_ZARCH"
327   "@
328    ldr\t%0,%1
329    ld\t%0,%1
330    ldy\t%0,%1
331    std\t%1,%0
332    stdy\t%1,%0
333    vlr\t%v0,%v1
334    vlvgg\t%v0,%1,0
335    vlgvg\t%0,%v1,0
336    vleg\t%v0,%1,0
337    vsteg\t%v1,%0,0
338    lzdr\t%0
339    vzero\t%v0
340    vone\t%v0
341    vgbm\t%v0,%t1
342    vgm\t%v0,%s1,%e1
343    mvghi\t%0,0
344    mvghi\t%0,-1
345    lghi\t%0,0
346    lghi\t%0,-1
347    ldgr\t%0,%1
348    lgdr\t%0,%1
349    lgrl\t%0,%1
350    lgr\t%0,%1
351    lg\t%0,%1
352    stg\t%1,%0
353    stgrl\t%1,%0"
354   [(set_attr "op_type" "RRE,RX,RXY,RX,RXY,VRR,VRS,VRS,VRX,VRX,RRE,VRI,VRI,VRI,VRI,
355                         SIL,SIL,RI,RI,RRE,RRE,RIL,RR,RXY,RXY,RIL")])
358 ; vec_load_lanes?
360 ; vec_store_lanes?
362 ; vec_set is supposed to *modify* an existing vector so operand 0 is
363 ; duplicated as input operand.
364 (define_expand "vec_set<mode>"
365   [(set (match_operand:V                    0 "register_operand"  "")
366         (unspec:V [(match_operand:<non_vec> 1 "general_operand"   "")
367                    (match_operand:SI        2 "nonmemory_operand" "")
368                    (match_dup 0)]
369                    UNSPEC_VEC_SET))]
370   "TARGET_VX")
372 ; FIXME: Support also vector mode operands for 1
373 ; FIXME: A target memory operand seems to be useful otherwise we end
374 ; up with vl vlvgg vst.  Shouldn't the middle-end be able to handle
375 ; that itself?
376 ; vlvgb, vlvgh, vlvgf, vlvgg, vleb, vleh, vlef, vleg, vleib, vleih, vleif, vleig
377 (define_insn "*vec_set<mode>"
378   [(set (match_operand:V                    0 "register_operand"  "=v,v,v")
379         (unspec:V [(match_operand:<non_vec> 1 "general_operand"    "d,R,K")
380                    (match_operand:SI        2 "nonmemory_operand" "an,I,I")
381                    (match_operand:V         3 "register_operand"   "0,0,0")]
382                   UNSPEC_VEC_SET))]
383   "TARGET_VX
384    && (!CONST_INT_P (operands[2])
385        || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
386   "@
387    vlvg<bhfgq>\t%v0,%1,%Y2
388    vle<bhfgq>\t%v0,%1,%2
389    vlei<bhfgq>\t%v0,%1,%2"
390   [(set_attr "op_type" "VRS,VRX,VRI")])
392 ; vlvgb, vlvgh, vlvgf, vlvgg
393 (define_insn "*vec_set<mode>_plus"
394   [(set (match_operand:V                      0 "register_operand" "=v")
395         (unspec:V [(match_operand:<non_vec>   1 "general_operand"   "d")
396                    (plus:SI (match_operand:SI 2 "register_operand"  "a")
397                             (match_operand:SI 4 "const_int_operand" "n"))
398                    (match_operand:V           3 "register_operand"  "0")]
399                   UNSPEC_VEC_SET))]
400   "TARGET_VX"
401   "vlvg<bhfgq>\t%v0,%1,%Y4(%2)"
402   [(set_attr "op_type" "VRS")])
405 ; FIXME: Support also vector mode operands for 0
406 ; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :(
407 ; This is used via RTL standard name as well as for expanding the builtin
408 (define_expand "vec_extract<mode>"
409   [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "")
410         (unspec:<non_vec> [(match_operand:V  1 "register_operand" "")
411                            (match_operand:SI 2 "nonmemory_operand" "")]
412                           UNSPEC_VEC_EXTRACT))]
413   "TARGET_VX")
415 ; vlgvb, vlgvh, vlgvf, vlgvg, vsteb, vsteh, vstef, vsteg
416 (define_insn "*vec_extract<mode>"
417   [(set (match_operand:<non_vec> 0 "nonimmediate_operand"          "=d,R")
418         (unspec:<non_vec> [(match_operand:V  1 "register_operand"   "v,v")
419                            (match_operand:SI 2 "nonmemory_operand" "an,I")]
420                           UNSPEC_VEC_EXTRACT))]
421   "TARGET_VX
422    && (!CONST_INT_P (operands[2])
423        || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
424   "@
425    vlgv<bhfgq>\t%0,%v1,%Y2
426    vste<bhfgq>\t%v1,%0,%2"
427   [(set_attr "op_type" "VRS,VRX")])
429 ; vlgvb, vlgvh, vlgvf, vlgvg
430 (define_insn "*vec_extract<mode>_plus"
431   [(set (match_operand:<non_vec>                      0 "nonimmediate_operand" "=d")
432         (unspec:<non_vec> [(match_operand:V           1 "register_operand"      "v")
433                            (plus:SI (match_operand:SI 2 "nonmemory_operand"     "a")
434                                     (match_operand:SI 3 "const_int_operand"     "n"))]
435                            UNSPEC_VEC_EXTRACT))]
436   "TARGET_VX"
437   "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
438   [(set_attr "op_type" "VRS")])
440 (define_expand "vec_init<V_HW:mode>"
441   [(match_operand:V_HW 0 "register_operand" "")
442    (match_operand:V_HW 1 "nonmemory_operand" "")]
443   "TARGET_VX"
445   s390_expand_vec_init (operands[0], operands[1]);
446   DONE;
449 ; Replicate from vector element
450 ; vrepb, vreph, vrepf, vrepg
451 (define_insn "*vec_splat<mode>"
452   [(set (match_operand:V_HW   0 "register_operand" "=v")
453         (vec_duplicate:V_HW
454          (vec_select:<non_vec>
455           (match_operand:V_HW 1 "register_operand"  "v")
456           (parallel
457            [(match_operand:QI 2 "const_mask_operand" "C")]))))]
458   "TARGET_VX && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW:MODE>mode)"
459   "vrep<bhfgq>\t%v0,%v1,%2"
460   [(set_attr "op_type" "VRI")])
462 ; vlrepb, vlreph, vlrepf, vlrepg, vrepib, vrepih, vrepif, vrepig, vrepb, vreph, vrepf, vrepg
463 (define_insn "*vec_splats<mode>"
464   [(set (match_operand:V_HW                          0 "register_operand" "=v,v,v,v")
465         (vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand"  " R,K,v,d")))]
466   "TARGET_VX"
467   "@
468    vlrep<bhfgq>\t%v0,%1
469    vrepi<bhfgq>\t%v0,%h1
470    vrep<bhfgq>\t%v0,%v1,0
471    #"
472   [(set_attr "op_type" "VRX,VRI,VRI,*")])
474 ; vec_splats is supposed to replicate op1 into all elements of op0
475 ; This splitter first sets the rightmost element of op0 to op1 and
476 ; then does a vec_splat to replicate that element into all other
477 ; elements.
478 (define_split
479   [(set (match_operand:V_HW                          0 "register_operand" "")
480         (vec_duplicate:V_HW (match_operand:<non_vec> 1 "register_operand" "")))]
481   "TARGET_VX && GENERAL_REG_P (operands[1])"
482   [(set (match_dup 0)
483         (unspec:V_HW [(match_dup 1) (match_dup 2) (match_dup 0)] UNSPEC_VEC_SET))
484    (set (match_dup 0)
485         (vec_duplicate:V_HW
486          (vec_select:<non_vec>
487           (match_dup 0) (parallel [(match_dup 2)]))))]
489   operands[2] = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1);
492 (define_expand "vcond<V_HW:mode><V_HW2:mode>"
493   [(set (match_operand:V_HW 0 "register_operand" "")
494         (if_then_else:V_HW
495          (match_operator 3 "comparison_operator"
496                          [(match_operand:V_HW2 4 "register_operand" "")
497                           (match_operand:V_HW2 5 "nonmemory_operand" "")])
498          (match_operand:V_HW 1 "nonmemory_operand" "")
499          (match_operand:V_HW 2 "nonmemory_operand" "")))]
500   "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
502   s390_expand_vcond (operands[0], operands[1], operands[2],
503                      GET_CODE (operands[3]), operands[4], operands[5]);
504   DONE;
507 (define_expand "vcondu<V_HW:mode><V_HW2:mode>"
508   [(set (match_operand:V_HW 0 "register_operand" "")
509         (if_then_else:V_HW
510          (match_operator 3 "comparison_operator"
511                          [(match_operand:V_HW2 4 "register_operand" "")
512                           (match_operand:V_HW2 5 "nonmemory_operand" "")])
513          (match_operand:V_HW 1 "nonmemory_operand" "")
514          (match_operand:V_HW 2 "nonmemory_operand" "")))]
515   "TARGET_VX && GET_MODE_NUNITS (<V_HW:MODE>mode) == GET_MODE_NUNITS (<V_HW2:MODE>mode)"
517   s390_expand_vcond (operands[0], operands[1], operands[2],
518                      GET_CODE (operands[3]), operands[4], operands[5]);
519   DONE;
522 ; We only have HW support for byte vectors.  The middle-end is
523 ; supposed to lower the mode if required.
524 (define_insn "vec_permv16qi"
525   [(set (match_operand:V16QI 0 "register_operand"               "=v")
526         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
527                        (match_operand:V16QI 2 "register_operand" "v")
528                        (match_operand:V16QI 3 "register_operand" "v")]
529                       UNSPEC_VEC_PERM))]
530   "TARGET_VX"
531   "vperm\t%v0,%v1,%v2,%v3"
532   [(set_attr "op_type" "VRR")])
534 ; vec_perm_const for V2DI using vpdi?
537 ;; Vector integer arithmetic instructions
540 ; vab, vah, vaf, vag, vaq
542 ; We use nonimmediate_operand instead of register_operand since it is
543 ; better to have the reloads into VRs instead of splitting the
544 ; operation into two DImode ADDs.
545 (define_insn "<ti*>add<mode>3"
546   [(set (match_operand:VIT           0 "nonimmediate_operand" "=v")
547         (plus:VIT (match_operand:VIT 1 "nonimmediate_operand" "%v")
548                   (match_operand:VIT 2 "general_operand"       "v")))]
549   "TARGET_VX"
550   "va<bhfgq>\t%v0,%v1,%v2"
551   [(set_attr "op_type" "VRR")])
553 ; vsb, vsh, vsf, vsg, vsq
554 (define_insn "<ti*>sub<mode>3"
555   [(set (match_operand:VIT            0 "nonimmediate_operand" "=v")
556         (minus:VIT (match_operand:VIT 1 "nonimmediate_operand"  "v")
557                    (match_operand:VIT 2 "general_operand"  "v")))]
558   "TARGET_VX"
559   "vs<bhfgq>\t%v0,%v1,%v2"
560   [(set_attr "op_type" "VRR")])
562 ; vmlb, vmlhw, vmlf
563 (define_insn "mul<mode>3"
564   [(set (match_operand:VI_QHS              0 "register_operand" "=v")
565         (mult:VI_QHS (match_operand:VI_QHS 1 "register_operand" "%v")
566                      (match_operand:VI_QHS 2 "register_operand"  "v")))]
567   "TARGET_VX"
568   "vml<bhfgq><w>\t%v0,%v1,%v2"
569   [(set_attr "op_type" "VRR")])
571 ; vlcb, vlch, vlcf, vlcg
572 (define_insn "neg<mode>2"
573   [(set (match_operand:VI         0 "register_operand" "=v")
574         (neg:VI (match_operand:VI 1 "register_operand"  "v")))]
575   "TARGET_VX"
576   "vlc<bhfgq>\t%v0,%v1"
577   [(set_attr "op_type" "VRR")])
579 ; vlpb, vlph, vlpf, vlpg
580 (define_insn "abs<mode>2"
581   [(set (match_operand:VI         0 "register_operand" "=v")
582         (abs:VI (match_operand:VI 1 "register_operand"  "v")))]
583   "TARGET_VX"
584   "vlp<bhfgq>\t%v0,%v1"
585   [(set_attr "op_type" "VRR")])
588 ; Vector sum across
590 ; Sum across DImode parts of the 1st operand and add the rightmost
591 ; element of 2nd operand
592 ; vsumgh, vsumgf
593 (define_insn "*vec_sum2<mode>"
594   [(set (match_operand:V2DI 0 "register_operand" "=v")
595         (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "v")
596                       (match_operand:VI_HW_HS 2 "register_operand" "v")]
597                      UNSPEC_VEC_VSUMG))]
598   "TARGET_VX"
599   "vsumg<bhfgq>\t%v0,%v1,%v2"
600   [(set_attr "op_type" "VRR")])
602 ; vsumb, vsumh
603 (define_insn "*vec_sum4<mode>"
604   [(set (match_operand:V4SI 0 "register_operand" "=v")
605         (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "v")
606                       (match_operand:VI_HW_QH 2 "register_operand" "v")]
607                      UNSPEC_VEC_VSUM))]
608   "TARGET_VX"
609   "vsum<bhfgq>\t%v0,%v1,%v2"
610   [(set_attr "op_type" "VRR")])
613 ;; Vector bit instructions (int + fp)
616 ; Vector and
618 (define_insn "and<mode>3"
619   [(set (match_operand:VT         0 "register_operand" "=v")
620         (and:VT (match_operand:VT 1 "register_operand" "%v")
621                 (match_operand:VT 2 "register_operand"  "v")))]
622   "TARGET_VX"
623   "vn\t%v0,%v1,%v2"
624   [(set_attr "op_type" "VRR")])
627 ; Vector or
629 (define_insn "ior<mode>3"
630   [(set (match_operand:VT         0 "register_operand" "=v")
631         (ior:VT (match_operand:VT 1 "register_operand" "%v")
632                 (match_operand:VT 2 "register_operand"  "v")))]
633   "TARGET_VX"
634   "vo\t%v0,%v1,%v2"
635   [(set_attr "op_type" "VRR")])
638 ; Vector xor
640 (define_insn "xor<mode>3"
641   [(set (match_operand:VT         0 "register_operand" "=v")
642         (xor:VT (match_operand:VT 1 "register_operand" "%v")
643                 (match_operand:VT 2 "register_operand"  "v")))]
644   "TARGET_VX"
645   "vx\t%v0,%v1,%v2"
646   [(set_attr "op_type" "VRR")])
649 ; Bitwise inversion of a vector - used for vec_cmpne
650 (define_insn "*not<mode>"
651   [(set (match_operand:VT         0 "register_operand" "=v")
652         (not:VT (match_operand:VT 1 "register_operand"  "v")))]
653   "TARGET_VX"
654   "vnot\t%v0,%v1"
655   [(set_attr "op_type" "VRR")])
657 ; Vector population count
659 (define_insn "popcountv16qi2"
660   [(set (match_operand:V16QI                0 "register_operand" "=v")
661         (unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "v")]
662                       UNSPEC_POPCNT))]
663   "TARGET_VX"
664   "vpopct\t%v0,%v1,0"
665   [(set_attr "op_type" "VRR")])
667 ; vpopct only counts bits in byte elements.  Bigger element sizes need
668 ; to be emulated.  Word and doubleword elements can use the sum across
669 ; instructions.  For halfword sized elements we do a shift of a copy
670 ; of the result, add it to the result and extend it to halfword
671 ; element size (unpack).
673 (define_expand "popcountv8hi2"
674   [(set (match_dup 2)
675         (unspec:V16QI [(subreg:V16QI (match_operand:V8HI 1 "register_operand" "v") 0)]
676                       UNSPEC_POPCNT))
677    ; Make a copy of the result
678    (set (match_dup 3) (match_dup 2))
679    ; Generate the shift count operand in a VR (8->byte 7)
680    (set (match_dup 4) (match_dup 5))
681    (set (match_dup 4) (unspec:V16QI [(const_int 8)
682                                      (const_int 7)
683                                      (match_dup 4)] UNSPEC_VEC_SET))
684    ; Vector shift right logical by one byte
685    (set (match_dup 3)
686         (unspec:V16QI [(match_dup 3) (match_dup 4)] UNSPEC_VEC_SRLB))
687    ; Add the shifted and the original result
688    (set (match_dup 2)
689         (plus:V16QI (match_dup 2) (match_dup 3)))
690    ; Generate mask for the odd numbered byte elements
691    (set (match_dup 3)
692         (const_vector:V16QI [(const_int 0) (const_int 255)
693                              (const_int 0) (const_int 255)
694                              (const_int 0) (const_int 255)
695                              (const_int 0) (const_int 255)
696                              (const_int 0) (const_int 255)
697                              (const_int 0) (const_int 255)
698                              (const_int 0) (const_int 255)
699                              (const_int 0) (const_int 255)]))
700    ; Zero out the even indexed bytes
701    (set (match_operand:V8HI 0 "register_operand" "=v")
702         (and:V8HI (subreg:V8HI (match_dup 2) 0)
703                   (subreg:V8HI (match_dup 3) 0)))
705   "TARGET_VX"
707   operands[2] = gen_reg_rtx (V16QImode);
708   operands[3] = gen_reg_rtx (V16QImode);
709   operands[4] = gen_reg_rtx (V16QImode);
710   operands[5] = CONST0_RTX (V16QImode);
713 (define_expand "popcountv4si2"
714   [(set (match_dup 2)
715         (unspec:V16QI [(subreg:V16QI (match_operand:V4SI 1 "register_operand" "v") 0)]
716                       UNSPEC_POPCNT))
717    (set (match_operand:V4SI 0 "register_operand" "=v")
718         (unspec:V4SI [(match_dup 2) (match_dup 3)]
719                      UNSPEC_VEC_VSUM))]
720   "TARGET_VX"
722   operands[2] = gen_reg_rtx (V16QImode);
723   operands[3] = force_reg (V16QImode, CONST0_RTX (V16QImode));
726 (define_expand "popcountv2di2"
727   [(set (match_dup 2)
728         (unspec:V16QI [(subreg:V16QI (match_operand:V2DI 1 "register_operand" "v") 0)]
729                       UNSPEC_POPCNT))
730    (set (match_dup 3)
731         (unspec:V4SI [(match_dup 2) (match_dup 4)]
732                      UNSPEC_VEC_VSUM))
733    (set (match_operand:V2DI 0 "register_operand" "=v")
734         (unspec:V2DI [(match_dup 3) (match_dup 5)]
735                      UNSPEC_VEC_VSUMG))]
736   "TARGET_VX"
738   operands[2] = gen_reg_rtx (V16QImode);
739   operands[3] = gen_reg_rtx (V4SImode);
740   operands[4] = force_reg (V16QImode, CONST0_RTX (V16QImode));
741   operands[5] = force_reg (V4SImode, CONST0_RTX (V4SImode));
744 ; Count leading zeros
745 ; vclzb, vclzh, vclzf, vclzg
746 (define_insn "clz<mode>2"
747   [(set (match_operand:V        0 "register_operand" "=v")
748         (clz:V (match_operand:V 1 "register_operand"  "v")))]
749   "TARGET_VX"
750   "vclz<bhfgq>\t%v0,%v1"
751   [(set_attr "op_type" "VRR")])
753 ; Count trailing zeros
754 ; vctzb, vctzh, vctzf, vctzg
755 (define_insn "ctz<mode>2"
756   [(set (match_operand:V        0 "register_operand" "=v")
757         (ctz:V (match_operand:V 1 "register_operand"  "v")))]
758   "TARGET_VX"
759   "vctz<bhfgq>\t%v0,%v1"
760   [(set_attr "op_type" "VRR")])
764 ; Each vector element rotated by the corresponding vector element
765 ; verllvb, verllvh, verllvf, verllvg
766 (define_insn "vrotl<mode>3"
767   [(set (match_operand:VI            0 "register_operand" "=v")
768         (rotate:VI (match_operand:VI 1 "register_operand"  "v")
769                    (match_operand:VI 2 "register_operand"  "v")))]
770   "TARGET_VX"
771   "verllv<bhfgq>\t%v0,%v1,%v2"
772   [(set_attr "op_type" "VRR")])
775 ; Vector rotate and shift by scalar instructions
777 (define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate])
778 (define_code_attr vec_shifts_name [(ashift "ashl")    (ashiftrt "ashr")
779                                    (lshiftrt "lshr")  (rotate "rotl")])
780 (define_code_attr vec_shifts_mnem [(ashift "vesl")    (ashiftrt "vesra")
781                                    (lshiftrt "vesrl") (rotate "verll")])
783 ; Each vector element rotated by a scalar
784 (define_expand "<vec_shifts_name><mode>3"
785   [(set (match_operand:VI 0 "register_operand" "")
786         (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "")
787                        (match_operand:SI 2 "nonmemory_operand" "")))]
788   "TARGET_VX")
790 ; verllb, verllh, verllf, verllg
791 ; veslb,  veslh,  veslf,  veslg
792 ; vesrab, vesrah, vesraf, vesrag
793 ; vesrlb, vesrlh, vesrlf, vesrlg
794 (define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
795   [(set (match_operand:VI                0 "register_operand"  "=v")
796         (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand"   "v")
797                        (match_operand:SI 2 "nonmemory_operand" "an")))]
798   "TARGET_VX"
799   "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
800   [(set_attr "op_type" "VRS")])
802 ; Shift each element by corresponding vector element
804 ; veslvb, veslvh, veslvf, veslvg
805 (define_insn "vashl<mode>3"
806   [(set (match_operand:VI            0 "register_operand" "=v")
807         (ashift:VI (match_operand:VI 1 "register_operand"  "v")
808                    (match_operand:VI 2 "register_operand"  "v")))]
809   "TARGET_VX"
810   "veslv<bhfgq>\t%v0,%v1,%v2"
811   [(set_attr "op_type" "VRR")])
813 ; vesravb, vesravh, vesravf, vesravg
814 (define_insn "vashr<mode>3"
815   [(set (match_operand:VI              0 "register_operand" "=v")
816         (ashiftrt:VI (match_operand:VI 1 "register_operand"  "v")
817                      (match_operand:VI 2 "register_operand"  "v")))]
818   "TARGET_VX"
819   "vesrav<bhfgq>\t%v0,%v1,%v2"
820   [(set_attr "op_type" "VRR")])
822 ; vesrlvb, vesrlvh, vesrlvf, vesrlvg
823 (define_insn "vlshr<mode>3"
824   [(set (match_operand:VI              0 "register_operand" "=v")
825         (lshiftrt:VI (match_operand:VI 1 "register_operand"  "v")
826                      (match_operand:VI 2 "register_operand"  "v")))]
827   "TARGET_VX"
828   "vesrlv<bhfgq>\t%v0,%v1,%v2"
829   [(set_attr "op_type" "VRR")])
831 ; Vector shift right logical by byte
833 ; Pattern used by e.g. popcount
834 (define_insn "*vec_srb<mode>"
835   [(set (match_operand:V_HW 0 "register_operand"                    "=v")
836         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "v")
837                       (match_operand:<tointvec> 2 "register_operand" "v")]
838                      UNSPEC_VEC_SRLB))]
839   "TARGET_VX"
840   "vsrlb\t%v0,%v1,%v2"
841   [(set_attr "op_type" "VRR")])
844 ; vmnb, vmnh, vmnf, vmng
845 (define_insn "smin<mode>3"
846   [(set (match_operand:VI          0 "register_operand" "=v")
847         (smin:VI (match_operand:VI 1 "register_operand" "%v")
848                  (match_operand:VI 2 "register_operand"  "v")))]
849   "TARGET_VX"
850   "vmn<bhfgq>\t%v0,%v1,%v2"
851   [(set_attr "op_type" "VRR")])
853 ; vmxb, vmxh, vmxf, vmxg
854 (define_insn "smax<mode>3"
855   [(set (match_operand:VI          0 "register_operand" "=v")
856         (smax:VI (match_operand:VI 1 "register_operand" "%v")
857                  (match_operand:VI 2 "register_operand"  "v")))]
858   "TARGET_VX"
859   "vmx<bhfgq>\t%v0,%v1,%v2"
860   [(set_attr "op_type" "VRR")])
862 ; vmnlb, vmnlh, vmnlf, vmnlg
863 (define_insn "umin<mode>3"
864   [(set (match_operand:VI          0 "register_operand" "=v")
865         (umin:VI (match_operand:VI 1 "register_operand" "%v")
866                  (match_operand:VI 2 "register_operand"  "v")))]
867   "TARGET_VX"
868   "vmnl<bhfgq>\t%v0,%v1,%v2"
869   [(set_attr "op_type" "VRR")])
871 ; vmxlb, vmxlh, vmxlf, vmxlg
872 (define_insn "umax<mode>3"
873   [(set (match_operand:VI          0 "register_operand" "=v")
874         (umax:VI (match_operand:VI 1 "register_operand" "%v")
875                  (match_operand:VI 2 "register_operand"  "v")))]
876   "TARGET_VX"
877   "vmxl<bhfgq>\t%v0,%v1,%v2"
878   [(set_attr "op_type" "VRR")])
880 ; vmeb, vmeh, vmef
881 (define_insn "vec_widen_smult_even_<mode>"
882   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
883         (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
884                               (match_operand:VI_QHS 2 "register_operand"  "v")]
885                              UNSPEC_VEC_SMULT_EVEN))]
886   "TARGET_VX"
887   "vme<bhfgq>\t%v0,%v1,%v2"
888   [(set_attr "op_type" "VRR")])
890 ; vmleb, vmleh, vmlef
891 (define_insn "vec_widen_umult_even_<mode>"
892   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
893         (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
894                               (match_operand:VI_QHS 2 "register_operand"  "v")]
895                              UNSPEC_VEC_UMULT_EVEN))]
896   "TARGET_VX"
897   "vmle<bhfgq>\t%v0,%v1,%v2"
898   [(set_attr "op_type" "VRR")])
900 ; vmob, vmoh, vmof
901 (define_insn "vec_widen_smult_odd_<mode>"
902   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
903         (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
904                               (match_operand:VI_QHS 2 "register_operand"  "v")]
905                              UNSPEC_VEC_SMULT_ODD))]
906   "TARGET_VX"
907   "vmo<bhfgq>\t%v0,%v1,%v2"
908   [(set_attr "op_type" "VRR")])
910 ; vmlob, vmloh, vmlof
911 (define_insn "vec_widen_umult_odd_<mode>"
912   [(set (match_operand:<vec_double>                 0 "register_operand" "=v")
913         (unspec:<vec_double> [(match_operand:VI_QHS 1 "register_operand" "%v")
914                               (match_operand:VI_QHS 2 "register_operand"  "v")]
915                              UNSPEC_VEC_UMULT_ODD))]
916   "TARGET_VX"
917   "vmlo<bhfgq>\t%v0,%v1,%v2"
918   [(set_attr "op_type" "VRR")])
920 ; vec_widen_umult_hi
921 ; vec_widen_umult_lo
922 ; vec_widen_smult_hi
923 ; vec_widen_smult_lo
925 ; vec_widen_ushiftl_hi
926 ; vec_widen_ushiftl_lo
927 ; vec_widen_sshiftl_hi
928 ; vec_widen_sshiftl_lo
931 ;; Vector floating point arithmetic instructions
934 (define_insn "addv2df3"
935   [(set (match_operand:V2DF            0 "register_operand" "=v")
936         (plus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
937                    (match_operand:V2DF 2 "register_operand"  "v")))]
938   "TARGET_VX"
939   "vfadb\t%v0,%v1,%v2"
940   [(set_attr "op_type" "VRR")])
942 (define_insn "subv2df3"
943   [(set (match_operand:V2DF             0 "register_operand" "=v")
944         (minus:V2DF (match_operand:V2DF 1 "register_operand" "%v")
945                     (match_operand:V2DF 2 "register_operand"  "v")))]
946   "TARGET_VX"
947   "vfsdb\t%v0,%v1,%v2"
948   [(set_attr "op_type" "VRR")])
950 (define_insn "mulv2df3"
951   [(set (match_operand:V2DF            0 "register_operand" "=v")
952         (mult:V2DF (match_operand:V2DF 1 "register_operand" "%v")
953                    (match_operand:V2DF 2 "register_operand"  "v")))]
954   "TARGET_VX"
955   "vfmdb\t%v0,%v1,%v2"
956   [(set_attr "op_type" "VRR")])
958 (define_insn "divv2df3"
959   [(set (match_operand:V2DF           0 "register_operand" "=v")
960         (div:V2DF (match_operand:V2DF 1 "register_operand"  "v")
961                   (match_operand:V2DF 2 "register_operand"  "v")))]
962   "TARGET_VX"
963   "vfddb\t%v0,%v1,%v2"
964   [(set_attr "op_type" "VRR")])
966 (define_insn "sqrtv2df2"
967   [(set (match_operand:V2DF            0 "register_operand" "=v")
968         (sqrt:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
969   "TARGET_VX"
970   "vfsqdb\t%v0,%v1"
971   [(set_attr "op_type" "VRR")])
973 (define_insn "fmav2df4"
974   [(set (match_operand:V2DF           0 "register_operand" "=v")
975         (fma:V2DF (match_operand:V2DF 1 "register_operand" "%v")
976                   (match_operand:V2DF 2 "register_operand"  "v")
977                   (match_operand:V2DF 3 "register_operand"  "v")))]
978   "TARGET_VX"
979   "vfmadb\t%v0,%v1,%v2,%v3"
980   [(set_attr "op_type" "VRR")])
982 (define_insn "fmsv2df4"
983   [(set (match_operand:V2DF                     0 "register_operand" "=v")
984         (fma:V2DF (match_operand:V2DF           1 "register_operand" "%v")
985                   (match_operand:V2DF           2 "register_operand"  "v")
986                   (neg:V2DF (match_operand:V2DF 3 "register_operand"  "v"))))]
987   "TARGET_VX"
988   "vfmsdb\t%v0,%v1,%v2,%v3"
989   [(set_attr "op_type" "VRR")])
991 (define_insn "negv2df2"
992   [(set (match_operand:V2DF           0 "register_operand" "=v")
993         (neg:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
994   "TARGET_VX"
995   "vflcdb\t%v0,%v1"
996   [(set_attr "op_type" "VRR")])
998 (define_insn "absv2df2"
999   [(set (match_operand:V2DF           0 "register_operand" "=v")
1000         (abs:V2DF (match_operand:V2DF 1 "register_operand"  "v")))]
1001   "TARGET_VX"
1002   "vflpdb\t%v0,%v1"
1003   [(set_attr "op_type" "VRR")])
1005 (define_insn "*negabsv2df2"
1006   [(set (match_operand:V2DF                     0 "register_operand" "=v")
1007         (neg:V2DF (abs:V2DF (match_operand:V2DF 1 "register_operand"  "v"))))]
1008   "TARGET_VX"
1009   "vflndb\t%v0,%v1"
1010   [(set_attr "op_type" "VRR")])
1012 ; Emulate with compare + select
1013 (define_insn_and_split "smaxv2df3"
1014   [(set (match_operand:V2DF            0 "register_operand" "=v")
1015         (smax:V2DF (match_operand:V2DF 1 "register_operand" "%v")
1016                    (match_operand:V2DF 2 "register_operand"  "v")))]
1017   "TARGET_VX"
1018   "#"
1019   ""
1020   [(set (match_dup 3)
1021         (gt:V2DI (match_dup 1) (match_dup 2)))
1022    (set (match_dup 0)
1023         (if_then_else:V2DF
1024          (eq (match_dup 3) (match_dup 4))
1025          (match_dup 2)
1026          (match_dup 1)))]
1028   operands[3] = gen_reg_rtx (V2DImode);
1029   operands[4] = CONST0_RTX (V2DImode);
1032 ; Emulate with compare + select
1033 (define_insn_and_split "sminv2df3"
1034   [(set (match_operand:V2DF            0 "register_operand" "=v")
1035         (smin:V2DF (match_operand:V2DF 1 "register_operand" "%v")
1036                    (match_operand:V2DF 2 "register_operand"  "v")))]
1037   "TARGET_VX"
1038   "#"
1039   ""
1040   [(set (match_dup 3)
1041         (gt:V2DI (match_dup 1) (match_dup 2)))
1042    (set (match_dup 0)
1043         (if_then_else:V2DF
1044          (eq (match_dup 3) (match_dup 4))
1045          (match_dup 1)
1046          (match_dup 2)))]
1048   operands[3] = gen_reg_rtx (V2DImode);
1049   operands[4] = CONST0_RTX (V2DImode);
1054 ;; Integer compares
1057 (define_insn "*vec_cmp<VICMP_HW_OP:code><VI:mode>_nocc"
1058   [(set (match_operand:VI                 2 "register_operand" "=v")
1059         (VICMP_HW_OP:VI (match_operand:VI 0 "register_operand"  "v")
1060                         (match_operand:VI 1 "register_operand"  "v")))]
1061   "TARGET_VX"
1062   "vc<VICMP_HW_OP:insn_cmp_op><VI:bhfgq>\t%v2,%v0,%v1"
1063   [(set_attr "op_type" "VRR")])
1067 ;; Floating point compares
1070 ; EQ, GT, GE
1071 (define_insn "*vec_cmp<VFCMP_HW_OP:code>v2df_nocc"
1072   [(set (match_operand:V2DI                   0 "register_operand" "=v")
1073         (VFCMP_HW_OP:V2DI (match_operand:V2DF 1 "register_operand"  "v")
1074                           (match_operand:V2DF 2 "register_operand"  "v")))]
1075    "TARGET_VX"
1076    "vfc<VFCMP_HW_OP:asm_fcmp_op>db\t%v0,%v1,%v2"
1077   [(set_attr "op_type" "VRR")])
1079 ; Expanders for not directly supported comparisons
1081 ; UNEQ a u== b -> !(a > b | b > a)
1082 (define_expand "vec_cmpuneqv2df"
1083   [(set (match_operand:V2DI          0 "register_operand" "=v")
1084         (gt:V2DI (match_operand:V2DF 1 "register_operand"  "v")
1085                  (match_operand:V2DF 2 "register_operand"  "v")))
1086    (set (match_dup 3)
1087         (gt:V2DI (match_dup 2) (match_dup 1)))
1088    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
1089    (set (match_dup 0) (not:V2DI (match_dup 0)))]
1090   "TARGET_VX"
1092   operands[3] = gen_reg_rtx (V2DImode);
1095 ; LTGT a <> b -> a > b | b > a
1096 (define_expand "vec_cmpltgtv2df"
1097   [(set (match_operand:V2DI          0 "register_operand" "=v")
1098         (gt:V2DI (match_operand:V2DF 1 "register_operand"  "v")
1099                  (match_operand:V2DF 2 "register_operand"  "v")))
1100    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
1101    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
1102   "TARGET_VX"
1104   operands[3] = gen_reg_rtx (V2DImode);
1107 ; ORDERED (a, b): a >= b | b > a
1108 (define_expand "vec_orderedv2df"
1109   [(set (match_operand:V2DI          0 "register_operand" "=v")
1110         (ge:V2DI (match_operand:V2DF 1 "register_operand"  "v")
1111                  (match_operand:V2DF 2 "register_operand"  "v")))
1112    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
1113    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))]
1114   "TARGET_VX"
1116   operands[3] = gen_reg_rtx (V2DImode);
1119 ; UNORDERED (a, b): !ORDERED (a, b)
1120 (define_expand "vec_unorderedv2df"
1121   [(set (match_operand:V2DI          0 "register_operand" "=v")
1122         (ge:V2DI (match_operand:V2DF 1 "register_operand"  "v")
1123                  (match_operand:V2DF 2 "register_operand"  "v")))
1124    (set (match_dup 3) (gt:V2DI (match_dup 2) (match_dup 1)))
1125    (set (match_dup 0) (ior:V2DI (match_dup 0) (match_dup 3)))
1126    (set (match_dup 0) (not:V2DI (match_dup 0)))]
1127   "TARGET_VX"
1129   operands[3] = gen_reg_rtx (V2DImode);
1132 (define_insn "*vec_load_pairv2di"
1133   [(set (match_operand:V2DI                0 "register_operand" "=v")
1134         (vec_concat:V2DI (match_operand:DI 1 "register_operand"  "d")
1135                          (match_operand:DI 2 "register_operand"  "d")))]
1136   "TARGET_VX"
1137   "vlvgp\t%v0,%1,%2"
1138   [(set_attr "op_type" "VRR")])
1140 (define_insn "vllv16qi"
1141   [(set (match_operand:V16QI              0 "register_operand" "=v")
1142         (unspec:V16QI [(match_operand:SI  1 "register_operand"  "d")
1143                        (match_operand:BLK 2 "memory_operand"    "Q")]
1144                       UNSPEC_VEC_LOAD_LEN))]
1145   "TARGET_VX"
1146   "vll\t%v0,%1,%2"
1147   [(set_attr "op_type" "VRS")])
1149 ; vfenebs, vfenehs, vfenefs
1150 ; vfenezbs, vfenezhs, vfenezfs
1151 (define_insn "vec_vfenes<mode>"
1152   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1153         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1154                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
1155                            (match_operand:QI 3 "const_mask_operand" "C")]
1156                           UNSPEC_VEC_VFENE))
1157    (set (reg:CCRAW CC_REGNUM)
1158         (unspec:CCRAW [(match_dup 1)
1159                        (match_dup 2)
1160                        (match_dup 3)]
1161                       UNSPEC_VEC_VFENECC))]
1162   "TARGET_VX"
1164   unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1166   gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
1167   flags &= ~VSTRING_FLAG_CS;
1169   if (flags == VSTRING_FLAG_ZS)
1170     return "vfenez<bhfgq>s\t%v0,%v1,%v2";
1171   return "vfene<bhfgq>s\t%v0,%v1,%v2";
1173   [(set_attr "op_type" "VRR")])
1176 ; Vector select
1178 ; The following splitters simplify vec_sel for constant 0 or -1
1179 ; selection sources.  This is required to generate efficient code for
1180 ; vcond.
1182 ; a = b == c;
1183 (define_split
1184   [(set (match_operand:V 0 "register_operand" "")
1185         (if_then_else:V
1186          (eq (match_operand:<tointvec> 3 "register_operand" "")
1187              (match_operand:V 4 "const0_operand" ""))
1188          (match_operand:V 1 "const0_operand" "")
1189          (match_operand:V 2 "all_ones_operand" "")))]
1190   "TARGET_VX"
1191   [(set (match_dup 0) (match_dup 3))]
1193   PUT_MODE (operands[3], <V:MODE>mode);
1196 ; a = ~(b == c)
1197 (define_split
1198   [(set (match_operand:V 0 "register_operand" "")
1199         (if_then_else:V
1200          (eq (match_operand:<tointvec> 3 "register_operand" "")
1201              (match_operand:V 4 "const0_operand" ""))
1202          (match_operand:V 1 "all_ones_operand" "")
1203          (match_operand:V 2 "const0_operand" "")))]
1204   "TARGET_VX"
1205   [(set (match_dup 0) (not:V (match_dup 3)))]
1207   PUT_MODE (operands[3], <V:MODE>mode);
1210 ; a = b != c
1211 (define_split
1212   [(set (match_operand:V 0 "register_operand" "")
1213         (if_then_else:V
1214          (ne (match_operand:<tointvec> 3 "register_operand" "")
1215              (match_operand:V 4 "const0_operand" ""))
1216          (match_operand:V 1 "all_ones_operand" "")
1217          (match_operand:V 2 "const0_operand" "")))]
1218   "TARGET_VX"
1219   [(set (match_dup 0) (match_dup 3))]
1221   PUT_MODE (operands[3], <V:MODE>mode);
1224 ; a = ~(b != c)
1225 (define_split
1226   [(set (match_operand:V 0 "register_operand" "")
1227         (if_then_else:V
1228          (ne (match_operand:<tointvec> 3 "register_operand" "")
1229              (match_operand:V 4 "const0_operand" ""))
1230          (match_operand:V 1 "const0_operand" "")
1231          (match_operand:V 2 "all_ones_operand" "")))]
1232   "TARGET_VX"
1233   [(set (match_dup 0) (not:V (match_dup 3)))]
1235   PUT_MODE (operands[3], <V:MODE>mode);
1238 ; op0 = op3 == 0 ? op1 : op2
1239 (define_insn "*vec_sel0<mode>"
1240   [(set (match_operand:V 0 "register_operand" "=v")
1241         (if_then_else:V
1242          (eq (match_operand:<tointvec> 3 "register_operand" "v")
1243              (match_operand:<tointvec> 4 "const0_operand" ""))
1244          (match_operand:V 1 "register_operand" "v")
1245          (match_operand:V 2 "register_operand" "v")))]
1246   "TARGET_VX"
1247   "vsel\t%v0,%2,%1,%3"
1248   [(set_attr "op_type" "VRR")])
1250 ; op0 = !op3 == 0 ? op1 : op2
1251 (define_insn "*vec_sel0<mode>"
1252   [(set (match_operand:V 0 "register_operand" "=v")
1253         (if_then_else:V
1254          (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
1255              (match_operand:<tointvec> 4 "const0_operand" ""))
1256          (match_operand:V 1 "register_operand" "v")
1257          (match_operand:V 2 "register_operand" "v")))]
1258   "TARGET_VX"
1259   "vsel\t%v0,%1,%2,%3"
1260   [(set_attr "op_type" "VRR")])
1262 ; op0 = op3 == -1 ? op1 : op2
1263 (define_insn "*vec_sel1<mode>"
1264   [(set (match_operand:V 0 "register_operand" "=v")
1265         (if_then_else:V
1266          (eq (match_operand:<tointvec> 3 "register_operand" "v")
1267              (match_operand:<tointvec> 4 "all_ones_operand" ""))
1268          (match_operand:V 1 "register_operand" "v")
1269          (match_operand:V 2 "register_operand" "v")))]
1270   "TARGET_VX"
1271   "vsel\t%v0,%1,%2,%3"
1272   [(set_attr "op_type" "VRR")])
1274 ; op0 = !op3 == -1 ? op1 : op2
1275 (define_insn "*vec_sel1<mode>"
1276   [(set (match_operand:V 0 "register_operand" "=v")
1277         (if_then_else:V
1278          (eq (not:<tointvec> (match_operand:<tointvec> 3 "register_operand" "v"))
1279              (match_operand:<tointvec> 4 "all_ones_operand" ""))
1280          (match_operand:V 1 "register_operand" "v")
1281          (match_operand:V 2 "register_operand" "v")))]
1282   "TARGET_VX"
1283   "vsel\t%v0,%2,%1,%3"
1284   [(set_attr "op_type" "VRR")])
1286 ; vec_pack_trunc
1288 ; vpkh, vpkf, vpkg
1289 (define_insn "vec_pack_trunc_<mode>"
1290   [(set (match_operand:<vec_half> 0 "register_operand" "=v")
1291         (vec_concat:<vec_half>
1292          (truncate:<vec_halfhalf>
1293           (match_operand:VI_HW_HSD 1 "register_operand" "v"))
1294          (truncate:<vec_halfhalf>
1295           (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
1296   "TARGET_VX"
1297   "vpk<bhfgq>\t%0,%1,%2"
1298   [(set_attr "op_type" "VRR")])
1300 ; vpksh, vpksf, vpksg
1301 (define_insn "vec_pack_ssat_<mode>"
1302   [(set (match_operand:<vec_half> 0 "register_operand" "=v")
1303         (vec_concat:<vec_half>
1304          (ss_truncate:<vec_halfhalf>
1305           (match_operand:VI_HW_HSD 1 "register_operand" "v"))
1306          (ss_truncate:<vec_halfhalf>
1307           (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
1308   "TARGET_VX"
1309   "vpks<bhfgq>\t%0,%1,%2"
1310   [(set_attr "op_type" "VRR")])
1312 ; vpklsh, vpklsf, vpklsg
1313 (define_insn "vec_pack_usat_<mode>"
1314   [(set (match_operand:<vec_half> 0 "register_operand" "=v")
1315         (vec_concat:<vec_half>
1316          (us_truncate:<vec_halfhalf>
1317           (match_operand:VI_HW_HSD 1 "register_operand" "v"))
1318          (us_truncate:<vec_halfhalf>
1319           (match_operand:VI_HW_HSD 2 "register_operand" "v"))))]
1320   "TARGET_VX"
1321   "vpkls<bhfgq>\t%0,%1,%2"
1322   [(set_attr "op_type" "VRR")])
1324 ;; vector unpack v16qi
1326 ; signed
1328 (define_insn "vec_unpacks_hi_v16qi"
1329   [(set (match_operand:V8HI 0 "register_operand" "=v")
1330         (sign_extend:V8HI
1331          (vec_select:V8QI
1332           (match_operand:V16QI 1 "register_operand" "v")
1333           (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
1334                      (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
1335   "TARGET_VX"
1336   "vuphb\t%0,%1"
1337   [(set_attr "op_type" "VRR")])
1339 (define_insn "vec_unpacks_low_v16qi"
1340   [(set (match_operand:V8HI 0 "register_operand" "=v")
1341         (sign_extend:V8HI
1342          (vec_select:V8QI
1343           (match_operand:V16QI 1 "register_operand" "v")
1344           (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11)
1345                      (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
1346   "TARGET_VX"
1347   "vuplb\t%0,%1"
1348   [(set_attr "op_type" "VRR")])
1350 ; unsigned
1352 (define_insn "vec_unpacku_hi_v16qi"
1353   [(set (match_operand:V8HI 0 "register_operand" "=v")
1354         (zero_extend:V8HI
1355          (vec_select:V8QI
1356           (match_operand:V16QI 1 "register_operand" "v")
1357           (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
1358                      (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
1359   "TARGET_VX"
1360   "vuplhb\t%0,%1"
1361   [(set_attr "op_type" "VRR")])
1363 (define_insn "vec_unpacku_low_v16qi"
1364   [(set (match_operand:V8HI 0 "register_operand" "=v")
1365         (zero_extend:V8HI
1366          (vec_select:V8QI
1367           (match_operand:V16QI 1 "register_operand" "v")
1368           (parallel [(const_int 8) (const_int 9) (const_int 10)(const_int 11)
1369                      (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
1370   "TARGET_VX"
1371   "vupllb\t%0,%1"
1372   [(set_attr "op_type" "VRR")])
1374 ;; vector unpack v8hi
1376 ; signed
1378 (define_insn "vec_unpacks_hi_v8hi"
1379   [(set (match_operand:V4SI 0 "register_operand" "=v")
1380         (sign_extend:V4SI
1381          (vec_select:V4HI
1382           (match_operand:V8HI 1 "register_operand" "v")
1383           (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
1384   "TARGET_VX"
1385   "vuphh\t%0,%1"
1386   [(set_attr "op_type" "VRR")])
1388 (define_insn "vec_unpacks_lo_v8hi"
1389   [(set (match_operand:V4SI 0 "register_operand" "=v")
1390         (sign_extend:V4SI
1391          (vec_select:V4HI
1392           (match_operand:V8HI 1 "register_operand" "v")
1393           (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
1394   "TARGET_VX"
1395   "vuplhw\t%0,%1"
1396   [(set_attr "op_type" "VRR")])
1398 ; unsigned
1400 (define_insn "vec_unpacku_hi_v8hi"
1401   [(set (match_operand:V4SI 0 "register_operand" "=v")
1402         (zero_extend:V4SI
1403          (vec_select:V4HI
1404           (match_operand:V8HI 1 "register_operand" "v")
1405           (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
1406   "TARGET_VX"
1407   "vuplhh\t%0,%1"
1408   [(set_attr "op_type" "VRR")])
1410 (define_insn "vec_unpacku_lo_v8hi"
1411   [(set (match_operand:V4SI 0 "register_operand" "=v")
1412         (zero_extend:V4SI
1413          (vec_select:V4HI
1414           (match_operand:V8HI 1 "register_operand" "v")
1415           (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
1416   "TARGET_VX"
1417   "vupllh\t%0,%1"
1418   [(set_attr "op_type" "VRR")])
1420 ;; vector unpack v4si
1422 ; signed
1424 (define_insn "vec_unpacks_hi_v4si"
1425   [(set (match_operand:V2DI 0 "register_operand" "=v")
1426         (sign_extend:V2DI
1427          (vec_select:V2SI
1428           (match_operand:V4SI 1 "register_operand" "v")
1429           (parallel [(const_int 0)(const_int 1)]))))]
1430   "TARGET_VX"
1431   "vuphf\t%0,%1"
1432   [(set_attr "op_type" "VRR")])
1434 (define_insn "vec_unpacks_lo_v4si"
1435   [(set (match_operand:V2DI 0 "register_operand" "=v")
1436         (sign_extend:V2DI
1437          (vec_select:V2SI
1438           (match_operand:V4SI 1 "register_operand" "v")
1439           (parallel [(const_int 2)(const_int 3)]))))]
1440   "TARGET_VX"
1441   "vuplf\t%0,%1"
1442   [(set_attr "op_type" "VRR")])
1444 ; unsigned
1446 (define_insn "vec_unpacku_hi_v4si"
1447   [(set (match_operand:V2DI 0 "register_operand" "=v")
1448         (zero_extend:V2DI
1449          (vec_select:V2SI
1450           (match_operand:V4SI 1 "register_operand" "v")
1451           (parallel [(const_int 0)(const_int 1)]))))]
1452   "TARGET_VX"
1453   "vuplhf\t%0,%1"
1454   [(set_attr "op_type" "VRR")])
1456 (define_insn "vec_unpacku_lo_v4si"
1457   [(set (match_operand:V2DI 0 "register_operand" "=v")
1458         (zero_extend:V2DI
1459          (vec_select:V2SI
1460           (match_operand:V4SI 1 "register_operand" "v")
1461           (parallel [(const_int 2)(const_int 3)]))))]
1462   "TARGET_VX"
1463   "vupllf\t%0,%1"
1464   [(set_attr "op_type" "VRR")])
1467 ; reduc_smin
1468 ; reduc_smax
1469 ; reduc_umin
1470 ; reduc_umax
1472 ; vec_shl vrep + vsl
1473 ; vec_shr
1475 ; vec_pack_sfix_trunc: convert + pack ?
1476 ; vec_pack_ufix_trunc
1477 ; vec_unpacks_float_hi
1478 ; vec_unpacks_float_lo
1479 ; vec_unpacku_float_hi
1480 ; vec_unpacku_float_lo