1 ;;- Instruction patterns for the System z vector facility builtins.
2 ;; Copyright (C) 2015-2020 Free Software Foundation, Inc.
3 ;; Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it under
8 ;; the terms of the GNU General Public License as published by the Free
9 ;; Software Foundation; either version 3, or (at your option) any later
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
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ; The patterns in this file are enabled with -mzvector
23 (define_mode_iterator V_HW_32_64 [V4SI V2DI V2DF (V4SF "TARGET_VXE")])
24 (define_mode_iterator VI_HW_SD [V4SI V2DI])
25 (define_mode_iterator V_HW_4 [V4SI V4SF])
26 ; Full size vector modes with more than one element which are directly supported in vector registers by the hardware.
27 (define_mode_iterator VEC_HW [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE")])
28 (define_mode_iterator VECF_HW [(V4SF "TARGET_VXE") V2DF])
30 ; The element type of the vector with floating point modes translated
31 ; to int modes of the same size.
32 (define_mode_attr non_vec_int[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
33 (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
34 (V1SI "SI") (V2SI "SI") (V4SI "SI")
35 (V1DI "DI") (V2DI "DI")
36 (V1SF "SI") (V2SF "SI") (V4SF "SI")
37 (V1DF "DI") (V2DF "DI")])
39 ; Condition code modes generated by int comparisons
40 (define_mode_iterator VICMP [CCVEQ CCVIH CCVIHU])
42 ; Comparisons supported by the vec_cmp* builtins
43 (define_code_iterator intcmp [eq gt gtu ge geu lt ltu le leu])
44 (define_code_iterator fpcmp [eq gt ge lt le])
46 ; Comparisons supported by the vec_all/any* builtins
47 (define_code_iterator intcmpcc [eq ne gt ge lt le gtu geu ltu leu])
48 (define_code_iterator fpcmpcc [eq ne gt ge unle unlt lt le])
50 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4)
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
60 (VEC_RND_NEAREST_AWAY_FROM_ZERO 1)
61 (VEC_RND_SHORT_PREC 3)
62 (VEC_RND_NEAREST_TO_EVEN 4)
67 ; Inexact suppression facility flag as being used for e.g. VFI
73 ; Vector gather element
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")]
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")]
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]);
98 unsigned HOST_WIDE_INT mask;
99 bool swapped_p = false;
103 i = start - 1; start = end + 1; end = i;
107 mask = HOST_WIDE_INT_M1U;
109 mask = (HOST_WIDE_INT_1U << (end + 1)) - 1;
111 mask &= ~((HOST_WIDE_INT_1U << start) - 1);
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,
124 (define_expand "vec_genbytemaskv16qi"
125 [(match_operand:V16QI 0 "register_operand" "")
126 (match_operand:HI 1 "const_int_operand" "")]
130 unsigned mask = 0x8000;
132 unsigned HOST_WIDE_INT byte_mask = UINTVAL (operands[1]);
134 for (i = 0; i < 16; i++)
136 if (mask & byte_mask)
137 const_vec[i] = constm1_rtx;
139 const_vec[i] = const0_rtx;
142 emit_insn (gen_rtx_SET (operands[0],
143 gen_rtx_CONST_VECTOR (V16QImode,
144 gen_rtvec_v (16, const_vec))));
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" "")))]
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" "")]
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" "")
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))]
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"))]
192 "vllebrz<bhfgq>\t%v0,%1"
193 [(set_attr "op_type" "VRX")])
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"
203 [(set_attr "op_type" "VRX")])
205 (define_insn "vlrlrv16qi"
206 [(set (match_operand:V16QI 0 "register_operand" "=v,v")
207 (unspec:V16QI [(match_operand:BLK 2 "memory_operand" "Q,Q")
208 (match_operand:SI 1 "nonmemory_operand" "d,C")]
209 UNSPEC_VEC_LOAD_LEN_R))]
214 [(set_attr "op_type" "VRS,VSI")])
217 ; FIXME: The following two patterns might using vec_merge. But what is
218 ; the canonical form: (vec_select (vec_merge op0 op1)) or (vec_merge
219 ; (vec_select op0) (vec_select op1)
220 ; vmrhb, vmrhh, vmrhf, vmrhg
221 (define_insn "vec_mergeh<mode>"
222 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v")
223 (unspec:V_128_NOSINGLE [(match_operand:V_128_NOSINGLE 1 "register_operand" "v")
224 (match_operand:V_128_NOSINGLE 2 "register_operand" "v")]
227 "vmrh<bhfgq>\t%v0,%1,%2"
228 [(set_attr "op_type" "VRR")])
230 ; vmrlb, vmrlh, vmrlf, vmrlg
231 (define_insn "vec_mergel<mode>"
232 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v")
233 (unspec:V_128_NOSINGLE [(match_operand:V_128_NOSINGLE 1 "register_operand" "v")
234 (match_operand:V_128_NOSINGLE 2 "register_operand" "v")]
237 "vmrl<bhfgq>\t%v0,%1,%2"
238 [(set_attr "op_type" "VRR")])
244 (define_insn "vec_pack<mode>"
245 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
246 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
247 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
250 "vpk<bhfgq>\t%v0,%v1,%v2"
251 [(set_attr "op_type" "VRR")])
254 ; Vector pack saturate
256 ; vpksh, vpksf, vpksg
257 (define_insn "vec_packs<mode>"
258 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
259 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
260 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
261 UNSPEC_VEC_PACK_SATURATE))]
263 "vpks<bhfgq>\t%v0,%v1,%v2"
264 [(set_attr "op_type" "VRR")])
267 ; This is vec_packs_cc + loading cc into a caller specified memory location.
268 (define_expand "vec_packs_cc<mode>"
270 [(set (reg:CCRAW CC_REGNUM)
271 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
272 (match_operand:VI_HW_HSD 2 "register_operand" "")]
273 UNSPEC_VEC_PACK_SATURATE_GENCC))
274 (set (match_operand:<vec_half> 0 "register_operand" "")
275 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
276 UNSPEC_VEC_PACK_SATURATE_CC))])
278 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
279 (set (match_operand:SI 3 "memory_operand" "")
283 operands[4] = gen_reg_rtx (SImode);
286 ; vpksh, vpksf, vpksg
287 (define_insn "*vec_packs_cc<mode>"
288 [(set (reg:CCRAW CC_REGNUM)
289 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
290 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
291 UNSPEC_VEC_PACK_SATURATE_GENCC))
292 (set (match_operand:<vec_half> 0 "register_operand" "=v")
293 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
294 UNSPEC_VEC_PACK_SATURATE_CC))]
296 "vpks<bhfgq>s\t%v0,%v1,%v2"
297 [(set_attr "op_type" "VRR")])
300 ; Vector pack logical saturate
302 ; vpklsh, vpklsf, vpklsg
303 (define_insn "vec_packsu<mode>"
304 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
305 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
306 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
307 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
309 "vpkls<bhfgq>\t%v0,%v1,%v2"
310 [(set_attr "op_type" "VRR")])
312 ; Emulate saturate unsigned pack on signed operands.
313 ; Zero out negative elements and continue with the unsigned saturating pack.
314 (define_expand "vec_packsu_u<mode>"
315 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
316 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
317 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
318 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
321 rtx null_vec = CONST0_RTX(<MODE>mode);
322 machine_mode half_mode;
325 case E_V8HImode: half_mode = V16QImode; break;
326 case E_V4SImode: half_mode = V8HImode; break;
327 case E_V2DImode: half_mode = V4SImode; break;
328 default: gcc_unreachable ();
330 s390_expand_vcond (operands[1], operands[1], null_vec,
331 GE, operands[1], null_vec);
332 s390_expand_vcond (operands[2], operands[2], null_vec,
333 GE, operands[2], null_vec);
334 emit_insn (gen_rtx_SET (operands[0],
335 gen_rtx_UNSPEC (half_mode,
336 gen_rtvec (2, operands[1], operands[2]),
337 UNSPEC_VEC_PACK_UNSIGNED_SATURATE)));
341 ; This is vec_packsu_cc + loading cc into a caller specified memory location.
342 ; FIXME: The reg to target mem copy should be issued by reload?!
343 (define_expand "vec_packsu_cc<mode>"
345 [(set (reg:CCRAW CC_REGNUM)
346 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
347 (match_operand:VI_HW_HSD 2 "register_operand" "")]
348 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
349 (set (match_operand:<vec_half> 0 "register_operand" "")
350 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
351 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))])
353 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
354 (set (match_operand:SI 3 "memory_operand" "")
358 operands[4] = gen_reg_rtx (SImode);
361 ; vpklsh, vpklsf, vpklsg
362 (define_insn "*vec_packsu_cc<mode>"
363 [(set (reg:CCRAW CC_REGNUM)
364 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
365 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
366 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
367 (set (match_operand:<vec_half> 0 "register_operand" "=v")
368 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
369 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))]
371 "vpkls<bhfgq>s\t%v0,%v1,%v2"
372 [(set_attr "op_type" "VRR")])
377 ; vec_perm is also RTL standard name, but we can only use it for V16QI
379 (define_insn "vec_zperm<mode>"
380 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
381 (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "register_operand" "v")
382 (match_operand:V_HW_HSD 2 "register_operand" "v")
383 (match_operand:V16QI 3 "register_operand" "v")]
386 "vperm\t%v0,%v1,%v2,%v3"
387 [(set_attr "op_type" "VRR")])
389 (define_expand "vec_permi<mode>"
390 [(set (match_operand:V_HW_64 0 "register_operand" "")
391 (unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand" "")
392 (match_operand:V_HW_64 2 "register_operand" "")
393 (match_operand:QI 3 "const_mask_operand" "")]
397 HOST_WIDE_INT val = INTVAL (operands[3]);
398 operands[3] = GEN_INT ((val & 1) | (val & 2) << 1);
401 (define_insn "*vec_permi<mode>"
402 [(set (match_operand:V_HW_64 0 "register_operand" "=v")
403 (unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand" "v")
404 (match_operand:V_HW_64 2 "register_operand" "v")
405 (match_operand:QI 3 "const_mask_operand" "C")]
407 "TARGET_VX && (UINTVAL (operands[3]) & 10) == 0"
408 "vpdi\t%v0,%v1,%v2,%b3"
409 [(set_attr "op_type" "VRR")])
415 ; Replicate from vector element
416 (define_expand "vec_splat<mode>"
417 [(set (match_operand:V_HW 0 "register_operand" "")
418 (vec_duplicate:V_HW (vec_select:<non_vec>
419 (match_operand:V_HW 1 "register_operand" "")
421 [(match_operand:QI 2 "const_mask_operand" "")]))))]
424 ; Vector scatter element
428 ; A 64 bit target address generated from 32 bit elements
429 (define_insn "vec_scatter_element<V_HW_4:mode>_DI"
431 (plus:DI (zero_extend:DI
432 (unspec:SI [(match_operand:V4SI 1 "register_operand" "v")
433 (match_operand:QI 3 "const_mask_operand" "C")]
435 (match_operand:SI 2 "address_operand" "ZQ")))
436 (unspec:<non_vec> [(match_operand:V_HW_4 0 "register_operand" "v")
437 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
438 "TARGET_VX && TARGET_64BIT && UINTVAL (operands[3]) < 4"
439 "vscef\t%v0,%O2(%v1,%R2),%3"
440 [(set_attr "op_type" "VRV")])
442 ; A 31 bit target address is generated from 64 bit elements
444 (define_insn "vec_scatter_element<V_HW_64:mode>_SI"
447 (unspec:<non_vec_int> [(match_operand:V_HW_64 1 "register_operand" "v")
448 (match_operand:QI 3 "const_mask_operand" "C")]
449 UNSPEC_VEC_EXTRACT) 4)
450 (match_operand:SI 2 "address_operand" "ZQ")))
451 (unspec:<non_vec> [(match_operand:V_HW_64 0 "register_operand" "v")
452 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
453 "TARGET_VX && !TARGET_64BIT && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_64:MODE>mode)"
454 "vsce<V_HW_64:bhfgq>\t%v0,%O2(%v1,%R2),%3"
455 [(set_attr "op_type" "VRV")])
457 ; Element size and target address size is the same
459 (define_insn "vec_scatter_element<mode>_<non_vec_int>"
461 (plus:<non_vec_int> (unspec:<non_vec_int>
462 [(match_operand:<tointvec> 1 "register_operand" "v")
463 (match_operand:QI 3 "const_mask_operand" "C")]
465 (match_operand:DI 2 "address_operand" "ZQ")))
466 (unspec:<non_vec> [(match_operand:V_HW_32_64 0 "register_operand" "v")
467 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
468 "TARGET_VX && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
469 "vsce<bhfgq>\t%v0,%O2(%v1,%R2),%3"
470 [(set_attr "op_type" "VRV")])
472 ; Depending on the address size we have to expand a different pattern.
473 ; This however cannot be represented in s390-builtins.def so we do the
474 ; multiplexing here in the expander.
475 (define_expand "vec_scatter_element<V_HW_32_64:mode>"
476 [(match_operand:V_HW_32_64 0 "register_operand" "")
477 (match_operand:<tointvec> 1 "register_operand" "")
478 (match_operand 2 "address_operand" "")
479 (match_operand:QI 3 "const_mask_operand" "")]
484 PUT_MODE (operands[2], DImode);
486 gen_vec_scatter_element<V_HW_32_64:mode>_DI (operands[0], operands[1],
487 operands[2], operands[3]));
491 PUT_MODE (operands[2], SImode);
493 gen_vec_scatter_element<V_HW_32_64:mode>_SI (operands[0], operands[1],
494 operands[2], operands[3]));
502 ; Operand 3 selects bits from either OP1 (0) or OP2 (1)
504 ; Comparison operator should not matter as long as we always use the same ?!
506 ; Operands 1 and 2 are swapped in order to match the altivec builtin.
507 ; If operand 3 is a const_int bitmask this would be vec_merge
508 (define_expand "vec_sel<mode>"
509 [(set (match_operand:V_HW 0 "register_operand" "")
511 (eq (match_operand:<tointvec> 3 "register_operand" "")
513 (match_operand:V_HW 2 "register_operand" "")
514 (match_operand:V_HW 1 "register_operand" "")))]
517 operands[4] = CONST0_RTX (<tointvec>mode);
521 ; Vector sign extend to doubleword
523 ; Sign extend of right most vector element to respective double-word
524 ; vsegb, vsegh, vsegf
525 (define_insn "vec_extend<mode>"
526 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
527 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
530 "vseg<bhfgq>\t%v0,%1"
531 [(set_attr "op_type" "VRR")])
534 ; Vector store with length
536 ; Store bytes in OP1 from OP0 with the highest indexed byte to be
537 ; stored from OP0 given by OP2
538 (define_insn "vstl<mode>"
539 [(set (match_operand:BLK 2 "memory_operand" "=Q")
540 (unspec:BLK [(match_operand:V 0 "register_operand" "v")
541 (match_operand:SI 1 "register_operand" "d")]
542 UNSPEC_VEC_STORE_LEN))]
545 [(set_attr "op_type" "VRS")])
547 ; Vector store rightmost with length
549 (define_insn "vstrlrv16qi"
550 [(set (match_operand:BLK 2 "memory_operand" "=Q,Q")
551 (unspec:BLK [(match_operand:V16QI 0 "register_operand" "v,v")
552 (match_operand:SI 1 "nonmemory_operand" "d,C")]
553 UNSPEC_VEC_STORE_LEN_R))]
558 [(set_attr "op_type" "VRS,VSI")])
564 (define_insn "vbpermv16qi"
565 [(set (match_operand:V2DI 0 "register_operand" "=v")
566 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v")
567 (match_operand:V16QI 2 "register_operand" "v")]
570 "vbperm\t%v0,%v1,%v2"
571 [(set_attr "op_type" "VRR")])
575 ; vuphb, vuphh, vuphf
576 (define_insn "vec_unpackh<mode>"
577 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
578 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
579 UNSPEC_VEC_UNPACKH))]
581 "vuph<bhfgq>\t%v0,%v1"
582 [(set_attr "op_type" "VRR")])
584 ; vuplhb, vuplhh, vuplhf
585 (define_insn "vec_unpackh_l<mode>"
586 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
587 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
588 UNSPEC_VEC_UNPACKH_L))]
590 "vuplh<bhfgq>\t%v0,%v1"
591 [(set_attr "op_type" "VRR")])
596 ; vuplb, vuplhw, vuplf
597 (define_insn "vec_unpackl<mode>"
598 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
599 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
600 UNSPEC_VEC_UNPACKL))]
602 "vupl<bhfgq><w>\t%v0,%v1"
603 [(set_attr "op_type" "VRR")])
605 ; vupllb, vupllh, vupllf
606 (define_insn "vec_unpackl_l<mode>"
607 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
608 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
609 UNSPEC_VEC_UNPACKL_L))]
611 "vupll<bhfgq>\t%v0,%v1"
612 [(set_attr "op_type" "VRR")])
617 ; Vector add compute carry
619 ; vaccb, vacch, vaccf, vaccg, vaccq
620 (define_insn "vacc<bhfgq>_<mode>"
621 [(set (match_operand:VIT_HW 0 "register_operand" "=v")
622 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "%v")
623 (match_operand:VIT_HW 2 "register_operand" "v")]
626 "vacc<bhfgq>\t%v0,%v1,%v2"
627 [(set_attr "op_type" "VRR")])
629 ; Vector add with carry
632 [(set (match_operand:TI 0 "register_operand" "=v")
633 (unspec:TI [(match_operand:TI 1 "register_operand" "%v")
634 (match_operand:TI 2 "register_operand" "v")
635 (match_operand:TI 3 "register_operand" "v")]
636 UNSPEC_VEC_ADDE_U128))]
638 "vacq\t%v0,%v1,%v2,%v3"
639 [(set_attr "op_type" "VRR")])
642 ; Vector add with carry compute carry
644 (define_insn "vacccq"
645 [(set (match_operand:TI 0 "register_operand" "=v")
646 (unspec:TI [(match_operand:TI 1 "register_operand" "%v")
647 (match_operand:TI 2 "register_operand" "v")
648 (match_operand:TI 3 "register_operand" "v")]
649 UNSPEC_VEC_ADDEC_U128))]
651 "vacccq\t%v0,%v1,%v2,%v3"
652 [(set_attr "op_type" "VRR")])
657 ; Vector and with complement
660 (define_insn "vec_andc<mode>3"
661 [(set (match_operand:VT_HW 0 "register_operand" "=v")
662 (and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand" "v"))
663 (match_operand:VT_HW 1 "register_operand" "v")))]
666 [(set_attr "op_type" "VRR")])
671 ; vavgb, vavgh, vavgf, vavgg
672 (define_insn "vec_avg<mode>"
673 [(set (match_operand:VI_HW 0 "register_operand" "=v")
674 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "%v")
675 (match_operand:VI_HW 2 "register_operand" "v")]
678 "vavg<bhfgq>\t%v0,%v1,%v2"
679 [(set_attr "op_type" "VRR")])
681 ; Vector average logical
683 ; vavglb, vavglh, vavglf, vavglg
684 (define_insn "vec_avgu<mode>"
685 [(set (match_operand:VI_HW 0 "register_operand" "=v")
686 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "%v")
687 (match_operand:VI_HW 2 "register_operand" "v")]
690 "vavgl<bhfgq>\t%v0,%v1,%v2"
691 [(set_attr "op_type" "VRR")])
696 (define_insn "vec_checksum"
697 [(set (match_operand:V4SI 0 "register_operand" "=v")
698 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
699 (match_operand:V4SI 2 "register_operand" "v")]
700 UNSPEC_VEC_CHECKSUM))]
703 [(set_attr "op_type" "VRR")])
709 ; vec_all/any int compares
711 (define_expand "vec_all_<intcmpcc:code><VI_HW:mode>"
712 [(match_operand:SI 0 "register_operand" "")
713 (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
714 (match_operand:VI_HW 2 "register_operand" ""))]
717 s390_expand_vec_compare_cc (operands[0],
725 (define_expand "vec_any_<intcmpcc:code><VI_HW:mode>"
726 [(match_operand:SI 0 "register_operand" "")
727 (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
728 (match_operand:VI_HW 2 "register_operand" ""))]
731 s390_expand_vec_compare_cc (operands[0],
739 ; vec_all/any fp compares
741 (define_expand "vec_all_<fpcmpcc:code><mode>"
742 [(match_operand:SI 0 "register_operand" "")
743 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
744 (match_operand:VECF_HW 2 "register_operand" ""))]
747 s390_expand_vec_compare_cc (operands[0],
755 (define_expand "vec_any_<fpcmpcc:code><mode>"
756 [(match_operand:SI 0 "register_operand" "")
757 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
758 (match_operand:VECF_HW 2 "register_operand" ""))]
761 s390_expand_vec_compare_cc (operands[0],
770 ; Compare without generating CC
772 (define_expand "vec_cmp<intcmp:code><VI_HW:mode>"
773 [(set (match_operand:VI_HW 0 "register_operand" "=v")
774 (intcmp:VI_HW (match_operand:VI_HW 1 "register_operand" "v")
775 (match_operand:VI_HW 2 "register_operand" "v")))]
778 s390_expand_vec_compare (operands[0], <intcmp:CODE>, operands[1], operands[2]);
782 (define_expand "vec_cmp<fpcmp:code><mode>"
783 [(set (match_operand:<tointvec> 0 "register_operand" "=v")
784 (fpcmp:<tointvec> (match_operand:VF_HW 1 "register_operand" "v")
785 (match_operand:VF_HW 2 "register_operand" "v")))]
788 s390_expand_vec_compare (operands[0], <fpcmp:CODE>, operands[1], operands[2]);
793 ; Vector count leading zeros
802 ; Vector Galois field multiply sum
804 ; vgfmb, vgfmh, vgfmf
805 (define_insn "vec_gfmsum<mode>"
806 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
807 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
808 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
811 "vgfm<bhfgq>\t%v0,%v1,%v2"
812 [(set_attr "op_type" "VRR")])
814 (define_insn "vec_gfmsum_128"
815 [(set (match_operand:V16QI 0 "register_operand" "=v")
816 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
817 (match_operand:V2DI 2 "register_operand" "v")]
818 UNSPEC_VEC_GFMSUM_128))]
821 [(set_attr "op_type" "VRR")])
823 ; vgfmab, vgfmah, vgfmaf
824 (define_insn "vec_gfmsum_accum<mode>"
825 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
826 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
827 (match_operand:VI_HW_QHS 2 "register_operand" "v")
828 (match_operand:<vec_double> 3 "register_operand" "v")]
829 UNSPEC_VEC_GFMSUM_ACCUM))]
831 "vgfma<bhfgq>\t%v0,%v1,%v2,%v3"
832 [(set_attr "op_type" "VRR")])
834 (define_insn "vec_gfmsum_accum_128"
835 [(set (match_operand:V16QI 0 "register_operand" "=v")
836 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
837 (match_operand:V2DI 2 "register_operand" "v")
838 (match_operand:V16QI 3 "register_operand" "v")]
839 UNSPEC_VEC_GFMSUM_ACCUM_128))]
841 "vgfmag\t%v0,%v1,%v2,%v3"
842 [(set_attr "op_type" "VRR")])
847 ; Vector load positive: vec_abs -> abs
848 ; Vector maximum vec_max -> smax, logical vec_max -> umax
849 ; Vector maximum vec_min -> smin, logical vec_min -> umin
852 ; Vector multiply and add high
854 ; vec_mladd -> vec_vmal
855 ; vmalb, vmalh, vmalf, vmalg
856 (define_insn "vec_vmal<mode>"
857 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
858 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
859 (match_operand:VI_HW_QHS 2 "register_operand" "v")
860 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
863 "vmal<bhfgq><w>\t%v0,%v1,%v2,%v3"
864 [(set_attr "op_type" "VRR")])
866 ; vec_mhadd -> vec_vmah/vec_vmalh
868 ; vmahb; vmahh, vmahf, vmahg
869 (define_insn "vec_vmah<mode>"
870 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
871 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
872 (match_operand:VI_HW_QHS 2 "register_operand" "v")
873 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
876 "vmah<bhfgq>\t%v0,%v1,%v2,%v3"
877 [(set_attr "op_type" "VRR")])
879 ; vmalhb; vmalhh, vmalhf, vmalhg
880 (define_insn "vec_vmalh<mode>"
881 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
882 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
883 (match_operand:VI_HW_QHS 2 "register_operand" "v")
884 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
887 "vmalh<bhfgq>\t%v0,%v1,%v2,%v3"
888 [(set_attr "op_type" "VRR")])
890 ; vec_meadd -> vec_vmae/vec_vmale
892 ; vmaeb; vmaeh, vmaef, vmaeg
893 (define_insn "vec_vmae<mode>"
894 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
895 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
896 (match_operand:VI_HW_QHS 2 "register_operand" "v")
897 (match_operand:<vec_double> 3 "register_operand" "v")]
900 "vmae<bhfgq>\t%v0,%v1,%v2,%v3"
901 [(set_attr "op_type" "VRR")])
903 ; vmaleb; vmaleh, vmalef, vmaleg
904 (define_insn "vec_vmale<mode>"
905 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
906 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
907 (match_operand:VI_HW_QHS 2 "register_operand" "v")
908 (match_operand:<vec_double> 3 "register_operand" "v")]
911 "vmale<bhfgq>\t%v0,%v1,%v2,%v3"
912 [(set_attr "op_type" "VRR")])
914 ; vec_moadd -> vec_vmao/vec_vmalo
916 ; vmaob; vmaoh, vmaof, vmaog
917 (define_insn "vec_vmao<mode>"
918 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
919 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
920 (match_operand:VI_HW_QHS 2 "register_operand" "v")
921 (match_operand:<vec_double> 3 "register_operand" "v")]
924 "vmao<bhfgq>\t%v0,%v1,%v2,%v3"
925 [(set_attr "op_type" "VRR")])
927 ; vmalob; vmaloh, vmalof, vmalog
928 (define_insn "vec_vmalo<mode>"
929 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
930 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
931 (match_operand:VI_HW_QHS 2 "register_operand" "v")
932 (match_operand:<vec_double> 3 "register_operand" "v")]
935 "vmalo<bhfgq>\t%v0,%v1,%v2,%v3"
936 [(set_attr "op_type" "VRR")])
939 ; Vector multiply high
941 ; vec_mulh -> vec_smulh/vec_umulh
944 (define_insn "vec_smulh<mode>"
945 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
946 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
947 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
948 UNSPEC_VEC_SMULT_HI))]
950 "vmh<bhfgq>\t%v0,%v1,%v2"
951 [(set_attr "op_type" "VRR")])
953 ; vmlhb, vmlhh, vmlhf
954 (define_insn "vec_umulh<mode>"
955 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
956 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
957 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
958 UNSPEC_VEC_UMULT_HI))]
960 "vmlh<bhfgq>\t%v0,%v1,%v2"
961 [(set_attr "op_type" "VRR")])
964 ; Vector multiply low
966 ; vec_mule -> vec_widen_umult_even/vec_widen_smult_even
967 ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd
972 (define_insn "vec_nor<mode>3"
973 [(set (match_operand:VT_HW 0 "register_operand" "=v")
975 (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "%v")
976 (match_operand:VT_HW 2 "register_operand" "v"))))]
979 [(set_attr "op_type" "VRR")])
984 ; Vector population count vec_popcnt -> popcount
985 ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot
987 ; Vector element rotate and insert under mask
989 ; verimb, verimh, verimf, verimg
990 (define_insn "verim<mode>"
991 [(set (match_operand:VI_HW 0 "register_operand" "=v")
992 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "0")
993 (match_operand:VI_HW 2 "register_operand" "v")
994 (match_operand:VI_HW 3 "register_operand" "v")
995 (match_operand:QI 4 "const_int_operand" "C")]
996 UNSPEC_VEC_RL_MASK))]
998 "verim<bhfgq>\t%v0,%v2,%v3,%b4"
999 [(set_attr "op_type" "VRI")])
1004 (define_insn "vec_sll<VI_HW:mode><VI_HW_QHS:mode>"
1005 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1006 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1007 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1011 [(set_attr "op_type" "VRR")])
1014 ; Vector shift left by byte
1016 ; Pattern definition in vector.md, see vec_vslb
1017 (define_expand "vec_slb<mode>"
1018 [(set (match_operand:V_HW 0 "register_operand" "")
1019 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1020 (match_operand:<tointvec> 2 "register_operand" "")]
1024 PUT_MODE (operands[2], V16QImode);
1027 ; Vector shift left double by byte
1029 (define_insn "vec_sld<mode>"
1030 [(set (match_operand:V_HW 0 "register_operand" "=v")
1031 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1032 (match_operand:V_HW 2 "register_operand" "v")
1033 (match_operand:QI 3 "const_int_operand" "C")]
1034 UNSPEC_VEC_SLDBYTE))]
1036 "vsldb\t%v0,%v1,%v2,%b3"
1037 [(set_attr "op_type" "VRI")])
1039 (define_expand "vec_sldw<mode>"
1040 [(set (match_operand:V_HW 0 "register_operand" "")
1041 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1042 (match_operand:V_HW 2 "register_operand" "")
1043 (match_operand:QI 3 "const_int_operand" "")]
1044 UNSPEC_VEC_SLDBYTE))]
1047 operands[3] = GEN_INT (INTVAL (operands[3]) << 2);
1050 ; Vector shift left double by bit
1052 (define_insn "vec_sldb<mode>"
1053 [(set (match_operand:V_HW 0 "register_operand" "=v")
1054 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1055 (match_operand:V_HW 2 "register_operand" "v")
1056 (match_operand:QI 3 "const_int_operand" "C")]
1057 UNSPEC_VEC_SLDBIT))]
1059 "vsld\t%v0,%v1,%v2,%b3"
1060 [(set_attr "op_type" "VRI")])
1062 ; Vector shift right double by bit
1064 (define_insn "vec_srdb<mode>"
1065 [(set (match_operand:V_HW 0 "register_operand" "=v")
1066 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1067 (match_operand:V_HW 2 "register_operand" "v")
1068 (match_operand:QI 3 "const_int_operand" "C")]
1069 UNSPEC_VEC_SRDBIT))]
1071 "vsrd\t%v0,%v1,%v2,%b3"
1072 [(set_attr "op_type" "VRI")])
1074 ; Vector shift right arithmetic
1076 (define_insn "vec_sral<VI_HW:mode><VI_HW_QHS:mode>"
1077 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1078 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1079 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1083 [(set_attr "op_type" "VRR")])
1086 ; Vector shift right arithmetic by byte
1088 (define_insn "vec_srab<mode>"
1089 [(set (match_operand:V_HW 0 "register_operand" "=v")
1090 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1091 (match_operand:<tointvec> 2 "register_operand" "v")]
1094 "vsrab\t%v0,%v1,%v2"
1095 [(set_attr "op_type" "VRR")])
1098 ; Vector shift right logical
1100 (define_insn "vec_srl<VI_HW:mode><VI_HW_QHS:mode>"
1101 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1102 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1103 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1107 [(set_attr "op_type" "VRR")])
1110 ; Vector shift right logical by byte
1112 ; Pattern definition in vector.md, see vec_vsrb
1113 (define_expand "vec_srb<mode>"
1114 [(set (match_operand:V_HW 0 "register_operand" "")
1115 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1116 (match_operand:<tointvec> 2 "register_operand" "")]
1120 PUT_MODE (operands[2], V16QImode);
1125 ; Vector subtract compute borrow indication
1127 ; vscbib, vscbih, vscbif, vscbig, vscbiq
1128 (define_insn "vscbi<bhfgq>_<mode>"
1129 [(set (match_operand:VIT_HW 0 "register_operand" "=v")
1130 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
1131 (match_operand:VIT_HW 2 "register_operand" "v")]
1134 "vscbi<bhfgq>\t%v0,%v1,%v2"
1135 [(set_attr "op_type" "VRR")])
1137 ; Vector subtract with borrow indication
1139 (define_insn "vsbiq"
1140 [(set (match_operand:TI 0 "register_operand" "=v")
1141 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
1142 (match_operand:TI 2 "register_operand" "v")
1143 (match_operand:TI 3 "register_operand" "v")]
1144 UNSPEC_VEC_SUBE_U128))]
1146 "vsbiq\t%v0,%v1,%v2,%v3"
1147 [(set_attr "op_type" "VRR")])
1150 ; Vector subtract with borrow compute and borrow indication
1152 (define_insn "vsbcbiq"
1153 [(set (match_operand:TI 0 "register_operand" "=v")
1154 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
1155 (match_operand:TI 2 "register_operand" "v")
1156 (match_operand:TI 3 "register_operand" "v")]
1157 UNSPEC_VEC_SUBEC_U128))]
1159 "vsbcbiq\t%v0,%v1,%v2,%v3"
1160 [(set_attr "op_type" "VRR")])
1165 ; Sum across DImode parts of the 1st operand and add the rightmost
1166 ; element of 2nd operand
1168 (define_expand "vec_sum2<mode>"
1169 [(set (match_operand:V2DI 0 "register_operand" "")
1170 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "")
1171 (match_operand:VI_HW_HS 2 "register_operand" "")]
1176 (define_insn "vec_sum_u128<mode>"
1177 [(set (match_operand:V2DI 0 "register_operand" "=v")
1178 (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v")
1179 (match_operand:VI_HW_SD 2 "register_operand" "v")]
1182 "vsumq<bhfgq>\t%v0,%v1,%v2"
1183 [(set_attr "op_type" "VRR")])
1186 (define_expand "vec_sum4<mode>"
1187 [(set (match_operand:V4SI 0 "register_operand" "")
1188 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "")
1189 (match_operand:VI_HW_QH 2 "register_operand" "")]
1194 ; Vector test under mask
1196 (define_expand "vec_test_mask_int<mode>"
1197 [(set (reg:CCRAW CC_REGNUM)
1198 (unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
1199 (match_operand:<tointvec> 2 "register_operand" "")]
1200 UNSPEC_VEC_TEST_MASK))
1201 (set (match_operand:SI 0 "register_operand" "")
1202 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1205 (define_insn "*vec_test_mask<mode>"
1206 [(set (reg:CCRAW CC_REGNUM)
1207 (unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
1208 (match_operand:<tointvec> 1 "register_operand" "v")]
1209 UNSPEC_VEC_TEST_MASK))]
1212 [(set_attr "op_type" "VRR")])
1215 ; Vector multiply sum logical
1217 (define_insn "vec_msumv2di"
1218 [(set (match_operand:V16QI 0 "register_operand" "=v")
1219 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
1220 (match_operand:V2DI 2 "register_operand" "v")
1221 (match_operand:V16QI 3 "register_operand" "v")
1222 (match_operand:QI 4 "const_mask_operand" "C")]
1225 "vmslg\t%v0,%v1,%v2,%v3,%4"
1226 [(set_attr "op_type" "VRR")])
1228 (define_insn "vmslg"
1229 [(set (match_operand:TI 0 "register_operand" "=v")
1230 (unspec:TI [(match_operand:V2DI 1 "register_operand" "v")
1231 (match_operand:V2DI 2 "register_operand" "v")
1232 (match_operand:TI 3 "register_operand" "v")
1233 (match_operand:QI 4 "const_mask_operand" "C")]
1236 "vmslg\t%v0,%v1,%v2,%v3,%4"
1237 [(set_attr "op_type" "VRR")])
1240 ; Vector find any element equal
1242 ; vfaeb, vfaeh, vfaef
1243 ; vfaezb, vfaezh, vfaezf
1244 (define_insn "vfae<mode>"
1245 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1246 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1247 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1248 (match_operand:QI 3 "const_mask_operand" "C")]
1252 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1254 if (flags & VSTRING_FLAG_ZS)
1256 flags &= ~VSTRING_FLAG_ZS;
1257 operands[3] = GEN_INT (flags);
1258 return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3";
1260 return "vfae<bhfgq>\t%v0,%v1,%v2,%b3";
1262 [(set_attr "op_type" "VRR")])
1264 ; vfaebs, vfaehs, vfaefs
1265 ; vfaezbs, vfaezhs, vfaezfs
1266 (define_insn "*vfaes<mode>"
1267 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1268 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1269 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1270 (match_operand:QI 3 "const_mask_operand" "C")]
1272 (set (reg:CCRAW CC_REGNUM)
1273 (unspec:CCRAW [(match_dup 1)
1276 UNSPEC_VEC_VFAECC))]
1279 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1281 if (flags & VSTRING_FLAG_ZS)
1283 flags &= ~VSTRING_FLAG_ZS;
1284 operands[3] = GEN_INT (flags);
1285 return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3";
1287 return "vfae<bhfgq>s\t%v0,%v1,%v2,%b3";
1289 [(set_attr "op_type" "VRR")])
1291 (define_expand "vfaez<mode>"
1292 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1293 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1294 (match_operand:VI_HW_QHS 2 "register_operand" "")
1295 (match_operand:QI 3 "const_mask_operand" "")]
1299 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS);
1302 (define_expand "vfaes<mode>"
1304 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1305 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1306 (match_operand:VI_HW_QHS 2 "register_operand" "")
1307 (match_operand:QI 3 "const_mask_operand" "")]
1309 (set (reg:CCRAW CC_REGNUM)
1310 (unspec:CCRAW [(match_dup 1)
1313 UNSPEC_VEC_VFAECC))])
1314 (set (match_operand:SI 4 "memory_operand" "")
1315 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1318 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS);
1321 (define_expand "vfaezs<mode>"
1323 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1324 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1325 (match_operand:VI_HW_QHS 2 "register_operand" "")
1326 (match_operand:SI 3 "const_mask_operand" "")]
1328 (set (reg:CCRAW CC_REGNUM)
1329 (unspec:CCRAW [(match_dup 1)
1332 UNSPEC_VEC_VFAECC))])
1333 (set (match_operand:SI 4 "memory_operand" "")
1334 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1337 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1341 ; Vector find element equal
1343 ; vfeebs, vfeehs, vfeefs
1344 ; vfeezbs, vfeezhs, vfeezfs
1345 (define_insn "*vfees<mode>"
1346 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1347 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1348 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1349 (match_operand:QI 3 "const_mask_operand" "C")]
1351 (set (reg:CCRAW CC_REGNUM)
1352 (unspec:CCRAW [(match_dup 1)
1355 UNSPEC_VEC_VFEECC))]
1358 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1360 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
1361 flags &= ~VSTRING_FLAG_CS;
1363 if (flags == VSTRING_FLAG_ZS)
1364 return "vfeez<bhfgq>s\t%v0,%v1,%v2";
1365 return "vfee<bhfgq>s\t%v0,%v1,%v2,%b3";
1367 [(set_attr "op_type" "VRR")])
1369 ; vfeeb, vfeeh, vfeef
1370 (define_insn "vfee<mode>"
1371 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1372 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1373 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1377 "vfee<bhfgq>\t%v0,%v1,%v2,0"
1378 [(set_attr "op_type" "VRR")])
1380 ; vfeezb, vfeezh, vfeezf
1381 (define_insn "vfeez<mode>"
1382 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1383 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1384 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1385 (const_int VSTRING_FLAG_ZS)]
1388 "vfeez<bhfgq>s\t%v0,%v1,%v2,2"
1389 [(set_attr "op_type" "VRR")])
1391 (define_expand "vfees<mode>"
1393 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1394 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1395 (match_operand:VI_HW_QHS 2 "register_operand" "")
1396 (const_int VSTRING_FLAG_CS)]
1398 (set (reg:CCRAW CC_REGNUM)
1399 (unspec:CCRAW [(match_dup 1)
1401 (const_int VSTRING_FLAG_CS)]
1402 UNSPEC_VEC_VFEECC))])
1403 (set (match_operand:SI 3 "memory_operand" "")
1404 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1407 (define_expand "vfeezs<mode>"
1409 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1410 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1411 (match_operand:VI_HW_QHS 2 "register_operand" "")
1414 (set (reg:CCRAW CC_REGNUM)
1415 (unspec:CCRAW [(match_dup 1)
1418 UNSPEC_VEC_VFEECC))])
1419 (set (match_operand:SI 3 "memory_operand" "")
1420 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1423 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1426 ; Vector find element not equal
1428 ; vfeneb, vfeneh, vfenef
1429 (define_insn "vfene<mode>"
1430 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1431 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1432 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1436 "vfene<bhfgq>\t%v0,%v1,%v2,0"
1437 [(set_attr "op_type" "VRR")])
1439 ; vec_vfenes can be found in vector.md since it is used for strlen
1441 ; vfenezb, vfenezh, vfenezf
1442 (define_insn "vfenez<mode>"
1443 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1444 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1445 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1446 (const_int VSTRING_FLAG_ZS)]
1449 "vfenez<bhfgq>\t%v0,%v1,%v2"
1450 [(set_attr "op_type" "VRR")])
1452 (define_expand "vfenes<mode>"
1454 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1455 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1456 (match_operand:VI_HW_QHS 2 "register_operand" "")
1457 (const_int VSTRING_FLAG_CS)]
1459 (set (reg:CCRAW CC_REGNUM)
1460 (unspec:CCRAW [(match_dup 1)
1462 (const_int VSTRING_FLAG_CS)]
1463 UNSPEC_VEC_VFENECC))])
1464 (set (match_operand:SI 3 "memory_operand" "")
1465 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1468 (define_expand "vfenezs<mode>"
1470 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1471 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1472 (match_operand:VI_HW_QHS 2 "register_operand" "")
1475 (set (reg:CCRAW CC_REGNUM)
1476 (unspec:CCRAW [(match_dup 1)
1479 UNSPEC_VEC_VFENECC))])
1480 (set (match_operand:SI 3 "memory_operand" "")
1481 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1484 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1487 ; Vector isolate string
1489 ; vistrb, vistrh, vistrf
1490 (define_insn "vistr<mode>"
1491 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1492 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1495 "vistr<bhfgq>\t%v0,%v1"
1496 [(set_attr "op_type" "VRR")])
1498 ; vistrbs, vistrhs, vistrfs
1499 (define_insn "*vistrs<mode>"
1500 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1501 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1503 (set (reg:CCRAW CC_REGNUM)
1504 (unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))]
1506 "vistr<bhfgq>s\t%v0,%v1"
1507 [(set_attr "op_type" "VRR")])
1509 (define_expand "vistrs<mode>"
1511 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1512 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")]
1514 (set (reg:CCRAW CC_REGNUM)
1515 (unspec:CCRAW [(match_dup 1)]
1516 UNSPEC_VEC_VISTRCC))])
1517 (set (match_operand:SI 2 "memory_operand" "")
1518 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1522 ; Vector compare range
1524 ; vstrcb, vstrch, vstrcf
1525 ; vstrczb, vstrczh, vstrczf
1526 (define_insn "vstrc<mode>"
1527 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1528 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1529 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1530 (match_operand:VI_HW_QHS 3 "register_operand" "v")
1531 (match_operand:QI 4 "const_mask_operand" "C")]
1535 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1537 if (flags & VSTRING_FLAG_ZS)
1539 flags &= ~VSTRING_FLAG_ZS;
1540 operands[4] = GEN_INT (flags);
1541 return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1543 return "vstrc<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1545 [(set_attr "op_type" "VRR")])
1547 ; vstrcbs, vstrchs, vstrcfs
1548 ; vstrczbs, vstrczhs, vstrczfs
1549 (define_insn "*vstrcs<mode>"
1550 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1551 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1552 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1553 (match_operand:VI_HW_QHS 3 "register_operand" "v")
1554 (match_operand:QI 4 "const_mask_operand" "C")]
1556 (set (reg:CCRAW CC_REGNUM)
1557 (unspec:CCRAW [(match_dup 1)
1561 UNSPEC_VEC_VSTRCCC))]
1564 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1566 if (flags & VSTRING_FLAG_ZS)
1568 flags &= ~VSTRING_FLAG_ZS;
1569 operands[4] = GEN_INT (flags);
1570 return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1572 return "vstrc<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1574 [(set_attr "op_type" "VRR")])
1576 (define_expand "vstrcz<mode>"
1577 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1578 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1579 (match_operand:VI_HW_QHS 2 "register_operand" "")
1580 (match_operand:VI_HW_QHS 3 "register_operand" "")
1581 (match_operand:QI 4 "const_mask_operand" "")]
1585 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS);
1588 (define_expand "vstrcs<mode>"
1590 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1591 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1592 (match_operand:VI_HW_QHS 2 "register_operand" "")
1593 (match_operand:VI_HW_QHS 3 "register_operand" "")
1594 (match_operand:QI 4 "const_mask_operand" "")]
1596 (set (reg:CCRAW CC_REGNUM)
1597 (unspec:CCRAW [(match_dup 1)
1601 UNSPEC_VEC_VSTRCCC))])
1602 (set (match_operand:SI 5 "memory_operand" "")
1603 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1606 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS);
1609 (define_expand "vstrczs<mode>"
1611 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1612 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1613 (match_operand:VI_HW_QHS 2 "register_operand" "")
1614 (match_operand:VI_HW_QHS 3 "register_operand" "")
1615 (match_operand:QI 4 "const_mask_operand" "")]
1617 (set (reg:CCRAW CC_REGNUM)
1618 (unspec:CCRAW [(match_dup 1)
1622 UNSPEC_VEC_VSTRCCC))])
1623 (set (match_operand:SI 5 "memory_operand" "")
1624 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1627 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1630 ; Vector string search
1632 (define_expand "vstrs<mode>"
1634 [(set (match_operand:V16QI 0 "register_operand" "")
1635 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1636 (match_operand:VI_HW_QHS 2 "register_operand" "")
1637 (match_operand:V16QI 3 "register_operand" "")
1640 (set (reg:CCRAW CC_REGNUM)
1641 (unspec:CCRAW [(match_dup 1)
1645 UNSPEC_VEC_VSTRSCC))])
1646 (set (match_operand:SI 4 "memory_operand" "")
1647 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1650 (define_expand "vstrsz<mode>"
1652 [(set (match_operand:V16QI 0 "register_operand" "")
1653 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1654 (match_operand:VI_HW_QHS 2 "register_operand" "")
1655 (match_operand:V16QI 3 "register_operand" "")
1656 (const_int VSTRING_FLAG_ZS)]
1658 (set (reg:CCRAW CC_REGNUM)
1659 (unspec:CCRAW [(match_dup 1)
1662 (const_int VSTRING_FLAG_ZS)]
1663 UNSPEC_VEC_VSTRSCC))])
1664 (set (match_operand:SI 4 "memory_operand" "")
1665 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1668 ; vstrsb, vstrsh, vstrsf
1669 ; vstrszb, vstrszh, vstrszf
1670 (define_insn "vec_vstrs<mode>"
1671 [(set (match_operand:V16QI 0 "register_operand" "=v")
1672 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1673 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1674 (match_operand:V16QI 3 "register_operand" "v")
1675 (match_operand:QI 4 "const_mask_operand" "C")]
1677 (set (reg:CCRAW CC_REGNUM)
1678 (unspec:CCRAW [(match_dup 1)
1682 UNSPEC_VEC_VSTRSCC))]
1685 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1687 gcc_assert (!(flags & ~VSTRING_FLAG_ZS));
1689 if (flags == VSTRING_FLAG_ZS)
1690 return "vstrsz<bhfgq>\t%v0,%v1,%v2,%v3";
1691 return "vstrs<bhfgq>\t%v0,%v1,%v2,%v3";
1693 [(set_attr "op_type" "VRR")])
1696 ; Vector convert int<->float
1698 (define_insn "vcdgb"
1699 [(set (match_operand:V2DF 0 "register_operand" "=v")
1700 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v")
1701 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression
1702 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1704 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1705 "vcdgb\t%v0,%v1,%b2,%b3"
1706 [(set_attr "op_type" "VRR")])
1709 ; The result needs to be multiplied with 2**-op2
1710 (define_expand "vec_ctd_s64"
1711 [(set (match_operand:V2DF 0 "register_operand" "")
1712 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1713 (const_int VEC_NOINEXACT)
1714 (const_int VEC_RND_CURRENT)]
1716 (use (match_operand:QI 2 "const_int_operand" ""))
1717 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1723 real_2expN (&f, -INTVAL (operands[2]), DFmode);
1724 c = const_double_from_real_value (f, DFmode);
1726 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1727 operands[3] = force_reg (V2DFmode, operands[3]);
1730 (define_insn "vcdlgb"
1731 [(set (match_operand:V2DF 0 "register_operand" "=v")
1732 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v")
1733 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression
1734 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1735 UNSPEC_VEC_VCDLGB))]
1736 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1737 "vcdlgb\t%v0,%v1,%b2,%b3"
1738 [(set_attr "op_type" "VRR")])
1740 ; The result needs to be multiplied with 2**-op2
1741 (define_expand "vec_ctd_u64"
1742 [(set (match_operand:V2DF 0 "register_operand" "")
1743 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1744 (const_int VEC_NOINEXACT)
1745 (const_int VEC_RND_CURRENT)]
1747 (use (match_operand:QI 2 "const_int_operand" ""))
1748 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1754 real_2expN (&f, -INTVAL (operands[2]), DFmode);
1755 c = const_double_from_real_value (f, DFmode);
1757 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1758 operands[3] = force_reg (V2DFmode, operands[3]);
1761 (define_insn "vcgdb"
1762 [(set (match_operand:V2DI 0 "register_operand" "=v")
1763 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v")
1764 (match_operand:QI 2 "const_mask_operand" "C")
1765 (match_operand:QI 3 "const_mask_operand" "C")]
1767 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1768 "vcgdb\t%v0,%v1,%b2,%b3"
1769 [(set_attr "op_type" "VRR")])
1771 ; The input needs to be multiplied with 2**op2
1772 (define_expand "vec_ctsl"
1773 [(use (match_operand:QI 2 "const_int_operand" ""))
1774 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1776 (set (match_operand:V2DI 0 "register_operand" "")
1777 (unspec:V2DI [(match_dup 4)
1778 (const_int VEC_NOINEXACT)
1779 (const_int VEC_RND_CURRENT)]
1786 real_2expN (&f, INTVAL (operands[2]), DFmode);
1787 c = const_double_from_real_value (f, DFmode);
1789 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1790 operands[3] = force_reg (V2DFmode, operands[3]);
1791 operands[4] = gen_reg_rtx (V2DFmode);
1794 (define_insn "vclgdb"
1795 [(set (match_operand:V2DI 0 "register_operand" "=v")
1796 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v")
1797 (match_operand:QI 2 "const_mask_operand" "C")
1798 (match_operand:QI 3 "const_mask_operand" "C")]
1799 UNSPEC_VEC_VCLGDB))]
1800 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1801 "vclgdb\t%v0,%v1,%b2,%b3"
1802 [(set_attr "op_type" "VRR")])
1804 ; The input needs to be multiplied with 2**op2
1805 (define_expand "vec_ctul"
1806 [(use (match_operand:QI 2 "const_int_operand" ""))
1807 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1809 (set (match_operand:V2DI 0 "register_operand" "")
1810 (unspec:V2DI [(match_dup 4)
1811 (const_int VEC_NOINEXACT)
1812 (const_int VEC_RND_CURRENT)]
1813 UNSPEC_VEC_VCLGDB))]
1819 real_2expN (&f, INTVAL (operands[2]), DFmode);
1820 c = const_double_from_real_value (f, DFmode);
1822 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1823 operands[3] = force_reg (V2DFmode, operands[3]);
1824 operands[4] = gen_reg_rtx (V2DFmode);
1827 ; Vector load fp integer - IEEE inexact exception is suppressed
1828 ; vfisb, vfidb, wfisb, wfidb, wfixb
1829 (define_insn "vec_fpint<mode>"
1830 [(set (match_operand:VFT 0 "register_operand" "=v")
1831 (unspec:VFT [(match_operand:VFT 1 "register_operand" "v")
1832 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression control
1833 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1836 "<vw>fi<sdx>b\t%v0,%v1,%b2,%b3"
1837 [(set_attr "op_type" "VRR")])
1840 ; Vector load lengthened - V4SF -> V2DF
1842 (define_insn "vflls"
1843 [(set (match_operand:V2DF 0 "register_operand" "=v")
1844 (unspec:V2DF [(match_operand:V4SF 1 "register_operand" "v")]
1848 [(set_attr "op_type" "VRR")])
1850 (define_expand "vec_ld2f"
1851 [; Initialize a vector to all zeroes. FIXME: This should not be
1852 ; necessary since all elements of the vector will be set anyway.
1853 ; This is just to make it explicit to the data flow framework.
1854 (set (match_dup 2) (match_dup 3))
1855 (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "")
1859 (set (match_dup 2) (unspec:V4SF [(match_dup 4)
1863 (set (match_operand:V2DF 0 "register_operand" "")
1864 (unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VFLL))]
1867 operands[2] = gen_reg_rtx (V4SFmode);
1868 operands[3] = CONST0_RTX (V4SFmode);
1869 operands[4] = adjust_address (operands[1], SFmode, 4);
1873 ; Vector load rounded - V2DF -> V4SF
1875 (define_insn "vflrd"
1876 [(set (match_operand:V4SF 0 "register_operand" "=v")
1877 (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "v")
1878 (match_operand:QI 2 "const_mask_operand" "C")
1879 (match_operand:QI 3 "const_mask_operand" "C")]
1882 "vledb\t%v0,%v1,%b2,%b3"
1883 [(set_attr "op_type" "VRR")])
1885 (define_expand "vec_st2f"
1887 (unspec:V4SF [(match_operand:V2DF 0 "register_operand" "")
1888 (const_int VEC_INEXACT)
1889 (const_int VEC_RND_CURRENT)]
1891 (set (match_operand:SF 1 "memory_operand" "")
1892 (unspec:SF [(match_dup 2) (const_int 0)] UNSPEC_VEC_EXTRACT))
1894 (unspec:SF [(match_dup 2) (const_int 2)] UNSPEC_VEC_EXTRACT))]
1897 operands[2] = gen_reg_rtx (V4SFmode);
1898 operands[3] = adjust_address (operands[1], SFmode, 4);
1902 ; Vector square root fp vec_sqrt -> sqrt rtx standard name
1904 ;; Vector FP test data class immediate
1906 ; vec_all_nan, vec_all_numeric, vec_any_nan, vec_any_numeric
1907 ; These ignore the vector result and only want CC stored to an int
1911 (define_insn "*vftci<mode>_cconly"
1912 [(set (reg:CCRAW CC_REGNUM)
1913 (unspec:CCRAW [(match_operand:VECF_HW 1 "register_operand")
1914 (match_operand:HI 2 "const_int_operand")]
1915 UNSPEC_VEC_VFTCICC))
1916 (clobber (match_scratch:<tointvec> 0))]
1917 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1918 "vftci<sdx>b\t%v0,%v1,%x2"
1919 [(set_attr "op_type" "VRR")])
1921 (define_expand "vftci<mode>_intcconly"
1923 [(set (reg:CCRAW CC_REGNUM)
1924 (unspec:CCRAW [(match_operand:VECF_HW 0 "register_operand")
1925 (match_operand:HI 1 "const_int_operand")]
1926 UNSPEC_VEC_VFTCICC))
1927 (clobber (scratch:<tointvec>))])
1928 (set (match_operand:SI 2 "register_operand" "")
1929 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1930 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")")
1932 ; vec_fp_test_data_class wants the result vector and the CC stored to
1936 (define_insn "*vftci<mode>"
1937 [(set (match_operand:VECF_HW 0 "register_operand" "=v")
1938 (unspec:VECF_HW [(match_operand:VECF_HW 1 "register_operand" "v")
1939 (match_operand:HI 2 "const_int_operand" "J")]
1941 (set (reg:CCRAW CC_REGNUM)
1942 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))]
1943 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1944 "vftci<sdx>b\t%v0,%v1,%x2"
1945 [(set_attr "op_type" "VRR")])
1947 (define_expand "vftci<mode>_intcc"
1949 [(set (match_operand:VECF_HW 0 "register_operand")
1950 (unspec:VECF_HW [(match_operand:VECF_HW 1 "register_operand")
1951 (match_operand:HI 2 "const_int_operand")]
1953 (set (reg:CCRAW CC_REGNUM)
1954 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))])
1955 (set (match_operand:SI 3 "memory_operand" "")
1956 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1957 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")")
1963 ; All comparisons which produce a CC need fully populated (VI_HW)
1964 ; vector arguments. Otherwise the any/all CCs would be just bogus.
1966 (define_insn "*vec_cmp<VICMP:insn_cmp><VI_HW:mode>_cconly"
1967 [(set (reg:VICMP CC_REGNUM)
1968 (compare:VICMP (match_operand:VI_HW 0 "register_operand" "v")
1969 (match_operand:VI_HW 1 "register_operand" "v")))
1970 (clobber (match_scratch:VI_HW 2 "=v"))]
1972 "vc<VICMP:insn_cmp><VI_HW:bhfgq>s\t%v2,%v0,%v1"
1973 [(set_attr "op_type" "VRR")])
1975 ; FIXME: The following 2x3 definitions should be merged into 2 with
1976 ; VICMP like above but I could not find a way to set the comparison
1977 ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the
1978 ; other way around - setting the mode depending on the code
1980 (define_expand "vec_cmpeq<VI_HW:mode>_cc"
1982 [(set (reg:CCVEQ CC_REGNUM)
1983 (compare:CCVEQ (match_operand:VI_HW 1 "register_operand" "v")
1984 (match_operand:VI_HW 2 "register_operand" "v")))
1985 (set (match_operand:VI_HW 0 "register_operand" "=v")
1986 (eq:VI_HW (match_dup 1) (match_dup 2)))])
1987 (set (match_operand:SI 3 "memory_operand" "")
1988 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
1991 (define_expand "vec_cmph<VI_HW:mode>_cc"
1993 [(set (reg:CCVIH CC_REGNUM)
1994 (compare:CCVIH (match_operand:VI_HW 1 "register_operand" "v")
1995 (match_operand:VI_HW 2 "register_operand" "v")))
1996 (set (match_operand:VI_HW 0 "register_operand" "=v")
1997 (gt:VI_HW (match_dup 1) (match_dup 2)))])
1998 (set (match_operand:SI 3 "memory_operand" "")
1999 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2002 (define_expand "vec_cmphl<VI_HW:mode>_cc"
2004 [(set (reg:CCVIHU CC_REGNUM)
2005 (compare:CCVIHU (match_operand:VI_HW 1 "register_operand" "v")
2006 (match_operand:VI_HW 2 "register_operand" "v")))
2007 (set (match_operand:VI_HW 0 "register_operand" "=v")
2008 (gtu:VI_HW (match_dup 1) (match_dup 2)))])
2009 (set (match_operand:SI 3 "memory_operand" "")
2010 (unspec:SI [(reg:CCVIHU CC_REGNUM)] UNSPEC_CC_TO_INT))]
2014 (define_insn "*vec_cmpeq<VI_HW:mode>_cc"
2015 [(set (reg:CCVEQ CC_REGNUM)
2016 (compare:CCVEQ (match_operand:VI_HW 0 "register_operand" "v")
2017 (match_operand:VI_HW 1 "register_operand" "v")))
2018 (set (match_operand:VI_HW 2 "register_operand" "=v")
2019 (eq:VI_HW (match_dup 0) (match_dup 1)))]
2021 "vceq<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2022 [(set_attr "op_type" "VRR")])
2024 (define_insn "*vec_cmph<VI_HW:mode>_cc"
2025 [(set (reg:CCVIH CC_REGNUM)
2026 (compare:CCVIH (match_operand:VI_HW 0 "register_operand" "v")
2027 (match_operand:VI_HW 1 "register_operand" "v")))
2028 (set (match_operand:VI_HW 2 "register_operand" "=v")
2029 (gt:VI_HW (match_dup 0) (match_dup 1)))]
2031 "vch<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2032 [(set_attr "op_type" "VRR")])
2034 (define_insn "*vec_cmphl<VI_HW:mode>_cc"
2035 [(set (reg:CCVIHU CC_REGNUM)
2036 (compare:CCVIHU (match_operand:VI_HW 0 "register_operand" "v")
2037 (match_operand:VI_HW 1 "register_operand" "v")))
2038 (set (match_operand:VI_HW 2 "register_operand" "=v")
2039 (gtu:VI_HW (match_dup 0) (match_dup 1)))]
2041 "vchl<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2042 [(set_attr "op_type" "VRR")])
2045 ;; Floating point compares
2048 ; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs
2049 (define_insn "*vec_cmp<insn_cmp><VF_HW:mode>_cconly"
2050 [(set (reg:VFCMP CC_REGNUM)
2051 (compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
2052 (match_operand:VF_HW 1 "register_operand" "v")))
2053 (clobber (match_scratch:<tointvec> 2 "=v"))]
2055 "<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1"
2056 [(set_attr "op_type" "VRR")])
2058 ; FIXME: Merge the following 2x3 patterns with VFCMP
2059 (define_expand "vec_cmpeq<mode>_cc"
2061 [(set (reg:CCVEQ CC_REGNUM)
2062 (compare:CCVEQ (match_operand:VF_HW 1 "register_operand" "v")
2063 (match_operand:VF_HW 2 "register_operand" "v")))
2064 (set (match_operand:<tointvec> 0 "register_operand" "=v")
2065 (eq:<tointvec> (match_dup 1) (match_dup 2)))])
2066 (set (match_operand:SI 3 "memory_operand" "")
2067 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2070 (define_expand "vec_cmph<mode>_cc"
2072 [(set (reg:CCVFH CC_REGNUM)
2073 (compare:CCVFH (match_operand:VF_HW 1 "register_operand" "v")
2074 (match_operand:VF_HW 2 "register_operand" "v")))
2075 (set (match_operand:<tointvec> 0 "register_operand" "=v")
2076 (gt:<tointvec> (match_dup 1) (match_dup 2)))])
2077 (set (match_operand:SI 3 "memory_operand" "")
2078 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2081 (define_expand "vec_cmphe<mode>_cc"
2083 [(set (reg:CCVFHE CC_REGNUM)
2084 (compare:CCVFHE (match_operand:VF_HW 1 "register_operand" "v")
2085 (match_operand:VF_HW 2 "register_operand" "v")))
2086 (set (match_operand:<tointvec> 0 "register_operand" "=v")
2087 (ge:<tointvec> (match_dup 1) (match_dup 2)))])
2088 (set (match_operand:SI 3 "memory_operand" "")
2089 (unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]
2092 ; These 3 cannot be merged as the insn defintion above since it also
2093 ; requires to rewrite the RTL equality operator that the same time as
2096 ; vfcesbs, vfcedbs, wfcexbs
2097 (define_insn "*vec_cmpeq<mode>_cc"
2098 [(set (reg:CCVEQ CC_REGNUM)
2099 (compare:CCVEQ (match_operand:VF_HW 0 "register_operand" "v")
2100 (match_operand:VF_HW 1 "register_operand" "v")))
2101 (set (match_operand:<tointvec> 2 "register_operand" "=v")
2102 (eq:<tointvec> (match_dup 0) (match_dup 1)))]
2104 "<vw>fce<sdx>bs\t%v2,%v0,%v1"
2105 [(set_attr "op_type" "VRR")])
2107 ; vfchsbs, vfchdbs, wfchxbs
2108 (define_insn "*vec_cmph<mode>_cc"
2109 [(set (reg:CCVFH CC_REGNUM)
2110 (compare:CCVFH (match_operand:VF_HW 0 "register_operand" "v")
2111 (match_operand:VF_HW 1 "register_operand" "v")))
2112 (set (match_operand:<tointvec> 2 "register_operand" "=v")
2113 (gt:<tointvec> (match_dup 0) (match_dup 1)))]
2115 "<vw>fch<sdx>bs\t%v2,%v0,%v1"
2116 [(set_attr "op_type" "VRR")])
2118 ; vfchesbs, vfchedbs, wfchexbs
2119 (define_insn "*vec_cmphe<mode>_cc"
2120 [(set (reg:CCVFHE CC_REGNUM)
2121 (compare:CCVFHE (match_operand:VF_HW 0 "register_operand" "v")
2122 (match_operand:VF_HW 1 "register_operand" "v")))
2123 (set (match_operand:<tointvec> 2 "register_operand" "=v")
2124 (ge:<tointvec> (match_dup 0) (match_dup 1)))]
2126 "<vw>fche<sdx>bs\t%v2,%v0,%v1"
2127 [(set_attr "op_type" "VRR")])
2130 (define_insn "vfmin<mode>"
2131 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2132 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "%v")
2133 (match_operand:VF_HW 2 "register_operand" "v")
2134 (match_operand:QI 3 "const_mask_operand" "C")]
2137 "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3"
2138 [(set_attr "op_type" "VRR")])
2140 (define_insn "vfmax<mode>"
2141 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2142 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "%v")
2143 (match_operand:VF_HW 2 "register_operand" "v")
2144 (match_operand:QI 3 "const_mask_operand" "C")]
2147 "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3"
2148 [(set_attr "op_type" "VRR")])
2150 ; The element reversal builtins introduced with z15 have been made
2151 ; available also for older CPUs down to z13.
2152 (define_expand "eltswap<mode>"
2153 [(set (match_operand:VEC_HW 0 "nonimmediate_operand" "")
2154 (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "")]
2155 UNSPEC_VEC_ELTSWAP))]
2158 ; The byte element reversal is implemented as 128 bit byte swap.
2159 ; Alternatively this could be emitted as bswap:V1TI but the required
2160 ; subregs appear to confuse combine.
2161 (define_insn "*eltswapv16qi"
2162 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=v,v,R")
2163 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "v,R,v")]
2164 UNSPEC_VEC_ELTSWAP))]
2170 [(set_attr "op_type" "*,VRX,VRX")])
2172 ; vlerh, vlerf, vlerg, vsterh, vsterf, vsterg
2173 (define_insn "*eltswap<mode>"
2174 [(set (match_operand:V_HW_HSD 0 "nonimmediate_operand" "=v,v,R")
2175 (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "nonimmediate_operand" "v,R,v")]
2176 UNSPEC_VEC_ELTSWAP))]
2180 vler<bhfgq>\t%v0,%v1
2181 vster<bhfgq>\t%v1,%v0"
2182 [(set_attr "op_type" "*,VRX,VRX")])
2184 ; z15 has instructions for doing element reversal from mem to reg
2185 ; or the other way around. For reg to reg or on pre z15 machines
2186 ; we have to emulate it with vector permute.
2187 (define_insn_and_split "*eltswap<mode>_emu"
2188 [(set (match_operand:VEC_HW 0 "nonimmediate_operand" "=vR")
2189 (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "vR")]
2190 UNSPEC_VEC_ELTSWAP))]
2191 "TARGET_VX && can_create_pseudo_p ()"
2193 "&& ((!memory_operand (operands[0], <MODE>mode)
2194 && !memory_operand (operands[1], <MODE>mode))
2197 (unspec:V16QI [(match_dup 4)
2201 (set (match_dup 0) (subreg:VEC_HW (match_dup 3) 0))]
2203 static char p[4][16] =
2204 { { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, /* Q */
2205 { 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1 }, /* H */
2206 { 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3 }, /* S */
2207 { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 } }; /* D */
2209 rtx perm_rtx[16], constv;
2211 switch (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)))
2213 case 1: perm = p[0]; break;
2214 case 2: perm = p[1]; break;
2215 case 4: perm = p[2]; break;
2216 case 8: perm = p[3]; break;
2217 default: gcc_unreachable ();
2220 for (int i = 0; i < 16; i++)
2221 perm_rtx[i] = GEN_INT (perm[i]);
2223 operands[1] = force_reg (<MODE>mode, operands[1]);
2224 operands[2] = gen_reg_rtx (V16QImode);
2225 operands[3] = gen_reg_rtx (V16QImode);
2226 operands[4] = simplify_gen_subreg (V16QImode, operands[1], <MODE>mode, 0);
2227 constv = force_const_mem (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm_rtx)));
2228 emit_move_insn (operands[2], constv);
2231 ; vec_insert (__builtin_bswap32 (*a), b, 1) set-element-bswap-2.c
2232 ; b[1] = __builtin_bswap32 (*a) set-element-bswap-3.c
2233 ; vlebrh, vlebrf, vlebrg
2234 (define_insn "*vec_set_bswap_elem<mode>"
2235 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
2236 (unspec:V_HW_HSD [(bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand" "R"))
2237 (match_operand:SI 2 "const_int_operand" "C")
2238 (match_operand:V_HW_HSD 3 "register_operand" "0")]
2240 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2241 "vlebr<bhfgq>\t%v0,%1,%2"
2242 [(set_attr "op_type" "VRX")])
2244 ; vec_revb (vec_insert (*a, vec_revb (b), 1)) set-element-bswap-1.c
2245 ; vlebrh, vlebrf, vlebrg
2246 (define_insn "*vec_set_bswap_vec<mode>"
2247 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
2249 (unspec:V_HW_HSD [(match_operand:<non_vec> 1 "memory_operand" "R")
2250 (match_operand:SI 2 "const_int_operand" "C")
2251 (bswap:V_HW_HSD (match_operand:V_HW_HSD 3 "register_operand" "0"))]
2253 (use (match_operand:V16QI 4 "permute_pattern_operand" "X"))]
2254 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2255 "vlebr<bhfgq>\t%v0,%1,%2"
2256 [(set_attr "op_type" "VRX")])
2258 ; *a = vec_extract (vec_revb (b), 1); get-element-bswap-3.c
2259 ; *a = vec_revb (b)[1]; get-element-bswap-4.c
2260 ; vstebrh, vstebrf, vstebrg
2261 (define_insn "*vec_extract_bswap_vec<mode>"
2262 [(set (match_operand:<non_vec> 0 "memory_operand" "=R")
2263 (unspec:<non_vec> [(bswap:V_HW_HSD (match_operand:V_HW_HSD 1 "register_operand" "v"))
2264 (match_operand:SI 2 "const_int_operand" "C")]
2265 UNSPEC_VEC_EXTRACT))]
2266 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2267 "vstebr<bhfgq>\t%v1,%0,%2"
2268 [(set_attr "op_type" "VRX")])
2270 ; *a = __builtin_bswap32 (vec_extract (b, 1)); get-element-bswap-1.c
2271 ; *a = __builtin_bswap32 (b[1]); get-element-bswap-2.c
2272 ; vstebrh, vstebrf, vstebrg
2273 (define_insn "*vec_extract_bswap_elem<mode>"
2274 [(set (match_operand:<non_vec> 0 "memory_operand" "=R")
2276 (unspec:<non_vec> [(match_operand:V_HW_HSD 1 "register_operand" "v")
2277 (match_operand:SI 2 "const_int_operand" "C")]
2278 UNSPEC_VEC_EXTRACT)))]
2279 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2280 "vstebr<bhfgq>\t%v1,%0,%2"
2281 [(set_attr "op_type" "VRX")])