1 ;;- Instruction patterns for the System z vector facility builtins.
2 ;; Copyright (C) 2015-2019 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)))]
191 "vllebrz<bhfgq>\t%v0,%1"
192 [(set_attr "op_type" "VRX")])
196 [(set (match_operand:V16QI 0 "register_operand" "=v")
197 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "R")
198 (match_operand:QI 2 "const_mask_operand" "C")]
199 UNSPEC_VEC_LOAD_BNDRY))]
200 "TARGET_VX && UINTVAL (operands[2]) < 7"
202 [(set_attr "op_type" "VRX")])
204 (define_insn "vlrlrv16qi"
205 [(set (match_operand:V16QI 0 "register_operand" "=v,v")
206 (unspec:V16QI [(match_operand:BLK 2 "memory_operand" "Q,Q")
207 (match_operand:SI 1 "nonmemory_operand" "d,C")]
208 UNSPEC_VEC_LOAD_LEN_R))]
213 [(set_attr "op_type" "VRS,VSI")])
216 ; FIXME: The following two patterns might using vec_merge. But what is
217 ; the canonical form: (vec_select (vec_merge op0 op1)) or (vec_merge
218 ; (vec_select op0) (vec_select op1)
219 ; vmrhb, vmrhh, vmrhf, vmrhg
220 (define_insn "vec_mergeh<mode>"
221 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v")
222 (unspec:V_128_NOSINGLE [(match_operand:V_128_NOSINGLE 1 "register_operand" "v")
223 (match_operand:V_128_NOSINGLE 2 "register_operand" "v")]
226 "vmrh<bhfgq>\t%v0,%1,%2"
227 [(set_attr "op_type" "VRR")])
229 ; vmrlb, vmrlh, vmrlf, vmrlg
230 (define_insn "vec_mergel<mode>"
231 [(set (match_operand:V_128_NOSINGLE 0 "register_operand" "=v")
232 (unspec:V_128_NOSINGLE [(match_operand:V_128_NOSINGLE 1 "register_operand" "v")
233 (match_operand:V_128_NOSINGLE 2 "register_operand" "v")]
236 "vmrl<bhfgq>\t%v0,%1,%2"
237 [(set_attr "op_type" "VRR")])
243 (define_insn "vec_pack<mode>"
244 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
245 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
246 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
249 "vpk<bhfgq>\t%v0,%v1,%v2"
250 [(set_attr "op_type" "VRR")])
253 ; Vector pack saturate
255 ; vpksh, vpksf, vpksg
256 (define_insn "vec_packs<mode>"
257 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
258 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
259 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
260 UNSPEC_VEC_PACK_SATURATE))]
262 "vpks<bhfgq>\t%v0,%v1,%v2"
263 [(set_attr "op_type" "VRR")])
266 ; This is vec_packs_cc + loading cc into a caller specified memory location.
267 (define_expand "vec_packs_cc<mode>"
269 [(set (reg:CCRAW CC_REGNUM)
270 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
271 (match_operand:VI_HW_HSD 2 "register_operand" "")]
272 UNSPEC_VEC_PACK_SATURATE_GENCC))
273 (set (match_operand:<vec_half> 0 "register_operand" "")
274 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
275 UNSPEC_VEC_PACK_SATURATE_CC))])
277 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
278 (set (match_operand:SI 3 "memory_operand" "")
282 operands[4] = gen_reg_rtx (SImode);
285 ; vpksh, vpksf, vpksg
286 (define_insn "*vec_packs_cc<mode>"
287 [(set (reg:CCRAW CC_REGNUM)
288 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
289 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
290 UNSPEC_VEC_PACK_SATURATE_GENCC))
291 (set (match_operand:<vec_half> 0 "register_operand" "=v")
292 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
293 UNSPEC_VEC_PACK_SATURATE_CC))]
295 "vpks<bhfgq>s\t%v0,%v1,%v2"
296 [(set_attr "op_type" "VRR")])
299 ; Vector pack logical saturate
301 ; vpklsh, vpklsf, vpklsg
302 (define_insn "vec_packsu<mode>"
303 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
304 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
305 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
306 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
308 "vpkls<bhfgq>\t%v0,%v1,%v2"
309 [(set_attr "op_type" "VRR")])
311 ; Emulate saturate unsigned pack on signed operands.
312 ; Zero out negative elements and continue with the unsigned saturating pack.
313 (define_expand "vec_packsu_u<mode>"
314 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
315 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
316 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
317 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
320 rtx null_vec = CONST0_RTX(<MODE>mode);
321 machine_mode half_mode;
324 case E_V8HImode: half_mode = V16QImode; break;
325 case E_V4SImode: half_mode = V8HImode; break;
326 case E_V2DImode: half_mode = V4SImode; break;
327 default: gcc_unreachable ();
329 s390_expand_vcond (operands[1], operands[1], null_vec,
330 GE, operands[1], null_vec);
331 s390_expand_vcond (operands[2], operands[2], null_vec,
332 GE, operands[2], null_vec);
333 emit_insn (gen_rtx_SET (operands[0],
334 gen_rtx_UNSPEC (half_mode,
335 gen_rtvec (2, operands[1], operands[2]),
336 UNSPEC_VEC_PACK_UNSIGNED_SATURATE)));
340 ; This is vec_packsu_cc + loading cc into a caller specified memory location.
341 ; FIXME: The reg to target mem copy should be issued by reload?!
342 (define_expand "vec_packsu_cc<mode>"
344 [(set (reg:CCRAW CC_REGNUM)
345 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
346 (match_operand:VI_HW_HSD 2 "register_operand" "")]
347 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
348 (set (match_operand:<vec_half> 0 "register_operand" "")
349 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
350 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))])
352 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
353 (set (match_operand:SI 3 "memory_operand" "")
357 operands[4] = gen_reg_rtx (SImode);
360 ; vpklsh, vpklsf, vpklsg
361 (define_insn "*vec_packsu_cc<mode>"
362 [(set (reg:CCRAW CC_REGNUM)
363 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
364 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
365 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
366 (set (match_operand:<vec_half> 0 "register_operand" "=v")
367 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
368 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))]
370 "vpkls<bhfgq>s\t%v0,%v1,%v2"
371 [(set_attr "op_type" "VRR")])
376 ; vec_perm is also RTL standard name, but we can only use it for V16QI
378 (define_insn "vec_zperm<mode>"
379 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
380 (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "register_operand" "v")
381 (match_operand:V_HW_HSD 2 "register_operand" "v")
382 (match_operand:V16QI 3 "register_operand" "v")]
385 "vperm\t%v0,%v1,%v2,%v3"
386 [(set_attr "op_type" "VRR")])
388 (define_expand "vec_permi<mode>"
389 [(set (match_operand:V_HW_64 0 "register_operand" "")
390 (unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand" "")
391 (match_operand:V_HW_64 2 "register_operand" "")
392 (match_operand:QI 3 "const_mask_operand" "")]
396 HOST_WIDE_INT val = INTVAL (operands[3]);
397 operands[3] = GEN_INT ((val & 1) | (val & 2) << 1);
400 (define_insn "*vec_permi<mode>"
401 [(set (match_operand:V_HW_64 0 "register_operand" "=v")
402 (unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand" "v")
403 (match_operand:V_HW_64 2 "register_operand" "v")
404 (match_operand:QI 3 "const_mask_operand" "C")]
406 "TARGET_VX && (UINTVAL (operands[3]) & 10) == 0"
407 "vpdi\t%v0,%v1,%v2,%b3"
408 [(set_attr "op_type" "VRR")])
414 ; Replicate from vector element
415 (define_expand "vec_splat<mode>"
416 [(set (match_operand:V_HW 0 "register_operand" "")
417 (vec_duplicate:V_HW (vec_select:<non_vec>
418 (match_operand:V_HW 1 "register_operand" "")
420 [(match_operand:QI 2 "const_mask_operand" "")]))))]
423 ; Vector scatter element
427 ; A 64 bit target address generated from 32 bit elements
428 (define_insn "vec_scatter_element<V_HW_4:mode>_DI"
430 (plus:DI (zero_extend:DI
431 (unspec:SI [(match_operand:V4SI 1 "register_operand" "v")
432 (match_operand:QI 3 "const_mask_operand" "C")]
434 (match_operand:SI 2 "address_operand" "ZQ")))
435 (unspec:<non_vec> [(match_operand:V_HW_4 0 "register_operand" "v")
436 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
437 "TARGET_VX && TARGET_64BIT && UINTVAL (operands[3]) < 4"
438 "vscef\t%v0,%O2(%v1,%R2),%3"
439 [(set_attr "op_type" "VRV")])
441 ; A 31 bit target address is generated from 64 bit elements
443 (define_insn "vec_scatter_element<V_HW_64:mode>_SI"
446 (unspec:<non_vec_int> [(match_operand:V_HW_64 1 "register_operand" "v")
447 (match_operand:QI 3 "const_mask_operand" "C")]
448 UNSPEC_VEC_EXTRACT) 4)
449 (match_operand:SI 2 "address_operand" "ZQ")))
450 (unspec:<non_vec> [(match_operand:V_HW_64 0 "register_operand" "v")
451 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
452 "TARGET_VX && !TARGET_64BIT && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_64:MODE>mode)"
453 "vsce<V_HW_64:bhfgq>\t%v0,%O2(%v1,%R2),%3"
454 [(set_attr "op_type" "VRV")])
456 ; Element size and target address size is the same
458 (define_insn "vec_scatter_element<mode>_<non_vec_int>"
460 (plus:<non_vec_int> (unspec:<non_vec_int>
461 [(match_operand:<tointvec> 1 "register_operand" "v")
462 (match_operand:QI 3 "const_mask_operand" "C")]
464 (match_operand:DI 2 "address_operand" "ZQ")))
465 (unspec:<non_vec> [(match_operand:V_HW_32_64 0 "register_operand" "v")
466 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
467 "TARGET_VX && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
468 "vsce<bhfgq>\t%v0,%O2(%v1,%R2),%3"
469 [(set_attr "op_type" "VRV")])
471 ; Depending on the address size we have to expand a different pattern.
472 ; This however cannot be represented in s390-builtins.def so we do the
473 ; multiplexing here in the expander.
474 (define_expand "vec_scatter_element<V_HW_32_64:mode>"
475 [(match_operand:V_HW_32_64 0 "register_operand" "")
476 (match_operand:<tointvec> 1 "register_operand" "")
477 (match_operand 2 "address_operand" "")
478 (match_operand:QI 3 "const_mask_operand" "")]
483 PUT_MODE (operands[2], DImode);
485 gen_vec_scatter_element<V_HW_32_64:mode>_DI (operands[0], operands[1],
486 operands[2], operands[3]));
490 PUT_MODE (operands[2], SImode);
492 gen_vec_scatter_element<V_HW_32_64:mode>_SI (operands[0], operands[1],
493 operands[2], operands[3]));
501 ; Operand 3 selects bits from either OP1 (0) or OP2 (1)
503 ; Comparison operator should not matter as long as we always use the same ?!
505 ; Operands 1 and 2 are swapped in order to match the altivec builtin.
506 ; If operand 3 is a const_int bitmask this would be vec_merge
507 (define_expand "vec_sel<mode>"
508 [(set (match_operand:V_HW 0 "register_operand" "")
510 (eq (match_operand:<tointvec> 3 "register_operand" "")
512 (match_operand:V_HW 2 "register_operand" "")
513 (match_operand:V_HW 1 "register_operand" "")))]
516 operands[4] = CONST0_RTX (<tointvec>mode);
520 ; Vector sign extend to doubleword
522 ; Sign extend of right most vector element to respective double-word
523 ; vsegb, vsegh, vsegf
524 (define_insn "vec_extend<mode>"
525 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
526 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
529 "vseg<bhfgq>\t%v0,%1"
530 [(set_attr "op_type" "VRR")])
533 ; Vector store with length
535 ; Store bytes in OP1 from OP0 with the highest indexed byte to be
536 ; stored from OP0 given by OP2
537 (define_insn "vstl<mode>"
538 [(set (match_operand:BLK 2 "memory_operand" "=Q")
539 (unspec:BLK [(match_operand:V 0 "register_operand" "v")
540 (match_operand:SI 1 "register_operand" "d")]
541 UNSPEC_VEC_STORE_LEN))]
544 [(set_attr "op_type" "VRS")])
546 ; Vector store rightmost with length
548 (define_insn "vstrlrv16qi"
549 [(set (match_operand:BLK 2 "memory_operand" "=Q,Q")
550 (unspec:BLK [(match_operand:V16QI 0 "register_operand" "v,v")
551 (match_operand:SI 1 "nonmemory_operand" "d,C")]
552 UNSPEC_VEC_STORE_LEN_R))]
557 [(set_attr "op_type" "VRS,VSI")])
563 (define_insn "vbpermv16qi"
564 [(set (match_operand:V2DI 0 "register_operand" "=v")
565 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v")
566 (match_operand:V16QI 2 "register_operand" "v")]
569 "vbperm\t%v0,%v1,%v2"
570 [(set_attr "op_type" "VRR")])
574 ; vuphb, vuphh, vuphf
575 (define_insn "vec_unpackh<mode>"
576 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
577 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
578 UNSPEC_VEC_UNPACKH))]
580 "vuph<bhfgq>\t%v0,%v1"
581 [(set_attr "op_type" "VRR")])
583 ; vuplhb, vuplhh, vuplhf
584 (define_insn "vec_unpackh_l<mode>"
585 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
586 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
587 UNSPEC_VEC_UNPACKH_L))]
589 "vuplh<bhfgq>\t%v0,%v1"
590 [(set_attr "op_type" "VRR")])
595 ; vuplb, vuplhw, vuplf
596 (define_insn "vec_unpackl<mode>"
597 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
598 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
599 UNSPEC_VEC_UNPACKL))]
601 "vupl<bhfgq><w>\t%v0,%v1"
602 [(set_attr "op_type" "VRR")])
604 ; vupllb, vupllh, vupllf
605 (define_insn "vec_unpackl_l<mode>"
606 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
607 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
608 UNSPEC_VEC_UNPACKL_L))]
610 "vupll<bhfgq>\t%v0,%v1"
611 [(set_attr "op_type" "VRR")])
616 ; Vector add compute carry
618 ; vaccb, vacch, vaccf, vaccg, vaccq
619 (define_insn "vacc<bhfgq>_<mode>"
620 [(set (match_operand:VIT_HW 0 "register_operand" "=v")
621 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "%v")
622 (match_operand:VIT_HW 2 "register_operand" "v")]
625 "vacc<bhfgq>\t%v0,%v1,%v2"
626 [(set_attr "op_type" "VRR")])
628 ; Vector add with carry
631 [(set (match_operand:TI 0 "register_operand" "=v")
632 (unspec:TI [(match_operand:TI 1 "register_operand" "%v")
633 (match_operand:TI 2 "register_operand" "v")
634 (match_operand:TI 3 "register_operand" "v")]
635 UNSPEC_VEC_ADDE_U128))]
637 "vacq\t%v0,%v1,%v2,%v3"
638 [(set_attr "op_type" "VRR")])
641 ; Vector add with carry compute carry
643 (define_insn "vacccq"
644 [(set (match_operand:TI 0 "register_operand" "=v")
645 (unspec:TI [(match_operand:TI 1 "register_operand" "%v")
646 (match_operand:TI 2 "register_operand" "v")
647 (match_operand:TI 3 "register_operand" "v")]
648 UNSPEC_VEC_ADDEC_U128))]
650 "vacccq\t%v0,%v1,%v2,%v3"
651 [(set_attr "op_type" "VRR")])
656 ; Vector and with complement
659 (define_insn "vec_andc<mode>3"
660 [(set (match_operand:VT_HW 0 "register_operand" "=v")
661 (and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand" "v"))
662 (match_operand:VT_HW 1 "register_operand" "v")))]
665 [(set_attr "op_type" "VRR")])
670 ; vavgb, vavgh, vavgf, vavgg
671 (define_insn "vec_avg<mode>"
672 [(set (match_operand:VI_HW 0 "register_operand" "=v")
673 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "%v")
674 (match_operand:VI_HW 2 "register_operand" "v")]
677 "vavg<bhfgq>\t%v0,%v1,%v2"
678 [(set_attr "op_type" "VRR")])
680 ; Vector average logical
682 ; vavglb, vavglh, vavglf, vavglg
683 (define_insn "vec_avgu<mode>"
684 [(set (match_operand:VI_HW 0 "register_operand" "=v")
685 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "%v")
686 (match_operand:VI_HW 2 "register_operand" "v")]
689 "vavgl<bhfgq>\t%v0,%v1,%v2"
690 [(set_attr "op_type" "VRR")])
695 (define_insn "vec_checksum"
696 [(set (match_operand:V4SI 0 "register_operand" "=v")
697 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
698 (match_operand:V4SI 2 "register_operand" "v")]
699 UNSPEC_VEC_CHECKSUM))]
702 [(set_attr "op_type" "VRR")])
708 ; vec_all/any int compares
710 (define_expand "vec_all_<intcmpcc:code><VI_HW:mode>"
711 [(match_operand:SI 0 "register_operand" "")
712 (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
713 (match_operand:VI_HW 2 "register_operand" ""))]
716 s390_expand_vec_compare_cc (operands[0],
724 (define_expand "vec_any_<intcmpcc:code><VI_HW:mode>"
725 [(match_operand:SI 0 "register_operand" "")
726 (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
727 (match_operand:VI_HW 2 "register_operand" ""))]
730 s390_expand_vec_compare_cc (operands[0],
738 ; vec_all/any fp compares
740 (define_expand "vec_all_<fpcmpcc:code><mode>"
741 [(match_operand:SI 0 "register_operand" "")
742 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
743 (match_operand:VECF_HW 2 "register_operand" ""))]
746 s390_expand_vec_compare_cc (operands[0],
754 (define_expand "vec_any_<fpcmpcc:code><mode>"
755 [(match_operand:SI 0 "register_operand" "")
756 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
757 (match_operand:VECF_HW 2 "register_operand" ""))]
760 s390_expand_vec_compare_cc (operands[0],
769 ; Compare without generating CC
771 (define_expand "vec_cmp<intcmp:code><VI_HW:mode>"
772 [(set (match_operand:VI_HW 0 "register_operand" "=v")
773 (intcmp:VI_HW (match_operand:VI_HW 1 "register_operand" "v")
774 (match_operand:VI_HW 2 "register_operand" "v")))]
777 s390_expand_vec_compare (operands[0], <intcmp:CODE>, operands[1], operands[2]);
781 (define_expand "vec_cmp<fpcmp:code><mode>"
782 [(set (match_operand:<tointvec> 0 "register_operand" "=v")
783 (fpcmp:<tointvec> (match_operand:VF_HW 1 "register_operand" "v")
784 (match_operand:VF_HW 2 "register_operand" "v")))]
787 s390_expand_vec_compare (operands[0], <fpcmp:CODE>, operands[1], operands[2]);
792 ; Vector count leading zeros
801 ; Vector Galois field multiply sum
803 ; vgfmb, vgfmh, vgfmf
804 (define_insn "vec_gfmsum<mode>"
805 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
806 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
807 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
810 "vgfm<bhfgq>\t%v0,%v1,%v2"
811 [(set_attr "op_type" "VRR")])
813 (define_insn "vec_gfmsum_128"
814 [(set (match_operand:V16QI 0 "register_operand" "=v")
815 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
816 (match_operand:V2DI 2 "register_operand" "v")]
817 UNSPEC_VEC_GFMSUM_128))]
820 [(set_attr "op_type" "VRR")])
822 ; vgfmab, vgfmah, vgfmaf
823 (define_insn "vec_gfmsum_accum<mode>"
824 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
825 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
826 (match_operand:VI_HW_QHS 2 "register_operand" "v")
827 (match_operand:<vec_double> 3 "register_operand" "v")]
828 UNSPEC_VEC_GFMSUM_ACCUM))]
830 "vgfma<bhfgq>\t%v0,%v1,%v2,%v3"
831 [(set_attr "op_type" "VRR")])
833 (define_insn "vec_gfmsum_accum_128"
834 [(set (match_operand:V16QI 0 "register_operand" "=v")
835 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
836 (match_operand:V2DI 2 "register_operand" "v")
837 (match_operand:V16QI 3 "register_operand" "v")]
838 UNSPEC_VEC_GFMSUM_ACCUM_128))]
840 "vgfmag\t%v0,%v1,%v2,%v3"
841 [(set_attr "op_type" "VRR")])
846 ; Vector load positive: vec_abs -> abs
847 ; Vector maximum vec_max -> smax, logical vec_max -> umax
848 ; Vector maximum vec_min -> smin, logical vec_min -> umin
851 ; Vector multiply and add high
853 ; vec_mladd -> vec_vmal
854 ; vmalb, vmalh, vmalf, vmalg
855 (define_insn "vec_vmal<mode>"
856 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
857 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
858 (match_operand:VI_HW_QHS 2 "register_operand" "v")
859 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
862 "vmal<bhfgq><w>\t%v0,%v1,%v2,%v3"
863 [(set_attr "op_type" "VRR")])
865 ; vec_mhadd -> vec_vmah/vec_vmalh
867 ; vmahb; vmahh, vmahf, vmahg
868 (define_insn "vec_vmah<mode>"
869 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
870 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
871 (match_operand:VI_HW_QHS 2 "register_operand" "v")
872 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
875 "vmah<bhfgq>\t%v0,%v1,%v2,%v3"
876 [(set_attr "op_type" "VRR")])
878 ; vmalhb; vmalhh, vmalhf, vmalhg
879 (define_insn "vec_vmalh<mode>"
880 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
881 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
882 (match_operand:VI_HW_QHS 2 "register_operand" "v")
883 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
886 "vmalh<bhfgq>\t%v0,%v1,%v2,%v3"
887 [(set_attr "op_type" "VRR")])
889 ; vec_meadd -> vec_vmae/vec_vmale
891 ; vmaeb; vmaeh, vmaef, vmaeg
892 (define_insn "vec_vmae<mode>"
893 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
894 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
895 (match_operand:VI_HW_QHS 2 "register_operand" "v")
896 (match_operand:<vec_double> 3 "register_operand" "v")]
899 "vmae<bhfgq>\t%v0,%v1,%v2,%v3"
900 [(set_attr "op_type" "VRR")])
902 ; vmaleb; vmaleh, vmalef, vmaleg
903 (define_insn "vec_vmale<mode>"
904 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
905 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
906 (match_operand:VI_HW_QHS 2 "register_operand" "v")
907 (match_operand:<vec_double> 3 "register_operand" "v")]
910 "vmale<bhfgq>\t%v0,%v1,%v2,%v3"
911 [(set_attr "op_type" "VRR")])
913 ; vec_moadd -> vec_vmao/vec_vmalo
915 ; vmaob; vmaoh, vmaof, vmaog
916 (define_insn "vec_vmao<mode>"
917 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
918 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
919 (match_operand:VI_HW_QHS 2 "register_operand" "v")
920 (match_operand:<vec_double> 3 "register_operand" "v")]
923 "vmao<bhfgq>\t%v0,%v1,%v2,%v3"
924 [(set_attr "op_type" "VRR")])
926 ; vmalob; vmaloh, vmalof, vmalog
927 (define_insn "vec_vmalo<mode>"
928 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
929 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
930 (match_operand:VI_HW_QHS 2 "register_operand" "v")
931 (match_operand:<vec_double> 3 "register_operand" "v")]
934 "vmalo<bhfgq>\t%v0,%v1,%v2,%v3"
935 [(set_attr "op_type" "VRR")])
938 ; Vector multiply high
940 ; vec_mulh -> vec_smulh/vec_umulh
943 (define_insn "vec_smulh<mode>"
944 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
945 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
946 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
947 UNSPEC_VEC_SMULT_HI))]
949 "vmh<bhfgq>\t%v0,%v1,%v2"
950 [(set_attr "op_type" "VRR")])
952 ; vmlhb, vmlhh, vmlhf
953 (define_insn "vec_umulh<mode>"
954 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
955 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "%v")
956 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
957 UNSPEC_VEC_UMULT_HI))]
959 "vmlh<bhfgq>\t%v0,%v1,%v2"
960 [(set_attr "op_type" "VRR")])
963 ; Vector multiply low
965 ; vec_mule -> vec_widen_umult_even/vec_widen_smult_even
966 ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd
971 (define_insn "vec_nor<mode>3"
972 [(set (match_operand:VT_HW 0 "register_operand" "=v")
974 (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "%v")
975 (match_operand:VT_HW 2 "register_operand" "v"))))]
978 [(set_attr "op_type" "VRR")])
983 ; Vector population count vec_popcnt -> popcount
984 ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot
986 ; Vector element rotate and insert under mask
988 ; verimb, verimh, verimf, verimg
989 (define_insn "verim<mode>"
990 [(set (match_operand:VI_HW 0 "register_operand" "=v")
991 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "0")
992 (match_operand:VI_HW 2 "register_operand" "v")
993 (match_operand:VI_HW 3 "register_operand" "v")
994 (match_operand:QI 4 "const_int_operand" "C")]
995 UNSPEC_VEC_RL_MASK))]
997 "verim<bhfgq>\t%v0,%v2,%v3,%b4"
998 [(set_attr "op_type" "VRI")])
1003 (define_insn "vec_sll<VI_HW:mode><VI_HW_QHS:mode>"
1004 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1005 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1006 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1010 [(set_attr "op_type" "VRR")])
1013 ; Vector shift left by byte
1015 ; Pattern definition in vector.md, see vec_vslb
1016 (define_expand "vec_slb<mode>"
1017 [(set (match_operand:V_HW 0 "register_operand" "")
1018 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1019 (match_operand:<tointvec> 2 "register_operand" "")]
1023 PUT_MODE (operands[2], V16QImode);
1026 ; Vector shift left double by byte
1028 (define_insn "vec_sld<mode>"
1029 [(set (match_operand:V_HW 0 "register_operand" "=v")
1030 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1031 (match_operand:V_HW 2 "register_operand" "v")
1032 (match_operand:QI 3 "const_int_operand" "C")]
1033 UNSPEC_VEC_SLDBYTE))]
1035 "vsldb\t%v0,%v1,%v2,%b3"
1036 [(set_attr "op_type" "VRI")])
1038 (define_expand "vec_sldw<mode>"
1039 [(set (match_operand:V_HW 0 "register_operand" "")
1040 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1041 (match_operand:V_HW 2 "register_operand" "")
1042 (match_operand:QI 3 "const_int_operand" "")]
1043 UNSPEC_VEC_SLDBYTE))]
1046 operands[3] = GEN_INT (INTVAL (operands[3]) << 2);
1049 ; Vector shift left double by bit
1051 (define_insn "vec_sldb<mode>"
1052 [(set (match_operand:V_HW 0 "register_operand" "=v")
1053 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1054 (match_operand:V_HW 2 "register_operand" "v")
1055 (match_operand:QI 3 "const_int_operand" "C")]
1056 UNSPEC_VEC_SLDBIT))]
1058 "vsld\t%v0,%v1,%v2,%b3"
1059 [(set_attr "op_type" "VRI")])
1061 ; Vector shift right double by bit
1063 (define_insn "vec_srdb<mode>"
1064 [(set (match_operand:V_HW 0 "register_operand" "=v")
1065 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1066 (match_operand:V_HW 2 "register_operand" "v")
1067 (match_operand:QI 3 "const_int_operand" "C")]
1068 UNSPEC_VEC_SRDBIT))]
1070 "vsrd\t%v0,%v1,%v2,%b3"
1071 [(set_attr "op_type" "VRI")])
1073 ; Vector shift right arithmetic
1075 (define_insn "vec_sral<VI_HW:mode><VI_HW_QHS:mode>"
1076 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1077 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1078 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1082 [(set_attr "op_type" "VRR")])
1085 ; Vector shift right arithmetic by byte
1087 (define_insn "vec_srab<mode>"
1088 [(set (match_operand:V_HW 0 "register_operand" "=v")
1089 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1090 (match_operand:<tointvec> 2 "register_operand" "v")]
1093 "vsrab\t%v0,%v1,%v2"
1094 [(set_attr "op_type" "VRR")])
1097 ; Vector shift right logical
1099 (define_insn "vec_srl<VI_HW:mode><VI_HW_QHS:mode>"
1100 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1101 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1102 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1106 [(set_attr "op_type" "VRR")])
1109 ; Vector shift right logical by byte
1111 ; Pattern definition in vector.md, see vec_vsrb
1112 (define_expand "vec_srb<mode>"
1113 [(set (match_operand:V_HW 0 "register_operand" "")
1114 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1115 (match_operand:<tointvec> 2 "register_operand" "")]
1119 PUT_MODE (operands[2], V16QImode);
1124 ; Vector subtract compute borrow indication
1126 ; vscbib, vscbih, vscbif, vscbig, vscbiq
1127 (define_insn "vscbi<bhfgq>_<mode>"
1128 [(set (match_operand:VIT_HW 0 "register_operand" "=v")
1129 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
1130 (match_operand:VIT_HW 2 "register_operand" "v")]
1133 "vscbi<bhfgq>\t%v0,%v1,%v2"
1134 [(set_attr "op_type" "VRR")])
1136 ; Vector subtract with borrow indication
1138 (define_insn "vsbiq"
1139 [(set (match_operand:TI 0 "register_operand" "=v")
1140 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
1141 (match_operand:TI 2 "register_operand" "v")
1142 (match_operand:TI 3 "register_operand" "v")]
1143 UNSPEC_VEC_SUBE_U128))]
1145 "vsbiq\t%v0,%v1,%v2,%v3"
1146 [(set_attr "op_type" "VRR")])
1149 ; Vector subtract with borrow compute and borrow indication
1151 (define_insn "vsbcbiq"
1152 [(set (match_operand:TI 0 "register_operand" "=v")
1153 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
1154 (match_operand:TI 2 "register_operand" "v")
1155 (match_operand:TI 3 "register_operand" "v")]
1156 UNSPEC_VEC_SUBEC_U128))]
1158 "vsbcbiq\t%v0,%v1,%v2,%v3"
1159 [(set_attr "op_type" "VRR")])
1164 ; Sum across DImode parts of the 1st operand and add the rightmost
1165 ; element of 2nd operand
1167 (define_expand "vec_sum2<mode>"
1168 [(set (match_operand:V2DI 0 "register_operand" "")
1169 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "")
1170 (match_operand:VI_HW_HS 2 "register_operand" "")]
1175 (define_insn "vec_sum_u128<mode>"
1176 [(set (match_operand:V2DI 0 "register_operand" "=v")
1177 (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v")
1178 (match_operand:VI_HW_SD 2 "register_operand" "v")]
1181 "vsumq<bhfgq>\t%v0,%v1,%v2"
1182 [(set_attr "op_type" "VRR")])
1185 (define_expand "vec_sum4<mode>"
1186 [(set (match_operand:V4SI 0 "register_operand" "")
1187 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "")
1188 (match_operand:VI_HW_QH 2 "register_operand" "")]
1193 ; Vector test under mask
1195 (define_expand "vec_test_mask_int<mode>"
1196 [(set (reg:CCRAW CC_REGNUM)
1197 (unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
1198 (match_operand:<tointvec> 2 "register_operand" "")]
1199 UNSPEC_VEC_TEST_MASK))
1200 (set (match_operand:SI 0 "register_operand" "")
1201 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1204 (define_insn "*vec_test_mask<mode>"
1205 [(set (reg:CCRAW CC_REGNUM)
1206 (unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
1207 (match_operand:<tointvec> 1 "register_operand" "v")]
1208 UNSPEC_VEC_TEST_MASK))]
1211 [(set_attr "op_type" "VRR")])
1214 ; Vector multiply sum logical
1216 (define_insn "vec_msumv2di"
1217 [(set (match_operand:V16QI 0 "register_operand" "=v")
1218 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
1219 (match_operand:V2DI 2 "register_operand" "v")
1220 (match_operand:V16QI 3 "register_operand" "v")
1221 (match_operand:QI 4 "const_mask_operand" "C")]
1224 "vmslg\t%v0,%v1,%v2,%v3,%4"
1225 [(set_attr "op_type" "VRR")])
1227 (define_insn "vmslg"
1228 [(set (match_operand:TI 0 "register_operand" "=v")
1229 (unspec:TI [(match_operand:V2DI 1 "register_operand" "v")
1230 (match_operand:V2DI 2 "register_operand" "v")
1231 (match_operand:TI 3 "register_operand" "v")
1232 (match_operand:QI 4 "const_mask_operand" "C")]
1235 "vmslg\t%v0,%v1,%v2,%v3,%4"
1236 [(set_attr "op_type" "VRR")])
1239 ; Vector find any element equal
1241 ; vfaeb, vfaeh, vfaef
1242 ; vfaezb, vfaezh, vfaezf
1243 (define_insn "vfae<mode>"
1244 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1245 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1246 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1247 (match_operand:QI 3 "const_mask_operand" "C")]
1251 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1253 if (flags & VSTRING_FLAG_ZS)
1255 flags &= ~VSTRING_FLAG_ZS;
1256 operands[3] = GEN_INT (flags);
1257 return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3";
1259 return "vfae<bhfgq>\t%v0,%v1,%v2,%b3";
1261 [(set_attr "op_type" "VRR")])
1263 ; vfaebs, vfaehs, vfaefs
1264 ; vfaezbs, vfaezhs, vfaezfs
1265 (define_insn "*vfaes<mode>"
1266 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1267 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1268 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1269 (match_operand:QI 3 "const_mask_operand" "C")]
1271 (set (reg:CCRAW CC_REGNUM)
1272 (unspec:CCRAW [(match_dup 1)
1275 UNSPEC_VEC_VFAECC))]
1278 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1280 if (flags & VSTRING_FLAG_ZS)
1282 flags &= ~VSTRING_FLAG_ZS;
1283 operands[3] = GEN_INT (flags);
1284 return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3";
1286 return "vfae<bhfgq>s\t%v0,%v1,%v2,%b3";
1288 [(set_attr "op_type" "VRR")])
1290 (define_expand "vfaez<mode>"
1291 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1292 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1293 (match_operand:VI_HW_QHS 2 "register_operand" "")
1294 (match_operand:QI 3 "const_mask_operand" "")]
1298 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS);
1301 (define_expand "vfaes<mode>"
1303 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1304 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1305 (match_operand:VI_HW_QHS 2 "register_operand" "")
1306 (match_operand:QI 3 "const_mask_operand" "")]
1308 (set (reg:CCRAW CC_REGNUM)
1309 (unspec:CCRAW [(match_dup 1)
1312 UNSPEC_VEC_VFAECC))])
1313 (set (match_operand:SI 4 "memory_operand" "")
1314 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1317 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS);
1320 (define_expand "vfaezs<mode>"
1322 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1323 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1324 (match_operand:VI_HW_QHS 2 "register_operand" "")
1325 (match_operand:SI 3 "const_mask_operand" "")]
1327 (set (reg:CCRAW CC_REGNUM)
1328 (unspec:CCRAW [(match_dup 1)
1331 UNSPEC_VEC_VFAECC))])
1332 (set (match_operand:SI 4 "memory_operand" "")
1333 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1336 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1340 ; Vector find element equal
1342 ; vfeebs, vfeehs, vfeefs
1343 ; vfeezbs, vfeezhs, vfeezfs
1344 (define_insn "*vfees<mode>"
1345 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1346 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1347 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1348 (match_operand:QI 3 "const_mask_operand" "C")]
1350 (set (reg:CCRAW CC_REGNUM)
1351 (unspec:CCRAW [(match_dup 1)
1354 UNSPEC_VEC_VFEECC))]
1357 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1359 gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS)));
1360 flags &= ~VSTRING_FLAG_CS;
1362 if (flags == VSTRING_FLAG_ZS)
1363 return "vfeez<bhfgq>s\t%v0,%v1,%v2";
1364 return "vfee<bhfgq>s\t%v0,%v1,%v2,%b3";
1366 [(set_attr "op_type" "VRR")])
1368 ; vfeeb, vfeeh, vfeef
1369 (define_insn "vfee<mode>"
1370 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1371 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1372 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1376 "vfee<bhfgq>\t%v0,%v1,%v2,0"
1377 [(set_attr "op_type" "VRR")])
1379 ; vfeezb, vfeezh, vfeezf
1380 (define_insn "vfeez<mode>"
1381 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1382 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1383 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1384 (const_int VSTRING_FLAG_ZS)]
1387 "vfeez<bhfgq>s\t%v0,%v1,%v2,2"
1388 [(set_attr "op_type" "VRR")])
1390 (define_expand "vfees<mode>"
1392 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1393 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1394 (match_operand:VI_HW_QHS 2 "register_operand" "")
1395 (const_int VSTRING_FLAG_CS)]
1397 (set (reg:CCRAW CC_REGNUM)
1398 (unspec:CCRAW [(match_dup 1)
1400 (const_int VSTRING_FLAG_CS)]
1401 UNSPEC_VEC_VFEECC))])
1402 (set (match_operand:SI 3 "memory_operand" "")
1403 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1406 (define_expand "vfeezs<mode>"
1408 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1409 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1410 (match_operand:VI_HW_QHS 2 "register_operand" "")
1413 (set (reg:CCRAW CC_REGNUM)
1414 (unspec:CCRAW [(match_dup 1)
1417 UNSPEC_VEC_VFEECC))])
1418 (set (match_operand:SI 3 "memory_operand" "")
1419 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1422 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1425 ; Vector find element not equal
1427 ; vfeneb, vfeneh, vfenef
1428 (define_insn "vfene<mode>"
1429 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1430 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1431 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1435 "vfene<bhfgq>\t%v0,%v1,%v2,0"
1436 [(set_attr "op_type" "VRR")])
1438 ; vec_vfenes can be found in vector.md since it is used for strlen
1440 ; vfenezb, vfenezh, vfenezf
1441 (define_insn "vfenez<mode>"
1442 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1443 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1444 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1445 (const_int VSTRING_FLAG_ZS)]
1448 "vfenez<bhfgq>\t%v0,%v1,%v2"
1449 [(set_attr "op_type" "VRR")])
1451 (define_expand "vfenes<mode>"
1453 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1454 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1455 (match_operand:VI_HW_QHS 2 "register_operand" "")
1456 (const_int VSTRING_FLAG_CS)]
1458 (set (reg:CCRAW CC_REGNUM)
1459 (unspec:CCRAW [(match_dup 1)
1461 (const_int VSTRING_FLAG_CS)]
1462 UNSPEC_VEC_VFENECC))])
1463 (set (match_operand:SI 3 "memory_operand" "")
1464 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1467 (define_expand "vfenezs<mode>"
1469 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1470 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1471 (match_operand:VI_HW_QHS 2 "register_operand" "")
1474 (set (reg:CCRAW CC_REGNUM)
1475 (unspec:CCRAW [(match_dup 1)
1478 UNSPEC_VEC_VFENECC))])
1479 (set (match_operand:SI 3 "memory_operand" "")
1480 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1483 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1486 ; Vector isolate string
1488 ; vistrb, vistrh, vistrf
1489 (define_insn "vistr<mode>"
1490 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1491 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1494 "vistr<bhfgq>\t%v0,%v1"
1495 [(set_attr "op_type" "VRR")])
1497 ; vistrbs, vistrhs, vistrfs
1498 (define_insn "*vistrs<mode>"
1499 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1500 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1502 (set (reg:CCRAW CC_REGNUM)
1503 (unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))]
1505 "vistr<bhfgq>s\t%v0,%v1"
1506 [(set_attr "op_type" "VRR")])
1508 (define_expand "vistrs<mode>"
1510 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1511 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")]
1513 (set (reg:CCRAW CC_REGNUM)
1514 (unspec:CCRAW [(match_dup 1)]
1515 UNSPEC_VEC_VISTRCC))])
1516 (set (match_operand:SI 2 "memory_operand" "")
1517 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1521 ; Vector compare range
1523 ; vstrcb, vstrch, vstrcf
1524 ; vstrczb, vstrczh, vstrczf
1525 (define_insn "vstrc<mode>"
1526 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1527 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1528 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1529 (match_operand:VI_HW_QHS 3 "register_operand" "v")
1530 (match_operand:QI 4 "const_mask_operand" "C")]
1534 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1536 if (flags & VSTRING_FLAG_ZS)
1538 flags &= ~VSTRING_FLAG_ZS;
1539 operands[4] = GEN_INT (flags);
1540 return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1542 return "vstrc<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1544 [(set_attr "op_type" "VRR")])
1546 ; vstrcbs, vstrchs, vstrcfs
1547 ; vstrczbs, vstrczhs, vstrczfs
1548 (define_insn "*vstrcs<mode>"
1549 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1550 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1551 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1552 (match_operand:VI_HW_QHS 3 "register_operand" "v")
1553 (match_operand:QI 4 "const_mask_operand" "C")]
1555 (set (reg:CCRAW CC_REGNUM)
1556 (unspec:CCRAW [(match_dup 1)
1560 UNSPEC_VEC_VSTRCCC))]
1563 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1565 if (flags & VSTRING_FLAG_ZS)
1567 flags &= ~VSTRING_FLAG_ZS;
1568 operands[4] = GEN_INT (flags);
1569 return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1571 return "vstrc<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1573 [(set_attr "op_type" "VRR")])
1575 (define_expand "vstrcz<mode>"
1576 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1577 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1578 (match_operand:VI_HW_QHS 2 "register_operand" "")
1579 (match_operand:VI_HW_QHS 3 "register_operand" "")
1580 (match_operand:QI 4 "const_mask_operand" "")]
1584 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS);
1587 (define_expand "vstrcs<mode>"
1589 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1590 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1591 (match_operand:VI_HW_QHS 2 "register_operand" "")
1592 (match_operand:VI_HW_QHS 3 "register_operand" "")
1593 (match_operand:QI 4 "const_mask_operand" "")]
1595 (set (reg:CCRAW CC_REGNUM)
1596 (unspec:CCRAW [(match_dup 1)
1600 UNSPEC_VEC_VSTRCCC))])
1601 (set (match_operand:SI 5 "memory_operand" "")
1602 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1605 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS);
1608 (define_expand "vstrczs<mode>"
1610 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1611 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1612 (match_operand:VI_HW_QHS 2 "register_operand" "")
1613 (match_operand:VI_HW_QHS 3 "register_operand" "")
1614 (match_operand:QI 4 "const_mask_operand" "")]
1616 (set (reg:CCRAW CC_REGNUM)
1617 (unspec:CCRAW [(match_dup 1)
1621 UNSPEC_VEC_VSTRCCC))])
1622 (set (match_operand:SI 5 "memory_operand" "")
1623 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1626 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1629 (define_insn "vcdgb"
1630 [(set (match_operand:V2DF 0 "register_operand" "=v")
1631 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v")
1632 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression
1633 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1635 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1636 "vcdgb\t%v0,%v1,%b2,%b3"
1637 [(set_attr "op_type" "VRR")])
1640 ; The result needs to be multiplied with 2**-op2
1641 (define_expand "vec_ctd_s64"
1642 [(set (match_operand:V2DF 0 "register_operand" "")
1643 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1644 (const_int VEC_NOINEXACT)
1645 (const_int VEC_RND_CURRENT)]
1647 (use (match_operand:QI 2 "const_int_operand" ""))
1648 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1654 real_2expN (&f, -INTVAL (operands[2]), DFmode);
1655 c = const_double_from_real_value (f, DFmode);
1657 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1658 operands[3] = force_reg (V2DFmode, operands[3]);
1661 (define_insn "vcdlgb"
1662 [(set (match_operand:V2DF 0 "register_operand" "=v")
1663 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v")
1664 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression
1665 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1666 UNSPEC_VEC_VCDLGB))]
1667 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1668 "vcdlgb\t%v0,%v1,%b2,%b3"
1669 [(set_attr "op_type" "VRR")])
1671 ; The result needs to be multiplied with 2**-op2
1672 (define_expand "vec_ctd_u64"
1673 [(set (match_operand:V2DF 0 "register_operand" "")
1674 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1675 (const_int VEC_NOINEXACT)
1676 (const_int VEC_RND_CURRENT)]
1678 (use (match_operand:QI 2 "const_int_operand" ""))
1679 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1685 real_2expN (&f, -INTVAL (operands[2]), DFmode);
1686 c = const_double_from_real_value (f, DFmode);
1688 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1689 operands[3] = force_reg (V2DFmode, operands[3]);
1692 (define_insn "vcgdb"
1693 [(set (match_operand:V2DI 0 "register_operand" "=v")
1694 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v")
1695 (match_operand:QI 2 "const_mask_operand" "C")
1696 (match_operand:QI 3 "const_mask_operand" "C")]
1698 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1699 "vcgdb\t%v0,%v1,%b2,%b3"
1700 [(set_attr "op_type" "VRR")])
1702 ; The input needs to be multiplied with 2**op2
1703 (define_expand "vec_ctsl"
1704 [(use (match_operand:QI 2 "const_int_operand" ""))
1705 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1707 (set (match_operand:V2DI 0 "register_operand" "")
1708 (unspec:V2DI [(match_dup 4)
1709 (const_int VEC_NOINEXACT)
1710 (const_int VEC_RND_CURRENT)]
1717 real_2expN (&f, INTVAL (operands[2]), DFmode);
1718 c = const_double_from_real_value (f, DFmode);
1720 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1721 operands[3] = force_reg (V2DFmode, operands[3]);
1722 operands[4] = gen_reg_rtx (V2DFmode);
1725 (define_insn "vclgdb"
1726 [(set (match_operand:V2DI 0 "register_operand" "=v")
1727 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v")
1728 (match_operand:QI 2 "const_mask_operand" "C")
1729 (match_operand:QI 3 "const_mask_operand" "C")]
1730 UNSPEC_VEC_VCLGDB))]
1731 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1732 "vclgdb\t%v0,%v1,%b2,%b3"
1733 [(set_attr "op_type" "VRR")])
1735 ; The input needs to be multiplied with 2**op2
1736 (define_expand "vec_ctul"
1737 [(use (match_operand:QI 2 "const_int_operand" ""))
1738 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1740 (set (match_operand:V2DI 0 "register_operand" "")
1741 (unspec:V2DI [(match_dup 4)
1742 (const_int VEC_NOINEXACT)
1743 (const_int VEC_RND_CURRENT)]
1744 UNSPEC_VEC_VCLGDB))]
1750 real_2expN (&f, INTVAL (operands[2]), DFmode);
1751 c = const_double_from_real_value (f, DFmode);
1753 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1754 operands[3] = force_reg (V2DFmode, operands[3]);
1755 operands[4] = gen_reg_rtx (V2DFmode);
1758 ; Vector load fp integer - IEEE inexact exception is suppressed
1759 ; vfisb, vfidb, wfisb, wfidb, wfixb
1760 (define_insn "vec_fpint<mode>"
1761 [(set (match_operand:VFT 0 "register_operand" "=v")
1762 (unspec:VFT [(match_operand:VFT 1 "register_operand" "v")
1763 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression control
1764 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1767 "<vw>fi<sdx>b\t%v0,%v1,%b2,%b3"
1768 [(set_attr "op_type" "VRR")])
1771 ; Vector load lengthened - V4SF -> V2DF
1773 (define_insn "vflls"
1774 [(set (match_operand:V2DF 0 "register_operand" "=v")
1775 (unspec:V2DF [(match_operand:V4SF 1 "register_operand" "v")]
1779 [(set_attr "op_type" "VRR")])
1781 (define_expand "vec_ld2f"
1782 [; Initialize a vector to all zeroes. FIXME: This should not be
1783 ; necessary since all elements of the vector will be set anyway.
1784 ; This is just to make it explicit to the data flow framework.
1785 (set (match_dup 2) (match_dup 3))
1786 (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "")
1790 (set (match_dup 2) (unspec:V4SF [(match_dup 4)
1794 (set (match_operand:V2DF 0 "register_operand" "")
1795 (unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VFLL))]
1798 operands[2] = gen_reg_rtx (V4SFmode);
1799 operands[3] = CONST0_RTX (V4SFmode);
1800 operands[4] = adjust_address (operands[1], SFmode, 4);
1804 ; Vector load rounded - V2DF -> V4SF
1806 (define_insn "vflrd"
1807 [(set (match_operand:V4SF 0 "register_operand" "=v")
1808 (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "v")
1809 (match_operand:QI 2 "const_mask_operand" "C")
1810 (match_operand:QI 3 "const_mask_operand" "C")]
1813 "vledb\t%v0,%v1,%b2,%b3"
1814 [(set_attr "op_type" "VRR")])
1816 (define_expand "vec_st2f"
1818 (unspec:V4SF [(match_operand:V2DF 0 "register_operand" "")
1819 (const_int VEC_INEXACT)
1820 (const_int VEC_RND_CURRENT)]
1822 (set (match_operand:SF 1 "memory_operand" "")
1823 (unspec:SF [(match_dup 2) (const_int 0)] UNSPEC_VEC_EXTRACT))
1825 (unspec:SF [(match_dup 2) (const_int 2)] UNSPEC_VEC_EXTRACT))]
1828 operands[2] = gen_reg_rtx (V4SFmode);
1829 operands[3] = adjust_address (operands[1], SFmode, 4);
1833 ; Vector square root fp vec_sqrt -> sqrt rtx standard name
1835 ;; Vector FP test data class immediate
1837 ; vec_all_nan, vec_all_numeric, vec_any_nan, vec_any_numeric
1838 ; These ignore the vector result and only want CC stored to an int
1842 (define_insn "*vftci<mode>_cconly"
1843 [(set (reg:CCRAW CC_REGNUM)
1844 (unspec:CCRAW [(match_operand:VECF_HW 1 "register_operand")
1845 (match_operand:HI 2 "const_int_operand")]
1846 UNSPEC_VEC_VFTCICC))
1847 (clobber (match_scratch:<tointvec> 0))]
1848 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1849 "vftci<sdx>b\t%v0,%v1,%x2"
1850 [(set_attr "op_type" "VRR")])
1852 (define_expand "vftci<mode>_intcconly"
1854 [(set (reg:CCRAW CC_REGNUM)
1855 (unspec:CCRAW [(match_operand:VECF_HW 0 "register_operand")
1856 (match_operand:HI 1 "const_int_operand")]
1857 UNSPEC_VEC_VFTCICC))
1858 (clobber (scratch:<tointvec>))])
1859 (set (match_operand:SI 2 "register_operand" "")
1860 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1861 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")")
1863 ; vec_fp_test_data_class wants the result vector and the CC stored to
1867 (define_insn "*vftci<mode>"
1868 [(set (match_operand:VECF_HW 0 "register_operand" "=v")
1869 (unspec:VECF_HW [(match_operand:VECF_HW 1 "register_operand" "v")
1870 (match_operand:HI 2 "const_int_operand" "J")]
1872 (set (reg:CCRAW CC_REGNUM)
1873 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))]
1874 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1875 "vftci<sdx>b\t%v0,%v1,%x2"
1876 [(set_attr "op_type" "VRR")])
1878 (define_expand "vftci<mode>_intcc"
1880 [(set (match_operand:VECF_HW 0 "register_operand")
1881 (unspec:VECF_HW [(match_operand:VECF_HW 1 "register_operand")
1882 (match_operand:HI 2 "const_int_operand")]
1884 (set (reg:CCRAW CC_REGNUM)
1885 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))])
1886 (set (match_operand:SI 3 "memory_operand" "")
1887 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1888 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")")
1894 ; All comparisons which produce a CC need fully populated (VI_HW)
1895 ; vector arguments. Otherwise the any/all CCs would be just bogus.
1897 (define_insn "*vec_cmp<VICMP:insn_cmp><VI_HW:mode>_cconly"
1898 [(set (reg:VICMP CC_REGNUM)
1899 (compare:VICMP (match_operand:VI_HW 0 "register_operand" "v")
1900 (match_operand:VI_HW 1 "register_operand" "v")))
1901 (clobber (match_scratch:VI_HW 2 "=v"))]
1903 "vc<VICMP:insn_cmp><VI_HW:bhfgq>s\t%v2,%v0,%v1"
1904 [(set_attr "op_type" "VRR")])
1906 ; FIXME: The following 2x3 definitions should be merged into 2 with
1907 ; VICMP like above but I could not find a way to set the comparison
1908 ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the
1909 ; other way around - setting the mode depending on the code
1911 (define_expand "vec_cmpeq<VI_HW:mode>_cc"
1913 [(set (reg:CCVEQ CC_REGNUM)
1914 (compare:CCVEQ (match_operand:VI_HW 1 "register_operand" "v")
1915 (match_operand:VI_HW 2 "register_operand" "v")))
1916 (set (match_operand:VI_HW 0 "register_operand" "=v")
1917 (eq:VI_HW (match_dup 1) (match_dup 2)))])
1918 (set (match_operand:SI 3 "memory_operand" "")
1919 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
1922 (define_expand "vec_cmph<VI_HW:mode>_cc"
1924 [(set (reg:CCVIH CC_REGNUM)
1925 (compare:CCVIH (match_operand:VI_HW 1 "register_operand" "v")
1926 (match_operand:VI_HW 2 "register_operand" "v")))
1927 (set (match_operand:VI_HW 0 "register_operand" "=v")
1928 (gt:VI_HW (match_dup 1) (match_dup 2)))])
1929 (set (match_operand:SI 3 "memory_operand" "")
1930 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
1933 (define_expand "vec_cmphl<VI_HW:mode>_cc"
1935 [(set (reg:CCVIHU CC_REGNUM)
1936 (compare:CCVIHU (match_operand:VI_HW 1 "register_operand" "v")
1937 (match_operand:VI_HW 2 "register_operand" "v")))
1938 (set (match_operand:VI_HW 0 "register_operand" "=v")
1939 (gtu:VI_HW (match_dup 1) (match_dup 2)))])
1940 (set (match_operand:SI 3 "memory_operand" "")
1941 (unspec:SI [(reg:CCVIHU CC_REGNUM)] UNSPEC_CC_TO_INT))]
1945 (define_insn "*vec_cmpeq<VI_HW:mode>_cc"
1946 [(set (reg:CCVEQ CC_REGNUM)
1947 (compare:CCVEQ (match_operand:VI_HW 0 "register_operand" "v")
1948 (match_operand:VI_HW 1 "register_operand" "v")))
1949 (set (match_operand:VI_HW 2 "register_operand" "=v")
1950 (eq:VI_HW (match_dup 0) (match_dup 1)))]
1952 "vceq<VI_HW:bhfgq>s\t%v2,%v0,%v1"
1953 [(set_attr "op_type" "VRR")])
1955 (define_insn "*vec_cmph<VI_HW:mode>_cc"
1956 [(set (reg:CCVIH CC_REGNUM)
1957 (compare:CCVIH (match_operand:VI_HW 0 "register_operand" "v")
1958 (match_operand:VI_HW 1 "register_operand" "v")))
1959 (set (match_operand:VI_HW 2 "register_operand" "=v")
1960 (gt:VI_HW (match_dup 0) (match_dup 1)))]
1962 "vch<VI_HW:bhfgq>s\t%v2,%v0,%v1"
1963 [(set_attr "op_type" "VRR")])
1965 (define_insn "*vec_cmphl<VI_HW:mode>_cc"
1966 [(set (reg:CCVIHU CC_REGNUM)
1967 (compare:CCVIHU (match_operand:VI_HW 0 "register_operand" "v")
1968 (match_operand:VI_HW 1 "register_operand" "v")))
1969 (set (match_operand:VI_HW 2 "register_operand" "=v")
1970 (gtu:VI_HW (match_dup 0) (match_dup 1)))]
1972 "vchl<VI_HW:bhfgq>s\t%v2,%v0,%v1"
1973 [(set_attr "op_type" "VRR")])
1976 ;; Floating point compares
1979 ; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs
1980 (define_insn "*vec_cmp<insn_cmp><mode>_cconly"
1981 [(set (reg:VFCMP CC_REGNUM)
1982 (compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
1983 (match_operand:VF_HW 1 "register_operand" "v")))
1984 (clobber (match_scratch:<tointvec> 2 "=v"))]
1986 "<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1"
1987 [(set_attr "op_type" "VRR")])
1989 ; FIXME: Merge the following 2x3 patterns with VFCMP
1990 (define_expand "vec_cmpeq<mode>_cc"
1992 [(set (reg:CCVEQ CC_REGNUM)
1993 (compare:CCVEQ (match_operand:VF_HW 1 "register_operand" "v")
1994 (match_operand:VF_HW 2 "register_operand" "v")))
1995 (set (match_operand:<tointvec> 0 "register_operand" "=v")
1996 (eq:<tointvec> (match_dup 1) (match_dup 2)))])
1997 (set (match_operand:SI 3 "memory_operand" "")
1998 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2001 (define_expand "vec_cmph<mode>_cc"
2003 [(set (reg:CCVFH CC_REGNUM)
2004 (compare:CCVFH (match_operand:VF_HW 1 "register_operand" "v")
2005 (match_operand:VF_HW 2 "register_operand" "v")))
2006 (set (match_operand:<tointvec> 0 "register_operand" "=v")
2007 (gt:<tointvec> (match_dup 1) (match_dup 2)))])
2008 (set (match_operand:SI 3 "memory_operand" "")
2009 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2012 (define_expand "vec_cmphe<mode>_cc"
2014 [(set (reg:CCVFHE CC_REGNUM)
2015 (compare:CCVFHE (match_operand:VF_HW 1 "register_operand" "v")
2016 (match_operand:VF_HW 2 "register_operand" "v")))
2017 (set (match_operand:<tointvec> 0 "register_operand" "=v")
2018 (ge:<tointvec> (match_dup 1) (match_dup 2)))])
2019 (set (match_operand:SI 3 "memory_operand" "")
2020 (unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]
2023 ; These 3 cannot be merged as the insn defintion above since it also
2024 ; requires to rewrite the RTL equality operator that the same time as
2027 ; vfcesbs, vfcedbs, wfcexbs
2028 (define_insn "*vec_cmpeq<mode>_cc"
2029 [(set (reg:CCVEQ CC_REGNUM)
2030 (compare:CCVEQ (match_operand:VF_HW 0 "register_operand" "v")
2031 (match_operand:VF_HW 1 "register_operand" "v")))
2032 (set (match_operand:<tointvec> 2 "register_operand" "=v")
2033 (eq:<tointvec> (match_dup 0) (match_dup 1)))]
2035 "<vw>fce<sdx>bs\t%v2,%v0,%v1"
2036 [(set_attr "op_type" "VRR")])
2038 ; vfchsbs, vfchdbs, wfchxbs
2039 (define_insn "*vec_cmph<mode>_cc"
2040 [(set (reg:CCVFH CC_REGNUM)
2041 (compare:CCVFH (match_operand:VF_HW 0 "register_operand" "v")
2042 (match_operand:VF_HW 1 "register_operand" "v")))
2043 (set (match_operand:<tointvec> 2 "register_operand" "=v")
2044 (gt:<tointvec> (match_dup 0) (match_dup 1)))]
2046 "<vw>fch<sdx>bs\t%v2,%v0,%v1"
2047 [(set_attr "op_type" "VRR")])
2049 ; vfchesbs, vfchedbs, wfchexbs
2050 (define_insn "*vec_cmphe<mode>_cc"
2051 [(set (reg:CCVFHE CC_REGNUM)
2052 (compare:CCVFHE (match_operand:VF_HW 0 "register_operand" "v")
2053 (match_operand:VF_HW 1 "register_operand" "v")))
2054 (set (match_operand:<tointvec> 2 "register_operand" "=v")
2055 (ge:<tointvec> (match_dup 0) (match_dup 1)))]
2057 "<vw>fche<sdx>bs\t%v2,%v0,%v1"
2058 [(set_attr "op_type" "VRR")])
2060 (define_expand "vec_double_s64"
2061 [(set (match_operand:V2DF 0 "register_operand")
2062 (unspec:V2DF [(match_operand:V2DI 1 "register_operand")
2063 (const_int VEC_INEXACT)
2064 (const_int VEC_RND_CURRENT)]
2068 (define_expand "vec_double_u64"
2069 [(set (match_operand:V2DF 0 "register_operand")
2070 (unspec:V2DF [(match_operand:V2DI 1 "register_operand")
2071 (const_int VEC_INEXACT)
2072 (const_int VEC_RND_CURRENT)]
2073 UNSPEC_VEC_VCDLGB))]
2077 (define_insn "vfmin<mode>"
2078 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2079 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "%v")
2080 (match_operand:VF_HW 2 "register_operand" "v")
2081 (match_operand:QI 3 "const_mask_operand" "C")]
2084 "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3"
2085 [(set_attr "op_type" "VRR")])
2087 (define_insn "vfmax<mode>"
2088 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2089 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "%v")
2090 (match_operand:VF_HW 2 "register_operand" "v")
2091 (match_operand:QI 3 "const_mask_operand" "C")]
2094 "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3"
2095 [(set_attr "op_type" "VRR")])
2097 ; The element reversal builtins introduced with arch13 have been made
2098 ; available also for older CPUs down to z13.
2099 (define_expand "eltswap<mode>"
2100 [(set (match_operand:VEC_HW 0 "nonimmediate_operand" "")
2101 (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "")]
2102 UNSPEC_VEC_ELTSWAP))]
2105 ; The byte element reversal is implemented as 128 bit byte swap.
2106 ; Alternatively this could be emitted as bswap:V1TI but the required
2107 ; subregs appear to confuse combine.
2108 (define_insn "*eltswapv16qi"
2109 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=v,v,R")
2110 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "v,R,v")]
2111 UNSPEC_VEC_ELTSWAP))]
2117 [(set_attr "op_type" "*,VRX,VRX")])
2119 ; vlerh, vlerf, vlerg, vsterh, vsterf, vsterg
2120 (define_insn "*eltswap<mode>"
2121 [(set (match_operand:V_HW_HSD 0 "nonimmediate_operand" "=v,v,R")
2122 (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "nonimmediate_operand" "v,R,v")]
2123 UNSPEC_VEC_ELTSWAP))]
2127 vler<bhfgq>\t%v0,%v1
2128 vster<bhfgq>\t%v1,%v0"
2129 [(set_attr "op_type" "*,VRX,VRX")])
2131 ; arch13 has instructions for doing element reversal from mem to reg
2132 ; or the other way around. For reg to reg or on pre arch13 machines
2133 ; we have to emulate it with vector permute.
2134 (define_insn_and_split "*eltswap<mode>_emu"
2135 [(set (match_operand:VEC_HW 0 "nonimmediate_operand" "=vR")
2136 (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "vR")]
2137 UNSPEC_VEC_ELTSWAP))]
2138 "TARGET_VX && can_create_pseudo_p ()"
2140 "&& ((!memory_operand (operands[0], <MODE>mode)
2141 && !memory_operand (operands[1], <MODE>mode))
2144 (unspec:V16QI [(match_dup 4)
2148 (set (match_dup 0) (subreg:VEC_HW (match_dup 3) 0))]
2150 static char p[4][16] =
2151 { { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, /* Q */
2152 { 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1 }, /* H */
2153 { 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3 }, /* S */
2154 { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 } }; /* D */
2156 rtx perm_rtx[16], constv;
2158 switch (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)))
2160 case 1: perm = p[0]; break;
2161 case 2: perm = p[1]; break;
2162 case 4: perm = p[2]; break;
2163 case 8: perm = p[3]; break;
2164 default: gcc_unreachable ();
2167 for (int i = 0; i < 16; i++)
2168 perm_rtx[i] = GEN_INT (perm[i]);
2170 operands[1] = force_reg (<MODE>mode, operands[1]);
2171 operands[2] = gen_reg_rtx (V16QImode);
2172 operands[3] = gen_reg_rtx (V16QImode);
2173 operands[4] = simplify_gen_subreg (V16QImode, operands[1], <MODE>mode, 0);
2174 constv = force_const_mem (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm_rtx)));
2175 emit_move_insn (operands[2], constv);
2178 ; vec_insert (__builtin_bswap32 (*a), b, 1) set-element-bswap-2.c
2179 ; b[1] = __builtin_bswap32 (*a) set-element-bswap-3.c
2180 ; vlebrh, vlebrf, vlebrg
2181 (define_insn "*vec_set_bswap_elem<mode>"
2182 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
2183 (unspec:V_HW_HSD [(bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand" "R"))
2184 (match_operand:SI 2 "const_int_operand" "C")
2185 (match_operand:V_HW_HSD 3 "register_operand" "0")]
2187 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2188 "vlebr<bhfgq>\t%v0,%1,%2"
2189 [(set_attr "op_type" "VRX")])
2191 ; vec_revb (vec_insert (*a, vec_revb (b), 1)) set-element-bswap-1.c
2192 ; vlebrh, vlebrf, vlebrg
2193 (define_insn "*vec_set_bswap_vec<mode>"
2194 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
2196 (unspec:V_HW_HSD [(match_operand:<non_vec> 1 "memory_operand" "R")
2197 (match_operand:SI 2 "const_int_operand" "C")
2198 (bswap:V_HW_HSD (match_operand:V_HW_HSD 3 "register_operand" "0"))]
2200 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2201 "vlebr<bhfgq>\t%v0,%1,%2"
2202 [(set_attr "op_type" "VRX")])
2204 ; *a = vec_extract (vec_revb (b), 1); get-element-bswap-3.c
2205 ; *a = vec_revb (b)[1]; get-element-bswap-4.c
2206 ; vstebrh, vstebrf, vstebrg
2207 (define_insn "*vec_extract_bswap_vec<mode>"
2208 [(set (match_operand:<non_vec> 0 "memory_operand" "=R")
2209 (unspec:<non_vec> [(bswap:V_HW_HSD (match_operand:V_HW_HSD 1 "register_operand" "v"))
2210 (match_operand:SI 2 "const_int_operand" "C")]
2211 UNSPEC_VEC_EXTRACT))]
2212 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2213 "vstebr<bhfgq>\t%v1,%0,%2"
2214 [(set_attr "op_type" "VRX")])
2216 ; *a = __builtin_bswap32 (vec_extract (b, 1)); get-element-bswap-1.c
2217 ; *a = __builtin_bswap32 (b[1]); get-element-bswap-2.c
2218 ; vstebrh, vstebrf, vstebrg
2219 (define_insn "*vec_extract_bswap_elem<mode>"
2220 [(set (match_operand:<non_vec> 0 "memory_operand" "=R")
2222 (unspec:<non_vec> [(match_operand:V_HW_HSD 1 "register_operand" "v")
2223 (match_operand:SI 2 "const_int_operand" "C")]
2224 UNSPEC_VEC_EXTRACT)))]
2225 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2226 "vstebr<bhfgq>\t%v1,%0,%2"
2227 [(set_attr "op_type" "VRX")])