Add assember CFI directives to millicode division and remainder routines.
[official-gcc.git] / gcc / config / s390 / vx-builtins.md
blobf4248c55d4ec5b71cca75082cbdbefd9689167d3
1 ;;- Instruction patterns for the System z vector facility builtins.
2 ;;  Copyright (C) 2015-2023 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])
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 ; vmrhb, vmrhh, vmrhf, vmrhg
236 (define_expand "vec_mergeh<mode>"
237   [(match_operand:V_128_NOSINGLE 0 "register_operand" "")
238    (match_operand:V_128_NOSINGLE 1 "register_operand" "")
239    (match_operand:V_128_NOSINGLE 2 "register_operand" "")]
240   "TARGET_VX"
242   s390_expand_merge (operands[0], operands[1], operands[2], true);
243   DONE;
246 ; vmrlb, vmrlh, vmrlf, vmrlg
247 (define_expand "vec_mergel<mode>"
248   [(match_operand:V_128_NOSINGLE 0 "register_operand" "")
249    (match_operand:V_128_NOSINGLE 1 "register_operand" "")
250    (match_operand:V_128_NOSINGLE 2 "register_operand" "")]
251   "TARGET_VX"
253   s390_expand_merge (operands[0], operands[1], operands[2], false);
254   DONE;
258 ; Vector pack
260 ; vpkh, vpkf, vpkg
261 (define_insn "vec_pack<mode>"
262   [(set (match_operand:<vec_half>                    0 "register_operand" "=v")
263         (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
264                             (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
265                            UNSPEC_VEC_PACK))]
266   "TARGET_VX"
267   "vpk<bhfgq>\t%v0,%v1,%v2"
268   [(set_attr "op_type" "VRR")])
271 ; Vector pack saturate
273 ; vpksh, vpksf, vpksg
274 (define_insn "vec_packs<mode>"
275   [(set (match_operand:<vec_half>                    0 "register_operand" "=v")
276         (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
277                             (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
278                            UNSPEC_VEC_PACK_SATURATE))]
279   "TARGET_VX"
280   "vpks<bhfgq>\t%v0,%v1,%v2"
281   [(set_attr "op_type" "VRR")])
284 ; This is vec_packs_cc + loading cc into a caller specified memory location.
285 (define_expand "vec_packs_cc<mode>"
286   [(parallel
287     [(set (reg:CCRAW CC_REGNUM)
288           (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
289                          (match_operand:VI_HW_HSD 2 "register_operand" "")]
290                         UNSPEC_VEC_PACK_SATURATE_GENCC))
291      (set (match_operand:<vec_half> 0 "register_operand" "")
292           (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
293                              UNSPEC_VEC_PACK_SATURATE_CC))])
294    (set (match_dup 4)
295         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
296    (set (match_operand:SI 3 "memory_operand" "")
297         (match_dup 4))]
298   "TARGET_VX"
300   operands[4] = gen_reg_rtx (SImode);
303 ; vpksh, vpksf, vpksg
304 (define_insn "*vec_packs_cc<mode>"
305   [(set (reg:CCRAW CC_REGNUM)
306         (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
307                        (match_operand:VI_HW_HSD 2 "register_operand" "v")]
308                       UNSPEC_VEC_PACK_SATURATE_GENCC))
309    (set (match_operand:<vec_half> 0 "register_operand" "=v")
310         (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
311                            UNSPEC_VEC_PACK_SATURATE_CC))]
312   "TARGET_VX"
313   "vpks<bhfgq>s\t%v0,%v1,%v2"
314   [(set_attr "op_type" "VRR")])
317 ; Vector pack logical saturate
319 ; vpklsh, vpklsf, vpklsg
320 (define_insn "vec_packsu<mode>"
321   [(set (match_operand:<vec_half>                    0 "register_operand" "=v")
322         (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
323                             (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
324                            UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
325   "TARGET_VX"
326   "vpkls<bhfgq>\t%v0,%v1,%v2"
327   [(set_attr "op_type" "VRR")])
329 ; Emulate saturate unsigned pack on signed operands.
330 ; Zero out negative elements and continue with the unsigned saturating pack.
331 (define_expand "vec_packsu_u<mode>"
332   [(set (match_operand:<vec_half>                    0 "register_operand" "=v")
333         (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
334                             (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
335                            UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
336   "TARGET_VX"
338    rtx null_vec = CONST0_RTX(<MODE>mode);
339    machine_mode half_mode;
340    switch (<MODE>mode)
341    {
342      case E_V8HImode: half_mode = V16QImode; break;
343      case E_V4SImode: half_mode = V8HImode; break;
344      case E_V2DImode: half_mode = V4SImode; break;
345      default: gcc_unreachable ();
346    }
347    s390_expand_vcond (operands[1], operands[1], null_vec,
348                       GE, operands[1], null_vec);
349    s390_expand_vcond (operands[2], operands[2], null_vec,
350                       GE, operands[2], null_vec);
351    emit_insn (gen_rtx_SET (operands[0],
352                            gen_rtx_UNSPEC (half_mode,
353                                            gen_rtvec (2, operands[1], operands[2]),
354                                            UNSPEC_VEC_PACK_UNSIGNED_SATURATE)));
355    DONE;
358 ; This is vec_packsu_cc + loading cc into a caller specified memory location.
359 ; FIXME: The reg to target mem copy should be issued by reload?!
360 (define_expand "vec_packsu_cc<mode>"
361   [(parallel
362     [(set (reg:CCRAW CC_REGNUM)
363           (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
364                          (match_operand:VI_HW_HSD 2 "register_operand" "")]
365                         UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
366      (set (match_operand:<vec_half> 0 "register_operand" "")
367           (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
368                              UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))])
369    (set (match_dup 4)
370         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
371    (set (match_operand:SI 3 "memory_operand" "")
372         (match_dup 4))]
373   "TARGET_VX"
375   operands[4] = gen_reg_rtx (SImode);
378 ; vpklsh, vpklsf, vpklsg
379 (define_insn "*vec_packsu_cc<mode>"
380   [(set (reg:CCRAW CC_REGNUM)
381         (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
382                        (match_operand:VI_HW_HSD 2 "register_operand" "v")]
383                       UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
384    (set (match_operand:<vec_half> 0 "register_operand" "=v")
385         (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
386                            UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))]
387   "TARGET_VX"
388   "vpkls<bhfgq>s\t%v0,%v1,%v2"
389   [(set_attr "op_type" "VRR")])
392 ; Vector permute
394 ; vec_perm is also RTL standard name, but we can only use it for V16QI
396 (define_insn "vec_zperm<mode>"
397   [(set (match_operand:V_HW_HSD                   0 "register_operand" "=v")
398         (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "register_operand"  "v")
399                           (match_operand:V_HW_HSD 2 "register_operand"  "v")
400                           (match_operand:V16QI    3 "register_operand"  "v")]
401                          UNSPEC_VEC_PERM))]
402   "TARGET_VX"
403   "vperm\t%v0,%v1,%v2,%v3"
404   [(set_attr "op_type" "VRR")])
406 ; Incoming op3 is in vec_permi format and will we turned into a
407 ; permute vector consisting of op3 and op4.
408 (define_expand "vec_permi<mode>"
409   [(set (match_operand:V_HW_2   0 "register_operand" "")
410         (vec_select:V_HW_2
411          (vec_concat:<vec_2x_nelts>
412           (match_operand:V_HW_2 1 "register_operand" "")
413           (match_operand:V_HW_2 2 "register_operand" ""))
414          (parallel [(match_operand:QI 3 "const_mask_operand" "") (match_dup 4)])))]
415   "TARGET_VX"
417   HOST_WIDE_INT val = INTVAL (operands[3]);
418   operands[3] = GEN_INT ((val & 2) >> 1);
419   operands[4] = GEN_INT ((val & 1) + 2);
423 ; Vector replicate
426 ; Replicate from vector element
427 (define_expand "vec_splat<mode>"
428   [(set (match_operand:V_HW                      0 "register_operand"  "")
429         (vec_duplicate:V_HW (vec_select:<non_vec>
430                              (match_operand:V_HW 1 "register_operand"  "")
431                              (parallel
432                               [(match_operand:QI 2 "const_mask_operand" "")]))))]
433   "TARGET_VX")
435 ; Vector scatter element
437 ; vscef, vsceg
439 ; A 64 bit target address generated from 32 bit elements
440 (define_insn "vec_scatter_element<V_HW_4:mode>_DI"
441   [(set (mem:<non_vec>
442          (plus:DI (zero_extend:DI
443                    (vec_select:SI
444                     (match_operand:V4SI           1 "register_operand"   "v")
445                     (parallel [(match_operand:QI  3 "const_mask_operand" "C")])))
446           (match_operand:SI                       2 "address_operand"    "ZQ")))
447         (vec_select:<non_vec>
448          (match_operand:V_HW_4                    0 "register_operand"   "v")
449          (parallel [(match_dup 3)])))]
450   "TARGET_VX && TARGET_64BIT && UINTVAL (operands[3]) < 4"
451   "vscef\t%v0,%O2(%v1,%R2),%3"
452   [(set_attr "op_type" "VRV")])
454 ; A 31 bit target address is generated from 64 bit elements
455 ; vsceg
456 (define_insn "vec_scatter_element<V_HW_2:mode>_SI"
457   [(set (mem:<non_vec>
458          (plus:SI (subreg:SI
459                    (vec_select:<non_vec_int>
460                     (match_operand:<TOINTVEC>     1 "register_operand"   "v")
461                     (parallel [(match_operand:QI  3 "const_mask_operand" "C")])) 4)
462           (match_operand:SI                       2 "address_operand"    "ZQ")))
463     (vec_select:<non_vec>
464      (match_operand:V_HW_2                        0 "register_operand"   "v")
465      (parallel [(match_dup 3)])))]
466   "TARGET_VX && !TARGET_64BIT && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_2:MODE>mode)"
467   "vsce<V_HW_2:bhfgq>\t%v0,%O2(%v1,%R2),%3"
468   [(set_attr "op_type" "VRV")])
470 ; Element size and target address size is the same
471 ; vscef, vsceg
472 (define_insn "vec_scatter_element<mode>_<non_vec_int>"
473   [(set (mem:<non_vec>
474          (plus:<non_vec_int>
475           (vec_select:<non_vec_int>
476            (match_operand:<TOINTVEC>      1 "register_operand"   "v")
477             (parallel [(match_operand:QI  3 "const_mask_operand" "C")]))
478           (match_operand:DI               2 "address_operand"   "ZQ")))
479         (vec_select:<non_vec>
480          (match_operand:V_HW_32_64        0 "register_operand"   "v")
481          (parallel [(match_dup 3)])))]
482   "TARGET_VX && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
483   "vsce<bhfgq>\t%v0,%O2(%v1,%R2),%3"
484   [(set_attr "op_type" "VRV")])
486 ; Depending on the address size we have to expand a different pattern.
487 ; This however cannot be represented in s390-builtins.def so we do the
488 ; multiplexing here in the expander.
489 (define_expand "vec_scatter_element<V_HW_32_64:mode>"
490   [(match_operand:V_HW_32_64 0 "register_operand" "")
491    (match_operand:<TOINTVEC> 1 "register_operand" "")
492    (match_operand 2 "address_operand" "")
493    (match_operand:QI 3 "const_mask_operand" "")]
494   "TARGET_VX"
496   if (TARGET_64BIT)
497     {
498       PUT_MODE (operands[2], DImode);
499       emit_insn (
500         gen_vec_scatter_element<V_HW_32_64:mode>_DI (operands[0], operands[1],
501                                                      operands[2], operands[3]));
502     }
503   else
504     {
505       PUT_MODE (operands[2], SImode);
506       emit_insn (
507         gen_vec_scatter_element<V_HW_32_64:mode>_SI (operands[0], operands[1],
508                                                      operands[2], operands[3]));
509     }
510   DONE;
514 ; Vector select
516 ; for all b in bits op0[b] = op3[b] == 0 ? op2[b] : op1[b]
517 ; implemented as: op0 = (op1 & op3) | (op2 & ~op3)
519 ; Used to expand the vec_sel builtin. Operands op1 and op2 already got
520 ; swapped in s390-c.cc when we get here.
522 (define_insn "vsel<mode>"
523   [(set (match_operand:V_HW_FT               0 "register_operand" "=v")
524         (ior:V_HW_FT
525          (and:V_HW_FT (match_operand:V_HW_FT 1 "register_operand"  "v")
526                       (match_operand:V_HW_FT 3 "register_operand"  "v"))
527          (and:V_HW_FT (not:V_HW_FT (match_dup 3))
528                       (match_operand:V_HW_FT 2 "register_operand"  "v"))))]
529   "TARGET_VX"
530   "vsel\t%v0,%1,%2,%3"
531   [(set_attr "op_type" "VRR")])
534 ; Vector sign extend to doubleword
536 ; Sign extend of right most vector element to respective double-word
537 ; vsegb, vsegh, vsegf
538 (define_insn "vec_extend<mode>"
539   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
540         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
541                           UNSPEC_VEC_EXTEND))]
542   "TARGET_VX"
543   "vseg<bhfgq>\t%v0,%1"
544   [(set_attr "op_type" "VRR")])
547 ; Vector store with length
549 ; Store bytes in OP1 from OP0 with the highest indexed byte to be
550 ; stored from OP0 given by OP2
551 (define_insn "vstl<mode>"
552   [(set (match_operand:BLK             2 "memory_operand"   "=Q")
553         (unspec:BLK [(match_operand:V  0 "register_operand"  "v")
554                      (match_operand:SI 1 "register_operand"  "d")]
555                     UNSPEC_VEC_STORE_LEN))]
556   "TARGET_VX"
557   "vstl\t%v0,%1,%2"
558   [(set_attr "op_type" "VRS")])
560 ; Vector store rightmost with length
562 (define_expand "vstrlrv16qi"
563   [(set (match_operand:BLK                2 "memory_operand"    "")
564         (unspec:BLK [(match_operand:V16QI 0 "register_operand"  "")
565                      (match_operand:SI    1 "nonmemory_operand" "")]
566                     UNSPEC_VEC_STORE_LEN_R))]
567   "TARGET_VXE"
569   /* vstrlr sets all length values beyond 15 to 15.  Emulate the same
570      behavior for immediate length operands.  vstrl would trigger a
571      SIGILL for too large immediate operands.  */
572   if (CONST_INT_P (operands[1])
573       && (UINTVAL (operands[1]) & 0xffffffff) > 15)
574     operands[1] = GEN_INT (15);
577 (define_insn "*vstrlrv16qi"
578   [(set (match_operand:BLK                2 "memory_operand"    "=Q,  R,  Q")
579         (unspec:BLK [(match_operand:V16QI 0 "register_operand"   "v,  v,  v")
580                      (match_operand:SI    1 "nonmemory_operand"  "d,j>f,jb4")]
581                     UNSPEC_VEC_STORE_LEN_R))]
582   "TARGET_VXE"
583   "@
584    vstrlr\t%v0,%1,%2
585    vst\t%v0,%2%A2
586    vstrl\t%v0,%2,%1"
587   [(set_attr "op_type" "VRS,VRX,VSI")])
591 ; vector bit permute
593 (define_insn "vbpermv16qi"
594   [(set (match_operand:V2DI                0 "register_operand" "=v")
595         (unspec:V2DI [(match_operand:V16QI 1 "register_operand"  "v")
596                       (match_operand:V16QI 2 "register_operand"  "v")]
597                      UNSPEC_VEC_VBPERM))]
598   "TARGET_VXE"
599   "vbperm\t%v0,%v1,%v2"
600   [(set_attr "op_type" "VRR")])
602 ; Vector unpack high
604 ; vuphb, vuphh, vuphf
605 (define_insn "vec_unpackh<mode>"
606   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
607         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
608                              UNSPEC_VEC_UNPACKH))]
609   "TARGET_VX"
610   "vuph<bhfgq>\t%v0,%v1"
611   [(set_attr "op_type" "VRR")])
613 ; vuplhb, vuplhh, vuplhf
614 (define_insn "vec_unpackh_l<mode>"
615   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
616         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
617                              UNSPEC_VEC_UNPACKH_L))]
618   "TARGET_VX"
619   "vuplh<bhfgq>\t%v0,%v1"
620   [(set_attr "op_type" "VRR")])
623 ; Vector unpack low
625 ; vuplb, vuplhw, vuplf
626 (define_insn "vec_unpackl<mode>"
627   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
628         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
629                              UNSPEC_VEC_UNPACKL))]
630   "TARGET_VX"
631   "vupl<bhfgq><w>\t%v0,%v1"
632   [(set_attr "op_type" "VRR")])
634 ; vupllb, vupllh, vupllf
635 (define_insn "vec_unpackl_l<mode>"
636   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
637         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
638                              UNSPEC_VEC_UNPACKL_L))]
639   "TARGET_VX"
640   "vupll<bhfgq>\t%v0,%v1"
641   [(set_attr "op_type" "VRR")])
644 ; Vector add
646 ; Vector add compute carry
648 ; vaccb, vacch, vaccf, vaccg, vaccq
649 (define_insn "vacc<bhfgq>_<mode>"
650   [(set (match_operand:VIT_HW                 0 "register_operand" "=v")
651         (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand"  "v")
652                         (match_operand:VIT_HW 2 "register_operand"  "v")]
653                        UNSPEC_VEC_ADDC))]
654   "TARGET_VX"
655   "vacc<bhfgq>\t%v0,%v1,%v2"
656   [(set_attr "op_type" "VRR")])
658 ; Vector add with carry
660 (define_insn "vacq"
661   [(set (match_operand:TI             0 "register_operand" "=v")
662         (unspec:TI [(match_operand:TI 1 "register_operand"  "v")
663                     (match_operand:TI 2 "register_operand"  "v")
664                     (match_operand:TI 3 "register_operand"  "v")]
665                    UNSPEC_VEC_ADDE_U128))]
666   "TARGET_VX"
667   "vacq\t%v0,%v1,%v2,%v3"
668   [(set_attr "op_type" "VRR")])
671 ; Vector add with carry compute carry
673 (define_insn "vacccq"
674   [(set (match_operand:TI             0 "register_operand" "=v")
675         (unspec:TI [(match_operand:TI 1 "register_operand"  "v")
676                     (match_operand:TI 2 "register_operand"  "v")
677                     (match_operand:TI 3 "register_operand"  "v")]
678                    UNSPEC_VEC_ADDEC_U128))]
679   "TARGET_VX"
680   "vacccq\t%v0,%v1,%v2,%v3"
681   [(set_attr "op_type" "VRR")])
684 ; Vector and
686 ; Vector and with complement
688 ; vnc
689 (define_insn "vec_andc<mode>3"
690   [(set (match_operand:VT_HW                       0 "register_operand" "=v")
691         (and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand"  "v"))
692                   (match_operand:VT_HW             1 "register_operand"  "v")))]
693   "TARGET_VX"
694   "vnc\t%v0,%v1,%v2"
695   [(set_attr "op_type" "VRR")])
698 ; Vector average
700 ; vavgb, vavgh, vavgf, vavgg
701 (define_insn "vec_avg<mode>"
702   [(set (match_operand:VI_HW                0 "register_operand" "=v")
703         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
704                        (match_operand:VI_HW 2 "register_operand"  "v")]
705                       UNSPEC_VEC_AVG))]
706   "TARGET_VX"
707   "vavg<bhfgq>\t%v0,%v1,%v2"
708   [(set_attr "op_type" "VRR")])
710 ; Vector average logical
712 ; vavglb, vavglh, vavglf, vavglg
713 (define_insn "vec_avgu<mode>"
714   [(set (match_operand:VI_HW                0 "register_operand" "=v")
715         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
716                        (match_operand:VI_HW 2 "register_operand"  "v")]
717                       UNSPEC_VEC_AVGU))]
718   "TARGET_VX"
719   "vavgl<bhfgq>\t%v0,%v1,%v2"
720   [(set_attr "op_type" "VRR")])
723 ; Vector checksum
725 (define_insn "vec_checksum"
726   [(set (match_operand:V4SI               0 "register_operand" "=v")
727         (unspec:V4SI [(match_operand:V4SI 1 "register_operand"  "v")
728                       (match_operand:V4SI 2 "register_operand"  "v")]
729                      UNSPEC_VEC_CHECKSUM))]
730   "TARGET_VX"
731   "vcksm\t%v0,%v1,%v2"
732   [(set_attr "op_type" "VRR")])
735 ;; Vector compare
738 ; vec_all/any int compares
740 (define_expand "vec_all_<intcmpcc:code><VI_HW:mode>"
741   [(match_operand:SI                0 "register_operand" "")
742    (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
743              (match_operand:VI_HW 2 "register_operand" ""))]
744   "TARGET_VX"
746   s390_expand_vec_compare_cc (operands[0],
747                               <intcmpcc:CODE>,
748                               operands[1],
749                               operands[2],
750                               true);
751   DONE;
754 (define_expand "vec_any_<intcmpcc:code><VI_HW:mode>"
755   [(match_operand:SI                0 "register_operand" "")
756    (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
757              (match_operand:VI_HW 2 "register_operand" ""))]
758   "TARGET_VX"
760   s390_expand_vec_compare_cc (operands[0],
761                               <intcmpcc:CODE>,
762                               operands[1],
763                               operands[2],
764                               false);
765   DONE;
768 ; vec_all/any fp compares
770 (define_expand "vec_all_<fpcmpcc:code><mode>"
771   [(match_operand:SI               0 "register_operand" "")
772    (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
773             (match_operand:VECF_HW 2 "register_operand" ""))]
774   "TARGET_VX"
776   s390_expand_vec_compare_cc (operands[0],
777                               <fpcmpcc:CODE>,
778                               operands[1],
779                               operands[2],
780                               true);
781   DONE;
784 (define_expand "vec_any_<fpcmpcc:code><mode>"
785   [(match_operand:SI               0 "register_operand" "")
786    (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
787             (match_operand:VECF_HW 2 "register_operand" ""))]
788   "TARGET_VX"
790   s390_expand_vec_compare_cc (operands[0],
791                               <fpcmpcc:CODE>,
792                               operands[1],
793                               operands[2],
794                               false);
795   DONE;
799 ; Compare without generating CC
801 (define_expand "vec_cmp<intcmp:code><VI_HW:mode>"
802   [(set (match_operand:VI_HW               0 "register_operand" "=v")
803         (intcmp:VI_HW (match_operand:VI_HW 1 "register_operand"  "v")
804                       (match_operand:VI_HW 2 "register_operand"  "v")))]
805   "TARGET_VX"
807   s390_expand_vec_compare (operands[0], <intcmp:CODE>, operands[1], operands[2]);
808   DONE;
811 (define_expand "vec_cmp<fpcmp:code><mode>"
812   [(set (match_operand:<TOINTVEC>              0 "register_operand" "=v")
813         (fpcmp:<TOINTVEC> (match_operand:VF_HW 1 "register_operand"  "v")
814                        (match_operand:VF_HW 2 "register_operand"  "v")))]
815   "TARGET_VX"
817   s390_expand_vec_compare (operands[0], <fpcmp:CODE>, operands[1], operands[2]);
818   DONE;
822 ; Vector count leading zeros
824 ; vec_cntlz -> clz
825 ; vec_cnttz -> ctz
827 ; Vector xor
829 ; vec_xor -> xor
831 ; Vector Galois field multiply sum
833 ; vgfmb, vgfmh, vgfmf
834 (define_insn "vec_gfmsum<mode>"
835   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
836         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
837                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
838                           UNSPEC_VEC_GFMSUM))]
839   "TARGET_VX"
840   "vgfm<bhfgq>\t%v0,%v1,%v2"
841   [(set_attr "op_type" "VRR")])
843 (define_insn "vec_gfmsum_128"
844   [(set (match_operand:V16QI 0 "register_operand" "=v")
845         (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
846                        (match_operand:V2DI 2 "register_operand" "v")]
847                       UNSPEC_VEC_GFMSUM_128))]
848   "TARGET_VX"
849   "vgfmg\t%v0,%v1,%v2"
850   [(set_attr "op_type" "VRR")])
852 ; vgfmab, vgfmah, vgfmaf
853 (define_insn "vec_gfmsum_accum<mode>"
854   [(set (match_operand:<vec_double> 0 "register_operand" "=v")
855         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
856                               (match_operand:VI_HW_QHS 2 "register_operand" "v")
857                               (match_operand:<vec_double> 3 "register_operand" "v")]
858                              UNSPEC_VEC_GFMSUM_ACCUM))]
859   "TARGET_VX"
860   "vgfma<bhfgq>\t%v0,%v1,%v2,%v3"
861   [(set_attr "op_type" "VRR")])
863 (define_insn "vec_gfmsum_accum_128"
864   [(set (match_operand:V16QI 0 "register_operand" "=v")
865         (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
866                        (match_operand:V2DI 2 "register_operand" "v")
867                        (match_operand:V16QI 3 "register_operand" "v")]
868                       UNSPEC_VEC_GFMSUM_ACCUM_128))]
869   "TARGET_VX"
870   "vgfmag\t%v0,%v1,%v2,%v3"
871   [(set_attr "op_type" "VRR")])
874 ; FIXME: vec_neg ?
876 ; Vector load positive: vec_abs -> abs
877 ; Vector maximum vec_max -> smax, logical vec_max -> umax
878 ; Vector maximum vec_min -> smin, logical vec_min -> umin
881 ; Vector multiply and add high
883 ; vec_mladd -> vec_vmal
884 ; vmalb, vmalh, vmalf, vmalg
885 (define_insn "vec_vmal<mode>"
886   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
887         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
888                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
889                            (match_operand:VI_HW_QHS 3 "register_operand" "v")]
890                           UNSPEC_VEC_VMAL))]
891   "TARGET_VX"
892   "vmal<bhfgq><w>\t%v0,%v1,%v2,%v3"
893   [(set_attr "op_type" "VRR")])
895 ; vec_mhadd -> vec_vmah/vec_vmalh
897 ; vmahb; vmahh, vmahf, vmahg
898 (define_insn "vec_vmah<mode>"
899   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
900         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
901                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
902                            (match_operand:VI_HW_QHS 3 "register_operand" "v")]
903                           UNSPEC_VEC_VMAH))]
904   "TARGET_VX"
905   "vmah<bhfgq>\t%v0,%v1,%v2,%v3"
906   [(set_attr "op_type" "VRR")])
908 ; vmalhb; vmalhh, vmalhf, vmalhg
909 (define_insn "vec_vmalh<mode>"
910   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
911         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
912                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
913                            (match_operand:VI_HW_QHS 3 "register_operand" "v")]
914                           UNSPEC_VEC_VMALH))]
915   "TARGET_VX"
916   "vmalh<bhfgq>\t%v0,%v1,%v2,%v3"
917   [(set_attr "op_type" "VRR")])
919 ; vec_meadd -> vec_vmae/vec_vmale
921 ; vmaeb; vmaeh, vmaef, vmaeg
922 (define_insn "vec_vmae<mode>"
923   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
924         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
925                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
926                               (match_operand:<vec_double> 3 "register_operand" "v")]
927                              UNSPEC_VEC_VMAE))]
928   "TARGET_VX"
929   "vmae<bhfgq>\t%v0,%v1,%v2,%v3"
930   [(set_attr "op_type" "VRR")])
932 ; vmaleb; vmaleh, vmalef, vmaleg
933 (define_insn "vec_vmale<mode>"
934   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
935         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
936                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
937                               (match_operand:<vec_double> 3 "register_operand" "v")]
938                              UNSPEC_VEC_VMALE))]
939   "TARGET_VX"
940   "vmale<bhfgq>\t%v0,%v1,%v2,%v3"
941   [(set_attr "op_type" "VRR")])
943 ; vec_moadd -> vec_vmao/vec_vmalo
945 ; vmaob; vmaoh, vmaof, vmaog
946 (define_insn "vec_vmao<mode>"
947   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
948         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
949                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
950                               (match_operand:<vec_double> 3 "register_operand" "v")]
951                              UNSPEC_VEC_VMAO))]
952   "TARGET_VX"
953   "vmao<bhfgq>\t%v0,%v1,%v2,%v3"
954   [(set_attr "op_type" "VRR")])
956 ; vmalob; vmaloh, vmalof, vmalog
957 (define_insn "vec_vmalo<mode>"
958   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
959         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
960                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
961                               (match_operand:<vec_double> 3 "register_operand" "v")]
962                              UNSPEC_VEC_VMALO))]
963   "TARGET_VX"
964   "vmalo<bhfgq>\t%v0,%v1,%v2,%v3"
965   [(set_attr "op_type" "VRR")])
968 ; Vector multiply high
970 ; vec_mulh -> vec_smulh/vec_umulh
972 ; vmhb, vmhh, vmhf
973 (define_insn "vec_smulh<mode>"
974   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
975         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
976                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
977                           UNSPEC_VEC_SMULT_HI))]
978   "TARGET_VX"
979   "vmh<bhfgq>\t%v0,%v1,%v2"
980   [(set_attr "op_type" "VRR")])
982 ; vmlhb, vmlhh, vmlhf
983 (define_insn "vec_umulh<mode>"
984   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
985         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
986                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
987                           UNSPEC_VEC_UMULT_HI))]
988   "TARGET_VX"
989   "vmlh<bhfgq>\t%v0,%v1,%v2"
990   [(set_attr "op_type" "VRR")])
993 ; Vector multiply low
995 ; vec_mule -> vec_widen_umult_even/vec_widen_smult_even
996 ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd
999 ; Vector nor
1001 (define_insn "vec_nor<mode>3"
1002   [(set (match_operand:VT_HW 0 "register_operand"            "=v")
1003         (not:VT_HW
1004          (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "v")
1005                     (match_operand:VT_HW 2 "register_operand" "v"))))]
1006   "TARGET_VX"
1007   "vno\t%v0,%v1,%v2"
1008   [(set_attr "op_type" "VRR")])
1011 ; Vector or
1013 ; Vector population count vec_popcnt -> popcount
1014 ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot
1016 ; Vector element rotate and insert under mask
1018 ; verimb, verimh, verimf, verimg
1019 (define_insn "verim<mode>"
1020   [(set (match_operand:VI_HW                0 "register_operand" "=v")
1021         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "0")
1022                        (match_operand:VI_HW 2 "register_operand"  "v")
1023                        (match_operand:VI_HW 3 "register_operand"  "v")
1024                        (match_operand:QI    4 "const_int_operand" "C")]
1025                       UNSPEC_VEC_RL_MASK))]
1026   "TARGET_VX"
1027   "verim<bhfgq>\t%v0,%v2,%v3,%b4"
1028   [(set_attr "op_type" "VRI")])
1031 ; Vector shift left
1033 (define_insn "vec_sll<VI_HW:mode><VI_HW_QHS:mode>"
1034   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1035         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1036                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1037                       UNSPEC_VEC_SLL))]
1038   "TARGET_VX"
1039   "vsl\t%v0,%v1,%v2"
1040   [(set_attr "op_type" "VRR")])
1043 ; Vector shift left by byte
1045 ; Pattern definition in vector.md, see vec_vslb
1046 (define_expand "vec_slb<mode>"
1047   [(set (match_operand:V_HW 0 "register_operand"                     "")
1048         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "")
1049                       (match_operand:<TOINTVEC> 2 "register_operand" "")]
1050                      UNSPEC_VEC_SLB))]
1051   "TARGET_VX"
1053   PUT_MODE (operands[2], V16QImode);
1056 ; Vector shift left double by byte
1058 (define_insn "vec_sld<mode>"
1059   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1060         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1061                       (match_operand:V_HW 2 "register_operand" "v")
1062                       (match_operand:QI 3 "const_int_operand"  "C")]
1063                      UNSPEC_VEC_SLDBYTE))]
1064   "TARGET_VX"
1065   "vsldb\t%v0,%v1,%v2,%b3"
1066   [(set_attr "op_type" "VRI")])
1068 (define_expand "vec_sldw<mode>"
1069   [(set (match_operand:V_HW 0 "register_operand"               "")
1070         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1071                       (match_operand:V_HW 2 "register_operand" "")
1072                       (match_operand:QI 3 "const_int_operand"  "")]
1073                      UNSPEC_VEC_SLDBYTE))]
1074   "TARGET_VX"
1076   operands[3] = GEN_INT (INTVAL (operands[3]) << 2);
1079 ; Vector shift left double by bit
1081 (define_insn "vec_sldb<mode>"
1082   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1083         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1084                       (match_operand:V_HW 2 "register_operand" "v")
1085                       (match_operand:QI 3 "const_int_operand"  "C")]
1086                      UNSPEC_VEC_SLDBIT))]
1087   "TARGET_VXE2"
1088   "vsld\t%v0,%v1,%v2,%b3"
1089   [(set_attr "op_type" "VRI")])
1091 ; Vector shift right double by bit
1093 (define_insn "vec_srdb<mode>"
1094   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1095         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1096                       (match_operand:V_HW 2 "register_operand" "v")
1097                       (match_operand:QI 3 "const_int_operand"  "C")]
1098                      UNSPEC_VEC_SRDBIT))]
1099   "TARGET_VXE2"
1100   "vsrd\t%v0,%v1,%v2,%b3"
1101   [(set_attr "op_type" "VRI")])
1103 ; Vector shift right arithmetic
1105 (define_insn "vec_sral<VI_HW:mode><VI_HW_QHS:mode>"
1106   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1107         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1108                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1109                       UNSPEC_VEC_SRAL))]
1110   "TARGET_VX"
1111   "vsra\t%v0,%v1,%v2"
1112   [(set_attr "op_type" "VRR")])
1115 ; Vector shift right arithmetic by byte
1117 (define_insn "vec_srab<mode>"
1118   [(set (match_operand:V_HW 0 "register_operand"                    "=v")
1119         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "v")
1120                       (match_operand:<TOINTVEC> 2 "register_operand" "v")]
1121                      UNSPEC_VEC_SRAB))]
1122   "TARGET_VX"
1123   "vsrab\t%v0,%v1,%v2"
1124   [(set_attr "op_type" "VRR")])
1127 ; Vector shift right logical
1129 (define_insn "vec_srl<VI_HW:mode><VI_HW_QHS:mode>"
1130   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1131         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1132                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1133                       UNSPEC_VEC_SRL))]
1134   "TARGET_VX"
1135   "vsrl\t%v0,%v1,%v2"
1136   [(set_attr "op_type" "VRR")])
1139 ; Vector shift right logical by byte
1141 ; Pattern definition in vector.md, see vec_vsrb
1142 (define_expand "vec_srb<mode>"
1143   [(set (match_operand:V_HW 0 "register_operand"                     "")
1144         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "")
1145                       (match_operand:<TOINTVEC> 2 "register_operand" "")]
1146                      UNSPEC_VEC_SRLB))]
1147   "TARGET_VX"
1149   PUT_MODE (operands[2], V16QImode);
1152 ; Vector subtract
1154 ; Vector subtract compute borrow indication
1156 ; vscbib, vscbih, vscbif, vscbig, vscbiq
1157 (define_insn "vscbi<bhfgq>_<mode>"
1158   [(set (match_operand:VIT_HW 0 "register_operand"                "=v")
1159         (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
1160                         (match_operand:VIT_HW 2 "register_operand" "v")]
1161                       UNSPEC_VEC_SUBC))]
1162   "TARGET_VX"
1163   "vscbi<bhfgq>\t%v0,%v1,%v2"
1164   [(set_attr "op_type" "VRR")])
1166 ; Vector subtract with borrow indication
1168 (define_insn "vsbiq"
1169   [(set (match_operand:TI 0 "register_operand"               "=v")
1170         (unspec:TI [(match_operand:TI 1 "register_operand"    "v")
1171                        (match_operand:TI 2 "register_operand" "v")
1172                        (match_operand:TI 3 "register_operand" "v")]
1173                       UNSPEC_VEC_SUBE_U128))]
1174   "TARGET_VX"
1175   "vsbiq\t%v0,%v1,%v2,%v3"
1176   [(set_attr "op_type" "VRR")])
1179 ; Vector subtract with borrow compute and borrow indication
1181 (define_insn "vsbcbiq"
1182   [(set (match_operand:TI 0 "register_operand"               "=v")
1183         (unspec:TI [(match_operand:TI 1 "register_operand"    "v")
1184                        (match_operand:TI 2 "register_operand" "v")
1185                        (match_operand:TI 3 "register_operand" "v")]
1186                       UNSPEC_VEC_SUBEC_U128))]
1187   "TARGET_VX"
1188   "vsbcbiq\t%v0,%v1,%v2,%v3"
1189   [(set_attr "op_type" "VRR")])
1192 ; Vector sum across
1194 ; Sum across DImode parts of the 1st operand and add the rightmost
1195 ; element of 2nd operand
1196 ; vsumgh, vsumgf
1197 (define_expand "vec_sum2<mode>"
1198   [(set (match_operand:V2DI 0 "register_operand" "")
1199         (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "")
1200                       (match_operand:VI_HW_HS 2 "register_operand" "")]
1201                      UNSPEC_VEC_VSUMG))]
1202   "TARGET_VX")
1204 ; vsumqh, vsumqf
1205 (define_insn "vec_sum_u128<mode>"
1206   [(set (match_operand:V2DI 0 "register_operand" "=v")
1207         (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v")
1208                       (match_operand:VI_HW_SD 2 "register_operand" "v")]
1209                      UNSPEC_VEC_VSUMQ))]
1210   "TARGET_VX"
1211   "vsumq<bhfgq>\t%v0,%v1,%v2"
1212   [(set_attr "op_type" "VRR")])
1214 ; vsumb, vsumh
1215 (define_expand "vec_sum4<mode>"
1216   [(set (match_operand:V4SI 0 "register_operand" "")
1217         (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "")
1218                       (match_operand:VI_HW_QH 2 "register_operand" "")]
1219                      UNSPEC_VEC_VSUM))]
1220   "TARGET_VX")
1223 ; Vector test under mask
1225 (define_expand "vec_test_mask_int<mode>"
1226   [(set (reg:CCRAW CC_REGNUM)
1227         (unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
1228                        (match_operand:<TOINTVEC> 2 "register_operand" "")]
1229                       UNSPEC_VEC_TEST_MASK))
1230    (set (match_operand:SI 0 "register_operand" "")
1231         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1232   "TARGET_VX")
1234 (define_insn "*vec_test_mask<mode>"
1235   [(set (reg:CCRAW CC_REGNUM)
1236         (unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
1237                        (match_operand:<TOINTVEC> 1 "register_operand" "v")]
1238                       UNSPEC_VEC_TEST_MASK))]
1239   "TARGET_VX"
1240   "vtm\t%v0,%v1"
1241   [(set_attr "op_type" "VRR")])
1244 ; Vector multiply sum logical
1246 (define_insn "vec_msumv2di"
1247   [(set (match_operand:V16QI 0 "register_operand" "=v")
1248         (unspec:V16QI [(match_operand:V2DI  1 "register_operand"   "v")
1249                        (match_operand:V2DI  2 "register_operand"   "v")
1250                        (match_operand:V16QI 3 "register_operand"   "v")
1251                        (match_operand:QI    4 "const_mask_operand" "C")]
1252                       UNSPEC_VEC_MSUM))]
1253   "TARGET_VXE"
1254   "vmslg\t%v0,%v1,%v2,%v3,%4"
1255   [(set_attr "op_type" "VRR")])
1257 (define_insn "vmslg"
1258   [(set (match_operand:TI 0 "register_operand" "=v")
1259         (unspec:TI [(match_operand:V2DI  1 "register_operand"   "v")
1260                     (match_operand:V2DI  2 "register_operand"   "v")
1261                     (match_operand:TI    3 "register_operand"   "v")
1262                     (match_operand:QI    4 "const_mask_operand" "C")]
1263                    UNSPEC_VEC_MSUM))]
1264   "TARGET_VXE"
1265   "vmslg\t%v0,%v1,%v2,%v3,%4"
1266   [(set_attr "op_type" "VRR")])
1269 ; Vector find any element equal
1271 ; vfaeb, vfaeh, vfaef
1272 ; vfaezb, vfaezh, vfaezf
1273 (define_insn "vfae<mode>"
1274   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1275         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1276                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
1277                            (match_operand:QI        3 "const_mask_operand" "C")]
1278                           UNSPEC_VEC_VFAE))]
1279   "TARGET_VX"
1281   unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1283   if (flags & VSTRING_FLAG_ZS)
1284     {
1285       flags &= ~VSTRING_FLAG_ZS;
1286       operands[3] = GEN_INT (flags);
1287       return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3";
1288     }
1289   return "vfae<bhfgq>\t%v0,%v1,%v2,%b3";
1291 [(set_attr "op_type" "VRR")])
1293 ; vfaebs, vfaehs, vfaefs
1294 ; vfaezbs, vfaezhs, vfaezfs
1295 (define_insn "*vfaes<mode>"
1296   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1297         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1298                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1299                            (match_operand:QI        3 "const_mask_operand" "C")]
1300                           UNSPEC_VEC_VFAE))
1301    (set (reg:CCRAW CC_REGNUM)
1302         (unspec:CCRAW [(match_dup 1)
1303                        (match_dup 2)
1304                        (match_dup 3)]
1305                       UNSPEC_VEC_VFAECC))]
1306   "TARGET_VX"
1308   unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1310   if (flags & VSTRING_FLAG_ZS)
1311     {
1312       flags &= ~VSTRING_FLAG_ZS;
1313       operands[3] = GEN_INT (flags);
1314       return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3";
1315     }
1316   return "vfae<bhfgq>s\t%v0,%v1,%v2,%b3";
1318   [(set_attr "op_type" "VRR")])
1320 (define_expand "vfaez<mode>"
1321   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1322         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1323                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1324                            (match_operand:QI        3 "const_mask_operand" "")]
1325                           UNSPEC_VEC_VFAE))]
1326   "TARGET_VX"
1328   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS);
1331 (define_expand "vfaes<mode>"
1332   [(parallel
1333     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1334         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1335                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1336                            (match_operand:QI        3 "const_mask_operand" "")]
1337                           UNSPEC_VEC_VFAE))
1338    (set (reg:CCRAW CC_REGNUM)
1339         (unspec:CCRAW [(match_dup 1)
1340                        (match_dup 2)
1341                        (match_dup 3)]
1342                       UNSPEC_VEC_VFAECC))])
1343    (set (match_operand:SI 4 "memory_operand" "")
1344         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1345   "TARGET_VX"
1347   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS);
1350 (define_expand "vfaezs<mode>"
1351   [(parallel
1352     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1353         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1354                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1355                            (match_operand:SI        3 "const_mask_operand" "")]
1356                           UNSPEC_VEC_VFAE))
1357    (set (reg:CCRAW CC_REGNUM)
1358         (unspec:CCRAW [(match_dup 1)
1359                        (match_dup 2)
1360                        (match_dup 3)]
1361                       UNSPEC_VEC_VFAECC))])
1362    (set (match_operand:SI 4 "memory_operand" "")
1363         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1364   "TARGET_VX"
1366   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1370 ; Vector find element equal
1372 ; vfeeb, vfeeh, vfeef
1373 (define_insn "vfee<mode>"
1374   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1375         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1376                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1377                            (const_int 0)]
1378                           UNSPEC_VEC_VFEE))]
1379   "TARGET_VX"
1380   "vfee<bhfgq>\t%v0,%v1,%v2,0"
1381   [(set_attr "op_type" "VRR")])
1383 ; vfeezb, vfeezh, vfeezf
1384 (define_insn "vfeez<mode>"
1385   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1386         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1387                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1388                            (const_int VSTRING_FLAG_ZS)]
1389                           UNSPEC_VEC_VFEE))]
1390   "TARGET_VX"
1391   "vfeez<bhfgq>s\t%v0,%v1,%v2,2"
1392   [(set_attr "op_type" "VRR")])
1394 (define_expand "vfees<mode>"
1395   [(parallel
1396     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1397           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1398                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1399                              (const_int VSTRING_FLAG_CS)]
1400                             UNSPEC_VEC_VFEE))
1401    (set (reg:CCRAW CC_REGNUM)
1402         (unspec:CCRAW [(match_dup 1)
1403                        (match_dup 2)
1404                        (const_int VSTRING_FLAG_CS)]
1405                       UNSPEC_VEC_VFEECC))])
1406    (set (match_operand:SI 3 "memory_operand" "")
1407         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1408   "TARGET_VX")
1410 (define_expand "vfeezs<mode>"
1411   [(parallel
1412     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1413           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1414                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1415                              (match_dup 4)]
1416                             UNSPEC_VEC_VFEE))
1417    (set (reg:CCRAW CC_REGNUM)
1418         (unspec:CCRAW [(match_dup 1)
1419                        (match_dup 2)
1420                        (match_dup 4)]
1421                       UNSPEC_VEC_VFEECC))])
1422    (set (match_operand:SI 3 "memory_operand" "")
1423         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1424   "TARGET_VX"
1426   operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1429 ; Vector find element not equal
1431 ; vfeneb, vfeneh, vfenef
1432 (define_insn "vfene<mode>"
1433   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1434         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1435                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1436                            (const_int 0)]
1437                           UNSPEC_VEC_VFENE))]
1438   "TARGET_VX"
1439   "vfene<bhfgq>\t%v0,%v1,%v2,0"
1440   [(set_attr "op_type" "VRR")])
1442 ; vec_vfenes can be found in vector.md since it is used for strlen
1444 ; vfenezb, vfenezh, vfenezf
1445 (define_insn "vfenez<mode>"
1446   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1447         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1448                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1449                            (const_int VSTRING_FLAG_ZS)]
1450                           UNSPEC_VEC_VFENE))]
1451   "TARGET_VX"
1452   "vfenez<bhfgq>\t%v0,%v1,%v2"
1453   [(set_attr "op_type" "VRR")])
1455 (define_expand "vfenes<mode>"
1456   [(parallel
1457     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1458           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1459                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1460                              (const_int VSTRING_FLAG_CS)]
1461                             UNSPEC_VEC_VFENE))
1462    (set (reg:CCRAW CC_REGNUM)
1463         (unspec:CCRAW [(match_dup 1)
1464                        (match_dup 2)
1465                        (const_int VSTRING_FLAG_CS)]
1466                       UNSPEC_VEC_VFENECC))])
1467    (set (match_operand:SI 3 "memory_operand" "")
1468         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1469   "TARGET_VX")
1471 (define_expand "vfenezs<mode>"
1472   [(parallel
1473     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1474           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1475                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1476                              (match_dup 4)]
1477                             UNSPEC_VEC_VFENE))
1478      (set (reg:CCRAW CC_REGNUM)
1479           (unspec:CCRAW [(match_dup 1)
1480                          (match_dup 2)
1481                          (match_dup 4)]
1482                         UNSPEC_VEC_VFENECC))])
1483    (set (match_operand:SI 3 "memory_operand" "")
1484         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1485   "TARGET_VX"
1487   operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1490 ; Vector isolate string
1492 ; vistrb, vistrh, vistrf
1493 (define_insn "vistr<mode>"
1494   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1495         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1496                           UNSPEC_VEC_VISTR))]
1497   "TARGET_VX"
1498   "vistr<bhfgq>\t%v0,%v1"
1499   [(set_attr "op_type" "VRR")])
1501 ; vistrbs, vistrhs, vistrfs
1502 (define_insn "*vistrs<mode>"
1503   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1504         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1505                           UNSPEC_VEC_VISTR))
1506    (set (reg:CCRAW CC_REGNUM)
1507         (unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))]
1508   "TARGET_VX"
1509   "vistr<bhfgq>s\t%v0,%v1"
1510   [(set_attr "op_type" "VRR")])
1512 (define_expand "vistrs<mode>"
1513   [(parallel
1514     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1515           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")]
1516                             UNSPEC_VEC_VISTR))
1517      (set (reg:CCRAW CC_REGNUM)
1518           (unspec:CCRAW [(match_dup 1)]
1519                         UNSPEC_VEC_VISTRCC))])
1520    (set (match_operand:SI 2 "memory_operand" "")
1521         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1522   "TARGET_VX")
1525 ; Vector compare range
1527 ; vstrcb, vstrch, vstrcf
1528 ; vstrczb, vstrczh, vstrczf
1529 (define_insn "vstrc<mode>"
1530   [(set (match_operand:VI_HW_QHS                    0 "register_operand"  "=v")
1531         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1532                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1533                            (match_operand:VI_HW_QHS 3 "register_operand"   "v")
1534                            (match_operand:QI        4 "const_mask_operand" "C")]
1535                           UNSPEC_VEC_VSTRC))]
1536   "TARGET_VX"
1538   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1540   if (flags & VSTRING_FLAG_ZS)
1541     {
1542       flags &= ~VSTRING_FLAG_ZS;
1543       operands[4] = GEN_INT (flags);
1544       return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1545     }
1546   return "vstrc<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1548 [(set_attr "op_type" "VRR")])
1550 ; vstrcbs, vstrchs, vstrcfs
1551 ; vstrczbs, vstrczhs, vstrczfs
1552 (define_insn "*vstrcs<mode>"
1553   [(set (match_operand:VI_HW_QHS                    0 "register_operand"  "=v")
1554         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1555                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1556                            (match_operand:VI_HW_QHS 3 "register_operand"   "v")
1557                            (match_operand:QI        4 "const_mask_operand" "C")]
1558                           UNSPEC_VEC_VSTRC))
1559    (set (reg:CCRAW CC_REGNUM)
1560         (unspec:CCRAW [(match_dup 1)
1561                        (match_dup 2)
1562                        (match_dup 3)
1563                        (match_dup 4)]
1564                       UNSPEC_VEC_VSTRCCC))]
1565   "TARGET_VX"
1567   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1569   if (flags & VSTRING_FLAG_ZS)
1570     {
1571       flags &= ~VSTRING_FLAG_ZS;
1572       operands[4] = GEN_INT (flags);
1573       return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1574     }
1575   return "vstrc<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1577   [(set_attr "op_type" "VRR")])
1579 (define_expand "vstrcz<mode>"
1580   [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1581         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "")
1582                            (match_operand:VI_HW_QHS 2 "register_operand"   "")
1583                            (match_operand:VI_HW_QHS 3 "register_operand"   "")
1584                            (match_operand:QI        4 "const_mask_operand" "")]
1585                           UNSPEC_VEC_VSTRC))]
1586   "TARGET_VX"
1588   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS);
1591 (define_expand "vstrcs<mode>"
1592   [(parallel
1593     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1594         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1595                            (match_operand:VI_HW_QHS 2 "register_operand" "")
1596                            (match_operand:VI_HW_QHS 3 "register_operand" "")
1597                            (match_operand:QI        4 "const_mask_operand" "")]
1598                           UNSPEC_VEC_VSTRC))
1599    (set (reg:CCRAW CC_REGNUM)
1600         (unspec:CCRAW [(match_dup 1)
1601                        (match_dup 2)
1602                        (match_dup 3)
1603                        (match_dup 4)]
1604                       UNSPEC_VEC_VSTRCCC))])
1605    (set (match_operand:SI 5 "memory_operand" "")
1606         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1607   "TARGET_VX"
1609   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS);
1612 (define_expand "vstrczs<mode>"
1613   [(parallel
1614     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1615         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1616                            (match_operand:VI_HW_QHS 2 "register_operand" "")
1617                            (match_operand:VI_HW_QHS 3 "register_operand" "")
1618                            (match_operand:QI        4 "const_mask_operand" "")]
1619                           UNSPEC_VEC_VSTRC))
1620    (set (reg:CCRAW CC_REGNUM)
1621         (unspec:CCRAW [(match_dup 1)
1622                        (match_dup 2)
1623                        (match_dup 3)
1624                        (match_dup 4)]
1625                       UNSPEC_VEC_VSTRCCC))])
1626    (set (match_operand:SI 5 "memory_operand" "")
1627         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1628   "TARGET_VX"
1630   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1633 ; Vector string search
1635 (define_expand "vstrs<mode>"
1636   [(parallel
1637     [(set (match_operand:V16QI                    0 "register_operand" "")
1638           (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1639                          (match_operand:VI_HW_QHS 2 "register_operand" "")
1640                          (match_operand:V16QI     3 "register_operand" "")
1641                          (const_int 0)]
1642                         UNSPEC_VEC_VSTRS))
1643      (set (reg:CCRAW CC_REGNUM)
1644           (unspec:CCRAW [(match_dup 1)
1645                          (match_dup 2)
1646                          (match_dup 3)
1647                          (const_int 0)]
1648                         UNSPEC_VEC_VSTRSCC))])
1649    (set (match_operand:SI 4 "memory_operand" "")
1650         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1651   "TARGET_VXE2")
1653 (define_expand "vstrsz<mode>"
1654   [(parallel
1655     [(set (match_operand:V16QI                    0 "register_operand" "")
1656           (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1657                          (match_operand:VI_HW_QHS 2 "register_operand" "")
1658                          (match_operand:V16QI     3 "register_operand" "")
1659                          (const_int VSTRING_FLAG_ZS)]
1660                         UNSPEC_VEC_VSTRS))
1661      (set (reg:CCRAW CC_REGNUM)
1662           (unspec:CCRAW [(match_dup 1)
1663                          (match_dup 2)
1664                          (match_dup 3)
1665                          (const_int VSTRING_FLAG_ZS)]
1666                         UNSPEC_VEC_VSTRSCC))])
1667    (set (match_operand:SI 4 "memory_operand" "")
1668         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1669   "TARGET_VXE2")
1671 ; vstrsb, vstrsh, vstrsf
1672 ; vstrszb, vstrszh, vstrszf
1673 (define_insn "vec_vstrs<mode>"
1674   [(set (match_operand:V16QI                    0 "register_operand" "=v")
1675         (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1676                        (match_operand:VI_HW_QHS 2 "register_operand" "v")
1677                        (match_operand:V16QI     3 "register_operand" "v")
1678                        (match_operand:QI        4 "const_mask_operand" "C")]
1679                       UNSPEC_VEC_VSTRS))
1680    (set (reg:CCRAW CC_REGNUM)
1681         (unspec:CCRAW [(match_dup 1)
1682                        (match_dup 2)
1683                        (match_dup 3)
1684                        (match_dup 4)]
1685                       UNSPEC_VEC_VSTRSCC))]
1686   "TARGET_VXE2"
1688   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1690   gcc_assert (!(flags & ~VSTRING_FLAG_ZS));
1692   if (flags == VSTRING_FLAG_ZS)
1693     return "vstrsz<bhfgq>\t%v0,%v1,%v2,%v3";
1694   return "vstrs<bhfgq>\t%v0,%v1,%v2,%v3";
1696   [(set_attr "op_type" "VRR")])
1699 ; Vector convert int<->float
1701 (define_insn "vcdgb"
1702   [(set (match_operand:V2DF 0 "register_operand"                "=v")
1703         (unspec:V2DF [(match_operand:V2DI 1 "register_operand"   "v")
1704                       (match_operand:QI   2 "const_mask_operand" "C")  ; inexact suppression
1705                       (match_operand:QI   3 "const_mask_operand" "C")] ; rounding mode
1706                      UNSPEC_VEC_VCDGB))]
1707   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1708   "vcdgb\t%v0,%v1,%b2,%b3"
1709   [(set_attr "op_type" "VRR")])
1712 ; The result needs to be multiplied with 2**-op2
1713 (define_expand "vec_ctd_s64"
1714   [(set (match_operand:V2DF               0 "register_operand" "")
1715         (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1716                       (const_int VEC_NOINEXACT)
1717                       (const_int VEC_RND_CURRENT)]
1718                      UNSPEC_VEC_VCDGB))
1719    (use (match_operand:QI 2 "const_int_operand" ""))
1720    (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1721   "TARGET_VX"
1723   REAL_VALUE_TYPE f;
1724   rtx c;
1726   real_2expN (&f, -INTVAL (operands[2]), DFmode);
1727   c = const_double_from_real_value (f, DFmode);
1729   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1730   operands[3] = force_reg (V2DFmode, operands[3]);
1733 (define_insn "vcdlgb"
1734   [(set (match_operand:V2DF 0 "register_operand"                 "=v")
1735         (unspec:V2DF [(match_operand:V2DI 1 "register_operand"    "v")
1736                       (match_operand:QI   2 "const_mask_operand"  "C")  ; inexact suppression
1737                       (match_operand:QI   3 "const_mask_operand"  "C")] ; rounding mode
1738                      UNSPEC_VEC_VCDLGB))]
1739   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1740   "vcdlgb\t%v0,%v1,%b2,%b3"
1741   [(set_attr "op_type" "VRR")])
1743 ; The result needs to be multiplied with 2**-op2
1744 (define_expand "vec_ctd_u64"
1745   [(set (match_operand:V2DF               0 "register_operand" "")
1746         (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1747                       (const_int VEC_NOINEXACT)
1748                       (const_int VEC_RND_CURRENT)]
1749                      UNSPEC_VEC_VCDLGB))
1750    (use (match_operand:QI 2 "const_int_operand" ""))
1751    (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1752   "TARGET_VX"
1754   REAL_VALUE_TYPE f;
1755   rtx c;
1757   real_2expN (&f, -INTVAL (operands[2]), DFmode);
1758   c = const_double_from_real_value (f, DFmode);
1760   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1761   operands[3] = force_reg (V2DFmode, operands[3]);
1764 (define_insn "vcgdb"
1765   [(set (match_operand:V2DI 0 "register_operand"                "=v")
1766         (unspec:V2DI [(match_operand:V2DF 1 "register_operand"   "v")
1767                       (match_operand:QI   2 "const_mask_operand" "C")
1768                       (match_operand:QI   3 "const_mask_operand" "C")]
1769                      UNSPEC_VEC_VCGDB))]
1770   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1771   "vcgdb\t%v0,%v1,%b2,%b3"
1772   [(set_attr "op_type" "VRR")])
1774 ; The input needs to be multiplied with 2**op2
1775 (define_expand "vec_ctsl"
1776   [(use (match_operand:QI 2 "const_int_operand" ""))
1777    (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1778                                  (match_dup 3)))
1779    (set (match_operand:V2DI 0 "register_operand" "")
1780         (unspec:V2DI [(match_dup 4)
1781                       (const_int VEC_NOINEXACT)
1782                       (const_int VEC_RND_CURRENT)]
1783                      UNSPEC_VEC_VCGDB))]
1784   "TARGET_VX"
1786   REAL_VALUE_TYPE f;
1787   rtx c;
1789   real_2expN (&f, INTVAL (operands[2]), DFmode);
1790   c = const_double_from_real_value (f, DFmode);
1792   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1793   operands[3] = force_reg (V2DFmode, operands[3]);
1794   operands[4] = gen_reg_rtx (V2DFmode);
1797 (define_insn "vclgdb"
1798   [(set (match_operand:V2DI 0 "register_operand"               "=v")
1799         (unspec:V2DI [(match_operand:V2DF 1 "register_operand"  "v")
1800                       (match_operand:QI   2 "const_mask_operand" "C")
1801                       (match_operand:QI   3 "const_mask_operand" "C")]
1802                      UNSPEC_VEC_VCLGDB))]
1803   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1804   "vclgdb\t%v0,%v1,%b2,%b3"
1805   [(set_attr "op_type" "VRR")])
1807 ; The input needs to be multiplied with 2**op2
1808 (define_expand "vec_ctul"
1809   [(use (match_operand:QI 2 "const_int_operand" ""))
1810    (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1811                                  (match_dup 3)))
1812    (set (match_operand:V2DI 0 "register_operand" "")
1813         (unspec:V2DI [(match_dup 4)
1814                       (const_int VEC_NOINEXACT)
1815                       (const_int VEC_RND_CURRENT)]
1816                      UNSPEC_VEC_VCLGDB))]
1817   "TARGET_VX"
1819   REAL_VALUE_TYPE f;
1820   rtx c;
1822   real_2expN (&f, INTVAL (operands[2]), DFmode);
1823   c = const_double_from_real_value (f, DFmode);
1825   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1826   operands[3] = force_reg (V2DFmode, operands[3]);
1827   operands[4] = gen_reg_rtx (V2DFmode);
1830 ; Vector load fp integer - IEEE inexact exception is suppressed
1831 ; vfisb, vfidb, wfisb, wfidb, wfixb
1832 (define_insn "vec_fpint<mode>"
1833   [(set (match_operand:VFT              0 "register_operand"  "=v")
1834         (unspec:VFT [(match_operand:VFT 1 "register_operand"   "v")
1835                      (match_operand:QI  2 "const_mask_operand" "C")  ; inexact suppression control
1836                      (match_operand:QI  3 "const_mask_operand" "C")] ; rounding mode
1837                      UNSPEC_VEC_VFI))]
1838   "TARGET_VX"
1839   "<vw>fi<sdx>b\t%v0,%v1,%b2,%b3"
1840   [(set_attr "op_type" "VRR")])
1843 ; Vector load lengthened - V4SF -> V2DF
1845 (define_insn "vflls"
1846   [(set (match_operand:V2DF 0 "register_operand"               "=v")
1847         (unspec:V2DF [(match_operand:V4SF 1 "register_operand"  "v")]
1848                      UNSPEC_VEC_VFLL))]
1849   "TARGET_VX"
1850   "vldeb\t%v0,%v1"
1851   [(set_attr "op_type" "VRR")])
1853 (define_expand "vec_ld2f"
1854   [; Initialize a vector to all zeroes.  FIXME: This should not be
1855    ; necessary since all elements of the vector will be set anyway.
1856    ; This is just to make it explicit to the data flow framework.
1857    (set (match_dup 2) (match_dup 3))
1858    (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "")
1859                                     (const_int 0)
1860                                     (match_dup 2)]
1861                                     UNSPEC_VEC_SET))
1862    (set (match_dup 2) (unspec:V4SF [(match_dup 4)
1863                                     (const_int 2)
1864                                     (match_dup 2)]
1865                                     UNSPEC_VEC_SET))
1866    (set (match_operand:V2DF 0 "register_operand" "")
1867         (unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VFLL))]
1868   "TARGET_VX"
1870   operands[2] = gen_reg_rtx (V4SFmode);
1871   operands[3] = CONST0_RTX (V4SFmode);
1872   operands[4] = adjust_address (operands[1], SFmode, 4);
1876 ; Vector load rounded - V2DF -> V4SF
1878 (define_insn "vflrd"
1879   [(set (match_operand:V4SF 0 "register_operand"                "=v")
1880         (unspec:V4SF [(match_operand:V2DF 1 "register_operand"   "v")
1881                       (match_operand:QI   2 "const_mask_operand" "C")
1882                       (match_operand:QI   3 "const_mask_operand" "C")]
1883                      UNSPEC_VEC_VFLR))]
1884   "TARGET_VX"
1885   "vledb\t%v0,%v1,%b2,%b3"
1886   [(set_attr "op_type" "VRR")])
1888 (define_expand "vec_st2f"
1889   [(set (match_dup 2)
1890         (unspec:V4SF [(match_operand:V2DF 0 "register_operand" "")
1891                       (const_int VEC_INEXACT)
1892                       (const_int VEC_RND_CURRENT)]
1893                      UNSPEC_VEC_VFLR))
1894    (set (match_operand:SF 1 "memory_operand" "")
1895         (vec_select:SF (match_dup 2)
1896          (parallel [(const_int 0)])))
1897    (set (match_dup 3)
1898         (vec_select:SF (match_dup 2)
1899          (parallel [(const_int 2)])))]
1900   "TARGET_VX"
1902   operands[2] = gen_reg_rtx (V4SFmode);
1903   operands[3] = adjust_address (operands[1], SFmode, 4);
1907 ; Vector square root fp vec_sqrt -> sqrt rtx standard name
1909 ;; Vector FP test data class immediate
1911 ; vec_all_nan, vec_all_numeric, vec_any_nan, vec_any_numeric
1912 ; These ignore the vector result and only want CC stored to an int
1913 ; pointer.
1915 ; vftcisb, vftcidb, wftcixb
1916 (define_insn "*vftci<mode>_cconly"
1917   [(set (reg:CCRAW CC_REGNUM)
1918         (unspec:CCRAW [(match_operand:VF_HW 1 "register_operand"  "v")
1919                        (match_operand:HI    2 "const_int_operand" "J")]
1920                       UNSPEC_VEC_VFTCICC))
1921    (clobber (match_scratch:<TOINTVEC> 0 "=v"))]
1922   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1923   "<vw>ftci<sdx>b\t%v0,%v1,%x2"
1924   [(set_attr "op_type" "VRR")])
1926 (define_expand "vftci<mode>_intcconly"
1927   [(parallel
1928     [(set (reg:CCRAW CC_REGNUM)
1929           (unspec:CCRAW [(match_operand:VF_HW 0 "register_operand")
1930                          (match_operand:HI    1 "const_int_operand")]
1931                         UNSPEC_VEC_VFTCICC))
1932      (clobber (scratch:<TOINTVEC>))])
1933    (set (match_operand:SI 2 "register_operand" "")
1934         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1935   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")")
1937 ; vec_fp_test_data_class wants the result vector and the CC stored to
1938 ; an int pointer.
1940 ; vftcisb, vftcidb, wftcixb
1941 (define_insn "vftci<mode>"
1942   [(set (match_operand:VF_HW                0 "register_operand"  "=v")
1943         (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand"   "v")
1944                        (match_operand:HI    2 "const_int_operand"  "J")]
1945                       UNSPEC_VEC_VFTCI))
1946    (set (reg:CCRAW CC_REGNUM)
1947         (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))]
1948   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1949   "<vw>ftci<sdx>b\t%v0,%v1,%x2"
1950   [(set_attr "op_type" "VRR")])
1952 (define_expand "vftci<mode>_intcc"
1953   [(parallel
1954     [(set (match_operand:VF_HW                0 "register_operand")
1955           (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand")
1956                          (match_operand:HI    2 "const_int_operand")]
1957                         UNSPEC_VEC_VFTCI))
1958      (set (reg:CCRAW CC_REGNUM)
1959           (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))])
1960    (set (match_operand:SI                     3 "nonimmediate_operand")
1961         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1962   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")")
1965 ;; Integer compares
1968 ; All comparisons which produce a CC need fully populated (VI_HW)
1969 ; vector arguments.  Otherwise the any/all CCs would be just bogus.
1971 (define_insn "*vec_cmp<VICMP:insn_cmp><VI_HW:mode>_cconly"
1972   [(set (reg:VICMP CC_REGNUM)
1973         (compare:VICMP (match_operand:VI_HW 0 "register_operand" "v")
1974                        (match_operand:VI_HW 1 "register_operand" "v")))
1975    (clobber (match_scratch:VI_HW 2 "=v"))]
1976   "TARGET_VX"
1977   "vc<VICMP:insn_cmp><VI_HW:bhfgq>s\t%v2,%v0,%v1"
1978   [(set_attr "op_type" "VRR")])
1980 ; FIXME: The following 2x3 definitions should be merged into 2 with
1981 ; VICMP like above but I could not find a way to set the comparison
1982 ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the
1983 ; other way around - setting the mode depending on the code
1984 ; (code_iterator).
1985 (define_expand "vec_cmpeq<VI_HW:mode>_cc"
1986   [(parallel
1987     [(set (reg:CCVEQ CC_REGNUM)
1988         (compare:CCVEQ (match_operand:VI_HW 1 "register_operand" "v")
1989                        (match_operand:VI_HW 2 "register_operand" "v")))
1990      (set (match_operand:VI_HW 0 "register_operand" "=v")
1991           (eq:VI_HW (match_dup 1) (match_dup 2)))])
1992    (set (match_operand:SI 3 "memory_operand" "")
1993         (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
1994   "TARGET_VX")
1996 (define_expand "vec_cmph<VI_HW:mode>_cc"
1997   [(parallel
1998     [(set (reg:CCVIH CC_REGNUM)
1999           (compare:CCVIH (match_operand:VI_HW 1 "register_operand" "v")
2000                          (match_operand:VI_HW 2 "register_operand" "v")))
2001      (set (match_operand:VI_HW 0 "register_operand" "=v")
2002           (gt:VI_HW (match_dup 1) (match_dup 2)))])
2003    (set (match_operand:SI 3 "memory_operand" "")
2004         (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2005   "TARGET_VX")
2007 (define_expand "vec_cmphl<VI_HW:mode>_cc"
2008   [(parallel
2009     [(set (reg:CCVIHU CC_REGNUM)
2010           (compare:CCVIHU (match_operand:VI_HW 1 "register_operand" "v")
2011                           (match_operand:VI_HW 2 "register_operand" "v")))
2012      (set (match_operand:VI_HW 0 "register_operand" "=v")
2013           (gtu:VI_HW (match_dup 1) (match_dup 2)))])
2014    (set (match_operand:SI 3 "memory_operand" "")
2015         (unspec:SI [(reg:CCVIHU CC_REGNUM)] UNSPEC_CC_TO_INT))]
2016   "TARGET_VX")
2019 (define_insn "*vec_cmpeq<VI_HW:mode>_cc"
2020   [(set (reg:CCVEQ CC_REGNUM)
2021         (compare:CCVEQ (match_operand:VI_HW 0 "register_operand"  "v")
2022                        (match_operand:VI_HW 1 "register_operand"  "v")))
2023    (set (match_operand:VI_HW                2 "register_operand" "=v")
2024         (eq:VI_HW (match_dup 0) (match_dup 1)))]
2025   "TARGET_VX"
2026   "vceq<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2027   [(set_attr "op_type" "VRR")])
2029 (define_insn "*vec_cmph<VI_HW:mode>_cc"
2030   [(set (reg:CCVIH CC_REGNUM)
2031         (compare:CCVIH (match_operand:VI_HW 0 "register_operand"  "v")
2032                        (match_operand:VI_HW 1 "register_operand"  "v")))
2033    (set (match_operand:VI_HW               2 "register_operand" "=v")
2034         (gt:VI_HW (match_dup 0) (match_dup 1)))]
2035   "TARGET_VX"
2036   "vch<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2037   [(set_attr "op_type" "VRR")])
2039 (define_insn "*vec_cmphl<VI_HW:mode>_cc"
2040   [(set (reg:CCVIHU CC_REGNUM)
2041         (compare:CCVIHU (match_operand:VI_HW 0 "register_operand"  "v")
2042                         (match_operand:VI_HW 1 "register_operand"  "v")))
2043    (set (match_operand:VI_HW                2 "register_operand" "=v")
2044         (gtu:VI_HW (match_dup 0) (match_dup 1)))]
2045   "TARGET_VX"
2046   "vchl<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2047   [(set_attr "op_type" "VRR")])
2050 ;; Floating point compares
2053 ; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs
2054 (define_insn "*vec_cmp<insn_cmp><VF_HW:mode>_cconly"
2055   [(set (reg:VFCMP CC_REGNUM)
2056         (compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
2057                        (match_operand:VF_HW 1 "register_operand" "v")))
2058    (clobber (match_scratch:<TOINTVEC> 2 "=v"))]
2059   "TARGET_VX"
2060   "<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1"
2061   [(set_attr "op_type" "VRR")])
2063 ; FIXME: Merge the following 2x3 patterns with VFCMP
2064 (define_expand "vec_cmpeq<mode>_cc"
2065   [(parallel
2066     [(set (reg:CCVEQ CC_REGNUM)
2067           (compare:CCVEQ (match_operand:VF_HW 1 "register_operand"  "v")
2068                          (match_operand:VF_HW 2 "register_operand"  "v")))
2069      (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2070           (eq:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2071    (set (match_operand:SI 3 "memory_operand" "")
2072         (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2073   "TARGET_VX")
2075 (define_expand "vec_cmph<mode>_cc"
2076   [(parallel
2077     [(set (reg:CCVFH CC_REGNUM)
2078           (compare:CCVFH (match_operand:VF_HW 1 "register_operand"  "v")
2079                          (match_operand:VF_HW 2 "register_operand"  "v")))
2080      (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2081           (gt:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2082    (set (match_operand:SI 3 "memory_operand" "")
2083         (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2084   "TARGET_VX")
2086 (define_expand "vec_cmphe<mode>_cc"
2087   [(parallel
2088     [(set (reg:CCVFHE CC_REGNUM)
2089           (compare:CCVFHE (match_operand:VF_HW 1 "register_operand"  "v")
2090                           (match_operand:VF_HW 2 "register_operand"  "v")))
2091      (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2092           (ge:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2093    (set (match_operand:SI 3 "memory_operand" "")
2094         (unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]
2095   "TARGET_VX")
2097 ; These 3 cannot be merged as the insn defintion above since it also
2098 ; requires to rewrite the RTL equality operator that the same time as
2099 ; the CC mode.
2101 ; vfcesbs, vfcedbs, wfcexbs
2102 (define_insn "*vec_cmpeq<mode>_cc"
2103   [(set (reg:CCVEQ CC_REGNUM)
2104         (compare:CCVEQ (match_operand:VF_HW 0 "register_operand"  "v")
2105                        (match_operand:VF_HW 1 "register_operand"  "v")))
2106    (set (match_operand:<TOINTVEC>              2 "register_operand" "=v")
2107         (eq:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2108   "TARGET_VX"
2109   "<vw>fce<sdx>bs\t%v2,%v0,%v1"
2110   [(set_attr "op_type" "VRR")])
2112 ; vfchsbs, vfchdbs, wfchxbs
2113 (define_insn "*vec_cmph<mode>_cc"
2114   [(set (reg:CCVFH CC_REGNUM)
2115         (compare:CCVFH (match_operand:VF_HW 0 "register_operand"  "v")
2116                        (match_operand:VF_HW 1 "register_operand"  "v")))
2117    (set (match_operand:<TOINTVEC>              2 "register_operand" "=v")
2118         (gt:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2119   "TARGET_VX"
2120   "<vw>fch<sdx>bs\t%v2,%v0,%v1"
2121   [(set_attr "op_type" "VRR")])
2123 ; vfchesbs, vfchedbs, wfchexbs
2124 (define_insn "*vec_cmphe<mode>_cc"
2125   [(set (reg:CCVFHE CC_REGNUM)
2126         (compare:CCVFHE (match_operand:VF_HW 0 "register_operand"  "v")
2127                         (match_operand:VF_HW 1 "register_operand"  "v")))
2128    (set (match_operand:<TOINTVEC>            2 "register_operand" "=v")
2129         (ge:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2130   "TARGET_VX"
2131   "<vw>fche<sdx>bs\t%v2,%v0,%v1"
2132   [(set_attr "op_type" "VRR")])
2135 (define_insn "vfmin<mode>"
2136   [(set (match_operand:VF_HW                0 "register_operand"  "=v")
2137         (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand"   "v")
2138                        (match_operand:VF_HW 2 "register_operand"   "v")
2139                        (match_operand:QI    3 "const_mask_operand" "C")]
2140                       UNSPEC_VEC_VFMIN))]
2141   "TARGET_VXE"
2142   "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3"
2143   [(set_attr "op_type" "VRR")])
2145 (define_insn "vfmax<mode>"
2146   [(set (match_operand:VF_HW                0 "register_operand"  "=v")
2147         (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand"   "v")
2148                        (match_operand:VF_HW 2 "register_operand"   "v")
2149                        (match_operand:QI    3 "const_mask_operand" "C")]
2150                       UNSPEC_VEC_VFMAX))]
2151   "TARGET_VXE"
2152   "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3"
2153   [(set_attr "op_type" "VRR")])
2155 ; The element reversal builtins introduced with z15 have been made
2156 ; available also for older CPUs down to z13.
2157 (define_expand "eltswap<mode>"
2158   [(set (match_operand:VEC_HW                 0 "nonimmediate_operand" "")
2159         (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "")]
2160                        UNSPEC_VEC_ELTSWAP))]
2161   "TARGET_VX")
2163 ; The byte element reversal is implemented as 128 bit byte swap.
2164 ; Alternatively this could be emitted as bswap:V1TI but the required
2165 ; subregs appear to confuse combine.
2166 (define_insn "*eltswapv16qi"
2167   [(set (match_operand:V16QI                0 "nonimmediate_operand" "=v,v,R")
2168         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand"  "v,R,v")]
2169                       UNSPEC_VEC_ELTSWAP))]
2170   "TARGET_VXE2"
2171   "@
2172    #
2173    vlbrq\t%v0,%v1
2174    vstbrq\t%v1,%v0"
2175   [(set_attr "op_type" "*,VRX,VRX")])
2177 ; vlerh, vlerf, vlerg, vsterh, vsterf, vsterg
2178 (define_insn "*eltswap<mode>"
2179   [(set (match_operand:V_HW_HSD                   0 "nonimmediate_operand" "=v,v,R")
2180         (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "nonimmediate_operand"  "v,R,v")]
2181                          UNSPEC_VEC_ELTSWAP))]
2182   "TARGET_VXE2"
2183   "@
2184    #
2185    vler<bhfgq>\t%v0,%v1
2186    vster<bhfgq>\t%v1,%v0"
2187   [(set_attr "op_type" "*,VRX,VRX")])
2189 ; The emulation pattern below will also accept
2190 ;  vst (eltswap (vl))
2191 ; i.e. both operands in memory, which reload needs to fix.
2192 ; Split into
2193 ;  vl
2194 ;  vster (=vst (eltswap))
2195 ; since we prefer vster over vler as long as the latter
2196 ; does not support alignment hints.
2197 (define_split
2198   [(set (match_operand:VEC_HW                 0 "memory_operand" "")
2199         (unspec:VEC_HW [(match_operand:VEC_HW 1 "memory_operand" "")]
2200                        UNSPEC_VEC_ELTSWAP))]
2201   "TARGET_VXE2 && can_create_pseudo_p ()"
2202   [(set (match_dup 2) (match_dup 1))
2203    (set (match_dup 0)
2204         (unspec:VEC_HW [(match_dup 2)] UNSPEC_VEC_ELTSWAP))]
2206   operands[2] = gen_reg_rtx (<MODE>mode);
2210 ; Swapping v2df/v2di can be done via vpdi on z13 and z14.
2211 (define_split
2212   [(set (match_operand:V_HW_2                 0 "register_operand" "")
2213         (unspec:V_HW_2 [(match_operand:V_HW_2 1 "register_operand" "")]
2214                        UNSPEC_VEC_ELTSWAP))]
2215   "TARGET_VX && can_create_pseudo_p ()"
2216   [(set (match_operand:V_HW_2     0 "register_operand" "=v")
2217         (vec_select:V_HW_2
2218          (vec_concat:<vec_2x_nelts>
2219           (match_operand:V_HW_2 1 "register_operand"  "v")
2220           (match_dup 1))
2221          (parallel [(const_int 1) (const_int 2)])))]
2225 ; Swapping v4df/v4si can be done via vpdi and rot.
2226 (define_split
2227   [(set (match_operand:V_HW_4                 0 "register_operand" "")
2228         (unspec:V_HW_4 [(match_operand:V_HW_4 1 "register_operand" "")]
2229                        UNSPEC_VEC_ELTSWAP))]
2230   "TARGET_VX && can_create_pseudo_p ()"
2231   [(set (match_dup 2)
2232         (vec_select:V_HW_4
2233          (vec_concat:<vec_2x_nelts>
2234           (match_dup 1)
2235           (match_dup 1))
2236          (parallel [(const_int 2) (const_int 3) (const_int 4) (const_int 5)])))
2237  (set (match_dup 3)
2238   (subreg:V2DI (match_dup 2) 0))
2239  (set (match_dup 4)
2240   (rotate:V2DI
2241    (match_dup 3)
2242    (const_int 32)))
2243  (set (match_operand:V_HW_4 0)
2244   (subreg:V_HW_4 (match_dup 4) 0))]
2246   operands[2] = gen_reg_rtx (<MODE>mode);
2247   operands[3] = gen_reg_rtx (V2DImode);
2248   operands[4] = gen_reg_rtx (V2DImode);
2251 ; z15 has instructions for doing element reversal from mem to reg
2252 ; or the other way around.  For reg to reg or on pre z15 machines
2253 ; we have to emulate it with vector permute.
2254 (define_insn_and_split "*eltswap<mode>_emu"
2255   [(set (match_operand:VEC_HW                 0 "nonimmediate_operand" "=vR")
2256         (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "vR")]
2257                        UNSPEC_VEC_ELTSWAP))]
2258   "TARGET_VX && can_create_pseudo_p ()"
2259   "#"
2260   "&& ((!memory_operand (operands[0], <MODE>mode)
2261         && !memory_operand (operands[1], <MODE>mode))
2262        || !TARGET_VXE2)"
2263   [(set (match_dup 3)
2264         (unspec:V16QI [(match_dup 4)
2265                        (match_dup 4)
2266                        (match_dup 2)]
2267                       UNSPEC_VEC_PERM))
2268    (set (match_dup 0) (subreg:VEC_HW (match_dup 3) 0))]
2270   static char p[4][16] =
2271     { { 15, 14, 13, 12, 11, 10, 9,  8,  7,  6,  5,  4,  3,  2,  1,  0 },   /* Q */
2272       { 14, 15, 12, 13, 10, 11, 8,  9,  6,  7,  4,  5,  2,  3,  0,  1 },   /* H */
2273       { 12, 13, 14, 15, 8,  9,  10, 11, 4,  5,  6,  7,  0,  1,  2,  3 },   /* S */
2274       { 8,  9,  10, 11, 12, 13, 14, 15, 0,  1,  2,  3,  4,  5,  6,  7 } }; /* D */
2275   char *perm;
2276   rtx perm_rtx[16], constv;
2278   switch (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)))
2279     {
2280     case 1: perm = p[0]; break;
2281     case 2: perm = p[1]; break;
2282     case 4: perm = p[2]; break;
2283     case 8: perm = p[3]; break;
2284     default: gcc_unreachable ();
2285     }
2287   for (int i = 0; i < 16; i++)
2288     perm_rtx[i] = GEN_INT (perm[i]);
2290   operands[1] = force_reg (<MODE>mode, operands[1]);
2291   operands[2] = gen_reg_rtx (V16QImode);
2292   operands[3] = gen_reg_rtx (V16QImode);
2293   operands[4] = simplify_gen_subreg (V16QImode, operands[1], <MODE>mode, 0);
2294   constv = force_const_mem (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm_rtx)));
2295   emit_move_insn (operands[2], constv);
2298 ; vec_insert (__builtin_bswap32 (*a), b, 1)        set-element-bswap-2.c
2299 ; b[1] = __builtin_bswap32 (*a)                    set-element-bswap-3.c
2300 ; vlebrh, vlebrf, vlebrg
2301 (define_insn "*vec_set_bswap_elem<mode>"
2302   [(set (match_operand:V_HW_HSD                                     0 "register_operand" "=v")
2303         (unspec:V_HW_HSD [(bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand"    "R"))
2304                                            (match_operand:SI        2 "const_int_operand" "C")
2305                                            (match_operand:V_HW_HSD  3 "register_operand"  "0")]
2306                   UNSPEC_VEC_SET))]
2307   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2308   "vlebr<bhfgq>\t%v0,%1,%2"
2309   [(set_attr "op_type" "VRX")])
2311 ; vec_revb (vec_insert (*a, vec_revb (b), 1))      set-element-bswap-1.c
2312 ; vlebrh, vlebrf, vlebrg
2313 (define_insn "*vec_set_bswap_vec<mode>"
2314   [(set (match_operand:V_HW_HSD                                     0 "register_operand"       "=v")
2315         (bswap:V_HW_HSD
2316          (unspec:V_HW_HSD [(match_operand:<non_vec>                 1 "memory_operand"          "R")
2317                            (match_operand:SI                        2 "const_int_operand"       "C")
2318                            (bswap:V_HW_HSD (match_operand:V_HW_HSD  3 "register_operand"        "0"))]
2319                           UNSPEC_VEC_SET)))
2320    (use (match_operand:V16QI                                        4 "permute_pattern_operand" "X"))]
2321   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2322   "vlebr<bhfgq>\t%v0,%1,%2"
2323   [(set_attr "op_type" "VRX")])
2325 ; *a = vec_extract (vec_revb (b), 1);              get-element-bswap-3.c
2326 ; *a = vec_revb (b)[1];                            get-element-bswap-4.c
2327 ; vstebrh, vstebrf, vstebrg
2328 (define_insn "*vec_extract_bswap_vec<mode>"
2329   [(set (match_operand:<non_vec>                  0 "memory_operand"   "=R")
2330         (vec_select:<non_vec>
2331          (bswap:V_HW_HSD (match_operand:V_HW_HSD  1 "register_operand"  "v"))
2332          (parallel [(match_operand:SI             2 "const_int_operand" "C")])))]
2333   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2334   "vstebr<bhfgq>\t%v1,%0,%2"
2335   [(set_attr "op_type" "VRX")])
2337 ; *a = __builtin_bswap32 (vec_extract (b, 1));     get-element-bswap-1.c
2338 ; *a = __builtin_bswap32 (b[1]);                   get-element-bswap-2.c
2339 ; vstebrh, vstebrf, vstebrg
2340 (define_insn "*vec_extract_bswap_elem<mode>"
2341   [(set (match_operand:<non_vec>                  0 "memory_operand"   "=R")
2342         (bswap:<non_vec>
2343          (vec_select:<non_vec>
2344           (match_operand:V_HW_HSD                 1 "register_operand"  "v")
2345           (parallel [(match_operand:SI            2 "const_int_operand" "C")]))))]
2346   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2347   "vstebr<bhfgq>\t%v1,%0,%2"
2348   [(set_attr "op_type" "VRX")])
2352 ;; NNPA Facility
2355 (define_insn "vclfnhs_v8hi"
2356   [(set (match_operand:V4SF                0 "register_operand"  "=v")
2357         (unspec:V4SF [(vec_select:V4HI
2358                        (match_operand:V8HI 1 "register_operand"   "v")
2359                        (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))
2360                       (match_operand:QI    2 "const_mask_operand" "C")]
2361                      UNSPEC_NNPA_VCLFNHS_V8HI))]
2362   "TARGET_NNPA"
2363   "vclfnh\t%v0,%v1,2,%2"
2364   [(set_attr "op_type" "VRR")])
2366 (define_insn "vclfnls_v8hi"
2367   [(set (match_operand:V4SF                0 "register_operand"   "=v")
2368         (unspec:V4SF [(vec_select:V4HI
2369                        (match_operand:V8HI 1 "register_operand"   "v")
2370                        (parallel [(const_int 4) (const_int 5) (const_int 6) (const_int 7)]))
2371                       (match_operand:QI    2 "const_mask_operand"  "C")]
2372                      UNSPEC_NNPA_VCLFNLS_V8HI))]
2373   "TARGET_NNPA"
2374   "vclfnl\t%v0,%v1,2,%2"
2375   [(set_attr "op_type" "VRR")])
2377 (define_insn "vcrnfs_v8hi"
2378   [(set (match_operand:V8HI               0 "register_operand"   "=v")
2379         (unspec:V8HI [(match_operand:V4SF 1 "register_operand"    "v")
2380                       (match_operand:V4SF 2 "register_operand"    "v")
2381                       (match_operand:QI   3 "const_mask_operand"  "C")]
2382                      UNSPEC_NNPA_VCRNFS_V8HI))]
2383   "TARGET_NNPA"
2384   "vcrnf\t%v0,%v1,%v2,%3,2"
2385   [(set_attr "op_type" "VRR")])
2387 (define_insn "vcfn_v8hi"
2388   [(set (match_operand:V8HI               0 "register_operand"   "=v")
2389         (unspec:V8HI [(match_operand:V8HI 1 "register_operand"    "v")
2390                       (match_operand:QI   2 "const_mask_operand"  "C")]
2391                      UNSPEC_NNPA_VCFN_V8HI))]
2392   "TARGET_NNPA"
2393   "vcfn\t%v0,%v1,1,%2"
2394   [(set_attr "op_type" "VRR")])
2396 (define_insn "vcnf_v8hi"
2397   [(set (match_operand:V8HI               0 "register_operand"   "=v")
2398         (unspec:V8HI [(match_operand:V8HI 1 "register_operand"    "v")
2399                       (match_operand:QI   2 "const_mask_operand"  "C")]
2400                      UNSPEC_NNPA_VCNF_V8HI))]
2401   "TARGET_NNPA"
2402   "vcnf\t%v0,%v1,%2,1"
2403   [(set_attr "op_type" "VRR")])