Add hppa*-*-hpux* to targets which do not support split DWARF
[official-gcc.git] / gcc / config / s390 / vx-builtins.md
blob432d81a719fcf78eeaaf3505e221402a6e304be7
1 ;;- Instruction patterns for the System z vector facility builtins.
2 ;;  Copyright (C) 2015-2024 Free Software Foundation, Inc.
3 ;;  Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it under
8 ;; the terms of the GNU General Public License as published by the Free
9 ;; Software Foundation; either version 3, or (at your option) any later
10 ;; version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 ;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 ;; for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ; 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")])
533 (define_insn "*vsel<mode>_swapped"
534   [(set (match_operand:V_HW_FT               0 "register_operand" "=v")
535         (ior:V_HW_FT
536          (and:V_HW_FT (not:V_HW_FT (match_operand:V_HW_FT 3 "register_operand"  "v"))
537                       (match_operand:V_HW_FT 1 "register_operand"  "v"))
538          (and:V_HW_FT (match_dup 3)
539                       (match_operand:V_HW_FT 2 "register_operand"  "v"))))]
540   "TARGET_VX"
541   "vsel\t%v0,%2,%1,%3"
542   [(set_attr "op_type" "VRR")])
545 ; Vector sign extend to doubleword
547 ; Sign extend of right most vector element to respective double-word
548 ; vsegb, vsegh, vsegf
549 (define_insn "vec_extend<mode>"
550   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
551         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
552                           UNSPEC_VEC_EXTEND))]
553   "TARGET_VX"
554   "vseg<bhfgq>\t%v0,%1"
555   [(set_attr "op_type" "VRR")])
558 ; Vector store with length
560 ; Store bytes in OP1 from OP0 with the highest indexed byte to be
561 ; stored from OP0 given by OP2
562 (define_insn "vstl<mode>"
563   [(set (match_operand:BLK             2 "memory_operand"   "=Q")
564         (unspec:BLK [(match_operand:V  0 "register_operand"  "v")
565                      (match_operand:SI 1 "register_operand"  "d")]
566                     UNSPEC_VEC_STORE_LEN))]
567   "TARGET_VX"
568   "vstl\t%v0,%1,%2"
569   [(set_attr "op_type" "VRS")])
571 ; Vector store rightmost with length
573 (define_expand "vstrlrv16qi"
574   [(set (match_operand:BLK                2 "memory_operand"    "")
575         (unspec:BLK [(match_operand:V16QI 0 "register_operand"  "")
576                      (match_operand:SI    1 "nonmemory_operand" "")]
577                     UNSPEC_VEC_STORE_LEN_R))]
578   "TARGET_VXE"
580   /* vstrlr sets all length values beyond 15 to 15.  Emulate the same
581      behavior for immediate length operands.  vstrl would trigger a
582      SIGILL for too large immediate operands.  */
583   if (CONST_INT_P (operands[1])
584       && (UINTVAL (operands[1]) & 0xffffffff) > 15)
585     operands[1] = GEN_INT (15);
588 (define_insn "*vstrlrv16qi"
589   [(set (match_operand:BLK                2 "memory_operand"    "=Q,  R,  Q")
590         (unspec:BLK [(match_operand:V16QI 0 "register_operand"   "v,  v,  v")
591                      (match_operand:SI    1 "nonmemory_operand"  "d,j>f,jb4")]
592                     UNSPEC_VEC_STORE_LEN_R))]
593   "TARGET_VXE"
594   "@
595    vstrlr\t%v0,%1,%2
596    vst\t%v0,%2%A2
597    vstrl\t%v0,%2,%1"
598   [(set_attr "op_type" "VRS,VRX,VSI")])
602 ; vector bit permute
604 (define_insn "vbpermv16qi"
605   [(set (match_operand:V2DI                0 "register_operand" "=v")
606         (unspec:V2DI [(match_operand:V16QI 1 "register_operand"  "v")
607                       (match_operand:V16QI 2 "register_operand"  "v")]
608                      UNSPEC_VEC_VBPERM))]
609   "TARGET_VXE"
610   "vbperm\t%v0,%v1,%v2"
611   [(set_attr "op_type" "VRR")])
613 ; Vector unpack high
615 ; vuphb, vuphh, vuphf
616 (define_insn "vec_unpackh<mode>"
617   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
618         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
619                              UNSPEC_VEC_UNPACKH))]
620   "TARGET_VX"
621   "vuph<bhfgq>\t%v0,%v1"
622   [(set_attr "op_type" "VRR")])
624 ; vuplhb, vuplhh, vuplhf
625 (define_insn "vec_unpackh_l<mode>"
626   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
627         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
628                              UNSPEC_VEC_UNPACKH_L))]
629   "TARGET_VX"
630   "vuplh<bhfgq>\t%v0,%v1"
631   [(set_attr "op_type" "VRR")])
634 ; Vector unpack low
636 ; vuplb, vuplhw, vuplf
637 (define_insn "vec_unpackl<mode>"
638   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
639         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
640                              UNSPEC_VEC_UNPACKL))]
641   "TARGET_VX"
642   "vupl<bhfgq><w>\t%v0,%v1"
643   [(set_attr "op_type" "VRR")])
645 ; vupllb, vupllh, vupllf
646 (define_insn "vec_unpackl_l<mode>"
647   [(set (match_operand:<vec_double>                    0 "register_operand" "=v")
648         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
649                              UNSPEC_VEC_UNPACKL_L))]
650   "TARGET_VX"
651   "vupll<bhfgq>\t%v0,%v1"
652   [(set_attr "op_type" "VRR")])
655 ; Vector add
657 ; Vector add compute carry
659 ; vaccb, vacch, vaccf, vaccg, vaccq
660 (define_insn "vacc<bhfgq>_<mode>"
661   [(set (match_operand:VIT_HW                 0 "register_operand" "=v")
662         (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand"  "v")
663                         (match_operand:VIT_HW 2 "register_operand"  "v")]
664                        UNSPEC_VEC_ADDC))]
665   "TARGET_VX"
666   "vacc<bhfgq>\t%v0,%v1,%v2"
667   [(set_attr "op_type" "VRR")])
669 ; Vector add with carry
671 (define_insn "vacq"
672   [(set (match_operand:TI             0 "register_operand" "=v")
673         (unspec:TI [(match_operand:TI 1 "register_operand"  "v")
674                     (match_operand:TI 2 "register_operand"  "v")
675                     (match_operand:TI 3 "register_operand"  "v")]
676                    UNSPEC_VEC_ADDE_U128))]
677   "TARGET_VX"
678   "vacq\t%v0,%v1,%v2,%v3"
679   [(set_attr "op_type" "VRR")])
682 ; Vector add with carry compute carry
684 (define_insn "vacccq"
685   [(set (match_operand:TI             0 "register_operand" "=v")
686         (unspec:TI [(match_operand:TI 1 "register_operand"  "v")
687                     (match_operand:TI 2 "register_operand"  "v")
688                     (match_operand:TI 3 "register_operand"  "v")]
689                    UNSPEC_VEC_ADDEC_U128))]
690   "TARGET_VX"
691   "vacccq\t%v0,%v1,%v2,%v3"
692   [(set_attr "op_type" "VRR")])
695 ; Vector and
697 ; Vector and with complement
699 ; vnc
700 (define_insn "vec_andc<mode>3"
701   [(set (match_operand:VT_HW                       0 "register_operand" "=v")
702         (and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand"  "v"))
703                   (match_operand:VT_HW             1 "register_operand"  "v")))]
704   "TARGET_VX"
705   "vnc\t%v0,%v1,%v2"
706   [(set_attr "op_type" "VRR")])
709 ; Vector average
711 ; vavgb, vavgh, vavgf, vavgg
712 (define_insn "vec_avg<mode>"
713   [(set (match_operand:VI_HW                0 "register_operand" "=v")
714         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
715                        (match_operand:VI_HW 2 "register_operand"  "v")]
716                       UNSPEC_VEC_AVG))]
717   "TARGET_VX"
718   "vavg<bhfgq>\t%v0,%v1,%v2"
719   [(set_attr "op_type" "VRR")])
721 ; Vector average logical
723 ; vavglb, vavglh, vavglf, vavglg
724 (define_insn "vec_avgu<mode>"
725   [(set (match_operand:VI_HW                0 "register_operand" "=v")
726         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
727                        (match_operand:VI_HW 2 "register_operand"  "v")]
728                       UNSPEC_VEC_AVGU))]
729   "TARGET_VX"
730   "vavgl<bhfgq>\t%v0,%v1,%v2"
731   [(set_attr "op_type" "VRR")])
734 ; Vector checksum
736 (define_insn "vec_checksum"
737   [(set (match_operand:V4SI               0 "register_operand" "=v")
738         (unspec:V4SI [(match_operand:V4SI 1 "register_operand"  "v")
739                       (match_operand:V4SI 2 "register_operand"  "v")]
740                      UNSPEC_VEC_CHECKSUM))]
741   "TARGET_VX"
742   "vcksm\t%v0,%v1,%v2"
743   [(set_attr "op_type" "VRR")])
746 ;; Vector compare
749 ; vec_all/any int compares
751 (define_expand "vec_all_<intcmpcc:code><VI_HW:mode>"
752   [(match_operand:SI                0 "register_operand" "")
753    (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
754              (match_operand:VI_HW 2 "register_operand" ""))]
755   "TARGET_VX"
757   s390_expand_vec_compare_cc (operands[0],
758                               <intcmpcc:CODE>,
759                               operands[1],
760                               operands[2],
761                               true);
762   DONE;
765 (define_expand "vec_any_<intcmpcc:code><VI_HW:mode>"
766   [(match_operand:SI                0 "register_operand" "")
767    (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
768              (match_operand:VI_HW 2 "register_operand" ""))]
769   "TARGET_VX"
771   s390_expand_vec_compare_cc (operands[0],
772                               <intcmpcc:CODE>,
773                               operands[1],
774                               operands[2],
775                               false);
776   DONE;
779 ; vec_all/any fp compares
781 (define_expand "vec_all_<fpcmpcc:code><mode>"
782   [(match_operand:SI               0 "register_operand" "")
783    (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
784             (match_operand:VECF_HW 2 "register_operand" ""))]
785   "TARGET_VX"
787   s390_expand_vec_compare_cc (operands[0],
788                               <fpcmpcc:CODE>,
789                               operands[1],
790                               operands[2],
791                               true);
792   DONE;
795 (define_expand "vec_any_<fpcmpcc:code><mode>"
796   [(match_operand:SI               0 "register_operand" "")
797    (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
798             (match_operand:VECF_HW 2 "register_operand" ""))]
799   "TARGET_VX"
801   s390_expand_vec_compare_cc (operands[0],
802                               <fpcmpcc:CODE>,
803                               operands[1],
804                               operands[2],
805                               false);
806   DONE;
810 ; Compare without generating CC
812 (define_expand "vec_cmp<intcmp:code><VI_HW:mode>"
813   [(set (match_operand:VI_HW               0 "register_operand" "=v")
814         (intcmp:VI_HW (match_operand:VI_HW 1 "register_operand"  "v")
815                       (match_operand:VI_HW 2 "register_operand"  "v")))]
816   "TARGET_VX"
818   s390_expand_vec_compare (operands[0], <intcmp:CODE>, operands[1], operands[2]);
819   DONE;
822 (define_expand "vec_cmp<fpcmp:code><mode>"
823   [(set (match_operand:<TOINTVEC>              0 "register_operand" "=v")
824         (fpcmp:<TOINTVEC> (match_operand:VF_HW 1 "register_operand"  "v")
825                        (match_operand:VF_HW 2 "register_operand"  "v")))]
826   "TARGET_VX"
828   s390_expand_vec_compare (operands[0], <fpcmp:CODE>, operands[1], operands[2]);
829   DONE;
833 ; Vector count leading zeros
835 ; vec_cntlz -> clz
836 ; vec_cnttz -> ctz
838 ; Vector xor
840 ; vec_xor -> xor
842 ; Vector Galois field multiply sum
844 ; vgfmb, vgfmh, vgfmf
845 (define_insn "vec_gfmsum<mode>"
846   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
847         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
848                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
849                           UNSPEC_VEC_GFMSUM))]
850   "TARGET_VX"
851   "vgfm<bhfgq>\t%v0,%v1,%v2"
852   [(set_attr "op_type" "VRR")])
854 (define_insn "vec_gfmsum_128"
855   [(set (match_operand:V16QI 0 "register_operand" "=v")
856         (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
857                        (match_operand:V2DI 2 "register_operand" "v")]
858                       UNSPEC_VEC_GFMSUM_128))]
859   "TARGET_VX"
860   "vgfmg\t%v0,%v1,%v2"
861   [(set_attr "op_type" "VRR")])
863 ; vgfmab, vgfmah, vgfmaf
864 (define_insn "vec_gfmsum_accum<mode>"
865   [(set (match_operand:<vec_double> 0 "register_operand" "=v")
866         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
867                               (match_operand:VI_HW_QHS 2 "register_operand" "v")
868                               (match_operand:<vec_double> 3 "register_operand" "v")]
869                              UNSPEC_VEC_GFMSUM_ACCUM))]
870   "TARGET_VX"
871   "vgfma<bhfgq>\t%v0,%v1,%v2,%v3"
872   [(set_attr "op_type" "VRR")])
874 (define_insn "vec_gfmsum_accum_128"
875   [(set (match_operand:V16QI 0 "register_operand" "=v")
876         (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
877                        (match_operand:V2DI 2 "register_operand" "v")
878                        (match_operand:V16QI 3 "register_operand" "v")]
879                       UNSPEC_VEC_GFMSUM_ACCUM_128))]
880   "TARGET_VX"
881   "vgfmag\t%v0,%v1,%v2,%v3"
882   [(set_attr "op_type" "VRR")])
885 ; FIXME: vec_neg ?
887 ; Vector load positive: vec_abs -> abs
888 ; Vector maximum vec_max -> smax, logical vec_max -> umax
889 ; Vector maximum vec_min -> smin, logical vec_min -> umin
892 ; Vector multiply and add high
894 ; vec_mladd -> vec_vmal
895 ; vmalb, vmalh, vmalf, vmalg
896 (define_insn "vec_vmal<mode>"
897   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
898         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
899                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
900                            (match_operand:VI_HW_QHS 3 "register_operand" "v")]
901                           UNSPEC_VEC_VMAL))]
902   "TARGET_VX"
903   "vmal<bhfgq><w>\t%v0,%v1,%v2,%v3"
904   [(set_attr "op_type" "VRR")])
906 ; vec_mhadd -> vec_vmah/vec_vmalh
908 ; vmahb; vmahh, vmahf, vmahg
909 (define_insn "vec_vmah<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_VMAH))]
915   "TARGET_VX"
916   "vmah<bhfgq>\t%v0,%v1,%v2,%v3"
917   [(set_attr "op_type" "VRR")])
919 ; vmalhb; vmalhh, vmalhf, vmalhg
920 (define_insn "vec_vmalh<mode>"
921   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
922         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
923                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
924                            (match_operand:VI_HW_QHS 3 "register_operand" "v")]
925                           UNSPEC_VEC_VMALH))]
926   "TARGET_VX"
927   "vmalh<bhfgq>\t%v0,%v1,%v2,%v3"
928   [(set_attr "op_type" "VRR")])
930 ; vec_meadd -> vec_vmae/vec_vmale
932 ; vmaeb; vmaeh, vmaef, vmaeg
933 (define_insn "vec_vmae<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_VMAE))]
939   "TARGET_VX"
940   "vmae<bhfgq>\t%v0,%v1,%v2,%v3"
941   [(set_attr "op_type" "VRR")])
943 ; vmaleb; vmaleh, vmalef, vmaleg
944 (define_insn "vec_vmale<mode>"
945   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
946         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
947                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
948                               (match_operand:<vec_double> 3 "register_operand" "v")]
949                              UNSPEC_VEC_VMALE))]
950   "TARGET_VX"
951   "vmale<bhfgq>\t%v0,%v1,%v2,%v3"
952   [(set_attr "op_type" "VRR")])
954 ; vec_moadd -> vec_vmao/vec_vmalo
956 ; vmaob; vmaoh, vmaof, vmaog
957 (define_insn "vec_vmao<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_VMAO))]
963   "TARGET_VX"
964   "vmao<bhfgq>\t%v0,%v1,%v2,%v3"
965   [(set_attr "op_type" "VRR")])
967 ; vmalob; vmaloh, vmalof, vmalog
968 (define_insn "vec_vmalo<mode>"
969   [(set (match_operand:<vec_double> 0 "register_operand"                      "=v")
970         (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"    "v")
971                               (match_operand:VI_HW_QHS 2 "register_operand"    "v")
972                               (match_operand:<vec_double> 3 "register_operand" "v")]
973                              UNSPEC_VEC_VMALO))]
974   "TARGET_VX"
975   "vmalo<bhfgq>\t%v0,%v1,%v2,%v3"
976   [(set_attr "op_type" "VRR")])
979 ; Vector multiply high
981 ; vec_mulh -> vec_smulh/vec_umulh
983 ; vmhb, vmhh, vmhf
984 (define_insn "vec_smulh<mode>"
985   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
986         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
987                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
988                           UNSPEC_VEC_SMULT_HI))]
989   "TARGET_VX"
990   "vmh<bhfgq>\t%v0,%v1,%v2"
991   [(set_attr "op_type" "VRR")])
993 ; vmlhb, vmlhh, vmlhf
994 (define_insn "vec_umulh<mode>"
995   [(set (match_operand:VI_HW_QHS 0 "register_operand"                   "=v")
996         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
997                            (match_operand:VI_HW_QHS 2 "register_operand" "v")]
998                           UNSPEC_VEC_UMULT_HI))]
999   "TARGET_VX"
1000   "vmlh<bhfgq>\t%v0,%v1,%v2"
1001   [(set_attr "op_type" "VRR")])
1004 ; Vector multiply low
1006 ; vec_mule -> vec_widen_umult_even/vec_widen_smult_even
1007 ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd
1010 ; Vector nor
1012 (define_insn "vec_nor<mode>3"
1013   [(set (match_operand:VT_HW 0 "register_operand"            "=v")
1014         (not:VT_HW
1015          (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "v")
1016                     (match_operand:VT_HW 2 "register_operand" "v"))))]
1017   "TARGET_VX"
1018   "vno\t%v0,%v1,%v2"
1019   [(set_attr "op_type" "VRR")])
1022 ; Vector or
1024 ; Vector population count vec_popcnt -> popcount
1025 ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot
1027 ; Vector element rotate and insert under mask
1029 ; verimb, verimh, verimf, verimg
1030 (define_insn "verim<mode>"
1031   [(set (match_operand:VI_HW                0 "register_operand" "=v")
1032         (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "0")
1033                        (match_operand:VI_HW 2 "register_operand"  "v")
1034                        (match_operand:VI_HW 3 "register_operand"  "v")
1035                        (match_operand:QI    4 "const_int_operand" "C")]
1036                       UNSPEC_VEC_RL_MASK))]
1037   "TARGET_VX"
1038   "verim<bhfgq>\t%v0,%v2,%v3,%b4"
1039   [(set_attr "op_type" "VRI")])
1042 ; Vector shift left
1044 (define_insn "vec_sll<VI_HW:mode><VI_HW_QHS:mode>"
1045   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1046         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1047                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1048                       UNSPEC_VEC_SLL))]
1049   "TARGET_VX"
1050   "vsl\t%v0,%v1,%v2"
1051   [(set_attr "op_type" "VRR")])
1054 ; Vector shift left by byte
1056 ; Pattern definition in vector.md, see vec_vslb
1057 (define_expand "vec_slb<mode>"
1058   [(set (match_operand:V_HW 0 "register_operand"                     "")
1059         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "")
1060                       (match_operand:<TOINTVEC> 2 "register_operand" "")]
1061                      UNSPEC_VEC_SLB))]
1062   "TARGET_VX"
1064   PUT_MODE (operands[2], V16QImode);
1067 ; Vector shift left double by byte
1069 (define_insn "vec_sld<mode>"
1070   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1071         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1072                       (match_operand:V_HW 2 "register_operand" "v")
1073                       (match_operand:QI 3 "const_int_operand"  "C")]
1074                      UNSPEC_VEC_SLDBYTE))]
1075   "TARGET_VX"
1076   "vsldb\t%v0,%v1,%v2,%b3"
1077   [(set_attr "op_type" "VRI")])
1079 (define_expand "vec_sldw<mode>"
1080   [(set (match_operand:V_HW 0 "register_operand"               "")
1081         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1082                       (match_operand:V_HW 2 "register_operand" "")
1083                       (match_operand:QI 3 "const_int_operand"  "")]
1084                      UNSPEC_VEC_SLDBYTE))]
1085   "TARGET_VX"
1087   operands[3] = GEN_INT (INTVAL (operands[3]) << 2);
1090 ; Vector shift left double by bit
1092 (define_insn "vec_sldb<mode>"
1093   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1094         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1095                       (match_operand:V_HW 2 "register_operand" "v")
1096                       (match_operand:QI 3 "const_int_operand"  "C")]
1097                      UNSPEC_VEC_SLDBIT))]
1098   "TARGET_VXE2"
1099   "vsld\t%v0,%v1,%v2,%b3"
1100   [(set_attr "op_type" "VRI")])
1102 ; Vector shift right double by bit
1104 (define_insn "vec_srdb<mode>"
1105   [(set (match_operand:V_HW 0 "register_operand"              "=v")
1106         (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1107                       (match_operand:V_HW 2 "register_operand" "v")
1108                       (match_operand:QI 3 "const_int_operand"  "C")]
1109                      UNSPEC_VEC_SRDBIT))]
1110   "TARGET_VXE2"
1111   "vsrd\t%v0,%v1,%v2,%b3"
1112   [(set_attr "op_type" "VRI")])
1114 ; Vector shift right arithmetic
1116 (define_insn "vec_sral<VI_HW:mode><VI_HW_QHS:mode>"
1117   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1118         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1119                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1120                       UNSPEC_VEC_SRAL))]
1121   "TARGET_VX"
1122   "vsra\t%v0,%v1,%v2"
1123   [(set_attr "op_type" "VRR")])
1126 ; Vector shift right arithmetic by byte
1128 (define_insn "vec_srab<mode>"
1129   [(set (match_operand:V_HW 0 "register_operand"                    "=v")
1130         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "v")
1131                       (match_operand:<TOINTVEC> 2 "register_operand" "v")]
1132                      UNSPEC_VEC_SRAB))]
1133   "TARGET_VX"
1134   "vsrab\t%v0,%v1,%v2"
1135   [(set_attr "op_type" "VRR")])
1138 ; Vector shift right logical
1140 (define_insn "vec_srl<VI_HW:mode><VI_HW_QHS:mode>"
1141   [(set (match_operand:VI_HW                    0 "register_operand" "=v")
1142         (unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
1143                        (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
1144                       UNSPEC_VEC_SRL))]
1145   "TARGET_VX"
1146   "vsrl\t%v0,%v1,%v2"
1147   [(set_attr "op_type" "VRR")])
1150 ; Vector shift right logical by byte
1152 ; Pattern definition in vector.md, see vec_vsrb
1153 (define_expand "vec_srb<mode>"
1154   [(set (match_operand:V_HW 0 "register_operand"                     "")
1155         (unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "")
1156                       (match_operand:<TOINTVEC> 2 "register_operand" "")]
1157                      UNSPEC_VEC_SRLB))]
1158   "TARGET_VX"
1160   PUT_MODE (operands[2], V16QImode);
1163 ; Vector subtract
1165 ; Vector subtract compute borrow indication
1167 ; vscbib, vscbih, vscbif, vscbig, vscbiq
1168 (define_insn "vscbi<bhfgq>_<mode>"
1169   [(set (match_operand:VIT_HW 0 "register_operand"                "=v")
1170         (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
1171                         (match_operand:VIT_HW 2 "register_operand" "v")]
1172                       UNSPEC_VEC_SUBC))]
1173   "TARGET_VX"
1174   "vscbi<bhfgq>\t%v0,%v1,%v2"
1175   [(set_attr "op_type" "VRR")])
1177 ; Vector subtract with borrow indication
1179 (define_insn "vsbiq"
1180   [(set (match_operand:TI 0 "register_operand"               "=v")
1181         (unspec:TI [(match_operand:TI 1 "register_operand"    "v")
1182                        (match_operand:TI 2 "register_operand" "v")
1183                        (match_operand:TI 3 "register_operand" "v")]
1184                       UNSPEC_VEC_SUBE_U128))]
1185   "TARGET_VX"
1186   "vsbiq\t%v0,%v1,%v2,%v3"
1187   [(set_attr "op_type" "VRR")])
1190 ; Vector subtract with borrow compute and borrow indication
1192 (define_insn "vsbcbiq"
1193   [(set (match_operand:TI 0 "register_operand"               "=v")
1194         (unspec:TI [(match_operand:TI 1 "register_operand"    "v")
1195                        (match_operand:TI 2 "register_operand" "v")
1196                        (match_operand:TI 3 "register_operand" "v")]
1197                       UNSPEC_VEC_SUBEC_U128))]
1198   "TARGET_VX"
1199   "vsbcbiq\t%v0,%v1,%v2,%v3"
1200   [(set_attr "op_type" "VRR")])
1203 ; Vector sum across
1205 ; Sum across DImode parts of the 1st operand and add the rightmost
1206 ; element of 2nd operand
1207 ; vsumgh, vsumgf
1208 (define_expand "vec_sum2<mode>"
1209   [(set (match_operand:V2DI 0 "register_operand" "")
1210         (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "")
1211                       (match_operand:VI_HW_HS 2 "register_operand" "")]
1212                      UNSPEC_VEC_VSUMG))]
1213   "TARGET_VX")
1215 ; vsumqh, vsumqf
1216 (define_insn "vec_sum_u128<mode>"
1217   [(set (match_operand:V2DI 0 "register_operand" "=v")
1218         (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v")
1219                       (match_operand:VI_HW_SD 2 "register_operand" "v")]
1220                      UNSPEC_VEC_VSUMQ))]
1221   "TARGET_VX"
1222   "vsumq<bhfgq>\t%v0,%v1,%v2"
1223   [(set_attr "op_type" "VRR")])
1225 ; vsumb, vsumh
1226 (define_expand "vec_sum4<mode>"
1227   [(set (match_operand:V4SI 0 "register_operand" "")
1228         (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "")
1229                       (match_operand:VI_HW_QH 2 "register_operand" "")]
1230                      UNSPEC_VEC_VSUM))]
1231   "TARGET_VX")
1234 ; Vector test under mask
1236 (define_expand "vec_test_mask_int<mode>"
1237   [(set (reg:CCRAW CC_REGNUM)
1238         (unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
1239                        (match_operand:<TOINTVEC> 2 "register_operand" "")]
1240                       UNSPEC_VEC_TEST_MASK))
1241    (set (match_operand:SI 0 "register_operand" "")
1242         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1243   "TARGET_VX")
1245 (define_insn "*vec_test_mask<mode>"
1246   [(set (reg:CCRAW CC_REGNUM)
1247         (unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
1248                        (match_operand:<TOINTVEC> 1 "register_operand" "v")]
1249                       UNSPEC_VEC_TEST_MASK))]
1250   "TARGET_VX"
1251   "vtm\t%v0,%v1"
1252   [(set_attr "op_type" "VRR")])
1255 ; Vector multiply sum logical
1257 (define_insn "vec_msumv2di"
1258   [(set (match_operand:V16QI 0 "register_operand" "=v")
1259         (unspec:V16QI [(match_operand:V2DI  1 "register_operand"   "v")
1260                        (match_operand:V2DI  2 "register_operand"   "v")
1261                        (match_operand:V16QI 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")])
1268 (define_insn "vmslg"
1269   [(set (match_operand:TI 0 "register_operand" "=v")
1270         (unspec:TI [(match_operand:V2DI  1 "register_operand"   "v")
1271                     (match_operand:V2DI  2 "register_operand"   "v")
1272                     (match_operand:TI    3 "register_operand"   "v")
1273                     (match_operand:QI    4 "const_mask_operand" "C")]
1274                    UNSPEC_VEC_MSUM))]
1275   "TARGET_VXE"
1276   "vmslg\t%v0,%v1,%v2,%v3,%4"
1277   [(set_attr "op_type" "VRR")])
1280 ; Vector find any element equal
1282 ; vfaeb, vfaeh, vfaef
1283 ; vfaezb, vfaezh, vfaezf
1284 (define_insn "vfae<mode>"
1285   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1286         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1287                            (match_operand:VI_HW_QHS 2 "register_operand" "v")
1288                            (match_operand:QI        3 "const_mask_operand" "C")]
1289                           UNSPEC_VEC_VFAE))]
1290   "TARGET_VX"
1292   unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1294   if (flags & VSTRING_FLAG_ZS)
1295     {
1296       flags &= ~VSTRING_FLAG_ZS;
1297       operands[3] = GEN_INT (flags);
1298       return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3";
1299     }
1300   return "vfae<bhfgq>\t%v0,%v1,%v2,%b3";
1302 [(set_attr "op_type" "VRR")])
1304 ; vfaebs, vfaehs, vfaefs
1305 ; vfaezbs, vfaezhs, vfaezfs
1306 (define_insn "*vfaes<mode>"
1307   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1308         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1309                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1310                            (match_operand:QI        3 "const_mask_operand" "C")]
1311                           UNSPEC_VEC_VFAE))
1312    (set (reg:CCRAW CC_REGNUM)
1313         (unspec:CCRAW [(match_dup 1)
1314                        (match_dup 2)
1315                        (match_dup 3)]
1316                       UNSPEC_VEC_VFAECC))]
1317   "TARGET_VX"
1319   unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1321   if (flags & VSTRING_FLAG_ZS)
1322     {
1323       flags &= ~VSTRING_FLAG_ZS;
1324       operands[3] = GEN_INT (flags);
1325       return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3";
1326     }
1327   return "vfae<bhfgq>s\t%v0,%v1,%v2,%b3";
1329   [(set_attr "op_type" "VRR")])
1331 (define_expand "vfaez<mode>"
1332   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1333         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1334                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1335                            (match_operand:QI        3 "const_mask_operand" "")]
1336                           UNSPEC_VEC_VFAE))]
1337   "TARGET_VX"
1339   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS);
1342 (define_expand "vfaes<mode>"
1343   [(parallel
1344     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1345         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1346                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1347                            (match_operand:QI        3 "const_mask_operand" "")]
1348                           UNSPEC_VEC_VFAE))
1349    (set (reg:CCRAW CC_REGNUM)
1350         (unspec:CCRAW [(match_dup 1)
1351                        (match_dup 2)
1352                        (match_dup 3)]
1353                       UNSPEC_VEC_VFAECC))])
1354    (set (match_operand:SI 4 "memory_operand" "")
1355         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1356   "TARGET_VX"
1358   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS);
1361 (define_expand "vfaezs<mode>"
1362   [(parallel
1363     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1364         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "")
1365                            (match_operand:VI_HW_QHS 2 "register_operand"  "")
1366                            (match_operand:SI        3 "const_mask_operand" "")]
1367                           UNSPEC_VEC_VFAE))
1368    (set (reg:CCRAW CC_REGNUM)
1369         (unspec:CCRAW [(match_dup 1)
1370                        (match_dup 2)
1371                        (match_dup 3)]
1372                       UNSPEC_VEC_VFAECC))])
1373    (set (match_operand:SI 4 "memory_operand" "")
1374         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1375   "TARGET_VX"
1377   operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1381 ; Vector find element equal
1383 ; vfeeb, vfeeh, vfeef
1384 (define_insn "vfee<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 0)]
1389                           UNSPEC_VEC_VFEE))]
1390   "TARGET_VX"
1391   "vfee<bhfgq>\t%v0,%v1,%v2,0"
1392   [(set_attr "op_type" "VRR")])
1394 ; vfeezb, vfeezh, vfeezf
1395 (define_insn "vfeez<mode>"
1396   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1397         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1398                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1399                            (const_int VSTRING_FLAG_ZS)]
1400                           UNSPEC_VEC_VFEE))]
1401   "TARGET_VX"
1402   "vfeez<bhfgq>s\t%v0,%v1,%v2,2"
1403   [(set_attr "op_type" "VRR")])
1405 (define_expand "vfees<mode>"
1406   [(parallel
1407     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1408           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1409                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1410                              (const_int VSTRING_FLAG_CS)]
1411                             UNSPEC_VEC_VFEE))
1412    (set (reg:CCRAW CC_REGNUM)
1413         (unspec:CCRAW [(match_dup 1)
1414                        (match_dup 2)
1415                        (const_int VSTRING_FLAG_CS)]
1416                       UNSPEC_VEC_VFEECC))])
1417    (set (match_operand:SI 3 "memory_operand" "")
1418         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1419   "TARGET_VX")
1421 (define_expand "vfeezs<mode>"
1422   [(parallel
1423     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1424           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1425                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1426                              (match_dup 4)]
1427                             UNSPEC_VEC_VFEE))
1428    (set (reg:CCRAW CC_REGNUM)
1429         (unspec:CCRAW [(match_dup 1)
1430                        (match_dup 2)
1431                        (match_dup 4)]
1432                       UNSPEC_VEC_VFEECC))])
1433    (set (match_operand:SI 3 "memory_operand" "")
1434         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1435   "TARGET_VX"
1437   operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1440 ; Vector find element not equal
1442 ; vfeneb, vfeneh, vfenef
1443 (define_insn "vfene<mode>"
1444   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1445         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1446                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1447                            (const_int 0)]
1448                           UNSPEC_VEC_VFENE))]
1449   "TARGET_VX"
1450   "vfene<bhfgq>\t%v0,%v1,%v2,0"
1451   [(set_attr "op_type" "VRR")])
1453 ; vec_vfenes can be found in vector.md since it is used for strlen
1455 ; vfenezb, vfenezh, vfenezf
1456 (define_insn "vfenez<mode>"
1457   [(set (match_operand:VI_HW_QHS                    0 "register_operand" "=v")
1458         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
1459                            (match_operand:VI_HW_QHS 2 "register_operand"  "v")
1460                            (const_int VSTRING_FLAG_ZS)]
1461                           UNSPEC_VEC_VFENE))]
1462   "TARGET_VX"
1463   "vfenez<bhfgq>\t%v0,%v1,%v2"
1464   [(set_attr "op_type" "VRR")])
1466 (define_expand "vfenes<mode>"
1467   [(parallel
1468     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1469           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1470                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1471                              (const_int VSTRING_FLAG_CS)]
1472                             UNSPEC_VEC_VFENE))
1473    (set (reg:CCRAW CC_REGNUM)
1474         (unspec:CCRAW [(match_dup 1)
1475                        (match_dup 2)
1476                        (const_int VSTRING_FLAG_CS)]
1477                       UNSPEC_VEC_VFENECC))])
1478    (set (match_operand:SI 3 "memory_operand" "")
1479         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1480   "TARGET_VX")
1482 (define_expand "vfenezs<mode>"
1483   [(parallel
1484     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1485           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1486                              (match_operand:VI_HW_QHS 2 "register_operand" "")
1487                              (match_dup 4)]
1488                             UNSPEC_VEC_VFENE))
1489      (set (reg:CCRAW CC_REGNUM)
1490           (unspec:CCRAW [(match_dup 1)
1491                          (match_dup 2)
1492                          (match_dup 4)]
1493                         UNSPEC_VEC_VFENECC))])
1494    (set (match_operand:SI 3 "memory_operand" "")
1495         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1496   "TARGET_VX"
1498   operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1501 ; Vector isolate string
1503 ; vistrb, vistrh, vistrf
1504 (define_insn "vistr<mode>"
1505   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1506         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1507                           UNSPEC_VEC_VISTR))]
1508   "TARGET_VX"
1509   "vistr<bhfgq>\t%v0,%v1"
1510   [(set_attr "op_type" "VRR")])
1512 ; vistrbs, vistrhs, vistrfs
1513 (define_insn "*vistrs<mode>"
1514   [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1515         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1516                           UNSPEC_VEC_VISTR))
1517    (set (reg:CCRAW CC_REGNUM)
1518         (unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))]
1519   "TARGET_VX"
1520   "vistr<bhfgq>s\t%v0,%v1"
1521   [(set_attr "op_type" "VRR")])
1523 (define_expand "vistrs<mode>"
1524   [(parallel
1525     [(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
1526           (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")]
1527                             UNSPEC_VEC_VISTR))
1528      (set (reg:CCRAW CC_REGNUM)
1529           (unspec:CCRAW [(match_dup 1)]
1530                         UNSPEC_VEC_VISTRCC))])
1531    (set (match_operand:SI 2 "memory_operand" "")
1532         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1533   "TARGET_VX")
1536 ; Vector compare range
1538 ; vstrcb, vstrch, vstrcf
1539 ; vstrczb, vstrczh, vstrczf
1540 (define_insn "vstrc<mode>"
1541   [(set (match_operand:VI_HW_QHS                    0 "register_operand"  "=v")
1542         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1543                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1544                            (match_operand:VI_HW_QHS 3 "register_operand"   "v")
1545                            (match_operand:QI        4 "const_mask_operand" "C")]
1546                           UNSPEC_VEC_VSTRC))]
1547   "TARGET_VX"
1549   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1551   if (flags & VSTRING_FLAG_ZS)
1552     {
1553       flags &= ~VSTRING_FLAG_ZS;
1554       operands[4] = GEN_INT (flags);
1555       return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1556     }
1557   return "vstrc<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1559 [(set_attr "op_type" "VRR")])
1561 ; vstrcbs, vstrchs, vstrcfs
1562 ; vstrczbs, vstrczhs, vstrczfs
1563 (define_insn "*vstrcs<mode>"
1564   [(set (match_operand:VI_HW_QHS                    0 "register_operand"  "=v")
1565         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "v")
1566                            (match_operand:VI_HW_QHS 2 "register_operand"   "v")
1567                            (match_operand:VI_HW_QHS 3 "register_operand"   "v")
1568                            (match_operand:QI        4 "const_mask_operand" "C")]
1569                           UNSPEC_VEC_VSTRC))
1570    (set (reg:CCRAW CC_REGNUM)
1571         (unspec:CCRAW [(match_dup 1)
1572                        (match_dup 2)
1573                        (match_dup 3)
1574                        (match_dup 4)]
1575                       UNSPEC_VEC_VSTRCCC))]
1576   "TARGET_VX"
1578   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1580   if (flags & VSTRING_FLAG_ZS)
1581     {
1582       flags &= ~VSTRING_FLAG_ZS;
1583       operands[4] = GEN_INT (flags);
1584       return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1585     }
1586   return "vstrc<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1588   [(set_attr "op_type" "VRR")])
1590 (define_expand "vstrcz<mode>"
1591   [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1592         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"   "")
1593                            (match_operand:VI_HW_QHS 2 "register_operand"   "")
1594                            (match_operand:VI_HW_QHS 3 "register_operand"   "")
1595                            (match_operand:QI        4 "const_mask_operand" "")]
1596                           UNSPEC_VEC_VSTRC))]
1597   "TARGET_VX"
1599   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS);
1602 (define_expand "vstrcs<mode>"
1603   [(parallel
1604     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1605         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1606                            (match_operand:VI_HW_QHS 2 "register_operand" "")
1607                            (match_operand:VI_HW_QHS 3 "register_operand" "")
1608                            (match_operand:QI        4 "const_mask_operand" "")]
1609                           UNSPEC_VEC_VSTRC))
1610    (set (reg:CCRAW CC_REGNUM)
1611         (unspec:CCRAW [(match_dup 1)
1612                        (match_dup 2)
1613                        (match_dup 3)
1614                        (match_dup 4)]
1615                       UNSPEC_VEC_VSTRCCC))])
1616    (set (match_operand:SI 5 "memory_operand" "")
1617         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1618   "TARGET_VX"
1620   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS);
1623 (define_expand "vstrczs<mode>"
1624   [(parallel
1625     [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1626         (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1627                            (match_operand:VI_HW_QHS 2 "register_operand" "")
1628                            (match_operand:VI_HW_QHS 3 "register_operand" "")
1629                            (match_operand:QI        4 "const_mask_operand" "")]
1630                           UNSPEC_VEC_VSTRC))
1631    (set (reg:CCRAW CC_REGNUM)
1632         (unspec:CCRAW [(match_dup 1)
1633                        (match_dup 2)
1634                        (match_dup 3)
1635                        (match_dup 4)]
1636                       UNSPEC_VEC_VSTRCCC))])
1637    (set (match_operand:SI 5 "memory_operand" "")
1638         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1639   "TARGET_VX"
1641   operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1644 ; Vector string search
1646 (define_expand "vstrs<mode>"
1647   [(parallel
1648     [(set (match_operand:V16QI                    0 "register_operand" "")
1649           (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1650                          (match_operand:VI_HW_QHS 2 "register_operand" "")
1651                          (match_operand:V16QI     3 "register_operand" "")
1652                          (const_int 0)]
1653                         UNSPEC_VEC_VSTRS))
1654      (set (reg:CCRAW CC_REGNUM)
1655           (unspec:CCRAW [(match_dup 1)
1656                          (match_dup 2)
1657                          (match_dup 3)
1658                          (const_int 0)]
1659                         UNSPEC_VEC_VSTRSCC))])
1660    (set (match_operand:SI 4 "memory_operand" "")
1661         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1662   "TARGET_VXE2")
1664 (define_expand "vstrsz<mode>"
1665   [(parallel
1666     [(set (match_operand:V16QI                    0 "register_operand" "")
1667           (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1668                          (match_operand:VI_HW_QHS 2 "register_operand" "")
1669                          (match_operand:V16QI     3 "register_operand" "")
1670                          (const_int VSTRING_FLAG_ZS)]
1671                         UNSPEC_VEC_VSTRS))
1672      (set (reg:CCRAW CC_REGNUM)
1673           (unspec:CCRAW [(match_dup 1)
1674                          (match_dup 2)
1675                          (match_dup 3)
1676                          (const_int VSTRING_FLAG_ZS)]
1677                         UNSPEC_VEC_VSTRSCC))])
1678    (set (match_operand:SI 4 "memory_operand" "")
1679         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1680   "TARGET_VXE2")
1682 ; vstrsb, vstrsh, vstrsf
1683 ; vstrszb, vstrszh, vstrszf
1684 (define_insn "vec_vstrs<mode>"
1685   [(set (match_operand:V16QI                    0 "register_operand" "=v")
1686         (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1687                        (match_operand:VI_HW_QHS 2 "register_operand" "v")
1688                        (match_operand:V16QI     3 "register_operand" "v")
1689                        (match_operand:QI        4 "const_mask_operand" "C")]
1690                       UNSPEC_VEC_VSTRS))
1691    (set (reg:CCRAW CC_REGNUM)
1692         (unspec:CCRAW [(match_dup 1)
1693                        (match_dup 2)
1694                        (match_dup 3)
1695                        (match_dup 4)]
1696                       UNSPEC_VEC_VSTRSCC))]
1697   "TARGET_VXE2"
1699   unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1701   gcc_assert (!(flags & ~VSTRING_FLAG_ZS));
1703   if (flags == VSTRING_FLAG_ZS)
1704     return "vstrsz<bhfgq>\t%v0,%v1,%v2,%v3";
1705   return "vstrs<bhfgq>\t%v0,%v1,%v2,%v3";
1707   [(set_attr "op_type" "VRR")])
1710 ; Vector convert int<->float
1712 (define_insn "vcdgb"
1713   [(set (match_operand:V2DF 0 "register_operand"                "=v")
1714         (unspec:V2DF [(match_operand:V2DI 1 "register_operand"   "v")
1715                       (match_operand:QI   2 "const_mask_operand" "C")  ; inexact suppression
1716                       (match_operand:QI   3 "const_mask_operand" "C")] ; rounding mode
1717                      UNSPEC_VEC_VCDGB))]
1718   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1719   "vcdgb\t%v0,%v1,%b2,%b3"
1720   [(set_attr "op_type" "VRR")])
1723 ; The result needs to be multiplied with 2**-op2
1724 (define_expand "vec_ctd_s64"
1725   [(set (match_operand:V2DF               0 "register_operand" "")
1726         (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1727                       (const_int VEC_NOINEXACT)
1728                       (const_int VEC_RND_CURRENT)]
1729                      UNSPEC_VEC_VCDGB))
1730    (use (match_operand:QI 2 "const_int_operand" ""))
1731    (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1732   "TARGET_VX"
1734   REAL_VALUE_TYPE f;
1735   rtx c;
1737   real_2expN (&f, -INTVAL (operands[2]), DFmode);
1738   c = const_double_from_real_value (f, DFmode);
1740   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1741   operands[3] = force_reg (V2DFmode, operands[3]);
1744 (define_insn "vcdlgb"
1745   [(set (match_operand:V2DF 0 "register_operand"                 "=v")
1746         (unspec:V2DF [(match_operand:V2DI 1 "register_operand"    "v")
1747                       (match_operand:QI   2 "const_mask_operand"  "C")  ; inexact suppression
1748                       (match_operand:QI   3 "const_mask_operand"  "C")] ; rounding mode
1749                      UNSPEC_VEC_VCDLGB))]
1750   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1751   "vcdlgb\t%v0,%v1,%b2,%b3"
1752   [(set_attr "op_type" "VRR")])
1754 ; The result needs to be multiplied with 2**-op2
1755 (define_expand "vec_ctd_u64"
1756   [(set (match_operand:V2DF               0 "register_operand" "")
1757         (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1758                       (const_int VEC_NOINEXACT)
1759                       (const_int VEC_RND_CURRENT)]
1760                      UNSPEC_VEC_VCDLGB))
1761    (use (match_operand:QI 2 "const_int_operand" ""))
1762    (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1763   "TARGET_VX"
1765   REAL_VALUE_TYPE f;
1766   rtx c;
1768   real_2expN (&f, -INTVAL (operands[2]), DFmode);
1769   c = const_double_from_real_value (f, DFmode);
1771   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1772   operands[3] = force_reg (V2DFmode, operands[3]);
1775 (define_insn "vcgdb"
1776   [(set (match_operand:V2DI 0 "register_operand"                "=v")
1777         (unspec:V2DI [(match_operand:V2DF 1 "register_operand"   "v")
1778                       (match_operand:QI   2 "const_mask_operand" "C")
1779                       (match_operand:QI   3 "const_mask_operand" "C")]
1780                      UNSPEC_VEC_VCGDB))]
1781   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1782   "vcgdb\t%v0,%v1,%b2,%b3"
1783   [(set_attr "op_type" "VRR")])
1785 ; The input needs to be multiplied with 2**op2
1786 (define_expand "vec_ctsl"
1787   [(use (match_operand:QI 2 "const_int_operand" ""))
1788    (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1789                                  (match_dup 3)))
1790    (set (match_operand:V2DI 0 "register_operand" "")
1791         (unspec:V2DI [(match_dup 4)
1792                       (const_int VEC_NOINEXACT)
1793                       (const_int VEC_RND_CURRENT)]
1794                      UNSPEC_VEC_VCGDB))]
1795   "TARGET_VX"
1797   REAL_VALUE_TYPE f;
1798   rtx c;
1800   real_2expN (&f, INTVAL (operands[2]), DFmode);
1801   c = const_double_from_real_value (f, DFmode);
1803   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1804   operands[3] = force_reg (V2DFmode, operands[3]);
1805   operands[4] = gen_reg_rtx (V2DFmode);
1808 (define_insn "vclgdb"
1809   [(set (match_operand:V2DI 0 "register_operand"               "=v")
1810         (unspec:V2DI [(match_operand:V2DF 1 "register_operand"  "v")
1811                       (match_operand:QI   2 "const_mask_operand" "C")
1812                       (match_operand:QI   3 "const_mask_operand" "C")]
1813                      UNSPEC_VEC_VCLGDB))]
1814   "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1815   "vclgdb\t%v0,%v1,%b2,%b3"
1816   [(set_attr "op_type" "VRR")])
1818 ; The input needs to be multiplied with 2**op2
1819 (define_expand "vec_ctul"
1820   [(use (match_operand:QI 2 "const_int_operand" ""))
1821    (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1822                                  (match_dup 3)))
1823    (set (match_operand:V2DI 0 "register_operand" "")
1824         (unspec:V2DI [(match_dup 4)
1825                       (const_int VEC_NOINEXACT)
1826                       (const_int VEC_RND_CURRENT)]
1827                      UNSPEC_VEC_VCLGDB))]
1828   "TARGET_VX"
1830   REAL_VALUE_TYPE f;
1831   rtx c;
1833   real_2expN (&f, INTVAL (operands[2]), DFmode);
1834   c = const_double_from_real_value (f, DFmode);
1836   operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1837   operands[3] = force_reg (V2DFmode, operands[3]);
1838   operands[4] = gen_reg_rtx (V2DFmode);
1841 ; Vector load fp integer - IEEE inexact exception is suppressed
1842 ; vfisb, vfidb, wfisb, wfidb, wfixb
1843 (define_insn "vec_fpint<mode>"
1844   [(set (match_operand:VFT              0 "register_operand"  "=v")
1845         (unspec:VFT [(match_operand:VFT 1 "register_operand"   "v")
1846                      (match_operand:QI  2 "const_mask_operand" "C")  ; inexact suppression control
1847                      (match_operand:QI  3 "const_mask_operand" "C")] ; rounding mode
1848                      UNSPEC_VEC_VFI))]
1849   "TARGET_VX"
1850   "<vw>fi<sdx>b\t%v0,%v1,%b2,%b3"
1851   [(set_attr "op_type" "VRR")])
1854 ; Vector load lengthened - V4SF -> V2DF
1856 (define_insn "vflls"
1857   [(set (match_operand:V2DF 0 "register_operand"               "=v")
1858         (unspec:V2DF [(match_operand:V4SF 1 "register_operand"  "v")]
1859                      UNSPEC_VEC_VFLL))]
1860   "TARGET_VX"
1861   "vldeb\t%v0,%v1"
1862   [(set_attr "op_type" "VRR")])
1864 (define_expand "vec_ld2f"
1865   [; Initialize a vector to all zeroes.  FIXME: This should not be
1866    ; necessary since all elements of the vector will be set anyway.
1867    ; This is just to make it explicit to the data flow framework.
1868    (set (match_dup 2) (match_dup 3))
1869    (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "")
1870                                     (const_int 0)
1871                                     (match_dup 2)]
1872                                     UNSPEC_VEC_SET))
1873    (set (match_dup 2) (unspec:V4SF [(match_dup 4)
1874                                     (const_int 2)
1875                                     (match_dup 2)]
1876                                     UNSPEC_VEC_SET))
1877    (set (match_operand:V2DF 0 "register_operand" "")
1878         (unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VFLL))]
1879   "TARGET_VX"
1881   operands[2] = gen_reg_rtx (V4SFmode);
1882   operands[3] = CONST0_RTX (V4SFmode);
1883   operands[4] = adjust_address (operands[1], SFmode, 4);
1887 ; Vector load rounded - V2DF -> V4SF
1889 (define_insn "vflrd"
1890   [(set (match_operand:V4SF 0 "register_operand"                "=v")
1891         (unspec:V4SF [(match_operand:V2DF 1 "register_operand"   "v")
1892                       (match_operand:QI   2 "const_mask_operand" "C")
1893                       (match_operand:QI   3 "const_mask_operand" "C")]
1894                      UNSPEC_VEC_VFLR))]
1895   "TARGET_VX"
1896   "vledb\t%v0,%v1,%b2,%b3"
1897   [(set_attr "op_type" "VRR")])
1899 (define_expand "vec_st2f"
1900   [(set (match_dup 2)
1901         (unspec:V4SF [(match_operand:V2DF 0 "register_operand" "")
1902                       (const_int VEC_INEXACT)
1903                       (const_int VEC_RND_CURRENT)]
1904                      UNSPEC_VEC_VFLR))
1905    (set (match_operand:SF 1 "memory_operand" "")
1906         (vec_select:SF (match_dup 2)
1907          (parallel [(const_int 0)])))
1908    (set (match_dup 3)
1909         (vec_select:SF (match_dup 2)
1910          (parallel [(const_int 2)])))]
1911   "TARGET_VX"
1913   operands[2] = gen_reg_rtx (V4SFmode);
1914   operands[3] = adjust_address (operands[1], SFmode, 4);
1918 ; Vector square root fp vec_sqrt -> sqrt rtx standard name
1920 ;; Vector FP test data class immediate
1922 ; vec_all_nan, vec_all_numeric, vec_any_nan, vec_any_numeric
1923 ; These ignore the vector result and only want CC stored to an int
1924 ; pointer.
1926 ; vftcisb, vftcidb, wftcixb
1927 (define_insn "*vftci<mode>_cconly"
1928   [(set (reg:CCRAW CC_REGNUM)
1929         (unspec:CCRAW [(match_operand:VF_HW 1 "register_operand"  "v")
1930                        (match_operand:HI    2 "const_int_operand" "J")]
1931                       UNSPEC_VEC_VFTCICC))
1932    (clobber (match_scratch:<TOINTVEC> 0 "=v"))]
1933   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1934   "<vw>ftci<sdx>b\t%v0,%v1,%x2"
1935   [(set_attr "op_type" "VRR")])
1937 (define_expand "vftci<mode>_intcconly"
1938   [(parallel
1939     [(set (reg:CCRAW CC_REGNUM)
1940           (unspec:CCRAW [(match_operand:VF_HW 0 "register_operand")
1941                          (match_operand:HI    1 "const_int_operand")]
1942                         UNSPEC_VEC_VFTCICC))
1943      (clobber (scratch:<TOINTVEC>))])
1944    (set (match_operand:SI 2 "register_operand" "")
1945         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1946   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")")
1948 ; vec_fp_test_data_class wants the result vector and the CC stored to
1949 ; an int pointer.
1951 ; vftcisb, vftcidb, wftcixb
1952 (define_insn "vftci<mode>"
1953   [(set (match_operand:VF_HW                0 "register_operand"  "=v")
1954         (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand"   "v")
1955                        (match_operand:HI    2 "const_int_operand"  "J")]
1956                       UNSPEC_VEC_VFTCI))
1957    (set (reg:CCRAW CC_REGNUM)
1958         (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))]
1959   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1960   "<vw>ftci<sdx>b\t%v0,%v1,%x2"
1961   [(set_attr "op_type" "VRR")])
1963 (define_expand "vftci<mode>_intcc"
1964   [(parallel
1965     [(set (match_operand:VF_HW                0 "register_operand")
1966           (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand")
1967                          (match_operand:HI    2 "const_int_operand")]
1968                         UNSPEC_VEC_VFTCI))
1969      (set (reg:CCRAW CC_REGNUM)
1970           (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))])
1971    (set (match_operand:SI                     3 "nonimmediate_operand")
1972         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1973   "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")")
1976 ;; Integer compares
1979 ; All comparisons which produce a CC need fully populated (VI_HW)
1980 ; vector arguments.  Otherwise the any/all CCs would be just bogus.
1982 (define_insn "*vec_cmp<VICMP:insn_cmp><VI_HW:mode>_cconly"
1983   [(set (reg:VICMP CC_REGNUM)
1984         (compare:VICMP (match_operand:VI_HW 0 "register_operand" "v")
1985                        (match_operand:VI_HW 1 "register_operand" "v")))
1986    (clobber (match_scratch:VI_HW 2 "=v"))]
1987   "TARGET_VX"
1988   "vc<VICMP:insn_cmp><VI_HW:bhfgq>s\t%v2,%v0,%v1"
1989   [(set_attr "op_type" "VRR")])
1991 ; FIXME: The following 2x3 definitions should be merged into 2 with
1992 ; VICMP like above but I could not find a way to set the comparison
1993 ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the
1994 ; other way around - setting the mode depending on the code
1995 ; (code_iterator).
1996 (define_expand "vec_cmpeq<VI_HW:mode>_cc"
1997   [(parallel
1998     [(set (reg:CCVEQ CC_REGNUM)
1999         (compare:CCVEQ (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           (eq:VI_HW (match_dup 1) (match_dup 2)))])
2003    (set (match_operand:SI 3 "memory_operand" "")
2004         (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2005   "TARGET_VX")
2007 (define_expand "vec_cmph<VI_HW:mode>_cc"
2008   [(parallel
2009     [(set (reg:CCVIH CC_REGNUM)
2010           (compare:CCVIH (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           (gt:VI_HW (match_dup 1) (match_dup 2)))])
2014    (set (match_operand:SI 3 "memory_operand" "")
2015         (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2016   "TARGET_VX")
2018 (define_expand "vec_cmphl<VI_HW:mode>_cc"
2019   [(parallel
2020     [(set (reg:CCVIHU CC_REGNUM)
2021           (compare:CCVIHU (match_operand:VI_HW 1 "register_operand" "v")
2022                           (match_operand:VI_HW 2 "register_operand" "v")))
2023      (set (match_operand:VI_HW 0 "register_operand" "=v")
2024           (gtu:VI_HW (match_dup 1) (match_dup 2)))])
2025    (set (match_operand:SI 3 "memory_operand" "")
2026         (unspec:SI [(reg:CCVIHU CC_REGNUM)] UNSPEC_CC_TO_INT))]
2027   "TARGET_VX")
2030 (define_insn "*vec_cmpeq<VI_HW:mode>_cc"
2031   [(set (reg:CCVEQ CC_REGNUM)
2032         (compare:CCVEQ (match_operand:VI_HW 0 "register_operand"  "v")
2033                        (match_operand:VI_HW 1 "register_operand"  "v")))
2034    (set (match_operand:VI_HW                2 "register_operand" "=v")
2035         (eq:VI_HW (match_dup 0) (match_dup 1)))]
2036   "TARGET_VX"
2037   "vceq<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2038   [(set_attr "op_type" "VRR")])
2040 (define_insn "*vec_cmph<VI_HW:mode>_cc"
2041   [(set (reg:CCVIH CC_REGNUM)
2042         (compare:CCVIH (match_operand:VI_HW 0 "register_operand"  "v")
2043                        (match_operand:VI_HW 1 "register_operand"  "v")))
2044    (set (match_operand:VI_HW               2 "register_operand" "=v")
2045         (gt:VI_HW (match_dup 0) (match_dup 1)))]
2046   "TARGET_VX"
2047   "vch<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2048   [(set_attr "op_type" "VRR")])
2050 (define_insn "*vec_cmphl<VI_HW:mode>_cc"
2051   [(set (reg:CCVIHU CC_REGNUM)
2052         (compare:CCVIHU (match_operand:VI_HW 0 "register_operand"  "v")
2053                         (match_operand:VI_HW 1 "register_operand"  "v")))
2054    (set (match_operand:VI_HW                2 "register_operand" "=v")
2055         (gtu:VI_HW (match_dup 0) (match_dup 1)))]
2056   "TARGET_VX"
2057   "vchl<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2058   [(set_attr "op_type" "VRR")])
2061 ;; Floating point compares
2064 ; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs
2065 (define_insn "*vec_cmp<insn_cmp><VF_HW:mode>_cconly"
2066   [(set (reg:VFCMP CC_REGNUM)
2067         (compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
2068                        (match_operand:VF_HW 1 "register_operand" "v")))
2069    (clobber (match_scratch:<TOINTVEC> 2 "=v"))]
2070   "TARGET_VX"
2071   "<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1"
2072   [(set_attr "op_type" "VRR")])
2074 ; FIXME: Merge the following 2x3 patterns with VFCMP
2075 (define_expand "vec_cmpeq<mode>_cc"
2076   [(parallel
2077     [(set (reg:CCVEQ CC_REGNUM)
2078           (compare:CCVEQ (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           (eq:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2082    (set (match_operand:SI 3 "memory_operand" "")
2083         (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2084   "TARGET_VX")
2086 (define_expand "vec_cmph<mode>_cc"
2087   [(parallel
2088     [(set (reg:CCVFH CC_REGNUM)
2089           (compare:CCVFH (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           (gt:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2093    (set (match_operand:SI 3 "memory_operand" "")
2094         (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2095   "TARGET_VX")
2097 (define_expand "vec_cmphe<mode>_cc"
2098   [(parallel
2099     [(set (reg:CCVFHE CC_REGNUM)
2100           (compare:CCVFHE (match_operand:VF_HW 1 "register_operand"  "v")
2101                           (match_operand:VF_HW 2 "register_operand"  "v")))
2102      (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2103           (ge:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2104    (set (match_operand:SI 3 "memory_operand" "")
2105         (unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]
2106   "TARGET_VX")
2108 ; These 3 cannot be merged as the insn defintion above since it also
2109 ; requires to rewrite the RTL equality operator that the same time as
2110 ; the CC mode.
2112 ; vfcesbs, vfcedbs, wfcexbs
2113 (define_insn "*vec_cmpeq<mode>_cc"
2114   [(set (reg:CCVEQ CC_REGNUM)
2115         (compare:CCVEQ (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         (eq:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2119   "TARGET_VX"
2120   "<vw>fce<sdx>bs\t%v2,%v0,%v1"
2121   [(set_attr "op_type" "VRR")])
2123 ; vfchsbs, vfchdbs, wfchxbs
2124 (define_insn "*vec_cmph<mode>_cc"
2125   [(set (reg:CCVFH CC_REGNUM)
2126         (compare:CCVFH (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         (gt:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2130   "TARGET_VX"
2131   "<vw>fch<sdx>bs\t%v2,%v0,%v1"
2132   [(set_attr "op_type" "VRR")])
2134 ; vfchesbs, vfchedbs, wfchexbs
2135 (define_insn "*vec_cmphe<mode>_cc"
2136   [(set (reg:CCVFHE CC_REGNUM)
2137         (compare:CCVFHE (match_operand:VF_HW 0 "register_operand"  "v")
2138                         (match_operand:VF_HW 1 "register_operand"  "v")))
2139    (set (match_operand:<TOINTVEC>            2 "register_operand" "=v")
2140         (ge:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2141   "TARGET_VX"
2142   "<vw>fche<sdx>bs\t%v2,%v0,%v1"
2143   [(set_attr "op_type" "VRR")])
2146 (define_insn "vfmin<mode>"
2147   [(set (match_operand:VF_HW                0 "register_operand"  "=v")
2148         (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand"   "v")
2149                        (match_operand:VF_HW 2 "register_operand"   "v")
2150                        (match_operand:QI    3 "const_mask_operand" "C")]
2151                       UNSPEC_VEC_VFMIN))]
2152   "TARGET_VXE"
2153   "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3"
2154   [(set_attr "op_type" "VRR")])
2156 (define_insn "vfmax<mode>"
2157   [(set (match_operand:VF_HW                0 "register_operand"  "=v")
2158         (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand"   "v")
2159                        (match_operand:VF_HW 2 "register_operand"   "v")
2160                        (match_operand:QI    3 "const_mask_operand" "C")]
2161                       UNSPEC_VEC_VFMAX))]
2162   "TARGET_VXE"
2163   "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3"
2164   [(set_attr "op_type" "VRR")])
2166 ; vec_insert (__builtin_bswap32 (*a), b, 1)        set-element-bswap-2.c
2167 ; b[1] = __builtin_bswap32 (*a)                    set-element-bswap-3.c
2168 ; vlebrh, vlebrf, vlebrg
2169 (define_insn "*vec_set_bswap_elem<mode>"
2170   [(set (match_operand:V_HW_HSD                                     0 "register_operand" "=v")
2171         (unspec:V_HW_HSD [(bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand"    "R"))
2172                                            (match_operand:SI        2 "const_int_operand" "C")
2173                                            (match_operand:V_HW_HSD  3 "register_operand"  "0")]
2174                   UNSPEC_VEC_SET))]
2175   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2176   "vlebr<bhfgq>\t%v0,%1,%2"
2177   [(set_attr "op_type" "VRX")])
2179 ; vec_revb (vec_insert (*a, vec_revb (b), 1))      set-element-bswap-1.c
2180 ; vlebrh, vlebrf, vlebrg
2181 (define_insn "*vec_set_bswap_vec<mode>"
2182   [(set (match_operand:V_HW_HSD                                     0 "register_operand"       "=v")
2183         (bswap:V_HW_HSD
2184          (unspec:V_HW_HSD [(match_operand:<non_vec>                 1 "memory_operand"          "R")
2185                            (match_operand:SI                        2 "const_int_operand"       "C")
2186                            (bswap:V_HW_HSD (match_operand:V_HW_HSD  3 "register_operand"        "0"))]
2187                           UNSPEC_VEC_SET)))
2188    (use (match_operand:V16QI                                        4 "permute_pattern_operand" "X"))]
2189   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2190   "vlebr<bhfgq>\t%v0,%1,%2"
2191   [(set_attr "op_type" "VRX")])
2193 ; *a = vec_extract (vec_revb (b), 1);              get-element-bswap-3.c
2194 ; *a = vec_revb (b)[1];                            get-element-bswap-4.c
2195 ; vstebrh, vstebrf, vstebrg
2196 (define_insn "*vec_extract_bswap_vec<mode>"
2197   [(set (match_operand:<non_vec>                  0 "memory_operand"   "=R")
2198         (vec_select:<non_vec>
2199          (bswap:V_HW_HSD (match_operand:V_HW_HSD  1 "register_operand"  "v"))
2200          (parallel [(match_operand:SI             2 "const_int_operand" "C")])))]
2201   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2202   "vstebr<bhfgq>\t%v1,%0,%2"
2203   [(set_attr "op_type" "VRX")])
2205 ; *a = __builtin_bswap32 (vec_extract (b, 1));     get-element-bswap-1.c
2206 ; *a = __builtin_bswap32 (b[1]);                   get-element-bswap-2.c
2207 ; vstebrh, vstebrf, vstebrg
2208 (define_insn "*vec_extract_bswap_elem<mode>"
2209   [(set (match_operand:<non_vec>                  0 "memory_operand"   "=R")
2210         (bswap:<non_vec>
2211          (vec_select:<non_vec>
2212           (match_operand:V_HW_HSD                 1 "register_operand"  "v")
2213           (parallel [(match_operand:SI            2 "const_int_operand" "C")]))))]
2214   "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2215   "vstebr<bhfgq>\t%v1,%0,%2"
2216   [(set_attr "op_type" "VRX")])
2220 ;; NNPA Facility
2223 (define_insn "vclfnhs_v8hi"
2224   [(set (match_operand:V4SF                0 "register_operand"  "=v")
2225         (unspec:V4SF [(vec_select:V4HI
2226                        (match_operand:V8HI 1 "register_operand"   "v")
2227                        (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))
2228                       (match_operand:QI    2 "const_mask_operand" "C")]
2229                      UNSPEC_NNPA_VCLFNHS_V8HI))]
2230   "TARGET_NNPA"
2231   "vclfnh\t%v0,%v1,2,%2"
2232   [(set_attr "op_type" "VRR")])
2234 (define_insn "vclfnls_v8hi"
2235   [(set (match_operand:V4SF                0 "register_operand"   "=v")
2236         (unspec:V4SF [(vec_select:V4HI
2237                        (match_operand:V8HI 1 "register_operand"   "v")
2238                        (parallel [(const_int 4) (const_int 5) (const_int 6) (const_int 7)]))
2239                       (match_operand:QI    2 "const_mask_operand"  "C")]
2240                      UNSPEC_NNPA_VCLFNLS_V8HI))]
2241   "TARGET_NNPA"
2242   "vclfnl\t%v0,%v1,2,%2"
2243   [(set_attr "op_type" "VRR")])
2245 (define_insn "vcrnfs_v8hi"
2246   [(set (match_operand:V8HI               0 "register_operand"   "=v")
2247         (unspec:V8HI [(match_operand:V4SF 1 "register_operand"    "v")
2248                       (match_operand:V4SF 2 "register_operand"    "v")
2249                       (match_operand:QI   3 "const_mask_operand"  "C")]
2250                      UNSPEC_NNPA_VCRNFS_V8HI))]
2251   "TARGET_NNPA"
2252   "vcrnf\t%v0,%v1,%v2,%3,2"
2253   [(set_attr "op_type" "VRR")])
2255 (define_insn "vcfn_v8hi"
2256   [(set (match_operand:V8HI               0 "register_operand"   "=v")
2257         (unspec:V8HI [(match_operand:V8HI 1 "register_operand"    "v")
2258                       (match_operand:QI   2 "const_mask_operand"  "C")]
2259                      UNSPEC_NNPA_VCFN_V8HI))]
2260   "TARGET_NNPA"
2261   "vcfn\t%v0,%v1,1,%2"
2262   [(set_attr "op_type" "VRR")])
2264 (define_insn "vcnf_v8hi"
2265   [(set (match_operand:V8HI               0 "register_operand"   "=v")
2266         (unspec:V8HI [(match_operand:V8HI 1 "register_operand"    "v")
2267                       (match_operand:QI   2 "const_mask_operand"  "C")]
2268                      UNSPEC_NNPA_VCNF_V8HI))]
2269   "TARGET_NNPA"
2270   "vcnf\t%v0,%v1,%2,1"
2271   [(set_attr "op_type" "VRR")])