1 ;; Machine description for AArch64 AdvSIMD architecture.
2 ;; Copyright (C) 2011-2014 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 (define_expand "mov<mode>"
22 [(set (match_operand:VALL 0 "nonimmediate_operand" "")
23 (match_operand:VALL 1 "general_operand" ""))]
26 if (GET_CODE (operands[0]) == MEM)
27 operands[1] = force_reg (<MODE>mode, operands[1]);
31 (define_expand "movmisalign<mode>"
32 [(set (match_operand:VALL 0 "nonimmediate_operand" "")
33 (match_operand:VALL 1 "general_operand" ""))]
36 /* This pattern is not permitted to fail during expansion: if both arguments
37 are non-registers (e.g. memory := constant, which can be created by the
38 auto-vectorizer), force operand 1 into a register. */
39 if (!register_operand (operands[0], <MODE>mode)
40 && !register_operand (operands[1], <MODE>mode))
41 operands[1] = force_reg (<MODE>mode, operands[1]);
44 (define_insn "aarch64_simd_dup<mode>"
45 [(set (match_operand:VDQ 0 "register_operand" "=w, w")
46 (vec_duplicate:VDQ (match_operand:<VEL> 1 "register_operand" "r, w")))]
49 dup\\t%0.<Vtype>, %<vw>1
50 dup\\t%0.<Vtype>, %1.<Vetype>[0]"
51 [(set_attr "type" "neon_from_gp<q>, neon_dup<q>")]
54 (define_insn "aarch64_simd_dup<mode>"
55 [(set (match_operand:VDQF 0 "register_operand" "=w")
56 (vec_duplicate:VDQF (match_operand:<VEL> 1 "register_operand" "w")))]
58 "dup\\t%0.<Vtype>, %1.<Vetype>[0]"
59 [(set_attr "type" "neon_dup<q>")]
62 (define_insn "aarch64_dup_lane<mode>"
63 [(set (match_operand:VALL 0 "register_operand" "=w")
66 (match_operand:VALL 1 "register_operand" "w")
67 (parallel [(match_operand:SI 2 "immediate_operand" "i")])
71 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
72 return "dup\\t%0.<Vtype>, %1.<Vetype>[%2]";
74 [(set_attr "type" "neon_dup<q>")]
77 (define_insn "aarch64_dup_lane_<vswap_width_name><mode>"
78 [(set (match_operand:VALL 0 "register_operand" "=w")
81 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "w")
82 (parallel [(match_operand:SI 2 "immediate_operand" "i")])
86 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
87 INTVAL (operands[2])));
88 return "dup\\t%0.<Vtype>, %1.<Vetype>[%2]";
90 [(set_attr "type" "neon_dup<q>")]
93 (define_insn "*aarch64_simd_mov<mode>"
94 [(set (match_operand:VD 0 "nonimmediate_operand"
95 "=w, m, w, ?r, ?w, ?r, w")
96 (match_operand:VD 1 "general_operand"
97 "m, w, w, w, r, r, Dn"))]
99 && (register_operand (operands[0], <MODE>mode)
100 || register_operand (operands[1], <MODE>mode))"
102 switch (which_alternative)
104 case 0: return "ldr\\t%d0, %1";
105 case 1: return "str\\t%d1, %0";
106 case 2: return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
107 case 3: return "umov\t%0, %1.d[0]";
108 case 4: return "ins\t%0.d[0], %1";
109 case 5: return "mov\t%0, %1";
111 return aarch64_output_simd_mov_immediate (operands[1],
113 default: gcc_unreachable ();
116 [(set_attr "type" "neon_load1_1reg<q>, neon_store1_1reg<q>,\
117 neon_logic<q>, neon_to_gp<q>, neon_from_gp<q>,\
118 mov_reg, neon_move<q>")]
121 (define_insn "*aarch64_simd_mov<mode>"
122 [(set (match_operand:VQ 0 "nonimmediate_operand"
123 "=w, m, w, ?r, ?w, ?r, w")
124 (match_operand:VQ 1 "general_operand"
125 "m, w, w, w, r, r, Dn"))]
127 && (register_operand (operands[0], <MODE>mode)
128 || register_operand (operands[1], <MODE>mode))"
130 switch (which_alternative)
133 return "ldr\\t%q0, %1";
135 return "str\\t%q1, %0";
137 return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
143 return aarch64_output_simd_mov_immediate (operands[1], <MODE>mode, 128);
148 [(set_attr "type" "neon_load1_1reg<q>, neon_store1_1reg<q>,\
149 neon_logic<q>, multiple, multiple, multiple,\
151 (set_attr "length" "4,4,4,8,8,8,4")]
155 [(set (match_operand:VQ 0 "register_operand" "")
156 (match_operand:VQ 1 "register_operand" ""))]
157 "TARGET_SIMD && reload_completed
158 && GP_REGNUM_P (REGNO (operands[0]))
159 && GP_REGNUM_P (REGNO (operands[1]))"
160 [(set (match_dup 0) (match_dup 1))
161 (set (match_dup 2) (match_dup 3))]
163 int rdest = REGNO (operands[0]);
164 int rsrc = REGNO (operands[1]);
167 dest[0] = gen_rtx_REG (DImode, rdest);
168 src[0] = gen_rtx_REG (DImode, rsrc);
169 dest[1] = gen_rtx_REG (DImode, rdest + 1);
170 src[1] = gen_rtx_REG (DImode, rsrc + 1);
172 aarch64_simd_disambiguate_copy (operands, dest, src, 2);
176 [(set (match_operand:VQ 0 "register_operand" "")
177 (match_operand:VQ 1 "register_operand" ""))]
178 "TARGET_SIMD && reload_completed
179 && ((FP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1])))
180 || (GP_REGNUM_P (REGNO (operands[0])) && FP_REGNUM_P (REGNO (operands[1]))))"
183 aarch64_split_simd_move (operands[0], operands[1]);
187 (define_expand "aarch64_split_simd_mov<mode>"
188 [(set (match_operand:VQ 0)
189 (match_operand:VQ 1))]
192 rtx dst = operands[0];
193 rtx src = operands[1];
195 if (GP_REGNUM_P (REGNO (src)))
197 rtx src_low_part = gen_lowpart (<VHALF>mode, src);
198 rtx src_high_part = gen_highpart (<VHALF>mode, src);
201 (gen_move_lo_quad_<mode> (dst, src_low_part));
203 (gen_move_hi_quad_<mode> (dst, src_high_part));
208 rtx dst_low_part = gen_lowpart (<VHALF>mode, dst);
209 rtx dst_high_part = gen_highpart (<VHALF>mode, dst);
210 rtx lo = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
211 rtx hi = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
214 (gen_aarch64_simd_mov_from_<mode>low (dst_low_part, src, lo));
216 (gen_aarch64_simd_mov_from_<mode>high (dst_high_part, src, hi));
222 (define_insn "aarch64_simd_mov_from_<mode>low"
223 [(set (match_operand:<VHALF> 0 "register_operand" "=r")
225 (match_operand:VQ 1 "register_operand" "w")
226 (match_operand:VQ 2 "vect_par_cnst_lo_half" "")))]
227 "TARGET_SIMD && reload_completed"
229 [(set_attr "type" "neon_to_gp<q>")
230 (set_attr "length" "4")
233 (define_insn "aarch64_simd_mov_from_<mode>high"
234 [(set (match_operand:<VHALF> 0 "register_operand" "=r")
236 (match_operand:VQ 1 "register_operand" "w")
237 (match_operand:VQ 2 "vect_par_cnst_hi_half" "")))]
238 "TARGET_SIMD && reload_completed"
240 [(set_attr "type" "neon_to_gp<q>")
241 (set_attr "length" "4")
244 (define_insn "orn<mode>3"
245 [(set (match_operand:VDQ 0 "register_operand" "=w")
246 (ior:VDQ (not:VDQ (match_operand:VDQ 1 "register_operand" "w"))
247 (match_operand:VDQ 2 "register_operand" "w")))]
249 "orn\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
250 [(set_attr "type" "neon_logic<q>")]
253 (define_insn "bic<mode>3"
254 [(set (match_operand:VDQ 0 "register_operand" "=w")
255 (and:VDQ (not:VDQ (match_operand:VDQ 1 "register_operand" "w"))
256 (match_operand:VDQ 2 "register_operand" "w")))]
258 "bic\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
259 [(set_attr "type" "neon_logic<q>")]
262 (define_insn "add<mode>3"
263 [(set (match_operand:VDQ 0 "register_operand" "=w")
264 (plus:VDQ (match_operand:VDQ 1 "register_operand" "w")
265 (match_operand:VDQ 2 "register_operand" "w")))]
267 "add\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
268 [(set_attr "type" "neon_add<q>")]
271 (define_insn "sub<mode>3"
272 [(set (match_operand:VDQ 0 "register_operand" "=w")
273 (minus:VDQ (match_operand:VDQ 1 "register_operand" "w")
274 (match_operand:VDQ 2 "register_operand" "w")))]
276 "sub\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
277 [(set_attr "type" "neon_sub<q>")]
280 (define_insn "mul<mode>3"
281 [(set (match_operand:VDQM 0 "register_operand" "=w")
282 (mult:VDQM (match_operand:VDQM 1 "register_operand" "w")
283 (match_operand:VDQM 2 "register_operand" "w")))]
285 "mul\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
286 [(set_attr "type" "neon_mul_<Vetype><q>")]
289 (define_insn "bswap<mode>"
290 [(set (match_operand:VDQHSD 0 "register_operand" "=w")
291 (bswap:VDQHSD (match_operand:VDQHSD 1 "register_operand" "w")))]
293 "rev<Vrevsuff>\\t%0.<Vbtype>, %1.<Vbtype>"
294 [(set_attr "type" "neon_rev<q>")]
297 (define_insn "aarch64_rbit<mode>"
298 [(set (match_operand:VB 0 "register_operand" "=w")
299 (unspec:VB [(match_operand:VB 1 "register_operand" "w")]
302 "rbit\\t%0.<Vbtype>, %1.<Vbtype>"
303 [(set_attr "type" "neon_rbit")]
306 (define_insn "*aarch64_mul3_elt<mode>"
307 [(set (match_operand:VMUL 0 "register_operand" "=w")
311 (match_operand:VMUL 1 "register_operand" "<h_con>")
312 (parallel [(match_operand:SI 2 "immediate_operand")])))
313 (match_operand:VMUL 3 "register_operand" "w")))]
316 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
317 return "<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]";
319 [(set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")]
322 (define_insn "*aarch64_mul3_elt_<vswap_width_name><mode>"
323 [(set (match_operand:VMUL_CHANGE_NLANES 0 "register_operand" "=w")
324 (mult:VMUL_CHANGE_NLANES
325 (vec_duplicate:VMUL_CHANGE_NLANES
327 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
328 (parallel [(match_operand:SI 2 "immediate_operand")])))
329 (match_operand:VMUL_CHANGE_NLANES 3 "register_operand" "w")))]
332 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
333 INTVAL (operands[2])));
334 return "<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]";
336 [(set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")]
339 (define_insn "*aarch64_mul3_elt_to_128df"
340 [(set (match_operand:V2DF 0 "register_operand" "=w")
343 (match_operand:DF 2 "register_operand" "w"))
344 (match_operand:V2DF 1 "register_operand" "w")))]
346 "fmul\\t%0.2d, %1.2d, %2.d[0]"
347 [(set_attr "type" "neon_fp_mul_d_scalar_q")]
350 (define_insn "*aarch64_mul3_elt_to_64v2df"
351 [(set (match_operand:DF 0 "register_operand" "=w")
354 (match_operand:V2DF 1 "register_operand" "w")
355 (parallel [(match_operand:SI 2 "immediate_operand")]))
356 (match_operand:DF 3 "register_operand" "w")))]
359 operands[2] = GEN_INT (ENDIAN_LANE_N (V2DFmode, INTVAL (operands[2])));
360 return "fmul\\t%0.2d, %3.2d, %1.d[%2]";
362 [(set_attr "type" "neon_fp_mul_d_scalar_q")]
365 (define_insn "neg<mode>2"
366 [(set (match_operand:VDQ 0 "register_operand" "=w")
367 (neg:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
369 "neg\t%0.<Vtype>, %1.<Vtype>"
370 [(set_attr "type" "neon_neg<q>")]
373 (define_insn "abs<mode>2"
374 [(set (match_operand:VDQ 0 "register_operand" "=w")
375 (abs:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
377 "abs\t%0.<Vtype>, %1.<Vtype>"
378 [(set_attr "type" "neon_abs<q>")]
381 (define_insn "abd<mode>_3"
382 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
383 (abs:VDQ_BHSI (minus:VDQ_BHSI
384 (match_operand:VDQ_BHSI 1 "register_operand" "w")
385 (match_operand:VDQ_BHSI 2 "register_operand" "w"))))]
387 "sabd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
388 [(set_attr "type" "neon_abd<q>")]
391 (define_insn "aba<mode>_3"
392 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
393 (plus:VDQ_BHSI (abs:VDQ_BHSI (minus:VDQ_BHSI
394 (match_operand:VDQ_BHSI 1 "register_operand" "w")
395 (match_operand:VDQ_BHSI 2 "register_operand" "w")))
396 (match_operand:VDQ_BHSI 3 "register_operand" "0")))]
398 "saba\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
399 [(set_attr "type" "neon_arith_acc<q>")]
402 (define_insn "fabd<mode>_3"
403 [(set (match_operand:VDQF 0 "register_operand" "=w")
404 (abs:VDQF (minus:VDQF
405 (match_operand:VDQF 1 "register_operand" "w")
406 (match_operand:VDQF 2 "register_operand" "w"))))]
408 "fabd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
409 [(set_attr "type" "neon_fp_abd_<Vetype><q>")]
412 (define_insn "*fabd_scalar<mode>3"
413 [(set (match_operand:GPF 0 "register_operand" "=w")
415 (match_operand:GPF 1 "register_operand" "w")
416 (match_operand:GPF 2 "register_operand" "w"))))]
418 "fabd\t%<s>0, %<s>1, %<s>2"
419 [(set_attr "type" "neon_fp_abd_<Vetype><q>")]
422 (define_insn "and<mode>3"
423 [(set (match_operand:VDQ 0 "register_operand" "=w")
424 (and:VDQ (match_operand:VDQ 1 "register_operand" "w")
425 (match_operand:VDQ 2 "register_operand" "w")))]
427 "and\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
428 [(set_attr "type" "neon_logic<q>")]
431 (define_insn "ior<mode>3"
432 [(set (match_operand:VDQ 0 "register_operand" "=w")
433 (ior:VDQ (match_operand:VDQ 1 "register_operand" "w")
434 (match_operand:VDQ 2 "register_operand" "w")))]
436 "orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
437 [(set_attr "type" "neon_logic<q>")]
440 (define_insn "xor<mode>3"
441 [(set (match_operand:VDQ 0 "register_operand" "=w")
442 (xor:VDQ (match_operand:VDQ 1 "register_operand" "w")
443 (match_operand:VDQ 2 "register_operand" "w")))]
445 "eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
446 [(set_attr "type" "neon_logic<q>")]
449 (define_insn "one_cmpl<mode>2"
450 [(set (match_operand:VDQ 0 "register_operand" "=w")
451 (not:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
453 "not\t%0.<Vbtype>, %1.<Vbtype>"
454 [(set_attr "type" "neon_logic<q>")]
457 (define_insn "aarch64_simd_vec_set<mode>"
458 [(set (match_operand:VQ_S 0 "register_operand" "=w,w")
461 (match_operand:<VEL> 1 "register_operand" "r,w"))
462 (match_operand:VQ_S 3 "register_operand" "0,0")
463 (match_operand:SI 2 "immediate_operand" "i,i")))]
466 int elt = ENDIAN_LANE_N (<MODE>mode, exact_log2 (INTVAL (operands[2])));
467 operands[2] = GEN_INT ((HOST_WIDE_INT) 1 << elt);
468 switch (which_alternative)
471 return "ins\\t%0.<Vetype>[%p2], %w1";
473 return "ins\\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
478 [(set_attr "type" "neon_from_gp<q>, neon_ins<q>")]
481 (define_insn "aarch64_simd_lshr<mode>"
482 [(set (match_operand:VDQ 0 "register_operand" "=w")
483 (lshiftrt:VDQ (match_operand:VDQ 1 "register_operand" "w")
484 (match_operand:VDQ 2 "aarch64_simd_rshift_imm" "Dr")))]
486 "ushr\t%0.<Vtype>, %1.<Vtype>, %2"
487 [(set_attr "type" "neon_shift_imm<q>")]
490 (define_insn "aarch64_simd_ashr<mode>"
491 [(set (match_operand:VDQ 0 "register_operand" "=w")
492 (ashiftrt:VDQ (match_operand:VDQ 1 "register_operand" "w")
493 (match_operand:VDQ 2 "aarch64_simd_rshift_imm" "Dr")))]
495 "sshr\t%0.<Vtype>, %1.<Vtype>, %2"
496 [(set_attr "type" "neon_shift_imm<q>")]
499 (define_insn "aarch64_simd_imm_shl<mode>"
500 [(set (match_operand:VDQ 0 "register_operand" "=w")
501 (ashift:VDQ (match_operand:VDQ 1 "register_operand" "w")
502 (match_operand:VDQ 2 "aarch64_simd_lshift_imm" "Dl")))]
504 "shl\t%0.<Vtype>, %1.<Vtype>, %2"
505 [(set_attr "type" "neon_shift_imm<q>")]
508 (define_insn "aarch64_simd_reg_sshl<mode>"
509 [(set (match_operand:VDQ 0 "register_operand" "=w")
510 (ashift:VDQ (match_operand:VDQ 1 "register_operand" "w")
511 (match_operand:VDQ 2 "register_operand" "w")))]
513 "sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
514 [(set_attr "type" "neon_shift_reg<q>")]
517 (define_insn "aarch64_simd_reg_shl<mode>_unsigned"
518 [(set (match_operand:VDQ 0 "register_operand" "=w")
519 (unspec:VDQ [(match_operand:VDQ 1 "register_operand" "w")
520 (match_operand:VDQ 2 "register_operand" "w")]
521 UNSPEC_ASHIFT_UNSIGNED))]
523 "ushl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
524 [(set_attr "type" "neon_shift_reg<q>")]
527 (define_insn "aarch64_simd_reg_shl<mode>_signed"
528 [(set (match_operand:VDQ 0 "register_operand" "=w")
529 (unspec:VDQ [(match_operand:VDQ 1 "register_operand" "w")
530 (match_operand:VDQ 2 "register_operand" "w")]
531 UNSPEC_ASHIFT_SIGNED))]
533 "sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
534 [(set_attr "type" "neon_shift_reg<q>")]
537 (define_expand "ashl<mode>3"
538 [(match_operand:VDQ 0 "register_operand" "")
539 (match_operand:VDQ 1 "register_operand" "")
540 (match_operand:SI 2 "general_operand" "")]
543 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
546 if (CONST_INT_P (operands[2]))
548 shift_amount = INTVAL (operands[2]);
549 if (shift_amount >= 0 && shift_amount < bit_width)
551 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
553 emit_insn (gen_aarch64_simd_imm_shl<mode> (operands[0],
560 operands[2] = force_reg (SImode, operands[2]);
563 else if (MEM_P (operands[2]))
565 operands[2] = force_reg (SImode, operands[2]);
568 if (REG_P (operands[2]))
570 rtx tmp = gen_reg_rtx (<MODE>mode);
571 emit_insn (gen_aarch64_simd_dup<mode> (tmp,
572 convert_to_mode (<VEL>mode,
575 emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
584 (define_expand "lshr<mode>3"
585 [(match_operand:VDQ 0 "register_operand" "")
586 (match_operand:VDQ 1 "register_operand" "")
587 (match_operand:SI 2 "general_operand" "")]
590 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
593 if (CONST_INT_P (operands[2]))
595 shift_amount = INTVAL (operands[2]);
596 if (shift_amount > 0 && shift_amount <= bit_width)
598 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
600 emit_insn (gen_aarch64_simd_lshr<mode> (operands[0],
606 operands[2] = force_reg (SImode, operands[2]);
608 else if (MEM_P (operands[2]))
610 operands[2] = force_reg (SImode, operands[2]);
613 if (REG_P (operands[2]))
615 rtx tmp = gen_reg_rtx (SImode);
616 rtx tmp1 = gen_reg_rtx (<MODE>mode);
617 emit_insn (gen_negsi2 (tmp, operands[2]));
618 emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
619 convert_to_mode (<VEL>mode,
621 emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0],
631 (define_expand "ashr<mode>3"
632 [(match_operand:VDQ 0 "register_operand" "")
633 (match_operand:VDQ 1 "register_operand" "")
634 (match_operand:SI 2 "general_operand" "")]
637 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
640 if (CONST_INT_P (operands[2]))
642 shift_amount = INTVAL (operands[2]);
643 if (shift_amount > 0 && shift_amount <= bit_width)
645 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
647 emit_insn (gen_aarch64_simd_ashr<mode> (operands[0],
653 operands[2] = force_reg (SImode, operands[2]);
655 else if (MEM_P (operands[2]))
657 operands[2] = force_reg (SImode, operands[2]);
660 if (REG_P (operands[2]))
662 rtx tmp = gen_reg_rtx (SImode);
663 rtx tmp1 = gen_reg_rtx (<MODE>mode);
664 emit_insn (gen_negsi2 (tmp, operands[2]));
665 emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
666 convert_to_mode (<VEL>mode,
668 emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0],
678 (define_expand "vashl<mode>3"
679 [(match_operand:VDQ 0 "register_operand" "")
680 (match_operand:VDQ 1 "register_operand" "")
681 (match_operand:VDQ 2 "register_operand" "")]
684 emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
689 ;; Using mode VQ_S as there is no V2DImode neg!
690 ;; Negating individual lanes most certainly offsets the
691 ;; gain from vectorization.
692 (define_expand "vashr<mode>3"
693 [(match_operand:VQ_S 0 "register_operand" "")
694 (match_operand:VQ_S 1 "register_operand" "")
695 (match_operand:VQ_S 2 "register_operand" "")]
698 rtx neg = gen_reg_rtx (<MODE>mode);
699 emit (gen_neg<mode>2 (neg, operands[2]));
700 emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0], operands[1],
706 (define_expand "aarch64_ashr_simddi"
707 [(match_operand:DI 0 "register_operand" "=w")
708 (match_operand:DI 1 "register_operand" "w")
709 (match_operand:SI 2 "aarch64_shift_imm64_di" "")]
712 if (INTVAL (operands[2]) == 64)
713 emit_insn (gen_aarch64_sshr_simddi (operands[0], operands[1]));
715 emit_insn (gen_ashrdi3 (operands[0], operands[1], operands[2]));
720 ;; SIMD shift by 64. This pattern is a special case as standard pattern does
721 ;; not handle NEON shifts by 64.
722 (define_insn "aarch64_sshr_simddi"
723 [(set (match_operand:DI 0 "register_operand" "=w")
725 [(match_operand:DI 1 "register_operand" "w")] UNSPEC_SSHR64))]
728 [(set_attr "type" "neon_shift_imm")]
731 (define_expand "vlshr<mode>3"
732 [(match_operand:VQ_S 0 "register_operand" "")
733 (match_operand:VQ_S 1 "register_operand" "")
734 (match_operand:VQ_S 2 "register_operand" "")]
737 rtx neg = gen_reg_rtx (<MODE>mode);
738 emit (gen_neg<mode>2 (neg, operands[2]));
739 emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0], operands[1],
744 (define_expand "aarch64_lshr_simddi"
745 [(match_operand:DI 0 "register_operand" "=w")
746 (match_operand:DI 1 "register_operand" "w")
747 (match_operand:SI 2 "aarch64_shift_imm64_di" "")]
750 if (INTVAL (operands[2]) == 64)
751 emit_insn (gen_aarch64_ushr_simddi (operands[0], operands[1]));
753 emit_insn (gen_lshrdi3 (operands[0], operands[1], operands[2]));
758 ;; SIMD shift by 64. This pattern is a special case as standard pattern does
759 ;; not handle NEON shifts by 64.
760 (define_insn "aarch64_ushr_simddi"
761 [(set (match_operand:DI 0 "register_operand" "=w")
763 [(match_operand:DI 1 "register_operand" "w")] UNSPEC_USHR64))]
766 [(set_attr "type" "neon_shift_imm")]
769 (define_expand "vec_set<mode>"
770 [(match_operand:VQ_S 0 "register_operand")
771 (match_operand:<VEL> 1 "register_operand")
772 (match_operand:SI 2 "immediate_operand")]
775 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
776 emit_insn (gen_aarch64_simd_vec_set<mode> (operands[0], operands[1],
777 GEN_INT (elem), operands[0]));
782 (define_insn "aarch64_simd_vec_setv2di"
783 [(set (match_operand:V2DI 0 "register_operand" "=w,w")
786 (match_operand:DI 1 "register_operand" "r,w"))
787 (match_operand:V2DI 3 "register_operand" "0,0")
788 (match_operand:SI 2 "immediate_operand" "i,i")))]
791 int elt = ENDIAN_LANE_N (V2DImode, exact_log2 (INTVAL (operands[2])));
792 operands[2] = GEN_INT ((HOST_WIDE_INT) 1 << elt);
793 switch (which_alternative)
796 return "ins\\t%0.d[%p2], %1";
798 return "ins\\t%0.d[%p2], %1.d[0]";
803 [(set_attr "type" "neon_from_gp, neon_ins_q")]
806 (define_expand "vec_setv2di"
807 [(match_operand:V2DI 0 "register_operand")
808 (match_operand:DI 1 "register_operand")
809 (match_operand:SI 2 "immediate_operand")]
812 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
813 emit_insn (gen_aarch64_simd_vec_setv2di (operands[0], operands[1],
814 GEN_INT (elem), operands[0]));
819 (define_insn "aarch64_simd_vec_set<mode>"
820 [(set (match_operand:VDQF 0 "register_operand" "=w")
823 (match_operand:<VEL> 1 "register_operand" "w"))
824 (match_operand:VDQF 3 "register_operand" "0")
825 (match_operand:SI 2 "immediate_operand" "i")))]
828 int elt = ENDIAN_LANE_N (<MODE>mode, exact_log2 (INTVAL (operands[2])));
830 operands[2] = GEN_INT ((HOST_WIDE_INT)1 << elt);
831 return "ins\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
833 [(set_attr "type" "neon_ins<q>")]
836 (define_expand "vec_set<mode>"
837 [(match_operand:VDQF 0 "register_operand" "+w")
838 (match_operand:<VEL> 1 "register_operand" "w")
839 (match_operand:SI 2 "immediate_operand" "")]
842 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
843 emit_insn (gen_aarch64_simd_vec_set<mode> (operands[0], operands[1],
844 GEN_INT (elem), operands[0]));
850 (define_insn "aarch64_mla<mode>"
851 [(set (match_operand:VQ_S 0 "register_operand" "=w")
852 (plus:VQ_S (mult:VQ_S (match_operand:VQ_S 2 "register_operand" "w")
853 (match_operand:VQ_S 3 "register_operand" "w"))
854 (match_operand:VQ_S 1 "register_operand" "0")))]
856 "mla\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
857 [(set_attr "type" "neon_mla_<Vetype><q>")]
860 (define_insn "*aarch64_mla_elt<mode>"
861 [(set (match_operand:VDQHS 0 "register_operand" "=w")
866 (match_operand:VDQHS 1 "register_operand" "<h_con>")
867 (parallel [(match_operand:SI 2 "immediate_operand")])))
868 (match_operand:VDQHS 3 "register_operand" "w"))
869 (match_operand:VDQHS 4 "register_operand" "0")))]
872 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
873 return "mla\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
875 [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
878 (define_insn "*aarch64_mla_elt_<vswap_width_name><mode>"
879 [(set (match_operand:VDQHS 0 "register_operand" "=w")
884 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
885 (parallel [(match_operand:SI 2 "immediate_operand")])))
886 (match_operand:VDQHS 3 "register_operand" "w"))
887 (match_operand:VDQHS 4 "register_operand" "0")))]
890 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
891 INTVAL (operands[2])));
892 return "mla\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
894 [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
897 (define_insn "aarch64_mls<mode>"
898 [(set (match_operand:VQ_S 0 "register_operand" "=w")
899 (minus:VQ_S (match_operand:VQ_S 1 "register_operand" "0")
900 (mult:VQ_S (match_operand:VQ_S 2 "register_operand" "w")
901 (match_operand:VQ_S 3 "register_operand" "w"))))]
903 "mls\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
904 [(set_attr "type" "neon_mla_<Vetype><q>")]
907 (define_insn "*aarch64_mls_elt<mode>"
908 [(set (match_operand:VDQHS 0 "register_operand" "=w")
910 (match_operand:VDQHS 4 "register_operand" "0")
914 (match_operand:VDQHS 1 "register_operand" "<h_con>")
915 (parallel [(match_operand:SI 2 "immediate_operand")])))
916 (match_operand:VDQHS 3 "register_operand" "w"))))]
919 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
920 return "mls\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
922 [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
925 (define_insn "*aarch64_mls_elt_<vswap_width_name><mode>"
926 [(set (match_operand:VDQHS 0 "register_operand" "=w")
928 (match_operand:VDQHS 4 "register_operand" "0")
932 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
933 (parallel [(match_operand:SI 2 "immediate_operand")])))
934 (match_operand:VDQHS 3 "register_operand" "w"))))]
937 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
938 INTVAL (operands[2])));
939 return "mls\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
941 [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
944 ;; Max/Min operations.
945 (define_insn "<su><maxmin><mode>3"
946 [(set (match_operand:VQ_S 0 "register_operand" "=w")
947 (MAXMIN:VQ_S (match_operand:VQ_S 1 "register_operand" "w")
948 (match_operand:VQ_S 2 "register_operand" "w")))]
950 "<su><maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
951 [(set_attr "type" "neon_minmax<q>")]
954 ;; vec_concat gives a new vector with the low elements from operand 1, and
955 ;; the high elements from operand 2. That is to say, given op1 = { a, b }
956 ;; op2 = { c, d }, vec_concat (op1, op2) = { a, b, c, d }.
957 ;; What that means, is that the RTL descriptions of the below patterns
958 ;; need to change depending on endianness.
960 ;; Move to the low architectural bits of the register.
961 ;; On little-endian this is { operand, zeroes }
962 ;; On big-endian this is { zeroes, operand }
964 (define_insn "move_lo_quad_internal_<mode>"
965 [(set (match_operand:VQ_NO2E 0 "register_operand" "=w,w,w")
967 (match_operand:<VHALF> 1 "register_operand" "w,r,r")
968 (vec_duplicate:<VHALF> (const_int 0))))]
969 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
974 [(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
975 (set_attr "simd" "yes,*,yes")
976 (set_attr "fp" "*,yes,*")
977 (set_attr "length" "4")]
980 (define_insn "move_lo_quad_internal_<mode>"
981 [(set (match_operand:VQ_2E 0 "register_operand" "=w,w,w")
983 (match_operand:<VHALF> 1 "register_operand" "w,r,r")
985 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
990 [(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
991 (set_attr "simd" "yes,*,yes")
992 (set_attr "fp" "*,yes,*")
993 (set_attr "length" "4")]
996 (define_insn "move_lo_quad_internal_be_<mode>"
997 [(set (match_operand:VQ_NO2E 0 "register_operand" "=w,w,w")
999 (vec_duplicate:<VHALF> (const_int 0))
1000 (match_operand:<VHALF> 1 "register_operand" "w,r,r")))]
1001 "TARGET_SIMD && BYTES_BIG_ENDIAN"
1006 [(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
1007 (set_attr "simd" "yes,*,yes")
1008 (set_attr "fp" "*,yes,*")
1009 (set_attr "length" "4")]
1012 (define_insn "move_lo_quad_internal_be_<mode>"
1013 [(set (match_operand:VQ_2E 0 "register_operand" "=w,w,w")
1016 (match_operand:<VHALF> 1 "register_operand" "w,r,r")))]
1017 "TARGET_SIMD && BYTES_BIG_ENDIAN"
1022 [(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
1023 (set_attr "simd" "yes,*,yes")
1024 (set_attr "fp" "*,yes,*")
1025 (set_attr "length" "4")]
1028 (define_expand "move_lo_quad_<mode>"
1029 [(match_operand:VQ 0 "register_operand")
1030 (match_operand:VQ 1 "register_operand")]
1033 if (BYTES_BIG_ENDIAN)
1034 emit_insn (gen_move_lo_quad_internal_be_<mode> (operands[0], operands[1]));
1036 emit_insn (gen_move_lo_quad_internal_<mode> (operands[0], operands[1]));
1041 ;; Move operand1 to the high architectural bits of the register, keeping
1042 ;; the low architectural bits of operand2.
1043 ;; For little-endian this is { operand2, operand1 }
1044 ;; For big-endian this is { operand1, operand2 }
1046 (define_insn "aarch64_simd_move_hi_quad_<mode>"
1047 [(set (match_operand:VQ 0 "register_operand" "+w,w")
1051 (match_operand:VQ 2 "vect_par_cnst_lo_half" ""))
1052 (match_operand:<VHALF> 1 "register_operand" "w,r")))]
1053 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
1055 ins\\t%0.d[1], %1.d[0]
1057 [(set_attr "type" "neon_ins")]
1060 (define_insn "aarch64_simd_move_hi_quad_be_<mode>"
1061 [(set (match_operand:VQ 0 "register_operand" "+w,w")
1063 (match_operand:<VHALF> 1 "register_operand" "w,r")
1066 (match_operand:VQ 2 "vect_par_cnst_lo_half" ""))))]
1067 "TARGET_SIMD && BYTES_BIG_ENDIAN"
1069 ins\\t%0.d[1], %1.d[0]
1071 [(set_attr "type" "neon_ins")]
1074 (define_expand "move_hi_quad_<mode>"
1075 [(match_operand:VQ 0 "register_operand" "")
1076 (match_operand:<VHALF> 1 "register_operand" "")]
1079 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1080 if (BYTES_BIG_ENDIAN)
1081 emit_insn (gen_aarch64_simd_move_hi_quad_be_<mode> (operands[0],
1084 emit_insn (gen_aarch64_simd_move_hi_quad_<mode> (operands[0],
1089 ;; Narrowing operations.
1092 (define_insn "aarch64_simd_vec_pack_trunc_<mode>"
1093 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
1094 (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w")))]
1096 "xtn\\t%0.<Vntype>, %1.<Vtype>"
1097 [(set_attr "type" "neon_shift_imm_narrow_q")]
1100 (define_expand "vec_pack_trunc_<mode>"
1101 [(match_operand:<VNARROWD> 0 "register_operand" "")
1102 (match_operand:VDN 1 "register_operand" "")
1103 (match_operand:VDN 2 "register_operand" "")]
1106 rtx tempreg = gen_reg_rtx (<VDBL>mode);
1107 int lo = BYTES_BIG_ENDIAN ? 2 : 1;
1108 int hi = BYTES_BIG_ENDIAN ? 1 : 2;
1110 emit_insn (gen_move_lo_quad_<Vdbl> (tempreg, operands[lo]));
1111 emit_insn (gen_move_hi_quad_<Vdbl> (tempreg, operands[hi]));
1112 emit_insn (gen_aarch64_simd_vec_pack_trunc_<Vdbl> (operands[0], tempreg));
1118 (define_insn "vec_pack_trunc_<mode>"
1119 [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=&w")
1120 (vec_concat:<VNARROWQ2>
1121 (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w"))
1122 (truncate:<VNARROWQ> (match_operand:VQN 2 "register_operand" "w"))))]
1125 if (BYTES_BIG_ENDIAN)
1126 return "xtn\\t%0.<Vntype>, %2.<Vtype>\;xtn2\\t%0.<V2ntype>, %1.<Vtype>";
1128 return "xtn\\t%0.<Vntype>, %1.<Vtype>\;xtn2\\t%0.<V2ntype>, %2.<Vtype>";
1130 [(set_attr "type" "multiple")
1131 (set_attr "length" "8")]
1134 ;; Widening operations.
1136 (define_insn "aarch64_simd_vec_unpack<su>_lo_<mode>"
1137 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1138 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1139 (match_operand:VQW 1 "register_operand" "w")
1140 (match_operand:VQW 2 "vect_par_cnst_lo_half" "")
1143 "<su>shll %0.<Vwtype>, %1.<Vhalftype>, 0"
1144 [(set_attr "type" "neon_shift_imm_long")]
1147 (define_insn "aarch64_simd_vec_unpack<su>_hi_<mode>"
1148 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1149 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1150 (match_operand:VQW 1 "register_operand" "w")
1151 (match_operand:VQW 2 "vect_par_cnst_hi_half" "")
1154 "<su>shll2 %0.<Vwtype>, %1.<Vtype>, 0"
1155 [(set_attr "type" "neon_shift_imm_long")]
1158 (define_expand "vec_unpack<su>_hi_<mode>"
1159 [(match_operand:<VWIDE> 0 "register_operand" "")
1160 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))]
1163 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
1164 emit_insn (gen_aarch64_simd_vec_unpack<su>_hi_<mode> (operands[0],
1170 (define_expand "vec_unpack<su>_lo_<mode>"
1171 [(match_operand:<VWIDE> 0 "register_operand" "")
1172 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))]
1175 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1176 emit_insn (gen_aarch64_simd_vec_unpack<su>_lo_<mode> (operands[0],
1182 ;; Widening arithmetic.
1184 (define_insn "*aarch64_<su>mlal_lo<mode>"
1185 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1188 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1189 (match_operand:VQW 2 "register_operand" "w")
1190 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
1191 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1192 (match_operand:VQW 4 "register_operand" "w")
1194 (match_operand:<VWIDE> 1 "register_operand" "0")))]
1196 "<su>mlal\t%0.<Vwtype>, %2.<Vhalftype>, %4.<Vhalftype>"
1197 [(set_attr "type" "neon_mla_<Vetype>_long")]
1200 (define_insn "*aarch64_<su>mlal_hi<mode>"
1201 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1204 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1205 (match_operand:VQW 2 "register_operand" "w")
1206 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
1207 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1208 (match_operand:VQW 4 "register_operand" "w")
1210 (match_operand:<VWIDE> 1 "register_operand" "0")))]
1212 "<su>mlal2\t%0.<Vwtype>, %2.<Vtype>, %4.<Vtype>"
1213 [(set_attr "type" "neon_mla_<Vetype>_long")]
1216 (define_insn "*aarch64_<su>mlsl_lo<mode>"
1217 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1219 (match_operand:<VWIDE> 1 "register_operand" "0")
1221 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1222 (match_operand:VQW 2 "register_operand" "w")
1223 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
1224 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1225 (match_operand:VQW 4 "register_operand" "w")
1228 "<su>mlsl\t%0.<Vwtype>, %2.<Vhalftype>, %4.<Vhalftype>"
1229 [(set_attr "type" "neon_mla_<Vetype>_long")]
1232 (define_insn "*aarch64_<su>mlsl_hi<mode>"
1233 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1235 (match_operand:<VWIDE> 1 "register_operand" "0")
1237 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1238 (match_operand:VQW 2 "register_operand" "w")
1239 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
1240 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1241 (match_operand:VQW 4 "register_operand" "w")
1244 "<su>mlsl2\t%0.<Vwtype>, %2.<Vtype>, %4.<Vtype>"
1245 [(set_attr "type" "neon_mla_<Vetype>_long")]
1248 (define_insn "*aarch64_<su>mlal<mode>"
1249 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1253 (match_operand:VDW 1 "register_operand" "w"))
1255 (match_operand:VDW 2 "register_operand" "w")))
1256 (match_operand:<VWIDE> 3 "register_operand" "0")))]
1258 "<su>mlal\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
1259 [(set_attr "type" "neon_mla_<Vetype>_long")]
1262 (define_insn "*aarch64_<su>mlsl<mode>"
1263 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1265 (match_operand:<VWIDE> 1 "register_operand" "0")
1268 (match_operand:VDW 2 "register_operand" "w"))
1270 (match_operand:VDW 3 "register_operand" "w")))))]
1272 "<su>mlsl\t%0.<Vwtype>, %2.<Vtype>, %3.<Vtype>"
1273 [(set_attr "type" "neon_mla_<Vetype>_long")]
1276 (define_insn "aarch64_simd_vec_<su>mult_lo_<mode>"
1277 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1278 (mult:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1279 (match_operand:VQW 1 "register_operand" "w")
1280 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
1281 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1282 (match_operand:VQW 2 "register_operand" "w")
1285 "<su>mull\\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
1286 [(set_attr "type" "neon_mul_<Vetype>_long")]
1289 (define_expand "vec_widen_<su>mult_lo_<mode>"
1290 [(match_operand:<VWIDE> 0 "register_operand" "")
1291 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
1292 (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
1295 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1296 emit_insn (gen_aarch64_simd_vec_<su>mult_lo_<mode> (operands[0],
1303 (define_insn "aarch64_simd_vec_<su>mult_hi_<mode>"
1304 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1305 (mult:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1306 (match_operand:VQW 1 "register_operand" "w")
1307 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
1308 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1309 (match_operand:VQW 2 "register_operand" "w")
1312 "<su>mull2\\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
1313 [(set_attr "type" "neon_mul_<Vetype>_long")]
1316 (define_expand "vec_widen_<su>mult_hi_<mode>"
1317 [(match_operand:<VWIDE> 0 "register_operand" "")
1318 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
1319 (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
1322 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
1323 emit_insn (gen_aarch64_simd_vec_<su>mult_hi_<mode> (operands[0],
1331 ;; FP vector operations.
1332 ;; AArch64 AdvSIMD supports single-precision (32-bit) and
1333 ;; double-precision (64-bit) floating-point data types and arithmetic as
1334 ;; defined by the IEEE 754-2008 standard. This makes them vectorizable
1335 ;; without the need for -ffast-math or -funsafe-math-optimizations.
1337 ;; Floating-point operations can raise an exception. Vectorizing such
1338 ;; operations are safe because of reasons explained below.
1340 ;; ARMv8 permits an extension to enable trapped floating-point
1341 ;; exception handling, however this is an optional feature. In the
1342 ;; event of a floating-point exception being raised by vectorised
1344 ;; 1. If trapped floating-point exceptions are available, then a trap
1345 ;; will be taken when any lane raises an enabled exception. A trap
1346 ;; handler may determine which lane raised the exception.
1347 ;; 2. Alternatively a sticky exception flag is set in the
1348 ;; floating-point status register (FPSR). Software may explicitly
1349 ;; test the exception flags, in which case the tests will either
1350 ;; prevent vectorisation, allowing precise identification of the
1351 ;; failing operation, or if tested outside of vectorisable regions
1352 ;; then the specific operation and lane are not of interest.
1354 ;; FP arithmetic operations.
1356 (define_insn "add<mode>3"
1357 [(set (match_operand:VDQF 0 "register_operand" "=w")
1358 (plus:VDQF (match_operand:VDQF 1 "register_operand" "w")
1359 (match_operand:VDQF 2 "register_operand" "w")))]
1361 "fadd\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1362 [(set_attr "type" "neon_fp_addsub_<Vetype><q>")]
1365 (define_insn "sub<mode>3"
1366 [(set (match_operand:VDQF 0 "register_operand" "=w")
1367 (minus:VDQF (match_operand:VDQF 1 "register_operand" "w")
1368 (match_operand:VDQF 2 "register_operand" "w")))]
1370 "fsub\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1371 [(set_attr "type" "neon_fp_addsub_<Vetype><q>")]
1374 (define_insn "mul<mode>3"
1375 [(set (match_operand:VDQF 0 "register_operand" "=w")
1376 (mult:VDQF (match_operand:VDQF 1 "register_operand" "w")
1377 (match_operand:VDQF 2 "register_operand" "w")))]
1379 "fmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1380 [(set_attr "type" "neon_fp_mul_<Vetype><q>")]
1383 (define_insn "div<mode>3"
1384 [(set (match_operand:VDQF 0 "register_operand" "=w")
1385 (div:VDQF (match_operand:VDQF 1 "register_operand" "w")
1386 (match_operand:VDQF 2 "register_operand" "w")))]
1388 "fdiv\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1389 [(set_attr "type" "neon_fp_div_<Vetype><q>")]
1392 (define_insn "neg<mode>2"
1393 [(set (match_operand:VDQF 0 "register_operand" "=w")
1394 (neg:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
1396 "fneg\\t%0.<Vtype>, %1.<Vtype>"
1397 [(set_attr "type" "neon_fp_neg_<Vetype><q>")]
1400 (define_insn "abs<mode>2"
1401 [(set (match_operand:VDQF 0 "register_operand" "=w")
1402 (abs:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
1404 "fabs\\t%0.<Vtype>, %1.<Vtype>"
1405 [(set_attr "type" "neon_fp_abs_<Vetype><q>")]
1408 (define_insn "fma<mode>4"
1409 [(set (match_operand:VDQF 0 "register_operand" "=w")
1410 (fma:VDQF (match_operand:VDQF 1 "register_operand" "w")
1411 (match_operand:VDQF 2 "register_operand" "w")
1412 (match_operand:VDQF 3 "register_operand" "0")))]
1414 "fmla\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1415 [(set_attr "type" "neon_fp_mla_<Vetype><q>")]
1418 (define_insn "*aarch64_fma4_elt<mode>"
1419 [(set (match_operand:VDQF 0 "register_operand" "=w")
1423 (match_operand:VDQF 1 "register_operand" "<h_con>")
1424 (parallel [(match_operand:SI 2 "immediate_operand")])))
1425 (match_operand:VDQF 3 "register_operand" "w")
1426 (match_operand:VDQF 4 "register_operand" "0")))]
1429 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
1430 return "fmla\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1432 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1435 (define_insn "*aarch64_fma4_elt_<vswap_width_name><mode>"
1436 [(set (match_operand:VDQSF 0 "register_operand" "=w")
1438 (vec_duplicate:VDQSF
1440 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
1441 (parallel [(match_operand:SI 2 "immediate_operand")])))
1442 (match_operand:VDQSF 3 "register_operand" "w")
1443 (match_operand:VDQSF 4 "register_operand" "0")))]
1446 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
1447 INTVAL (operands[2])));
1448 return "fmla\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1450 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1453 (define_insn "*aarch64_fma4_elt_to_128df"
1454 [(set (match_operand:V2DF 0 "register_operand" "=w")
1457 (match_operand:DF 1 "register_operand" "w"))
1458 (match_operand:V2DF 2 "register_operand" "w")
1459 (match_operand:V2DF 3 "register_operand" "0")))]
1461 "fmla\\t%0.2d, %2.2d, %1.2d[0]"
1462 [(set_attr "type" "neon_fp_mla_d_scalar_q")]
1465 (define_insn "*aarch64_fma4_elt_to_64v2df"
1466 [(set (match_operand:DF 0 "register_operand" "=w")
1469 (match_operand:V2DF 1 "register_operand" "w")
1470 (parallel [(match_operand:SI 2 "immediate_operand")]))
1471 (match_operand:DF 3 "register_operand" "w")
1472 (match_operand:DF 4 "register_operand" "0")))]
1475 operands[2] = GEN_INT (ENDIAN_LANE_N (V2DFmode, INTVAL (operands[2])));
1476 return "fmla\\t%0.2d, %3.2d, %1.2d[%2]";
1478 [(set_attr "type" "neon_fp_mla_d_scalar_q")]
1481 (define_insn "fnma<mode>4"
1482 [(set (match_operand:VDQF 0 "register_operand" "=w")
1484 (match_operand:VDQF 1 "register_operand" "w")
1486 (match_operand:VDQF 2 "register_operand" "w"))
1487 (match_operand:VDQF 3 "register_operand" "0")))]
1489 "fmls\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1490 [(set_attr "type" "neon_fp_mla_<Vetype><q>")]
1493 (define_insn "*aarch64_fnma4_elt<mode>"
1494 [(set (match_operand:VDQF 0 "register_operand" "=w")
1497 (match_operand:VDQF 3 "register_operand" "w"))
1500 (match_operand:VDQF 1 "register_operand" "<h_con>")
1501 (parallel [(match_operand:SI 2 "immediate_operand")])))
1502 (match_operand:VDQF 4 "register_operand" "0")))]
1505 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
1506 return "fmls\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1508 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1511 (define_insn "*aarch64_fnma4_elt_<vswap_width_name><mode>"
1512 [(set (match_operand:VDQSF 0 "register_operand" "=w")
1515 (match_operand:VDQSF 3 "register_operand" "w"))
1516 (vec_duplicate:VDQSF
1518 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
1519 (parallel [(match_operand:SI 2 "immediate_operand")])))
1520 (match_operand:VDQSF 4 "register_operand" "0")))]
1523 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
1524 INTVAL (operands[2])));
1525 return "fmls\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1527 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1530 (define_insn "*aarch64_fnma4_elt_to_128df"
1531 [(set (match_operand:V2DF 0 "register_operand" "=w")
1534 (match_operand:V2DF 2 "register_operand" "w"))
1536 (match_operand:DF 1 "register_operand" "w"))
1537 (match_operand:V2DF 3 "register_operand" "0")))]
1539 "fmls\\t%0.2d, %2.2d, %1.2d[0]"
1540 [(set_attr "type" "neon_fp_mla_d_scalar_q")]
1543 (define_insn "*aarch64_fnma4_elt_to_64v2df"
1544 [(set (match_operand:DF 0 "register_operand" "=w")
1547 (match_operand:V2DF 1 "register_operand" "w")
1548 (parallel [(match_operand:SI 2 "immediate_operand")]))
1550 (match_operand:DF 3 "register_operand" "w"))
1551 (match_operand:DF 4 "register_operand" "0")))]
1554 operands[2] = GEN_INT (ENDIAN_LANE_N (V2DFmode, INTVAL (operands[2])));
1555 return "fmls\\t%0.2d, %3.2d, %1.2d[%2]";
1557 [(set_attr "type" "neon_fp_mla_d_scalar_q")]
1560 ;; Vector versions of the floating-point frint patterns.
1561 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
1562 (define_insn "<frint_pattern><mode>2"
1563 [(set (match_operand:VDQF 0 "register_operand" "=w")
1564 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")]
1567 "frint<frint_suffix>\\t%0.<Vtype>, %1.<Vtype>"
1568 [(set_attr "type" "neon_fp_round_<Vetype><q>")]
1571 ;; Vector versions of the fcvt standard patterns.
1572 ;; Expands to lbtrunc, lround, lceil, lfloor
1573 (define_insn "l<fcvt_pattern><su_optab><VDQF:mode><fcvt_target>2"
1574 [(set (match_operand:<FCVT_TARGET> 0 "register_operand" "=w")
1575 (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
1576 [(match_operand:VDQF 1 "register_operand" "w")]
1579 "fcvt<frint_suffix><su>\\t%0.<Vtype>, %1.<Vtype>"
1580 [(set_attr "type" "neon_fp_to_int_<Vetype><q>")]
1583 (define_expand "<optab><VDQF:mode><fcvt_target>2"
1584 [(set (match_operand:<FCVT_TARGET> 0 "register_operand")
1585 (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
1586 [(match_operand:VDQF 1 "register_operand")]
1591 (define_expand "<fix_trunc_optab><VDQF:mode><fcvt_target>2"
1592 [(set (match_operand:<FCVT_TARGET> 0 "register_operand")
1593 (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
1594 [(match_operand:VDQF 1 "register_operand")]
1599 (define_expand "ftrunc<VDQF:mode>2"
1600 [(set (match_operand:VDQF 0 "register_operand")
1601 (unspec:VDQF [(match_operand:VDQF 1 "register_operand")]
1606 (define_insn "<optab><fcvt_target><VDQF:mode>2"
1607 [(set (match_operand:VDQF 0 "register_operand" "=w")
1609 (match_operand:<FCVT_TARGET> 1 "register_operand" "w")))]
1611 "<su_optab>cvtf\\t%0.<Vtype>, %1.<Vtype>"
1612 [(set_attr "type" "neon_int_to_fp_<Vetype><q>")]
1615 ;; Conversions between vectors of floats and doubles.
1616 ;; Contains a mix of patterns to match standard pattern names
1617 ;; and those for intrinsics.
1619 ;; Float widening operations.
1621 (define_insn "vec_unpacks_lo_v4sf"
1622 [(set (match_operand:V2DF 0 "register_operand" "=w")
1625 (match_operand:V4SF 1 "register_operand" "w")
1626 (parallel [(const_int 0) (const_int 1)])
1629 "fcvtl\\t%0.2d, %1.2s"
1630 [(set_attr "type" "neon_fp_cvt_widen_s")]
1633 (define_insn "aarch64_float_extend_lo_v2df"
1634 [(set (match_operand:V2DF 0 "register_operand" "=w")
1636 (match_operand:V2SF 1 "register_operand" "w")))]
1638 "fcvtl\\t%0.2d, %1.2s"
1639 [(set_attr "type" "neon_fp_cvt_widen_s")]
1642 (define_insn "vec_unpacks_hi_v4sf"
1643 [(set (match_operand:V2DF 0 "register_operand" "=w")
1646 (match_operand:V4SF 1 "register_operand" "w")
1647 (parallel [(const_int 2) (const_int 3)])
1650 "fcvtl2\\t%0.2d, %1.4s"
1651 [(set_attr "type" "neon_fp_cvt_widen_s")]
1654 ;; Float narrowing operations.
1656 (define_insn "aarch64_float_truncate_lo_v2sf"
1657 [(set (match_operand:V2SF 0 "register_operand" "=w")
1658 (float_truncate:V2SF
1659 (match_operand:V2DF 1 "register_operand" "w")))]
1661 "fcvtn\\t%0.2s, %1.2d"
1662 [(set_attr "type" "neon_fp_cvt_narrow_d_q")]
1665 (define_insn "aarch64_float_truncate_hi_v4sf"
1666 [(set (match_operand:V4SF 0 "register_operand" "=w")
1668 (match_operand:V2SF 1 "register_operand" "0")
1669 (float_truncate:V2SF
1670 (match_operand:V2DF 2 "register_operand" "w"))))]
1672 "fcvtn2\\t%0.4s, %2.2d"
1673 [(set_attr "type" "neon_fp_cvt_narrow_d_q")]
1676 (define_expand "vec_pack_trunc_v2df"
1677 [(set (match_operand:V4SF 0 "register_operand")
1679 (float_truncate:V2SF
1680 (match_operand:V2DF 1 "register_operand"))
1681 (float_truncate:V2SF
1682 (match_operand:V2DF 2 "register_operand"))
1686 rtx tmp = gen_reg_rtx (V2SFmode);
1687 int lo = BYTES_BIG_ENDIAN ? 2 : 1;
1688 int hi = BYTES_BIG_ENDIAN ? 1 : 2;
1690 emit_insn (gen_aarch64_float_truncate_lo_v2sf (tmp, operands[lo]));
1691 emit_insn (gen_aarch64_float_truncate_hi_v4sf (operands[0],
1692 tmp, operands[hi]));
1697 (define_expand "vec_pack_trunc_df"
1698 [(set (match_operand:V2SF 0 "register_operand")
1701 (match_operand:DF 1 "register_operand"))
1703 (match_operand:DF 2 "register_operand"))
1707 rtx tmp = gen_reg_rtx (V2SFmode);
1708 int lo = BYTES_BIG_ENDIAN ? 2 : 1;
1709 int hi = BYTES_BIG_ENDIAN ? 1 : 2;
1711 emit_insn (gen_move_lo_quad_v2df (tmp, operands[lo]));
1712 emit_insn (gen_move_hi_quad_v2df (tmp, operands[hi]));
1713 emit_insn (gen_aarch64_float_truncate_lo_v2sf (operands[0], tmp));
1718 (define_insn "aarch64_vmls<mode>"
1719 [(set (match_operand:VDQF 0 "register_operand" "=w")
1720 (minus:VDQF (match_operand:VDQF 1 "register_operand" "0")
1721 (mult:VDQF (match_operand:VDQF 2 "register_operand" "w")
1722 (match_operand:VDQF 3 "register_operand" "w"))))]
1724 "fmls\\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
1725 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1729 ;; Max/Min are introduced by idiom recognition by GCC's mid-end. An
1731 ;; a = (b < c) ? b : c;
1732 ;; is idiom-matched as MIN_EXPR<b,c> only if -ffinite-math-only is enabled
1733 ;; either explicitly or indirectly via -ffast-math.
1735 ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
1736 ;; The 'smax' and 'smin' RTL standard pattern names do not specify which
1737 ;; operand will be returned when both operands are zero (i.e. they may not
1738 ;; honour signed zeroes), or when either operand is NaN. Therefore GCC
1739 ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
1742 (define_insn "<su><maxmin><mode>3"
1743 [(set (match_operand:VDQF 0 "register_operand" "=w")
1744 (FMAXMIN:VDQF (match_operand:VDQF 1 "register_operand" "w")
1745 (match_operand:VDQF 2 "register_operand" "w")))]
1747 "f<maxmin>nm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1748 [(set_attr "type" "neon_fp_minmax_<Vetype><q>")]
1751 (define_insn "<maxmin_uns><mode>3"
1752 [(set (match_operand:VDQF 0 "register_operand" "=w")
1753 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
1754 (match_operand:VDQF 2 "register_operand" "w")]
1757 "<maxmin_uns_op>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1758 [(set_attr "type" "neon_fp_minmax_<Vetype><q>")]
1761 ;; 'across lanes' add.
1763 (define_expand "reduc_plus_scal_<mode>"
1764 [(match_operand:<VEL> 0 "register_operand" "=w")
1765 (unspec:VDQ [(match_operand:VDQ 1 "register_operand" "w")]
1769 rtx elt = GEN_INT (ENDIAN_LANE_N (<MODE>mode, 0));
1770 rtx scratch = gen_reg_rtx (<MODE>mode);
1771 emit_insn (gen_aarch64_reduc_plus_internal<mode> (scratch, operands[1]));
1772 emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
1777 (define_expand "reduc_plus_scal_<mode>"
1778 [(match_operand:<VEL> 0 "register_operand" "=w")
1779 (match_operand:V2F 1 "register_operand" "w")]
1782 rtx elt = GEN_INT (ENDIAN_LANE_N (<MODE>mode, 0));
1783 rtx scratch = gen_reg_rtx (<MODE>mode);
1784 emit_insn (gen_aarch64_reduc_plus_internal<mode> (scratch, operands[1]));
1785 emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
1790 (define_insn "aarch64_reduc_plus_internal<mode>"
1791 [(set (match_operand:VDQV 0 "register_operand" "=w")
1792 (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
1795 "add<VDQV:vp>\\t%<Vetype>0, %1.<Vtype>"
1796 [(set_attr "type" "neon_reduc_add<q>")]
1799 (define_insn "aarch64_reduc_plus_internalv2si"
1800 [(set (match_operand:V2SI 0 "register_operand" "=w")
1801 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
1804 "addp\\t%0.2s, %1.2s, %1.2s"
1805 [(set_attr "type" "neon_reduc_add")]
1808 (define_insn "aarch64_reduc_plus_internal<mode>"
1809 [(set (match_operand:V2F 0 "register_operand" "=w")
1810 (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
1813 "faddp\\t%<Vetype>0, %1.<Vtype>"
1814 [(set_attr "type" "neon_fp_reduc_add_<Vetype><q>")]
1817 (define_insn "aarch64_addpv4sf"
1818 [(set (match_operand:V4SF 0 "register_operand" "=w")
1819 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
1822 "faddp\\t%0.4s, %1.4s, %1.4s"
1823 [(set_attr "type" "neon_fp_reduc_add_s_q")]
1826 (define_expand "reduc_plus_scal_v4sf"
1827 [(set (match_operand:SF 0 "register_operand")
1828 (unspec:V4SF [(match_operand:V4SF 1 "register_operand")]
1832 rtx elt = GEN_INT (ENDIAN_LANE_N (V4SFmode, 0));
1833 rtx scratch = gen_reg_rtx (V4SFmode);
1834 emit_insn (gen_aarch64_addpv4sf (scratch, operands[1]));
1835 emit_insn (gen_aarch64_addpv4sf (scratch, scratch));
1836 emit_insn (gen_aarch64_get_lanev4sf (operands[0], scratch, elt));
1840 (define_insn "clz<mode>2"
1841 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
1842 (clz:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")))]
1844 "clz\\t%0.<Vtype>, %1.<Vtype>"
1845 [(set_attr "type" "neon_cls<q>")]
1848 ;; 'across lanes' max and min ops.
1850 ;; Template for outputting a scalar, so we can create __builtins which can be
1851 ;; gimple_fold'd to the REDUC_(MAX|MIN)_EXPR tree code. (This is FP smax/smin).
1852 (define_expand "reduc_<maxmin_uns>_scal_<mode>"
1853 [(match_operand:<VEL> 0 "register_operand")
1854 (unspec:VDQF [(match_operand:VDQF 1 "register_operand")]
1858 rtx elt = GEN_INT (ENDIAN_LANE_N (<MODE>mode, 0));
1859 rtx scratch = gen_reg_rtx (<MODE>mode);
1860 emit_insn (gen_aarch64_reduc_<maxmin_uns>_internal<mode> (scratch,
1862 emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
1867 ;; Likewise for integer cases, signed and unsigned.
1868 (define_expand "reduc_<maxmin_uns>_scal_<mode>"
1869 [(match_operand:<VEL> 0 "register_operand")
1870 (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand")]
1874 rtx elt = GEN_INT (ENDIAN_LANE_N (<MODE>mode, 0));
1875 rtx scratch = gen_reg_rtx (<MODE>mode);
1876 emit_insn (gen_aarch64_reduc_<maxmin_uns>_internal<mode> (scratch,
1878 emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
1883 (define_insn "aarch64_reduc_<maxmin_uns>_internal<mode>"
1884 [(set (match_operand:VDQV_S 0 "register_operand" "=w")
1885 (unspec:VDQV_S [(match_operand:VDQV_S 1 "register_operand" "w")]
1888 "<maxmin_uns_op>v\\t%<Vetype>0, %1.<Vtype>"
1889 [(set_attr "type" "neon_reduc_minmax<q>")]
1892 (define_insn "aarch64_reduc_<maxmin_uns>_internalv2si"
1893 [(set (match_operand:V2SI 0 "register_operand" "=w")
1894 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
1897 "<maxmin_uns_op>p\\t%0.2s, %1.2s, %1.2s"
1898 [(set_attr "type" "neon_reduc_minmax")]
1901 (define_insn "aarch64_reduc_<maxmin_uns>_internal<mode>"
1902 [(set (match_operand:VDQF 0 "register_operand" "=w")
1903 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")]
1906 "<maxmin_uns_op><vp>\\t%<Vetype>0, %1.<Vtype>"
1907 [(set_attr "type" "neon_fp_reduc_minmax_<Vetype><q>")]
1910 ;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register
1912 ;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which
1915 ;; Thus our BSL is of the form:
1916 ;; op0 = bsl (mask, op2, op3)
1917 ;; We can use any of:
1920 ;; bsl mask, op1, op2
1921 ;; if (op0 = op1) (so 1-bits in mask choose bits from op2, else op0)
1922 ;; bit op0, op2, mask
1923 ;; if (op0 = op2) (so 0-bits in mask choose bits from op1, else op0)
1924 ;; bif op0, op1, mask
1926 (define_insn "aarch64_simd_bsl<mode>_internal"
1927 [(set (match_operand:VALLDIF 0 "register_operand" "=w,w,w")
1930 (match_operand:<V_cmp_result> 1 "register_operand" " 0,w,w")
1931 (match_operand:VALLDIF 2 "register_operand" " w,w,0"))
1934 (match_dup:<V_cmp_result> 1))
1935 (match_operand:VALLDIF 3 "register_operand" " w,0,w"))
1939 bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
1940 bit\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
1941 bif\\t%0.<Vbtype>, %3.<Vbtype>, %1.<Vbtype>"
1942 [(set_attr "type" "neon_bsl<q>")]
1945 (define_expand "aarch64_simd_bsl<mode>"
1946 [(match_operand:VALLDIF 0 "register_operand")
1947 (match_operand:<V_cmp_result> 1 "register_operand")
1948 (match_operand:VALLDIF 2 "register_operand")
1949 (match_operand:VALLDIF 3 "register_operand")]
1952 /* We can't alias operands together if they have different modes. */
1953 operands[1] = gen_lowpart (<V_cmp_result>mode, operands[1]);
1954 emit_insn (gen_aarch64_simd_bsl<mode>_internal (operands[0], operands[1],
1955 operands[2], operands[3]));
1959 (define_expand "aarch64_vcond_internal<mode><mode>"
1960 [(set (match_operand:VDQ 0 "register_operand")
1962 (match_operator 3 "comparison_operator"
1963 [(match_operand:VDQ 4 "register_operand")
1964 (match_operand:VDQ 5 "nonmemory_operand")])
1965 (match_operand:VDQ 1 "nonmemory_operand")
1966 (match_operand:VDQ 2 "nonmemory_operand")))]
1969 rtx op1 = operands[1];
1970 rtx op2 = operands[2];
1971 rtx mask = gen_reg_rtx (<MODE>mode);
1972 enum rtx_code code = GET_CODE (operands[3]);
1974 /* Switching OP1 and OP2 is necessary for NE (to output a cmeq insn),
1975 and desirable for other comparisons if it results in FOO ? -1 : 0
1976 (this allows direct use of the comparison result without a bsl). */
1979 && op1 == CONST0_RTX (<V_cmp_result>mode)
1980 && op2 == CONSTM1_RTX (<V_cmp_result>mode)))
1986 case LE: code = GT; break;
1987 case LT: code = GE; break;
1988 case GE: code = LT; break;
1989 case GT: code = LE; break;
1991 case NE: code = EQ; break;
1992 case LTU: code = GEU; break;
1993 case LEU: code = GTU; break;
1994 case GTU: code = LEU; break;
1995 case GEU: code = LTU; break;
1996 default: gcc_unreachable ();
2000 /* Make sure we can handle the last operand. */
2004 /* Normalized to EQ above. */
2012 /* These instructions have a form taking an immediate zero. */
2013 if (operands[5] == CONST0_RTX (<MODE>mode))
2015 /* Fall through, as may need to load into register. */
2017 if (!REG_P (operands[5]))
2018 operands[5] = force_reg (<MODE>mode, operands[5]);
2025 emit_insn (gen_aarch64_cmlt<mode> (mask, operands[4], operands[5]));
2029 emit_insn (gen_aarch64_cmge<mode> (mask, operands[4], operands[5]));
2033 emit_insn (gen_aarch64_cmle<mode> (mask, operands[4], operands[5]));
2037 emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
2041 emit_insn (gen_aarch64_cmgtu<mode> (mask, operands[5], operands[4]));
2045 emit_insn (gen_aarch64_cmgeu<mode> (mask, operands[4], operands[5]));
2049 emit_insn (gen_aarch64_cmgeu<mode> (mask, operands[5], operands[4]));
2053 emit_insn (gen_aarch64_cmgtu<mode> (mask, operands[4], operands[5]));
2056 /* NE has been normalized to EQ above. */
2058 emit_insn (gen_aarch64_cmeq<mode> (mask, operands[4], operands[5]));
2065 /* If we have (a = (b CMP c) ? -1 : 0);
2066 Then we can simply move the generated mask. */
2068 if (op1 == CONSTM1_RTX (<V_cmp_result>mode)
2069 && op2 == CONST0_RTX (<V_cmp_result>mode))
2070 emit_move_insn (operands[0], mask);
2074 op1 = force_reg (<MODE>mode, op1);
2076 op2 = force_reg (<MODE>mode, op2);
2077 emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask,
2084 (define_expand "aarch64_vcond_internal<VDQF_COND:mode><VDQF:mode>"
2085 [(set (match_operand:VDQF_COND 0 "register_operand")
2087 (match_operator 3 "comparison_operator"
2088 [(match_operand:VDQF 4 "register_operand")
2089 (match_operand:VDQF 5 "nonmemory_operand")])
2090 (match_operand:VDQF_COND 1 "nonmemory_operand")
2091 (match_operand:VDQF_COND 2 "nonmemory_operand")))]
2095 int use_zero_form = 0;
2096 int swap_bsl_operands = 0;
2097 rtx op1 = operands[1];
2098 rtx op2 = operands[2];
2099 rtx mask = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
2100 rtx tmp = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
2102 rtx (*base_comparison) (rtx, rtx, rtx);
2103 rtx (*complimentary_comparison) (rtx, rtx, rtx);
2105 switch (GET_CODE (operands[3]))
2112 if (operands[5] == CONST0_RTX (<MODE>mode))
2119 if (!REG_P (operands[5]))
2120 operands[5] = force_reg (<VDQF:MODE>mode, operands[5]);
2123 switch (GET_CODE (operands[3]))
2133 base_comparison = gen_aarch64_cmge<VDQF:mode>;
2134 complimentary_comparison = gen_aarch64_cmgt<VDQF:mode>;
2142 base_comparison = gen_aarch64_cmgt<VDQF:mode>;
2143 complimentary_comparison = gen_aarch64_cmge<VDQF:mode>;
2148 base_comparison = gen_aarch64_cmeq<VDQF:mode>;
2149 complimentary_comparison = gen_aarch64_cmeq<VDQF:mode>;
2155 switch (GET_CODE (operands[3]))
2162 /* The easy case. Here we emit one of FCMGE, FCMGT or FCMEQ.
2163 As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
2169 Note that there also exist direct comparison against 0 forms,
2170 so catch those as a special case. */
2174 switch (GET_CODE (operands[3]))
2177 base_comparison = gen_aarch64_cmlt<VDQF:mode>;
2180 base_comparison = gen_aarch64_cmle<VDQF:mode>;
2183 /* Do nothing, other zero form cases already have the correct
2190 emit_insn (base_comparison (mask, operands[4], operands[5]));
2192 emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
2199 /* FCM returns false for lanes which are unordered, so if we use
2200 the inverse of the comparison we actually want to emit, then
2201 swap the operands to BSL, we will end up with the correct result.
2202 Note that a NE NaN and NaN NE b are true for all a, b.
2204 Our transformations are:
2209 a NE b -> !(a EQ b) */
2212 emit_insn (base_comparison (mask, operands[4], operands[5]));
2214 emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
2216 swap_bsl_operands = 1;
2219 /* We check (a > b || b > a). combining these comparisons give us
2220 true iff !(a != b && a ORDERED b), swapping the operands to BSL
2221 will then give us (a == b || a UNORDERED b) as intended. */
2223 emit_insn (gen_aarch64_cmgt<VDQF:mode> (mask, operands[4], operands[5]));
2224 emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[5], operands[4]));
2225 emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
2226 swap_bsl_operands = 1;
2229 /* Operands are ORDERED iff (a > b || b >= a).
2230 Swapping the operands to BSL will give the UNORDERED case. */
2231 swap_bsl_operands = 1;
2234 emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[4], operands[5]));
2235 emit_insn (gen_aarch64_cmge<VDQF:mode> (mask, operands[5], operands[4]));
2236 emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
2242 if (swap_bsl_operands)
2248 /* If we have (a = (b CMP c) ? -1 : 0);
2249 Then we can simply move the generated mask. */
2251 if (op1 == CONSTM1_RTX (<VDQF_COND:V_cmp_result>mode)
2252 && op2 == CONST0_RTX (<VDQF_COND:V_cmp_result>mode))
2253 emit_move_insn (operands[0], mask);
2257 op1 = force_reg (<VDQF_COND:MODE>mode, op1);
2259 op2 = force_reg (<VDQF_COND:MODE>mode, op2);
2260 emit_insn (gen_aarch64_simd_bsl<VDQF_COND:mode> (operands[0], mask,
2267 (define_expand "vcond<mode><mode>"
2268 [(set (match_operand:VALL 0 "register_operand")
2270 (match_operator 3 "comparison_operator"
2271 [(match_operand:VALL 4 "register_operand")
2272 (match_operand:VALL 5 "nonmemory_operand")])
2273 (match_operand:VALL 1 "nonmemory_operand")
2274 (match_operand:VALL 2 "nonmemory_operand")))]
2277 emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
2278 operands[2], operands[3],
2279 operands[4], operands[5]));
2283 (define_expand "vcond<v_cmp_result><mode>"
2284 [(set (match_operand:<V_cmp_result> 0 "register_operand")
2285 (if_then_else:<V_cmp_result>
2286 (match_operator 3 "comparison_operator"
2287 [(match_operand:VDQF 4 "register_operand")
2288 (match_operand:VDQF 5 "nonmemory_operand")])
2289 (match_operand:<V_cmp_result> 1 "nonmemory_operand")
2290 (match_operand:<V_cmp_result> 2 "nonmemory_operand")))]
2293 emit_insn (gen_aarch64_vcond_internal<v_cmp_result><mode> (
2294 operands[0], operands[1],
2295 operands[2], operands[3],
2296 operands[4], operands[5]));
2300 (define_expand "vcondu<mode><mode>"
2301 [(set (match_operand:VDQ 0 "register_operand")
2303 (match_operator 3 "comparison_operator"
2304 [(match_operand:VDQ 4 "register_operand")
2305 (match_operand:VDQ 5 "nonmemory_operand")])
2306 (match_operand:VDQ 1 "nonmemory_operand")
2307 (match_operand:VDQ 2 "nonmemory_operand")))]
2310 emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
2311 operands[2], operands[3],
2312 operands[4], operands[5]));
2316 ;; Patterns for AArch64 SIMD Intrinsics.
2318 (define_expand "aarch64_create<mode>"
2319 [(match_operand:VD1 0 "register_operand" "")
2320 (match_operand:DI 1 "general_operand" "")]
2323 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2324 emit_move_insn (operands[0], src);
2328 ;; Lane extraction with sign extension to general purpose register.
2329 (define_insn "*aarch64_get_lane_extend<GPI:mode><VDQQH:mode>"
2330 [(set (match_operand:GPI 0 "register_operand" "=r")
2333 (match_operand:VDQQH 1 "register_operand" "w")
2334 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2337 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2338 return "smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]";
2340 [(set_attr "type" "neon_to_gp<q>")]
2343 (define_insn "*aarch64_get_lane_zero_extendsi<mode>"
2344 [(set (match_operand:SI 0 "register_operand" "=r")
2347 (match_operand:VDQQH 1 "register_operand" "w")
2348 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2351 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2352 return "umov\\t%w0, %1.<Vetype>[%2]";
2354 [(set_attr "type" "neon_to_gp<q>")]
2357 (define_expand "aarch64_be_checked_get_lane<mode>"
2358 [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand")
2359 (match_operand:VALL 1 "register_operand")
2360 (match_operand:SI 2 "immediate_operand")]
2363 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2364 emit_insn (gen_aarch64_get_lane<mode> (operands[0],
2371 ;; Lane extraction of a value, neither sign nor zero extension
2372 ;; is guaranteed so upper bits should be considered undefined.
2373 (define_insn "aarch64_get_lane<mode>"
2374 [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
2376 (match_operand:VALL 1 "register_operand" "w, w, w")
2377 (parallel [(match_operand:SI 2 "immediate_operand" "i, i, i")])))]
2380 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2381 switch (which_alternative)
2384 return "umov\\t%<vwcore>0, %1.<Vetype>[%2]";
2386 return "dup\\t%<Vetype>0, %1.<Vetype>[%2]";
2388 return "st1\\t{%1.<Vetype>}[%2], %0";
2393 [(set_attr "type" "neon_to_gp<q>, neon_dup<q>, neon_store1_one_lane<q>")]
2396 (define_expand "aarch64_get_lanedi"
2397 [(match_operand:DI 0 "register_operand")
2398 (match_operand:DI 1 "register_operand")
2399 (match_operand:SI 2 "immediate_operand")]
2402 aarch64_simd_lane_bounds (operands[2], 0, 1);
2403 emit_move_insn (operands[0], operands[1]);
2407 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2410 (define_insn "*aarch64_combinez<mode>"
2411 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2413 (match_operand:VDIC 1 "register_operand" "w")
2414 (match_operand:VDIC 2 "aarch64_simd_imm_zero" "Dz")))]
2415 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
2416 "mov\\t%0.8b, %1.8b"
2417 [(set_attr "type" "neon_move<q>")]
2420 (define_insn "*aarch64_combinez_be<mode>"
2421 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2423 (match_operand:VDIC 2 "aarch64_simd_imm_zero" "Dz")
2424 (match_operand:VDIC 1 "register_operand" "w")))]
2425 "TARGET_SIMD && BYTES_BIG_ENDIAN"
2426 "mov\\t%0.8b, %1.8b"
2427 [(set_attr "type" "neon_move<q>")]
2430 (define_expand "aarch64_combine<mode>"
2431 [(match_operand:<VDBL> 0 "register_operand")
2432 (match_operand:VDC 1 "register_operand")
2433 (match_operand:VDC 2 "register_operand")]
2437 if (BYTES_BIG_ENDIAN)
2447 emit_insn (gen_aarch64_combine_internal<mode> (operands[0], op1, op2));
2452 (define_insn_and_split "aarch64_combine_internal<mode>"
2453 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2454 (vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
2455 (match_operand:VDC 2 "register_operand" "w")))]
2458 "&& reload_completed"
2461 if (BYTES_BIG_ENDIAN)
2462 aarch64_split_simd_combine (operands[0], operands[2], operands[1]);
2464 aarch64_split_simd_combine (operands[0], operands[1], operands[2]);
2467 [(set_attr "type" "multiple")]
2470 (define_expand "aarch64_simd_combine<mode>"
2471 [(match_operand:<VDBL> 0 "register_operand")
2472 (match_operand:VDC 1 "register_operand")
2473 (match_operand:VDC 2 "register_operand")]
2476 emit_insn (gen_move_lo_quad_<Vdbl> (operands[0], operands[1]));
2477 emit_insn (gen_move_hi_quad_<Vdbl> (operands[0], operands[2]));
2480 [(set_attr "type" "multiple")]
2483 ;; <su><addsub>l<q>.
2485 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>_hi_internal"
2486 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2487 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2488 (match_operand:VQW 1 "register_operand" "w")
2489 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
2490 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2491 (match_operand:VQW 2 "register_operand" "w")
2494 "<ANY_EXTEND:su><ADDSUB:optab>l2\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
2495 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2498 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>_lo_internal"
2499 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2500 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2501 (match_operand:VQW 1 "register_operand" "w")
2502 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
2503 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2504 (match_operand:VQW 2 "register_operand" "w")
2507 "<ANY_EXTEND:su><ADDSUB:optab>l\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
2508 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2512 (define_expand "aarch64_saddl2<mode>"
2513 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2514 (match_operand:VQW 1 "register_operand" "w")
2515 (match_operand:VQW 2 "register_operand" "w")]
2518 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2519 emit_insn (gen_aarch64_saddl<mode>_hi_internal (operands[0], operands[1],
2524 (define_expand "aarch64_uaddl2<mode>"
2525 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2526 (match_operand:VQW 1 "register_operand" "w")
2527 (match_operand:VQW 2 "register_operand" "w")]
2530 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2531 emit_insn (gen_aarch64_uaddl<mode>_hi_internal (operands[0], operands[1],
2536 (define_expand "aarch64_ssubl2<mode>"
2537 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2538 (match_operand:VQW 1 "register_operand" "w")
2539 (match_operand:VQW 2 "register_operand" "w")]
2542 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2543 emit_insn (gen_aarch64_ssubl<mode>_hi_internal (operands[0], operands[1],
2548 (define_expand "aarch64_usubl2<mode>"
2549 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2550 (match_operand:VQW 1 "register_operand" "w")
2551 (match_operand:VQW 2 "register_operand" "w")]
2554 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2555 emit_insn (gen_aarch64_usubl<mode>_hi_internal (operands[0], operands[1],
2560 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>"
2561 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2562 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE>
2563 (match_operand:VDW 1 "register_operand" "w"))
2565 (match_operand:VDW 2 "register_operand" "w"))))]
2567 "<ANY_EXTEND:su><ADDSUB:optab>l %0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
2568 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2571 ;; <su><addsub>w<q>.
2573 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w<mode>"
2574 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2575 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2577 (match_operand:VDW 2 "register_operand" "w"))))]
2579 "<ANY_EXTEND:su><ADDSUB:optab>w\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
2580 [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
2583 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w2<mode>_internal"
2584 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2585 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2588 (match_operand:VQW 2 "register_operand" "w")
2589 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))))]
2591 "<ANY_EXTEND:su><ADDSUB:optab>w2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
2592 [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
2595 (define_expand "aarch64_saddw2<mode>"
2596 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2597 (match_operand:<VWIDE> 1 "register_operand" "w")
2598 (match_operand:VQW 2 "register_operand" "w")]
2601 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2602 emit_insn (gen_aarch64_saddw2<mode>_internal (operands[0], operands[1],
2607 (define_expand "aarch64_uaddw2<mode>"
2608 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2609 (match_operand:<VWIDE> 1 "register_operand" "w")
2610 (match_operand:VQW 2 "register_operand" "w")]
2613 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2614 emit_insn (gen_aarch64_uaddw2<mode>_internal (operands[0], operands[1],
2620 (define_expand "aarch64_ssubw2<mode>"
2621 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2622 (match_operand:<VWIDE> 1 "register_operand" "w")
2623 (match_operand:VQW 2 "register_operand" "w")]
2626 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2627 emit_insn (gen_aarch64_ssubw2<mode>_internal (operands[0], operands[1],
2632 (define_expand "aarch64_usubw2<mode>"
2633 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2634 (match_operand:<VWIDE> 1 "register_operand" "w")
2635 (match_operand:VQW 2 "register_operand" "w")]
2638 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2639 emit_insn (gen_aarch64_usubw2<mode>_internal (operands[0], operands[1],
2644 ;; <su><r>h<addsub>.
2646 (define_insn "aarch64_<sur>h<addsub><mode>"
2647 [(set (match_operand:VQ_S 0 "register_operand" "=w")
2648 (unspec:VQ_S [(match_operand:VQ_S 1 "register_operand" "w")
2649 (match_operand:VQ_S 2 "register_operand" "w")]
2652 "<sur>h<addsub>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2653 [(set_attr "type" "neon_<addsub>_halve<q>")]
2656 ;; <r><addsub>hn<q>.
2658 (define_insn "aarch64_<sur><addsub>hn<mode>"
2659 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2660 (unspec:<VNARROWQ> [(match_operand:VQN 1 "register_operand" "w")
2661 (match_operand:VQN 2 "register_operand" "w")]
2664 "<sur><addsub>hn\\t%0.<Vntype>, %1.<Vtype>, %2.<Vtype>"
2665 [(set_attr "type" "neon_<addsub>_halve_narrow_q")]
2668 (define_insn "aarch64_<sur><addsub>hn2<mode>"
2669 [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
2670 (unspec:<VNARROWQ2> [(match_operand:<VNARROWQ> 1 "register_operand" "0")
2671 (match_operand:VQN 2 "register_operand" "w")
2672 (match_operand:VQN 3 "register_operand" "w")]
2675 "<sur><addsub>hn2\\t%0.<V2ntype>, %2.<Vtype>, %3.<Vtype>"
2676 [(set_attr "type" "neon_<addsub>_halve_narrow_q")]
2681 (define_insn "aarch64_pmul<mode>"
2682 [(set (match_operand:VB 0 "register_operand" "=w")
2683 (unspec:VB [(match_operand:VB 1 "register_operand" "w")
2684 (match_operand:VB 2 "register_operand" "w")]
2687 "pmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2688 [(set_attr "type" "neon_mul_<Vetype><q>")]
2693 (define_insn "aarch64_<su_optab><optab><mode>"
2694 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
2695 (BINQOPS:VSDQ_I (match_operand:VSDQ_I 1 "register_operand" "w")
2696 (match_operand:VSDQ_I 2 "register_operand" "w")))]
2698 "<su_optab><optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
2699 [(set_attr "type" "neon_<optab><q>")]
2702 ;; suqadd and usqadd
2704 (define_insn "aarch64_<sur>qadd<mode>"
2705 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
2706 (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "0")
2707 (match_operand:VSDQ_I 2 "register_operand" "w")]
2710 "<sur>qadd\\t%<v>0<Vmtype>, %<v>2<Vmtype>"
2711 [(set_attr "type" "neon_qadd<q>")]
2716 (define_insn "aarch64_sqmovun<mode>"
2717 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2718 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
2721 "sqxtun\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
2722 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
2725 ;; sqmovn and uqmovn
2727 (define_insn "aarch64_<sur>qmovn<mode>"
2728 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2729 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
2732 "<sur>qxtn\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
2733 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
2738 (define_insn "aarch64_s<optab><mode>"
2739 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
2741 (match_operand:VSDQ_I 1 "register_operand" "w")))]
2743 "s<optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>"
2744 [(set_attr "type" "neon_<optab><q>")]
2749 (define_insn "aarch64_sq<r>dmulh<mode>"
2750 [(set (match_operand:VSDQ_HSI 0 "register_operand" "=w")
2752 [(match_operand:VSDQ_HSI 1 "register_operand" "w")
2753 (match_operand:VSDQ_HSI 2 "register_operand" "w")]
2756 "sq<r>dmulh\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
2757 [(set_attr "type" "neon_sat_mul_<Vetype><q>")]
2762 (define_expand "aarch64_sqdmulh_lane<mode>"
2763 [(match_operand:VDQHS 0 "register_operand" "")
2764 (match_operand:VDQHS 1 "register_operand" "")
2765 (match_operand:<VCOND> 2 "register_operand" "")
2766 (match_operand:SI 3 "immediate_operand" "")]
2769 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2770 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2771 emit_insn (gen_aarch64_sqdmulh_lane<mode>_internal (operands[0],
2779 (define_expand "aarch64_sqrdmulh_lane<mode>"
2780 [(match_operand:VDQHS 0 "register_operand" "")
2781 (match_operand:VDQHS 1 "register_operand" "")
2782 (match_operand:<VCOND> 2 "register_operand" "")
2783 (match_operand:SI 3 "immediate_operand" "")]
2786 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2787 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2788 emit_insn (gen_aarch64_sqrdmulh_lane<mode>_internal (operands[0],
2796 (define_insn "aarch64_sq<r>dmulh_lane<mode>_internal"
2797 [(set (match_operand:VDQHS 0 "register_operand" "=w")
2799 [(match_operand:VDQHS 1 "register_operand" "w")
2801 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
2802 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2806 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2807 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2808 return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
2809 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
2812 (define_expand "aarch64_sqdmulh_laneq<mode>"
2813 [(match_operand:VSDQ_HSI 0 "register_operand" "")
2814 (match_operand:VSDQ_HSI 1 "register_operand" "")
2815 (match_operand:<VCONQ> 2 "register_operand" "")
2816 (match_operand:SI 3 "immediate_operand" "")]
2819 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
2820 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
2821 emit_insn (gen_aarch64_sqdmulh_laneq<mode>_internal (operands[0],
2829 (define_expand "aarch64_sqrdmulh_laneq<mode>"
2830 [(match_operand:VSDQ_HSI 0 "register_operand" "")
2831 (match_operand:VSDQ_HSI 1 "register_operand" "")
2832 (match_operand:<VCONQ> 2 "register_operand" "")
2833 (match_operand:SI 3 "immediate_operand" "")]
2836 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
2837 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
2838 emit_insn (gen_aarch64_sqrdmulh_laneq<mode>_internal (operands[0],
2846 (define_insn "aarch64_sq<r>dmulh_laneq<mode>_internal"
2847 [(set (match_operand:VDQHS 0 "register_operand" "=w")
2849 [(match_operand:VDQHS 1 "register_operand" "w")
2851 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
2852 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2856 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
2857 return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
2858 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
2861 (define_expand "aarch64_sqdmulh_lane<mode>"
2862 [(match_operand:SD_HSI 0 "register_operand" "")
2863 (match_operand:SD_HSI 1 "register_operand" "")
2864 (match_operand:<VCOND> 2 "register_operand" "")
2865 (match_operand:SI 3 "immediate_operand" "")]
2868 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2869 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2870 emit_insn (gen_aarch64_sqdmulh_lane<mode>_internal (operands[0],
2878 (define_expand "aarch64_sqrdmulh_lane<mode>"
2879 [(match_operand:SD_HSI 0 "register_operand" "")
2880 (match_operand:SD_HSI 1 "register_operand" "")
2881 (match_operand:<VCOND> 2 "register_operand" "")
2882 (match_operand:SI 3 "immediate_operand" "")]
2885 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2886 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2887 emit_insn (gen_aarch64_sqrdmulh_lane<mode>_internal (operands[0],
2895 (define_insn "aarch64_sq<r>dmulh_lane<mode>_internal"
2896 [(set (match_operand:SD_HSI 0 "register_operand" "=w")
2898 [(match_operand:SD_HSI 1 "register_operand" "w")
2900 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
2901 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2905 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2906 return \"sq<r>dmulh\\t%<v>0, %<v>1, %2.<v>[%3]\";"
2907 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
2910 (define_insn "aarch64_sq<r>dmulh_laneq<mode>_internal"
2911 [(set (match_operand:SD_HSI 0 "register_operand" "=w")
2913 [(match_operand:SD_HSI 1 "register_operand" "w")
2915 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
2916 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2920 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
2921 return \"sq<r>dmulh\\t%<v>0, %<v>1, %2.<v>[%3]\";"
2922 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
2927 (define_insn "aarch64_sqdml<SBINQOPS:as>l<mode>"
2928 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2930 (match_operand:<VWIDE> 1 "register_operand" "0")
2933 (sign_extend:<VWIDE>
2934 (match_operand:VSD_HSI 2 "register_operand" "w"))
2935 (sign_extend:<VWIDE>
2936 (match_operand:VSD_HSI 3 "register_operand" "w")))
2939 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
2940 [(set_attr "type" "neon_sat_mla_<Vetype>_long")]
2945 (define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
2946 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2948 (match_operand:<VWIDE> 1 "register_operand" "0")
2951 (sign_extend:<VWIDE>
2952 (match_operand:VD_HSI 2 "register_operand" "w"))
2953 (sign_extend:<VWIDE>
2954 (vec_duplicate:VD_HSI
2956 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
2957 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
2962 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
2964 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
2966 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
2969 (define_insn "aarch64_sqdml<SBINQOPS:as>l_laneq<mode>_internal"
2970 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2972 (match_operand:<VWIDE> 1 "register_operand" "0")
2975 (sign_extend:<VWIDE>
2976 (match_operand:VD_HSI 2 "register_operand" "w"))
2977 (sign_extend:<VWIDE>
2978 (vec_duplicate:VD_HSI
2980 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
2981 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
2986 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
2988 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
2990 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
2993 (define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
2994 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2996 (match_operand:<VWIDE> 1 "register_operand" "0")
2999 (sign_extend:<VWIDE>
3000 (match_operand:SD_HSI 2 "register_operand" "w"))
3001 (sign_extend:<VWIDE>
3003 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3004 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3009 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3011 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3013 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3016 (define_insn "aarch64_sqdml<SBINQOPS:as>l_laneq<mode>_internal"
3017 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3019 (match_operand:<VWIDE> 1 "register_operand" "0")
3022 (sign_extend:<VWIDE>
3023 (match_operand:SD_HSI 2 "register_operand" "w"))
3024 (sign_extend:<VWIDE>
3026 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3027 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3032 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3034 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3036 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3039 (define_expand "aarch64_sqdmlal_lane<mode>"
3040 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3041 (match_operand:<VWIDE> 1 "register_operand" "0")
3042 (match_operand:VSD_HSI 2 "register_operand" "w")
3043 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3044 (match_operand:SI 4 "immediate_operand" "i")]
3047 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCOND>mode));
3048 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3049 emit_insn (gen_aarch64_sqdmlal_lane<mode>_internal (operands[0], operands[1],
3050 operands[2], operands[3],
3055 (define_expand "aarch64_sqdmlal_laneq<mode>"
3056 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3057 (match_operand:<VWIDE> 1 "register_operand" "0")
3058 (match_operand:VSD_HSI 2 "register_operand" "w")
3059 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3060 (match_operand:SI 4 "immediate_operand" "i")]
3063 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCONQ>mode));
3064 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3065 emit_insn (gen_aarch64_sqdmlal_laneq<mode>_internal (operands[0], operands[1],
3066 operands[2], operands[3],
3071 (define_expand "aarch64_sqdmlsl_lane<mode>"
3072 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3073 (match_operand:<VWIDE> 1 "register_operand" "0")
3074 (match_operand:VSD_HSI 2 "register_operand" "w")
3075 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3076 (match_operand:SI 4 "immediate_operand" "i")]
3079 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCOND>mode));
3080 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3081 emit_insn (gen_aarch64_sqdmlsl_lane<mode>_internal (operands[0], operands[1],
3082 operands[2], operands[3],
3087 (define_expand "aarch64_sqdmlsl_laneq<mode>"
3088 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3089 (match_operand:<VWIDE> 1 "register_operand" "0")
3090 (match_operand:VSD_HSI 2 "register_operand" "w")
3091 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3092 (match_operand:SI 4 "immediate_operand" "i")]
3095 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCONQ>mode));
3096 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3097 emit_insn (gen_aarch64_sqdmlsl_laneq<mode>_internal (operands[0], operands[1],
3098 operands[2], operands[3],
3105 (define_insn "aarch64_sqdml<SBINQOPS:as>l_n<mode>"
3106 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3108 (match_operand:<VWIDE> 1 "register_operand" "0")
3111 (sign_extend:<VWIDE>
3112 (match_operand:VD_HSI 2 "register_operand" "w"))
3113 (sign_extend:<VWIDE>
3114 (vec_duplicate:VD_HSI
3115 (match_operand:<VEL> 3 "register_operand" "<vwx>"))))
3118 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
3119 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3124 (define_insn "aarch64_sqdml<SBINQOPS:as>l2<mode>_internal"
3125 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3127 (match_operand:<VWIDE> 1 "register_operand" "0")
3130 (sign_extend:<VWIDE>
3132 (match_operand:VQ_HSI 2 "register_operand" "w")
3133 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3134 (sign_extend:<VWIDE>
3136 (match_operand:VQ_HSI 3 "register_operand" "w")
3140 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
3141 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3144 (define_expand "aarch64_sqdmlal2<mode>"
3145 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3146 (match_operand:<VWIDE> 1 "register_operand" "w")
3147 (match_operand:VQ_HSI 2 "register_operand" "w")
3148 (match_operand:VQ_HSI 3 "register_operand" "w")]
3151 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3152 emit_insn (gen_aarch64_sqdmlal2<mode>_internal (operands[0], operands[1],
3153 operands[2], operands[3], p));
3157 (define_expand "aarch64_sqdmlsl2<mode>"
3158 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3159 (match_operand:<VWIDE> 1 "register_operand" "w")
3160 (match_operand:VQ_HSI 2 "register_operand" "w")
3161 (match_operand:VQ_HSI 3 "register_operand" "w")]
3164 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3165 emit_insn (gen_aarch64_sqdmlsl2<mode>_internal (operands[0], operands[1],
3166 operands[2], operands[3], p));
3172 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_lane<mode>_internal"
3173 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3175 (match_operand:<VWIDE> 1 "register_operand" "0")
3178 (sign_extend:<VWIDE>
3180 (match_operand:VQ_HSI 2 "register_operand" "w")
3181 (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" "")))
3182 (sign_extend:<VWIDE>
3183 (vec_duplicate:<VHALF>
3185 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3186 (parallel [(match_operand:SI 4 "immediate_operand" "i")])
3191 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3193 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3195 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3198 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_laneq<mode>_internal"
3199 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3201 (match_operand:<VWIDE> 1 "register_operand" "0")
3204 (sign_extend:<VWIDE>
3206 (match_operand:VQ_HSI 2 "register_operand" "w")
3207 (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" "")))
3208 (sign_extend:<VWIDE>
3209 (vec_duplicate:<VHALF>
3211 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3212 (parallel [(match_operand:SI 4 "immediate_operand" "i")])
3217 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3219 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3221 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3224 (define_expand "aarch64_sqdmlal2_lane<mode>"
3225 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3226 (match_operand:<VWIDE> 1 "register_operand" "w")
3227 (match_operand:VQ_HSI 2 "register_operand" "w")
3228 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3229 (match_operand:SI 4 "immediate_operand" "i")]
3232 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3233 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCOND>mode));
3234 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3235 emit_insn (gen_aarch64_sqdmlal2_lane<mode>_internal (operands[0], operands[1],
3236 operands[2], operands[3],
3241 (define_expand "aarch64_sqdmlal2_laneq<mode>"
3242 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3243 (match_operand:<VWIDE> 1 "register_operand" "w")
3244 (match_operand:VQ_HSI 2 "register_operand" "w")
3245 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3246 (match_operand:SI 4 "immediate_operand" "i")]
3249 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3250 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCONQ>mode));
3251 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3252 emit_insn (gen_aarch64_sqdmlal2_laneq<mode>_internal (operands[0], operands[1],
3253 operands[2], operands[3],
3258 (define_expand "aarch64_sqdmlsl2_lane<mode>"
3259 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3260 (match_operand:<VWIDE> 1 "register_operand" "w")
3261 (match_operand:VQ_HSI 2 "register_operand" "w")
3262 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3263 (match_operand:SI 4 "immediate_operand" "i")]
3266 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3267 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCOND>mode));
3268 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3269 emit_insn (gen_aarch64_sqdmlsl2_lane<mode>_internal (operands[0], operands[1],
3270 operands[2], operands[3],
3275 (define_expand "aarch64_sqdmlsl2_laneq<mode>"
3276 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3277 (match_operand:<VWIDE> 1 "register_operand" "w")
3278 (match_operand:VQ_HSI 2 "register_operand" "w")
3279 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3280 (match_operand:SI 4 "immediate_operand" "i")]
3283 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3284 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCONQ>mode));
3285 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3286 emit_insn (gen_aarch64_sqdmlsl2_laneq<mode>_internal (operands[0], operands[1],
3287 operands[2], operands[3],
3292 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal"
3293 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3295 (match_operand:<VWIDE> 1 "register_operand" "0")
3298 (sign_extend:<VWIDE>
3300 (match_operand:VQ_HSI 2 "register_operand" "w")
3301 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3302 (sign_extend:<VWIDE>
3303 (vec_duplicate:<VHALF>
3304 (match_operand:<VEL> 3 "register_operand" "<vwx>"))))
3307 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
3308 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3311 (define_expand "aarch64_sqdmlal2_n<mode>"
3312 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3313 (match_operand:<VWIDE> 1 "register_operand" "w")
3314 (match_operand:VQ_HSI 2 "register_operand" "w")
3315 (match_operand:<VEL> 3 "register_operand" "w")]
3318 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3319 emit_insn (gen_aarch64_sqdmlal2_n<mode>_internal (operands[0], operands[1],
3320 operands[2], operands[3],
3325 (define_expand "aarch64_sqdmlsl2_n<mode>"
3326 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3327 (match_operand:<VWIDE> 1 "register_operand" "w")
3328 (match_operand:VQ_HSI 2 "register_operand" "w")
3329 (match_operand:<VEL> 3 "register_operand" "w")]
3332 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3333 emit_insn (gen_aarch64_sqdmlsl2_n<mode>_internal (operands[0], operands[1],
3334 operands[2], operands[3],
3341 (define_insn "aarch64_sqdmull<mode>"
3342 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3345 (sign_extend:<VWIDE>
3346 (match_operand:VSD_HSI 1 "register_operand" "w"))
3347 (sign_extend:<VWIDE>
3348 (match_operand:VSD_HSI 2 "register_operand" "w")))
3351 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3352 [(set_attr "type" "neon_sat_mul_<Vetype>_long")]
3357 (define_insn "aarch64_sqdmull_lane<mode>_internal"
3358 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3361 (sign_extend:<VWIDE>
3362 (match_operand:VD_HSI 1 "register_operand" "w"))
3363 (sign_extend:<VWIDE>
3364 (vec_duplicate:VD_HSI
3366 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3367 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3372 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3373 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3375 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3378 (define_insn "aarch64_sqdmull_laneq<mode>_internal"
3379 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3382 (sign_extend:<VWIDE>
3383 (match_operand:VD_HSI 1 "register_operand" "w"))
3384 (sign_extend:<VWIDE>
3385 (vec_duplicate:VD_HSI
3387 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3388 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3393 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3394 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3396 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3399 (define_insn "aarch64_sqdmull_lane<mode>_internal"
3400 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3403 (sign_extend:<VWIDE>
3404 (match_operand:SD_HSI 1 "register_operand" "w"))
3405 (sign_extend:<VWIDE>
3407 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3408 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))
3413 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3414 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3416 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3419 (define_insn "aarch64_sqdmull_laneq<mode>_internal"
3420 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3423 (sign_extend:<VWIDE>
3424 (match_operand:SD_HSI 1 "register_operand" "w"))
3425 (sign_extend:<VWIDE>
3427 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3428 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))
3433 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3434 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3436 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3439 (define_expand "aarch64_sqdmull_lane<mode>"
3440 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3441 (match_operand:VSD_HSI 1 "register_operand" "w")
3442 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3443 (match_operand:SI 3 "immediate_operand" "i")]
3446 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
3447 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3448 emit_insn (gen_aarch64_sqdmull_lane<mode>_internal (operands[0], operands[1],
3449 operands[2], operands[3]));
3453 (define_expand "aarch64_sqdmull_laneq<mode>"
3454 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3455 (match_operand:VSD_HSI 1 "register_operand" "w")
3456 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3457 (match_operand:SI 3 "immediate_operand" "i")]
3460 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
3461 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3462 emit_insn (gen_aarch64_sqdmull_laneq<mode>_internal
3463 (operands[0], operands[1], operands[2], operands[3]));
3469 (define_insn "aarch64_sqdmull_n<mode>"
3470 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3473 (sign_extend:<VWIDE>
3474 (match_operand:VD_HSI 1 "register_operand" "w"))
3475 (sign_extend:<VWIDE>
3476 (vec_duplicate:VD_HSI
3477 (match_operand:<VEL> 2 "register_operand" "<vwx>")))
3481 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
3482 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3489 (define_insn "aarch64_sqdmull2<mode>_internal"
3490 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3493 (sign_extend:<VWIDE>
3495 (match_operand:VQ_HSI 1 "register_operand" "w")
3496 (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
3497 (sign_extend:<VWIDE>
3499 (match_operand:VQ_HSI 2 "register_operand" "w")
3504 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3505 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3508 (define_expand "aarch64_sqdmull2<mode>"
3509 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3510 (match_operand:VQ_HSI 1 "register_operand" "w")
3511 (match_operand:VQ_HSI 2 "register_operand" "w")]
3514 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3515 emit_insn (gen_aarch64_sqdmull2<mode>_internal (operands[0], operands[1],
3522 (define_insn "aarch64_sqdmull2_lane<mode>_internal"
3523 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3526 (sign_extend:<VWIDE>
3528 (match_operand:VQ_HSI 1 "register_operand" "w")
3529 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3530 (sign_extend:<VWIDE>
3531 (vec_duplicate:<VHALF>
3533 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3534 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3539 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3540 return "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3542 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3545 (define_insn "aarch64_sqdmull2_laneq<mode>_internal"
3546 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3549 (sign_extend:<VWIDE>
3551 (match_operand:VQ_HSI 1 "register_operand" "w")
3552 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3553 (sign_extend:<VWIDE>
3554 (vec_duplicate:<VHALF>
3556 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3557 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3562 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3563 return "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3565 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3568 (define_expand "aarch64_sqdmull2_lane<mode>"
3569 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3570 (match_operand:VQ_HSI 1 "register_operand" "w")
3571 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3572 (match_operand:SI 3 "immediate_operand" "i")]
3575 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3576 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
3577 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3578 emit_insn (gen_aarch64_sqdmull2_lane<mode>_internal (operands[0], operands[1],
3579 operands[2], operands[3],
3584 (define_expand "aarch64_sqdmull2_laneq<mode>"
3585 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3586 (match_operand:VQ_HSI 1 "register_operand" "w")
3587 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3588 (match_operand:SI 3 "immediate_operand" "i")]
3591 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3592 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
3593 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3594 emit_insn (gen_aarch64_sqdmull2_laneq<mode>_internal (operands[0], operands[1],
3595 operands[2], operands[3],
3602 (define_insn "aarch64_sqdmull2_n<mode>_internal"
3603 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3606 (sign_extend:<VWIDE>
3608 (match_operand:VQ_HSI 1 "register_operand" "w")
3609 (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
3610 (sign_extend:<VWIDE>
3611 (vec_duplicate:<VHALF>
3612 (match_operand:<VEL> 2 "register_operand" "<vwx>")))
3616 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
3617 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3620 (define_expand "aarch64_sqdmull2_n<mode>"
3621 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3622 (match_operand:VQ_HSI 1 "register_operand" "w")
3623 (match_operand:<VEL> 2 "register_operand" "w")]
3626 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3627 emit_insn (gen_aarch64_sqdmull2_n<mode>_internal (operands[0], operands[1],
3634 (define_insn "aarch64_<sur>shl<mode>"
3635 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3637 [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
3638 (match_operand:VSDQ_I_DI 2 "register_operand" "w")]
3641 "<sur>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
3642 [(set_attr "type" "neon_shift_reg<q>")]
3648 (define_insn "aarch64_<sur>q<r>shl<mode>"
3649 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3651 [(match_operand:VSDQ_I 1 "register_operand" "w")
3652 (match_operand:VSDQ_I 2 "register_operand" "w")]
3655 "<sur>q<r>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
3656 [(set_attr "type" "neon_sat_shift_reg<q>")]
3661 (define_insn "aarch64_<sur>shll_n<mode>"
3662 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3663 (unspec:<VWIDE> [(match_operand:VDW 1 "register_operand" "w")
3665 "aarch64_simd_shift_imm_bitsize_<ve_mode>" "i")]
3669 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3670 if (INTVAL (operands[2]) == bit_width)
3672 return \"shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3675 return \"<sur>shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3677 [(set_attr "type" "neon_shift_imm_long")]
3682 (define_insn "aarch64_<sur>shll2_n<mode>"
3683 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3684 (unspec:<VWIDE> [(match_operand:VQW 1 "register_operand" "w")
3685 (match_operand:SI 2 "immediate_operand" "i")]
3689 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3690 if (INTVAL (operands[2]) == bit_width)
3692 return \"shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3695 return \"<sur>shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3697 [(set_attr "type" "neon_shift_imm_long")]
3702 (define_insn "aarch64_<sur>shr_n<mode>"
3703 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3704 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
3706 "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
3709 "<sur>shr\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2"
3710 [(set_attr "type" "neon_sat_shift_imm<q>")]
3715 (define_insn "aarch64_<sur>sra_n<mode>"
3716 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3717 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
3718 (match_operand:VSDQ_I_DI 2 "register_operand" "w")
3720 "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
3723 "<sur>sra\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3"
3724 [(set_attr "type" "neon_shift_acc<q>")]
3729 (define_insn "aarch64_<sur>s<lr>i_n<mode>"
3730 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3731 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
3732 (match_operand:VSDQ_I_DI 2 "register_operand" "w")
3734 "aarch64_simd_shift_imm_<offsetlr><ve_mode>" "i")]
3737 "s<lr>i\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3"
3738 [(set_attr "type" "neon_shift_imm<q>")]
3743 (define_insn "aarch64_<sur>qshl<u>_n<mode>"
3744 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3745 (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "w")
3747 "aarch64_simd_shift_imm_<ve_mode>" "i")]
3750 "<sur>qshl<u>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2"
3751 [(set_attr "type" "neon_sat_shift_imm<q>")]
3757 (define_insn "aarch64_<sur>q<r>shr<u>n_n<mode>"
3758 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
3759 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")
3761 "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
3764 "<sur>q<r>shr<u>n\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2"
3765 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
3769 ;; cm(eq|ge|gt|lt|le)
3770 ;; Note, we have constraints for Dz and Z as different expanders
3771 ;; have different ideas of what should be passed to this pattern.
3773 (define_insn "aarch64_cm<optab><mode>"
3774 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
3776 (COMPARISONS:<V_cmp_result>
3777 (match_operand:VDQ 1 "register_operand" "w,w")
3778 (match_operand:VDQ 2 "aarch64_simd_reg_or_zero" "w,ZDz")
3782 cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
3783 cm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #0"
3784 [(set_attr "type" "neon_compare<q>, neon_compare_zero<q>")]
3787 (define_insn_and_split "aarch64_cm<optab>di"
3788 [(set (match_operand:DI 0 "register_operand" "=w,w,r")
3791 (match_operand:DI 1 "register_operand" "w,w,r")
3792 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz,r")
3794 (clobber (reg:CC CC_REGNUM))]
3798 [(set (match_operand:DI 0 "register_operand")
3801 (match_operand:DI 1 "register_operand")
3802 (match_operand:DI 2 "aarch64_simd_reg_or_zero")
3805 /* If we are in the general purpose register file,
3806 we split to a sequence of comparison and store. */
3807 if (GP_REGNUM_P (REGNO (operands[0]))
3808 && GP_REGNUM_P (REGNO (operands[1])))
3810 machine_mode mode = SELECT_CC_MODE (<CMP>, operands[1], operands[2]);
3811 rtx cc_reg = aarch64_gen_compare_reg (<CMP>, operands[1], operands[2]);
3812 rtx comparison = gen_rtx_<CMP> (mode, operands[1], operands[2]);
3813 emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
3816 /* Otherwise, we expand to a similar pattern which does not
3817 clobber CC_REGNUM. */
3819 [(set_attr "type" "neon_compare, neon_compare_zero, multiple")]
3822 (define_insn "*aarch64_cm<optab>di"
3823 [(set (match_operand:DI 0 "register_operand" "=w,w")
3826 (match_operand:DI 1 "register_operand" "w,w")
3827 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz")
3829 "TARGET_SIMD && reload_completed"
3831 cm<n_optab>\t%d0, %d<cmp_1>, %d<cmp_2>
3832 cm<optab>\t%d0, %d1, #0"
3833 [(set_attr "type" "neon_compare, neon_compare_zero")]
3838 (define_insn "aarch64_cm<optab><mode>"
3839 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
3841 (UCOMPARISONS:<V_cmp_result>
3842 (match_operand:VDQ 1 "register_operand" "w")
3843 (match_operand:VDQ 2 "register_operand" "w")
3846 "cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
3847 [(set_attr "type" "neon_compare<q>")]
3850 (define_insn_and_split "aarch64_cm<optab>di"
3851 [(set (match_operand:DI 0 "register_operand" "=w,r")
3854 (match_operand:DI 1 "register_operand" "w,r")
3855 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,r")
3857 (clobber (reg:CC CC_REGNUM))]
3861 [(set (match_operand:DI 0 "register_operand")
3864 (match_operand:DI 1 "register_operand")
3865 (match_operand:DI 2 "aarch64_simd_reg_or_zero")
3868 /* If we are in the general purpose register file,
3869 we split to a sequence of comparison and store. */
3870 if (GP_REGNUM_P (REGNO (operands[0]))
3871 && GP_REGNUM_P (REGNO (operands[1])))
3873 machine_mode mode = CCmode;
3874 rtx cc_reg = aarch64_gen_compare_reg (<CMP>, operands[1], operands[2]);
3875 rtx comparison = gen_rtx_<CMP> (mode, operands[1], operands[2]);
3876 emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
3879 /* Otherwise, we expand to a similar pattern which does not
3880 clobber CC_REGNUM. */
3882 [(set_attr "type" "neon_compare,multiple")]
3885 (define_insn "*aarch64_cm<optab>di"
3886 [(set (match_operand:DI 0 "register_operand" "=w")
3889 (match_operand:DI 1 "register_operand" "w")
3890 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w")
3892 "TARGET_SIMD && reload_completed"
3893 "cm<n_optab>\t%d0, %d<cmp_1>, %d<cmp_2>"
3894 [(set_attr "type" "neon_compare")]
3899 ;; Although neg (ne (and x y) 0) is the natural way of expressing a cmtst,
3900 ;; we don't have any insns using ne, and aarch64_vcond_internal outputs
3901 ;; not (neg (eq (and x y) 0))
3902 ;; which is rewritten by simplify_rtx as
3903 ;; plus (eq (and x y) 0) -1.
3905 (define_insn "aarch64_cmtst<mode>"
3906 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
3907 (plus:<V_cmp_result>
3910 (match_operand:VDQ 1 "register_operand" "w")
3911 (match_operand:VDQ 2 "register_operand" "w"))
3912 (match_operand:VDQ 3 "aarch64_simd_imm_zero"))
3913 (match_operand:<V_cmp_result> 4 "aarch64_simd_imm_minus_one")))
3916 "cmtst\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3917 [(set_attr "type" "neon_tst<q>")]
3920 (define_insn_and_split "aarch64_cmtstdi"
3921 [(set (match_operand:DI 0 "register_operand" "=w,r")
3925 (match_operand:DI 1 "register_operand" "w,r")
3926 (match_operand:DI 2 "register_operand" "w,r"))
3928 (clobber (reg:CC CC_REGNUM))]
3932 [(set (match_operand:DI 0 "register_operand")
3936 (match_operand:DI 1 "register_operand")
3937 (match_operand:DI 2 "register_operand"))
3940 /* If we are in the general purpose register file,
3941 we split to a sequence of comparison and store. */
3942 if (GP_REGNUM_P (REGNO (operands[0]))
3943 && GP_REGNUM_P (REGNO (operands[1])))
3945 rtx and_tree = gen_rtx_AND (DImode, operands[1], operands[2]);
3946 machine_mode mode = SELECT_CC_MODE (NE, and_tree, const0_rtx);
3947 rtx cc_reg = aarch64_gen_compare_reg (NE, and_tree, const0_rtx);
3948 rtx comparison = gen_rtx_NE (mode, and_tree, const0_rtx);
3949 emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
3952 /* Otherwise, we expand to a similar pattern which does not
3953 clobber CC_REGNUM. */
3955 [(set_attr "type" "neon_tst,multiple")]
3958 (define_insn "*aarch64_cmtstdi"
3959 [(set (match_operand:DI 0 "register_operand" "=w")
3963 (match_operand:DI 1 "register_operand" "w")
3964 (match_operand:DI 2 "register_operand" "w"))
3967 "cmtst\t%d0, %d1, %d2"
3968 [(set_attr "type" "neon_tst")]
3971 ;; fcm(eq|ge|gt|le|lt)
3973 (define_insn "aarch64_cm<optab><mode>"
3974 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
3976 (COMPARISONS:<V_cmp_result>
3977 (match_operand:VALLF 1 "register_operand" "w,w")
3978 (match_operand:VALLF 2 "aarch64_simd_reg_or_zero" "w,YDz")
3982 fcm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
3983 fcm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
3984 [(set_attr "type" "neon_fp_compare_<Vetype><q>")]
3988 ;; Note we can also handle what would be fac(le|lt) by
3989 ;; generating fac(ge|gt).
3991 (define_insn "*aarch64_fac<optab><mode>"
3992 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
3994 (FAC_COMPARISONS:<V_cmp_result>
3995 (abs:VALLF (match_operand:VALLF 1 "register_operand" "w"))
3996 (abs:VALLF (match_operand:VALLF 2 "register_operand" "w"))
3999 "fac<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
4000 [(set_attr "type" "neon_fp_compare_<Vetype><q>")]
4005 (define_insn "aarch64_addp<mode>"
4006 [(set (match_operand:VD_BHSI 0 "register_operand" "=w")
4008 [(match_operand:VD_BHSI 1 "register_operand" "w")
4009 (match_operand:VD_BHSI 2 "register_operand" "w")]
4012 "addp\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
4013 [(set_attr "type" "neon_reduc_add<q>")]
4016 (define_insn "aarch64_addpdi"
4017 [(set (match_operand:DI 0 "register_operand" "=w")
4019 [(match_operand:V2DI 1 "register_operand" "w")]
4023 [(set_attr "type" "neon_reduc_add")]
4028 (define_insn "sqrt<mode>2"
4029 [(set (match_operand:VDQF 0 "register_operand" "=w")
4030 (sqrt:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
4032 "fsqrt\\t%0.<Vtype>, %1.<Vtype>"
4033 [(set_attr "type" "neon_fp_sqrt_<Vetype><q>")]
4036 ;; Patterns for vector struct loads and stores.
4038 (define_insn "vec_load_lanesoi<mode>"
4039 [(set (match_operand:OI 0 "register_operand" "=w")
4040 (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")
4041 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4044 "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4045 [(set_attr "type" "neon_load2_2reg<q>")]
4048 (define_insn "aarch64_simd_ld2r<mode>"
4049 [(set (match_operand:OI 0 "register_operand" "=w")
4050 (unspec:OI [(match_operand:<V_TWO_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4051 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4054 "ld2r\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4055 [(set_attr "type" "neon_load2_all_lanes<q>")]
4058 (define_insn "aarch64_vec_load_lanesoi_lane<mode>"
4059 [(set (match_operand:OI 0 "register_operand" "=w")
4060 (unspec:OI [(match_operand:<V_TWO_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4061 (match_operand:OI 2 "register_operand" "0")
4062 (match_operand:SI 3 "immediate_operand" "i")
4063 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4066 "ld2\\t{%S0.<Vetype> - %T0.<Vetype>}[%3], %1"
4067 [(set_attr "type" "neon_load2_one_lane")]
4070 (define_insn "vec_store_lanesoi<mode>"
4071 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
4072 (unspec:OI [(match_operand:OI 1 "register_operand" "w")
4073 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4076 "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
4077 [(set_attr "type" "neon_store2_2reg<q>")]
4080 (define_insn "vec_store_lanesoi_lane<mode>"
4081 [(set (match_operand:<V_TWO_ELEM> 0 "aarch64_simd_struct_operand" "=Utv")
4082 (unspec:<V_TWO_ELEM> [(match_operand:OI 1 "register_operand" "w")
4083 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4084 (match_operand:SI 2 "immediate_operand" "i")]
4087 "st2\\t{%S1.<Vetype> - %T1.<Vetype>}[%2], %0"
4088 [(set_attr "type" "neon_store3_one_lane<q>")]
4091 (define_insn "vec_load_lanesci<mode>"
4092 [(set (match_operand:CI 0 "register_operand" "=w")
4093 (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv")
4094 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4097 "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4098 [(set_attr "type" "neon_load3_3reg<q>")]
4101 (define_insn "aarch64_simd_ld3r<mode>"
4102 [(set (match_operand:CI 0 "register_operand" "=w")
4103 (unspec:CI [(match_operand:<V_THREE_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4104 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4107 "ld3r\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4108 [(set_attr "type" "neon_load3_all_lanes<q>")]
4111 (define_insn "aarch64_vec_load_lanesci_lane<mode>"
4112 [(set (match_operand:CI 0 "register_operand" "=w")
4113 (unspec:CI [(match_operand:<V_THREE_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4114 (match_operand:CI 2 "register_operand" "0")
4115 (match_operand:SI 3 "immediate_operand" "i")
4116 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4119 "ld3\\t{%S0.<Vetype> - %U0.<Vetype>}[%3], %1"
4120 [(set_attr "type" "neon_load3_one_lane")]
4123 (define_insn "vec_store_lanesci<mode>"
4124 [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv")
4125 (unspec:CI [(match_operand:CI 1 "register_operand" "w")
4126 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4129 "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
4130 [(set_attr "type" "neon_store3_3reg<q>")]
4133 (define_insn "vec_store_lanesci_lane<mode>"
4134 [(set (match_operand:<V_THREE_ELEM> 0 "aarch64_simd_struct_operand" "=Utv")
4135 (unspec:<V_THREE_ELEM> [(match_operand:CI 1 "register_operand" "w")
4136 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4137 (match_operand:SI 2 "immediate_operand" "i")]
4140 "st3\\t{%S1.<Vetype> - %U1.<Vetype>}[%2], %0"
4141 [(set_attr "type" "neon_store3_one_lane<q>")]
4144 (define_insn "vec_load_lanesxi<mode>"
4145 [(set (match_operand:XI 0 "register_operand" "=w")
4146 (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv")
4147 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4150 "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4151 [(set_attr "type" "neon_load4_4reg<q>")]
4154 (define_insn "aarch64_simd_ld4r<mode>"
4155 [(set (match_operand:XI 0 "register_operand" "=w")
4156 (unspec:XI [(match_operand:<V_FOUR_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4157 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4160 "ld4r\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4161 [(set_attr "type" "neon_load4_all_lanes<q>")]
4164 (define_insn "aarch64_vec_load_lanesxi_lane<mode>"
4165 [(set (match_operand:XI 0 "register_operand" "=w")
4166 (unspec:XI [(match_operand:<V_FOUR_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4167 (match_operand:XI 2 "register_operand" "0")
4168 (match_operand:SI 3 "immediate_operand" "i")
4169 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4172 "ld4\\t{%S0.<Vetype> - %V0.<Vetype>}[%3], %1"
4173 [(set_attr "type" "neon_load4_one_lane")]
4176 (define_insn "vec_store_lanesxi<mode>"
4177 [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
4178 (unspec:XI [(match_operand:XI 1 "register_operand" "w")
4179 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4182 "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
4183 [(set_attr "type" "neon_store4_4reg<q>")]
4186 (define_insn "vec_store_lanesxi_lane<mode>"
4187 [(set (match_operand:<V_FOUR_ELEM> 0 "aarch64_simd_struct_operand" "=Utv")
4188 (unspec:<V_FOUR_ELEM> [(match_operand:XI 1 "register_operand" "w")
4189 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4190 (match_operand:SI 2 "immediate_operand" "i")]
4193 "st4\\t{%S1.<Vetype> - %V1.<Vetype>}[%2], %0"
4194 [(set_attr "type" "neon_store4_one_lane<q>")]
4197 ;; Reload patterns for AdvSIMD register list operands.
4199 (define_expand "mov<mode>"
4200 [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "")
4201 (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" ""))]
4204 if (can_create_pseudo_p ())
4206 if (GET_CODE (operands[0]) != REG)
4207 operands[1] = force_reg (<MODE>mode, operands[1]);
4211 (define_insn "*aarch64_mov<mode>"
4212 [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "=w,Utv,w")
4213 (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" " w,w,Utv"))]
4215 && (register_operand (operands[0], <MODE>mode)
4216 || register_operand (operands[1], <MODE>mode))"
4219 switch (which_alternative)
4222 case 1: return "st1\\t{%S1.16b - %<Vendreg>1.16b}, %0";
4223 case 2: return "ld1\\t{%S0.16b - %<Vendreg>0.16b}, %1";
4224 default: gcc_unreachable ();
4227 [(set_attr "type" "neon_move,neon_store<nregs>_<nregs>reg_q,\
4228 neon_load<nregs>_<nregs>reg_q")
4229 (set (attr "length") (symbol_ref "aarch64_simd_attr_length_move (insn)"))]
4232 (define_insn "aarch64_be_ld1<mode>"
4233 [(set (match_operand:VALLDI 0 "register_operand" "=w")
4234 (unspec:VALLDI [(match_operand:VALLDI 1 "aarch64_simd_struct_operand" "Utv")]
4237 "ld1\\t{%0<Vmtype>}, %1"
4238 [(set_attr "type" "neon_load1_1reg<q>")]
4241 (define_insn "aarch64_be_st1<mode>"
4242 [(set (match_operand:VALLDI 0 "aarch64_simd_struct_operand" "=Utv")
4243 (unspec:VALLDI [(match_operand:VALLDI 1 "register_operand" "w")]
4246 "st1\\t{%1<Vmtype>}, %0"
4247 [(set_attr "type" "neon_store1_1reg<q>")]
4251 [(set (match_operand:OI 0 "register_operand" "")
4252 (match_operand:OI 1 "register_operand" ""))]
4253 "TARGET_SIMD && reload_completed"
4254 [(set (match_dup 0) (match_dup 1))
4255 (set (match_dup 2) (match_dup 3))]
4257 int rdest = REGNO (operands[0]);
4258 int rsrc = REGNO (operands[1]);
4259 rtx dest[2], src[2];
4261 dest[0] = gen_rtx_REG (TFmode, rdest);
4262 src[0] = gen_rtx_REG (TFmode, rsrc);
4263 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
4264 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
4266 aarch64_simd_disambiguate_copy (operands, dest, src, 2);
4270 [(set (match_operand:CI 0 "register_operand" "")
4271 (match_operand:CI 1 "register_operand" ""))]
4272 "TARGET_SIMD && reload_completed"
4273 [(set (match_dup 0) (match_dup 1))
4274 (set (match_dup 2) (match_dup 3))
4275 (set (match_dup 4) (match_dup 5))]
4277 int rdest = REGNO (operands[0]);
4278 int rsrc = REGNO (operands[1]);
4279 rtx dest[3], src[3];
4281 dest[0] = gen_rtx_REG (TFmode, rdest);
4282 src[0] = gen_rtx_REG (TFmode, rsrc);
4283 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
4284 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
4285 dest[2] = gen_rtx_REG (TFmode, rdest + 2);
4286 src[2] = gen_rtx_REG (TFmode, rsrc + 2);
4288 aarch64_simd_disambiguate_copy (operands, dest, src, 3);
4292 [(set (match_operand:XI 0 "register_operand" "")
4293 (match_operand:XI 1 "register_operand" ""))]
4294 "TARGET_SIMD && reload_completed"
4295 [(set (match_dup 0) (match_dup 1))
4296 (set (match_dup 2) (match_dup 3))
4297 (set (match_dup 4) (match_dup 5))
4298 (set (match_dup 6) (match_dup 7))]
4300 int rdest = REGNO (operands[0]);
4301 int rsrc = REGNO (operands[1]);
4302 rtx dest[4], src[4];
4304 dest[0] = gen_rtx_REG (TFmode, rdest);
4305 src[0] = gen_rtx_REG (TFmode, rsrc);
4306 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
4307 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
4308 dest[2] = gen_rtx_REG (TFmode, rdest + 2);
4309 src[2] = gen_rtx_REG (TFmode, rsrc + 2);
4310 dest[3] = gen_rtx_REG (TFmode, rdest + 3);
4311 src[3] = gen_rtx_REG (TFmode, rsrc + 3);
4313 aarch64_simd_disambiguate_copy (operands, dest, src, 4);
4316 (define_expand "aarch64_ld2r<mode>"
4317 [(match_operand:OI 0 "register_operand" "=w")
4318 (match_operand:DI 1 "register_operand" "w")
4319 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4322 machine_mode mode = <V_TWO_ELEM>mode;
4323 rtx mem = gen_rtx_MEM (mode, operands[1]);
4325 emit_insn (gen_aarch64_simd_ld2r<mode> (operands[0], mem));
4329 (define_expand "aarch64_ld3r<mode>"
4330 [(match_operand:CI 0 "register_operand" "=w")
4331 (match_operand:DI 1 "register_operand" "w")
4332 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4335 machine_mode mode = <V_THREE_ELEM>mode;
4336 rtx mem = gen_rtx_MEM (mode, operands[1]);
4338 emit_insn (gen_aarch64_simd_ld3r<mode> (operands[0], mem));
4342 (define_expand "aarch64_ld4r<mode>"
4343 [(match_operand:XI 0 "register_operand" "=w")
4344 (match_operand:DI 1 "register_operand" "w")
4345 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4348 machine_mode mode = <V_FOUR_ELEM>mode;
4349 rtx mem = gen_rtx_MEM (mode, operands[1]);
4351 emit_insn (gen_aarch64_simd_ld4r<mode> (operands[0],mem));
4355 (define_insn "aarch64_ld2<mode>_dreg"
4356 [(set (match_operand:OI 0 "register_operand" "=w")
4360 (unspec:VD [(match_operand:TI 1 "aarch64_simd_struct_operand" "Utv")]
4362 (vec_duplicate:VD (const_int 0)))
4364 (unspec:VD [(match_dup 1)]
4366 (vec_duplicate:VD (const_int 0)))) 0))]
4368 "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4369 [(set_attr "type" "neon_load2_2reg<q>")]
4372 (define_insn "aarch64_ld2<mode>_dreg"
4373 [(set (match_operand:OI 0 "register_operand" "=w")
4377 (unspec:DX [(match_operand:TI 1 "aarch64_simd_struct_operand" "Utv")]
4381 (unspec:DX [(match_dup 1)]
4383 (const_int 0))) 0))]
4385 "ld1\\t{%S0.1d - %T0.1d}, %1"
4386 [(set_attr "type" "neon_load1_2reg<q>")]
4389 (define_insn "aarch64_ld3<mode>_dreg"
4390 [(set (match_operand:CI 0 "register_operand" "=w")
4395 (unspec:VD [(match_operand:EI 1 "aarch64_simd_struct_operand" "Utv")]
4397 (vec_duplicate:VD (const_int 0)))
4399 (unspec:VD [(match_dup 1)]
4401 (vec_duplicate:VD (const_int 0))))
4403 (unspec:VD [(match_dup 1)]
4405 (vec_duplicate:VD (const_int 0)))) 0))]
4407 "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4408 [(set_attr "type" "neon_load3_3reg<q>")]
4411 (define_insn "aarch64_ld3<mode>_dreg"
4412 [(set (match_operand:CI 0 "register_operand" "=w")
4417 (unspec:DX [(match_operand:EI 1 "aarch64_simd_struct_operand" "Utv")]
4421 (unspec:DX [(match_dup 1)]
4425 (unspec:DX [(match_dup 1)]
4427 (const_int 0))) 0))]
4429 "ld1\\t{%S0.1d - %U0.1d}, %1"
4430 [(set_attr "type" "neon_load1_3reg<q>")]
4433 (define_insn "aarch64_ld4<mode>_dreg"
4434 [(set (match_operand:XI 0 "register_operand" "=w")
4439 (unspec:VD [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")]
4441 (vec_duplicate:VD (const_int 0)))
4443 (unspec:VD [(match_dup 1)]
4445 (vec_duplicate:VD (const_int 0))))
4448 (unspec:VD [(match_dup 1)]
4450 (vec_duplicate:VD (const_int 0)))
4452 (unspec:VD [(match_dup 1)]
4454 (vec_duplicate:VD (const_int 0))))) 0))]
4456 "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4457 [(set_attr "type" "neon_load4_4reg<q>")]
4460 (define_insn "aarch64_ld4<mode>_dreg"
4461 [(set (match_operand:XI 0 "register_operand" "=w")
4466 (unspec:DX [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")]
4470 (unspec:DX [(match_dup 1)]
4475 (unspec:DX [(match_dup 1)]
4479 (unspec:DX [(match_dup 1)]
4481 (const_int 0)))) 0))]
4483 "ld1\\t{%S0.1d - %V0.1d}, %1"
4484 [(set_attr "type" "neon_load1_4reg<q>")]
4487 (define_expand "aarch64_ld<VSTRUCT:nregs><VDC:mode>"
4488 [(match_operand:VSTRUCT 0 "register_operand" "=w")
4489 (match_operand:DI 1 "register_operand" "r")
4490 (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4493 machine_mode mode = <VSTRUCT:VSTRUCT_DREG>mode;
4494 rtx mem = gen_rtx_MEM (mode, operands[1]);
4496 emit_insn (gen_aarch64_ld<VSTRUCT:nregs><VDC:mode>_dreg (operands[0], mem));
4500 (define_expand "aarch64_ld1<VALL:mode>"
4501 [(match_operand:VALL 0 "register_operand")
4502 (match_operand:DI 1 "register_operand")]
4505 machine_mode mode = <VALL:MODE>mode;
4506 rtx mem = gen_rtx_MEM (mode, operands[1]);
4508 if (BYTES_BIG_ENDIAN)
4509 emit_insn (gen_aarch64_be_ld1<VALL:mode> (operands[0], mem));
4511 emit_move_insn (operands[0], mem);
4515 (define_expand "aarch64_ld<VSTRUCT:nregs><VQ:mode>"
4516 [(match_operand:VSTRUCT 0 "register_operand" "=w")
4517 (match_operand:DI 1 "register_operand" "r")
4518 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4521 machine_mode mode = <VSTRUCT:MODE>mode;
4522 rtx mem = gen_rtx_MEM (mode, operands[1]);
4524 emit_insn (gen_vec_load_lanes<VSTRUCT:mode><VQ:mode> (operands[0], mem));
4528 (define_expand "aarch64_ld2_lane<mode>"
4529 [(match_operand:OI 0 "register_operand" "=w")
4530 (match_operand:DI 1 "register_operand" "w")
4531 (match_operand:OI 2 "register_operand" "0")
4532 (match_operand:SI 3 "immediate_operand" "i")
4533 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4536 machine_mode mode = <V_TWO_ELEM>mode;
4537 rtx mem = gen_rtx_MEM (mode, operands[1]);
4539 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
4540 emit_insn (gen_aarch64_vec_load_lanesoi_lane<mode> (operands[0],
4547 (define_expand "aarch64_ld3_lane<mode>"
4548 [(match_operand:CI 0 "register_operand" "=w")
4549 (match_operand:DI 1 "register_operand" "w")
4550 (match_operand:CI 2 "register_operand" "0")
4551 (match_operand:SI 3 "immediate_operand" "i")
4552 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4555 machine_mode mode = <V_THREE_ELEM>mode;
4556 rtx mem = gen_rtx_MEM (mode, operands[1]);
4558 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
4559 emit_insn (gen_aarch64_vec_load_lanesci_lane<mode> (operands[0],
4566 (define_expand "aarch64_ld4_lane<mode>"
4567 [(match_operand:XI 0 "register_operand" "=w")
4568 (match_operand:DI 1 "register_operand" "w")
4569 (match_operand:XI 2 "register_operand" "0")
4570 (match_operand:SI 3 "immediate_operand" "i")
4571 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4574 machine_mode mode = <V_FOUR_ELEM>mode;
4575 rtx mem = gen_rtx_MEM (mode, operands[1]);
4577 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
4578 emit_insn (gen_aarch64_vec_load_lanesxi_lane<mode> (operands[0],
4587 ;; Expanders for builtins to extract vector registers from large
4588 ;; opaque integer modes.
4592 (define_expand "aarch64_get_dreg<VSTRUCT:mode><VDC:mode>"
4593 [(match_operand:VDC 0 "register_operand" "=w")
4594 (match_operand:VSTRUCT 1 "register_operand" "w")
4595 (match_operand:SI 2 "immediate_operand" "i")]
4598 int part = INTVAL (operands[2]);
4599 rtx temp = gen_reg_rtx (<VDC:VDBL>mode);
4600 int offset = part * 16;
4602 emit_move_insn (temp, gen_rtx_SUBREG (<VDC:VDBL>mode, operands[1], offset));
4603 emit_move_insn (operands[0], gen_lowpart (<VDC:MODE>mode, temp));
4609 (define_expand "aarch64_get_qreg<VSTRUCT:mode><VQ:mode>"
4610 [(match_operand:VQ 0 "register_operand" "=w")
4611 (match_operand:VSTRUCT 1 "register_operand" "w")
4612 (match_operand:SI 2 "immediate_operand" "i")]
4615 int part = INTVAL (operands[2]);
4616 int offset = part * 16;
4618 emit_move_insn (operands[0],
4619 gen_rtx_SUBREG (<VQ:MODE>mode, operands[1], offset));
4623 ;; Permuted-store expanders for neon intrinsics.
4625 ;; Permute instructions
4629 (define_expand "vec_perm_const<mode>"
4630 [(match_operand:VALL 0 "register_operand")
4631 (match_operand:VALL 1 "register_operand")
4632 (match_operand:VALL 2 "register_operand")
4633 (match_operand:<V_cmp_result> 3)]
4636 if (aarch64_expand_vec_perm_const (operands[0], operands[1],
4637 operands[2], operands[3]))
4643 (define_expand "vec_perm<mode>"
4644 [(match_operand:VB 0 "register_operand")
4645 (match_operand:VB 1 "register_operand")
4646 (match_operand:VB 2 "register_operand")
4647 (match_operand:VB 3 "register_operand")]
4650 aarch64_expand_vec_perm (operands[0], operands[1],
4651 operands[2], operands[3]);
4655 (define_insn "aarch64_tbl1<mode>"
4656 [(set (match_operand:VB 0 "register_operand" "=w")
4657 (unspec:VB [(match_operand:V16QI 1 "register_operand" "w")
4658 (match_operand:VB 2 "register_operand" "w")]
4661 "tbl\\t%0.<Vtype>, {%1.16b}, %2.<Vtype>"
4662 [(set_attr "type" "neon_tbl1<q>")]
4665 ;; Two source registers.
4667 (define_insn "aarch64_tbl2v16qi"
4668 [(set (match_operand:V16QI 0 "register_operand" "=w")
4669 (unspec:V16QI [(match_operand:OI 1 "register_operand" "w")
4670 (match_operand:V16QI 2 "register_operand" "w")]
4673 "tbl\\t%0.16b, {%S1.16b - %T1.16b}, %2.16b"
4674 [(set_attr "type" "neon_tbl2_q")]
4677 (define_insn_and_split "aarch64_combinev16qi"
4678 [(set (match_operand:OI 0 "register_operand" "=w")
4679 (unspec:OI [(match_operand:V16QI 1 "register_operand" "w")
4680 (match_operand:V16QI 2 "register_operand" "w")]
4684 "&& reload_completed"
4687 aarch64_split_combinev16qi (operands);
4690 [(set_attr "type" "multiple")]
4693 (define_insn "aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>"
4694 [(set (match_operand:VALL 0 "register_operand" "=w")
4695 (unspec:VALL [(match_operand:VALL 1 "register_operand" "w")
4696 (match_operand:VALL 2 "register_operand" "w")]
4699 "<PERMUTE:perm_insn><PERMUTE:perm_hilo>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
4700 [(set_attr "type" "neon_permute<q>")]
4703 ;; Note immediate (third) operand is lane index not byte index.
4704 (define_insn "aarch64_ext<mode>"
4705 [(set (match_operand:VALL 0 "register_operand" "=w")
4706 (unspec:VALL [(match_operand:VALL 1 "register_operand" "w")
4707 (match_operand:VALL 2 "register_operand" "w")
4708 (match_operand:SI 3 "immediate_operand" "i")]
4712 operands[3] = GEN_INT (INTVAL (operands[3])
4713 * GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)));
4714 return "ext\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>, #%3";
4716 [(set_attr "type" "neon_ext<q>")]
4719 ;; This exists solely to check the arguments to the corresponding __builtin.
4720 ;; Used where we want an error for out-of-range indices which would otherwise
4721 ;; be silently wrapped (e.g. the mask to a __builtin_shuffle).
4722 (define_expand "aarch64_im_lane_boundsi"
4723 [(match_operand:SI 0 "immediate_operand" "i")
4724 (match_operand:SI 1 "immediate_operand" "i")]
4727 aarch64_simd_lane_bounds (operands[0], 0, INTVAL (operands[1]));
4732 (define_insn "aarch64_rev<REVERSE:rev_op><mode>"
4733 [(set (match_operand:VALL 0 "register_operand" "=w")
4734 (unspec:VALL [(match_operand:VALL 1 "register_operand" "w")]
4737 "rev<REVERSE:rev_op>\\t%0.<Vtype>, %1.<Vtype>"
4738 [(set_attr "type" "neon_rev<q>")]
4741 (define_insn "aarch64_st2<mode>_dreg"
4742 [(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
4743 (unspec:TI [(match_operand:OI 1 "register_operand" "w")
4744 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4747 "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
4748 [(set_attr "type" "neon_store2_2reg")]
4751 (define_insn "aarch64_st2<mode>_dreg"
4752 [(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
4753 (unspec:TI [(match_operand:OI 1 "register_operand" "w")
4754 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4757 "st1\\t{%S1.1d - %T1.1d}, %0"
4758 [(set_attr "type" "neon_store1_2reg")]
4761 (define_insn "aarch64_st3<mode>_dreg"
4762 [(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
4763 (unspec:EI [(match_operand:CI 1 "register_operand" "w")
4764 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4767 "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
4768 [(set_attr "type" "neon_store3_3reg")]
4771 (define_insn "aarch64_st3<mode>_dreg"
4772 [(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
4773 (unspec:EI [(match_operand:CI 1 "register_operand" "w")
4774 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4777 "st1\\t{%S1.1d - %U1.1d}, %0"
4778 [(set_attr "type" "neon_store1_3reg")]
4781 (define_insn "aarch64_st4<mode>_dreg"
4782 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
4783 (unspec:OI [(match_operand:XI 1 "register_operand" "w")
4784 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4787 "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
4788 [(set_attr "type" "neon_store4_4reg")]
4791 (define_insn "aarch64_st4<mode>_dreg"
4792 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
4793 (unspec:OI [(match_operand:XI 1 "register_operand" "w")
4794 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4797 "st1\\t{%S1.1d - %V1.1d}, %0"
4798 [(set_attr "type" "neon_store1_4reg")]
4801 (define_expand "aarch64_st<VSTRUCT:nregs><VDC:mode>"
4802 [(match_operand:DI 0 "register_operand" "r")
4803 (match_operand:VSTRUCT 1 "register_operand" "w")
4804 (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4807 machine_mode mode = <VSTRUCT:VSTRUCT_DREG>mode;
4808 rtx mem = gen_rtx_MEM (mode, operands[0]);
4810 emit_insn (gen_aarch64_st<VSTRUCT:nregs><VDC:mode>_dreg (mem, operands[1]));
4814 (define_expand "aarch64_st<VSTRUCT:nregs><VQ:mode>"
4815 [(match_operand:DI 0 "register_operand" "r")
4816 (match_operand:VSTRUCT 1 "register_operand" "w")
4817 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4820 machine_mode mode = <VSTRUCT:MODE>mode;
4821 rtx mem = gen_rtx_MEM (mode, operands[0]);
4823 emit_insn (gen_vec_store_lanes<VSTRUCT:mode><VQ:mode> (mem, operands[1]));
4827 (define_expand "aarch64_st2_lane<VQ:mode>"
4828 [(match_operand:DI 0 "register_operand" "r")
4829 (match_operand:OI 1 "register_operand" "w")
4830 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4831 (match_operand:SI 2 "immediate_operand")]
4834 machine_mode mode = <V_TWO_ELEM>mode;
4835 rtx mem = gen_rtx_MEM (mode, operands[0]);
4836 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4838 emit_insn (gen_vec_store_lanesoi_lane<VQ:mode> (mem,
4844 (define_expand "aarch64_st3_lane<VQ:mode>"
4845 [(match_operand:DI 0 "register_operand" "r")
4846 (match_operand:CI 1 "register_operand" "w")
4847 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4848 (match_operand:SI 2 "immediate_operand")]
4851 machine_mode mode = <V_THREE_ELEM>mode;
4852 rtx mem = gen_rtx_MEM (mode, operands[0]);
4853 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4855 emit_insn (gen_vec_store_lanesci_lane<VQ:mode> (mem,
4861 (define_expand "aarch64_st4_lane<VQ:mode>"
4862 [(match_operand:DI 0 "register_operand" "r")
4863 (match_operand:XI 1 "register_operand" "w")
4864 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4865 (match_operand:SI 2 "immediate_operand")]
4868 machine_mode mode = <V_FOUR_ELEM>mode;
4869 rtx mem = gen_rtx_MEM (mode, operands[0]);
4870 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4872 emit_insn (gen_vec_store_lanesxi_lane<VQ:mode> (mem,
4878 (define_expand "aarch64_st1<VALL:mode>"
4879 [(match_operand:DI 0 "register_operand")
4880 (match_operand:VALL 1 "register_operand")]
4883 machine_mode mode = <VALL:MODE>mode;
4884 rtx mem = gen_rtx_MEM (mode, operands[0]);
4886 if (BYTES_BIG_ENDIAN)
4887 emit_insn (gen_aarch64_be_st1<VALL:mode> (mem, operands[1]));
4889 emit_move_insn (mem, operands[1]);
4893 ;; Expander for builtins to insert vector registers into large
4894 ;; opaque integer modes.
4896 ;; Q-register list. We don't need a D-reg inserter as we zero
4897 ;; extend them in arm_neon.h and insert the resulting Q-regs.
4899 (define_expand "aarch64_set_qreg<VSTRUCT:mode><VQ:mode>"
4900 [(match_operand:VSTRUCT 0 "register_operand" "+w")
4901 (match_operand:VSTRUCT 1 "register_operand" "0")
4902 (match_operand:VQ 2 "register_operand" "w")
4903 (match_operand:SI 3 "immediate_operand" "i")]
4906 int part = INTVAL (operands[3]);
4907 int offset = part * 16;
4909 emit_move_insn (operands[0], operands[1]);
4910 emit_move_insn (gen_rtx_SUBREG (<VQ:MODE>mode, operands[0], offset),
4915 ;; Standard pattern name vec_init<mode>.
4917 (define_expand "vec_init<mode>"
4918 [(match_operand:VALL 0 "register_operand" "")
4919 (match_operand 1 "" "")]
4922 aarch64_expand_vector_init (operands[0], operands[1]);
4926 (define_insn "*aarch64_simd_ld1r<mode>"
4927 [(set (match_operand:VALLDI 0 "register_operand" "=w")
4928 (vec_duplicate:VALLDI
4929 (match_operand:<VEL> 1 "aarch64_simd_struct_operand" "Utv")))]
4931 "ld1r\\t{%0.<Vtype>}, %1"
4932 [(set_attr "type" "neon_load1_all_lanes")]
4935 (define_insn "aarch64_frecpe<mode>"
4936 [(set (match_operand:VDQF 0 "register_operand" "=w")
4937 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")]
4940 "frecpe\\t%0.<Vtype>, %1.<Vtype>"
4941 [(set_attr "type" "neon_fp_recpe_<Vetype><q>")]
4944 (define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
4945 [(set (match_operand:GPF 0 "register_operand" "=w")
4946 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4949 "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
4950 [(set_attr "type" "neon_fp_recp<FRECP:frecp_suffix>_<GPF:Vetype><GPF:q>")]
4953 (define_insn "aarch64_frecps<mode>"
4954 [(set (match_operand:VALLF 0 "register_operand" "=w")
4955 (unspec:VALLF [(match_operand:VALLF 1 "register_operand" "w")
4956 (match_operand:VALLF 2 "register_operand" "w")]
4959 "frecps\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
4960 [(set_attr "type" "neon_fp_recps_<Vetype><q>")]
4963 ;; Standard pattern name vec_extract<mode>.
4965 (define_expand "vec_extract<mode>"
4966 [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "")
4967 (match_operand:VALL 1 "register_operand" "")
4968 (match_operand:SI 2 "immediate_operand" "")]
4972 (gen_aarch64_get_lane<mode> (operands[0], operands[1], operands[2]));
4978 (define_insn "aarch64_crypto_aes<aes_op>v16qi"
4979 [(set (match_operand:V16QI 0 "register_operand" "=w")
4980 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
4981 (match_operand:V16QI 2 "register_operand" "w")]
4983 "TARGET_SIMD && TARGET_CRYPTO"
4984 "aes<aes_op>\\t%0.16b, %2.16b"
4985 [(set_attr "type" "crypto_aese")]
4988 (define_insn "aarch64_crypto_aes<aesmc_op>v16qi"
4989 [(set (match_operand:V16QI 0 "register_operand" "=w")
4990 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "w")]
4992 "TARGET_SIMD && TARGET_CRYPTO"
4993 "aes<aesmc_op>\\t%0.16b, %1.16b"
4994 [(set_attr "type" "crypto_aesmc")]
4999 (define_insn "aarch64_crypto_sha1hsi"
5000 [(set (match_operand:SI 0 "register_operand" "=w")
5001 (unspec:SI [(match_operand:SI 1
5002 "register_operand" "w")]
5004 "TARGET_SIMD && TARGET_CRYPTO"
5006 [(set_attr "type" "crypto_sha1_fast")]
5009 (define_insn "aarch64_crypto_sha1su1v4si"
5010 [(set (match_operand:V4SI 0 "register_operand" "=w")
5011 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5012 (match_operand:V4SI 2 "register_operand" "w")]
5014 "TARGET_SIMD && TARGET_CRYPTO"
5015 "sha1su1\\t%0.4s, %2.4s"
5016 [(set_attr "type" "crypto_sha1_fast")]
5019 (define_insn "aarch64_crypto_sha1<sha1_op>v4si"
5020 [(set (match_operand:V4SI 0 "register_operand" "=w")
5021 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5022 (match_operand:SI 2 "register_operand" "w")
5023 (match_operand:V4SI 3 "register_operand" "w")]
5025 "TARGET_SIMD && TARGET_CRYPTO"
5026 "sha1<sha1_op>\\t%q0, %s2, %3.4s"
5027 [(set_attr "type" "crypto_sha1_slow")]
5030 (define_insn "aarch64_crypto_sha1su0v4si"
5031 [(set (match_operand:V4SI 0 "register_operand" "=w")
5032 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5033 (match_operand:V4SI 2 "register_operand" "w")
5034 (match_operand:V4SI 3 "register_operand" "w")]
5036 "TARGET_SIMD && TARGET_CRYPTO"
5037 "sha1su0\\t%0.4s, %2.4s, %3.4s"
5038 [(set_attr "type" "crypto_sha1_xor")]
5043 (define_insn "aarch64_crypto_sha256h<sha256_op>v4si"
5044 [(set (match_operand:V4SI 0 "register_operand" "=w")
5045 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5046 (match_operand:V4SI 2 "register_operand" "w")
5047 (match_operand:V4SI 3 "register_operand" "w")]
5049 "TARGET_SIMD && TARGET_CRYPTO"
5050 "sha256h<sha256_op>\\t%q0, %q2, %3.4s"
5051 [(set_attr "type" "crypto_sha256_slow")]
5054 (define_insn "aarch64_crypto_sha256su0v4si"
5055 [(set (match_operand:V4SI 0 "register_operand" "=w")
5056 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5057 (match_operand:V4SI 2 "register_operand" "w")]
5059 "TARGET_SIMD &&TARGET_CRYPTO"
5060 "sha256su0\\t%0.4s, %2.4s"
5061 [(set_attr "type" "crypto_sha256_fast")]
5064 (define_insn "aarch64_crypto_sha256su1v4si"
5065 [(set (match_operand:V4SI 0 "register_operand" "=w")
5066 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5067 (match_operand:V4SI 2 "register_operand" "w")
5068 (match_operand:V4SI 3 "register_operand" "w")]
5070 "TARGET_SIMD &&TARGET_CRYPTO"
5071 "sha256su1\\t%0.4s, %2.4s, %3.4s"
5072 [(set_attr "type" "crypto_sha256_slow")]
5077 (define_insn "aarch64_crypto_pmulldi"
5078 [(set (match_operand:TI 0 "register_operand" "=w")
5079 (unspec:TI [(match_operand:DI 1 "register_operand" "w")
5080 (match_operand:DI 2 "register_operand" "w")]
5082 "TARGET_SIMD && TARGET_CRYPTO"
5083 "pmull\\t%0.1q, %1.1d, %2.1d"
5084 [(set_attr "type" "neon_mul_d_long")]
5087 (define_insn "aarch64_crypto_pmullv2di"
5088 [(set (match_operand:TI 0 "register_operand" "=w")
5089 (unspec:TI [(match_operand:V2DI 1 "register_operand" "w")
5090 (match_operand:V2DI 2 "register_operand" "w")]
5092 "TARGET_SIMD && TARGET_CRYPTO"
5093 "pmull2\\t%0.1q, %1.2d, %2.2d"
5094 [(set_attr "type" "neon_mul_d_long")]