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_insn "reduc_<sur>plus_<mode>"
1764 [(set (match_operand:VDQV 0 "register_operand" "=w")
1765 (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
1768 "add<VDQV:vp>\\t%<Vetype>0, %1.<Vtype>"
1769 [(set_attr "type" "neon_reduc_add<q>")]
1772 (define_insn "reduc_<sur>plus_v2si"
1773 [(set (match_operand:V2SI 0 "register_operand" "=w")
1774 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
1777 "addp\\t%0.2s, %1.2s, %1.2s"
1778 [(set_attr "type" "neon_reduc_add")]
1781 (define_insn "reduc_splus_<mode>"
1782 [(set (match_operand:V2F 0 "register_operand" "=w")
1783 (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
1786 "faddp\\t%<Vetype>0, %1.<Vtype>"
1787 [(set_attr "type" "neon_fp_reduc_add_<Vetype><q>")]
1790 (define_insn "aarch64_addpv4sf"
1791 [(set (match_operand:V4SF 0 "register_operand" "=w")
1792 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
1795 "faddp\\t%0.4s, %1.4s, %1.4s"
1796 [(set_attr "type" "neon_fp_reduc_add_s_q")]
1799 (define_expand "reduc_splus_v4sf"
1800 [(set (match_operand:V4SF 0 "register_operand")
1801 (unspec:V4SF [(match_operand:V4SF 1 "register_operand")]
1805 emit_insn (gen_aarch64_addpv4sf (operands[0], operands[1]));
1806 emit_insn (gen_aarch64_addpv4sf (operands[0], operands[0]));
1810 (define_insn "clz<mode>2"
1811 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
1812 (clz:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")))]
1814 "clz\\t%0.<Vtype>, %1.<Vtype>"
1815 [(set_attr "type" "neon_cls<q>")]
1818 ;; 'across lanes' max and min ops.
1820 (define_insn "reduc_<maxmin_uns>_<mode>"
1821 [(set (match_operand:VDQV_S 0 "register_operand" "=w")
1822 (unspec:VDQV_S [(match_operand:VDQV_S 1 "register_operand" "w")]
1825 "<maxmin_uns_op>v\\t%<Vetype>0, %1.<Vtype>"
1826 [(set_attr "type" "neon_reduc_minmax<q>")]
1829 (define_insn "reduc_<maxmin_uns>_v2si"
1830 [(set (match_operand:V2SI 0 "register_operand" "=w")
1831 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
1834 "<maxmin_uns_op>p\\t%0.2s, %1.2s, %1.2s"
1835 [(set_attr "type" "neon_reduc_minmax")]
1838 (define_insn "reduc_<maxmin_uns>_<mode>"
1839 [(set (match_operand:V2F 0 "register_operand" "=w")
1840 (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
1843 "<maxmin_uns_op>p\\t%<Vetype>0, %1.<Vtype>"
1844 [(set_attr "type" "neon_fp_reduc_minmax_<Vetype><q>")]
1847 (define_insn "reduc_<maxmin_uns>_v4sf"
1848 [(set (match_operand:V4SF 0 "register_operand" "=w")
1849 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
1852 "<maxmin_uns_op>v\\t%s0, %1.4s"
1853 [(set_attr "type" "neon_fp_reduc_minmax_s_q")]
1856 ;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register
1858 ;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which
1861 ;; Thus our BSL is of the form:
1862 ;; op0 = bsl (mask, op2, op3)
1863 ;; We can use any of:
1866 ;; bsl mask, op1, op2
1867 ;; if (op0 = op1) (so 1-bits in mask choose bits from op2, else op0)
1868 ;; bit op0, op2, mask
1869 ;; if (op0 = op2) (so 0-bits in mask choose bits from op1, else op0)
1870 ;; bif op0, op1, mask
1872 (define_insn "aarch64_simd_bsl<mode>_internal"
1873 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w,w,w")
1877 (match_operand:<V_cmp_result> 1 "register_operand" " 0,w,w"))
1878 (match_operand:VSDQ_I_DI 3 "register_operand" " w,0,w"))
1880 (match_dup:<V_cmp_result> 1)
1881 (match_operand:VSDQ_I_DI 2 "register_operand" " w,w,0"))
1885 bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
1886 bit\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
1887 bif\\t%0.<Vbtype>, %3.<Vbtype>, %1.<Vbtype>"
1888 [(set_attr "type" "neon_bsl<q>")]
1891 (define_expand "aarch64_simd_bsl<mode>"
1892 [(match_operand:VALLDIF 0 "register_operand")
1893 (match_operand:<V_cmp_result> 1 "register_operand")
1894 (match_operand:VALLDIF 2 "register_operand")
1895 (match_operand:VALLDIF 3 "register_operand")]
1898 /* We can't alias operands together if they have different modes. */
1899 rtx tmp = operands[0];
1900 if (FLOAT_MODE_P (<MODE>mode))
1902 operands[2] = gen_lowpart (<V_cmp_result>mode, operands[2]);
1903 operands[3] = gen_lowpart (<V_cmp_result>mode, operands[3]);
1904 tmp = gen_reg_rtx (<V_cmp_result>mode);
1906 operands[1] = gen_lowpart (<V_cmp_result>mode, operands[1]);
1907 emit_insn (gen_aarch64_simd_bsl<v_cmp_result>_internal (tmp,
1911 if (tmp != operands[0])
1912 emit_move_insn (operands[0], gen_lowpart (<MODE>mode, tmp));
1917 (define_expand "aarch64_vcond_internal<mode><mode>"
1918 [(set (match_operand:VDQ 0 "register_operand")
1920 (match_operator 3 "comparison_operator"
1921 [(match_operand:VDQ 4 "register_operand")
1922 (match_operand:VDQ 5 "nonmemory_operand")])
1923 (match_operand:VDQ 1 "nonmemory_operand")
1924 (match_operand:VDQ 2 "nonmemory_operand")))]
1927 rtx op1 = operands[1];
1928 rtx op2 = operands[2];
1929 rtx mask = gen_reg_rtx (<MODE>mode);
1930 enum rtx_code code = GET_CODE (operands[3]);
1932 /* Switching OP1 and OP2 is necessary for NE (to output a cmeq insn),
1933 and desirable for other comparisons if it results in FOO ? -1 : 0
1934 (this allows direct use of the comparison result without a bsl). */
1937 && op1 == CONST0_RTX (<V_cmp_result>mode)
1938 && op2 == CONSTM1_RTX (<V_cmp_result>mode)))
1944 case LE: code = GT; break;
1945 case LT: code = GE; break;
1946 case GE: code = LT; break;
1947 case GT: code = LE; break;
1949 case NE: code = EQ; break;
1950 case LTU: code = GEU; break;
1951 case LEU: code = GTU; break;
1952 case GTU: code = LEU; break;
1953 case GEU: code = LTU; break;
1954 default: gcc_unreachable ();
1958 /* Make sure we can handle the last operand. */
1962 /* Normalized to EQ above. */
1970 /* These instructions have a form taking an immediate zero. */
1971 if (operands[5] == CONST0_RTX (<MODE>mode))
1973 /* Fall through, as may need to load into register. */
1975 if (!REG_P (operands[5]))
1976 operands[5] = force_reg (<MODE>mode, operands[5]);
1983 emit_insn (gen_aarch64_cmlt<mode> (mask, operands[4], operands[5]));
1987 emit_insn (gen_aarch64_cmge<mode> (mask, operands[4], operands[5]));
1991 emit_insn (gen_aarch64_cmle<mode> (mask, operands[4], operands[5]));
1995 emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
1999 emit_insn (gen_aarch64_cmgtu<mode> (mask, operands[5], operands[4]));
2003 emit_insn (gen_aarch64_cmgeu<mode> (mask, operands[4], operands[5]));
2007 emit_insn (gen_aarch64_cmgeu<mode> (mask, operands[5], operands[4]));
2011 emit_insn (gen_aarch64_cmgtu<mode> (mask, operands[4], operands[5]));
2014 /* NE has been normalized to EQ above. */
2016 emit_insn (gen_aarch64_cmeq<mode> (mask, operands[4], operands[5]));
2023 /* If we have (a = (b CMP c) ? -1 : 0);
2024 Then we can simply move the generated mask. */
2026 if (op1 == CONSTM1_RTX (<V_cmp_result>mode)
2027 && op2 == CONST0_RTX (<V_cmp_result>mode))
2028 emit_move_insn (operands[0], mask);
2032 op1 = force_reg (<MODE>mode, op1);
2034 op2 = force_reg (<MODE>mode, op2);
2035 emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask,
2042 (define_expand "aarch64_vcond_internal<VDQF_COND:mode><VDQF:mode>"
2043 [(set (match_operand:VDQF_COND 0 "register_operand")
2045 (match_operator 3 "comparison_operator"
2046 [(match_operand:VDQF 4 "register_operand")
2047 (match_operand:VDQF 5 "nonmemory_operand")])
2048 (match_operand:VDQF_COND 1 "nonmemory_operand")
2049 (match_operand:VDQF_COND 2 "nonmemory_operand")))]
2053 int use_zero_form = 0;
2054 int swap_bsl_operands = 0;
2055 rtx op1 = operands[1];
2056 rtx op2 = operands[2];
2057 rtx mask = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
2058 rtx tmp = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
2060 rtx (*base_comparison) (rtx, rtx, rtx);
2061 rtx (*complimentary_comparison) (rtx, rtx, rtx);
2063 switch (GET_CODE (operands[3]))
2070 if (operands[5] == CONST0_RTX (<MODE>mode))
2077 if (!REG_P (operands[5]))
2078 operands[5] = force_reg (<VDQF:MODE>mode, operands[5]);
2081 switch (GET_CODE (operands[3]))
2091 base_comparison = gen_aarch64_cmge<VDQF:mode>;
2092 complimentary_comparison = gen_aarch64_cmgt<VDQF:mode>;
2100 base_comparison = gen_aarch64_cmgt<VDQF:mode>;
2101 complimentary_comparison = gen_aarch64_cmge<VDQF:mode>;
2106 base_comparison = gen_aarch64_cmeq<VDQF:mode>;
2107 complimentary_comparison = gen_aarch64_cmeq<VDQF:mode>;
2113 switch (GET_CODE (operands[3]))
2120 /* The easy case. Here we emit one of FCMGE, FCMGT or FCMEQ.
2121 As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
2127 Note that there also exist direct comparison against 0 forms,
2128 so catch those as a special case. */
2132 switch (GET_CODE (operands[3]))
2135 base_comparison = gen_aarch64_cmlt<VDQF:mode>;
2138 base_comparison = gen_aarch64_cmle<VDQF:mode>;
2141 /* Do nothing, other zero form cases already have the correct
2148 emit_insn (base_comparison (mask, operands[4], operands[5]));
2150 emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
2157 /* FCM returns false for lanes which are unordered, so if we use
2158 the inverse of the comparison we actually want to emit, then
2159 swap the operands to BSL, we will end up with the correct result.
2160 Note that a NE NaN and NaN NE b are true for all a, b.
2162 Our transformations are:
2167 a NE b -> !(a EQ b) */
2170 emit_insn (base_comparison (mask, operands[4], operands[5]));
2172 emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
2174 swap_bsl_operands = 1;
2177 /* We check (a > b || b > a). combining these comparisons give us
2178 true iff !(a != b && a ORDERED b), swapping the operands to BSL
2179 will then give us (a == b || a UNORDERED b) as intended. */
2181 emit_insn (gen_aarch64_cmgt<VDQF:mode> (mask, operands[4], operands[5]));
2182 emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[5], operands[4]));
2183 emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
2184 swap_bsl_operands = 1;
2187 /* Operands are ORDERED iff (a > b || b >= a).
2188 Swapping the operands to BSL will give the UNORDERED case. */
2189 swap_bsl_operands = 1;
2192 emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[4], operands[5]));
2193 emit_insn (gen_aarch64_cmge<VDQF:mode> (mask, operands[5], operands[4]));
2194 emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
2200 if (swap_bsl_operands)
2206 /* If we have (a = (b CMP c) ? -1 : 0);
2207 Then we can simply move the generated mask. */
2209 if (op1 == CONSTM1_RTX (<VDQF_COND:V_cmp_result>mode)
2210 && op2 == CONST0_RTX (<VDQF_COND:V_cmp_result>mode))
2211 emit_move_insn (operands[0], mask);
2215 op1 = force_reg (<VDQF_COND:MODE>mode, op1);
2217 op2 = force_reg (<VDQF_COND:MODE>mode, op2);
2218 emit_insn (gen_aarch64_simd_bsl<VDQF_COND:mode> (operands[0], mask,
2225 (define_expand "vcond<mode><mode>"
2226 [(set (match_operand:VALL 0 "register_operand")
2228 (match_operator 3 "comparison_operator"
2229 [(match_operand:VALL 4 "register_operand")
2230 (match_operand:VALL 5 "nonmemory_operand")])
2231 (match_operand:VALL 1 "nonmemory_operand")
2232 (match_operand:VALL 2 "nonmemory_operand")))]
2235 emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
2236 operands[2], operands[3],
2237 operands[4], operands[5]));
2241 (define_expand "vcond<v_cmp_result><mode>"
2242 [(set (match_operand:<V_cmp_result> 0 "register_operand")
2243 (if_then_else:<V_cmp_result>
2244 (match_operator 3 "comparison_operator"
2245 [(match_operand:VDQF 4 "register_operand")
2246 (match_operand:VDQF 5 "nonmemory_operand")])
2247 (match_operand:<V_cmp_result> 1 "nonmemory_operand")
2248 (match_operand:<V_cmp_result> 2 "nonmemory_operand")))]
2251 emit_insn (gen_aarch64_vcond_internal<v_cmp_result><mode> (
2252 operands[0], operands[1],
2253 operands[2], operands[3],
2254 operands[4], operands[5]));
2258 (define_expand "vcondu<mode><mode>"
2259 [(set (match_operand:VDQ 0 "register_operand")
2261 (match_operator 3 "comparison_operator"
2262 [(match_operand:VDQ 4 "register_operand")
2263 (match_operand:VDQ 5 "nonmemory_operand")])
2264 (match_operand:VDQ 1 "nonmemory_operand")
2265 (match_operand:VDQ 2 "nonmemory_operand")))]
2268 emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
2269 operands[2], operands[3],
2270 operands[4], operands[5]));
2274 ;; Patterns for AArch64 SIMD Intrinsics.
2276 (define_expand "aarch64_create<mode>"
2277 [(match_operand:VD_RE 0 "register_operand" "")
2278 (match_operand:DI 1 "general_operand" "")]
2281 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2282 emit_move_insn (operands[0], src);
2286 ;; Lane extraction with sign extension to general purpose register.
2287 (define_insn "*aarch64_get_lane_extend<GPI:mode><VDQQH:mode>"
2288 [(set (match_operand:GPI 0 "register_operand" "=r")
2291 (match_operand:VDQQH 1 "register_operand" "w")
2292 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2295 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2296 return "smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]";
2298 [(set_attr "type" "neon_to_gp<q>")]
2301 (define_insn "*aarch64_get_lane_zero_extendsi<mode>"
2302 [(set (match_operand:SI 0 "register_operand" "=r")
2305 (match_operand:VDQQH 1 "register_operand" "w")
2306 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2309 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2310 return "umov\\t%w0, %1.<Vetype>[%2]";
2312 [(set_attr "type" "neon_to_gp<q>")]
2315 (define_expand "aarch64_be_checked_get_lane<mode>"
2316 [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand")
2317 (match_operand:VALL 1 "register_operand")
2318 (match_operand:SI 2 "immediate_operand")]
2321 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2322 emit_insn (gen_aarch64_get_lane<mode> (operands[0],
2329 ;; Lane extraction of a value, neither sign nor zero extension
2330 ;; is guaranteed so upper bits should be considered undefined.
2331 (define_insn "aarch64_get_lane<mode>"
2332 [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
2334 (match_operand:VALL 1 "register_operand" "w, w, w")
2335 (parallel [(match_operand:SI 2 "immediate_operand" "i, i, i")])))]
2338 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2339 switch (which_alternative)
2342 return "umov\\t%<vwcore>0, %1.<Vetype>[%2]";
2344 return "dup\\t%<Vetype>0, %1.<Vetype>[%2]";
2346 return "st1\\t{%1.<Vetype>}[%2], %0";
2351 [(set_attr "type" "neon_to_gp<q>, neon_dup<q>, neon_store1_one_lane<q>")]
2354 (define_expand "aarch64_get_lanedi"
2355 [(match_operand:DI 0 "register_operand")
2356 (match_operand:DI 1 "register_operand")
2357 (match_operand:SI 2 "immediate_operand")]
2360 aarch64_simd_lane_bounds (operands[2], 0, 1);
2361 emit_move_insn (operands[0], operands[1]);
2365 (define_expand "aarch64_reinterpretv8qi<mode>"
2366 [(match_operand:V8QI 0 "register_operand" "")
2367 (match_operand:VDC 1 "register_operand" "")]
2370 aarch64_simd_reinterpret (operands[0], operands[1]);
2374 (define_expand "aarch64_reinterpretv4hi<mode>"
2375 [(match_operand:V4HI 0 "register_operand" "")
2376 (match_operand:VDC 1 "register_operand" "")]
2379 aarch64_simd_reinterpret (operands[0], operands[1]);
2383 (define_expand "aarch64_reinterpretv2si<mode>"
2384 [(match_operand:V2SI 0 "register_operand" "")
2385 (match_operand:VDC 1 "register_operand" "")]
2388 aarch64_simd_reinterpret (operands[0], operands[1]);
2392 (define_expand "aarch64_reinterpretv2sf<mode>"
2393 [(match_operand:V2SF 0 "register_operand" "")
2394 (match_operand:VDC 1 "register_operand" "")]
2397 aarch64_simd_reinterpret (operands[0], operands[1]);
2401 (define_expand "aarch64_reinterpretdi<mode>"
2402 [(match_operand:DI 0 "register_operand" "")
2403 (match_operand:VD_RE 1 "register_operand" "")]
2406 aarch64_simd_reinterpret (operands[0], operands[1]);
2410 (define_expand "aarch64_reinterpretdf<mode>"
2411 [(match_operand:DF 0 "register_operand" "")
2412 (match_operand:VD_RE 1 "register_operand" "")]
2415 aarch64_simd_reinterpret (operands[0], operands[1]);
2419 (define_expand "aarch64_reinterpretv16qi<mode>"
2420 [(match_operand:V16QI 0 "register_operand" "")
2421 (match_operand:VQ 1 "register_operand" "")]
2424 aarch64_simd_reinterpret (operands[0], operands[1]);
2428 (define_expand "aarch64_reinterpretv8hi<mode>"
2429 [(match_operand:V8HI 0 "register_operand" "")
2430 (match_operand:VQ 1 "register_operand" "")]
2433 aarch64_simd_reinterpret (operands[0], operands[1]);
2437 (define_expand "aarch64_reinterpretv4si<mode>"
2438 [(match_operand:V4SI 0 "register_operand" "")
2439 (match_operand:VQ 1 "register_operand" "")]
2442 aarch64_simd_reinterpret (operands[0], operands[1]);
2446 (define_expand "aarch64_reinterpretv4sf<mode>"
2447 [(match_operand:V4SF 0 "register_operand" "")
2448 (match_operand:VQ 1 "register_operand" "")]
2451 aarch64_simd_reinterpret (operands[0], operands[1]);
2455 (define_expand "aarch64_reinterpretv2di<mode>"
2456 [(match_operand:V2DI 0 "register_operand" "")
2457 (match_operand:VQ 1 "register_operand" "")]
2460 aarch64_simd_reinterpret (operands[0], operands[1]);
2464 (define_expand "aarch64_reinterpretv2df<mode>"
2465 [(match_operand:V2DF 0 "register_operand" "")
2466 (match_operand:VQ 1 "register_operand" "")]
2469 aarch64_simd_reinterpret (operands[0], operands[1]);
2473 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2476 (define_insn "*aarch64_combinez<mode>"
2477 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2479 (match_operand:VDIC 1 "register_operand" "w")
2480 (match_operand:VDIC 2 "aarch64_simd_imm_zero" "Dz")))]
2481 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
2482 "mov\\t%0.8b, %1.8b"
2483 [(set_attr "type" "neon_move<q>")]
2486 (define_insn "*aarch64_combinez_be<mode>"
2487 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2489 (match_operand:VDIC 2 "aarch64_simd_imm_zero" "Dz")
2490 (match_operand:VDIC 1 "register_operand" "w")))]
2491 "TARGET_SIMD && BYTES_BIG_ENDIAN"
2492 "mov\\t%0.8b, %1.8b"
2493 [(set_attr "type" "neon_move<q>")]
2496 (define_expand "aarch64_combine<mode>"
2497 [(match_operand:<VDBL> 0 "register_operand")
2498 (match_operand:VDC 1 "register_operand")
2499 (match_operand:VDC 2 "register_operand")]
2503 if (BYTES_BIG_ENDIAN)
2513 emit_insn (gen_aarch64_combine_internal<mode> (operands[0], op1, op2));
2518 (define_insn_and_split "aarch64_combine_internal<mode>"
2519 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2520 (vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
2521 (match_operand:VDC 2 "register_operand" "w")))]
2524 "&& reload_completed"
2527 if (BYTES_BIG_ENDIAN)
2528 aarch64_split_simd_combine (operands[0], operands[2], operands[1]);
2530 aarch64_split_simd_combine (operands[0], operands[1], operands[2]);
2533 [(set_attr "type" "multiple")]
2536 (define_expand "aarch64_simd_combine<mode>"
2537 [(match_operand:<VDBL> 0 "register_operand")
2538 (match_operand:VDC 1 "register_operand")
2539 (match_operand:VDC 2 "register_operand")]
2542 emit_insn (gen_move_lo_quad_<Vdbl> (operands[0], operands[1]));
2543 emit_insn (gen_move_hi_quad_<Vdbl> (operands[0], operands[2]));
2546 [(set_attr "type" "multiple")]
2549 ;; <su><addsub>l<q>.
2551 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>_hi_internal"
2552 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2553 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2554 (match_operand:VQW 1 "register_operand" "w")
2555 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
2556 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2557 (match_operand:VQW 2 "register_operand" "w")
2560 "<ANY_EXTEND:su><ADDSUB:optab>l2\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
2561 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2564 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>_lo_internal"
2565 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2566 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2567 (match_operand:VQW 1 "register_operand" "w")
2568 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
2569 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2570 (match_operand:VQW 2 "register_operand" "w")
2573 "<ANY_EXTEND:su><ADDSUB:optab>l\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
2574 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2578 (define_expand "aarch64_saddl2<mode>"
2579 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2580 (match_operand:VQW 1 "register_operand" "w")
2581 (match_operand:VQW 2 "register_operand" "w")]
2584 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2585 emit_insn (gen_aarch64_saddl<mode>_hi_internal (operands[0], operands[1],
2590 (define_expand "aarch64_uaddl2<mode>"
2591 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2592 (match_operand:VQW 1 "register_operand" "w")
2593 (match_operand:VQW 2 "register_operand" "w")]
2596 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2597 emit_insn (gen_aarch64_uaddl<mode>_hi_internal (operands[0], operands[1],
2602 (define_expand "aarch64_ssubl2<mode>"
2603 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2604 (match_operand:VQW 1 "register_operand" "w")
2605 (match_operand:VQW 2 "register_operand" "w")]
2608 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2609 emit_insn (gen_aarch64_ssubl<mode>_hi_internal (operands[0], operands[1],
2614 (define_expand "aarch64_usubl2<mode>"
2615 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2616 (match_operand:VQW 1 "register_operand" "w")
2617 (match_operand:VQW 2 "register_operand" "w")]
2620 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2621 emit_insn (gen_aarch64_usubl<mode>_hi_internal (operands[0], operands[1],
2626 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>"
2627 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2628 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE>
2629 (match_operand:VDW 1 "register_operand" "w"))
2631 (match_operand:VDW 2 "register_operand" "w"))))]
2633 "<ANY_EXTEND:su><ADDSUB:optab>l %0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
2634 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2637 ;; <su><addsub>w<q>.
2639 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w<mode>"
2640 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2641 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2643 (match_operand:VDW 2 "register_operand" "w"))))]
2645 "<ANY_EXTEND:su><ADDSUB:optab>w\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
2646 [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
2649 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w2<mode>_internal"
2650 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2651 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2654 (match_operand:VQW 2 "register_operand" "w")
2655 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))))]
2657 "<ANY_EXTEND:su><ADDSUB:optab>w2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
2658 [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
2661 (define_expand "aarch64_saddw2<mode>"
2662 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2663 (match_operand:<VWIDE> 1 "register_operand" "w")
2664 (match_operand:VQW 2 "register_operand" "w")]
2667 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2668 emit_insn (gen_aarch64_saddw2<mode>_internal (operands[0], operands[1],
2673 (define_expand "aarch64_uaddw2<mode>"
2674 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2675 (match_operand:<VWIDE> 1 "register_operand" "w")
2676 (match_operand:VQW 2 "register_operand" "w")]
2679 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2680 emit_insn (gen_aarch64_uaddw2<mode>_internal (operands[0], operands[1],
2686 (define_expand "aarch64_ssubw2<mode>"
2687 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2688 (match_operand:<VWIDE> 1 "register_operand" "w")
2689 (match_operand:VQW 2 "register_operand" "w")]
2692 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2693 emit_insn (gen_aarch64_ssubw2<mode>_internal (operands[0], operands[1],
2698 (define_expand "aarch64_usubw2<mode>"
2699 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2700 (match_operand:<VWIDE> 1 "register_operand" "w")
2701 (match_operand:VQW 2 "register_operand" "w")]
2704 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2705 emit_insn (gen_aarch64_usubw2<mode>_internal (operands[0], operands[1],
2710 ;; <su><r>h<addsub>.
2712 (define_insn "aarch64_<sur>h<addsub><mode>"
2713 [(set (match_operand:VQ_S 0 "register_operand" "=w")
2714 (unspec:VQ_S [(match_operand:VQ_S 1 "register_operand" "w")
2715 (match_operand:VQ_S 2 "register_operand" "w")]
2718 "<sur>h<addsub>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2719 [(set_attr "type" "neon_<addsub>_halve<q>")]
2722 ;; <r><addsub>hn<q>.
2724 (define_insn "aarch64_<sur><addsub>hn<mode>"
2725 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2726 (unspec:<VNARROWQ> [(match_operand:VQN 1 "register_operand" "w")
2727 (match_operand:VQN 2 "register_operand" "w")]
2730 "<sur><addsub>hn\\t%0.<Vntype>, %1.<Vtype>, %2.<Vtype>"
2731 [(set_attr "type" "neon_<addsub>_halve_narrow_q")]
2734 (define_insn "aarch64_<sur><addsub>hn2<mode>"
2735 [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
2736 (unspec:<VNARROWQ2> [(match_operand:<VNARROWQ> 1 "register_operand" "0")
2737 (match_operand:VQN 2 "register_operand" "w")
2738 (match_operand:VQN 3 "register_operand" "w")]
2741 "<sur><addsub>hn2\\t%0.<V2ntype>, %2.<Vtype>, %3.<Vtype>"
2742 [(set_attr "type" "neon_<addsub>_halve_narrow_q")]
2747 (define_insn "aarch64_pmul<mode>"
2748 [(set (match_operand:VB 0 "register_operand" "=w")
2749 (unspec:VB [(match_operand:VB 1 "register_operand" "w")
2750 (match_operand:VB 2 "register_operand" "w")]
2753 "pmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2754 [(set_attr "type" "neon_mul_<Vetype><q>")]
2759 (define_insn "aarch64_<su_optab><optab><mode>"
2760 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
2761 (BINQOPS:VSDQ_I (match_operand:VSDQ_I 1 "register_operand" "w")
2762 (match_operand:VSDQ_I 2 "register_operand" "w")))]
2764 "<su_optab><optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
2765 [(set_attr "type" "neon_<optab><q>")]
2768 ;; suqadd and usqadd
2770 (define_insn "aarch64_<sur>qadd<mode>"
2771 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
2772 (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "0")
2773 (match_operand:VSDQ_I 2 "register_operand" "w")]
2776 "<sur>qadd\\t%<v>0<Vmtype>, %<v>2<Vmtype>"
2777 [(set_attr "type" "neon_qadd<q>")]
2782 (define_insn "aarch64_sqmovun<mode>"
2783 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2784 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
2787 "sqxtun\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
2788 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
2791 ;; sqmovn and uqmovn
2793 (define_insn "aarch64_<sur>qmovn<mode>"
2794 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2795 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
2798 "<sur>qxtn\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
2799 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
2804 (define_insn "aarch64_s<optab><mode>"
2805 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
2807 (match_operand:VSDQ_I 1 "register_operand" "w")))]
2809 "s<optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>"
2810 [(set_attr "type" "neon_<optab><q>")]
2815 (define_insn "aarch64_sq<r>dmulh<mode>"
2816 [(set (match_operand:VSDQ_HSI 0 "register_operand" "=w")
2818 [(match_operand:VSDQ_HSI 1 "register_operand" "w")
2819 (match_operand:VSDQ_HSI 2 "register_operand" "w")]
2822 "sq<r>dmulh\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
2823 [(set_attr "type" "neon_sat_mul_<Vetype><q>")]
2828 (define_expand "aarch64_sqdmulh_lane<mode>"
2829 [(match_operand:VDQHS 0 "register_operand" "")
2830 (match_operand:VDQHS 1 "register_operand" "")
2831 (match_operand:<VCOND> 2 "register_operand" "")
2832 (match_operand:SI 3 "immediate_operand" "")]
2835 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2836 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2837 emit_insn (gen_aarch64_sqdmulh_lane<mode>_internal (operands[0],
2845 (define_expand "aarch64_sqrdmulh_lane<mode>"
2846 [(match_operand:VDQHS 0 "register_operand" "")
2847 (match_operand:VDQHS 1 "register_operand" "")
2848 (match_operand:<VCOND> 2 "register_operand" "")
2849 (match_operand:SI 3 "immediate_operand" "")]
2852 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2853 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2854 emit_insn (gen_aarch64_sqrdmulh_lane<mode>_internal (operands[0],
2862 (define_insn "aarch64_sq<r>dmulh_lane<mode>_internal"
2863 [(set (match_operand:VDQHS 0 "register_operand" "=w")
2865 [(match_operand:VDQHS 1 "register_operand" "w")
2867 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
2868 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2872 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2873 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2874 return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
2875 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
2878 (define_expand "aarch64_sqdmulh_laneq<mode>"
2879 [(match_operand:VDQHS 0 "register_operand" "")
2880 (match_operand:VDQHS 1 "register_operand" "")
2881 (match_operand:<VCONQ> 2 "register_operand" "")
2882 (match_operand:SI 3 "immediate_operand" "")]
2885 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
2886 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
2887 emit_insn (gen_aarch64_sqdmulh_laneq<mode>_internal (operands[0],
2895 (define_expand "aarch64_sqrdmulh_laneq<mode>"
2896 [(match_operand:VDQHS 0 "register_operand" "")
2897 (match_operand:VDQHS 1 "register_operand" "")
2898 (match_operand:<VCONQ> 2 "register_operand" "")
2899 (match_operand:SI 3 "immediate_operand" "")]
2902 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
2903 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
2904 emit_insn (gen_aarch64_sqrdmulh_laneq<mode>_internal (operands[0],
2912 (define_insn "aarch64_sq<r>dmulh_laneq<mode>_internal"
2913 [(set (match_operand:VDQHS 0 "register_operand" "=w")
2915 [(match_operand:VDQHS 1 "register_operand" "w")
2917 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
2918 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2922 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
2923 return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
2924 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
2927 (define_expand "aarch64_sqdmulh_lane<mode>"
2928 [(match_operand:SD_HSI 0 "register_operand" "")
2929 (match_operand:SD_HSI 1 "register_operand" "")
2930 (match_operand:<VCOND> 2 "register_operand" "")
2931 (match_operand:SI 3 "immediate_operand" "")]
2934 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2935 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2936 emit_insn (gen_aarch64_sqdmulh_lane<mode>_internal (operands[0],
2944 (define_expand "aarch64_sqrdmulh_lane<mode>"
2945 [(match_operand:SD_HSI 0 "register_operand" "")
2946 (match_operand:SD_HSI 1 "register_operand" "")
2947 (match_operand:<VCOND> 2 "register_operand" "")
2948 (match_operand:SI 3 "immediate_operand" "")]
2951 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2952 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2953 emit_insn (gen_aarch64_sqrdmulh_lane<mode>_internal (operands[0],
2961 (define_insn "aarch64_sq<r>dmulh_lane<mode>_internal"
2962 [(set (match_operand:SD_HSI 0 "register_operand" "=w")
2964 [(match_operand:SD_HSI 1 "register_operand" "w")
2966 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
2967 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2971 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
2972 return \"sq<r>dmulh\\t%<v>0, %<v>1, %2.<v>[%3]\";"
2973 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
2978 (define_insn "aarch64_sqdml<SBINQOPS:as>l<mode>"
2979 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2981 (match_operand:<VWIDE> 1 "register_operand" "0")
2984 (sign_extend:<VWIDE>
2985 (match_operand:VSD_HSI 2 "register_operand" "w"))
2986 (sign_extend:<VWIDE>
2987 (match_operand:VSD_HSI 3 "register_operand" "w")))
2990 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
2991 [(set_attr "type" "neon_sat_mla_<Vetype>_long")]
2996 (define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
2997 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2999 (match_operand:<VWIDE> 1 "register_operand" "0")
3002 (sign_extend:<VWIDE>
3003 (match_operand:VD_HSI 2 "register_operand" "w"))
3004 (sign_extend:<VWIDE>
3005 (vec_duplicate:VD_HSI
3007 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3008 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3013 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3015 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3017 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3020 (define_insn "aarch64_sqdml<SBINQOPS:as>l_laneq<mode>_internal"
3021 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3023 (match_operand:<VWIDE> 1 "register_operand" "0")
3026 (sign_extend:<VWIDE>
3027 (match_operand:VD_HSI 2 "register_operand" "w"))
3028 (sign_extend:<VWIDE>
3029 (vec_duplicate:VD_HSI
3031 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3032 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3037 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3039 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3041 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3044 (define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
3045 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3047 (match_operand:<VWIDE> 1 "register_operand" "0")
3050 (sign_extend:<VWIDE>
3051 (match_operand:SD_HSI 2 "register_operand" "w"))
3052 (sign_extend:<VWIDE>
3054 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3055 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3060 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3062 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3064 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3067 (define_insn "aarch64_sqdml<SBINQOPS:as>l_laneq<mode>_internal"
3068 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3070 (match_operand:<VWIDE> 1 "register_operand" "0")
3073 (sign_extend:<VWIDE>
3074 (match_operand:SD_HSI 2 "register_operand" "w"))
3075 (sign_extend:<VWIDE>
3077 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3078 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3083 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3085 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3087 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3090 (define_expand "aarch64_sqdmlal_lane<mode>"
3091 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3092 (match_operand:<VWIDE> 1 "register_operand" "0")
3093 (match_operand:VSD_HSI 2 "register_operand" "w")
3094 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3095 (match_operand:SI 4 "immediate_operand" "i")]
3098 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCOND>mode));
3099 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3100 emit_insn (gen_aarch64_sqdmlal_lane<mode>_internal (operands[0], operands[1],
3101 operands[2], operands[3],
3106 (define_expand "aarch64_sqdmlal_laneq<mode>"
3107 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3108 (match_operand:<VWIDE> 1 "register_operand" "0")
3109 (match_operand:VSD_HSI 2 "register_operand" "w")
3110 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3111 (match_operand:SI 4 "immediate_operand" "i")]
3114 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCONQ>mode));
3115 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3116 emit_insn (gen_aarch64_sqdmlal_laneq<mode>_internal (operands[0], operands[1],
3117 operands[2], operands[3],
3122 (define_expand "aarch64_sqdmlsl_lane<mode>"
3123 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3124 (match_operand:<VWIDE> 1 "register_operand" "0")
3125 (match_operand:VSD_HSI 2 "register_operand" "w")
3126 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3127 (match_operand:SI 4 "immediate_operand" "i")]
3130 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCOND>mode));
3131 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3132 emit_insn (gen_aarch64_sqdmlsl_lane<mode>_internal (operands[0], operands[1],
3133 operands[2], operands[3],
3138 (define_expand "aarch64_sqdmlsl_laneq<mode>"
3139 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3140 (match_operand:<VWIDE> 1 "register_operand" "0")
3141 (match_operand:VSD_HSI 2 "register_operand" "w")
3142 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3143 (match_operand:SI 4 "immediate_operand" "i")]
3146 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCONQ>mode));
3147 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3148 emit_insn (gen_aarch64_sqdmlsl_laneq<mode>_internal (operands[0], operands[1],
3149 operands[2], operands[3],
3156 (define_insn "aarch64_sqdml<SBINQOPS:as>l_n<mode>"
3157 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3159 (match_operand:<VWIDE> 1 "register_operand" "0")
3162 (sign_extend:<VWIDE>
3163 (match_operand:VD_HSI 2 "register_operand" "w"))
3164 (sign_extend:<VWIDE>
3165 (vec_duplicate:VD_HSI
3166 (match_operand:<VEL> 3 "register_operand" "<vwx>"))))
3169 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
3170 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3175 (define_insn "aarch64_sqdml<SBINQOPS:as>l2<mode>_internal"
3176 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3178 (match_operand:<VWIDE> 1 "register_operand" "0")
3181 (sign_extend:<VWIDE>
3183 (match_operand:VQ_HSI 2 "register_operand" "w")
3184 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3185 (sign_extend:<VWIDE>
3187 (match_operand:VQ_HSI 3 "register_operand" "w")
3191 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
3192 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3195 (define_expand "aarch64_sqdmlal2<mode>"
3196 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3197 (match_operand:<VWIDE> 1 "register_operand" "w")
3198 (match_operand:VQ_HSI 2 "register_operand" "w")
3199 (match_operand:VQ_HSI 3 "register_operand" "w")]
3202 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3203 emit_insn (gen_aarch64_sqdmlal2<mode>_internal (operands[0], operands[1],
3204 operands[2], operands[3], p));
3208 (define_expand "aarch64_sqdmlsl2<mode>"
3209 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3210 (match_operand:<VWIDE> 1 "register_operand" "w")
3211 (match_operand:VQ_HSI 2 "register_operand" "w")
3212 (match_operand:VQ_HSI 3 "register_operand" "w")]
3215 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3216 emit_insn (gen_aarch64_sqdmlsl2<mode>_internal (operands[0], operands[1],
3217 operands[2], operands[3], p));
3223 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_lane<mode>_internal"
3224 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3226 (match_operand:<VWIDE> 1 "register_operand" "0")
3229 (sign_extend:<VWIDE>
3231 (match_operand:VQ_HSI 2 "register_operand" "w")
3232 (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" "")))
3233 (sign_extend:<VWIDE>
3234 (vec_duplicate:<VHALF>
3236 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3237 (parallel [(match_operand:SI 4 "immediate_operand" "i")])
3242 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3244 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3246 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3249 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_laneq<mode>_internal"
3250 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3252 (match_operand:<VWIDE> 1 "register_operand" "0")
3255 (sign_extend:<VWIDE>
3257 (match_operand:VQ_HSI 2 "register_operand" "w")
3258 (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" "")))
3259 (sign_extend:<VWIDE>
3260 (vec_duplicate:<VHALF>
3262 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3263 (parallel [(match_operand:SI 4 "immediate_operand" "i")])
3268 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3270 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3272 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3275 (define_expand "aarch64_sqdmlal2_lane<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:<VCOND> 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 (<VCOND>mode));
3285 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3286 emit_insn (gen_aarch64_sqdmlal2_lane<mode>_internal (operands[0], operands[1],
3287 operands[2], operands[3],
3292 (define_expand "aarch64_sqdmlal2_laneq<mode>"
3293 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3294 (match_operand:<VWIDE> 1 "register_operand" "w")
3295 (match_operand:VQ_HSI 2 "register_operand" "w")
3296 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3297 (match_operand:SI 4 "immediate_operand" "i")]
3300 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3301 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCONQ>mode));
3302 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3303 emit_insn (gen_aarch64_sqdmlal2_laneq<mode>_internal (operands[0], operands[1],
3304 operands[2], operands[3],
3309 (define_expand "aarch64_sqdmlsl2_lane<mode>"
3310 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3311 (match_operand:<VWIDE> 1 "register_operand" "w")
3312 (match_operand:VQ_HSI 2 "register_operand" "w")
3313 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3314 (match_operand:SI 4 "immediate_operand" "i")]
3317 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3318 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCOND>mode));
3319 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3320 emit_insn (gen_aarch64_sqdmlsl2_lane<mode>_internal (operands[0], operands[1],
3321 operands[2], operands[3],
3326 (define_expand "aarch64_sqdmlsl2_laneq<mode>"
3327 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3328 (match_operand:<VWIDE> 1 "register_operand" "w")
3329 (match_operand:VQ_HSI 2 "register_operand" "w")
3330 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3331 (match_operand:SI 4 "immediate_operand" "i")]
3334 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3335 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCONQ>mode));
3336 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3337 emit_insn (gen_aarch64_sqdmlsl2_laneq<mode>_internal (operands[0], operands[1],
3338 operands[2], operands[3],
3343 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal"
3344 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3346 (match_operand:<VWIDE> 1 "register_operand" "0")
3349 (sign_extend:<VWIDE>
3351 (match_operand:VQ_HSI 2 "register_operand" "w")
3352 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3353 (sign_extend:<VWIDE>
3354 (vec_duplicate:<VHALF>
3355 (match_operand:<VEL> 3 "register_operand" "<vwx>"))))
3358 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
3359 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3362 (define_expand "aarch64_sqdmlal2_n<mode>"
3363 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3364 (match_operand:<VWIDE> 1 "register_operand" "w")
3365 (match_operand:VQ_HSI 2 "register_operand" "w")
3366 (match_operand:<VEL> 3 "register_operand" "w")]
3369 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3370 emit_insn (gen_aarch64_sqdmlal2_n<mode>_internal (operands[0], operands[1],
3371 operands[2], operands[3],
3376 (define_expand "aarch64_sqdmlsl2_n<mode>"
3377 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3378 (match_operand:<VWIDE> 1 "register_operand" "w")
3379 (match_operand:VQ_HSI 2 "register_operand" "w")
3380 (match_operand:<VEL> 3 "register_operand" "w")]
3383 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3384 emit_insn (gen_aarch64_sqdmlsl2_n<mode>_internal (operands[0], operands[1],
3385 operands[2], operands[3],
3392 (define_insn "aarch64_sqdmull<mode>"
3393 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3396 (sign_extend:<VWIDE>
3397 (match_operand:VSD_HSI 1 "register_operand" "w"))
3398 (sign_extend:<VWIDE>
3399 (match_operand:VSD_HSI 2 "register_operand" "w")))
3402 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3403 [(set_attr "type" "neon_sat_mul_<Vetype>_long")]
3408 (define_insn "aarch64_sqdmull_lane<mode>_internal"
3409 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3412 (sign_extend:<VWIDE>
3413 (match_operand:VD_HSI 1 "register_operand" "w"))
3414 (sign_extend:<VWIDE>
3415 (vec_duplicate:VD_HSI
3417 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3418 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3423 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3424 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3426 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3429 (define_insn "aarch64_sqdmull_laneq<mode>_internal"
3430 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3433 (sign_extend:<VWIDE>
3434 (match_operand:VD_HSI 1 "register_operand" "w"))
3435 (sign_extend:<VWIDE>
3436 (vec_duplicate:VD_HSI
3438 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3439 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3444 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3445 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3447 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3450 (define_insn "aarch64_sqdmull_lane<mode>_internal"
3451 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3454 (sign_extend:<VWIDE>
3455 (match_operand:SD_HSI 1 "register_operand" "w"))
3456 (sign_extend:<VWIDE>
3458 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3459 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))
3464 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3465 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3467 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3470 (define_insn "aarch64_sqdmull_laneq<mode>_internal"
3471 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3474 (sign_extend:<VWIDE>
3475 (match_operand:SD_HSI 1 "register_operand" "w"))
3476 (sign_extend:<VWIDE>
3478 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3479 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))
3484 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3485 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3487 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3490 (define_expand "aarch64_sqdmull_lane<mode>"
3491 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3492 (match_operand:VSD_HSI 1 "register_operand" "w")
3493 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3494 (match_operand:SI 3 "immediate_operand" "i")]
3497 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
3498 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3499 emit_insn (gen_aarch64_sqdmull_lane<mode>_internal (operands[0], operands[1],
3500 operands[2], operands[3]));
3504 (define_expand "aarch64_sqdmull_laneq<mode>"
3505 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3506 (match_operand:VD_HSI 1 "register_operand" "w")
3507 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3508 (match_operand:SI 3 "immediate_operand" "i")]
3511 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
3512 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3513 emit_insn (gen_aarch64_sqdmull_laneq<mode>_internal
3514 (operands[0], operands[1], operands[2], operands[3]));
3520 (define_insn "aarch64_sqdmull_n<mode>"
3521 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3524 (sign_extend:<VWIDE>
3525 (match_operand:VD_HSI 1 "register_operand" "w"))
3526 (sign_extend:<VWIDE>
3527 (vec_duplicate:VD_HSI
3528 (match_operand:<VEL> 2 "register_operand" "<vwx>")))
3532 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
3533 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3540 (define_insn "aarch64_sqdmull2<mode>_internal"
3541 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3544 (sign_extend:<VWIDE>
3546 (match_operand:VQ_HSI 1 "register_operand" "w")
3547 (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
3548 (sign_extend:<VWIDE>
3550 (match_operand:VQ_HSI 2 "register_operand" "w")
3555 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3556 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3559 (define_expand "aarch64_sqdmull2<mode>"
3560 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3561 (match_operand:VQ_HSI 1 "register_operand" "w")
3562 (match_operand:VQ_HSI 2 "register_operand" "w")]
3565 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3566 emit_insn (gen_aarch64_sqdmull2<mode>_internal (operands[0], operands[1],
3573 (define_insn "aarch64_sqdmull2_lane<mode>_internal"
3574 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3577 (sign_extend:<VWIDE>
3579 (match_operand:VQ_HSI 1 "register_operand" "w")
3580 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3581 (sign_extend:<VWIDE>
3582 (vec_duplicate:<VHALF>
3584 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3585 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3590 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3591 return "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3593 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3596 (define_insn "aarch64_sqdmull2_laneq<mode>_internal"
3597 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3600 (sign_extend:<VWIDE>
3602 (match_operand:VQ_HSI 1 "register_operand" "w")
3603 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3604 (sign_extend:<VWIDE>
3605 (vec_duplicate:<VHALF>
3607 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3608 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3613 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3614 return "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3616 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3619 (define_expand "aarch64_sqdmull2_lane<mode>"
3620 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3621 (match_operand:VQ_HSI 1 "register_operand" "w")
3622 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3623 (match_operand:SI 3 "immediate_operand" "i")]
3626 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3627 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
3628 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3629 emit_insn (gen_aarch64_sqdmull2_lane<mode>_internal (operands[0], operands[1],
3630 operands[2], operands[3],
3635 (define_expand "aarch64_sqdmull2_laneq<mode>"
3636 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3637 (match_operand:VQ_HSI 1 "register_operand" "w")
3638 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3639 (match_operand:SI 3 "immediate_operand" "i")]
3642 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3643 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
3644 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3645 emit_insn (gen_aarch64_sqdmull2_laneq<mode>_internal (operands[0], operands[1],
3646 operands[2], operands[3],
3653 (define_insn "aarch64_sqdmull2_n<mode>_internal"
3654 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3657 (sign_extend:<VWIDE>
3659 (match_operand:VQ_HSI 1 "register_operand" "w")
3660 (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
3661 (sign_extend:<VWIDE>
3662 (vec_duplicate:<VHALF>
3663 (match_operand:<VEL> 2 "register_operand" "<vwx>")))
3667 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
3668 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3671 (define_expand "aarch64_sqdmull2_n<mode>"
3672 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3673 (match_operand:VQ_HSI 1 "register_operand" "w")
3674 (match_operand:<VEL> 2 "register_operand" "w")]
3677 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3678 emit_insn (gen_aarch64_sqdmull2_n<mode>_internal (operands[0], operands[1],
3685 (define_insn "aarch64_<sur>shl<mode>"
3686 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3688 [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
3689 (match_operand:VSDQ_I_DI 2 "register_operand" "w")]
3692 "<sur>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
3693 [(set_attr "type" "neon_shift_reg<q>")]
3699 (define_insn "aarch64_<sur>q<r>shl<mode>"
3700 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3702 [(match_operand:VSDQ_I 1 "register_operand" "w")
3703 (match_operand:VSDQ_I 2 "register_operand" "w")]
3706 "<sur>q<r>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
3707 [(set_attr "type" "neon_sat_shift_reg<q>")]
3712 (define_insn "aarch64_<sur>shll_n<mode>"
3713 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3714 (unspec:<VWIDE> [(match_operand:VDW 1 "register_operand" "w")
3715 (match_operand:SI 2 "immediate_operand" "i")]
3719 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3720 aarch64_simd_const_bounds (operands[2], 0, bit_width + 1);
3721 if (INTVAL (operands[2]) == bit_width)
3723 return \"shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3726 return \"<sur>shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3728 [(set_attr "type" "neon_shift_imm_long")]
3733 (define_insn "aarch64_<sur>shll2_n<mode>"
3734 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3735 (unspec:<VWIDE> [(match_operand:VQW 1 "register_operand" "w")
3736 (match_operand:SI 2 "immediate_operand" "i")]
3740 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3741 aarch64_simd_const_bounds (operands[2], 0, bit_width + 1);
3742 if (INTVAL (operands[2]) == bit_width)
3744 return \"shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3747 return \"<sur>shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3749 [(set_attr "type" "neon_shift_imm_long")]
3754 (define_insn "aarch64_<sur>shr_n<mode>"
3755 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3756 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
3757 (match_operand:SI 2 "immediate_operand" "i")]
3761 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3762 aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
3763 return \"<sur>shr\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
3764 [(set_attr "type" "neon_sat_shift_imm<q>")]
3769 (define_insn "aarch64_<sur>sra_n<mode>"
3770 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3771 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
3772 (match_operand:VSDQ_I_DI 2 "register_operand" "w")
3773 (match_operand:SI 3 "immediate_operand" "i")]
3777 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3778 aarch64_simd_const_bounds (operands[3], 1, bit_width + 1);
3779 return \"<sur>sra\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
3780 [(set_attr "type" "neon_shift_acc<q>")]
3785 (define_insn "aarch64_<sur>s<lr>i_n<mode>"
3786 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3787 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
3788 (match_operand:VSDQ_I_DI 2 "register_operand" "w")
3789 (match_operand:SI 3 "immediate_operand" "i")]
3793 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3794 aarch64_simd_const_bounds (operands[3], 1 - <VSLRI:offsetlr>,
3795 bit_width - <VSLRI:offsetlr> + 1);
3796 return \"s<lr>i\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
3797 [(set_attr "type" "neon_shift_imm<q>")]
3802 (define_insn "aarch64_<sur>qshl<u>_n<mode>"
3803 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3804 (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "w")
3805 (match_operand:SI 2 "immediate_operand" "i")]
3809 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3810 aarch64_simd_const_bounds (operands[2], 0, bit_width);
3811 return \"<sur>qshl<u>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
3812 [(set_attr "type" "neon_sat_shift_imm<q>")]
3818 (define_insn "aarch64_<sur>q<r>shr<u>n_n<mode>"
3819 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
3820 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")
3821 (match_operand:SI 2 "immediate_operand" "i")]
3825 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3826 aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
3827 return \"<sur>q<r>shr<u>n\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2\";"
3828 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
3832 ;; cm(eq|ge|gt|lt|le)
3833 ;; Note, we have constraints for Dz and Z as different expanders
3834 ;; have different ideas of what should be passed to this pattern.
3836 (define_insn "aarch64_cm<optab><mode>"
3837 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
3839 (COMPARISONS:<V_cmp_result>
3840 (match_operand:VDQ 1 "register_operand" "w,w")
3841 (match_operand:VDQ 2 "aarch64_simd_reg_or_zero" "w,ZDz")
3845 cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
3846 cm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #0"
3847 [(set_attr "type" "neon_compare<q>, neon_compare_zero<q>")]
3850 (define_insn_and_split "aarch64_cm<optab>di"
3851 [(set (match_operand:DI 0 "register_operand" "=w,w,r")
3854 (match_operand:DI 1 "register_operand" "w,w,r")
3855 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz,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 enum machine_mode mode = SELECT_CC_MODE (<CMP>, operands[1], operands[2]);
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, neon_compare_zero, multiple")]
3885 (define_insn "*aarch64_cm<optab>di"
3886 [(set (match_operand:DI 0 "register_operand" "=w,w")
3889 (match_operand:DI 1 "register_operand" "w,w")
3890 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz")
3892 "TARGET_SIMD && reload_completed"
3894 cm<n_optab>\t%d0, %d<cmp_1>, %d<cmp_2>
3895 cm<optab>\t%d0, %d1, #0"
3896 [(set_attr "type" "neon_compare, neon_compare_zero")]
3901 (define_insn "aarch64_cm<optab><mode>"
3902 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
3904 (UCOMPARISONS:<V_cmp_result>
3905 (match_operand:VDQ 1 "register_operand" "w")
3906 (match_operand:VDQ 2 "register_operand" "w")
3909 "cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
3910 [(set_attr "type" "neon_compare<q>")]
3913 (define_insn_and_split "aarch64_cm<optab>di"
3914 [(set (match_operand:DI 0 "register_operand" "=w,r")
3917 (match_operand:DI 1 "register_operand" "w,r")
3918 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,r")
3920 (clobber (reg:CC CC_REGNUM))]
3924 [(set (match_operand:DI 0 "register_operand")
3927 (match_operand:DI 1 "register_operand")
3928 (match_operand:DI 2 "aarch64_simd_reg_or_zero")
3931 /* If we are in the general purpose register file,
3932 we split to a sequence of comparison and store. */
3933 if (GP_REGNUM_P (REGNO (operands[0]))
3934 && GP_REGNUM_P (REGNO (operands[1])))
3936 enum machine_mode mode = CCmode;
3937 rtx cc_reg = aarch64_gen_compare_reg (<CMP>, operands[1], operands[2]);
3938 rtx comparison = gen_rtx_<CMP> (mode, operands[1], operands[2]);
3939 emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
3942 /* Otherwise, we expand to a similar pattern which does not
3943 clobber CC_REGNUM. */
3945 [(set_attr "type" "neon_compare,multiple")]
3948 (define_insn "*aarch64_cm<optab>di"
3949 [(set (match_operand:DI 0 "register_operand" "=w")
3952 (match_operand:DI 1 "register_operand" "w")
3953 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w")
3955 "TARGET_SIMD && reload_completed"
3956 "cm<n_optab>\t%d0, %d<cmp_1>, %d<cmp_2>"
3957 [(set_attr "type" "neon_compare")]
3962 ;; Although neg (ne (and x y) 0) is the natural way of expressing a cmtst,
3963 ;; we don't have any insns using ne, and aarch64_vcond_internal outputs
3964 ;; not (neg (eq (and x y) 0))
3965 ;; which is rewritten by simplify_rtx as
3966 ;; plus (eq (and x y) 0) -1.
3968 (define_insn "aarch64_cmtst<mode>"
3969 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
3970 (plus:<V_cmp_result>
3973 (match_operand:VDQ 1 "register_operand" "w")
3974 (match_operand:VDQ 2 "register_operand" "w"))
3975 (match_operand:VDQ 3 "aarch64_simd_imm_zero"))
3976 (match_operand:<V_cmp_result> 4 "aarch64_simd_imm_minus_one")))
3979 "cmtst\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3980 [(set_attr "type" "neon_tst<q>")]
3983 (define_insn_and_split "aarch64_cmtstdi"
3984 [(set (match_operand:DI 0 "register_operand" "=w,r")
3988 (match_operand:DI 1 "register_operand" "w,r")
3989 (match_operand:DI 2 "register_operand" "w,r"))
3991 (clobber (reg:CC CC_REGNUM))]
3995 [(set (match_operand:DI 0 "register_operand")
3999 (match_operand:DI 1 "register_operand")
4000 (match_operand:DI 2 "register_operand"))
4003 /* If we are in the general purpose register file,
4004 we split to a sequence of comparison and store. */
4005 if (GP_REGNUM_P (REGNO (operands[0]))
4006 && GP_REGNUM_P (REGNO (operands[1])))
4008 rtx and_tree = gen_rtx_AND (DImode, operands[1], operands[2]);
4009 enum machine_mode mode = SELECT_CC_MODE (NE, and_tree, const0_rtx);
4010 rtx cc_reg = aarch64_gen_compare_reg (NE, and_tree, const0_rtx);
4011 rtx comparison = gen_rtx_NE (mode, and_tree, const0_rtx);
4012 emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
4015 /* Otherwise, we expand to a similar pattern which does not
4016 clobber CC_REGNUM. */
4018 [(set_attr "type" "neon_tst,multiple")]
4021 (define_insn "*aarch64_cmtstdi"
4022 [(set (match_operand:DI 0 "register_operand" "=w")
4026 (match_operand:DI 1 "register_operand" "w")
4027 (match_operand:DI 2 "register_operand" "w"))
4030 "cmtst\t%d0, %d1, %d2"
4031 [(set_attr "type" "neon_tst")]
4034 ;; fcm(eq|ge|gt|le|lt)
4036 (define_insn "aarch64_cm<optab><mode>"
4037 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
4039 (COMPARISONS:<V_cmp_result>
4040 (match_operand:VALLF 1 "register_operand" "w,w")
4041 (match_operand:VALLF 2 "aarch64_simd_reg_or_zero" "w,YDz")
4045 fcm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
4046 fcm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
4047 [(set_attr "type" "neon_fp_compare_<Vetype><q>")]
4051 ;; Note we can also handle what would be fac(le|lt) by
4052 ;; generating fac(ge|gt).
4054 (define_insn "*aarch64_fac<optab><mode>"
4055 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
4057 (FAC_COMPARISONS:<V_cmp_result>
4058 (abs:VALLF (match_operand:VALLF 1 "register_operand" "w"))
4059 (abs:VALLF (match_operand:VALLF 2 "register_operand" "w"))
4062 "fac<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
4063 [(set_attr "type" "neon_fp_compare_<Vetype><q>")]
4068 (define_insn "aarch64_addp<mode>"
4069 [(set (match_operand:VD_BHSI 0 "register_operand" "=w")
4071 [(match_operand:VD_BHSI 1 "register_operand" "w")
4072 (match_operand:VD_BHSI 2 "register_operand" "w")]
4075 "addp\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
4076 [(set_attr "type" "neon_reduc_add<q>")]
4079 (define_insn "aarch64_addpdi"
4080 [(set (match_operand:DI 0 "register_operand" "=w")
4082 [(match_operand:V2DI 1 "register_operand" "w")]
4086 [(set_attr "type" "neon_reduc_add")]
4091 (define_insn "sqrt<mode>2"
4092 [(set (match_operand:VDQF 0 "register_operand" "=w")
4093 (sqrt:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
4095 "fsqrt\\t%0.<Vtype>, %1.<Vtype>"
4096 [(set_attr "type" "neon_fp_sqrt_<Vetype><q>")]
4099 ;; Patterns for vector struct loads and stores.
4101 (define_insn "vec_load_lanesoi<mode>"
4102 [(set (match_operand:OI 0 "register_operand" "=w")
4103 (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")
4104 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4107 "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4108 [(set_attr "type" "neon_load2_2reg<q>")]
4111 (define_insn "aarch64_simd_ld2r<mode>"
4112 [(set (match_operand:OI 0 "register_operand" "=w")
4113 (unspec:OI [(match_operand:<V_TWO_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4114 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4117 "ld2r\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4118 [(set_attr "type" "neon_load2_all_lanes<q>")]
4121 (define_insn "vec_store_lanesoi<mode>"
4122 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
4123 (unspec:OI [(match_operand:OI 1 "register_operand" "w")
4124 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4127 "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
4128 [(set_attr "type" "neon_store2_2reg<q>")]
4131 (define_insn "vec_store_lanesoi_lane<mode>"
4132 [(set (match_operand:<V_TWO_ELEM> 0 "aarch64_simd_struct_operand" "=Utv")
4133 (unspec:<V_TWO_ELEM> [(match_operand:OI 1 "register_operand" "w")
4134 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4135 (match_operand:SI 2 "immediate_operand" "i")]
4138 "st2\\t{%S1.<Vetype> - %T1.<Vetype>}[%2], %0"
4139 [(set_attr "type" "neon_store3_one_lane<q>")]
4142 (define_insn "vec_load_lanesci<mode>"
4143 [(set (match_operand:CI 0 "register_operand" "=w")
4144 (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv")
4145 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4148 "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4149 [(set_attr "type" "neon_load3_3reg<q>")]
4152 (define_insn "aarch64_simd_ld3r<mode>"
4153 [(set (match_operand:CI 0 "register_operand" "=w")
4154 (unspec:CI [(match_operand:<V_THREE_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4155 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4158 "ld3r\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4159 [(set_attr "type" "neon_load3_all_lanes<q>")]
4162 (define_insn "vec_store_lanesci<mode>"
4163 [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv")
4164 (unspec:CI [(match_operand:CI 1 "register_operand" "w")
4165 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4168 "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
4169 [(set_attr "type" "neon_store3_3reg<q>")]
4172 (define_insn "vec_store_lanesci_lane<mode>"
4173 [(set (match_operand:<V_THREE_ELEM> 0 "aarch64_simd_struct_operand" "=Utv")
4174 (unspec:<V_THREE_ELEM> [(match_operand:CI 1 "register_operand" "w")
4175 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4176 (match_operand:SI 2 "immediate_operand" "i")]
4179 "st3\\t{%S1.<Vetype> - %U1.<Vetype>}[%2], %0"
4180 [(set_attr "type" "neon_store3_one_lane<q>")]
4183 (define_insn "vec_load_lanesxi<mode>"
4184 [(set (match_operand:XI 0 "register_operand" "=w")
4185 (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv")
4186 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4189 "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4190 [(set_attr "type" "neon_load4_4reg<q>")]
4193 (define_insn "aarch64_simd_ld4r<mode>"
4194 [(set (match_operand:XI 0 "register_operand" "=w")
4195 (unspec:XI [(match_operand:<V_FOUR_ELEM> 1 "aarch64_simd_struct_operand" "Utv")
4196 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4199 "ld4r\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4200 [(set_attr "type" "neon_load4_all_lanes<q>")]
4203 (define_insn "vec_store_lanesxi<mode>"
4204 [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
4205 (unspec:XI [(match_operand:XI 1 "register_operand" "w")
4206 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4209 "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
4210 [(set_attr "type" "neon_store4_4reg<q>")]
4213 (define_insn "vec_store_lanesxi_lane<mode>"
4214 [(set (match_operand:<V_FOUR_ELEM> 0 "aarch64_simd_struct_operand" "=Utv")
4215 (unspec:<V_FOUR_ELEM> [(match_operand:XI 1 "register_operand" "w")
4216 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4217 (match_operand:SI 2 "immediate_operand" "i")]
4220 "st4\\t{%S1.<Vetype> - %V1.<Vetype>}[%2], %0"
4221 [(set_attr "type" "neon_store4_one_lane<q>")]
4224 ;; Reload patterns for AdvSIMD register list operands.
4226 (define_expand "mov<mode>"
4227 [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "")
4228 (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" ""))]
4231 if (can_create_pseudo_p ())
4233 if (GET_CODE (operands[0]) != REG)
4234 operands[1] = force_reg (<MODE>mode, operands[1]);
4238 (define_insn "*aarch64_mov<mode>"
4239 [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "=w,Utv,w")
4240 (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" " w,w,Utv"))]
4242 && (register_operand (operands[0], <MODE>mode)
4243 || register_operand (operands[1], <MODE>mode))"
4246 switch (which_alternative)
4249 case 1: return "st1\\t{%S1.16b - %<Vendreg>1.16b}, %0";
4250 case 2: return "ld1\\t{%S0.16b - %<Vendreg>0.16b}, %1";
4251 default: gcc_unreachable ();
4254 [(set_attr "type" "neon_move,neon_store<nregs>_<nregs>reg_q,\
4255 neon_load<nregs>_<nregs>reg_q")
4256 (set (attr "length") (symbol_ref "aarch64_simd_attr_length_move (insn)"))]
4259 (define_insn "aarch64_be_ld1<mode>"
4260 [(set (match_operand:VALLDI 0 "register_operand" "=w")
4261 (unspec:VALLDI [(match_operand:VALLDI 1 "aarch64_simd_struct_operand" "Utv")]
4264 "ld1\\t{%0<Vmtype>}, %1"
4265 [(set_attr "type" "neon_load1_1reg<q>")]
4268 (define_insn "aarch64_be_st1<mode>"
4269 [(set (match_operand:VALLDI 0 "aarch64_simd_struct_operand" "=Utv")
4270 (unspec:VALLDI [(match_operand:VALLDI 1 "register_operand" "w")]
4273 "st1\\t{%1<Vmtype>}, %0"
4274 [(set_attr "type" "neon_store1_1reg<q>")]
4278 [(set (match_operand:OI 0 "register_operand" "")
4279 (match_operand:OI 1 "register_operand" ""))]
4280 "TARGET_SIMD && reload_completed"
4281 [(set (match_dup 0) (match_dup 1))
4282 (set (match_dup 2) (match_dup 3))]
4284 int rdest = REGNO (operands[0]);
4285 int rsrc = REGNO (operands[1]);
4286 rtx dest[2], src[2];
4288 dest[0] = gen_rtx_REG (TFmode, rdest);
4289 src[0] = gen_rtx_REG (TFmode, rsrc);
4290 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
4291 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
4293 aarch64_simd_disambiguate_copy (operands, dest, src, 2);
4297 [(set (match_operand:CI 0 "register_operand" "")
4298 (match_operand:CI 1 "register_operand" ""))]
4299 "TARGET_SIMD && reload_completed"
4300 [(set (match_dup 0) (match_dup 1))
4301 (set (match_dup 2) (match_dup 3))
4302 (set (match_dup 4) (match_dup 5))]
4304 int rdest = REGNO (operands[0]);
4305 int rsrc = REGNO (operands[1]);
4306 rtx dest[3], src[3];
4308 dest[0] = gen_rtx_REG (TFmode, rdest);
4309 src[0] = gen_rtx_REG (TFmode, rsrc);
4310 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
4311 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
4312 dest[2] = gen_rtx_REG (TFmode, rdest + 2);
4313 src[2] = gen_rtx_REG (TFmode, rsrc + 2);
4315 aarch64_simd_disambiguate_copy (operands, dest, src, 3);
4319 [(set (match_operand:XI 0 "register_operand" "")
4320 (match_operand:XI 1 "register_operand" ""))]
4321 "TARGET_SIMD && reload_completed"
4322 [(set (match_dup 0) (match_dup 1))
4323 (set (match_dup 2) (match_dup 3))
4324 (set (match_dup 4) (match_dup 5))
4325 (set (match_dup 6) (match_dup 7))]
4327 int rdest = REGNO (operands[0]);
4328 int rsrc = REGNO (operands[1]);
4329 rtx dest[4], src[4];
4331 dest[0] = gen_rtx_REG (TFmode, rdest);
4332 src[0] = gen_rtx_REG (TFmode, rsrc);
4333 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
4334 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
4335 dest[2] = gen_rtx_REG (TFmode, rdest + 2);
4336 src[2] = gen_rtx_REG (TFmode, rsrc + 2);
4337 dest[3] = gen_rtx_REG (TFmode, rdest + 3);
4338 src[3] = gen_rtx_REG (TFmode, rsrc + 3);
4340 aarch64_simd_disambiguate_copy (operands, dest, src, 4);
4343 (define_expand "aarch64_ld2r<mode>"
4344 [(match_operand:OI 0 "register_operand" "=w")
4345 (match_operand:DI 1 "register_operand" "w")
4346 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4349 enum machine_mode mode = <V_TWO_ELEM>mode;
4350 rtx mem = gen_rtx_MEM (mode, operands[1]);
4352 emit_insn (gen_aarch64_simd_ld2r<mode> (operands[0], mem));
4356 (define_expand "aarch64_ld3r<mode>"
4357 [(match_operand:CI 0 "register_operand" "=w")
4358 (match_operand:DI 1 "register_operand" "w")
4359 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4362 enum machine_mode mode = <V_THREE_ELEM>mode;
4363 rtx mem = gen_rtx_MEM (mode, operands[1]);
4365 emit_insn (gen_aarch64_simd_ld3r<mode> (operands[0], mem));
4369 (define_expand "aarch64_ld4r<mode>"
4370 [(match_operand:XI 0 "register_operand" "=w")
4371 (match_operand:DI 1 "register_operand" "w")
4372 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4375 enum machine_mode mode = <V_FOUR_ELEM>mode;
4376 rtx mem = gen_rtx_MEM (mode, operands[1]);
4378 emit_insn (gen_aarch64_simd_ld4r<mode> (operands[0],mem));
4382 (define_insn "aarch64_ld2<mode>_dreg"
4383 [(set (match_operand:OI 0 "register_operand" "=w")
4387 (unspec:VD [(match_operand:TI 1 "aarch64_simd_struct_operand" "Utv")]
4389 (vec_duplicate:VD (const_int 0)))
4391 (unspec:VD [(match_dup 1)]
4393 (vec_duplicate:VD (const_int 0)))) 0))]
4395 "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4396 [(set_attr "type" "neon_load2_2reg<q>")]
4399 (define_insn "aarch64_ld2<mode>_dreg"
4400 [(set (match_operand:OI 0 "register_operand" "=w")
4404 (unspec:DX [(match_operand:TI 1 "aarch64_simd_struct_operand" "Utv")]
4408 (unspec:DX [(match_dup 1)]
4410 (const_int 0))) 0))]
4412 "ld1\\t{%S0.1d - %T0.1d}, %1"
4413 [(set_attr "type" "neon_load1_2reg<q>")]
4416 (define_insn "aarch64_ld3<mode>_dreg"
4417 [(set (match_operand:CI 0 "register_operand" "=w")
4422 (unspec:VD [(match_operand:EI 1 "aarch64_simd_struct_operand" "Utv")]
4424 (vec_duplicate:VD (const_int 0)))
4426 (unspec:VD [(match_dup 1)]
4428 (vec_duplicate:VD (const_int 0))))
4430 (unspec:VD [(match_dup 1)]
4432 (vec_duplicate:VD (const_int 0)))) 0))]
4434 "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4435 [(set_attr "type" "neon_load3_3reg<q>")]
4438 (define_insn "aarch64_ld3<mode>_dreg"
4439 [(set (match_operand:CI 0 "register_operand" "=w")
4444 (unspec:DX [(match_operand:EI 1 "aarch64_simd_struct_operand" "Utv")]
4448 (unspec:DX [(match_dup 1)]
4452 (unspec:DX [(match_dup 1)]
4454 (const_int 0))) 0))]
4456 "ld1\\t{%S0.1d - %U0.1d}, %1"
4457 [(set_attr "type" "neon_load1_3reg<q>")]
4460 (define_insn "aarch64_ld4<mode>_dreg"
4461 [(set (match_operand:XI 0 "register_operand" "=w")
4466 (unspec:VD [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")]
4468 (vec_duplicate:VD (const_int 0)))
4470 (unspec:VD [(match_dup 1)]
4472 (vec_duplicate:VD (const_int 0))))
4475 (unspec:VD [(match_dup 1)]
4477 (vec_duplicate:VD (const_int 0)))
4479 (unspec:VD [(match_dup 1)]
4481 (vec_duplicate:VD (const_int 0))))) 0))]
4483 "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4484 [(set_attr "type" "neon_load4_4reg<q>")]
4487 (define_insn "aarch64_ld4<mode>_dreg"
4488 [(set (match_operand:XI 0 "register_operand" "=w")
4493 (unspec:DX [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")]
4497 (unspec:DX [(match_dup 1)]
4502 (unspec:DX [(match_dup 1)]
4506 (unspec:DX [(match_dup 1)]
4508 (const_int 0)))) 0))]
4510 "ld1\\t{%S0.1d - %V0.1d}, %1"
4511 [(set_attr "type" "neon_load1_4reg<q>")]
4514 (define_expand "aarch64_ld<VSTRUCT:nregs><VDC:mode>"
4515 [(match_operand:VSTRUCT 0 "register_operand" "=w")
4516 (match_operand:DI 1 "register_operand" "r")
4517 (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4520 enum machine_mode mode = <VSTRUCT:VSTRUCT_DREG>mode;
4521 rtx mem = gen_rtx_MEM (mode, operands[1]);
4523 emit_insn (gen_aarch64_ld<VSTRUCT:nregs><VDC:mode>_dreg (operands[0], mem));
4527 (define_expand "aarch64_ld1<VALL:mode>"
4528 [(match_operand:VALL 0 "register_operand")
4529 (match_operand:DI 1 "register_operand")]
4532 enum machine_mode mode = <VALL:MODE>mode;
4533 rtx mem = gen_rtx_MEM (mode, operands[1]);
4535 if (BYTES_BIG_ENDIAN)
4536 emit_insn (gen_aarch64_be_ld1<VALL:mode> (operands[0], mem));
4538 emit_move_insn (operands[0], mem);
4542 (define_expand "aarch64_ld<VSTRUCT:nregs><VQ:mode>"
4543 [(match_operand:VSTRUCT 0 "register_operand" "=w")
4544 (match_operand:DI 1 "register_operand" "r")
4545 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4548 enum machine_mode mode = <VSTRUCT:MODE>mode;
4549 rtx mem = gen_rtx_MEM (mode, operands[1]);
4551 emit_insn (gen_vec_load_lanes<VSTRUCT:mode><VQ:mode> (operands[0], mem));
4555 ;; Expanders for builtins to extract vector registers from large
4556 ;; opaque integer modes.
4560 (define_expand "aarch64_get_dreg<VSTRUCT:mode><VDC:mode>"
4561 [(match_operand:VDC 0 "register_operand" "=w")
4562 (match_operand:VSTRUCT 1 "register_operand" "w")
4563 (match_operand:SI 2 "immediate_operand" "i")]
4566 int part = INTVAL (operands[2]);
4567 rtx temp = gen_reg_rtx (<VDC:VDBL>mode);
4568 int offset = part * 16;
4570 emit_move_insn (temp, gen_rtx_SUBREG (<VDC:VDBL>mode, operands[1], offset));
4571 emit_move_insn (operands[0], gen_lowpart (<VDC:MODE>mode, temp));
4577 (define_expand "aarch64_get_qreg<VSTRUCT:mode><VQ:mode>"
4578 [(match_operand:VQ 0 "register_operand" "=w")
4579 (match_operand:VSTRUCT 1 "register_operand" "w")
4580 (match_operand:SI 2 "immediate_operand" "i")]
4583 int part = INTVAL (operands[2]);
4584 int offset = part * 16;
4586 emit_move_insn (operands[0],
4587 gen_rtx_SUBREG (<VQ:MODE>mode, operands[1], offset));
4591 ;; Permuted-store expanders for neon intrinsics.
4593 ;; Permute instructions
4597 (define_expand "vec_perm_const<mode>"
4598 [(match_operand:VALL 0 "register_operand")
4599 (match_operand:VALL 1 "register_operand")
4600 (match_operand:VALL 2 "register_operand")
4601 (match_operand:<V_cmp_result> 3)]
4604 if (aarch64_expand_vec_perm_const (operands[0], operands[1],
4605 operands[2], operands[3]))
4611 (define_expand "vec_perm<mode>"
4612 [(match_operand:VB 0 "register_operand")
4613 (match_operand:VB 1 "register_operand")
4614 (match_operand:VB 2 "register_operand")
4615 (match_operand:VB 3 "register_operand")]
4618 aarch64_expand_vec_perm (operands[0], operands[1],
4619 operands[2], operands[3]);
4623 (define_insn "aarch64_tbl1<mode>"
4624 [(set (match_operand:VB 0 "register_operand" "=w")
4625 (unspec:VB [(match_operand:V16QI 1 "register_operand" "w")
4626 (match_operand:VB 2 "register_operand" "w")]
4629 "tbl\\t%0.<Vtype>, {%1.16b}, %2.<Vtype>"
4630 [(set_attr "type" "neon_tbl1<q>")]
4633 ;; Two source registers.
4635 (define_insn "aarch64_tbl2v16qi"
4636 [(set (match_operand:V16QI 0 "register_operand" "=w")
4637 (unspec:V16QI [(match_operand:OI 1 "register_operand" "w")
4638 (match_operand:V16QI 2 "register_operand" "w")]
4641 "tbl\\t%0.16b, {%S1.16b - %T1.16b}, %2.16b"
4642 [(set_attr "type" "neon_tbl2_q")]
4645 (define_insn_and_split "aarch64_combinev16qi"
4646 [(set (match_operand:OI 0 "register_operand" "=w")
4647 (unspec:OI [(match_operand:V16QI 1 "register_operand" "w")
4648 (match_operand:V16QI 2 "register_operand" "w")]
4652 "&& reload_completed"
4655 aarch64_split_combinev16qi (operands);
4658 [(set_attr "type" "multiple")]
4661 (define_insn "aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>"
4662 [(set (match_operand:VALL 0 "register_operand" "=w")
4663 (unspec:VALL [(match_operand:VALL 1 "register_operand" "w")
4664 (match_operand:VALL 2 "register_operand" "w")]
4667 "<PERMUTE:perm_insn><PERMUTE:perm_hilo>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
4668 [(set_attr "type" "neon_permute<q>")]
4671 ;; Note immediate (third) operand is lane index not byte index.
4672 (define_insn "aarch64_ext<mode>"
4673 [(set (match_operand:VALL 0 "register_operand" "=w")
4674 (unspec:VALL [(match_operand:VALL 1 "register_operand" "w")
4675 (match_operand:VALL 2 "register_operand" "w")
4676 (match_operand:SI 3 "immediate_operand" "i")]
4680 operands[3] = GEN_INT (INTVAL (operands[3])
4681 * GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)));
4682 return "ext\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>, #%3";
4684 [(set_attr "type" "neon_ext<q>")]
4687 ;; This exists solely to check the arguments to the corresponding __builtin.
4688 ;; Used where we want an error for out-of-range indices which would otherwise
4689 ;; be silently wrapped (e.g. the mask to a __builtin_shuffle).
4690 (define_expand "aarch64_im_lane_boundsi"
4691 [(match_operand:SI 0 "immediate_operand" "i")
4692 (match_operand:SI 1 "immediate_operand" "i")]
4695 aarch64_simd_lane_bounds (operands[0], 0, INTVAL (operands[1]));
4700 (define_insn "aarch64_rev<REVERSE:rev_op><mode>"
4701 [(set (match_operand:VALL 0 "register_operand" "=w")
4702 (unspec:VALL [(match_operand:VALL 1 "register_operand" "w")]
4705 "rev<REVERSE:rev_op>\\t%0.<Vtype>, %1.<Vtype>"
4706 [(set_attr "type" "neon_rev<q>")]
4709 (define_insn "aarch64_st2<mode>_dreg"
4710 [(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
4711 (unspec:TI [(match_operand:OI 1 "register_operand" "w")
4712 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4715 "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
4716 [(set_attr "type" "neon_store2_2reg")]
4719 (define_insn "aarch64_st2<mode>_dreg"
4720 [(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
4721 (unspec:TI [(match_operand:OI 1 "register_operand" "w")
4722 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4725 "st1\\t{%S1.1d - %T1.1d}, %0"
4726 [(set_attr "type" "neon_store1_2reg")]
4729 (define_insn "aarch64_st3<mode>_dreg"
4730 [(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
4731 (unspec:EI [(match_operand:CI 1 "register_operand" "w")
4732 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4735 "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
4736 [(set_attr "type" "neon_store3_3reg")]
4739 (define_insn "aarch64_st3<mode>_dreg"
4740 [(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
4741 (unspec:EI [(match_operand:CI 1 "register_operand" "w")
4742 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4745 "st1\\t{%S1.1d - %U1.1d}, %0"
4746 [(set_attr "type" "neon_store1_3reg")]
4749 (define_insn "aarch64_st4<mode>_dreg"
4750 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
4751 (unspec:OI [(match_operand:XI 1 "register_operand" "w")
4752 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4755 "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
4756 [(set_attr "type" "neon_store4_4reg")]
4759 (define_insn "aarch64_st4<mode>_dreg"
4760 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
4761 (unspec:OI [(match_operand:XI 1 "register_operand" "w")
4762 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4765 "st1\\t{%S1.1d - %V1.1d}, %0"
4766 [(set_attr "type" "neon_store1_4reg")]
4769 (define_expand "aarch64_st<VSTRUCT:nregs><VDC:mode>"
4770 [(match_operand:DI 0 "register_operand" "r")
4771 (match_operand:VSTRUCT 1 "register_operand" "w")
4772 (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4775 enum machine_mode mode = <VSTRUCT:VSTRUCT_DREG>mode;
4776 rtx mem = gen_rtx_MEM (mode, operands[0]);
4778 emit_insn (gen_aarch64_st<VSTRUCT:nregs><VDC:mode>_dreg (mem, operands[1]));
4782 (define_expand "aarch64_st<VSTRUCT:nregs><VQ:mode>"
4783 [(match_operand:DI 0 "register_operand" "r")
4784 (match_operand:VSTRUCT 1 "register_operand" "w")
4785 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4788 enum machine_mode mode = <VSTRUCT:MODE>mode;
4789 rtx mem = gen_rtx_MEM (mode, operands[0]);
4791 emit_insn (gen_vec_store_lanes<VSTRUCT:mode><VQ:mode> (mem, operands[1]));
4795 (define_expand "aarch64_st2_lane<VQ:mode>"
4796 [(match_operand:DI 0 "register_operand" "r")
4797 (match_operand:OI 1 "register_operand" "w")
4798 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4799 (match_operand:SI 2 "immediate_operand")]
4802 enum machine_mode mode = <V_TWO_ELEM>mode;
4803 rtx mem = gen_rtx_MEM (mode, operands[0]);
4804 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4806 emit_insn (gen_vec_store_lanesoi_lane<VQ:mode> (mem,
4812 (define_expand "aarch64_st3_lane<VQ:mode>"
4813 [(match_operand:DI 0 "register_operand" "r")
4814 (match_operand:CI 1 "register_operand" "w")
4815 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4816 (match_operand:SI 2 "immediate_operand")]
4819 enum machine_mode mode = <V_THREE_ELEM>mode;
4820 rtx mem = gen_rtx_MEM (mode, operands[0]);
4821 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4823 emit_insn (gen_vec_store_lanesci_lane<VQ:mode> (mem,
4829 (define_expand "aarch64_st4_lane<VQ:mode>"
4830 [(match_operand:DI 0 "register_operand" "r")
4831 (match_operand:XI 1 "register_operand" "w")
4832 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4833 (match_operand:SI 2 "immediate_operand")]
4836 enum machine_mode mode = <V_FOUR_ELEM>mode;
4837 rtx mem = gen_rtx_MEM (mode, operands[0]);
4838 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4840 emit_insn (gen_vec_store_lanesxi_lane<VQ:mode> (mem,
4846 (define_expand "aarch64_st1<VALL:mode>"
4847 [(match_operand:DI 0 "register_operand")
4848 (match_operand:VALL 1 "register_operand")]
4851 enum machine_mode mode = <VALL:MODE>mode;
4852 rtx mem = gen_rtx_MEM (mode, operands[0]);
4854 if (BYTES_BIG_ENDIAN)
4855 emit_insn (gen_aarch64_be_st1<VALL:mode> (mem, operands[1]));
4857 emit_move_insn (mem, operands[1]);
4861 ;; Expander for builtins to insert vector registers into large
4862 ;; opaque integer modes.
4864 ;; Q-register list. We don't need a D-reg inserter as we zero
4865 ;; extend them in arm_neon.h and insert the resulting Q-regs.
4867 (define_expand "aarch64_set_qreg<VSTRUCT:mode><VQ:mode>"
4868 [(match_operand:VSTRUCT 0 "register_operand" "+w")
4869 (match_operand:VSTRUCT 1 "register_operand" "0")
4870 (match_operand:VQ 2 "register_operand" "w")
4871 (match_operand:SI 3 "immediate_operand" "i")]
4874 int part = INTVAL (operands[3]);
4875 int offset = part * 16;
4877 emit_move_insn (operands[0], operands[1]);
4878 emit_move_insn (gen_rtx_SUBREG (<VQ:MODE>mode, operands[0], offset),
4883 ;; Standard pattern name vec_init<mode>.
4885 (define_expand "vec_init<mode>"
4886 [(match_operand:VALL 0 "register_operand" "")
4887 (match_operand 1 "" "")]
4890 aarch64_expand_vector_init (operands[0], operands[1]);
4894 (define_insn "*aarch64_simd_ld1r<mode>"
4895 [(set (match_operand:VALL 0 "register_operand" "=w")
4897 (match_operand:<VEL> 1 "aarch64_simd_struct_operand" "Utv")))]
4899 "ld1r\\t{%0.<Vtype>}, %1"
4900 [(set_attr "type" "neon_load1_all_lanes")]
4903 (define_insn "aarch64_frecpe<mode>"
4904 [(set (match_operand:VDQF 0 "register_operand" "=w")
4905 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")]
4908 "frecpe\\t%0.<Vtype>, %1.<Vtype>"
4909 [(set_attr "type" "neon_fp_recpe_<Vetype><q>")]
4912 (define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
4913 [(set (match_operand:GPF 0 "register_operand" "=w")
4914 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4917 "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
4918 [(set_attr "type" "neon_fp_recp<FRECP:frecp_suffix>_<GPF:Vetype><GPF:q>")]
4921 (define_insn "aarch64_frecps<mode>"
4922 [(set (match_operand:VALLF 0 "register_operand" "=w")
4923 (unspec:VALLF [(match_operand:VALLF 1 "register_operand" "w")
4924 (match_operand:VALLF 2 "register_operand" "w")]
4927 "frecps\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
4928 [(set_attr "type" "neon_fp_recps_<Vetype><q>")]
4931 ;; Standard pattern name vec_extract<mode>.
4933 (define_expand "vec_extract<mode>"
4934 [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "")
4935 (match_operand:VALL 1 "register_operand" "")
4936 (match_operand:SI 2 "immediate_operand" "")]
4940 (gen_aarch64_get_lane<mode> (operands[0], operands[1], operands[2]));
4946 (define_insn "aarch64_crypto_aes<aes_op>v16qi"
4947 [(set (match_operand:V16QI 0 "register_operand" "=w")
4948 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
4949 (match_operand:V16QI 2 "register_operand" "w")]
4951 "TARGET_SIMD && TARGET_CRYPTO"
4952 "aes<aes_op>\\t%0.16b, %2.16b"
4953 [(set_attr "type" "crypto_aese")]
4956 (define_insn "aarch64_crypto_aes<aesmc_op>v16qi"
4957 [(set (match_operand:V16QI 0 "register_operand" "=w")
4958 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "w")]
4960 "TARGET_SIMD && TARGET_CRYPTO"
4961 "aes<aesmc_op>\\t%0.16b, %1.16b"
4962 [(set_attr "type" "crypto_aesmc")]
4967 (define_insn "aarch64_crypto_sha1hsi"
4968 [(set (match_operand:SI 0 "register_operand" "=w")
4969 (unspec:SI [(match_operand:SI 1
4970 "register_operand" "w")]
4972 "TARGET_SIMD && TARGET_CRYPTO"
4974 [(set_attr "type" "crypto_sha1_fast")]
4977 (define_insn "aarch64_crypto_sha1su1v4si"
4978 [(set (match_operand:V4SI 0 "register_operand" "=w")
4979 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
4980 (match_operand:V4SI 2 "register_operand" "w")]
4982 "TARGET_SIMD && TARGET_CRYPTO"
4983 "sha1su1\\t%0.4s, %2.4s"
4984 [(set_attr "type" "crypto_sha1_fast")]
4987 (define_insn "aarch64_crypto_sha1<sha1_op>v4si"
4988 [(set (match_operand:V4SI 0 "register_operand" "=w")
4989 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
4990 (match_operand:SI 2 "register_operand" "w")
4991 (match_operand:V4SI 3 "register_operand" "w")]
4993 "TARGET_SIMD && TARGET_CRYPTO"
4994 "sha1<sha1_op>\\t%q0, %s2, %3.4s"
4995 [(set_attr "type" "crypto_sha1_slow")]
4998 (define_insn "aarch64_crypto_sha1su0v4si"
4999 [(set (match_operand:V4SI 0 "register_operand" "=w")
5000 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5001 (match_operand:V4SI 2 "register_operand" "w")
5002 (match_operand:V4SI 3 "register_operand" "w")]
5004 "TARGET_SIMD && TARGET_CRYPTO"
5005 "sha1su0\\t%0.4s, %2.4s, %3.4s"
5006 [(set_attr "type" "crypto_sha1_xor")]
5011 (define_insn "aarch64_crypto_sha256h<sha256_op>v4si"
5012 [(set (match_operand:V4SI 0 "register_operand" "=w")
5013 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5014 (match_operand:V4SI 2 "register_operand" "w")
5015 (match_operand:V4SI 3 "register_operand" "w")]
5017 "TARGET_SIMD && TARGET_CRYPTO"
5018 "sha256h<sha256_op>\\t%q0, %q2, %3.4s"
5019 [(set_attr "type" "crypto_sha256_slow")]
5022 (define_insn "aarch64_crypto_sha256su0v4si"
5023 [(set (match_operand:V4SI 0 "register_operand" "=w")
5024 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5025 (match_operand:V4SI 2 "register_operand" "w")]
5027 "TARGET_SIMD &&TARGET_CRYPTO"
5028 "sha256su0\\t%0.4s, %2.4s"
5029 [(set_attr "type" "crypto_sha256_fast")]
5032 (define_insn "aarch64_crypto_sha256su1v4si"
5033 [(set (match_operand:V4SI 0 "register_operand" "=w")
5034 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5035 (match_operand:V4SI 2 "register_operand" "w")
5036 (match_operand:V4SI 3 "register_operand" "w")]
5038 "TARGET_SIMD &&TARGET_CRYPTO"
5039 "sha256su1\\t%0.4s, %2.4s, %3.4s"
5040 [(set_attr "type" "crypto_sha256_slow")]
5045 (define_insn "aarch64_crypto_pmulldi"
5046 [(set (match_operand:TI 0 "register_operand" "=w")
5047 (unspec:TI [(match_operand:DI 1 "register_operand" "w")
5048 (match_operand:DI 2 "register_operand" "w")]
5050 "TARGET_SIMD && TARGET_CRYPTO"
5051 "pmull\\t%0.1q, %1.1d, %2.1d"
5052 [(set_attr "type" "neon_mul_d_long")]
5055 (define_insn "aarch64_crypto_pmullv2di"
5056 [(set (match_operand:TI 0 "register_operand" "=w")
5057 (unspec:TI [(match_operand:V2DI 1 "register_operand" "w")
5058 (match_operand:V2DI 2 "register_operand" "w")]
5060 "TARGET_SIMD && TARGET_CRYPTO"
5061 "pmull2\\t%0.1q, %1.2d, %2.2d"
5062 [(set_attr "type" "neon_mul_d_long")]