1 ;; Machine description for AArch64 SVE.
2 ;; Copyright (C) 2009-2016 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Note on the handling of big-endian SVE
22 ;; --------------------------------------
24 ;; On big-endian systems, Advanced SIMD mov<mode> patterns act in the
25 ;; same way as movdi or movti would: the first byte of memory goes
26 ;; into the most significant byte of the register and the last byte
27 ;; of memory goes into the least significant byte of the register.
28 ;; This is the most natural ordering for Advanced SIMD and matches
29 ;; the ABI layout for 64-bit and 128-bit vector types.
31 ;; As a result, the order of bytes within the register is what GCC
32 ;; expects for a big-endian target, and subreg offsets therefore work
33 ;; as expected, with the first element in memory having subreg offset 0
34 ;; and the last element in memory having the subreg offset associated
35 ;; with a big-endian lowpart. However, this ordering also means that
36 ;; GCC's lane numbering does not match the architecture's numbering:
37 ;; GCC always treats the element at the lowest address in memory
38 ;; (subreg offset 0) as element 0, while the architecture treats
39 ;; the least significant end of the register as element 0.
41 ;; The situation for SVE is different. We want the layout of the
42 ;; SVE register to be same for mov<mode> as it is for maskload<mode>:
43 ;; logically, a mov<mode> load must be indistinguishable from a
44 ;; maskload<mode> whose mask is all true. We therefore need the
45 ;; register layout to match LD1 rather than LDR. The ABI layout of
46 ;; SVE types also matches LD1 byte ordering rather than LDR byte ordering.
48 ;; As a result, the architecture lane numbering matches GCC's lane
49 ;; numbering, with element 0 always being the first in memory.
52 ;; - Applying a subreg offset to a register does not give the element
53 ;; that GCC expects: the first element in memory has the subreg offset
54 ;; associated with a big-endian lowpart while the last element in memory
55 ;; has subreg offset 0. We handle this via TARGET_CAN_CHANGE_MODE_CLASS.
57 ;; - We cannot use LDR and STR for spill slots that might be accessed
58 ;; via subregs, since although the elements have the order GCC expects,
59 ;; the order of the bytes within the elements is different. We instead
60 ;; access spill slots via LD1 and ST1, using secondary reloads to
61 ;; reserve a predicate register.
65 (define_expand "mov<mode>"
66 [(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
67 (match_operand:SVE_ALL 1 "general_operand"))]
70 /* Use the predicated load and store patterns where possible.
71 This is required for big-endian targets (see the comment at the
72 head of the file) and increases the addressing choices for
74 if ((MEM_P (operands[0]) || MEM_P (operands[1]))
75 && can_create_pseudo_p ())
77 aarch64_expand_sve_mem_move (operands[0], operands[1], <VPRED>mode);
81 if (CONSTANT_P (operands[1]))
83 aarch64_expand_mov_immediate (operands[0], operands[1],
84 gen_vec_duplicate<mode>);
88 /* Optimize subregs on big-endian targets: we can use REV[BHW]
89 instead of going through memory. */
91 && aarch64_maybe_expand_sve_subreg_move (operands[0], operands[1]))
96 ;; A pattern for optimizing SUBREGs that have a reinterpreting effect
97 ;; on big-endian targets; see aarch64_maybe_expand_sve_subreg_move
98 ;; for details. We use a special predicate for operand 2 to reduce
99 ;; the number of patterns.
100 (define_insn_and_split "*aarch64_sve_mov<mode>_subreg_be"
101 [(set (match_operand:SVE_ALL 0 "aarch64_sve_nonimmediate_operand" "=w")
103 [(match_operand:VNx16BI 1 "register_operand" "Upl")
104 (match_operand 2 "aarch64_any_register_operand" "w")]
106 "TARGET_SVE && BYTES_BIG_ENDIAN"
108 "&& reload_completed"
111 aarch64_split_sve_subreg_move (operands[0], operands[1], operands[2]);
116 ;; Unpredicated moves (little-endian). Only allow memory operations
117 ;; during and after RA; before RA we want the predicated load and
118 ;; store patterns to be used instead.
119 (define_insn "*aarch64_sve_mov<mode>_le"
120 [(set (match_operand:SVE_ALL 0 "aarch64_sve_nonimmediate_operand" "=w, Utr, w, w")
121 (match_operand:SVE_ALL 1 "aarch64_sve_general_operand" "Utr, w, w, Dn"))]
124 && ((lra_in_progress || reload_completed)
125 || (register_operand (operands[0], <MODE>mode)
126 && nonmemory_operand (operands[1], <MODE>mode)))"
131 * return aarch64_output_sve_mov_immediate (operands[1]);"
134 ;; Unpredicated moves (big-endian). Memory accesses require secondary
136 (define_insn "*aarch64_sve_mov<mode>_be"
137 [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w")
138 (match_operand:SVE_ALL 1 "aarch64_nonmemory_operand" "w, Dn"))]
139 "TARGET_SVE && BYTES_BIG_ENDIAN"
142 * return aarch64_output_sve_mov_immediate (operands[1]);"
145 ;; Handle big-endian memory reloads. We use byte PTRUE for all modes
146 ;; to try to encourage reuse.
147 (define_expand "aarch64_sve_reload_be"
149 [(set (match_operand 0)
151 (clobber (match_operand:VNx16BI 2 "register_operand" "=Upl"))])]
152 "TARGET_SVE && BYTES_BIG_ENDIAN"
154 /* Create a PTRUE. */
155 emit_move_insn (operands[2], CONSTM1_RTX (VNx16BImode));
157 /* Refer to the PTRUE in the appropriate mode for this move. */
158 machine_mode mode = GET_MODE (operands[0]);
159 machine_mode pred_mode
160 = aarch64_sve_pred_mode (GET_MODE_UNIT_SIZE (mode)).require ();
161 rtx pred = gen_lowpart (pred_mode, operands[2]);
163 /* Emit a predicated load or store. */
164 aarch64_emit_sve_pred_move (operands[0], pred, operands[1]);
169 ;; A predicated load or store for which the predicate is known to be
170 ;; all-true. Note that this pattern is generated directly by
171 ;; aarch64_emit_sve_pred_move, so changes to this pattern will
172 ;; need changes there as well.
173 (define_insn "*pred_mov<mode>"
174 [(set (match_operand:SVE_ALL 0 "nonimmediate_operand" "=w, m")
176 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
177 (match_operand:SVE_ALL 2 "nonimmediate_operand" "m, w")]
178 UNSPEC_MERGE_PTRUE))]
180 && (register_operand (operands[0], <MODE>mode)
181 || register_operand (operands[2], <MODE>mode))"
183 ld1<Vesize>\t%0.<Vetype>, %1/z, %2
184 st1<Vesize>\t%2.<Vetype>, %1, %0"
187 (define_expand "movmisalign<mode>"
188 [(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
189 (match_operand:SVE_ALL 1 "general_operand"))]
192 /* Equivalent to a normal move for our purpooses. */
193 emit_move_insn (operands[0], operands[1]);
198 (define_insn "maskload<mode><vpred>"
199 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
201 [(match_operand:<VPRED> 2 "register_operand" "Upl")
202 (match_operand:SVE_ALL 1 "memory_operand" "m")]
205 "ld1<Vesize>\t%0.<Vetype>, %2/z, %1"
208 (define_insn "maskstore<mode><vpred>"
209 [(set (match_operand:SVE_ALL 0 "memory_operand" "+m")
210 (unspec:SVE_ALL [(match_operand:<VPRED> 2 "register_operand" "Upl")
211 (match_operand:SVE_ALL 1 "register_operand" "w")
215 "st1<Vesize>\t%1.<Vetype>, %2, %0"
218 ;; Unpredicated gather loads.
219 (define_expand "gather_load<mode>"
220 [(set (match_operand:SVE_SD 0 "register_operand")
223 (match_operand:DI 1 "aarch64_reg_or_zero")
224 (match_operand:<V_INT_EQUIV> 2 "register_operand")
225 (match_operand:DI 3 "const_int_operand")
226 (match_operand:DI 4 "aarch64_gather_scale_operand_<Vesize>")
231 operands[5] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
235 ;; Predicated gather loads for 32-bit elements. Operand 3 is true for
236 ;; unsigned extension and false for signed extension.
237 (define_insn "mask_gather_load<mode>"
238 [(set (match_operand:SVE_S 0 "register_operand" "=w, w, w, w, w")
240 [(match_operand:<VPRED> 5 "register_operand" "Upl, Upl, Upl, Upl, Upl")
241 (match_operand:DI 1 "aarch64_reg_or_zero" "Z, rk, rk, rk, rk")
242 (match_operand:<V_INT_EQUIV> 2 "register_operand" "w, w, w, w, w")
243 (match_operand:DI 3 "const_int_operand" "i, Z, Ui1, Z, Ui1")
244 (match_operand:DI 4 "aarch64_gather_scale_operand_w" "Ui1, Ui1, Ui1, i, i")
249 ld1w\t%0.s, %5/z, [%2.s]
250 ld1w\t%0.s, %5/z, [%1, %2.s, sxtw]
251 ld1w\t%0.s, %5/z, [%1, %2.s, uxtw]
252 ld1w\t%0.s, %5/z, [%1, %2.s, sxtw %p4]
253 ld1w\t%0.s, %5/z, [%1, %2.s, uxtw %p4]"
256 ;; Predicated gather loads for 64-bit elements. The value of operand 3
257 ;; doesn't matter in this case.
258 (define_insn "mask_gather_load<mode>"
259 [(set (match_operand:SVE_D 0 "register_operand" "=w, w, w")
261 [(match_operand:<VPRED> 5 "register_operand" "Upl, Upl, Upl")
262 (match_operand:DI 1 "aarch64_reg_or_zero" "Z, rk, rk")
263 (match_operand:<V_INT_EQUIV> 2 "register_operand" "w, w, w")
264 (match_operand:DI 3 "const_int_operand")
265 (match_operand:DI 4 "aarch64_gather_scale_operand_d" "Ui1, Ui1, i")
270 ld1d\t%0.d, %5/z, [%2.d]
271 ld1d\t%0.d, %5/z, [%1, %2.d]
272 ld1d\t%0.d, %5/z, [%1, %2.d, lsl %p4]"
275 ;; Unpredicated scatter store.
276 (define_expand "scatter_store<mode>"
277 [(set (mem:BLK (scratch))
280 (match_operand:DI 0 "aarch64_reg_or_zero")
281 (match_operand:<V_INT_EQUIV> 1 "register_operand")
282 (match_operand:DI 2 "const_int_operand")
283 (match_operand:DI 3 "aarch64_gather_scale_operand_<Vesize>")
284 (match_operand:SVE_SD 4 "register_operand")]
285 UNSPEC_ST1_SCATTER))]
288 operands[5] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
292 ;; Predicated scatter stores for 32-bit elements. Operand 2 is true for
293 ;; unsigned extension and false for signed extension.
294 (define_insn "mask_scatter_store<mode>"
295 [(set (mem:BLK (scratch))
297 [(match_operand:<VPRED> 5 "register_operand" "Upl, Upl, Upl, Upl, Upl")
298 (match_operand:DI 0 "aarch64_reg_or_zero" "Z, rk, rk, rk, rk")
299 (match_operand:<V_INT_EQUIV> 1 "register_operand" "w, w, w, w, w")
300 (match_operand:DI 2 "const_int_operand" "i, Z, Ui1, Z, Ui1")
301 (match_operand:DI 3 "aarch64_gather_scale_operand_w" "Ui1, Ui1, Ui1, i, i")
302 (match_operand:SVE_S 4 "register_operand" "w, w, w, w, w")]
303 UNSPEC_ST1_SCATTER))]
306 st1w\t%4.s, %5, [%1.s]
307 st1w\t%4.s, %5, [%0, %1.s, sxtw]
308 st1w\t%4.s, %5, [%0, %1.s, uxtw]
309 st1w\t%4.s, %5, [%0, %1.s, sxtw %p3]
310 st1w\t%4.s, %5, [%0, %1.s, uxtw %p3]"
313 ;; Predicated scatter stores for 64-bit elements. The value of operand 2
314 ;; doesn't matter in this case.
315 (define_insn "mask_scatter_store<mode>"
316 [(set (mem:BLK (scratch))
318 [(match_operand:<VPRED> 5 "register_operand" "Upl, Upl, Upl")
319 (match_operand:DI 0 "aarch64_reg_or_zero" "Z, rk, rk")
320 (match_operand:<V_INT_EQUIV> 1 "register_operand" "w, w, w")
321 (match_operand:DI 2 "const_int_operand")
322 (match_operand:DI 3 "aarch64_gather_scale_operand_d" "Ui1, Ui1, i")
323 (match_operand:SVE_D 4 "register_operand" "w, w, w")]
324 UNSPEC_ST1_SCATTER))]
327 st1d\t%4.d, %5, [%1.d]
328 st1d\t%4.d, %5, [%0, %1.d]
329 st1d\t%4.d, %5, [%0, %1.d, lsl %p3]"
332 ;; SVE structure moves.
333 (define_expand "mov<mode>"
334 [(set (match_operand:SVE_STRUCT 0 "nonimmediate_operand")
335 (match_operand:SVE_STRUCT 1 "general_operand"))]
338 /* Big-endian loads and stores need to be done via LD1 and ST1;
339 see the comment at the head of the file for details. */
340 if ((MEM_P (operands[0]) || MEM_P (operands[1]))
343 gcc_assert (can_create_pseudo_p ());
344 aarch64_expand_sve_mem_move (operands[0], operands[1], <VPRED>mode);
348 if (CONSTANT_P (operands[1]))
350 aarch64_expand_mov_immediate (operands[0], operands[1]);
356 ;; Unpredicated structure moves (little-endian).
357 (define_insn "*aarch64_sve_mov<mode>_le"
358 [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand" "=w, Utr, w, w")
359 (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand" "Utr, w, w, Dn"))]
360 "TARGET_SVE && !BYTES_BIG_ENDIAN"
362 [(set_attr "length" "<insn_length>")]
365 ;; Unpredicated structure moves (big-endian). Memory accesses require
366 ;; secondary reloads.
367 (define_insn "*aarch64_sve_mov<mode>_le"
368 [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w, w")
369 (match_operand:SVE_STRUCT 1 "aarch64_nonmemory_operand" "w, Dn"))]
370 "TARGET_SVE && BYTES_BIG_ENDIAN"
372 [(set_attr "length" "<insn_length>")]
375 ;; Split unpredicated structure moves into pieces. This is the same
376 ;; for both big-endian and little-endian code, although it only needs
377 ;; to handle memory operands for little-endian code.
379 [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand")
380 (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand"))]
381 "TARGET_SVE && reload_completed"
384 rtx dest = operands[0];
385 rtx src = operands[1];
386 if (REG_P (dest) && REG_P (src))
387 aarch64_simd_emit_reg_reg_move (operands, <VSINGLE>mode, <vector_count>);
389 for (unsigned int i = 0; i < <vector_count>; ++i)
391 rtx subdest = simplify_gen_subreg (<VSINGLE>mode, dest, <MODE>mode,
392 i * BYTES_PER_SVE_VECTOR);
393 rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, src, <MODE>mode,
394 i * BYTES_PER_SVE_VECTOR);
395 emit_insn (gen_rtx_SET (subdest, subsrc));
401 ;; Predicated structure moves. This works for both endiannesses but in
402 ;; practice is only useful for big-endian.
403 (define_insn_and_split "pred_mov<mode>"
404 [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_struct_nonimmediate_operand" "=w, Utx")
406 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
407 (match_operand:SVE_STRUCT 2 "aarch64_sve_struct_nonimmediate_operand" "Utx, w")]
408 UNSPEC_MERGE_PTRUE))]
410 && (register_operand (operands[0], <MODE>mode)
411 || register_operand (operands[2], <MODE>mode))"
413 "&& reload_completed"
416 for (unsigned int i = 0; i < <vector_count>; ++i)
418 rtx subdest = simplify_gen_subreg (<VSINGLE>mode, operands[0],
420 i * BYTES_PER_SVE_VECTOR);
421 rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, operands[2],
423 i * BYTES_PER_SVE_VECTOR);
424 aarch64_emit_sve_pred_move (subdest, operands[1], subsrc);
428 [(set_attr "length" "<insn_length>")]
431 (define_expand "mov<mode>"
432 [(set (match_operand:PRED_ALL 0 "nonimmediate_operand")
433 (match_operand:PRED_ALL 1 "general_operand"))]
436 if (GET_CODE (operands[0]) == MEM)
437 operands[1] = force_reg (<MODE>mode, operands[1]);
441 (define_insn "*aarch64_sve_mov<mode>"
442 [(set (match_operand:PRED_ALL 0 "nonimmediate_operand" "=Upa, m, Upa, Upa, Upa")
443 (match_operand:PRED_ALL 1 "general_operand" "Upa, Upa, m, Dz, Dm"))]
445 && (register_operand (operands[0], <MODE>mode)
446 || register_operand (operands[1], <MODE>mode))"
452 * return aarch64_output_ptrue (<MODE>mode, '<Vetype>');"
455 ;; Handle extractions from a predicate by converting to an integer vector
456 ;; and extracting from there.
457 (define_expand "vec_extract<vpred><Vel>"
458 [(match_operand:<VEL> 0 "register_operand")
459 (match_operand:<VPRED> 1 "register_operand")
460 (match_operand:SI 2 "nonmemory_operand")
461 ;; Dummy operand to which we can attach the iterator.
462 (reg:SVE_I V0_REGNUM)]
465 rtx tmp = gen_reg_rtx (<MODE>mode);
466 emit_insn (gen_aarch64_sve_dup<mode>_const (tmp, operands[1],
467 CONST1_RTX (<MODE>mode),
468 CONST0_RTX (<MODE>mode)));
469 emit_insn (gen_vec_extract<mode><Vel> (operands[0], tmp, operands[2]));
474 (define_expand "vec_extract<mode><Vel>"
475 [(set (match_operand:<VEL> 0 "register_operand")
477 (match_operand:SVE_ALL 1 "register_operand")
478 (parallel [(match_operand:SI 2 "nonmemory_operand")])))]
482 if (poly_int_rtx_p (operands[2], &val)
483 && known_eq (val, GET_MODE_NUNITS (<MODE>mode) - 1))
485 /* The last element can be extracted with a LASTB and a false
487 rtx sel = force_reg (<VPRED>mode, CONST0_RTX (<VPRED>mode));
488 emit_insn (gen_extract_last_<mode> (operands[0], sel, operands[1]));
491 if (!CONST_INT_P (operands[2]))
493 /* Create an index with operand[2] as the base and -1 as the step.
494 It will then be zero for the element we care about. */
495 rtx index = gen_lowpart (<VEL_INT>mode, operands[2]);
496 index = force_reg (<VEL_INT>mode, index);
497 rtx series = gen_reg_rtx (<V_INT_EQUIV>mode);
498 emit_insn (gen_vec_series<v_int_equiv> (series, index, constm1_rtx));
500 /* Get a predicate that is true for only that element. */
501 rtx zero = CONST0_RTX (<V_INT_EQUIV>mode);
502 rtx cmp = gen_rtx_EQ (<V_INT_EQUIV>mode, series, zero);
503 rtx sel = gen_reg_rtx (<VPRED>mode);
504 emit_insn (gen_vec_cmp<v_int_equiv><vpred> (sel, cmp, series, zero));
506 /* Select the element using LASTB. */
507 emit_insn (gen_extract_last_<mode> (operands[0], sel, operands[1]));
513 ;; Extract element zero. This is a special case because we want to force
514 ;; the registers to be the same for the second alternative, and then
515 ;; split the instruction into nothing after RA.
516 (define_insn_and_split "*vec_extract<mode><Vel>_0"
517 [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
519 (match_operand:SVE_ALL 1 "register_operand" "w, 0, w")
520 (parallel [(const_int 0)])))]
523 operands[1] = gen_rtx_REG (<V128>mode, REGNO (operands[1]));
524 switch (which_alternative)
527 return "umov\\t%<vwcore>0, %1.<Vetype>[0]";
531 return "st1\\t{%1.<Vetype>}[0], %0";
537 && REG_P (operands[0])
538 && REGNO (operands[0]) == REGNO (operands[1])"
541 emit_note (NOTE_INSN_DELETED);
544 [(set_attr "type" "neon_to_gp_q, untyped, neon_store1_one_lane_q")]
547 ;; Extract an element from the Advanced SIMD portion of the register.
548 ;; We don't just reuse the aarch64-simd.md pattern because we don't
549 ;; want any change in lane number on big-endian targets.
550 (define_insn "*vec_extract<mode><Vel>_v128"
551 [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
553 (match_operand:SVE_ALL 1 "register_operand" "w, w, w")
554 (parallel [(match_operand:SI 2 "const_int_operand")])))]
556 && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 1, 15)"
558 operands[1] = gen_rtx_REG (<V128>mode, REGNO (operands[1]));
559 switch (which_alternative)
562 return "umov\\t%<vwcore>0, %1.<Vetype>[%2]";
564 return "dup\\t%<Vetype>0, %1.<Vetype>[%2]";
566 return "st1\\t{%1.<Vetype>}[%2], %0";
571 [(set_attr "type" "neon_to_gp_q, neon_dup_q, neon_store1_one_lane_q")]
574 ;; Extract an element in the range of DUP. This pattern allows the
575 ;; source and destination to be different.
576 (define_insn "*vec_extract<mode><Vel>_dup"
577 [(set (match_operand:<VEL> 0 "register_operand" "=w")
579 (match_operand:SVE_ALL 1 "register_operand" "w")
580 (parallel [(match_operand:SI 2 "const_int_operand")])))]
582 && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 16, 63)"
584 operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
585 return "dup\t%0.<Vetype>, %1.<Vetype>[%2]";
589 ;; Extract an element outside the range of DUP. This pattern requires the
590 ;; source and destination to be the same.
591 (define_insn "*vec_extract<mode><Vel>_ext"
592 [(set (match_operand:<VEL> 0 "register_operand" "=w")
594 (match_operand:SVE_ALL 1 "register_operand" "0")
595 (parallel [(match_operand:SI 2 "const_int_operand")])))]
596 "TARGET_SVE && INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode) >= 64"
598 operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
599 operands[2] = GEN_INT (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode));
600 return "ext\t%0.b, %0.b, %0.b, #%2";
604 ;; Extract the last active element of operand 1 into operand 0.
605 ;; If no elements are active, extract the last inactive element instead.
606 (define_insn "extract_last_<mode>"
607 [(set (match_operand:<VEL> 0 "register_operand" "=r, w")
609 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
610 (match_operand:SVE_ALL 2 "register_operand" "w, w")]
614 lastb\t%<vwcore>0, %1, %2.<Vetype>
615 lastb\t%<Vetype>0, %1, %2.<Vetype>"
618 (define_expand "vec_duplicate<mode>"
620 [(set (match_operand:SVE_ALL 0 "register_operand")
621 (vec_duplicate:SVE_ALL
622 (match_operand:<VEL> 1 "aarch64_sve_dup_operand")))
623 (clobber (scratch:<VPRED>))])]
626 if (MEM_P (operands[1]))
628 rtx ptrue = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
629 emit_insn (gen_sve_ld1r<mode> (operands[0], ptrue, operands[1],
630 CONST0_RTX (<MODE>mode)));
636 ;; Accept memory operands for the benefit of combine, and also in case
637 ;; the scalar input gets spilled to memory during RA. We want to split
638 ;; the load at the first opportunity in order to allow the PTRUE to be
639 ;; optimized with surrounding code.
640 (define_insn_and_split "*vec_duplicate<mode>_reg"
641 [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w, w")
642 (vec_duplicate:SVE_ALL
643 (match_operand:<VEL> 1 "aarch64_sve_dup_operand" "r, w, Uty")))
644 (clobber (match_scratch:<VPRED> 2 "=X, X, Upl"))]
647 mov\t%0.<Vetype>, %<vwcore>1
648 mov\t%0.<Vetype>, %<Vetype>1
650 "&& MEM_P (operands[1])"
653 if (GET_CODE (operands[2]) == SCRATCH)
654 operands[2] = gen_reg_rtx (<VPRED>mode);
655 emit_move_insn (operands[2], CONSTM1_RTX (<VPRED>mode));
656 emit_insn (gen_sve_ld1r<mode> (operands[0], operands[2], operands[1],
657 CONST0_RTX (<MODE>mode)));
660 [(set_attr "length" "4,4,8")]
663 ;; This is used for vec_duplicate<mode>s from memory, but can also
664 ;; be used by combine to optimize selects of a a vec_duplicate<mode>
666 (define_insn "sve_ld1r<mode>"
667 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
669 [(match_operand:<VPRED> 1 "register_operand" "Upl")
670 (vec_duplicate:SVE_ALL
671 (match_operand:<VEL> 2 "aarch64_sve_ld1r_operand" "Uty"))
672 (match_operand:SVE_ALL 3 "aarch64_simd_imm_zero")]
675 "ld1r<Vesize>\t%0.<Vetype>, %1/z, %2"
678 ;; Load 128 bits from memory and duplicate to fill a vector. Since there
679 ;; are so few operations on 128-bit "elements", we don't define a VNx1TI
680 ;; and simply use vectors of bytes instead.
681 (define_insn "*sve_ld1rq<Vesize>"
682 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
684 [(match_operand:<VPRED> 1 "register_operand" "Upl")
685 (match_operand:TI 2 "aarch64_sve_ld1r_operand" "Uty")]
688 "ld1rq<Vesize>\t%0.<Vetype>, %1/z, %2"
691 ;; Implement a predicate broadcast by shifting the low bit of the scalar
692 ;; input into the top bit and using a WHILELO. An alternative would be to
693 ;; duplicate the input and do a compare with zero.
694 (define_expand "vec_duplicate<mode>"
695 [(set (match_operand:PRED_ALL 0 "register_operand")
696 (vec_duplicate:PRED_ALL (match_operand 1 "register_operand")))]
699 rtx tmp = gen_reg_rtx (DImode);
700 rtx op1 = gen_lowpart (DImode, operands[1]);
701 emit_insn (gen_ashldi3 (tmp, op1, gen_int_mode (63, DImode)));
702 emit_insn (gen_while_ultdi<mode> (operands[0], const0_rtx, tmp));
707 (define_insn "vec_series<mode>"
708 [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w")
710 (match_operand:<VEL> 1 "aarch64_sve_index_operand" "Usi, r, r")
711 (match_operand:<VEL> 2 "aarch64_sve_index_operand" "r, Usi, r")))]
714 index\t%0.<Vetype>, #%1, %<vw>2
715 index\t%0.<Vetype>, %<vw>1, #%2
716 index\t%0.<Vetype>, %<vw>1, %<vw>2"
719 ;; Optimize {x, x, x, x, ...} + {0, n, 2*n, 3*n, ...} if n is in range
720 ;; of an INDEX instruction.
721 (define_insn "*vec_series<mode>_plus"
722 [(set (match_operand:SVE_I 0 "register_operand" "=w")
725 (match_operand:<VEL> 1 "register_operand" "r"))
726 (match_operand:SVE_I 2 "immediate_operand")))]
727 "TARGET_SVE && aarch64_check_zero_based_sve_index_immediate (operands[2])"
729 operands[2] = aarch64_check_zero_based_sve_index_immediate (operands[2]);
730 return "index\t%0.<Vetype>, %<vw>1, #%2";
734 ;; Unpredicated LD[234].
735 (define_expand "vec_load_lanes<mode><vsingle>"
736 [(set (match_operand:SVE_STRUCT 0 "register_operand")
739 (match_operand:SVE_STRUCT 1 "memory_operand")]
743 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
747 ;; Predicated LD[234].
748 (define_insn "vec_mask_load_lanes<mode><vsingle>"
749 [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w")
751 [(match_operand:<VPRED> 2 "register_operand" "Upl")
752 (match_operand:SVE_STRUCT 1 "memory_operand" "m")]
755 "ld<vector_count><Vesize>\t%0, %2/z, %1"
758 ;; Unpredicated ST[234]. This is always a full update, so the dependence
759 ;; on the old value of the memory location (via (match_dup 0)) is redundant.
760 ;; There doesn't seem to be any obvious benefit to treating the all-true
761 ;; case differently though. In particular, it's very unlikely that we'll
762 ;; only find out during RTL that a store_lanes is dead.
763 (define_expand "vec_store_lanes<mode><vsingle>"
764 [(set (match_operand:SVE_STRUCT 0 "memory_operand")
767 (match_operand:SVE_STRUCT 1 "register_operand")
772 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
776 ;; Predicated ST[234].
777 (define_insn "vec_mask_store_lanes<mode><vsingle>"
778 [(set (match_operand:SVE_STRUCT 0 "memory_operand" "+m")
780 [(match_operand:<VPRED> 2 "register_operand" "Upl")
781 (match_operand:SVE_STRUCT 1 "register_operand" "w")
785 "st<vector_count><Vesize>\t%1, %2, %0"
788 (define_expand "vec_perm<mode>"
789 [(match_operand:SVE_ALL 0 "register_operand")
790 (match_operand:SVE_ALL 1 "register_operand")
791 (match_operand:SVE_ALL 2 "register_operand")
792 (match_operand:<V_INT_EQUIV> 3 "aarch64_sve_vec_perm_operand")]
793 "TARGET_SVE && GET_MODE_NUNITS (<MODE>mode).is_constant ()"
795 aarch64_expand_sve_vec_perm (operands[0], operands[1],
796 operands[2], operands[3]);
801 (define_insn "*aarch64_sve_tbl<mode>"
802 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
804 [(match_operand:SVE_ALL 1 "register_operand" "w")
805 (match_operand:<V_INT_EQUIV> 2 "register_operand" "w")]
808 "tbl\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
811 (define_insn "*aarch64_sve_<perm_insn><perm_hilo><mode>"
812 [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
813 (unspec:PRED_ALL [(match_operand:PRED_ALL 1 "register_operand" "Upa")
814 (match_operand:PRED_ALL 2 "register_operand" "Upa")]
817 "<perm_insn><perm_hilo>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
820 (define_insn "aarch64_sve_<perm_insn><perm_hilo><mode>"
821 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
822 (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "w")
823 (match_operand:SVE_ALL 2 "register_operand" "w")]
826 "<perm_insn><perm_hilo>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
829 (define_insn "*aarch64_sve_rev64<mode>"
830 [(set (match_operand:SVE_BHS 0 "register_operand" "=w")
832 [(match_operand:VNx2BI 1 "register_operand" "Upl")
833 (unspec:SVE_BHS [(match_operand:SVE_BHS 2 "register_operand" "w")]
835 UNSPEC_MERGE_PTRUE))]
837 "rev<Vesize>\t%0.d, %1/m, %2.d"
840 (define_insn "*aarch64_sve_rev32<mode>"
841 [(set (match_operand:SVE_BH 0 "register_operand" "=w")
843 [(match_operand:VNx4BI 1 "register_operand" "Upl")
844 (unspec:SVE_BH [(match_operand:SVE_BH 2 "register_operand" "w")]
846 UNSPEC_MERGE_PTRUE))]
848 "rev<Vesize>\t%0.s, %1/m, %2.s"
851 (define_insn "*aarch64_sve_rev16vnx16qi"
852 [(set (match_operand:VNx16QI 0 "register_operand" "=w")
854 [(match_operand:VNx8BI 1 "register_operand" "Upl")
855 (unspec:VNx16QI [(match_operand:VNx16QI 2 "register_operand" "w")]
857 UNSPEC_MERGE_PTRUE))]
859 "revb\t%0.h, %1/m, %2.h"
862 (define_insn "*aarch64_sve_rev<mode>"
863 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
864 (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "w")]
867 "rev\t%0.<Vetype>, %1.<Vetype>")
869 (define_insn "*aarch64_sve_dup_lane<mode>"
870 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
871 (vec_duplicate:SVE_ALL
873 (match_operand:SVE_ALL 1 "register_operand" "w")
874 (parallel [(match_operand:SI 2 "const_int_operand")]))))]
876 && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 0, 63)"
877 "dup\t%0.<Vetype>, %1.<Vetype>[%2]"
880 ;; Note that the immediate (third) operand is the lane index not
882 (define_insn "*aarch64_sve_ext<mode>"
883 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
884 (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0")
885 (match_operand:SVE_ALL 2 "register_operand" "w")
886 (match_operand:SI 3 "const_int_operand")]
889 && IN_RANGE (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode), 0, 255)"
891 operands[3] = GEN_INT (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode));
892 return "ext\\t%0.b, %0.b, %2.b, #%3";
896 (define_insn "add<mode>3"
897 [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w, w")
899 (match_operand:SVE_I 1 "register_operand" "%0, 0, 0, w")
900 (match_operand:SVE_I 2 "aarch64_sve_add_operand" "vsa, vsn, vsi, w")))]
903 add\t%0.<Vetype>, %0.<Vetype>, #%D2
904 sub\t%0.<Vetype>, %0.<Vetype>, #%N2
905 * return aarch64_output_sve_inc_dec_immediate (\"%0.<Vetype>\", operands[2]);
906 add\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
909 (define_insn "sub<mode>3"
910 [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
912 (match_operand:SVE_I 1 "aarch64_sve_arith_operand" "w, vsa")
913 (match_operand:SVE_I 2 "register_operand" "w, 0")))]
916 sub\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>
917 subr\t%0.<Vetype>, %0.<Vetype>, #%D1"
920 ;; Unpredicated multiplication.
921 (define_expand "mul<mode>3"
922 [(set (match_operand:SVE_I 0 "register_operand")
926 (match_operand:SVE_I 1 "register_operand")
927 (match_operand:SVE_I 2 "aarch64_sve_mul_operand"))]
928 UNSPEC_MERGE_PTRUE))]
931 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
935 ;; Multiplication predicated with a PTRUE. We don't actually need the
936 ;; predicate for the first alternative, but using Upa or X isn't likely
937 ;; to gain much and would make the instruction seem less uniform to the
938 ;; register allocator.
939 (define_insn "*mul<mode>3"
940 [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
942 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
944 (match_operand:SVE_I 2 "register_operand" "%0, 0, w")
945 (match_operand:SVE_I 3 "aarch64_sve_mul_operand" "vsm, w, w"))]
946 UNSPEC_MERGE_PTRUE))]
949 mul\t%0.<Vetype>, %0.<Vetype>, #%3
950 mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
951 movprfx\t%0, %2\;mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
952 [(set_attr "movprfx" "*,*,yes")]
955 (define_insn "*madd<mode>"
956 [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
959 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
960 (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
961 (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
963 (match_operand:SVE_I 4 "register_operand" "w, 0, w")))]
966 mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
967 mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
968 movprfx\t%0, %4\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
969 [(set_attr "movprfx" "*,*,yes")]
972 (define_insn "*msub<mode>3"
973 [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
975 (match_operand:SVE_I 4 "register_operand" "w, 0, w")
977 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
978 (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
979 (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
980 UNSPEC_MERGE_PTRUE)))]
983 msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
984 mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
985 movprfx\t%0, %4\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
986 [(set_attr "movprfx" "*,*,yes")]
989 ;; Unpredicated highpart multiplication.
990 (define_expand "<su>mul<mode>3_highpart"
991 [(set (match_operand:SVE_I 0 "register_operand")
994 (unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
995 (match_operand:SVE_I 2 "register_operand")]
997 UNSPEC_MERGE_PTRUE))]
1000 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1004 ;; Predicated highpart multiplication.
1005 (define_insn "*<su>mul<mode>3_highpart"
1006 [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
1008 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1009 (unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0, w")
1010 (match_operand:SVE_I 3 "register_operand" "w, w")]
1012 UNSPEC_MERGE_PTRUE))]
1015 <su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1016 movprfx\t%0, %2\;<su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1017 [(set_attr "movprfx" "*,yes")]
1020 ;; Unpredicated division.
1021 (define_expand "<optab><mode>3"
1022 [(set (match_operand:SVE_SDI 0 "register_operand")
1025 (SVE_INT_BINARY_SD:SVE_SDI
1026 (match_operand:SVE_SDI 1 "register_operand")
1027 (match_operand:SVE_SDI 2 "register_operand"))]
1028 UNSPEC_MERGE_PTRUE))]
1031 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1035 ;; Division predicated with a PTRUE.
1036 (define_insn "*<optab><mode>3"
1037 [(set (match_operand:SVE_SDI 0 "register_operand" "=w, w, ?&w")
1039 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1040 (SVE_INT_BINARY_SD:SVE_SDI
1041 (match_operand:SVE_SDI 2 "register_operand" "0, w, w")
1042 (match_operand:SVE_SDI 3 "aarch64_sve_mul_operand" "w, 0, w"))]
1043 UNSPEC_MERGE_PTRUE))]
1046 <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1047 <sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1048 movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1049 [(set_attr "movprfx" "*,*,yes")]
1052 ;; Unpredicated NEG, NOT and POPCOUNT.
1053 (define_expand "<optab><mode>2"
1054 [(set (match_operand:SVE_I 0 "register_operand")
1057 (SVE_INT_UNARY:SVE_I (match_operand:SVE_I 1 "register_operand"))]
1058 UNSPEC_MERGE_PTRUE))]
1061 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1065 ;; NEG, NOT and POPCOUNT predicated with a PTRUE.
1066 (define_insn "*<optab><mode>2"
1067 [(set (match_operand:SVE_I 0 "register_operand" "=w")
1069 [(match_operand:<VPRED> 1 "register_operand" "Upl")
1070 (SVE_INT_UNARY:SVE_I
1071 (match_operand:SVE_I 2 "register_operand" "w"))]
1072 UNSPEC_MERGE_PTRUE))]
1074 "<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
1077 ;; Vector AND, ORR and XOR.
1078 (define_insn "<optab><mode>3"
1079 [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
1081 (match_operand:SVE_I 1 "register_operand" "%0, w")
1082 (match_operand:SVE_I 2 "aarch64_sve_logical_operand" "vsl, w")))]
1085 <logical>\t%0.<Vetype>, %0.<Vetype>, #%C2
1086 <logical>\t%0.d, %1.d, %2.d"
1089 ;; Vector AND, ORR and XOR on floating-point modes. We avoid subregs
1090 ;; by providing this, but we need to use UNSPECs since rtx logical ops
1091 ;; aren't defined for floating-point modes.
1092 (define_insn "*<optab><mode>3"
1093 [(set (match_operand:SVE_F 0 "register_operand" "=w")
1094 (unspec:SVE_F [(match_operand:SVE_F 1 "register_operand" "w")
1095 (match_operand:SVE_F 2 "register_operand" "w")]
1098 "<logicalf_op>\t%0.d, %1.d, %2.d"
1101 ;; REG_EQUAL notes on "not<mode>3" should ensure that we can generate
1102 ;; this pattern even though the NOT instruction itself is predicated.
1103 (define_insn "bic<mode>3"
1104 [(set (match_operand:SVE_I 0 "register_operand" "=w")
1106 (not:SVE_I (match_operand:SVE_I 1 "register_operand" "w"))
1107 (match_operand:SVE_I 2 "register_operand" "w")))]
1109 "bic\t%0.d, %2.d, %1.d"
1112 ;; Predicate AND. We can reuse one of the inputs as the GP.
1113 (define_insn "and<mode>3"
1114 [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1115 (and:PRED_ALL (match_operand:PRED_ALL 1 "register_operand" "Upa")
1116 (match_operand:PRED_ALL 2 "register_operand" "Upa")))]
1118 "and\t%0.b, %1/z, %1.b, %2.b"
1121 ;; Unpredicated predicate ORR and XOR.
1122 (define_expand "<optab><mode>3"
1123 [(set (match_operand:PRED_ALL 0 "register_operand")
1125 (LOGICAL_OR:PRED_ALL
1126 (match_operand:PRED_ALL 1 "register_operand")
1127 (match_operand:PRED_ALL 2 "register_operand"))
1131 operands[3] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));
1135 ;; Predicated predicate ORR and XOR.
1136 (define_insn "pred_<optab><mode>3"
1137 [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1140 (match_operand:PRED_ALL 2 "register_operand" "Upa")
1141 (match_operand:PRED_ALL 3 "register_operand" "Upa"))
1142 (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
1144 "<logical>\t%0.b, %1/z, %2.b, %3.b"
1147 ;; Perform a logical operation on operands 2 and 3, using operand 1 as
1148 ;; the GP (which is known to be a PTRUE). Store the result in operand 0
1149 ;; and set the flags in the same way as for PTEST. The (and ...) in the
1150 ;; UNSPEC_PTEST_PTRUE is logically redundant, but means that the tested
1151 ;; value is structurally equivalent to rhs of the second set.
1152 (define_insn "*<optab><mode>3_cc"
1153 [(set (reg:CC CC_REGNUM)
1155 (unspec:SI [(match_operand:PRED_ALL 1 "register_operand" "Upa")
1158 (match_operand:PRED_ALL 2 "register_operand" "Upa")
1159 (match_operand:PRED_ALL 3 "register_operand" "Upa"))
1163 (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1164 (and:PRED_ALL (LOGICAL:PRED_ALL (match_dup 2) (match_dup 3))
1167 "<logical>s\t%0.b, %1/z, %2.b, %3.b"
1170 ;; Unpredicated predicate inverse.
1171 (define_expand "one_cmpl<mode>2"
1172 [(set (match_operand:PRED_ALL 0 "register_operand")
1174 (not:PRED_ALL (match_operand:PRED_ALL 1 "register_operand"))
1178 operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));
1182 ;; Predicated predicate inverse.
1183 (define_insn "*one_cmpl<mode>3"
1184 [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1186 (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
1187 (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
1189 "not\t%0.b, %1/z, %2.b"
1192 ;; Predicated predicate BIC and ORN.
1193 (define_insn "*<nlogical><mode>3"
1194 [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1197 (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
1198 (match_operand:PRED_ALL 3 "register_operand" "Upa"))
1199 (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
1201 "<nlogical>\t%0.b, %1/z, %3.b, %2.b"
1204 ;; Predicated predicate NAND and NOR.
1205 (define_insn "*<logical_nn><mode>3"
1206 [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1209 (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
1210 (not:PRED_ALL (match_operand:PRED_ALL 3 "register_operand" "Upa")))
1211 (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
1213 "<logical_nn>\t%0.b, %1/z, %2.b, %3.b"
1216 ;; Unpredicated LSL, LSR and ASR by a vector.
1217 (define_expand "v<optab><mode>3"
1218 [(set (match_operand:SVE_I 0 "register_operand")
1222 (match_operand:SVE_I 1 "register_operand")
1223 (match_operand:SVE_I 2 "aarch64_sve_<lr>shift_operand"))]
1224 UNSPEC_MERGE_PTRUE))]
1227 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1231 ;; LSL, LSR and ASR by a vector, predicated with a PTRUE. We don't
1232 ;; actually need the predicate for the first alternative, but using Upa
1233 ;; or X isn't likely to gain much and would make the instruction seem
1234 ;; less uniform to the register allocator.
1235 (define_insn "*v<optab><mode>3"
1236 [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
1238 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1240 (match_operand:SVE_I 2 "register_operand" "w, 0, w")
1241 (match_operand:SVE_I 3 "aarch64_sve_<lr>shift_operand" "D<lr>, w, w"))]
1242 UNSPEC_MERGE_PTRUE))]
1245 <shift>\t%0.<Vetype>, %2.<Vetype>, #%3
1246 <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1247 movprfx\t%0, %2\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1248 [(set_attr "movprfx" "*,*,yes")]
1251 ;; LSL, LSR and ASR by a scalar, which expands into one of the vector
1253 (define_expand "<ASHIFT:optab><mode>3"
1254 [(set (match_operand:SVE_I 0 "register_operand")
1255 (ASHIFT:SVE_I (match_operand:SVE_I 1 "register_operand")
1256 (match_operand:<VEL> 2 "general_operand")))]
1260 if (CONST_INT_P (operands[2]))
1262 amount = gen_const_vec_duplicate (<MODE>mode, operands[2]);
1263 if (!aarch64_sve_<lr>shift_operand (operands[2], <MODE>mode))
1264 amount = force_reg (<MODE>mode, amount);
1268 amount = gen_reg_rtx (<MODE>mode);
1269 emit_insn (gen_vec_duplicate<mode> (amount,
1270 convert_to_mode (<VEL>mode,
1273 emit_insn (gen_v<optab><mode>3 (operands[0], operands[1], amount));
1278 ;; Test all bits of operand 1. Operand 0 is a GP that is known to hold PTRUE.
1280 ;; Using UNSPEC_PTEST_PTRUE allows combine patterns to assume that the GP
1281 ;; is a PTRUE even if the optimizers haven't yet been able to propagate
1282 ;; the constant. We would use a separate unspec code for PTESTs involving
1283 ;; GPs that might not be PTRUEs.
1284 (define_insn "ptest_ptrue<mode>"
1285 [(set (reg:CC CC_REGNUM)
1287 (unspec:SI [(match_operand:PRED_ALL 0 "register_operand" "Upa")
1288 (match_operand:PRED_ALL 1 "register_operand" "Upa")]
1295 ;; Set element I of the result if operand1 + J < operand2 for all J in [0, I].
1296 ;; with the comparison being unsigned.
1297 (define_insn "while_ult<GPI:mode><PRED_ALL:mode>"
1298 [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1299 (unspec:PRED_ALL [(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
1300 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
1302 (clobber (reg:CC CC_REGNUM))]
1304 "whilelo\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
1307 ;; WHILELO sets the flags in the same way as a PTEST with a PTRUE GP.
1308 ;; Handle the case in which both results are useful. The GP operand
1309 ;; to the PTEST isn't needed, so we allow it to be anything.
1310 (define_insn_and_split "while_ult<GPI:mode><PRED_ALL:mode>_cc"
1311 [(set (reg:CC CC_REGNUM)
1313 (unspec:SI [(match_operand:PRED_ALL 1)
1315 [(match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")
1316 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")]
1320 (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1321 (unspec:PRED_ALL [(match_dup 2)
1325 "whilelo\t%0.<PRED_ALL:Vetype>, %<w>2, %<w>3"
1326 ;; Force the compiler to drop the unused predicate operand, so that we
1327 ;; don't have an unnecessary PTRUE.
1328 "&& !CONSTANT_P (operands[1])"
1331 emit_insn (gen_while_ult<GPI:mode><PRED_ALL:mode>_cc
1332 (operands[0], CONSTM1_RTX (<MODE>mode),
1333 operands[2], operands[3]));
1338 ;; Integer comparisons predicated with a PTRUE.
1339 (define_insn "*cmp<cmp_op><mode>"
1340 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1342 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1343 (SVE_INT_CMP:<VPRED>
1344 (match_operand:SVE_I 2 "register_operand" "w, w")
1345 (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
1346 UNSPEC_MERGE_PTRUE))
1347 (clobber (reg:CC CC_REGNUM))]
1350 cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
1351 cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1354 ;; Integer comparisons predicated with a PTRUE in which only the flags result
1356 (define_insn "*cmp<cmp_op><mode>_ptest"
1357 [(set (reg:CC CC_REGNUM)
1360 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1363 (SVE_INT_CMP:<VPRED>
1364 (match_operand:SVE_I 2 "register_operand" "w, w")
1365 (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
1366 UNSPEC_MERGE_PTRUE)]
1369 (clobber (match_scratch:<VPRED> 0 "=Upa, Upa"))]
1372 cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
1373 cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1376 ;; Integer comparisons predicated with a PTRUE in which both the flag and
1377 ;; predicate results are interesting.
1378 (define_insn "*cmp<cmp_op><mode>_cc"
1379 [(set (reg:CC CC_REGNUM)
1382 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1385 (SVE_INT_CMP:<VPRED>
1386 (match_operand:SVE_I 2 "register_operand" "w, w")
1387 (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
1388 UNSPEC_MERGE_PTRUE)]
1391 (set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1394 (SVE_INT_CMP:<VPRED>
1397 UNSPEC_MERGE_PTRUE))]
1400 cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
1401 cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1404 ;; Predicated integer comparisons, formed by combining a PTRUE-predicated
1405 ;; comparison with an AND. Split the instruction into its preferred form
1406 ;; (below) at the earliest opportunity, in order to get rid of the
1407 ;; redundant operand 1.
1408 (define_insn_and_split "*pred_cmp<cmp_op><mode>_combine"
1409 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1412 [(match_operand:<VPRED> 1)
1413 (SVE_INT_CMP:<VPRED>
1414 (match_operand:SVE_I 2 "register_operand" "w, w")
1415 (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
1417 (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))
1418 (clobber (reg:CC CC_REGNUM))]
1425 (SVE_INT_CMP:<VPRED>
1429 (clobber (reg:CC CC_REGNUM))])]
1432 ;; Predicated integer comparisons.
1433 (define_insn "*pred_cmp<cmp_op><mode>"
1434 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1436 (SVE_INT_CMP:<VPRED>
1437 (match_operand:SVE_I 2 "register_operand" "w, w")
1438 (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))
1439 (match_operand:<VPRED> 1 "register_operand" "Upl, Upl")))
1440 (clobber (reg:CC CC_REGNUM))]
1443 cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
1444 cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1447 ;; Floating-point comparisons predicated with a PTRUE.
1448 (define_insn "*fcm<cmp_op><mode>"
1449 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1451 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1453 (match_operand:SVE_F 2 "register_operand" "w, w")
1454 (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))]
1455 UNSPEC_MERGE_PTRUE))]
1458 fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
1459 fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1462 (define_insn "*fcmuo<mode>"
1463 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
1465 [(match_operand:<VPRED> 1 "register_operand" "Upl")
1467 (match_operand:SVE_F 2 "register_operand" "w")
1468 (match_operand:SVE_F 3 "register_operand" "w"))]
1469 UNSPEC_MERGE_PTRUE))]
1471 "fcmuo\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1474 ;; Floating-point comparisons predicated on a PTRUE, with the results ANDed
1475 ;; with another predicate P. This does not have the same trapping behavior
1476 ;; as predicating the comparison itself on P, but it's a legitimate fold,
1477 ;; since we can drop any potentially-trapping operations whose results
1480 ;; Split the instruction into its preferred form (below) at the earliest
1481 ;; opportunity, in order to get rid of the redundant operand 1.
1482 (define_insn_and_split "*fcm<cmp_op><mode>_and_combine"
1483 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1486 [(match_operand:<VPRED> 1)
1488 (match_operand:SVE_F 2 "register_operand" "w, w")
1489 (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))]
1491 (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))]
1503 (define_insn_and_split "*fcmuo<mode>_and_combine"
1504 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
1507 [(match_operand:<VPRED> 1)
1509 (match_operand:SVE_F 2 "register_operand" "w")
1510 (match_operand:SVE_F 3 "register_operand" "w"))]
1512 (match_operand:<VPRED> 4 "register_operand" "Upl")))]
1524 ;; Unpredicated floating-point comparisons, with the results ANDed
1525 ;; with another predicate. This is a valid fold for the same reasons
1527 (define_insn "*fcm<cmp_op><mode>_and"
1528 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1531 (match_operand:SVE_F 2 "register_operand" "w, w")
1532 (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))
1533 (match_operand:<VPRED> 1 "register_operand" "Upl, Upl")))]
1536 fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
1537 fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1540 (define_insn "*fcmuo<mode>_and"
1541 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
1544 (match_operand:SVE_F 2 "register_operand" "w")
1545 (match_operand:SVE_F 3 "register_operand" "w"))
1546 (match_operand:<VPRED> 1 "register_operand" "Upl")))]
1548 "fcmuo\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1551 ;; Predicated floating-point comparisons. We don't need a version
1552 ;; of this for unordered comparisons.
1553 (define_insn "*pred_fcm<cmp_op><mode>"
1554 [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1556 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1557 (match_operand:SVE_F 2 "register_operand" "w, w")
1558 (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w")]
1562 fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
1563 fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1566 ;; vcond_mask operand order: true, false, mask
1567 ;; UNSPEC_SEL operand order: mask, true, false (as for VEC_COND_EXPR)
1568 ;; SEL operand order: mask, true, false
1569 (define_insn "vcond_mask_<mode><vpred>"
1570 [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
1572 [(match_operand:<VPRED> 3 "register_operand" "Upa")
1573 (match_operand:SVE_ALL 1 "register_operand" "w")
1574 (match_operand:SVE_ALL 2 "register_operand" "w")]
1577 "sel\t%0.<Vetype>, %3, %1.<Vetype>, %2.<Vetype>"
1580 ;; Selects between a duplicated immediate and zero.
1581 (define_insn "aarch64_sve_dup<mode>_const"
1582 [(set (match_operand:SVE_I 0 "register_operand" "=w")
1584 [(match_operand:<VPRED> 1 "register_operand" "Upl")
1585 (match_operand:SVE_I 2 "aarch64_sve_dup_immediate")
1586 (match_operand:SVE_I 3 "aarch64_simd_imm_zero")]
1589 "mov\t%0.<Vetype>, %1/z, #%2"
1592 ;; Integer (signed) vcond. Don't enforce an immediate range here, since it
1593 ;; depends on the comparison; leave it to aarch64_expand_sve_vcond instead.
1594 (define_expand "vcond<mode><v_int_equiv>"
1595 [(set (match_operand:SVE_ALL 0 "register_operand")
1596 (if_then_else:SVE_ALL
1597 (match_operator 3 "comparison_operator"
1598 [(match_operand:<V_INT_EQUIV> 4 "register_operand")
1599 (match_operand:<V_INT_EQUIV> 5 "nonmemory_operand")])
1600 (match_operand:SVE_ALL 1 "register_operand")
1601 (match_operand:SVE_ALL 2 "register_operand")))]
1604 aarch64_expand_sve_vcond (<MODE>mode, <V_INT_EQUIV>mode, operands);
1609 ;; Integer vcondu. Don't enforce an immediate range here, since it
1610 ;; depends on the comparison; leave it to aarch64_expand_sve_vcond instead.
1611 (define_expand "vcondu<mode><v_int_equiv>"
1612 [(set (match_operand:SVE_ALL 0 "register_operand")
1613 (if_then_else:SVE_ALL
1614 (match_operator 3 "comparison_operator"
1615 [(match_operand:<V_INT_EQUIV> 4 "register_operand")
1616 (match_operand:<V_INT_EQUIV> 5 "nonmemory_operand")])
1617 (match_operand:SVE_ALL 1 "register_operand")
1618 (match_operand:SVE_ALL 2 "register_operand")))]
1621 aarch64_expand_sve_vcond (<MODE>mode, <V_INT_EQUIV>mode, operands);
1626 ;; Floating-point vcond. All comparisons except FCMUO allow a zero
1627 ;; operand; aarch64_expand_sve_vcond handles the case of an FCMUO
1629 (define_expand "vcond<mode><v_fp_equiv>"
1630 [(set (match_operand:SVE_SD 0 "register_operand")
1631 (if_then_else:SVE_SD
1632 (match_operator 3 "comparison_operator"
1633 [(match_operand:<V_FP_EQUIV> 4 "register_operand")
1634 (match_operand:<V_FP_EQUIV> 5 "aarch64_simd_reg_or_zero")])
1635 (match_operand:SVE_SD 1 "register_operand")
1636 (match_operand:SVE_SD 2 "register_operand")))]
1639 aarch64_expand_sve_vcond (<MODE>mode, <V_FP_EQUIV>mode, operands);
1644 ;; Signed integer comparisons. Don't enforce an immediate range here, since
1645 ;; it depends on the comparison; leave it to aarch64_expand_sve_vec_cmp_int
1647 (define_expand "vec_cmp<mode><vpred>"
1649 [(set (match_operand:<VPRED> 0 "register_operand")
1650 (match_operator:<VPRED> 1 "comparison_operator"
1651 [(match_operand:SVE_I 2 "register_operand")
1652 (match_operand:SVE_I 3 "nonmemory_operand")]))
1653 (clobber (reg:CC CC_REGNUM))])]
1656 aarch64_expand_sve_vec_cmp_int (operands[0], GET_CODE (operands[1]),
1657 operands[2], operands[3]);
1662 ;; Unsigned integer comparisons. Don't enforce an immediate range here, since
1663 ;; it depends on the comparison; leave it to aarch64_expand_sve_vec_cmp_int
1665 (define_expand "vec_cmpu<mode><vpred>"
1667 [(set (match_operand:<VPRED> 0 "register_operand")
1668 (match_operator:<VPRED> 1 "comparison_operator"
1669 [(match_operand:SVE_I 2 "register_operand")
1670 (match_operand:SVE_I 3 "nonmemory_operand")]))
1671 (clobber (reg:CC CC_REGNUM))])]
1674 aarch64_expand_sve_vec_cmp_int (operands[0], GET_CODE (operands[1]),
1675 operands[2], operands[3]);
1680 ;; Floating-point comparisons. All comparisons except FCMUO allow a zero
1681 ;; operand; aarch64_expand_sve_vec_cmp_float handles the case of an FCMUO
1683 (define_expand "vec_cmp<mode><vpred>"
1684 [(set (match_operand:<VPRED> 0 "register_operand")
1685 (match_operator:<VPRED> 1 "comparison_operator"
1686 [(match_operand:SVE_F 2 "register_operand")
1687 (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero")]))]
1690 aarch64_expand_sve_vec_cmp_float (operands[0], GET_CODE (operands[1]),
1691 operands[2], operands[3], false);
1696 ;; Branch based on predicate equality or inequality.
1697 (define_expand "cbranch<mode>4"
1700 (match_operator 0 "aarch64_equality_operator"
1701 [(match_operand:PRED_ALL 1 "register_operand")
1702 (match_operand:PRED_ALL 2 "aarch64_simd_reg_or_zero")])
1703 (label_ref (match_operand 3 ""))
1707 rtx ptrue = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));
1709 if (operands[2] == CONST0_RTX (<MODE>mode))
1713 pred = gen_reg_rtx (<MODE>mode);
1714 emit_insn (gen_pred_xor<mode>3 (pred, ptrue, operands[1],
1717 emit_insn (gen_ptest_ptrue<mode> (ptrue, pred));
1718 operands[1] = gen_rtx_REG (CCmode, CC_REGNUM);
1719 operands[2] = const0_rtx;
1723 ;; Unpredicated integer MIN/MAX.
1724 (define_expand "<su><maxmin><mode>3"
1725 [(set (match_operand:SVE_I 0 "register_operand")
1728 (MAXMIN:SVE_I (match_operand:SVE_I 1 "register_operand")
1729 (match_operand:SVE_I 2 "register_operand"))]
1730 UNSPEC_MERGE_PTRUE))]
1733 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1737 ;; Integer MIN/MAX predicated with a PTRUE.
1738 (define_insn "*<su><maxmin><mode>3"
1739 [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
1741 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1742 (MAXMIN:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w")
1743 (match_operand:SVE_I 3 "register_operand" "w, w"))]
1744 UNSPEC_MERGE_PTRUE))]
1747 <su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1748 movprfx\t%0, %2\;<su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1749 [(set_attr "movprfx" "*,yes")]
1752 ;; Unpredicated floating-point MIN/MAX.
1753 (define_expand "<su><maxmin><mode>3"
1754 [(set (match_operand:SVE_F 0 "register_operand")
1757 (FMAXMIN:SVE_F (match_operand:SVE_F 1 "register_operand")
1758 (match_operand:SVE_F 2 "register_operand"))]
1759 UNSPEC_MERGE_PTRUE))]
1762 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1766 ;; Floating-point MIN/MAX predicated with a PTRUE.
1767 (define_insn "*<su><maxmin><mode>3"
1768 [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
1770 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1771 (FMAXMIN:SVE_F (match_operand:SVE_F 2 "register_operand" "%0, w")
1772 (match_operand:SVE_F 3 "register_operand" "w, w"))]
1773 UNSPEC_MERGE_PTRUE))]
1776 f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1777 movprfx\t%0, %2\;f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1778 [(set_attr "movprfx" "*,yes")]
1781 ;; Unpredicated fmin/fmax.
1782 (define_expand "<maxmin_uns><mode>3"
1783 [(set (match_operand:SVE_F 0 "register_operand")
1786 (unspec:SVE_F [(match_operand:SVE_F 1 "register_operand")
1787 (match_operand:SVE_F 2 "register_operand")]
1789 UNSPEC_MERGE_PTRUE))]
1792 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1796 ;; fmin/fmax predicated with a PTRUE.
1797 (define_insn "*<maxmin_uns><mode>3"
1798 [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
1800 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1801 (unspec:SVE_F [(match_operand:SVE_F 2 "register_operand" "%0, w")
1802 (match_operand:SVE_F 3 "register_operand" "w, w")]
1804 UNSPEC_MERGE_PTRUE))]
1807 <maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1808 movprfx\t%0, %2\;<maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1809 [(set_attr "movprfx" "*,yes")]
1812 ;; Predicated integer operations with select.
1813 (define_expand "cond_<optab><mode>"
1814 [(set (match_operand:SVE_I 0 "register_operand")
1816 [(match_operand:<VPRED> 1 "register_operand")
1817 (SVE_INT_BINARY:SVE_I
1818 (match_operand:SVE_I 2 "register_operand")
1819 (match_operand:SVE_I 3 "register_operand"))
1820 (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero")]
1825 (define_expand "cond_<optab><mode>"
1826 [(set (match_operand:SVE_SDI 0 "register_operand")
1828 [(match_operand:<VPRED> 1 "register_operand")
1829 (SVE_INT_BINARY_SD:SVE_SDI
1830 (match_operand:SVE_SDI 2 "register_operand")
1831 (match_operand:SVE_SDI 3 "register_operand"))
1832 (match_operand:SVE_SDI 4 "aarch64_simd_reg_or_zero")]
1837 ;; Predicated integer operations with select matching the output operand.
1838 (define_insn "*cond_<optab><mode>_0"
1839 [(set (match_operand:SVE_I 0 "register_operand" "+w, w, ?&w")
1841 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1842 (SVE_INT_BINARY:SVE_I
1843 (match_operand:SVE_I 2 "register_operand" "0, w, w")
1844 (match_operand:SVE_I 3 "register_operand" "w, 0, w"))
1849 <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1850 <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1851 movprfx\t%0, %1/m, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1852 [(set_attr "movprfx" "*,*,yes")]
1855 (define_insn "*cond_<optab><mode>_0"
1856 [(set (match_operand:SVE_SDI 0 "register_operand" "+w, w, ?&w")
1858 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1859 (SVE_INT_BINARY_SD:SVE_SDI
1860 (match_operand:SVE_SDI 2 "register_operand" "0, w, w")
1861 (match_operand:SVE_SDI 3 "register_operand" "w, 0, w"))
1866 <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1867 <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1868 movprfx\t%0, %1/m, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1869 [(set_attr "movprfx" "*,*,yes")]
1872 ;; Predicated integer operations with select matching the first operand.
1873 (define_insn "*cond_<optab><mode>_2"
1874 [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
1876 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1877 (SVE_INT_BINARY:SVE_I
1878 (match_operand:SVE_I 2 "register_operand" "0, w")
1879 (match_operand:SVE_I 3 "register_operand" "w, w"))
1884 <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1885 movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1886 [(set_attr "movprfx" "*,yes")]
1889 (define_insn "*cond_<optab><mode>_2"
1890 [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
1892 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1893 (SVE_INT_BINARY_SD:SVE_SDI
1894 (match_operand:SVE_SDI 2 "register_operand" "0, w")
1895 (match_operand:SVE_SDI 3 "register_operand" "w, w"))
1900 <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1901 movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1902 [(set_attr "movprfx" "*,yes")]
1905 ;; Predicated integer operations with select matching the second operand.
1906 (define_insn "*cond_<optab><mode>_3"
1907 [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
1909 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1910 (SVE_INT_BINARY:SVE_I
1911 (match_operand:SVE_I 2 "register_operand" "w, w")
1912 (match_operand:SVE_I 3 "register_operand" "0, w"))
1917 <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1918 movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
1919 [(set_attr "movprfx" "*,yes")]
1922 (define_insn "*cond_<optab><mode>_3"
1923 [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
1925 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1926 (SVE_INT_BINARY_SD:SVE_SDI
1927 (match_operand:SVE_SDI 2 "register_operand" "w, w")
1928 (match_operand:SVE_SDI 3 "register_operand" "0, w"))
1933 <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1934 movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
1935 [(set_attr "movprfx" "*,yes")]
1938 ;; Predicated integer operations with select matching zero.
1939 (define_insn "*cond_<optab><mode>_z"
1940 [(set (match_operand:SVE_I 0 "register_operand" "=&w")
1942 [(match_operand:<VPRED> 1 "register_operand" "Upl")
1943 (SVE_INT_BINARY:SVE_I
1944 (match_operand:SVE_I 2 "register_operand" "w")
1945 (match_operand:SVE_I 3 "register_operand" "w"))
1946 (match_operand:SVE_I 4 "aarch64_simd_imm_zero")]
1949 "movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1950 [(set_attr "movprfx" "yes")]
1953 (define_insn "*cond_<optab><mode>_z"
1954 [(set (match_operand:SVE_SDI 0 "register_operand" "=&w")
1956 [(match_operand:<VPRED> 1 "register_operand" "Upl")
1957 (SVE_INT_BINARY_SD:SVE_SDI
1958 (match_operand:SVE_SDI 2 "register_operand" "w")
1959 (match_operand:SVE_SDI 3 "register_operand" "w"))
1960 (match_operand:SVE_SDI 4 "aarch64_simd_imm_zero")]
1963 "movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1964 [(set_attr "movprfx" "yes")]
1967 ;; Synthetic predications with select unmatched.
1968 (define_insn "*cond_<optab><mode>_any"
1969 [(set (match_operand:SVE_I 0 "register_operand" "=&w")
1971 [(match_operand:<VPRED> 1 "register_operand" "Upl")
1972 (SVE_INT_BINARY:SVE_I
1973 (match_operand:SVE_I 2 "register_operand" "w")
1974 (match_operand:SVE_I 3 "register_operand" "w"))
1975 (match_operand:SVE_I 4 "register_operand" "w")]
1981 (define_insn "*cond_<optab><mode>_any"
1982 [(set (match_operand:SVE_SDI 0 "register_operand" "=&w")
1984 [(match_operand:<VPRED> 1 "register_operand" "Upl")
1985 (SVE_INT_BINARY_SD:SVE_I
1986 (match_operand:SVE_SDI 2 "register_operand" "w")
1987 (match_operand:SVE_SDI 3 "register_operand" "w"))
1988 (match_operand:SVE_SDI 4 "register_operand" "w")]
1995 [(set (match_operand:SVE_I 0 "register_operand")
1997 [(match_operand:<VPRED> 1 "register_operand")
1998 (match_operator:SVE_I 5 "aarch64_sve_any_binary_operator"
1999 [(match_operand:SVE_I 2 "register_operand")
2000 (match_operand:SVE_I 3 "register_operand")])
2001 (match_operand:SVE_I 4 "register_operand")]
2003 "TARGET_SVE && reload_completed
2004 && !(rtx_equal_p (operands[0], operands[4])
2005 || rtx_equal_p (operands[2], operands[4])
2006 || rtx_equal_p (operands[3], operands[4]))"
2007 ; Not matchable by any one insn or movprfx insn. We need a separate select.
2009 (unspec:SVE_I [(match_dup 1) (match_dup 2) (match_dup 4)]
2014 (match_op_dup 5 [(match_dup 0) (match_dup 3)])
2019 ;; Set operand 0 to the last active element in operand 3, or to tied
2020 ;; operand 1 if no elements are active.
2021 (define_insn "fold_extract_last_<mode>"
2022 [(set (match_operand:<VEL> 0 "register_operand" "=r, w")
2024 [(match_operand:<VEL> 1 "register_operand" "0, 0")
2025 (match_operand:<VPRED> 2 "register_operand" "Upl, Upl")
2026 (match_operand:SVE_ALL 3 "register_operand" "w, w")]
2030 clastb\t%<vwcore>0, %2, %<vwcore>0, %3.<Vetype>
2031 clastb\t%<vw>0, %2, %<vw>0, %3.<Vetype>"
2034 ;; Unpredicated integer add reduction.
2035 (define_expand "reduc_plus_scal_<mode>"
2036 [(set (match_operand:<VEL> 0 "register_operand")
2037 (unspec:<VEL> [(match_dup 2)
2038 (match_operand:SVE_I 1 "register_operand")]
2042 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2046 ;; Predicated integer add reduction. The result is always 64-bits.
2047 (define_insn "*reduc_plus_scal_<mode>"
2048 [(set (match_operand:<VEL> 0 "register_operand" "=w")
2049 (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2050 (match_operand:SVE_I 2 "register_operand" "w")]
2053 "uaddv\t%d0, %1, %2.<Vetype>"
2056 ;; Unpredicated floating-point add reduction.
2057 (define_expand "reduc_plus_scal_<mode>"
2058 [(set (match_operand:<VEL> 0 "register_operand")
2059 (unspec:<VEL> [(match_dup 2)
2060 (match_operand:SVE_F 1 "register_operand")]
2064 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2068 ;; Predicated floating-point add reduction.
2069 (define_insn "*reduc_plus_scal_<mode>"
2070 [(set (match_operand:<VEL> 0 "register_operand" "=w")
2071 (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2072 (match_operand:SVE_F 2 "register_operand" "w")]
2075 "faddv\t%<Vetype>0, %1, %2.<Vetype>"
2078 ;; Unpredicated integer MIN/MAX reduction.
2079 (define_expand "reduc_<maxmin_uns>_scal_<mode>"
2080 [(set (match_operand:<VEL> 0 "register_operand")
2081 (unspec:<VEL> [(match_dup 2)
2082 (match_operand:SVE_I 1 "register_operand")]
2086 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2090 ;; Predicated integer MIN/MAX reduction.
2091 (define_insn "*reduc_<maxmin_uns>_scal_<mode>"
2092 [(set (match_operand:<VEL> 0 "register_operand" "=w")
2093 (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2094 (match_operand:SVE_I 2 "register_operand" "w")]
2097 "<maxmin_uns_op>v\t%<Vetype>0, %1, %2.<Vetype>"
2100 ;; Unpredicated floating-point MIN/MAX reduction.
2101 (define_expand "reduc_<maxmin_uns>_scal_<mode>"
2102 [(set (match_operand:<VEL> 0 "register_operand")
2103 (unspec:<VEL> [(match_dup 2)
2104 (match_operand:SVE_F 1 "register_operand")]
2108 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2112 ;; Predicated floating-point MIN/MAX reduction.
2113 (define_insn "*reduc_<maxmin_uns>_scal_<mode>"
2114 [(set (match_operand:<VEL> 0 "register_operand" "=w")
2115 (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2116 (match_operand:SVE_F 2 "register_operand" "w")]
2119 "<maxmin_uns_op>v\t%<Vetype>0, %1, %2.<Vetype>"
2122 (define_expand "reduc_<optab>_scal_<mode>"
2123 [(set (match_operand:<VEL> 0 "register_operand")
2124 (unspec:<VEL> [(match_dup 2)
2125 (match_operand:SVE_I 1 "register_operand")]
2129 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2133 (define_insn "*reduc_<optab>_scal_<mode>"
2134 [(set (match_operand:<VEL> 0 "register_operand" "=w")
2135 (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2136 (match_operand:SVE_I 2 "register_operand" "w")]
2139 "<bit_reduc_op>\t%<Vetype>0, %1, %2.<Vetype>"
2142 ;; Unpredicated in-order FP reductions.
2143 (define_expand "fold_left_plus_<mode>"
2144 [(set (match_operand:<VEL> 0 "register_operand")
2145 (unspec:<VEL> [(match_dup 3)
2146 (match_operand:<VEL> 1 "register_operand")
2147 (match_operand:SVE_F 2 "register_operand")]
2151 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2155 ;; In-order FP reductions predicated with PTRUE.
2156 (define_insn "*fold_left_plus_<mode>"
2157 [(set (match_operand:<VEL> 0 "register_operand" "=w")
2158 (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2159 (match_operand:<VEL> 2 "register_operand" "0")
2160 (match_operand:SVE_F 3 "register_operand" "w")]
2163 "fadda\t%<Vetype>0, %1, %<Vetype>0, %3.<Vetype>"
2166 ;; Predicated form of the above in-order reduction.
2167 (define_insn "*pred_fold_left_plus_<mode>"
2168 [(set (match_operand:<VEL> 0 "register_operand" "=w")
2170 [(match_operand:<VEL> 1 "register_operand" "0")
2172 [(match_operand:<VPRED> 2 "register_operand" "Upl")
2173 (match_operand:SVE_F 3 "register_operand" "w")
2174 (match_operand:SVE_F 4 "aarch64_simd_imm_zero")]
2178 "fadda\t%<Vetype>0, %2, %<Vetype>0, %3.<Vetype>"
2181 ;; Unpredicated floating-point addition.
2182 (define_expand "add<mode>3"
2183 [(set (match_operand:SVE_F 0 "register_operand")
2187 (match_operand:SVE_F 1 "register_operand")
2188 (match_operand:SVE_F 2 "aarch64_sve_float_arith_with_sub_operand"))]
2189 UNSPEC_MERGE_PTRUE))]
2192 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2196 ;; Floating-point addition predicated with a PTRUE.
2197 (define_insn "*add<mode>3"
2198 [(set (match_operand:SVE_F 0 "register_operand" "=w, w, w")
2200 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2202 (match_operand:SVE_F 2 "register_operand" "%0, 0, w")
2203 (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_operand" "vsA, vsN, w"))]
2204 UNSPEC_MERGE_PTRUE))]
2207 fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
2208 fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
2209 fadd\t%0.<Vetype>, %2.<Vetype>, %3.<Vetype>"
2212 ;; Unpredicated floating-point subtraction.
2213 (define_expand "sub<mode>3"
2214 [(set (match_operand:SVE_F 0 "register_operand")
2218 (match_operand:SVE_F 1 "aarch64_sve_float_arith_operand")
2219 (match_operand:SVE_F 2 "register_operand"))]
2220 UNSPEC_MERGE_PTRUE))]
2223 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2227 ;; Floating-point subtraction predicated with a PTRUE.
2228 (define_insn "*sub<mode>3"
2229 [(set (match_operand:SVE_F 0 "register_operand" "=w, w, w, w")
2231 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
2233 (match_operand:SVE_F 2 "aarch64_sve_float_arith_operand" "0, 0, vsA, w")
2234 (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_operand" "vsA, vsN, 0, w"))]
2235 UNSPEC_MERGE_PTRUE))]
2237 && (register_operand (operands[2], <MODE>mode)
2238 || register_operand (operands[3], <MODE>mode))"
2240 fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
2241 fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
2242 fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
2243 fsub\t%0.<Vetype>, %2.<Vetype>, %3.<Vetype>"
2246 ;; Unpredicated floating-point multiplication.
2247 (define_expand "mul<mode>3"
2248 [(set (match_operand:SVE_F 0 "register_operand")
2252 (match_operand:SVE_F 1 "register_operand")
2253 (match_operand:SVE_F 2 "aarch64_sve_float_mul_operand"))]
2254 UNSPEC_MERGE_PTRUE))]
2257 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2261 ;; Floating-point multiplication predicated with a PTRUE.
2262 (define_insn "*mul<mode>3"
2263 [(set (match_operand:SVE_F 0 "register_operand" "=w, w")
2265 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2267 (match_operand:SVE_F 2 "register_operand" "%0, w")
2268 (match_operand:SVE_F 3 "aarch64_sve_float_mul_operand" "vsM, w"))]
2269 UNSPEC_MERGE_PTRUE))]
2272 fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
2273 fmul\t%0.<Vetype>, %2.<Vetype>, %3.<Vetype>"
2276 ;; Unpredicated fma (%0 = (%1 * %2) + %3).
2277 (define_expand "fma<mode>4"
2278 [(set (match_operand:SVE_F 0 "register_operand")
2281 (fma:SVE_F (match_operand:SVE_F 1 "register_operand")
2282 (match_operand:SVE_F 2 "register_operand")
2283 (match_operand:SVE_F 3 "register_operand"))]
2284 UNSPEC_MERGE_PTRUE))]
2287 operands[4] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2291 ;; fma predicated with a PTRUE.
2292 (define_insn "*fma<mode>4"
2293 [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2295 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2296 (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w, w")
2297 (match_operand:SVE_F 4 "register_operand" "w, w, w")
2298 (match_operand:SVE_F 2 "register_operand" "w, 0, w"))]
2299 UNSPEC_MERGE_PTRUE))]
2302 fmad\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
2303 fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2304 movprfx\t%0, %2\;fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2305 [(set_attr "movprfx" "*,*,yes")]
2308 ;; Unpredicated fnma (%0 = (-%1 * %2) + %3).
2309 (define_expand "fnma<mode>4"
2310 [(set (match_operand:SVE_F 0 "register_operand")
2313 (fma:SVE_F (neg:SVE_F
2314 (match_operand:SVE_F 1 "register_operand"))
2315 (match_operand:SVE_F 2 "register_operand")
2316 (match_operand:SVE_F 3 "register_operand"))]
2317 UNSPEC_MERGE_PTRUE))]
2320 operands[4] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2324 ;; fnma predicated with a PTRUE.
2325 (define_insn "*fnma<mode>4"
2326 [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2328 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2329 (fma:SVE_F (neg:SVE_F
2330 (match_operand:SVE_F 3 "register_operand" "%0, w, w"))
2331 (match_operand:SVE_F 4 "register_operand" "w, w, w")
2332 (match_operand:SVE_F 2 "register_operand" "w, 0, w"))]
2333 UNSPEC_MERGE_PTRUE))]
2336 fmsb\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
2337 fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2338 movprfx\t%0, %2\;fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2339 [(set_attr "movprfx" "*,*,yes")]
2342 ;; Unpredicated fms (%0 = (%1 * %2) - %3).
2343 (define_expand "fms<mode>4"
2344 [(set (match_operand:SVE_F 0 "register_operand")
2347 (fma:SVE_F (match_operand:SVE_F 1 "register_operand")
2348 (match_operand:SVE_F 2 "register_operand")
2350 (match_operand:SVE_F 3 "register_operand")))]
2351 UNSPEC_MERGE_PTRUE))]
2354 operands[4] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2358 ;; fms predicated with a PTRUE.
2359 (define_insn "*fms<mode>4"
2360 [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2362 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2363 (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w, w")
2364 (match_operand:SVE_F 4 "register_operand" "w, w, w")
2366 (match_operand:SVE_F 2 "register_operand" "w, 0, w")))]
2367 UNSPEC_MERGE_PTRUE))]
2370 fnmsb\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
2371 fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2372 movprfx\t%0, %2\;fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2373 [(set_attr "movprfx" "*,*,yes")]
2376 ;; Unpredicated fnms (%0 = (-%1 * %2) - %3).
2377 (define_expand "fnms<mode>4"
2378 [(set (match_operand:SVE_F 0 "register_operand")
2381 (fma:SVE_F (neg:SVE_F
2382 (match_operand:SVE_F 1 "register_operand"))
2383 (match_operand:SVE_F 2 "register_operand")
2385 (match_operand:SVE_F 3 "register_operand")))]
2386 UNSPEC_MERGE_PTRUE))]
2389 operands[4] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2393 ;; fnms predicated with a PTRUE.
2394 (define_insn "*fnms<mode>4"
2395 [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2397 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2398 (fma:SVE_F (neg:SVE_F
2399 (match_operand:SVE_F 3 "register_operand" "%0, w, w"))
2400 (match_operand:SVE_F 4 "register_operand" "w, w, w")
2402 (match_operand:SVE_F 2 "register_operand" "w, 0, w")))]
2403 UNSPEC_MERGE_PTRUE))]
2406 fnmad\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
2407 fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2408 movprfx\t%0, %2\;fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2409 [(set_attr "movprfx" "*,*,yes")]
2412 ;; Unpredicated floating-point division.
2413 (define_expand "div<mode>3"
2414 [(set (match_operand:SVE_F 0 "register_operand")
2417 (div:SVE_F (match_operand:SVE_F 1 "register_operand")
2418 (match_operand:SVE_F 2 "register_operand"))]
2419 UNSPEC_MERGE_PTRUE))]
2422 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2426 ;; Floating-point division predicated with a PTRUE.
2427 (define_insn "*div<mode>3"
2428 [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2430 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2431 (div:SVE_F (match_operand:SVE_F 2 "register_operand" "0, w, w")
2432 (match_operand:SVE_F 3 "register_operand" "w, 0, w"))]
2433 UNSPEC_MERGE_PTRUE))]
2436 fdiv\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
2437 fdivr\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
2438 movprfx\t%0, %2\;fdiv\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2439 [(set_attr "movprfx" "*,*,yes")]
2442 ;; Unpredicated FNEG, FABS and FSQRT.
2443 (define_expand "<optab><mode>2"
2444 [(set (match_operand:SVE_F 0 "register_operand")
2447 (SVE_FP_UNARY:SVE_F (match_operand:SVE_F 1 "register_operand"))]
2448 UNSPEC_MERGE_PTRUE))]
2451 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2455 ;; FNEG, FABS and FSQRT predicated with a PTRUE.
2456 (define_insn "*<optab><mode>2"
2457 [(set (match_operand:SVE_F 0 "register_operand" "=w")
2459 [(match_operand:<VPRED> 1 "register_operand" "Upl")
2460 (SVE_FP_UNARY:SVE_F (match_operand:SVE_F 2 "register_operand" "w"))]
2461 UNSPEC_MERGE_PTRUE))]
2463 "<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
2466 ;; Unpredicated FRINTy.
2467 (define_expand "<frint_pattern><mode>2"
2468 [(set (match_operand:SVE_F 0 "register_operand")
2471 (unspec:SVE_F [(match_operand:SVE_F 1 "register_operand")]
2473 UNSPEC_MERGE_PTRUE))]
2476 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2480 ;; FRINTy predicated with a PTRUE.
2481 (define_insn "*<frint_pattern><mode>2"
2482 [(set (match_operand:SVE_F 0 "register_operand" "=w")
2484 [(match_operand:<VPRED> 1 "register_operand" "Upl")
2485 (unspec:SVE_F [(match_operand:SVE_F 2 "register_operand" "w")]
2487 UNSPEC_MERGE_PTRUE))]
2489 "frint<frint_suffix>\t%0.<Vetype>, %1/m, %2.<Vetype>"
2492 ;; Unpredicated conversion of floats to integers of the same size (HF to HI,
2493 ;; SF to SI or DF to DI).
2494 (define_expand "<fix_trunc_optab><mode><v_int_equiv>2"
2495 [(set (match_operand:<V_INT_EQUIV> 0 "register_operand")
2496 (unspec:<V_INT_EQUIV>
2498 (FIXUORS:<V_INT_EQUIV>
2499 (match_operand:SVE_F 1 "register_operand"))]
2500 UNSPEC_MERGE_PTRUE))]
2503 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2507 ;; Conversion of SF to DI, SI or HI, predicated with a PTRUE.
2508 (define_insn "*<fix_trunc_optab>v16hsf<mode>2"
2509 [(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
2511 [(match_operand:<VPRED> 1 "register_operand" "Upl")
2513 (match_operand:VNx8HF 2 "register_operand" "w"))]
2514 UNSPEC_MERGE_PTRUE))]
2516 "fcvtz<su>\t%0.<Vetype>, %1/m, %2.h"
2519 ;; Conversion of SF to DI or SI, predicated with a PTRUE.
2520 (define_insn "*<fix_trunc_optab>vnx4sf<mode>2"
2521 [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
2523 [(match_operand:<VPRED> 1 "register_operand" "Upl")
2525 (match_operand:VNx4SF 2 "register_operand" "w"))]
2526 UNSPEC_MERGE_PTRUE))]
2528 "fcvtz<su>\t%0.<Vetype>, %1/m, %2.s"
2531 ;; Conversion of DF to DI or SI, predicated with a PTRUE.
2532 (define_insn "*<fix_trunc_optab>vnx2df<mode>2"
2533 [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
2535 [(match_operand:VNx2BI 1 "register_operand" "Upl")
2537 (match_operand:VNx2DF 2 "register_operand" "w"))]
2538 UNSPEC_MERGE_PTRUE))]
2540 "fcvtz<su>\t%0.<Vetype>, %1/m, %2.d"
2543 ;; Unpredicated conversion of integers to floats of the same size
2544 ;; (HI to HF, SI to SF or DI to DF).
2545 (define_expand "<optab><v_int_equiv><mode>2"
2546 [(set (match_operand:SVE_F 0 "register_operand")
2550 (match_operand:<V_INT_EQUIV> 1 "register_operand"))]
2551 UNSPEC_MERGE_PTRUE))]
2554 operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2558 ;; Conversion of DI, SI or HI to the same number of HFs, predicated
2560 (define_insn "*<optab><mode>vnx8hf2"
2561 [(set (match_operand:VNx8HF 0 "register_operand" "=w")
2563 [(match_operand:<VPRED> 1 "register_operand" "Upl")
2565 (match_operand:SVE_HSDI 2 "register_operand" "w"))]
2566 UNSPEC_MERGE_PTRUE))]
2568 "<su_optab>cvtf\t%0.h, %1/m, %2.<Vetype>"
2571 ;; Conversion of DI or SI to the same number of SFs, predicated with a PTRUE.
2572 (define_insn "*<optab><mode>vnx4sf2"
2573 [(set (match_operand:VNx4SF 0 "register_operand" "=w")
2575 [(match_operand:<VPRED> 1 "register_operand" "Upl")
2577 (match_operand:SVE_SDI 2 "register_operand" "w"))]
2578 UNSPEC_MERGE_PTRUE))]
2580 "<su_optab>cvtf\t%0.s, %1/m, %2.<Vetype>"
2583 ;; Conversion of DI or SI to DF, predicated with a PTRUE.
2584 (define_insn "aarch64_sve_<optab><mode>vnx2df2"
2585 [(set (match_operand:VNx2DF 0 "register_operand" "=w")
2587 [(match_operand:VNx2BI 1 "register_operand" "Upl")
2589 (match_operand:SVE_SDI 2 "register_operand" "w"))]
2590 UNSPEC_MERGE_PTRUE))]
2592 "<su_optab>cvtf\t%0.d, %1/m, %2.<Vetype>"
2595 ;; Conversion of DFs to the same number of SFs, or SFs to the same number
2597 (define_insn "*trunc<Vwide><mode>2"
2598 [(set (match_operand:SVE_HSF 0 "register_operand" "=w")
2600 [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
2602 [(match_operand:<VWIDE> 2 "register_operand" "w")]
2603 UNSPEC_FLOAT_CONVERT)]
2604 UNSPEC_MERGE_PTRUE))]
2606 "fcvt\t%0.<Vetype>, %1/m, %2.<Vewtype>"
2609 ;; Conversion of SFs to the same number of DFs, or HFs to the same number
2611 (define_insn "aarch64_sve_extend<mode><Vwide>2"
2612 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2614 [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
2616 [(match_operand:SVE_HSF 2 "register_operand" "w")]
2617 UNSPEC_FLOAT_CONVERT)]
2618 UNSPEC_MERGE_PTRUE))]
2620 "fcvt\t%0.<Vewtype>, %1/m, %2.<Vetype>"
2623 ;; Unpack the low or high half of a predicate, where "high" refers to
2624 ;; the low-numbered lanes for big-endian and the high-numbered lanes
2625 ;; for little-endian.
2626 (define_expand "vec_unpack<su>_<perm_hilo>_<mode>"
2627 [(match_operand:<VWIDE> 0 "register_operand")
2628 (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand")]
2632 emit_insn ((<hi_lanes_optab>
2633 ? gen_aarch64_sve_punpkhi_<PRED_BHS:mode>
2634 : gen_aarch64_sve_punpklo_<PRED_BHS:mode>)
2635 (operands[0], operands[1]));
2640 ;; PUNPKHI and PUNPKLO.
2641 (define_insn "aarch64_sve_punpk<perm_hilo>_<mode>"
2642 [(set (match_operand:<VWIDE> 0 "register_operand" "=Upa")
2643 (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand" "Upa")]
2646 "punpk<perm_hilo>\t%0.h, %1.b"
2649 ;; Unpack the low or high half of a vector, where "high" refers to
2650 ;; the low-numbered lanes for big-endian and the high-numbered lanes
2651 ;; for little-endian.
2652 (define_expand "vec_unpack<su>_<perm_hilo>_<SVE_BHSI:mode>"
2653 [(match_operand:<VWIDE> 0 "register_operand")
2654 (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand")] UNPACK)]
2657 emit_insn ((<hi_lanes_optab>
2658 ? gen_aarch64_sve_<su>unpkhi_<SVE_BHSI:mode>
2659 : gen_aarch64_sve_<su>unpklo_<SVE_BHSI:mode>)
2660 (operands[0], operands[1]));
2665 ;; SUNPKHI, UUNPKHI, SUNPKLO and UUNPKLO.
2666 (define_insn "aarch64_sve_<su>unpk<perm_hilo>_<SVE_BHSI:mode>"
2667 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2668 (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand" "w")]
2671 "<su>unpk<perm_hilo>\t%0.<Vewtype>, %1.<Vetype>"
2674 ;; Unpack one half of a VNx4SF to VNx2DF, or one half of a VNx8HF to VNx4SF.
2675 ;; First unpack the source without conversion, then float-convert the
2677 (define_expand "vec_unpacks_<perm_hilo>_<mode>"
2678 [(match_operand:<VWIDE> 0 "register_operand")
2679 (unspec:SVE_HSF [(match_operand:SVE_HSF 1 "register_operand")]
2683 /* Use ZIP to do the unpack, since we don't care about the upper halves
2684 and since it has the nice property of not needing any subregs.
2685 If using UUNPK* turns out to be preferable, we could model it as
2686 a ZIP whose first operand is zero. */
2687 rtx temp = gen_reg_rtx (<MODE>mode);
2688 emit_insn ((<hi_lanes_optab>
2689 ? gen_aarch64_sve_zip2<mode>
2690 : gen_aarch64_sve_zip1<mode>)
2691 (temp, operands[1], operands[1]));
2692 rtx ptrue = force_reg (<VWIDE_PRED>mode, CONSTM1_RTX (<VWIDE_PRED>mode));
2693 emit_insn (gen_aarch64_sve_extend<mode><Vwide>2 (operands[0],
2699 ;; Unpack one half of a VNx4SI to VNx2DF. First unpack from VNx4SI
2700 ;; to VNx2DI, reinterpret the VNx2DI as a VNx4SI, then convert the
2701 ;; unpacked VNx4SI to VNx2DF.
2702 (define_expand "vec_unpack<su_optab>_float_<perm_hilo>_vnx4si"
2703 [(match_operand:VNx2DF 0 "register_operand")
2705 (unspec:VNx2DI [(match_operand:VNx4SI 1 "register_operand")]
2709 /* Use ZIP to do the unpack, since we don't care about the upper halves
2710 and since it has the nice property of not needing any subregs.
2711 If using UUNPK* turns out to be preferable, we could model it as
2712 a ZIP whose first operand is zero. */
2713 rtx temp = gen_reg_rtx (VNx4SImode);
2714 emit_insn ((<hi_lanes_optab>
2715 ? gen_aarch64_sve_zip2vnx4si
2716 : gen_aarch64_sve_zip1vnx4si)
2717 (temp, operands[1], operands[1]));
2718 rtx ptrue = force_reg (VNx2BImode, CONSTM1_RTX (VNx2BImode));
2719 emit_insn (gen_aarch64_sve_<FLOATUORS:optab>vnx4sivnx2df2 (operands[0],
2725 ;; Predicate pack. Use UZP1 on the narrower type, which discards
2726 ;; the high part of each wide element.
2727 (define_insn "vec_pack_trunc_<Vwide>"
2728 [(set (match_operand:PRED_BHS 0 "register_operand" "=Upa")
2730 [(match_operand:<VWIDE> 1 "register_operand" "Upa")
2731 (match_operand:<VWIDE> 2 "register_operand" "Upa")]
2734 "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
2737 ;; Integer pack. Use UZP1 on the narrower type, which discards
2738 ;; the high part of each wide element.
2739 (define_insn "vec_pack_trunc_<Vwide>"
2740 [(set (match_operand:SVE_BHSI 0 "register_operand" "=w")
2742 [(match_operand:<VWIDE> 1 "register_operand" "w")
2743 (match_operand:<VWIDE> 2 "register_operand" "w")]
2746 "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
2749 ;; Convert two vectors of DF to SF, or two vectors of SF to HF, and pack
2750 ;; the results into a single vector.
2751 (define_expand "vec_pack_trunc_<Vwide>"
2755 (unspec:SVE_HSF [(match_operand:<VWIDE> 1 "register_operand")]
2756 UNSPEC_FLOAT_CONVERT)]
2757 UNSPEC_MERGE_PTRUE))
2761 (unspec:SVE_HSF [(match_operand:<VWIDE> 2 "register_operand")]
2762 UNSPEC_FLOAT_CONVERT)]
2763 UNSPEC_MERGE_PTRUE))
2764 (set (match_operand:SVE_HSF 0 "register_operand")
2765 (unspec:SVE_HSF [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
2768 operands[3] = force_reg (<VWIDE_PRED>mode, CONSTM1_RTX (<VWIDE_PRED>mode));
2769 operands[4] = gen_reg_rtx (<MODE>mode);
2770 operands[5] = gen_reg_rtx (<MODE>mode);
2774 ;; Convert two vectors of DF to SI and pack the results into a single vector.
2775 (define_expand "vec_pack_<su>fix_trunc_vnx2df"
2779 (FIXUORS:VNx4SI (match_operand:VNx2DF 1 "register_operand"))]
2780 UNSPEC_MERGE_PTRUE))
2784 (FIXUORS:VNx4SI (match_operand:VNx2DF 2 "register_operand"))]
2785 UNSPEC_MERGE_PTRUE))
2786 (set (match_operand:VNx4SI 0 "register_operand")
2787 (unspec:VNx4SI [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
2790 operands[3] = force_reg (VNx2BImode, CONSTM1_RTX (VNx2BImode));
2791 operands[4] = gen_reg_rtx (VNx4SImode);
2792 operands[5] = gen_reg_rtx (VNx4SImode);
2796 ;; Predicated floating-point operations with select.
2797 (define_expand "cond_<optab><mode>"
2798 [(set (match_operand:SVE_F 0 "register_operand")
2800 [(match_operand:<VPRED> 1 "register_operand")
2802 [(match_operand:SVE_F 2 "register_operand")
2803 (match_operand:SVE_F 3 "register_operand")]
2805 (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero")]
2810 ;; Predicated floating-point operations with select matching output.
2811 (define_insn "*cond_<optab><mode>_0"
2812 [(set (match_operand:SVE_F 0 "register_operand" "+w, w, ?&w")
2814 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2816 [(match_operand:SVE_F 2 "register_operand" "0, w, w")
2817 (match_operand:SVE_F 3 "register_operand" "w, 0, w")]
2823 <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
2824 <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
2825 movprfx\t%0, %1/m, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2826 [(set_attr "movprfx" "*,*,yes")]
2829 ;; Predicated floating-point operations with select matching first operand.
2830 (define_insn "*cond_<optab><mode>_2"
2831 [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
2833 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2835 [(match_operand:SVE_F 2 "register_operand" "0, w")
2836 (match_operand:SVE_F 3 "register_operand" "w, w")]
2842 <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
2843 movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2844 [(set_attr "movprfx" "*,yes")]
2847 ;; Predicated floating-point operations with select matching second operand.
2848 (define_insn "*cond_<optab><mode>_3"
2849 [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
2851 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2853 [(match_operand:SVE_F 2 "register_operand" "w, w")
2854 (match_operand:SVE_F 3 "register_operand" "0, w")]
2860 <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
2861 movprfx\t%0, %3\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
2862 [(set_attr "movprfx" "*,yes")]
2865 ;; Predicated floating-point operations with select matching zero.
2866 (define_insn "*cond_<optab><mode>_z"
2867 [(set (match_operand:SVE_F 0 "register_operand" "=&w")
2869 [(match_operand:<VPRED> 1 "register_operand" "Upl")
2871 [(match_operand:SVE_F 2 "register_operand" "w")
2872 (match_operand:SVE_F 3 "register_operand" "w")]
2874 (match_operand:SVE_F 4 "aarch64_simd_imm_zero")]
2877 "movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2878 [(set_attr "movprfx" "yes")]
2881 ;; Synthetic predication of floating-point operations with select unmatched.
2882 (define_insn_and_split "*cond_<optab><mode>_any"
2883 [(set (match_operand:SVE_F 0 "register_operand" "=&w")
2885 [(match_operand:<VPRED> 1 "register_operand" "Upl")
2887 [(match_operand:SVE_F 2 "register_operand" "w")
2888 (match_operand:SVE_F 3 "register_operand" "w")]
2890 (match_operand:SVE_F 4 "register_operand" "w")]
2894 "&& reload_completed
2895 && !(rtx_equal_p (operands[0], operands[4])
2896 || rtx_equal_p (operands[2], operands[4])
2897 || rtx_equal_p (operands[3], operands[4]))"
2898 ; Not matchable by any one insn or movprfx insn. We need a separate select.
2900 (unspec:SVE_F [(match_dup 1) (match_dup 2) (match_dup 4)] UNSPEC_SEL))
2904 (unspec:SVE_F [(match_dup 0) (match_dup 3)] SVE_COND_FP_BINARY)
2909 ;; Predicated floating-point ternary operations with select.
2910 (define_expand "cond_<optab><mode>"
2911 [(set (match_operand:SVE_F 0 "register_operand")
2913 [(match_operand:<VPRED> 1 "register_operand")
2915 [(match_operand:SVE_F 2 "register_operand")
2916 (match_operand:SVE_F 3 "register_operand")
2917 (match_operand:SVE_F 4 "register_operand")]
2918 SVE_COND_FP_TERNARY)
2919 (match_operand:SVE_F 5 "aarch64_simd_reg_or_zero")]
2923 /* Swap the multiplication operands if the fallback value is the
2924 second of the two. */
2925 if (rtx_equal_p (operands[3], operands[5]))
2926 std::swap (operands[2], operands[3]);
2929 ;; Predicated floating-point ternary operations using the FMAD-like form.
2930 (define_insn "*cond_<optab><mode>_2"
2931 [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
2933 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2935 [(match_operand:SVE_F 2 "register_operand" "0, w")
2936 (match_operand:SVE_F 3 "register_operand" "w, w")
2937 (match_operand:SVE_F 4 "register_operand" "w, w")]
2938 SVE_COND_FP_TERNARY)
2943 <sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2944 movprfx\t%0, %2\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2945 [(set_attr "movprfx" "*,yes")]
2948 ;; Predicated floating-point ternary operations using the FMLA-like form.
2949 (define_insn "*cond_<optab><mode>_4"
2950 [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
2952 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2954 [(match_operand:SVE_F 2 "register_operand" "w, w")
2955 (match_operand:SVE_F 3 "register_operand" "w, w")
2956 (match_operand:SVE_F 4 "register_operand" "0, w")]
2957 SVE_COND_FP_TERNARY)
2962 <sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
2963 movprfx\t%0, %4\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
2964 [(set_attr "movprfx" "*,yes")]
2967 ;; Predicated floating-point ternary operations in which the value for
2968 ;; inactive lanes is distinct from the other inputs.
2969 (define_insn_and_split "*cond_<optab><mode>_any"
2970 [(set (match_operand:SVE_F 0 "register_operand" "=&w, &w, ?&w")
2972 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2974 [(match_operand:SVE_F 2 "register_operand" "w, w, w")
2975 (match_operand:SVE_F 3 "register_operand" "w, w, w")
2976 (match_operand:SVE_F 4 "register_operand" "w, w, w")]
2977 SVE_COND_FP_TERNARY)
2978 (match_operand:SVE_F 5 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
2981 && !rtx_equal_p (operands[2], operands[5])
2982 && !rtx_equal_p (operands[3], operands[5])
2983 && !rtx_equal_p (operands[4], operands[5])"
2985 movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
2986 movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
2988 "&& reload_completed
2989 && !CONSTANT_P (operands[5])
2990 && !rtx_equal_p (operands[0], operands[5])"
2992 (unspec:SVE_F [(match_dup 1) (match_dup 4) (match_dup 5)] UNSPEC_SEL))
2996 (unspec:SVE_F [(match_dup 2) (match_dup 3) (match_dup 0)]
2997 SVE_COND_FP_TERNARY)
3001 [(set_attr "movprfx" "yes")]
3004 ;; Shift an SVE vector left and insert a scalar into element 0.
3005 (define_insn "vec_shl_insert_<mode>"
3006 [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w")
3008 [(match_operand:SVE_ALL 1 "register_operand" "0, 0")
3009 (match_operand:<VEL> 2 "register_operand" "rZ, w")]
3013 insr\t%0.<Vetype>, %<vwcore>2
3014 insr\t%0.<Vetype>, %<Vetype>2"