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