testsuite: Correct vec-rlmi-rlnm.c testsuite expected result
[official-gcc.git] / gcc / config / s390 / vx-builtins.md
blob6f1add02d0b6b2547fd0d268494bb85c8291e411
1 ;;- Instruction patterns for the System z vector facility builtins.
2 ;;  Copyright (C) 2015-2020 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 ; The patterns in this file are enabled with -mzvector
23 (define_mode_iterator V_HW_32_64 [V4SI V2DI V2DF (V4SF "TARGET_VXE")])
24 (define_mode_iterator VI_HW_SD [V4SI V2DI])
25 (define_mode_iterator V_HW_4 [V4SI V4SF])
26 ; Full size vector modes with more than one element which are directly supported in vector registers by the hardware.
27 (define_mode_iterator VEC_HW  [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE")])
28 (define_mode_iterator VECF_HW [(V4SF "TARGET_VXE") V2DF])
30 ; The element type of the vector with floating point modes translated
31 ; to int modes of the same size.
32 (define_mode_attr non_vec_int[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
33                               (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
34                               (V1SI "SI") (V2SI "SI") (V4SI "SI")
35                               (V1DI "DI") (V2DI "DI")
36                               (V1SF "SI") (V2SF "SI") (V4SF "SI")
37                               (V1DF "DI") (V2DF "DI")])
39 ; Condition code modes generated by int comparisons
40 (define_mode_iterator VICMP [CCVEQ CCVIH CCVIHU])
42 ; Comparisons supported by the vec_cmp* builtins
43 (define_code_iterator intcmp [eq gt gtu ge geu lt ltu le leu])
44 (define_code_iterator fpcmp  [eq gt ge lt le])
46 ; Comparisons supported by the vec_all/any* builtins
47 (define_code_iterator intcmpcc [eq ne gt ge lt le gtu geu ltu leu])
48 (define_code_iterator fpcmpcc  [eq ne gt ge unle unlt lt le])
50 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4)
51 (define_constants
52   [(VSTRING_FLAG_IN         8)   ; invert result
53    (VSTRING_FLAG_RT         4)   ; result type
54    (VSTRING_FLAG_ZS         2)   ; zero search
55    (VSTRING_FLAG_CS         1)]) ; condition code set
57 ; Rounding modes as being used for e.g. VFI
58 (define_constants
59   [(VEC_RND_CURRENT                0)
60    (VEC_RND_NEAREST_AWAY_FROM_ZERO 1)
61    (VEC_RND_SHORT_PREC             3)
62    (VEC_RND_NEAREST_TO_EVEN        4)
63    (VEC_RND_TO_ZERO                5)
64    (VEC_RND_TO_INF                 6)
65    (VEC_RND_TO_MINF                7)])
67 ; Inexact suppression facility flag as being used for e.g. VFI
68 (define_constants
69   [(VEC_INEXACT                0)
70    (VEC_NOINEXACT              4)])
73 ; Vector gather element
75 ; vgef, vgeg
76 (define_insn "vec_gather_element<mode>"
77   [(set (match_operand:V_HW_32_64                     0 "register_operand"  "=v")
78         (unspec:V_HW_32_64 [(match_operand:V_HW_32_64 1 "register_operand"   "0")
79                             (match_operand:<tointvec> 2 "register_operand"   "v")
80                             (match_operand:BLK        3 "memory_operand"     "R")
81                             (match_operand:QI         4 "const_mask_operand" "C")]
82                            UNSPEC_VEC_GATHER))]
83   "TARGET_VX && UINTVAL (operands[4]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
84   "vge<bhfgq>\t%0,%O3(%v2,%R3),%b4"
85   [(set_attr "op_type" "VRV")])
87 (define_expand "vec_genmask<mode>"
88   [(match_operand:VI_HW 0 "register_operand" "=v")
89    (match_operand:QI    1 "const_int_operand" "C")
90    (match_operand:QI    2 "const_int_operand" "C")]
91   "TARGET_VX"
93   int bitlen = GET_MODE_UNIT_BITSIZE (<VI_HW:MODE>mode);
94   /* To bit little endian style.  */
95   int end = bitlen - 1 - INTVAL (operands[1]);
96   int start = bitlen - 1 - INTVAL (operands[2]);
97   int i;
98   unsigned HOST_WIDE_INT mask;
99   bool swapped_p = false;
101   if (start > end)
102     {
103       i = start - 1; start = end + 1; end = i;
104       swapped_p = true;
105     }
106   if (end == 63)
107     mask = HOST_WIDE_INT_M1U;
108   else
109     mask = (HOST_WIDE_INT_1U << (end + 1)) - 1;
111   mask &= ~((HOST_WIDE_INT_1U << start) - 1);
113   if (swapped_p)
114     mask = ~mask;
116   rtx mask_rtx = gen_int_mode (mask, GET_MODE_INNER (<VI_HW:MODE>mode));
118   emit_insn (gen_rtx_SET (operands[0],
119                           gen_const_vec_duplicate (<VI_HW:MODE>mode,
120                                                    mask_rtx)));
121   DONE;
124 (define_expand "vec_genbytemaskv16qi"
125   [(match_operand:V16QI 0 "register_operand"  "")
126    (match_operand:HI    1 "const_int_operand" "")]
127   "TARGET_VX"
129   int i;
130   unsigned mask = 0x8000;
131   rtx const_vec[16];
132   unsigned HOST_WIDE_INT byte_mask = UINTVAL (operands[1]);
134   for (i = 0; i < 16; i++)
135     {
136       if (mask & byte_mask)
137         const_vec[i] = constm1_rtx;
138       else
139         const_vec[i] = const0_rtx;
140       mask = mask >> 1;
141     }
142   emit_insn (gen_rtx_SET (operands[0],
143                           gen_rtx_CONST_VECTOR (V16QImode,
144                                                 gen_rtvec_v (16, const_vec))));
145   DONE;
148 (define_expand "vec_splats<mode>"
149   [(set (match_operand:VEC_HW                          0 "register_operand" "")
150         (vec_duplicate:VEC_HW (match_operand:<non_vec> 1 "general_operand"  "")))]
151   "TARGET_VX")
153 (define_expand "vec_insert<mode>"
154   [(set (match_operand:VEC_HW                    0 "register_operand" "")
155         (unspec:VEC_HW [(match_operand:<non_vec> 2 "register_operand" "")
156                         (match_operand:SI        3 "nonmemory_operand" "")
157                         (match_operand:VEC_HW    1 "register_operand" "")]
158                        UNSPEC_VEC_SET))]
159   "TARGET_VX"
160   "")
162 ; This is vec_set + modulo arithmetic on the element selector (op 2)
163 (define_expand "vec_promote<mode>"
164   [(set (match_operand:VEC_HW                    0 "register_operand" "")
165         (unspec:VEC_HW [(match_operand:<non_vec> 1 "register_operand" "")
166                         (match_operand:SI        2 "nonmemory_operand" "")
167                         (match_dup 0)]
168                        UNSPEC_VEC_SET))]
169   "TARGET_VX"
170   "")
172 ; vec_extract is also an RTL standard name -> vector.md
174 ; vllezb, vllezh, vllezf, vllezg
175 (define_insn "vec_insert_and_zero<mode>"
176   [(set (match_operand:VEC_HW                    0 "register_operand" "=v")
177         (unspec:VEC_HW [(match_operand:<non_vec> 1 "memory_operand"    "R")]
178                        UNSPEC_VEC_INSERT_AND_ZERO))]
179   "TARGET_VX"
180   "vllez<bhfgq>\t%v0,%1"
181   [(set_attr "op_type" "VRX")])
183 ; vec_revb (vec_insert_and_zero(x))             bswap-and-replicate-1.c
184 ; vllebrzh, vllebrzf, vllebrzg
185 (define_insn "*vec_insert_and_zero_bswap<mode>"
186   [(set (match_operand:V_HW_HSD                    0 "register_operand"       "=v")
187         (bswap:V_HW_HSD (unspec:V_HW_HSD
188                          [(match_operand:<non_vec> 1 "memory_operand"          "R")]
189                          UNSPEC_VEC_INSERT_AND_ZERO)))
190    (use (match_operand:V16QI                       2 "permute_pattern_operand" "X"))]
191   "TARGET_VXE2"
192   "vllebrz<bhfgq>\t%v0,%1"
193   [(set_attr "op_type" "VRX")])
196 (define_insn "vlbb"
197   [(set (match_operand:V16QI              0 "register_operand"   "=v")
198         (unspec:V16QI [(match_operand:BLK 1 "memory_operand"      "R")
199                        (match_operand:QI  2 "const_mask_operand"  "C")]
200                       UNSPEC_VEC_LOAD_BNDRY))]
201   "TARGET_VX && UINTVAL (operands[2]) < 7"
202   "vlbb\t%v0,%1,%2"
203   [(set_attr "op_type" "VRX")])
205 ; Vector load rightmost with length
207 (define_expand "vlrlrv16qi"
208   [(set (match_operand:V16QI              0 "register_operand"  "")
209         (unspec:V16QI [(match_operand:BLK 2 "memory_operand"    "")
210                        (match_operand:SI  1 "nonmemory_operand" "")]
211                       UNSPEC_VEC_LOAD_LEN_R))]
212   "TARGET_VXE"
214   /* vlrlr sets all length values beyond 15 to 15.  Emulate the same
215      behavior for immediate length operands.  vlrl would trigger a
216      SIGILL for too large immediate operands.  */
217   if (CONST_INT_P (operands[1])
218       && (UINTVAL (operands[1]) & 0xffffffff) > 15)
219     operands[1] = GEN_INT (15);
222 (define_insn "*vlrlrv16qi"
223   [(set (match_operand:V16QI              0 "register_operand"  "=v,  v,  v")
224         (unspec:V16QI [(match_operand:BLK 2 "memory_operand"     "Q,  R,  Q")
225                        (match_operand:SI  1 "nonmemory_operand"  "d,j>f,jb4")]
226                       UNSPEC_VEC_LOAD_LEN_R))]
227   "TARGET_VXE"
228   "@
229    vlrlr\t%v0,%1,%2
230    vl\t%v0,%2%A2
231    vlrl\t%v0,%2,%1"
232   [(set_attr "op_type" "VRS,VRX,VSI")])
235 ; FIXME: The following two patterns might using vec_merge. But what is
236 ; the canonical form: (vec_select (vec_merge op0 op1)) or (vec_merge
237 ; (vec_select op0) (vec_select op1)
238 ; vmrhb, vmrhh, vmrhf, vmrhg
239 (define_insn "vec_mergeh<mode>"
240   [(set (match_operand:V_128_NOSINGLE                         0 "register_operand" "=v")
241         (unspec:V_128_NOSINGLE [(match_operand:V_128_NOSINGLE 1 "register_operand"  "v")
242                         (match_operand:V_128_NOSINGLE         2 "register_operand"  "v")]
243                        UNSPEC_VEC_MERGEH))]
244   "TARGET_VX"
245   "vmrh<bhfgq>\t%v0,%1,%2"
246   [(set_attr "op_type" "VRR")])
248 ; vmrlb, vmrlh, vmrlf, vmrlg
249 (define_insn "vec_mergel<mode>"
250   [(set (match_operand:V_128_NOSINGLE                         0 "register_operand" "=v")
251         (unspec:V_128_NOSINGLE [(match_operand:V_128_NOSINGLE 1 "register_operand"  "v")
252                         (match_operand:V_128_NOSINGLE         2 "register_operand"  "v")]
253                      UNSPEC_VEC_MERGEL))]
254   "TARGET_VX"
255   "vmrl<bhfgq>\t%v0,%1,%2"
256   [(set_attr "op_type" "VRR")])
259 ; Vector pack
261 ; vpkh, vpkf, vpkg
262 (define_insn "vec_pack<mode>"
263   [(set (match_operand:<vec_half>                    0 "register_operand" "=v")
264         (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
265                             (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
266                            UNSPEC_VEC_PACK))]
267   "TARGET_VX"
268   "vpk<bhfgq>\t%v0,%v1,%v2"
269   [(set_attr "op_type" "VRR")])
272 ; Vector pack saturate
274 ; vpksh, vpksf, vpksg
275 (define_insn "vec_packs<mode>"
276   [(set (match_operand:<vec_half>                    0 "register_operand" "=v")
277         (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
278                             (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
279                            UNSPEC_VEC_PACK_SATURATE))]
280   "TARGET_VX"
281   "vpks<bhfgq>\t%v0,%v1,%v2"
282   [(set_attr "op_type" "VRR")])
285 ; This is vec_packs_cc + loading cc into a caller specified memory location.
286 (define_expand "vec_packs_cc<mode>"
287   [(parallel
288     [(set (reg:CCRAW CC_REGNUM)
289           (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
290                          (match_operand:VI_HW_HSD 2 "register_operand" "")]
291                         UNSPEC_VEC_PACK_SATURATE_GENCC))
292      (set (match_operand:<vec_half> 0 "register_operand" "")
293           (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
294                              UNSPEC_VEC_PACK_SATURATE_CC))])
295    (set (match_dup 4)
296         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
297    (set (match_operand:SI 3 "memory_operand" "")
298         (match_dup 4))]
299   "TARGET_VX"
301   operands[4] = gen_reg_rtx (SImode);
304 ; vpksh, vpksf, vpksg
305 (define_insn "*vec_packs_cc<mode>"
306   [(set (reg:CCRAW CC_REGNUM)
307         (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
308                        (match_operand:VI_HW_HSD 2 "register_operand" "v")]
309                       UNSPEC_VEC_PACK_SATURATE_GENCC))
310    (set (match_operand:<vec_half> 0 "register_operand" "=v")
311         (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
312                            UNSPEC_VEC_PACK_SATURATE_CC))]
313   "TARGET_VX"
314   "vpks<bhfgq>s\t%v0,%v1,%v2"
315   [(set_attr "op_type" "VRR")])
318 ; Vector pack logical saturate
320 ; vpklsh, vpklsf, vpklsg
321 (define_insn "vec_packsu<mode>"
322   [(set (match_operand:<vec_half>                    0 "register_operand" "=v")
323         (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
324                             (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
325                            UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
326   "TARGET_VX"
327   "vpkls<bhfgq>\t%v0,%v1,%v2"
328   [(set_attr "op_type" "VRR")])
330 ; Emulate saturate unsigned pack on signed operands.
331 ; Zero out negative elements and continue with the unsigned saturating pack.
332 (define_expand "vec_packsu_u<mode>"
333   [(set (match_operand:<vec_half>                    0 "register_operand" "=v")
334         (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
335                             (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
336                            UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
337   "TARGET_VX"
339    rtx null_vec = CONST0_RTX(<MODE>mode);
340    machine_mode half_mode;
341    switch (<MODE>mode)
342    {
343      case E_V8HImode: half_mode = V16QImode; break;
344      case E_V4SImode: half_mode = V8HImode; break;
345      case E_V2DImode: half_mode = V4SImode; break;
346      default: gcc_unreachable ();
347    }
348    s390_expand_vcond (operands[1], operands[1], null_vec,
349                       GE, operands[1], null_vec);
350    s390_expand_vcond (operands[2], operands[2], null_vec,
351                       GE, operands[2], null_vec);
352    emit_insn (gen_rtx_SET (operands[0],
353                            gen_rtx_UNSPEC (half_mode,
354                                            gen_rtvec (2, operands[1], operands[2]),
355                                            UNSPEC_VEC_PACK_UNSIGNED_SATURATE)));
356    DONE;
359 ; This is vec_packsu_cc + loading cc into a caller specified memory location.
360 ; FIXME: The reg to target mem copy should be issued by reload?!
361 (define_expand "vec_packsu_cc<mode>"
362   [(parallel
363     [(set (reg:CCRAW CC_REGNUM)
364           (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
365                          (match_operand:VI_HW_HSD 2 "register_operand" "")]
366                         UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
367      (set (match_operand:<vec_half> 0 "register_operand" "")
368           (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
369                              UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))])
370    (set (match_dup 4)
371         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
372    (set (match_operand:SI 3 "memory_operand" "")
373         (match_dup 4))]
374   "TARGET_VX"
376   operands[4] = gen_reg_rtx (SImode);
379 ; vpklsh, vpklsf, vpklsg
380 (define_insn "*vec_packsu_cc<mode>"
381   [(set (reg:CCRAW CC_REGNUM)
382         (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
383                        (match_operand:VI_HW_HSD 2 "register_operand" "v")]
384                       UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
385    (set (match_operand:<vec_half> 0 "register_operand" "=v")
386         (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
387                            UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))]
388   "TARGET_VX"
389   "vpkls<bhfgq>s\t%v0,%v1,%v2"
390   [(set_attr "op_type" "VRR")])
393 ; Vector permute
395 ; vec_perm is also RTL standard name, but we can only use it for V16QI
397 (define_insn "vec_zperm<mode>"
398   [(set (match_operand:V_HW_HSD                   0 "register_operand" "=v")
399         (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "register_operand"  "v")
400                           (match_operand:V_HW_HSD 2 "register_operand"  "v")
401                           (match_operand:V16QI    3 "register_operand"  "v")]
402                          UNSPEC_VEC_PERM))]
403   "TARGET_VX"
404   "vperm\t%v0,%v1,%v2,%v3"
405   [(set_attr "op_type" "VRR")])
407 (define_expand "vec_permi<mode>"
408   [(set (match_operand:V_HW_64                  0 "register_operand"   "")
409         (unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand"   "")
410                          (match_operand:V_HW_64 2 "register_operand"   "")
411                          (match_operand:QI      3 "const_mask_operand" "")]
412                         UNSPEC_VEC_PERMI))]
413   "TARGET_VX"
415   HOST_WIDE_INT val = INTVAL (operands[3]);
416   operands[3] = GEN_INT ((val & 1) | (val & 2) << 1);
419 (define_insn "*vec_permi<mode>"
420   [(set (match_operand:V_HW_64                  0 "register_operand"  "=v")
421         (unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand"   "v")
422                          (match_operand:V_HW_64 2 "register_operand"   "v")
423                          (match_operand:QI      3 "const_mask_operand" "C")]
424                         UNSPEC_VEC_PERMI))]
425   "TARGET_VX && (UINTVAL (operands[3]) & 10) == 0"
426   "vpdi\t%v0,%v1,%v2,%b3"
427   [(set_attr "op_type" "VRR")])
430 ; Vector replicate
433 ; Replicate from vector element
434 (define_expand "vec_splat<mode>"
435   [(set (match_operand:V_HW                      0 "register_operand"  "")
436         (vec_duplicate:V_HW (vec_select:<non_vec>
437                              (match_operand:V_HW 1 "register_operand"  "")
438                              (parallel
439                               [(match_operand:QI 2 "const_mask_operand" "")]))))]
440   "TARGET_VX")
442 ; Vector scatter element
444 ; vscef, vsceg
446 ; A 64 bit target address generated from 32 bit elements
447 (define_insn "vec_scatter_element<V_HW_4:mode>_DI"
448   [(set (mem:<non_vec>
449          (plus:DI (zero_extend:DI
450                    (unspec:SI [(match_operand:V4SI 1 "register_operand"   "v")
451                                (match_operand:QI   3 "const_mask_operand" "C")]
452                               UNSPEC_VEC_EXTRACT))
453                   (match_operand:SI                2 "address_operand"   "ZQ")))
454         (unspec:<non_vec> [(match_operand:V_HW_4          0 "register_operand"   "v")
455                            (match_dup 3)] UNSPEC_VEC_EXTRACT))]
456   "TARGET_VX && TARGET_64BIT && UINTVAL (operands[3]) < 4"
457   "vscef\t%v0,%O2(%v1,%R2),%3"
458   [(set_attr "op_type" "VRV")])
460 ; A 31 bit target address is generated from 64 bit elements
461 ; vsceg
462 (define_insn "vec_scatter_element<V_HW_64:mode>_SI"
463   [(set (mem:<non_vec>
464          (plus:SI (subreg:SI
465                    (unspec:<non_vec_int> [(match_operand:V_HW_64 1 "register_operand"   "v")
466                                           (match_operand:QI      3 "const_mask_operand" "C")]
467                                          UNSPEC_VEC_EXTRACT) 4)
468                   (match_operand:SI                              2 "address_operand"   "ZQ")))
469         (unspec:<non_vec> [(match_operand:V_HW_64                0 "register_operand"   "v")
470                            (match_dup 3)] UNSPEC_VEC_EXTRACT))]
471   "TARGET_VX && !TARGET_64BIT && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_64:MODE>mode)"
472   "vsce<V_HW_64:bhfgq>\t%v0,%O2(%v1,%R2),%3"
473   [(set_attr "op_type" "VRV")])
475 ; Element size and target address size is the same
476 ; vscef, vsceg
477 (define_insn "vec_scatter_element<mode>_<non_vec_int>"
478   [(set (mem:<non_vec>
479          (plus:<non_vec_int> (unspec:<non_vec_int>
480                               [(match_operand:<tointvec> 1 "register_operand"   "v")
481                                (match_operand:QI         3 "const_mask_operand" "C")]
482                               UNSPEC_VEC_EXTRACT)
483                              (match_operand:DI           2 "address_operand"   "ZQ")))
484         (unspec:<non_vec> [(match_operand:V_HW_32_64     0 "register_operand"   "v")
485                            (match_dup 3)] UNSPEC_VEC_EXTRACT))]
486   "TARGET_VX && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
487   "vsce<bhfgq>\t%v0,%O2(%v1,%R2),%3"
488   [(set_attr "op_type" "VRV")])
490 ; Depending on the address size we have to expand a different pattern.
491 ; This however cannot be represented in s390-builtins.def so we do the
492 ; multiplexing here in the expander.
493 (define_expand "vec_scatter_element<V_HW_32_64:mode>"
494   [(match_operand:V_HW_32_64 0 "register_operand" "")
495    (match_operand:<tointvec> 1 "register_operand" "")
496    (match_operand 2 "address_operand" "")
497    (match_operand:QI 3 "const_mask_operand" "")]
498   "TARGET_VX"
500   if (TARGET_64BIT)
501     {
502       PUT_MODE (operands[2], DImode);
503       emit_insn (
504         gen_vec_scatter_element<V_HW_32_64:mode>_DI (operands[0], operands[1],
505                                                      operands[2], operands[3]));
506     }
507   else
508     {
509       PUT_MODE (operands[2], SImode);
510       emit_insn (
511         gen_vec_scatter_element<V_HW_32_64:mode>_SI (operands[0], operands[1],
512                                                      operands[2], operands[3]));
513     }
514   DONE;
518 ; Vector select
520 ; for all b in bits op0[b] = op3[b] == 0 ? op2[b] : op1[b]
521 ; implemented as: op0 = (op1 & op3) | (op2 & ~op3)
523 ; Used to expand the vec_sel builtin. Operands op1 and op2 already got
524 ; swapped in s390-c.c when we get here.
526 (define_insn "vsel<mode>"
527   [(set (match_operand:V_HW                      0 "register_operand" "=v")
528         (ior:V_HW
529          (and:V_HW (match_operand:V_HW           1 "register_operand"  "v")
530                    (match_operand:V_HW           3 "register_operand"  "v"))
531          (and:V_HW (not:V_HW (match_dup 3))
532                    (match_operand:V_HW           2 "register_operand"  "v"))))]
533   "TARGET_VX"
534   "vsel\t%v0,%1,%2,%3"
535   [(set_attr "op_type" "VRR")])
538 ; Vector sign extend to doubleword
540 ; Sign extend of right most vector element to respective double-word
541 ; vsegb, vsegh, vsegf
542 (define_insn "vec_extend<mode>"
543   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
544         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
545                           UNSPEC_VEC_EXTEND))]
546   "TARGET_VX"
547   "vseg<bhfgq>\t%v0,%1"
548   [(set_attr "op_type" "VRR")])
551 ; Vector store with length
553 ; Store bytes in OP1 from OP0 with the highest indexed byte to be
554 ; stored from OP0 given by OP2
555 (define_insn "vstl<mode>"
556   [(set (match_operand:BLK             2 "memory_operand"   "=Q")
557         (unspec:BLK [(match_operand:V  0 "register_operand"  "v")
558                      (match_operand:SI 1 "register_operand"  "d")]
559                     UNSPEC_VEC_STORE_LEN))]
560   "TARGET_VX"
561   "vstl\t%v0,%1,%2"
562   [(set_attr "op_type" "VRS")])
564 ; Vector store rightmost with length
566 (define_expand "vstrlrv16qi"
567   [(set (match_operand:BLK                2 "memory_operand"    "")
568         (unspec:BLK [(match_operand:V16QI 0 "register_operand"  "")
569                      (match_operand:SI    1 "nonmemory_operand" "")]
570                     UNSPEC_VEC_STORE_LEN_R))]
571   "TARGET_VXE"
573   /* vstrlr sets all length values beyond 15 to 15.  Emulate the same
574      behavior for immediate length operands.  vstrl would trigger a
575      SIGILL for too large immediate operands.  */
576   if (CONST_INT_P (operands[1])
577       && (UINTVAL (operands[1]) & 0xffffffff) > 15)
578     operands[1] = GEN_INT (15);
581 (define_insn "*vstrlrv16qi"
582   [(set (match_operand:BLK                2 "memory_operand"    "=Q,  R,  Q")
583         (unspec:BLK [(match_operand:V16QI 0 "register_operand"   "v,  v,  v")
584                      (match_operand:SI    1 "nonmemory_operand"  "d,j>f,jb4")]
585                     UNSPEC_VEC_STORE_LEN_R))]
586   "TARGET_VXE"
587   "@
588    vstrlr\t%v0,%1,%2
589    vst\t%v0,%2%A2
590    vstrl\t%v0,%2,%1"
591   [(set_attr "op_type" "VRS,VRX,VSI")])
595 ; vector bit permute
597 (define_insn "vbpermv16qi"
598   [(set (match_operand:V2DI                0 "register_operand" "=v")
599         (unspec:V2DI [(match_operand:V16QI 1 "register_operand"  "v")
600                       (match_operand:V16QI 2 "register_operand"  "v")]
601                      UNSPEC_VEC_VBPERM))]
602   "TARGET_VXE"
603   "vbperm\t%v0,%v1,%v2"
604   [(set_attr "op_type" "VRR")])
606 ; Vector unpack high
608 ; vuphb, vuphh, vuphf
609 (define_insn "vec_unpackh<mode>"
610   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
611         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
612                              UNSPEC_VEC_UNPACKH))]
613   "TARGET_VX"
614   "vuph<bhfgq>\t%v0,%v1"
615   [(set_attr "op_type" "VRR")])
617 ; vuplhb, vuplhh, vuplhf
618 (define_insn "vec_unpackh_l<mode>"
619   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
620         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
621                              UNSPEC_VEC_UNPACKH_L))]
622   "TARGET_VX"
623   "vuplh<bhfgq>\t%v0,%v1"
624   [(set_attr "op_type" "VRR")])
627 ; Vector unpack low
629 ; vuplb, vuplhw, vuplf
630 (define_insn "vec_unpackl<mode>"
631   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
632         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
633                              UNSPEC_VEC_UNPACKL))]
634   "TARGET_VX"
635   "vupl<bhfgq><w>\t%v0,%v1"
636   [(set_attr "op_type" "VRR")])
638 ; vupllb, vupllh, vupllf
639 (define_insn "vec_unpackl_l<mode>"
640   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
641         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
642                              UNSPEC_VEC_UNPACKL_L))]
643   "TARGET_VX"
644   "vupll<bhfgq>\t%v0,%v1"
645   [(set_attr "op_type" "VRR")])
648 ; Vector add
650 ; Vector add compute carry
652 ; vaccb, vacch, vaccf, vaccg, vaccq
653 (define_insn "vacc<bhfgq>_<mode>"
654   [(set (match_operand:VIT_HW                 0 "register_operand" "=v")
655         (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand"  "v")
656                         (match_operand:VIT_HW 2 "register_operand"  "v")]
657                        UNSPEC_VEC_ADDC))]
658   "TARGET_VX"
659   "vacc<bhfgq>\t%v0,%v1,%v2"
660   [(set_attr "op_type" "VRR")])
662 ; Vector add with carry
664 (define_insn "vacq"
665   [(set (match_operand:TI             0 "register_operand" "=v")
666         (unspec:TI [(match_operand:TI 1 "register_operand"  "v")
667                     (match_operand:TI 2 "register_operand"  "v")
668                     (match_operand:TI 3 "register_operand"  "v")]
669                    UNSPEC_VEC_ADDE_U128))]
670   "TARGET_VX"
671   "vacq\t%v0,%v1,%v2,%v3"
672   [(set_attr "op_type" "VRR")])
675 ; Vector add with carry compute carry
677 (define_insn "vacccq"
678   [(set (match_operand:TI             0 "register_operand" "=v")
679         (unspec:TI [(match_operand:TI 1 "register_operand"  "v")
680                     (match_operand:TI 2 "register_operand"  "v")
681                     (match_operand:TI 3 "register_operand"  "v")]
682                    UNSPEC_VEC_ADDEC_U128))]
683   "TARGET_VX"
684   "vacccq\t%v0,%v1,%v2,%v3"
685   [(set_attr "op_type" "VRR")])
688 ; Vector and
690 ; Vector and with complement
692 ; vnc
693 (define_insn "vec_andc<mode>3"
694   [(set (match_operand:VT_HW                       0 "register_operand" "=v")
695         (and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand"  "v"))
696                   (match_operand:VT_HW             1 "register_operand"  "v")))]
697   "TARGET_VX"
698   "vnc\t%v0,%v1,%v2"
699   [(set_attr "op_type" "VRR")])
702 ; Vector average
704 ; vavgb, vavgh, vavgf, vavgg
705 (define_insn "vec_avg<mode>"
706   [(set (match_operand:VI_HW                0 "register_operand" "=v")
707         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
708                        (match_operand:VI_HW 2 "register_operand"  "v")]
709                       UNSPEC_VEC_AVG))]
710   "TARGET_VX"
711   "vavg<bhfgq>\t%v0,%v1,%v2"
712   [(set_attr "op_type" "VRR")])
714 ; Vector average logical
716 ; vavglb, vavglh, vavglf, vavglg
717 (define_insn "vec_avgu<mode>"
718   [(set (match_operand:VI_HW                0 "register_operand" "=v")
719         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
720                        (match_operand:VI_HW 2 "register_operand"  "v")]
721                       UNSPEC_VEC_AVGU))]
722   "TARGET_VX"
723   "vavgl<bhfgq>\t%v0,%v1,%v2"
724   [(set_attr "op_type" "VRR")])
727 ; Vector checksum
729 (define_insn "vec_checksum"
730   [(set (match_operand:V4SI               0 "register_operand" "=v")
731         (unspec:V4SI [(match_operand:V4SI 1 "register_operand"  "v")
732                       (match_operand:V4SI 2 "register_operand"  "v")]
733                      UNSPEC_VEC_CHECKSUM))]
734   "TARGET_VX"
735   "vcksm\t%v0,%v1,%v2"
736   [(set_attr "op_type" "VRR")])
739 ;; Vector compare
742 ; vec_all/any int compares
744 (define_expand "vec_all_<intcmpcc:code><VI_HW:mode>"
745   [(match_operand:SI                0 "register_operand" "")
746    (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
747              (match_operand:VI_HW 2 "register_operand" ""))]
748   "TARGET_VX"
750   s390_expand_vec_compare_cc (operands[0],
751                               <intcmpcc:CODE>,
752                               operands[1],
753                               operands[2],
754                               true);
755   DONE;
758 (define_expand "vec_any_<intcmpcc:code><VI_HW:mode>"
759   [(match_operand:SI                0 "register_operand" "")
760    (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
761              (match_operand:VI_HW 2 "register_operand" ""))]
762   "TARGET_VX"
764   s390_expand_vec_compare_cc (operands[0],
765                               <intcmpcc:CODE>,
766                               operands[1],
767                               operands[2],
768                               false);
769   DONE;
772 ; vec_all/any fp compares
774 (define_expand "vec_all_<fpcmpcc:code><mode>"
775   [(match_operand:SI               0 "register_operand" "")
776    (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
777             (match_operand:VECF_HW 2 "register_operand" ""))]
778   "TARGET_VX"
780   s390_expand_vec_compare_cc (operands[0],
781                               <fpcmpcc:CODE>,
782                               operands[1],
783                               operands[2],
784                               true);
785   DONE;
788 (define_expand "vec_any_<fpcmpcc:code><mode>"
789   [(match_operand:SI               0 "register_operand" "")
790    (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
791             (match_operand:VECF_HW 2 "register_operand" ""))]
792   "TARGET_VX"
794   s390_expand_vec_compare_cc (operands[0],
795                               <fpcmpcc:CODE>,
796                               operands[1],
797                               operands[2],
798                               false);
799   DONE;
803 ; Compare without generating CC
805 (define_expand "vec_cmp<intcmp:code><VI_HW:mode>"
806   [(set (match_operand:VI_HW               0 "register_operand" "=v")
807         (intcmp:VI_HW (match_operand:VI_HW 1 "register_operand"  "v")
808                       (match_operand:VI_HW 2 "register_operand"  "v")))]
809   "TARGET_VX"
811   s390_expand_vec_compare (operands[0], <intcmp:CODE>, operands[1], operands[2]);
812   DONE;
815 (define_expand "vec_cmp<fpcmp:code><mode>"
816   [(set (match_operand:<tointvec>              0 "register_operand" "=v")
817         (fpcmp:<tointvec> (match_operand:VF_HW 1 "register_operand"  "v")
818                        (match_operand:VF_HW 2 "register_operand"  "v")))]
819   "TARGET_VX"
821   s390_expand_vec_compare (operands[0], <fpcmp:CODE>, operands[1], operands[2]);
822   DONE;
826 ; Vector count leading zeros
828 ; vec_cntlz -> clz
829 ; vec_cnttz -> ctz
831 ; Vector xor
833 ; vec_xor -> xor
835 ; Vector Galois field multiply sum
837 ; vgfmb, vgfmh, vgfmf
838 (define_insn "vec_gfmsum<mode>"
839   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
840         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
841                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
842                           UNSPEC_VEC_GFMSUM))]
843   "TARGET_VX"
844   "vgfm<bhfgq>\t%v0,%v1,%v2"
845   [(set_attr "op_type" "VRR")])
847 (define_insn "vec_gfmsum_128"
848   [(set (match_operand:V16QI 0 "register_operand" "=v")
849         (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
850                        (match_operand:V2DI 2 "register_operand" "v")]
851                       UNSPEC_VEC_GFMSUM_128))]
852   "TARGET_VX"
853   "vgfmg\t%v0,%v1,%v2"
854   [(set_attr "op_type" "VRR")])
856 ; vgfmab, vgfmah, vgfmaf
857 (define_insn "vec_gfmsum_accum<mode>"
858   [(set (match_operand:<vec_double> 0 "register_operand" "=v")
859         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
860                               (match_operand:VI_HW_QHS 2 "register_operand" "v")
861                               (match_operand:<vec_double> 3 "register_operand" "v")]
862                              UNSPEC_VEC_GFMSUM_ACCUM))]
863   "TARGET_VX"
864   "vgfma<bhfgq>\t%v0,%v1,%v2,%v3"
865   [(set_attr "op_type" "VRR")])
867 (define_insn "vec_gfmsum_accum_128"
868   [(set (match_operand:V16QI 0 "register_operand" "=v")
869         (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
870                        (match_operand:V2DI 2 "register_operand" "v")
871                        (match_operand:V16QI 3 "register_operand" "v")]
872                       UNSPEC_VEC_GFMSUM_ACCUM_128))]
873   "TARGET_VX"
874   "vgfmag\t%v0,%v1,%v2,%v3"
875   [(set_attr "op_type" "VRR")])
878 ; FIXME: vec_neg ?
880 ; Vector load positive: vec_abs -> abs
881 ; Vector maximum vec_max -> smax, logical vec_max -> umax
882 ; Vector maximum vec_min -> smin, logical vec_min -> umin
885 ; Vector multiply and add high
887 ; vec_mladd -> vec_vmal
888 ; vmalb, vmalh, vmalf, vmalg
889 (define_insn "vec_vmal<mode>"
890   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
891         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
892                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
893                            (match_operand:VI_HW_QHS 3 "register_operand" "v")]
894                           UNSPEC_VEC_VMAL))]
895   "TARGET_VX"
896   "vmal<bhfgq><w>\t%v0,%v1,%v2,%v3"
897   [(set_attr "op_type" "VRR")])
899 ; vec_mhadd -> vec_vmah/vec_vmalh
901 ; vmahb; vmahh, vmahf, vmahg
902 (define_insn "vec_vmah<mode>"
903   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
904         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
905                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
906                            (match_operand:VI_HW_QHS 3 "register_operand" "v")]
907                           UNSPEC_VEC_VMAH))]
908   "TARGET_VX"
909   "vmah<bhfgq>\t%v0,%v1,%v2,%v3"
910   [(set_attr "op_type" "VRR")])
912 ; vmalhb; vmalhh, vmalhf, vmalhg
913 (define_insn "vec_vmalh<mode>"
914   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
915         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
916                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
917                            (match_operand:VI_HW_QHS 3 "register_operand" "v")]
918                           UNSPEC_VEC_VMALH))]
919   "TARGET_VX"
920   "vmalh<bhfgq>\t%v0,%v1,%v2,%v3"
921   [(set_attr "op_type" "VRR")])
923 ; vec_meadd -> vec_vmae/vec_vmale
925 ; vmaeb; vmaeh, vmaef, vmaeg
926 (define_insn "vec_vmae<mode>"
927   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
928         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
929                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
930                               (match_operand:<vec_double> 3 "register_operand" "v")]
931                              UNSPEC_VEC_VMAE))]
932   "TARGET_VX"
933   "vmae<bhfgq>\t%v0,%v1,%v2,%v3"
934   [(set_attr "op_type" "VRR")])
936 ; vmaleb; vmaleh, vmalef, vmaleg
937 (define_insn "vec_vmale<mode>"
938   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
939         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
940                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
941                               (match_operand:<vec_double> 3 "register_operand" "v")]
942                              UNSPEC_VEC_VMALE))]
943   "TARGET_VX"
944   "vmale<bhfgq>\t%v0,%v1,%v2,%v3"
945   [(set_attr "op_type" "VRR")])
947 ; vec_moadd -> vec_vmao/vec_vmalo
949 ; vmaob; vmaoh, vmaof, vmaog
950 (define_insn "vec_vmao<mode>"
951   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
952         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
953                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
954                               (match_operand:<vec_double> 3 "register_operand" "v")]
955                              UNSPEC_VEC_VMAO))]
956   "TARGET_VX"
957   "vmao<bhfgq>\t%v0,%v1,%v2,%v3"
958   [(set_attr "op_type" "VRR")])
960 ; vmalob; vmaloh, vmalof, vmalog
961 (define_insn "vec_vmalo<mode>"
962   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
963         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
964                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
965                               (match_operand:<vec_double> 3 "register_operand" "v")]
966                              UNSPEC_VEC_VMALO))]
967   "TARGET_VX"
968   "vmalo<bhfgq>\t%v0,%v1,%v2,%v3"
969   [(set_attr "op_type" "VRR")])
972 ; Vector multiply high
974 ; vec_mulh -> vec_smulh/vec_umulh
976 ; vmhb, vmhh, vmhf
977 (define_insn "vec_smulh<mode>"
978   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
979         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
980                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
981                           UNSPEC_VEC_SMULT_HI))]
982   "TARGET_VX"
983   "vmh<bhfgq>\t%v0,%v1,%v2"
984   [(set_attr "op_type" "VRR")])
986 ; vmlhb, vmlhh, vmlhf
987 (define_insn "vec_umulh<mode>"
988   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
989         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
990                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
991                           UNSPEC_VEC_UMULT_HI))]
992   "TARGET_VX"
993   "vmlh<bhfgq>\t%v0,%v1,%v2"
994   [(set_attr "op_type" "VRR")])
997 ; Vector multiply low
999 ; vec_mule -> vec_widen_umult_even/vec_widen_smult_even
1000 ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd
1003 ; Vector nor
1005 (define_insn "vec_nor<mode>3"
1006   [(set (match_operand:VT_HW 0 "register_operand"            "=v")
1007         (not:VT_HW
1008          (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "v")
1009                     (match_operand:VT_HW 2 "register_operand" "v"))))]
1010   "TARGET_VX"
1011   "vno\t%v0,%v1,%v2"
1012   [(set_attr "op_type" "VRR")])
1015 ; Vector or
1017 ; Vector population count vec_popcnt -> popcount
1018 ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot
1020 ; Vector element rotate and insert under mask
1022 ; verimb, verimh, verimf, verimg
1023 (define_insn "verim<mode>"
1024   [(set (match_operand:VI_HW                0 "register_operand" "=v")
1025         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "0")
1026                        (match_operand:VI_HW 2 "register_operand"  "v")
1027                        (match_operand:VI_HW 3 "register_operand"  "v")
1028                        (match_operand:QI    4 "const_int_operand" "C")]
1029                       UNSPEC_VEC_RL_MASK))]
1030   "TARGET_VX"
1031   "verim<bhfgq>\t%v0,%v2,%v3,%b4"
1032   [(set_attr "op_type" "VRI")])
1035 ; Vector shift left
1037 (define_insn "vec_sll<VI_HW:mode><VI_HW_QHS:mode>"
1038   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1039         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1040                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1041                       UNSPEC_VEC_SLL))]
1042   "TARGET_VX"
1043   "vsl\t%v0,%v1,%v2"
1044   [(set_attr "op_type" "VRR")])
1047 ; Vector shift left by byte
1049 ; Pattern definition in vector.md, see vec_vslb
1050 (define_expand "vec_slb<mode>"
1051   [(set (match_operand:V_HW 0 "register_operand"                     "")
1052         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "")
1053                       (match_operand:<tointvec> 2 "register_operand" "")]
1054                      UNSPEC_VEC_SLB))]
1055   "TARGET_VX"
1057   PUT_MODE (operands[2], V16QImode);
1060 ; Vector shift left double by byte
1062 (define_insn "vec_sld<mode>"
1063   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1064         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1065                       (match_operand:V_HW 2 "register_operand" "v")
1066                       (match_operand:QI 3 "const_int_operand"  "C")]
1067                      UNSPEC_VEC_SLDBYTE))]
1068   "TARGET_VX"
1069   "vsldb\t%v0,%v1,%v2,%b3"
1070   [(set_attr "op_type" "VRI")])
1072 (define_expand "vec_sldw<mode>"
1073   [(set (match_operand:V_HW 0 "register_operand"               "")
1074         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1075                       (match_operand:V_HW 2 "register_operand" "")
1076                       (match_operand:QI 3 "const_int_operand"  "")]
1077                      UNSPEC_VEC_SLDBYTE))]
1078   "TARGET_VX"
1080   operands[3] = GEN_INT (INTVAL (operands[3]) << 2);
1083 ; Vector shift left double by bit
1085 (define_insn "vec_sldb<mode>"
1086   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1087         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1088                       (match_operand:V_HW 2 "register_operand" "v")
1089                       (match_operand:QI 3 "const_int_operand"  "C")]
1090                      UNSPEC_VEC_SLDBIT))]
1091   "TARGET_VXE2"
1092   "vsld\t%v0,%v1,%v2,%b3"
1093   [(set_attr "op_type" "VRI")])
1095 ; Vector shift right double by bit
1097 (define_insn "vec_srdb<mode>"
1098   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1099         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1100                       (match_operand:V_HW 2 "register_operand" "v")
1101                       (match_operand:QI 3 "const_int_operand"  "C")]
1102                      UNSPEC_VEC_SRDBIT))]
1103   "TARGET_VXE2"
1104   "vsrd\t%v0,%v1,%v2,%b3"
1105   [(set_attr "op_type" "VRI")])
1107 ; Vector shift right arithmetic
1109 (define_insn "vec_sral<VI_HW:mode><VI_HW_QHS:mode>"
1110   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1111         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1112                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1113                       UNSPEC_VEC_SRAL))]
1114   "TARGET_VX"
1115   "vsra\t%v0,%v1,%v2"
1116   [(set_attr "op_type" "VRR")])
1119 ; Vector shift right arithmetic by byte
1121 (define_insn "vec_srab<mode>"
1122   [(set (match_operand:V_HW 0 "register_operand"                    "=v")
1123         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "v")
1124                       (match_operand:<tointvec> 2 "register_operand" "v")]
1125                      UNSPEC_VEC_SRAB))]
1126   "TARGET_VX"
1127   "vsrab\t%v0,%v1,%v2"
1128   [(set_attr "op_type" "VRR")])
1131 ; Vector shift right logical
1133 (define_insn "vec_srl<VI_HW:mode><VI_HW_QHS:mode>"
1134   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1135         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1136                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1137                       UNSPEC_VEC_SRL))]
1138   "TARGET_VX"
1139   "vsrl\t%v0,%v1,%v2"
1140   [(set_attr "op_type" "VRR")])
1143 ; Vector shift right logical by byte
1145 ; Pattern definition in vector.md, see vec_vsrb
1146 (define_expand "vec_srb<mode>"
1147   [(set (match_operand:V_HW 0 "register_operand"                     "")
1148         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "")
1149                       (match_operand:<tointvec> 2 "register_operand" "")]
1150                      UNSPEC_VEC_SRLB))]
1151   "TARGET_VX"
1153   PUT_MODE (operands[2], V16QImode);
1156 ; Vector subtract
1158 ; Vector subtract compute borrow indication
1160 ; vscbib, vscbih, vscbif, vscbig, vscbiq
1161 (define_insn "vscbi<bhfgq>_<mode>"
1162   [(set (match_operand:VIT_HW 0 "register_operand"                "=v")
1163         (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
1164                         (match_operand:VIT_HW 2 "register_operand" "v")]
1165                       UNSPEC_VEC_SUBC))]
1166   "TARGET_VX"
1167   "vscbi<bhfgq>\t%v0,%v1,%v2"
1168   [(set_attr "op_type" "VRR")])
1170 ; Vector subtract with borrow indication
1172 (define_insn "vsbiq"
1173   [(set (match_operand:TI 0 "register_operand"               "=v")
1174         (unspec:TI [(match_operand:TI 1 "register_operand"    "v")
1175                        (match_operand:TI 2 "register_operand" "v")
1176                        (match_operand:TI 3 "register_operand" "v")]
1177                       UNSPEC_VEC_SUBE_U128))]
1178   "TARGET_VX"
1179   "vsbiq\t%v0,%v1,%v2,%v3"
1180   [(set_attr "op_type" "VRR")])
1183 ; Vector subtract with borrow compute and borrow indication
1185 (define_insn "vsbcbiq"
1186   [(set (match_operand:TI 0 "register_operand"               "=v")
1187         (unspec:TI [(match_operand:TI 1 "register_operand"    "v")
1188                        (match_operand:TI 2 "register_operand" "v")
1189                        (match_operand:TI 3 "register_operand" "v")]
1190                       UNSPEC_VEC_SUBEC_U128))]
1191   "TARGET_VX"
1192   "vsbcbiq\t%v0,%v1,%v2,%v3"
1193   [(set_attr "op_type" "VRR")])
1196 ; Vector sum across
1198 ; Sum across DImode parts of the 1st operand and add the rightmost
1199 ; element of 2nd operand
1200 ; vsumgh, vsumgf
1201 (define_expand "vec_sum2<mode>"
1202   [(set (match_operand:V2DI 0 "register_operand" "")
1203         (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "")
1204                       (match_operand:VI_HW_HS 2 "register_operand" "")]
1205                      UNSPEC_VEC_VSUMG))]
1206   "TARGET_VX")
1208 ; vsumqh, vsumqf
1209 (define_insn "vec_sum_u128<mode>"
1210   [(set (match_operand:V2DI 0 "register_operand" "=v")
1211         (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v")
1212                       (match_operand:VI_HW_SD 2 "register_operand" "v")]
1213                      UNSPEC_VEC_VSUMQ))]
1214   "TARGET_VX"
1215   "vsumq<bhfgq>\t%v0,%v1,%v2"
1216   [(set_attr "op_type" "VRR")])
1218 ; vsumb, vsumh
1219 (define_expand "vec_sum4<mode>"
1220   [(set (match_operand:V4SI 0 "register_operand" "")
1221         (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "")
1222                       (match_operand:VI_HW_QH 2 "register_operand" "")]
1223                      UNSPEC_VEC_VSUM))]
1224   "TARGET_VX")
1227 ; Vector test under mask
1229 (define_expand "vec_test_mask_int<mode>"
1230   [(set (reg:CCRAW CC_REGNUM)
1231         (unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
1232                        (match_operand:<tointvec> 2 "register_operand" "")]
1233                       UNSPEC_VEC_TEST_MASK))
1234    (set (match_operand:SI 0 "register_operand" "")
1235         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1236   "TARGET_VX")
1238 (define_insn "*vec_test_mask<mode>"
1239   [(set (reg:CCRAW CC_REGNUM)
1240         (unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
1241                        (match_operand:<tointvec> 1 "register_operand" "v")]
1242                       UNSPEC_VEC_TEST_MASK))]
1243   "TARGET_VX"
1244   "vtm\t%v0,%v1"
1245   [(set_attr "op_type" "VRR")])
1248 ; Vector multiply sum logical
1250 (define_insn "vec_msumv2di"
1251   [(set (match_operand:V16QI 0 "register_operand" "=v")
1252         (unspec:V16QI [(match_operand:V2DI  1 "register_operand"   "v")
1253                        (match_operand:V2DI  2 "register_operand"   "v")
1254                        (match_operand:V16QI 3 "register_operand"   "v")
1255                        (match_operand:QI    4 "const_mask_operand" "C")]
1256                       UNSPEC_VEC_MSUM))]
1257   "TARGET_VXE"
1258   "vmslg\t%v0,%v1,%v2,%v3,%4"
1259   [(set_attr "op_type" "VRR")])
1261 (define_insn "vmslg"
1262   [(set (match_operand:TI 0 "register_operand" "=v")
1263         (unspec:TI [(match_operand:V2DI  1 "register_operand"   "v")
1264                     (match_operand:V2DI  2 "register_operand"   "v")
1265                     (match_operand:TI    3 "register_operand"   "v")
1266                     (match_operand:QI    4 "const_mask_operand" "C")]
1267                    UNSPEC_VEC_MSUM))]
1268   "TARGET_VXE"
1269   "vmslg\t%v0,%v1,%v2,%v3,%4"
1270   [(set_attr "op_type" "VRR")])
1273 ; Vector find any element equal
1275 ; vfaeb, vfaeh, vfaef
1276 ; vfaezb, vfaezh, vfaezf
1277 (define_insn "vfae<mode>"
1278   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1279         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1280                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
1281                            (match_operand:QI        3 "const_mask_operand" "C")]
1282                           UNSPEC_VEC_VFAE))]
1283   "TARGET_VX"
1285   unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1287   if (flags & VSTRING_FLAG_ZS)
1288     {
1289       flags &= ~VSTRING_FLAG_ZS;
1290       operands[3] = GEN_INT (flags);
1291       return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3";
1292     }
1293   return "vfae<bhfgq>\t%v0,%v1,%v2,%b3";
1295 [(set_attr "op_type" "VRR")])
1297 ; vfaebs, vfaehs, vfaefs
1298 ; vfaezbs, vfaezhs, vfaezfs
1299 (define_insn "*vfaes<mode>"
1300   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1301         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1302                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1303                            (match_operand:QI        3 "const_mask_operand" "C")]
1304                           UNSPEC_VEC_VFAE))
1305    (set (reg:CCRAW CC_REGNUM)
1306         (unspec:CCRAW [(match_dup 1)
1307                        (match_dup 2)
1308                        (match_dup 3)]
1309                       UNSPEC_VEC_VFAECC))]
1310   "TARGET_VX"
1312   unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1314   if (flags & VSTRING_FLAG_ZS)
1315     {
1316       flags &= ~VSTRING_FLAG_ZS;
1317       operands[3] = GEN_INT (flags);
1318       return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3";
1319     }
1320   return "vfae<bhfgq>s\t%v0,%v1,%v2,%b3";
1322   [(set_attr "op_type" "VRR")])
1324 (define_expand "vfaez<mode>"
1325   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1326         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1327                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1328                            (match_operand:QI        3 "const_mask_operand" "")]
1329                           UNSPEC_VEC_VFAE))]
1330   "TARGET_VX"
1332   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS);
1335 (define_expand "vfaes<mode>"
1336   [(parallel
1337     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1338         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1339                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1340                            (match_operand:QI        3 "const_mask_operand" "")]
1341                           UNSPEC_VEC_VFAE))
1342    (set (reg:CCRAW CC_REGNUM)
1343         (unspec:CCRAW [(match_dup 1)
1344                        (match_dup 2)
1345                        (match_dup 3)]
1346                       UNSPEC_VEC_VFAECC))])
1347    (set (match_operand:SI 4 "memory_operand" "")
1348         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1349   "TARGET_VX"
1351   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS);
1354 (define_expand "vfaezs<mode>"
1355   [(parallel
1356     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1357         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1358                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1359                            (match_operand:SI        3 "const_mask_operand" "")]
1360                           UNSPEC_VEC_VFAE))
1361    (set (reg:CCRAW CC_REGNUM)
1362         (unspec:CCRAW [(match_dup 1)
1363                        (match_dup 2)
1364                        (match_dup 3)]
1365                       UNSPEC_VEC_VFAECC))])
1366    (set (match_operand:SI 4 "memory_operand" "")
1367         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1368   "TARGET_VX"
1370   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1374 ; Vector find element equal
1376 ; vfeebs, vfeehs, vfeefs
1377 ; vfeezbs, vfeezhs, vfeezfs
1378 (define_insn "*vfees<mode>"
1379   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1380         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1381                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
1382                            (match_operand:QI 3 "const_mask_operand" "C")]
1383                           UNSPEC_VEC_VFEE))
1384    (set (reg:CCRAW CC_REGNUM)
1385         (unspec:CCRAW [(match_dup 1)
1386                        (match_dup 2)
1387                        (match_dup 3)]
1388                       UNSPEC_VEC_VFEECC))]
1389   "TARGET_VX"
1391   unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1393   gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
1394   flags &= ~VSTRING_FLAG_CS;
1396   if (flags == VSTRING_FLAG_ZS)
1397     return "vfeez<bhfgq>s\t%v0,%v1,%v2";
1398   return "vfee<bhfgq>s\t%v0,%v1,%v2,%b3";
1400   [(set_attr "op_type" "VRR")])
1402 ; vfeeb, vfeeh, vfeef
1403 (define_insn "vfee<mode>"
1404   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1405         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1406                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1407                            (const_int 0)]
1408                           UNSPEC_VEC_VFEE))]
1409   "TARGET_VX"
1410   "vfee<bhfgq>\t%v0,%v1,%v2,0"
1411   [(set_attr "op_type" "VRR")])
1413 ; vfeezb, vfeezh, vfeezf
1414 (define_insn "vfeez<mode>"
1415   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1416         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1417                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1418                            (const_int VSTRING_FLAG_ZS)]
1419                           UNSPEC_VEC_VFEE))]
1420   "TARGET_VX"
1421   "vfeez<bhfgq>s\t%v0,%v1,%v2,2"
1422   [(set_attr "op_type" "VRR")])
1424 (define_expand "vfees<mode>"
1425   [(parallel
1426     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1427           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1428                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1429                              (const_int VSTRING_FLAG_CS)]
1430                             UNSPEC_VEC_VFEE))
1431    (set (reg:CCRAW CC_REGNUM)
1432         (unspec:CCRAW [(match_dup 1)
1433                        (match_dup 2)
1434                        (const_int VSTRING_FLAG_CS)]
1435                       UNSPEC_VEC_VFEECC))])
1436    (set (match_operand:SI 3 "memory_operand" "")
1437         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1438   "TARGET_VX")
1440 (define_expand "vfeezs<mode>"
1441   [(parallel
1442     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1443           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1444                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1445                              (match_dup 4)]
1446                             UNSPEC_VEC_VFEE))
1447    (set (reg:CCRAW CC_REGNUM)
1448         (unspec:CCRAW [(match_dup 1)
1449                        (match_dup 2)
1450                        (match_dup 4)]
1451                       UNSPEC_VEC_VFEECC))])
1452    (set (match_operand:SI 3 "memory_operand" "")
1453         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1454   "TARGET_VX"
1456   operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1459 ; Vector find element not equal
1461 ; vfeneb, vfeneh, vfenef
1462 (define_insn "vfene<mode>"
1463   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1464         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1465                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1466                            (const_int 0)]
1467                           UNSPEC_VEC_VFENE))]
1468   "TARGET_VX"
1469   "vfene<bhfgq>\t%v0,%v1,%v2,0"
1470   [(set_attr "op_type" "VRR")])
1472 ; vec_vfenes can be found in vector.md since it is used for strlen
1474 ; vfenezb, vfenezh, vfenezf
1475 (define_insn "vfenez<mode>"
1476   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1477         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1478                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1479                            (const_int VSTRING_FLAG_ZS)]
1480                           UNSPEC_VEC_VFENE))]
1481   "TARGET_VX"
1482   "vfenez<bhfgq>\t%v0,%v1,%v2"
1483   [(set_attr "op_type" "VRR")])
1485 (define_expand "vfenes<mode>"
1486   [(parallel
1487     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1488           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1489                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1490                              (const_int VSTRING_FLAG_CS)]
1491                             UNSPEC_VEC_VFENE))
1492    (set (reg:CCRAW CC_REGNUM)
1493         (unspec:CCRAW [(match_dup 1)
1494                        (match_dup 2)
1495                        (const_int VSTRING_FLAG_CS)]
1496                       UNSPEC_VEC_VFENECC))])
1497    (set (match_operand:SI 3 "memory_operand" "")
1498         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1499   "TARGET_VX")
1501 (define_expand "vfenezs<mode>"
1502   [(parallel
1503     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1504           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1505                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1506                              (match_dup 4)]
1507                             UNSPEC_VEC_VFENE))
1508      (set (reg:CCRAW CC_REGNUM)
1509           (unspec:CCRAW [(match_dup 1)
1510                          (match_dup 2)
1511                          (match_dup 4)]
1512                         UNSPEC_VEC_VFENECC))])
1513    (set (match_operand:SI 3 "memory_operand" "")
1514         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1515   "TARGET_VX"
1517   operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1520 ; Vector isolate string
1522 ; vistrb, vistrh, vistrf
1523 (define_insn "vistr<mode>"
1524   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1525         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1526                           UNSPEC_VEC_VISTR))]
1527   "TARGET_VX"
1528   "vistr<bhfgq>\t%v0,%v1"
1529   [(set_attr "op_type" "VRR")])
1531 ; vistrbs, vistrhs, vistrfs
1532 (define_insn "*vistrs<mode>"
1533   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1534         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1535                           UNSPEC_VEC_VISTR))
1536    (set (reg:CCRAW CC_REGNUM)
1537         (unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))]
1538   "TARGET_VX"
1539   "vistr<bhfgq>s\t%v0,%v1"
1540   [(set_attr "op_type" "VRR")])
1542 (define_expand "vistrs<mode>"
1543   [(parallel
1544     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1545           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")]
1546                             UNSPEC_VEC_VISTR))
1547      (set (reg:CCRAW CC_REGNUM)
1548           (unspec:CCRAW [(match_dup 1)]
1549                         UNSPEC_VEC_VISTRCC))])
1550    (set (match_operand:SI 2 "memory_operand" "")
1551         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1552   "TARGET_VX")
1555 ; Vector compare range
1557 ; vstrcb, vstrch, vstrcf
1558 ; vstrczb, vstrczh, vstrczf
1559 (define_insn "vstrc<mode>"
1560   [(set (match_operand:VI_HW_QHS                    0 "register_operand"  "=v")
1561         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1562                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1563                            (match_operand:VI_HW_QHS 3 "register_operand"   "v")
1564                            (match_operand:QI        4 "const_mask_operand" "C")]
1565                           UNSPEC_VEC_VSTRC))]
1566   "TARGET_VX"
1568   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1570   if (flags & VSTRING_FLAG_ZS)
1571     {
1572       flags &= ~VSTRING_FLAG_ZS;
1573       operands[4] = GEN_INT (flags);
1574       return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1575     }
1576   return "vstrc<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1578 [(set_attr "op_type" "VRR")])
1580 ; vstrcbs, vstrchs, vstrcfs
1581 ; vstrczbs, vstrczhs, vstrczfs
1582 (define_insn "*vstrcs<mode>"
1583   [(set (match_operand:VI_HW_QHS                    0 "register_operand"  "=v")
1584         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1585                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1586                            (match_operand:VI_HW_QHS 3 "register_operand"   "v")
1587                            (match_operand:QI        4 "const_mask_operand" "C")]
1588                           UNSPEC_VEC_VSTRC))
1589    (set (reg:CCRAW CC_REGNUM)
1590         (unspec:CCRAW [(match_dup 1)
1591                        (match_dup 2)
1592                        (match_dup 3)
1593                        (match_dup 4)]
1594                       UNSPEC_VEC_VSTRCCC))]
1595   "TARGET_VX"
1597   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1599   if (flags & VSTRING_FLAG_ZS)
1600     {
1601       flags &= ~VSTRING_FLAG_ZS;
1602       operands[4] = GEN_INT (flags);
1603       return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1604     }
1605   return "vstrc<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1607   [(set_attr "op_type" "VRR")])
1609 (define_expand "vstrcz<mode>"
1610   [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1611         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "")
1612                            (match_operand:VI_HW_QHS 2 "register_operand"   "")
1613                            (match_operand:VI_HW_QHS 3 "register_operand"   "")
1614                            (match_operand:QI        4 "const_mask_operand" "")]
1615                           UNSPEC_VEC_VSTRC))]
1616   "TARGET_VX"
1618   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS);
1621 (define_expand "vstrcs<mode>"
1622   [(parallel
1623     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1624         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1625                            (match_operand:VI_HW_QHS 2 "register_operand" "")
1626                            (match_operand:VI_HW_QHS 3 "register_operand" "")
1627                            (match_operand:QI        4 "const_mask_operand" "")]
1628                           UNSPEC_VEC_VSTRC))
1629    (set (reg:CCRAW CC_REGNUM)
1630         (unspec:CCRAW [(match_dup 1)
1631                        (match_dup 2)
1632                        (match_dup 3)
1633                        (match_dup 4)]
1634                       UNSPEC_VEC_VSTRCCC))])
1635    (set (match_operand:SI 5 "memory_operand" "")
1636         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1637   "TARGET_VX"
1639   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS);
1642 (define_expand "vstrczs<mode>"
1643   [(parallel
1644     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1645         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1646                            (match_operand:VI_HW_QHS 2 "register_operand" "")
1647                            (match_operand:VI_HW_QHS 3 "register_operand" "")
1648                            (match_operand:QI        4 "const_mask_operand" "")]
1649                           UNSPEC_VEC_VSTRC))
1650    (set (reg:CCRAW CC_REGNUM)
1651         (unspec:CCRAW [(match_dup 1)
1652                        (match_dup 2)
1653                        (match_dup 3)
1654                        (match_dup 4)]
1655                       UNSPEC_VEC_VSTRCCC))])
1656    (set (match_operand:SI 5 "memory_operand" "")
1657         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1658   "TARGET_VX"
1660   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1663 ; Vector string search
1665 (define_expand "vstrs<mode>"
1666   [(parallel
1667     [(set (match_operand:V16QI                    0 "register_operand" "")
1668           (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1669                          (match_operand:VI_HW_QHS 2 "register_operand" "")
1670                          (match_operand:V16QI     3 "register_operand" "")
1671                          (const_int 0)]
1672                         UNSPEC_VEC_VSTRS))
1673      (set (reg:CCRAW CC_REGNUM)
1674           (unspec:CCRAW [(match_dup 1)
1675                          (match_dup 2)
1676                          (match_dup 3)
1677                          (const_int 0)]
1678                         UNSPEC_VEC_VSTRSCC))])
1679    (set (match_operand:SI 4 "memory_operand" "")
1680         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1681   "TARGET_VXE2")
1683 (define_expand "vstrsz<mode>"
1684   [(parallel
1685     [(set (match_operand:V16QI                    0 "register_operand" "")
1686           (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1687                          (match_operand:VI_HW_QHS 2 "register_operand" "")
1688                          (match_operand:V16QI     3 "register_operand" "")
1689                          (const_int VSTRING_FLAG_ZS)]
1690                         UNSPEC_VEC_VSTRS))
1691      (set (reg:CCRAW CC_REGNUM)
1692           (unspec:CCRAW [(match_dup 1)
1693                          (match_dup 2)
1694                          (match_dup 3)
1695                          (const_int VSTRING_FLAG_ZS)]
1696                         UNSPEC_VEC_VSTRSCC))])
1697    (set (match_operand:SI 4 "memory_operand" "")
1698         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1699   "TARGET_VXE2")
1701 ; vstrsb, vstrsh, vstrsf
1702 ; vstrszb, vstrszh, vstrszf
1703 (define_insn "vec_vstrs<mode>"
1704   [(set (match_operand:V16QI                    0 "register_operand" "=v")
1705         (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1706                        (match_operand:VI_HW_QHS 2 "register_operand" "v")
1707                        (match_operand:V16QI     3 "register_operand" "v")
1708                        (match_operand:QI        4 "const_mask_operand" "C")]
1709                       UNSPEC_VEC_VSTRS))
1710    (set (reg:CCRAW CC_REGNUM)
1711         (unspec:CCRAW [(match_dup 1)
1712                        (match_dup 2)
1713                        (match_dup 3)
1714                        (match_dup 4)]
1715                       UNSPEC_VEC_VSTRSCC))]
1716   "TARGET_VXE2"
1718   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1720   gcc_assert (!(flags & ~VSTRING_FLAG_ZS));
1722   if (flags == VSTRING_FLAG_ZS)
1723     return "vstrsz<bhfgq>\t%v0,%v1,%v2,%v3";
1724   return "vstrs<bhfgq>\t%v0,%v1,%v2,%v3";
1726   [(set_attr "op_type" "VRR")])
1729 ; Vector convert int<->float
1731 (define_insn "vcdgb"
1732   [(set (match_operand:V2DF 0 "register_operand"                "=v")
1733         (unspec:V2DF [(match_operand:V2DI 1 "register_operand"   "v")
1734                       (match_operand:QI   2 "const_mask_operand" "C")  ; inexact suppression
1735                       (match_operand:QI   3 "const_mask_operand" "C")] ; rounding mode
1736                      UNSPEC_VEC_VCDGB))]
1737   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1738   "vcdgb\t%v0,%v1,%b2,%b3"
1739   [(set_attr "op_type" "VRR")])
1742 ; The result needs to be multiplied with 2**-op2
1743 (define_expand "vec_ctd_s64"
1744   [(set (match_operand:V2DF               0 "register_operand" "")
1745         (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1746                       (const_int VEC_NOINEXACT)
1747                       (const_int VEC_RND_CURRENT)]
1748                      UNSPEC_VEC_VCDGB))
1749    (use (match_operand:QI 2 "const_int_operand" ""))
1750    (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1751   "TARGET_VX"
1753   REAL_VALUE_TYPE f;
1754   rtx c;
1756   real_2expN (&f, -INTVAL (operands[2]), DFmode);
1757   c = const_double_from_real_value (f, DFmode);
1759   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1760   operands[3] = force_reg (V2DFmode, operands[3]);
1763 (define_insn "vcdlgb"
1764   [(set (match_operand:V2DF 0 "register_operand"                 "=v")
1765         (unspec:V2DF [(match_operand:V2DI 1 "register_operand"    "v")
1766                       (match_operand:QI   2 "const_mask_operand"  "C")  ; inexact suppression
1767                       (match_operand:QI   3 "const_mask_operand"  "C")] ; rounding mode
1768                      UNSPEC_VEC_VCDLGB))]
1769   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1770   "vcdlgb\t%v0,%v1,%b2,%b3"
1771   [(set_attr "op_type" "VRR")])
1773 ; The result needs to be multiplied with 2**-op2
1774 (define_expand "vec_ctd_u64"
1775   [(set (match_operand:V2DF               0 "register_operand" "")
1776         (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1777                       (const_int VEC_NOINEXACT)
1778                       (const_int VEC_RND_CURRENT)]
1779                      UNSPEC_VEC_VCDLGB))
1780    (use (match_operand:QI 2 "const_int_operand" ""))
1781    (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1782   "TARGET_VX"
1784   REAL_VALUE_TYPE f;
1785   rtx c;
1787   real_2expN (&f, -INTVAL (operands[2]), DFmode);
1788   c = const_double_from_real_value (f, DFmode);
1790   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1791   operands[3] = force_reg (V2DFmode, operands[3]);
1794 (define_insn "vcgdb"
1795   [(set (match_operand:V2DI 0 "register_operand"                "=v")
1796         (unspec:V2DI [(match_operand:V2DF 1 "register_operand"   "v")
1797                       (match_operand:QI   2 "const_mask_operand" "C")
1798                       (match_operand:QI   3 "const_mask_operand" "C")]
1799                      UNSPEC_VEC_VCGDB))]
1800   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1801   "vcgdb\t%v0,%v1,%b2,%b3"
1802   [(set_attr "op_type" "VRR")])
1804 ; The input needs to be multiplied with 2**op2
1805 (define_expand "vec_ctsl"
1806   [(use (match_operand:QI 2 "const_int_operand" ""))
1807    (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1808                                  (match_dup 3)))
1809    (set (match_operand:V2DI 0 "register_operand" "")
1810         (unspec:V2DI [(match_dup 4)
1811                       (const_int VEC_NOINEXACT)
1812                       (const_int VEC_RND_CURRENT)]
1813                      UNSPEC_VEC_VCGDB))]
1814   "TARGET_VX"
1816   REAL_VALUE_TYPE f;
1817   rtx c;
1819   real_2expN (&f, INTVAL (operands[2]), DFmode);
1820   c = const_double_from_real_value (f, DFmode);
1822   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1823   operands[3] = force_reg (V2DFmode, operands[3]);
1824   operands[4] = gen_reg_rtx (V2DFmode);
1827 (define_insn "vclgdb"
1828   [(set (match_operand:V2DI 0 "register_operand"               "=v")
1829         (unspec:V2DI [(match_operand:V2DF 1 "register_operand"  "v")
1830                       (match_operand:QI   2 "const_mask_operand" "C")
1831                       (match_operand:QI   3 "const_mask_operand" "C")]
1832                      UNSPEC_VEC_VCLGDB))]
1833   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1834   "vclgdb\t%v0,%v1,%b2,%b3"
1835   [(set_attr "op_type" "VRR")])
1837 ; The input needs to be multiplied with 2**op2
1838 (define_expand "vec_ctul"
1839   [(use (match_operand:QI 2 "const_int_operand" ""))
1840    (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1841                                  (match_dup 3)))
1842    (set (match_operand:V2DI 0 "register_operand" "")
1843         (unspec:V2DI [(match_dup 4)
1844                       (const_int VEC_NOINEXACT)
1845                       (const_int VEC_RND_CURRENT)]
1846                      UNSPEC_VEC_VCLGDB))]
1847   "TARGET_VX"
1849   REAL_VALUE_TYPE f;
1850   rtx c;
1852   real_2expN (&f, INTVAL (operands[2]), DFmode);
1853   c = const_double_from_real_value (f, DFmode);
1855   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1856   operands[3] = force_reg (V2DFmode, operands[3]);
1857   operands[4] = gen_reg_rtx (V2DFmode);
1860 ; Vector load fp integer - IEEE inexact exception is suppressed
1861 ; vfisb, vfidb, wfisb, wfidb, wfixb
1862 (define_insn "vec_fpint<mode>"
1863   [(set (match_operand:VFT              0 "register_operand"  "=v")
1864         (unspec:VFT [(match_operand:VFT 1 "register_operand"   "v")
1865                      (match_operand:QI  2 "const_mask_operand" "C")  ; inexact suppression control
1866                      (match_operand:QI  3 "const_mask_operand" "C")] ; rounding mode
1867                      UNSPEC_VEC_VFI))]
1868   "TARGET_VX"
1869   "<vw>fi<sdx>b\t%v0,%v1,%b2,%b3"
1870   [(set_attr "op_type" "VRR")])
1873 ; Vector load lengthened - V4SF -> V2DF
1875 (define_insn "vflls"
1876   [(set (match_operand:V2DF 0 "register_operand"               "=v")
1877         (unspec:V2DF [(match_operand:V4SF 1 "register_operand"  "v")]
1878                      UNSPEC_VEC_VFLL))]
1879   "TARGET_VX"
1880   "vldeb\t%v0,%v1"
1881   [(set_attr "op_type" "VRR")])
1883 (define_expand "vec_ld2f"
1884   [; Initialize a vector to all zeroes.  FIXME: This should not be
1885    ; necessary since all elements of the vector will be set anyway.
1886    ; This is just to make it explicit to the data flow framework.
1887    (set (match_dup 2) (match_dup 3))
1888    (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "")
1889                                     (const_int 0)
1890                                     (match_dup 2)]
1891                                     UNSPEC_VEC_SET))
1892    (set (match_dup 2) (unspec:V4SF [(match_dup 4)
1893                                     (const_int 2)
1894                                     (match_dup 2)]
1895                                     UNSPEC_VEC_SET))
1896    (set (match_operand:V2DF 0 "register_operand" "")
1897         (unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VFLL))]
1898   "TARGET_VX"
1900   operands[2] = gen_reg_rtx (V4SFmode);
1901   operands[3] = CONST0_RTX (V4SFmode);
1902   operands[4] = adjust_address (operands[1], SFmode, 4);
1906 ; Vector load rounded - V2DF -> V4SF
1908 (define_insn "vflrd"
1909   [(set (match_operand:V4SF 0 "register_operand"                "=v")
1910         (unspec:V4SF [(match_operand:V2DF 1 "register_operand"   "v")
1911                       (match_operand:QI   2 "const_mask_operand" "C")
1912                       (match_operand:QI   3 "const_mask_operand" "C")]
1913                      UNSPEC_VEC_VFLR))]
1914   "TARGET_VX"
1915   "vledb\t%v0,%v1,%b2,%b3"
1916   [(set_attr "op_type" "VRR")])
1918 (define_expand "vec_st2f"
1919   [(set (match_dup 2)
1920         (unspec:V4SF [(match_operand:V2DF 0 "register_operand" "")
1921                       (const_int VEC_INEXACT)
1922                       (const_int VEC_RND_CURRENT)]
1923                      UNSPEC_VEC_VFLR))
1924    (set (match_operand:SF 1 "memory_operand" "")
1925         (unspec:SF [(match_dup 2) (const_int 0)] UNSPEC_VEC_EXTRACT))
1926    (set (match_dup 3)
1927         (unspec:SF [(match_dup 2) (const_int 2)] UNSPEC_VEC_EXTRACT))]
1928   "TARGET_VX"
1930   operands[2] = gen_reg_rtx (V4SFmode);
1931   operands[3] = adjust_address (operands[1], SFmode, 4);
1935 ; Vector square root fp vec_sqrt -> sqrt rtx standard name
1937 ;; Vector FP test data class immediate
1939 ; vec_all_nan, vec_all_numeric, vec_any_nan, vec_any_numeric
1940 ; These ignore the vector result and only want CC stored to an int
1941 ; pointer.
1943 ; vftcisb, vftcidb
1944 (define_insn "*vftci<mode>_cconly"
1945   [(set (reg:CCRAW CC_REGNUM)
1946         (unspec:CCRAW [(match_operand:VECF_HW 1 "register_operand")
1947                        (match_operand:HI      2 "const_int_operand")]
1948                       UNSPEC_VEC_VFTCICC))
1949    (clobber (match_scratch:<tointvec> 0))]
1950   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1951   "vftci<sdx>b\t%v0,%v1,%x2"
1952   [(set_attr "op_type" "VRR")])
1954 (define_expand "vftci<mode>_intcconly"
1955   [(parallel
1956     [(set (reg:CCRAW CC_REGNUM)
1957           (unspec:CCRAW [(match_operand:VECF_HW 0 "register_operand")
1958                          (match_operand:HI      1 "const_int_operand")]
1959                         UNSPEC_VEC_VFTCICC))
1960      (clobber (scratch:<tointvec>))])
1961    (set (match_operand:SI 2 "register_operand" "")
1962         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1963   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")")
1965 ; vec_fp_test_data_class wants the result vector and the CC stored to
1966 ; an int pointer.
1968 ; vftcisb, vftcidb
1969 (define_insn "*vftci<mode>"
1970   [(set (match_operand:VECF_HW                  0 "register_operand"  "=v")
1971         (unspec:VECF_HW [(match_operand:VECF_HW 1 "register_operand"   "v")
1972                          (match_operand:HI      2 "const_int_operand"  "J")]
1973                         UNSPEC_VEC_VFTCI))
1974    (set (reg:CCRAW CC_REGNUM)
1975         (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))]
1976   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1977   "vftci<sdx>b\t%v0,%v1,%x2"
1978   [(set_attr "op_type" "VRR")])
1980 (define_expand "vftci<mode>_intcc"
1981   [(parallel
1982     [(set (match_operand:VECF_HW                  0 "register_operand")
1983           (unspec:VECF_HW [(match_operand:VECF_HW 1 "register_operand")
1984                            (match_operand:HI      2 "const_int_operand")]
1985                           UNSPEC_VEC_VFTCI))
1986      (set (reg:CCRAW CC_REGNUM)
1987           (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))])
1988    (set (match_operand:SI 3 "memory_operand" "")
1989         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1990   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")")
1993 ;; Integer compares
1996 ; All comparisons which produce a CC need fully populated (VI_HW)
1997 ; vector arguments.  Otherwise the any/all CCs would be just bogus.
1999 (define_insn "*vec_cmp<VICMP:insn_cmp><VI_HW:mode>_cconly"
2000   [(set (reg:VICMP CC_REGNUM)
2001         (compare:VICMP (match_operand:VI_HW 0 "register_operand" "v")
2002                        (match_operand:VI_HW 1 "register_operand" "v")))
2003    (clobber (match_scratch:VI_HW 2 "=v"))]
2004   "TARGET_VX"
2005   "vc<VICMP:insn_cmp><VI_HW:bhfgq>s\t%v2,%v0,%v1"
2006   [(set_attr "op_type" "VRR")])
2008 ; FIXME: The following 2x3 definitions should be merged into 2 with
2009 ; VICMP like above but I could not find a way to set the comparison
2010 ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the
2011 ; other way around - setting the mode depending on the code
2012 ; (code_iterator).
2013 (define_expand "vec_cmpeq<VI_HW:mode>_cc"
2014   [(parallel
2015     [(set (reg:CCVEQ CC_REGNUM)
2016         (compare:CCVEQ (match_operand:VI_HW 1 "register_operand" "v")
2017                        (match_operand:VI_HW 2 "register_operand" "v")))
2018      (set (match_operand:VI_HW 0 "register_operand" "=v")
2019           (eq:VI_HW (match_dup 1) (match_dup 2)))])
2020    (set (match_operand:SI 3 "memory_operand" "")
2021         (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2022   "TARGET_VX")
2024 (define_expand "vec_cmph<VI_HW:mode>_cc"
2025   [(parallel
2026     [(set (reg:CCVIH CC_REGNUM)
2027           (compare:CCVIH (match_operand:VI_HW 1 "register_operand" "v")
2028                          (match_operand:VI_HW 2 "register_operand" "v")))
2029      (set (match_operand:VI_HW 0 "register_operand" "=v")
2030           (gt:VI_HW (match_dup 1) (match_dup 2)))])
2031    (set (match_operand:SI 3 "memory_operand" "")
2032         (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2033   "TARGET_VX")
2035 (define_expand "vec_cmphl<VI_HW:mode>_cc"
2036   [(parallel
2037     [(set (reg:CCVIHU CC_REGNUM)
2038           (compare:CCVIHU (match_operand:VI_HW 1 "register_operand" "v")
2039                           (match_operand:VI_HW 2 "register_operand" "v")))
2040      (set (match_operand:VI_HW 0 "register_operand" "=v")
2041           (gtu:VI_HW (match_dup 1) (match_dup 2)))])
2042    (set (match_operand:SI 3 "memory_operand" "")
2043         (unspec:SI [(reg:CCVIHU CC_REGNUM)] UNSPEC_CC_TO_INT))]
2044   "TARGET_VX")
2047 (define_insn "*vec_cmpeq<VI_HW:mode>_cc"
2048   [(set (reg:CCVEQ CC_REGNUM)
2049         (compare:CCVEQ (match_operand:VI_HW 0 "register_operand"  "v")
2050                        (match_operand:VI_HW 1 "register_operand"  "v")))
2051    (set (match_operand:VI_HW                2 "register_operand" "=v")
2052         (eq:VI_HW (match_dup 0) (match_dup 1)))]
2053   "TARGET_VX"
2054   "vceq<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2055   [(set_attr "op_type" "VRR")])
2057 (define_insn "*vec_cmph<VI_HW:mode>_cc"
2058   [(set (reg:CCVIH CC_REGNUM)
2059         (compare:CCVIH (match_operand:VI_HW 0 "register_operand"  "v")
2060                        (match_operand:VI_HW 1 "register_operand"  "v")))
2061    (set (match_operand:VI_HW               2 "register_operand" "=v")
2062         (gt:VI_HW (match_dup 0) (match_dup 1)))]
2063   "TARGET_VX"
2064   "vch<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2065   [(set_attr "op_type" "VRR")])
2067 (define_insn "*vec_cmphl<VI_HW:mode>_cc"
2068   [(set (reg:CCVIHU CC_REGNUM)
2069         (compare:CCVIHU (match_operand:VI_HW 0 "register_operand"  "v")
2070                         (match_operand:VI_HW 1 "register_operand"  "v")))
2071    (set (match_operand:VI_HW                2 "register_operand" "=v")
2072         (gtu:VI_HW (match_dup 0) (match_dup 1)))]
2073   "TARGET_VX"
2074   "vchl<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2075   [(set_attr "op_type" "VRR")])
2078 ;; Floating point compares
2081 ; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs
2082 (define_insn "*vec_cmp<insn_cmp><VF_HW:mode>_cconly"
2083   [(set (reg:VFCMP CC_REGNUM)
2084         (compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
2085                        (match_operand:VF_HW 1 "register_operand" "v")))
2086    (clobber (match_scratch:<tointvec> 2 "=v"))]
2087   "TARGET_VX"
2088   "<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1"
2089   [(set_attr "op_type" "VRR")])
2091 ; FIXME: Merge the following 2x3 patterns with VFCMP
2092 (define_expand "vec_cmpeq<mode>_cc"
2093   [(parallel
2094     [(set (reg:CCVEQ CC_REGNUM)
2095           (compare:CCVEQ (match_operand:VF_HW 1 "register_operand"  "v")
2096                          (match_operand:VF_HW 2 "register_operand"  "v")))
2097      (set (match_operand:<tointvec> 0 "register_operand" "=v")
2098           (eq:<tointvec> (match_dup 1) (match_dup 2)))])
2099    (set (match_operand:SI 3 "memory_operand" "")
2100         (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2101   "TARGET_VX")
2103 (define_expand "vec_cmph<mode>_cc"
2104   [(parallel
2105     [(set (reg:CCVFH CC_REGNUM)
2106           (compare:CCVFH (match_operand:VF_HW 1 "register_operand"  "v")
2107                          (match_operand:VF_HW 2 "register_operand"  "v")))
2108      (set (match_operand:<tointvec> 0 "register_operand" "=v")
2109           (gt:<tointvec> (match_dup 1) (match_dup 2)))])
2110    (set (match_operand:SI 3 "memory_operand" "")
2111         (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2112   "TARGET_VX")
2114 (define_expand "vec_cmphe<mode>_cc"
2115   [(parallel
2116     [(set (reg:CCVFHE CC_REGNUM)
2117           (compare:CCVFHE (match_operand:VF_HW 1 "register_operand"  "v")
2118                           (match_operand:VF_HW 2 "register_operand"  "v")))
2119      (set (match_operand:<tointvec> 0 "register_operand" "=v")
2120           (ge:<tointvec> (match_dup 1) (match_dup 2)))])
2121    (set (match_operand:SI 3 "memory_operand" "")
2122         (unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]
2123   "TARGET_VX")
2125 ; These 3 cannot be merged as the insn defintion above since it also
2126 ; requires to rewrite the RTL equality operator that the same time as
2127 ; the CC mode.
2129 ; vfcesbs, vfcedbs, wfcexbs
2130 (define_insn "*vec_cmpeq<mode>_cc"
2131   [(set (reg:CCVEQ CC_REGNUM)
2132         (compare:CCVEQ (match_operand:VF_HW 0 "register_operand"  "v")
2133                        (match_operand:VF_HW 1 "register_operand"  "v")))
2134    (set (match_operand:<tointvec>              2 "register_operand" "=v")
2135         (eq:<tointvec> (match_dup 0) (match_dup 1)))]
2136   "TARGET_VX"
2137   "<vw>fce<sdx>bs\t%v2,%v0,%v1"
2138   [(set_attr "op_type" "VRR")])
2140 ; vfchsbs, vfchdbs, wfchxbs
2141 (define_insn "*vec_cmph<mode>_cc"
2142   [(set (reg:CCVFH CC_REGNUM)
2143         (compare:CCVFH (match_operand:VF_HW 0 "register_operand"  "v")
2144                        (match_operand:VF_HW 1 "register_operand"  "v")))
2145    (set (match_operand:<tointvec>              2 "register_operand" "=v")
2146         (gt:<tointvec> (match_dup 0) (match_dup 1)))]
2147   "TARGET_VX"
2148   "<vw>fch<sdx>bs\t%v2,%v0,%v1"
2149   [(set_attr "op_type" "VRR")])
2151 ; vfchesbs, vfchedbs, wfchexbs
2152 (define_insn "*vec_cmphe<mode>_cc"
2153   [(set (reg:CCVFHE CC_REGNUM)
2154         (compare:CCVFHE (match_operand:VF_HW 0 "register_operand"  "v")
2155                         (match_operand:VF_HW 1 "register_operand"  "v")))
2156    (set (match_operand:<tointvec>            2 "register_operand" "=v")
2157         (ge:<tointvec> (match_dup 0) (match_dup 1)))]
2158   "TARGET_VX"
2159   "<vw>fche<sdx>bs\t%v2,%v0,%v1"
2160   [(set_attr "op_type" "VRR")])
2163 (define_insn "vfmin<mode>"
2164   [(set (match_operand:VF_HW                0 "register_operand"  "=v")
2165         (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand"   "v")
2166                        (match_operand:VF_HW 2 "register_operand"   "v")
2167                        (match_operand:QI    3 "const_mask_operand" "C")]
2168                       UNSPEC_VEC_VFMIN))]
2169   "TARGET_VXE"
2170   "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3"
2171   [(set_attr "op_type" "VRR")])
2173 (define_insn "vfmax<mode>"
2174   [(set (match_operand:VF_HW                0 "register_operand"  "=v")
2175         (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand"   "v")
2176                        (match_operand:VF_HW 2 "register_operand"   "v")
2177                        (match_operand:QI    3 "const_mask_operand" "C")]
2178                       UNSPEC_VEC_VFMAX))]
2179   "TARGET_VXE"
2180   "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3"
2181   [(set_attr "op_type" "VRR")])
2183 ; The element reversal builtins introduced with z15 have been made
2184 ; available also for older CPUs down to z13.
2185 (define_expand "eltswap<mode>"
2186   [(set (match_operand:VEC_HW                 0 "nonimmediate_operand" "")
2187         (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "")]
2188                        UNSPEC_VEC_ELTSWAP))]
2189   "TARGET_VX")
2191 ; The byte element reversal is implemented as 128 bit byte swap.
2192 ; Alternatively this could be emitted as bswap:V1TI but the required
2193 ; subregs appear to confuse combine.
2194 (define_insn "*eltswapv16qi"
2195   [(set (match_operand:V16QI                0 "nonimmediate_operand" "=v,v,R")
2196         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand"  "v,R,v")]
2197                       UNSPEC_VEC_ELTSWAP))]
2198   "TARGET_VXE2"
2199   "@
2200    #
2201    vlbrq\t%v0,%v1
2202    vstbrq\t%v1,%v0"
2203   [(set_attr "op_type" "*,VRX,VRX")])
2205 ; vlerh, vlerf, vlerg, vsterh, vsterf, vsterg
2206 (define_insn "*eltswap<mode>"
2207   [(set (match_operand:V_HW_HSD                   0 "nonimmediate_operand" "=v,v,R")
2208         (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "nonimmediate_operand"  "v,R,v")]
2209                          UNSPEC_VEC_ELTSWAP))]
2210   "TARGET_VXE2"
2211   "@
2212    #
2213    vler<bhfgq>\t%v0,%v1
2214    vster<bhfgq>\t%v1,%v0"
2215   [(set_attr "op_type" "*,VRX,VRX")])
2217 ; z15 has instructions for doing element reversal from mem to reg
2218 ; or the other way around.  For reg to reg or on pre z15 machines
2219 ; we have to emulate it with vector permute.
2220 (define_insn_and_split "*eltswap<mode>_emu"
2221   [(set (match_operand:VEC_HW                 0 "nonimmediate_operand" "=vR")
2222         (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "vR")]
2223                        UNSPEC_VEC_ELTSWAP))]
2224   "TARGET_VX && can_create_pseudo_p ()"
2225   "#"
2226   "&& ((!memory_operand (operands[0], <MODE>mode)
2227         && !memory_operand (operands[1], <MODE>mode))
2228        || !TARGET_VXE2)"
2229   [(set (match_dup 3)
2230         (unspec:V16QI [(match_dup 4)
2231                        (match_dup 4)
2232                        (match_dup 2)]
2233                       UNSPEC_VEC_PERM))
2234    (set (match_dup 0) (subreg:VEC_HW (match_dup 3) 0))]
2236   static char p[4][16] =
2237     { { 15, 14, 13, 12, 11, 10, 9,  8,  7,  6,  5,  4,  3,  2,  1,  0 },   /* Q */
2238       { 14, 15, 12, 13, 10, 11, 8,  9,  6,  7,  4,  5,  2,  3,  0,  1 },   /* H */
2239       { 12, 13, 14, 15, 8,  9,  10, 11, 4,  5,  6,  7,  0,  1,  2,  3 },   /* S */
2240       { 8,  9,  10, 11, 12, 13, 14, 15, 0,  1,  2,  3,  4,  5,  6,  7 } }; /* D */
2241   char *perm;
2242   rtx perm_rtx[16], constv;
2244   switch (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)))
2245     {
2246     case 1: perm = p[0]; break;
2247     case 2: perm = p[1]; break;
2248     case 4: perm = p[2]; break;
2249     case 8: perm = p[3]; break;
2250     default: gcc_unreachable ();
2251     }
2253   for (int i = 0; i < 16; i++)
2254     perm_rtx[i] = GEN_INT (perm[i]);
2256   operands[1] = force_reg (<MODE>mode, operands[1]);
2257   operands[2] = gen_reg_rtx (V16QImode);
2258   operands[3] = gen_reg_rtx (V16QImode);
2259   operands[4] = simplify_gen_subreg (V16QImode, operands[1], <MODE>mode, 0);
2260   constv = force_const_mem (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm_rtx)));
2261   emit_move_insn (operands[2], constv);
2264 ; vec_insert (__builtin_bswap32 (*a), b, 1)        set-element-bswap-2.c
2265 ; b[1] = __builtin_bswap32 (*a)                    set-element-bswap-3.c
2266 ; vlebrh, vlebrf, vlebrg
2267 (define_insn "*vec_set_bswap_elem<mode>"
2268   [(set (match_operand:V_HW_HSD                                     0 "register_operand" "=v")
2269         (unspec:V_HW_HSD [(bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand"    "R"))
2270                                            (match_operand:SI        2 "const_int_operand" "C")
2271                                            (match_operand:V_HW_HSD  3 "register_operand"  "0")]
2272                   UNSPEC_VEC_SET))]
2273   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2274   "vlebr<bhfgq>\t%v0,%1,%2"
2275   [(set_attr "op_type" "VRX")])
2277 ; vec_revb (vec_insert (*a, vec_revb (b), 1))      set-element-bswap-1.c
2278 ; vlebrh, vlebrf, vlebrg
2279 (define_insn "*vec_set_bswap_vec<mode>"
2280   [(set (match_operand:V_HW_HSD                                     0 "register_operand"       "=v")
2281         (bswap:V_HW_HSD
2282          (unspec:V_HW_HSD [(match_operand:<non_vec>                 1 "memory_operand"          "R")
2283                            (match_operand:SI                        2 "const_int_operand"       "C")
2284                            (bswap:V_HW_HSD (match_operand:V_HW_HSD  3 "register_operand"        "0"))]
2285                           UNSPEC_VEC_SET)))
2286    (use (match_operand:V16QI                                        4 "permute_pattern_operand" "X"))]
2287   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2288   "vlebr<bhfgq>\t%v0,%1,%2"
2289   [(set_attr "op_type" "VRX")])
2291 ; *a = vec_extract (vec_revb (b), 1);              get-element-bswap-3.c
2292 ; *a = vec_revb (b)[1];                            get-element-bswap-4.c
2293 ; vstebrh, vstebrf, vstebrg
2294 (define_insn "*vec_extract_bswap_vec<mode>"
2295   [(set (match_operand:<non_vec>                                    0 "memory_operand"   "=R")
2296         (unspec:<non_vec> [(bswap:V_HW_HSD (match_operand:V_HW_HSD  1 "register_operand"  "v"))
2297                            (match_operand:SI                        2 "const_int_operand" "C")]
2298                            UNSPEC_VEC_EXTRACT))]
2299   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2300   "vstebr<bhfgq>\t%v1,%0,%2"
2301   [(set_attr "op_type" "VRX")])
2303 ; *a = __builtin_bswap32 (vec_extract (b, 1));     get-element-bswap-1.c
2304 ; *a = __builtin_bswap32 (b[1]);                   get-element-bswap-2.c
2305 ; vstebrh, vstebrf, vstebrg
2306 (define_insn "*vec_extract_bswap_elem<mode>"
2307   [(set (match_operand:<non_vec>                     0 "memory_operand"   "=R")
2308         (bswap:<non_vec>
2309          (unspec:<non_vec> [(match_operand:V_HW_HSD  1 "register_operand"  "v")
2310                             (match_operand:SI        2 "const_int_operand" "C")]
2311                            UNSPEC_VEC_EXTRACT)))]
2312   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2313   "vstebr<bhfgq>\t%v1,%0,%2"
2314   [(set_attr "op_type" "VRX")])