1 ;; Machine description for AArch64 AdvSIMD architecture.
2 ;; Copyright (C) 2011-2016 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 (define_expand "mov<mode>"
22 [(set (match_operand:VALL_F16 0 "nonimmediate_operand" "")
23 (match_operand:VALL_F16 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_I 0 "register_operand" "=w, w")
47 (match_operand:<VEL> 1 "register_operand" "r, w")))]
50 dup\\t%0.<Vtype>, %<vw>1
51 dup\\t%0.<Vtype>, %1.<Vetype>[0]"
52 [(set_attr "type" "neon_from_gp<q>, neon_dup<q>")]
55 (define_insn "aarch64_simd_dup<mode>"
56 [(set (match_operand:VDQF_F16 0 "register_operand" "=w")
57 (vec_duplicate:VDQF_F16
58 (match_operand:<VEL> 1 "register_operand" "w")))]
60 "dup\\t%0.<Vtype>, %1.<Vetype>[0]"
61 [(set_attr "type" "neon_dup<q>")]
64 (define_insn "aarch64_dup_lane<mode>"
65 [(set (match_operand:VALL_F16 0 "register_operand" "=w")
66 (vec_duplicate:VALL_F16
68 (match_operand:VALL_F16 1 "register_operand" "w")
69 (parallel [(match_operand:SI 2 "immediate_operand" "i")])
73 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
74 return "dup\\t%0.<Vtype>, %1.<Vetype>[%2]";
76 [(set_attr "type" "neon_dup<q>")]
79 (define_insn "aarch64_dup_lane_<vswap_width_name><mode>"
80 [(set (match_operand:VALL_F16 0 "register_operand" "=w")
81 (vec_duplicate:VALL_F16
83 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "w")
84 (parallel [(match_operand:SI 2 "immediate_operand" "i")])
88 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
89 INTVAL (operands[2])));
90 return "dup\\t%0.<Vtype>, %1.<Vetype>[%2]";
92 [(set_attr "type" "neon_dup<q>")]
95 (define_insn "*aarch64_simd_mov<mode>"
96 [(set (match_operand:VD 0 "nonimmediate_operand"
97 "=w, m, w, ?r, ?w, ?r, w")
98 (match_operand:VD 1 "general_operand"
99 "m, w, w, w, r, r, Dn"))]
101 && (register_operand (operands[0], <MODE>mode)
102 || register_operand (operands[1], <MODE>mode))"
104 switch (which_alternative)
106 case 0: return "ldr\\t%d0, %1";
107 case 1: return "str\\t%d1, %0";
108 case 2: return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
109 case 3: return "umov\t%0, %1.d[0]";
110 case 4: return "ins\t%0.d[0], %1";
111 case 5: return "mov\t%0, %1";
113 return aarch64_output_simd_mov_immediate (operands[1],
115 default: gcc_unreachable ();
118 [(set_attr "type" "neon_load1_1reg<q>, neon_store1_1reg<q>,\
119 neon_logic<q>, neon_to_gp<q>, neon_from_gp<q>,\
120 mov_reg, neon_move<q>")]
123 (define_insn "*aarch64_simd_mov<mode>"
124 [(set (match_operand:VQ 0 "nonimmediate_operand"
125 "=w, m, w, ?r, ?w, ?r, w")
126 (match_operand:VQ 1 "general_operand"
127 "m, w, w, w, r, r, Dn"))]
129 && (register_operand (operands[0], <MODE>mode)
130 || register_operand (operands[1], <MODE>mode))"
132 switch (which_alternative)
135 return "ldr\\t%q0, %1";
137 return "str\\t%q1, %0";
139 return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
145 return aarch64_output_simd_mov_immediate (operands[1], <MODE>mode, 128);
150 [(set_attr "type" "neon_load1_1reg<q>, neon_store1_1reg<q>,\
151 neon_logic<q>, multiple, multiple, multiple,\
153 (set_attr "length" "4,4,4,8,8,8,4")]
156 (define_insn "load_pair<mode>"
157 [(set (match_operand:VD 0 "register_operand" "=w")
158 (match_operand:VD 1 "aarch64_mem_pair_operand" "Ump"))
159 (set (match_operand:VD 2 "register_operand" "=w")
160 (match_operand:VD 3 "memory_operand" "m"))]
162 && rtx_equal_p (XEXP (operands[3], 0),
163 plus_constant (Pmode,
164 XEXP (operands[1], 0),
165 GET_MODE_SIZE (<MODE>mode)))"
167 [(set_attr "type" "neon_ldp")]
170 (define_insn "store_pair<mode>"
171 [(set (match_operand:VD 0 "aarch64_mem_pair_operand" "=Ump")
172 (match_operand:VD 1 "register_operand" "w"))
173 (set (match_operand:VD 2 "memory_operand" "=m")
174 (match_operand:VD 3 "register_operand" "w"))]
176 && rtx_equal_p (XEXP (operands[2], 0),
177 plus_constant (Pmode,
178 XEXP (operands[0], 0),
179 GET_MODE_SIZE (<MODE>mode)))"
181 [(set_attr "type" "neon_stp")]
185 [(set (match_operand:VQ 0 "register_operand" "")
186 (match_operand:VQ 1 "register_operand" ""))]
187 "TARGET_SIMD && reload_completed
188 && GP_REGNUM_P (REGNO (operands[0]))
189 && GP_REGNUM_P (REGNO (operands[1]))"
192 aarch64_simd_emit_reg_reg_move (operands, DImode, 2);
197 [(set (match_operand:VQ 0 "register_operand" "")
198 (match_operand:VQ 1 "register_operand" ""))]
199 "TARGET_SIMD && reload_completed
200 && ((FP_REGNUM_P (REGNO (operands[0])) && GP_REGNUM_P (REGNO (operands[1])))
201 || (GP_REGNUM_P (REGNO (operands[0])) && FP_REGNUM_P (REGNO (operands[1]))))"
204 aarch64_split_simd_move (operands[0], operands[1]);
208 (define_expand "aarch64_split_simd_mov<mode>"
209 [(set (match_operand:VQ 0)
210 (match_operand:VQ 1))]
213 rtx dst = operands[0];
214 rtx src = operands[1];
216 if (GP_REGNUM_P (REGNO (src)))
218 rtx src_low_part = gen_lowpart (<VHALF>mode, src);
219 rtx src_high_part = gen_highpart (<VHALF>mode, src);
222 (gen_move_lo_quad_<mode> (dst, src_low_part));
224 (gen_move_hi_quad_<mode> (dst, src_high_part));
229 rtx dst_low_part = gen_lowpart (<VHALF>mode, dst);
230 rtx dst_high_part = gen_highpart (<VHALF>mode, dst);
231 rtx lo = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
232 rtx hi = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
235 (gen_aarch64_simd_mov_from_<mode>low (dst_low_part, src, lo));
237 (gen_aarch64_simd_mov_from_<mode>high (dst_high_part, src, hi));
243 (define_insn "aarch64_simd_mov_from_<mode>low"
244 [(set (match_operand:<VHALF> 0 "register_operand" "=r")
246 (match_operand:VQ 1 "register_operand" "w")
247 (match_operand:VQ 2 "vect_par_cnst_lo_half" "")))]
248 "TARGET_SIMD && reload_completed"
250 [(set_attr "type" "neon_to_gp<q>")
251 (set_attr "length" "4")
254 (define_insn "aarch64_simd_mov_from_<mode>high"
255 [(set (match_operand:<VHALF> 0 "register_operand" "=r")
257 (match_operand:VQ 1 "register_operand" "w")
258 (match_operand:VQ 2 "vect_par_cnst_hi_half" "")))]
259 "TARGET_SIMD && reload_completed"
261 [(set_attr "type" "neon_to_gp<q>")
262 (set_attr "length" "4")
265 (define_insn "orn<mode>3"
266 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
267 (ior:VDQ_I (not:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w"))
268 (match_operand:VDQ_I 2 "register_operand" "w")))]
270 "orn\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
271 [(set_attr "type" "neon_logic<q>")]
274 (define_insn "bic<mode>3"
275 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
276 (and:VDQ_I (not:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w"))
277 (match_operand:VDQ_I 2 "register_operand" "w")))]
279 "bic\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
280 [(set_attr "type" "neon_logic<q>")]
283 (define_insn "add<mode>3"
284 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
285 (plus:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
286 (match_operand:VDQ_I 2 "register_operand" "w")))]
288 "add\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
289 [(set_attr "type" "neon_add<q>")]
292 (define_insn "sub<mode>3"
293 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
294 (minus:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
295 (match_operand:VDQ_I 2 "register_operand" "w")))]
297 "sub\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
298 [(set_attr "type" "neon_sub<q>")]
301 (define_insn "mul<mode>3"
302 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
303 (mult:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")
304 (match_operand:VDQ_BHSI 2 "register_operand" "w")))]
306 "mul\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
307 [(set_attr "type" "neon_mul_<Vetype><q>")]
310 (define_insn "bswap<mode>2"
311 [(set (match_operand:VDQHSD 0 "register_operand" "=w")
312 (bswap:VDQHSD (match_operand:VDQHSD 1 "register_operand" "w")))]
314 "rev<Vrevsuff>\\t%0.<Vbtype>, %1.<Vbtype>"
315 [(set_attr "type" "neon_rev<q>")]
318 (define_insn "aarch64_rbit<mode>"
319 [(set (match_operand:VB 0 "register_operand" "=w")
320 (unspec:VB [(match_operand:VB 1 "register_operand" "w")]
323 "rbit\\t%0.<Vbtype>, %1.<Vbtype>"
324 [(set_attr "type" "neon_rbit")]
327 (define_expand "ctz<mode>2"
328 [(set (match_operand:VS 0 "register_operand")
329 (ctz:VS (match_operand:VS 1 "register_operand")))]
332 emit_insn (gen_bswap<mode>2 (operands[0], operands[1]));
333 rtx op0_castsi2qi = simplify_gen_subreg(<VS:VSI2QI>mode, operands[0],
335 emit_insn (gen_aarch64_rbit<VS:vsi2qi> (op0_castsi2qi, op0_castsi2qi));
336 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
341 (define_insn "*aarch64_mul3_elt<mode>"
342 [(set (match_operand:VMUL 0 "register_operand" "=w")
346 (match_operand:VMUL 1 "register_operand" "<h_con>")
347 (parallel [(match_operand:SI 2 "immediate_operand")])))
348 (match_operand:VMUL 3 "register_operand" "w")))]
351 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
352 return "<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]";
354 [(set_attr "type" "neon<fp>_mul_<stype>_scalar<q>")]
357 (define_insn "*aarch64_mul3_elt_<vswap_width_name><mode>"
358 [(set (match_operand:VMUL_CHANGE_NLANES 0 "register_operand" "=w")
359 (mult:VMUL_CHANGE_NLANES
360 (vec_duplicate:VMUL_CHANGE_NLANES
362 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
363 (parallel [(match_operand:SI 2 "immediate_operand")])))
364 (match_operand:VMUL_CHANGE_NLANES 3 "register_operand" "w")))]
367 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
368 INTVAL (operands[2])));
369 return "<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]";
371 [(set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")]
374 (define_insn "*aarch64_mul3_elt_from_dup<mode>"
375 [(set (match_operand:VMUL 0 "register_operand" "=w")
378 (match_operand:<VEL> 1 "register_operand" "<h_con>"))
379 (match_operand:VMUL 2 "register_operand" "w")))]
381 "<f>mul\t%0.<Vtype>, %2.<Vtype>, %1.<Vetype>[0]";
382 [(set_attr "type" "neon<fp>_mul_<stype>_scalar<q>")]
385 (define_insn "aarch64_rsqrte<mode>"
386 [(set (match_operand:VHSDF_SDF 0 "register_operand" "=w")
387 (unspec:VHSDF_SDF [(match_operand:VHSDF_SDF 1 "register_operand" "w")]
390 "frsqrte\\t%<v>0<Vmtype>, %<v>1<Vmtype>"
391 [(set_attr "type" "neon_fp_rsqrte_<stype><q>")])
393 (define_insn "aarch64_rsqrts<mode>"
394 [(set (match_operand:VHSDF_SDF 0 "register_operand" "=w")
395 (unspec:VHSDF_SDF [(match_operand:VHSDF_SDF 1 "register_operand" "w")
396 (match_operand:VHSDF_SDF 2 "register_operand" "w")]
399 "frsqrts\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
400 [(set_attr "type" "neon_fp_rsqrts_<stype><q>")])
402 (define_expand "rsqrt<mode>2"
403 [(set (match_operand:VALLF 0 "register_operand" "=w")
404 (unspec:VALLF [(match_operand:VALLF 1 "register_operand" "w")]
408 aarch64_emit_approx_sqrt (operands[0], operands[1], true);
412 (define_insn "*aarch64_mul3_elt_to_64v2df"
413 [(set (match_operand:DF 0 "register_operand" "=w")
416 (match_operand:V2DF 1 "register_operand" "w")
417 (parallel [(match_operand:SI 2 "immediate_operand")]))
418 (match_operand:DF 3 "register_operand" "w")))]
421 operands[2] = GEN_INT (ENDIAN_LANE_N (V2DFmode, INTVAL (operands[2])));
422 return "fmul\\t%0.2d, %3.2d, %1.d[%2]";
424 [(set_attr "type" "neon_fp_mul_d_scalar_q")]
427 (define_insn "neg<mode>2"
428 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
429 (neg:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")))]
431 "neg\t%0.<Vtype>, %1.<Vtype>"
432 [(set_attr "type" "neon_neg<q>")]
435 (define_insn "abs<mode>2"
436 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
437 (abs:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")))]
439 "abs\t%0.<Vtype>, %1.<Vtype>"
440 [(set_attr "type" "neon_abs<q>")]
443 ;; The intrinsic version of integer ABS must not be allowed to
444 ;; combine with any operation with an integerated ABS step, such
446 (define_insn "aarch64_abs<mode>"
447 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
449 [(match_operand:VSDQ_I_DI 1 "register_operand" "w")]
452 "abs\t%<v>0<Vmtype>, %<v>1<Vmtype>"
453 [(set_attr "type" "neon_abs<q>")]
456 (define_insn "abd<mode>_3"
457 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
458 (abs:VDQ_BHSI (minus:VDQ_BHSI
459 (match_operand:VDQ_BHSI 1 "register_operand" "w")
460 (match_operand:VDQ_BHSI 2 "register_operand" "w"))))]
462 "sabd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
463 [(set_attr "type" "neon_abd<q>")]
466 (define_insn "aba<mode>_3"
467 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
468 (plus:VDQ_BHSI (abs:VDQ_BHSI (minus:VDQ_BHSI
469 (match_operand:VDQ_BHSI 1 "register_operand" "w")
470 (match_operand:VDQ_BHSI 2 "register_operand" "w")))
471 (match_operand:VDQ_BHSI 3 "register_operand" "0")))]
473 "saba\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
474 [(set_attr "type" "neon_arith_acc<q>")]
477 (define_insn "fabd<mode>3"
478 [(set (match_operand:VHSDF_SDF 0 "register_operand" "=w")
481 (match_operand:VHSDF_SDF 1 "register_operand" "w")
482 (match_operand:VHSDF_SDF 2 "register_operand" "w"))))]
484 "fabd\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
485 [(set_attr "type" "neon_fp_abd_<stype><q>")]
488 (define_insn "and<mode>3"
489 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
490 (and:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
491 (match_operand:VDQ_I 2 "register_operand" "w")))]
493 "and\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
494 [(set_attr "type" "neon_logic<q>")]
497 (define_insn "ior<mode>3"
498 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
499 (ior:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
500 (match_operand:VDQ_I 2 "register_operand" "w")))]
502 "orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
503 [(set_attr "type" "neon_logic<q>")]
506 (define_insn "xor<mode>3"
507 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
508 (xor:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
509 (match_operand:VDQ_I 2 "register_operand" "w")))]
511 "eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
512 [(set_attr "type" "neon_logic<q>")]
515 (define_insn "one_cmpl<mode>2"
516 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
517 (not:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")))]
519 "not\t%0.<Vbtype>, %1.<Vbtype>"
520 [(set_attr "type" "neon_logic<q>")]
523 (define_insn "aarch64_simd_vec_set<mode>"
524 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w,w,w")
526 (vec_duplicate:VDQ_BHSI
527 (match_operand:<VEL> 1 "aarch64_simd_general_operand" "r,w,Utv"))
528 (match_operand:VDQ_BHSI 3 "register_operand" "0,0,0")
529 (match_operand:SI 2 "immediate_operand" "i,i,i")))]
532 int elt = ENDIAN_LANE_N (<MODE>mode, exact_log2 (INTVAL (operands[2])));
533 operands[2] = GEN_INT ((HOST_WIDE_INT) 1 << elt);
534 switch (which_alternative)
537 return "ins\\t%0.<Vetype>[%p2], %w1";
539 return "ins\\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
541 return "ld1\\t{%0.<Vetype>}[%p2], %1";
546 [(set_attr "type" "neon_from_gp<q>, neon_ins<q>, neon_load1_1reg<q>")]
549 (define_insn "*aarch64_simd_vec_copy_lane<mode>"
550 [(set (match_operand:VALL 0 "register_operand" "=w")
554 (match_operand:VALL 3 "register_operand" "w")
556 [(match_operand:SI 4 "immediate_operand" "i")])))
557 (match_operand:VALL 1 "register_operand" "0")
558 (match_operand:SI 2 "immediate_operand" "i")))]
561 int elt = ENDIAN_LANE_N (<MODE>mode, exact_log2 (INTVAL (operands[2])));
562 operands[2] = GEN_INT (HOST_WIDE_INT_1 << elt);
563 operands[4] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[4])));
565 return "ins\t%0.<Vetype>[%p2], %3.<Vetype>[%4]";
567 [(set_attr "type" "neon_ins<q>")]
570 (define_insn "*aarch64_simd_vec_copy_lane_<vswap_width_name><mode>"
571 [(set (match_operand:VALL 0 "register_operand" "=w")
575 (match_operand:<VSWAP_WIDTH> 3 "register_operand" "w")
577 [(match_operand:SI 4 "immediate_operand" "i")])))
578 (match_operand:VALL 1 "register_operand" "0")
579 (match_operand:SI 2 "immediate_operand" "i")))]
582 int elt = ENDIAN_LANE_N (<MODE>mode, exact_log2 (INTVAL (operands[2])));
583 operands[2] = GEN_INT (HOST_WIDE_INT_1 << elt);
584 operands[4] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
585 INTVAL (operands[4])));
587 return "ins\t%0.<Vetype>[%p2], %3.<Vetype>[%4]";
589 [(set_attr "type" "neon_ins<q>")]
592 (define_insn "aarch64_simd_lshr<mode>"
593 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
594 (lshiftrt:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
595 (match_operand:VDQ_I 2 "aarch64_simd_rshift_imm" "Dr")))]
597 "ushr\t%0.<Vtype>, %1.<Vtype>, %2"
598 [(set_attr "type" "neon_shift_imm<q>")]
601 (define_insn "aarch64_simd_ashr<mode>"
602 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
603 (ashiftrt:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
604 (match_operand:VDQ_I 2 "aarch64_simd_rshift_imm" "Dr")))]
606 "sshr\t%0.<Vtype>, %1.<Vtype>, %2"
607 [(set_attr "type" "neon_shift_imm<q>")]
610 (define_insn "aarch64_simd_imm_shl<mode>"
611 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
612 (ashift:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
613 (match_operand:VDQ_I 2 "aarch64_simd_lshift_imm" "Dl")))]
615 "shl\t%0.<Vtype>, %1.<Vtype>, %2"
616 [(set_attr "type" "neon_shift_imm<q>")]
619 (define_insn "aarch64_simd_reg_sshl<mode>"
620 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
621 (ashift:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
622 (match_operand:VDQ_I 2 "register_operand" "w")))]
624 "sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
625 [(set_attr "type" "neon_shift_reg<q>")]
628 (define_insn "aarch64_simd_reg_shl<mode>_unsigned"
629 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
630 (unspec:VDQ_I [(match_operand:VDQ_I 1 "register_operand" "w")
631 (match_operand:VDQ_I 2 "register_operand" "w")]
632 UNSPEC_ASHIFT_UNSIGNED))]
634 "ushl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
635 [(set_attr "type" "neon_shift_reg<q>")]
638 (define_insn "aarch64_simd_reg_shl<mode>_signed"
639 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
640 (unspec:VDQ_I [(match_operand:VDQ_I 1 "register_operand" "w")
641 (match_operand:VDQ_I 2 "register_operand" "w")]
642 UNSPEC_ASHIFT_SIGNED))]
644 "sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
645 [(set_attr "type" "neon_shift_reg<q>")]
648 (define_expand "ashl<mode>3"
649 [(match_operand:VDQ_I 0 "register_operand" "")
650 (match_operand:VDQ_I 1 "register_operand" "")
651 (match_operand:SI 2 "general_operand" "")]
654 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
657 if (CONST_INT_P (operands[2]))
659 shift_amount = INTVAL (operands[2]);
660 if (shift_amount >= 0 && shift_amount < bit_width)
662 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
664 emit_insn (gen_aarch64_simd_imm_shl<mode> (operands[0],
671 operands[2] = force_reg (SImode, operands[2]);
674 else if (MEM_P (operands[2]))
676 operands[2] = force_reg (SImode, operands[2]);
679 if (REG_P (operands[2]))
681 rtx tmp = gen_reg_rtx (<MODE>mode);
682 emit_insn (gen_aarch64_simd_dup<mode> (tmp,
683 convert_to_mode (<VEL>mode,
686 emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
695 (define_expand "lshr<mode>3"
696 [(match_operand:VDQ_I 0 "register_operand" "")
697 (match_operand:VDQ_I 1 "register_operand" "")
698 (match_operand:SI 2 "general_operand" "")]
701 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
704 if (CONST_INT_P (operands[2]))
706 shift_amount = INTVAL (operands[2]);
707 if (shift_amount > 0 && shift_amount <= bit_width)
709 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
711 emit_insn (gen_aarch64_simd_lshr<mode> (operands[0],
717 operands[2] = force_reg (SImode, operands[2]);
719 else if (MEM_P (operands[2]))
721 operands[2] = force_reg (SImode, operands[2]);
724 if (REG_P (operands[2]))
726 rtx tmp = gen_reg_rtx (SImode);
727 rtx tmp1 = gen_reg_rtx (<MODE>mode);
728 emit_insn (gen_negsi2 (tmp, operands[2]));
729 emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
730 convert_to_mode (<VEL>mode,
732 emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0],
742 (define_expand "ashr<mode>3"
743 [(match_operand:VDQ_I 0 "register_operand" "")
744 (match_operand:VDQ_I 1 "register_operand" "")
745 (match_operand:SI 2 "general_operand" "")]
748 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
751 if (CONST_INT_P (operands[2]))
753 shift_amount = INTVAL (operands[2]);
754 if (shift_amount > 0 && shift_amount <= bit_width)
756 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
758 emit_insn (gen_aarch64_simd_ashr<mode> (operands[0],
764 operands[2] = force_reg (SImode, operands[2]);
766 else if (MEM_P (operands[2]))
768 operands[2] = force_reg (SImode, operands[2]);
771 if (REG_P (operands[2]))
773 rtx tmp = gen_reg_rtx (SImode);
774 rtx tmp1 = gen_reg_rtx (<MODE>mode);
775 emit_insn (gen_negsi2 (tmp, operands[2]));
776 emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
777 convert_to_mode (<VEL>mode,
779 emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0],
789 (define_expand "vashl<mode>3"
790 [(match_operand:VDQ_I 0 "register_operand" "")
791 (match_operand:VDQ_I 1 "register_operand" "")
792 (match_operand:VDQ_I 2 "register_operand" "")]
795 emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
800 ;; Using mode VDQ_BHSI as there is no V2DImode neg!
801 ;; Negating individual lanes most certainly offsets the
802 ;; gain from vectorization.
803 (define_expand "vashr<mode>3"
804 [(match_operand:VDQ_BHSI 0 "register_operand" "")
805 (match_operand:VDQ_BHSI 1 "register_operand" "")
806 (match_operand:VDQ_BHSI 2 "register_operand" "")]
809 rtx neg = gen_reg_rtx (<MODE>mode);
810 emit (gen_neg<mode>2 (neg, operands[2]));
811 emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0], operands[1],
817 (define_expand "aarch64_ashr_simddi"
818 [(match_operand:DI 0 "register_operand" "=w")
819 (match_operand:DI 1 "register_operand" "w")
820 (match_operand:SI 2 "aarch64_shift_imm64_di" "")]
823 /* An arithmetic shift right by 64 fills the result with copies of the sign
824 bit, just like asr by 63 - however the standard pattern does not handle
826 if (INTVAL (operands[2]) == 64)
827 operands[2] = GEN_INT (63);
828 emit_insn (gen_ashrdi3 (operands[0], operands[1], operands[2]));
833 (define_expand "vlshr<mode>3"
834 [(match_operand:VDQ_BHSI 0 "register_operand" "")
835 (match_operand:VDQ_BHSI 1 "register_operand" "")
836 (match_operand:VDQ_BHSI 2 "register_operand" "")]
839 rtx neg = gen_reg_rtx (<MODE>mode);
840 emit (gen_neg<mode>2 (neg, operands[2]));
841 emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0], operands[1],
846 (define_expand "aarch64_lshr_simddi"
847 [(match_operand:DI 0 "register_operand" "=w")
848 (match_operand:DI 1 "register_operand" "w")
849 (match_operand:SI 2 "aarch64_shift_imm64_di" "")]
852 if (INTVAL (operands[2]) == 64)
853 emit_move_insn (operands[0], const0_rtx);
855 emit_insn (gen_lshrdi3 (operands[0], operands[1], operands[2]));
860 (define_expand "vec_set<mode>"
861 [(match_operand:VDQ_BHSI 0 "register_operand")
862 (match_operand:<VEL> 1 "register_operand")
863 (match_operand:SI 2 "immediate_operand")]
866 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
867 emit_insn (gen_aarch64_simd_vec_set<mode> (operands[0], operands[1],
868 GEN_INT (elem), operands[0]));
873 ;; For 64-bit modes we use ushl/r, as this does not require a SIMD zero.
874 (define_insn "vec_shr_<mode>"
875 [(set (match_operand:VD 0 "register_operand" "=w")
876 (unspec:VD [(match_operand:VD 1 "register_operand" "w")
877 (match_operand:SI 2 "immediate_operand" "i")]
881 if (BYTES_BIG_ENDIAN)
882 return "shl %d0, %d1, %2";
884 return "ushr %d0, %d1, %2";
886 [(set_attr "type" "neon_shift_imm")]
889 (define_insn "aarch64_simd_vec_setv2di"
890 [(set (match_operand:V2DI 0 "register_operand" "=w,w")
893 (match_operand:DI 1 "register_operand" "r,w"))
894 (match_operand:V2DI 3 "register_operand" "0,0")
895 (match_operand:SI 2 "immediate_operand" "i,i")))]
898 int elt = ENDIAN_LANE_N (V2DImode, exact_log2 (INTVAL (operands[2])));
899 operands[2] = GEN_INT ((HOST_WIDE_INT) 1 << elt);
900 switch (which_alternative)
903 return "ins\\t%0.d[%p2], %1";
905 return "ins\\t%0.d[%p2], %1.d[0]";
910 [(set_attr "type" "neon_from_gp, neon_ins_q")]
913 (define_expand "vec_setv2di"
914 [(match_operand:V2DI 0 "register_operand")
915 (match_operand:DI 1 "register_operand")
916 (match_operand:SI 2 "immediate_operand")]
919 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
920 emit_insn (gen_aarch64_simd_vec_setv2di (operands[0], operands[1],
921 GEN_INT (elem), operands[0]));
926 (define_insn "aarch64_simd_vec_set<mode>"
927 [(set (match_operand:VDQF_F16 0 "register_operand" "=w")
929 (vec_duplicate:VDQF_F16
930 (match_operand:<VEL> 1 "register_operand" "w"))
931 (match_operand:VDQF_F16 3 "register_operand" "0")
932 (match_operand:SI 2 "immediate_operand" "i")))]
935 int elt = ENDIAN_LANE_N (<MODE>mode, exact_log2 (INTVAL (operands[2])));
937 operands[2] = GEN_INT ((HOST_WIDE_INT)1 << elt);
938 return "ins\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
940 [(set_attr "type" "neon_ins<q>")]
943 (define_expand "vec_set<mode>"
944 [(match_operand:VDQF_F16 0 "register_operand" "+w")
945 (match_operand:<VEL> 1 "register_operand" "w")
946 (match_operand:SI 2 "immediate_operand" "")]
949 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
950 emit_insn (gen_aarch64_simd_vec_set<mode> (operands[0], operands[1],
951 GEN_INT (elem), operands[0]));
957 (define_insn "aarch64_mla<mode>"
958 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
959 (plus:VDQ_BHSI (mult:VDQ_BHSI
960 (match_operand:VDQ_BHSI 2 "register_operand" "w")
961 (match_operand:VDQ_BHSI 3 "register_operand" "w"))
962 (match_operand:VDQ_BHSI 1 "register_operand" "0")))]
964 "mla\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
965 [(set_attr "type" "neon_mla_<Vetype><q>")]
968 (define_insn "*aarch64_mla_elt<mode>"
969 [(set (match_operand:VDQHS 0 "register_operand" "=w")
974 (match_operand:VDQHS 1 "register_operand" "<h_con>")
975 (parallel [(match_operand:SI 2 "immediate_operand")])))
976 (match_operand:VDQHS 3 "register_operand" "w"))
977 (match_operand:VDQHS 4 "register_operand" "0")))]
980 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
981 return "mla\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
983 [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
986 (define_insn "*aarch64_mla_elt_<vswap_width_name><mode>"
987 [(set (match_operand:VDQHS 0 "register_operand" "=w")
992 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
993 (parallel [(match_operand:SI 2 "immediate_operand")])))
994 (match_operand:VDQHS 3 "register_operand" "w"))
995 (match_operand:VDQHS 4 "register_operand" "0")))]
998 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
999 INTVAL (operands[2])));
1000 return "mla\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1002 [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
1005 (define_insn "aarch64_mls<mode>"
1006 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
1007 (minus:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "0")
1008 (mult:VDQ_BHSI (match_operand:VDQ_BHSI 2 "register_operand" "w")
1009 (match_operand:VDQ_BHSI 3 "register_operand" "w"))))]
1011 "mls\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
1012 [(set_attr "type" "neon_mla_<Vetype><q>")]
1015 (define_insn "*aarch64_mls_elt<mode>"
1016 [(set (match_operand:VDQHS 0 "register_operand" "=w")
1018 (match_operand:VDQHS 4 "register_operand" "0")
1020 (vec_duplicate:VDQHS
1022 (match_operand:VDQHS 1 "register_operand" "<h_con>")
1023 (parallel [(match_operand:SI 2 "immediate_operand")])))
1024 (match_operand:VDQHS 3 "register_operand" "w"))))]
1027 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
1028 return "mls\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1030 [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
1033 (define_insn "*aarch64_mls_elt_<vswap_width_name><mode>"
1034 [(set (match_operand:VDQHS 0 "register_operand" "=w")
1036 (match_operand:VDQHS 4 "register_operand" "0")
1038 (vec_duplicate:VDQHS
1040 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
1041 (parallel [(match_operand:SI 2 "immediate_operand")])))
1042 (match_operand:VDQHS 3 "register_operand" "w"))))]
1045 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
1046 INTVAL (operands[2])));
1047 return "mls\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1049 [(set_attr "type" "neon_mla_<Vetype>_scalar<q>")]
1052 ;; Max/Min operations.
1053 (define_insn "<su><maxmin><mode>3"
1054 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
1055 (MAXMIN:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")
1056 (match_operand:VDQ_BHSI 2 "register_operand" "w")))]
1058 "<su><maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1059 [(set_attr "type" "neon_minmax<q>")]
1062 (define_expand "<su><maxmin>v2di3"
1063 [(set (match_operand:V2DI 0 "register_operand" "")
1064 (MAXMIN:V2DI (match_operand:V2DI 1 "register_operand" "")
1065 (match_operand:V2DI 2 "register_operand" "")))]
1068 enum rtx_code cmp_operator;
1089 cmp_fmt = gen_rtx_fmt_ee (cmp_operator, V2DImode, operands[1], operands[2]);
1090 emit_insn (gen_aarch64_vcond_internalv2div2di (operands[0], operands[1],
1091 operands[2], cmp_fmt, operands[1], operands[2]));
1095 ;; Pairwise Integer Max/Min operations.
1096 (define_insn "aarch64_<maxmin_uns>p<mode>"
1097 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
1098 (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand" "w")
1099 (match_operand:VDQ_BHSI 2 "register_operand" "w")]
1102 "<maxmin_uns_op>p\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1103 [(set_attr "type" "neon_minmax<q>")]
1106 ;; Pairwise FP Max/Min operations.
1107 (define_insn "aarch64_<maxmin_uns>p<mode>"
1108 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1109 (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")
1110 (match_operand:VHSDF 2 "register_operand" "w")]
1113 "<maxmin_uns_op>p\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1114 [(set_attr "type" "neon_minmax<q>")]
1117 ;; vec_concat gives a new vector with the low elements from operand 1, and
1118 ;; the high elements from operand 2. That is to say, given op1 = { a, b }
1119 ;; op2 = { c, d }, vec_concat (op1, op2) = { a, b, c, d }.
1120 ;; What that means, is that the RTL descriptions of the below patterns
1121 ;; need to change depending on endianness.
1123 ;; Move to the low architectural bits of the register.
1124 ;; On little-endian this is { operand, zeroes }
1125 ;; On big-endian this is { zeroes, operand }
1127 (define_insn "move_lo_quad_internal_<mode>"
1128 [(set (match_operand:VQ_NO2E 0 "register_operand" "=w,w,w")
1130 (match_operand:<VHALF> 1 "register_operand" "w,r,r")
1131 (vec_duplicate:<VHALF> (const_int 0))))]
1132 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
1137 [(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
1138 (set_attr "simd" "yes,*,yes")
1139 (set_attr "fp" "*,yes,*")
1140 (set_attr "length" "4")]
1143 (define_insn "move_lo_quad_internal_<mode>"
1144 [(set (match_operand:VQ_2E 0 "register_operand" "=w,w,w")
1146 (match_operand:<VHALF> 1 "register_operand" "w,r,r")
1148 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
1153 [(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
1154 (set_attr "simd" "yes,*,yes")
1155 (set_attr "fp" "*,yes,*")
1156 (set_attr "length" "4")]
1159 (define_insn "move_lo_quad_internal_be_<mode>"
1160 [(set (match_operand:VQ_NO2E 0 "register_operand" "=w,w,w")
1162 (vec_duplicate:<VHALF> (const_int 0))
1163 (match_operand:<VHALF> 1 "register_operand" "w,r,r")))]
1164 "TARGET_SIMD && BYTES_BIG_ENDIAN"
1169 [(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
1170 (set_attr "simd" "yes,*,yes")
1171 (set_attr "fp" "*,yes,*")
1172 (set_attr "length" "4")]
1175 (define_insn "move_lo_quad_internal_be_<mode>"
1176 [(set (match_operand:VQ_2E 0 "register_operand" "=w,w,w")
1179 (match_operand:<VHALF> 1 "register_operand" "w,r,r")))]
1180 "TARGET_SIMD && BYTES_BIG_ENDIAN"
1185 [(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
1186 (set_attr "simd" "yes,*,yes")
1187 (set_attr "fp" "*,yes,*")
1188 (set_attr "length" "4")]
1191 (define_expand "move_lo_quad_<mode>"
1192 [(match_operand:VQ 0 "register_operand")
1193 (match_operand:VQ 1 "register_operand")]
1196 if (BYTES_BIG_ENDIAN)
1197 emit_insn (gen_move_lo_quad_internal_be_<mode> (operands[0], operands[1]));
1199 emit_insn (gen_move_lo_quad_internal_<mode> (operands[0], operands[1]));
1204 ;; Move operand1 to the high architectural bits of the register, keeping
1205 ;; the low architectural bits of operand2.
1206 ;; For little-endian this is { operand2, operand1 }
1207 ;; For big-endian this is { operand1, operand2 }
1209 (define_insn "aarch64_simd_move_hi_quad_<mode>"
1210 [(set (match_operand:VQ 0 "register_operand" "+w,w")
1214 (match_operand:VQ 2 "vect_par_cnst_lo_half" ""))
1215 (match_operand:<VHALF> 1 "register_operand" "w,r")))]
1216 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
1218 ins\\t%0.d[1], %1.d[0]
1220 [(set_attr "type" "neon_ins")]
1223 (define_insn "aarch64_simd_move_hi_quad_be_<mode>"
1224 [(set (match_operand:VQ 0 "register_operand" "+w,w")
1226 (match_operand:<VHALF> 1 "register_operand" "w,r")
1229 (match_operand:VQ 2 "vect_par_cnst_lo_half" ""))))]
1230 "TARGET_SIMD && BYTES_BIG_ENDIAN"
1232 ins\\t%0.d[1], %1.d[0]
1234 [(set_attr "type" "neon_ins")]
1237 (define_expand "move_hi_quad_<mode>"
1238 [(match_operand:VQ 0 "register_operand" "")
1239 (match_operand:<VHALF> 1 "register_operand" "")]
1242 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1243 if (BYTES_BIG_ENDIAN)
1244 emit_insn (gen_aarch64_simd_move_hi_quad_be_<mode> (operands[0],
1247 emit_insn (gen_aarch64_simd_move_hi_quad_<mode> (operands[0],
1252 ;; Narrowing operations.
1255 (define_insn "aarch64_simd_vec_pack_trunc_<mode>"
1256 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
1257 (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w")))]
1259 "xtn\\t%0.<Vntype>, %1.<Vtype>"
1260 [(set_attr "type" "neon_shift_imm_narrow_q")]
1263 (define_expand "vec_pack_trunc_<mode>"
1264 [(match_operand:<VNARROWD> 0 "register_operand" "")
1265 (match_operand:VDN 1 "register_operand" "")
1266 (match_operand:VDN 2 "register_operand" "")]
1269 rtx tempreg = gen_reg_rtx (<VDBL>mode);
1270 int lo = BYTES_BIG_ENDIAN ? 2 : 1;
1271 int hi = BYTES_BIG_ENDIAN ? 1 : 2;
1273 emit_insn (gen_move_lo_quad_<Vdbl> (tempreg, operands[lo]));
1274 emit_insn (gen_move_hi_quad_<Vdbl> (tempreg, operands[hi]));
1275 emit_insn (gen_aarch64_simd_vec_pack_trunc_<Vdbl> (operands[0], tempreg));
1281 (define_insn "vec_pack_trunc_<mode>"
1282 [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=&w")
1283 (vec_concat:<VNARROWQ2>
1284 (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w"))
1285 (truncate:<VNARROWQ> (match_operand:VQN 2 "register_operand" "w"))))]
1288 if (BYTES_BIG_ENDIAN)
1289 return "xtn\\t%0.<Vntype>, %2.<Vtype>\;xtn2\\t%0.<V2ntype>, %1.<Vtype>";
1291 return "xtn\\t%0.<Vntype>, %1.<Vtype>\;xtn2\\t%0.<V2ntype>, %2.<Vtype>";
1293 [(set_attr "type" "multiple")
1294 (set_attr "length" "8")]
1297 ;; Widening operations.
1299 (define_insn "aarch64_simd_vec_unpack<su>_lo_<mode>"
1300 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1301 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1302 (match_operand:VQW 1 "register_operand" "w")
1303 (match_operand:VQW 2 "vect_par_cnst_lo_half" "")
1306 "<su>shll\t%0.<Vwtype>, %1.<Vhalftype>, 0"
1307 [(set_attr "type" "neon_shift_imm_long")]
1310 (define_insn "aarch64_simd_vec_unpack<su>_hi_<mode>"
1311 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1312 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1313 (match_operand:VQW 1 "register_operand" "w")
1314 (match_operand:VQW 2 "vect_par_cnst_hi_half" "")
1317 "<su>shll2\t%0.<Vwtype>, %1.<Vtype>, 0"
1318 [(set_attr "type" "neon_shift_imm_long")]
1321 (define_expand "vec_unpack<su>_hi_<mode>"
1322 [(match_operand:<VWIDE> 0 "register_operand" "")
1323 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))]
1326 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
1327 emit_insn (gen_aarch64_simd_vec_unpack<su>_hi_<mode> (operands[0],
1333 (define_expand "vec_unpack<su>_lo_<mode>"
1334 [(match_operand:<VWIDE> 0 "register_operand" "")
1335 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))]
1338 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1339 emit_insn (gen_aarch64_simd_vec_unpack<su>_lo_<mode> (operands[0],
1345 ;; Widening arithmetic.
1347 (define_insn "*aarch64_<su>mlal_lo<mode>"
1348 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1351 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1352 (match_operand:VQW 2 "register_operand" "w")
1353 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
1354 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1355 (match_operand:VQW 4 "register_operand" "w")
1357 (match_operand:<VWIDE> 1 "register_operand" "0")))]
1359 "<su>mlal\t%0.<Vwtype>, %2.<Vhalftype>, %4.<Vhalftype>"
1360 [(set_attr "type" "neon_mla_<Vetype>_long")]
1363 (define_insn "*aarch64_<su>mlal_hi<mode>"
1364 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1367 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1368 (match_operand:VQW 2 "register_operand" "w")
1369 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
1370 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1371 (match_operand:VQW 4 "register_operand" "w")
1373 (match_operand:<VWIDE> 1 "register_operand" "0")))]
1375 "<su>mlal2\t%0.<Vwtype>, %2.<Vtype>, %4.<Vtype>"
1376 [(set_attr "type" "neon_mla_<Vetype>_long")]
1379 (define_insn "*aarch64_<su>mlsl_lo<mode>"
1380 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1382 (match_operand:<VWIDE> 1 "register_operand" "0")
1384 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1385 (match_operand:VQW 2 "register_operand" "w")
1386 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
1387 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1388 (match_operand:VQW 4 "register_operand" "w")
1391 "<su>mlsl\t%0.<Vwtype>, %2.<Vhalftype>, %4.<Vhalftype>"
1392 [(set_attr "type" "neon_mla_<Vetype>_long")]
1395 (define_insn "*aarch64_<su>mlsl_hi<mode>"
1396 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1398 (match_operand:<VWIDE> 1 "register_operand" "0")
1400 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1401 (match_operand:VQW 2 "register_operand" "w")
1402 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
1403 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1404 (match_operand:VQW 4 "register_operand" "w")
1407 "<su>mlsl2\t%0.<Vwtype>, %2.<Vtype>, %4.<Vtype>"
1408 [(set_attr "type" "neon_mla_<Vetype>_long")]
1411 (define_insn "*aarch64_<su>mlal<mode>"
1412 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1416 (match_operand:VD_BHSI 1 "register_operand" "w"))
1418 (match_operand:VD_BHSI 2 "register_operand" "w")))
1419 (match_operand:<VWIDE> 3 "register_operand" "0")))]
1421 "<su>mlal\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
1422 [(set_attr "type" "neon_mla_<Vetype>_long")]
1425 (define_insn "*aarch64_<su>mlsl<mode>"
1426 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1428 (match_operand:<VWIDE> 1 "register_operand" "0")
1431 (match_operand:VD_BHSI 2 "register_operand" "w"))
1433 (match_operand:VD_BHSI 3 "register_operand" "w")))))]
1435 "<su>mlsl\t%0.<Vwtype>, %2.<Vtype>, %3.<Vtype>"
1436 [(set_attr "type" "neon_mla_<Vetype>_long")]
1439 (define_insn "aarch64_simd_vec_<su>mult_lo_<mode>"
1440 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1441 (mult:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1442 (match_operand:VQW 1 "register_operand" "w")
1443 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
1444 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1445 (match_operand:VQW 2 "register_operand" "w")
1448 "<su>mull\\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
1449 [(set_attr "type" "neon_mul_<Vetype>_long")]
1452 (define_expand "vec_widen_<su>mult_lo_<mode>"
1453 [(match_operand:<VWIDE> 0 "register_operand" "")
1454 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
1455 (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
1458 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1459 emit_insn (gen_aarch64_simd_vec_<su>mult_lo_<mode> (operands[0],
1466 (define_insn "aarch64_simd_vec_<su>mult_hi_<mode>"
1467 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1468 (mult:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1469 (match_operand:VQW 1 "register_operand" "w")
1470 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
1471 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1472 (match_operand:VQW 2 "register_operand" "w")
1475 "<su>mull2\\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
1476 [(set_attr "type" "neon_mul_<Vetype>_long")]
1479 (define_expand "vec_widen_<su>mult_hi_<mode>"
1480 [(match_operand:<VWIDE> 0 "register_operand" "")
1481 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
1482 (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
1485 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
1486 emit_insn (gen_aarch64_simd_vec_<su>mult_hi_<mode> (operands[0],
1494 ;; FP vector operations.
1495 ;; AArch64 AdvSIMD supports single-precision (32-bit) and
1496 ;; double-precision (64-bit) floating-point data types and arithmetic as
1497 ;; defined by the IEEE 754-2008 standard. This makes them vectorizable
1498 ;; without the need for -ffast-math or -funsafe-math-optimizations.
1500 ;; Floating-point operations can raise an exception. Vectorizing such
1501 ;; operations are safe because of reasons explained below.
1503 ;; ARMv8 permits an extension to enable trapped floating-point
1504 ;; exception handling, however this is an optional feature. In the
1505 ;; event of a floating-point exception being raised by vectorised
1507 ;; 1. If trapped floating-point exceptions are available, then a trap
1508 ;; will be taken when any lane raises an enabled exception. A trap
1509 ;; handler may determine which lane raised the exception.
1510 ;; 2. Alternatively a sticky exception flag is set in the
1511 ;; floating-point status register (FPSR). Software may explicitly
1512 ;; test the exception flags, in which case the tests will either
1513 ;; prevent vectorisation, allowing precise identification of the
1514 ;; failing operation, or if tested outside of vectorisable regions
1515 ;; then the specific operation and lane are not of interest.
1517 ;; FP arithmetic operations.
1519 (define_insn "add<mode>3"
1520 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1521 (plus:VHSDF (match_operand:VHSDF 1 "register_operand" "w")
1522 (match_operand:VHSDF 2 "register_operand" "w")))]
1524 "fadd\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1525 [(set_attr "type" "neon_fp_addsub_<stype><q>")]
1528 (define_insn "sub<mode>3"
1529 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1530 (minus:VHSDF (match_operand:VHSDF 1 "register_operand" "w")
1531 (match_operand:VHSDF 2 "register_operand" "w")))]
1533 "fsub\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1534 [(set_attr "type" "neon_fp_addsub_<stype><q>")]
1537 (define_insn "mul<mode>3"
1538 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1539 (mult:VHSDF (match_operand:VHSDF 1 "register_operand" "w")
1540 (match_operand:VHSDF 2 "register_operand" "w")))]
1542 "fmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1543 [(set_attr "type" "neon_fp_mul_<stype><q>")]
1546 (define_expand "div<mode>3"
1547 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1548 (div:VHSDF (match_operand:VHSDF 1 "register_operand" "w")
1549 (match_operand:VHSDF 2 "register_operand" "w")))]
1552 if (aarch64_emit_approx_div (operands[0], operands[1], operands[2]))
1555 operands[1] = force_reg (<MODE>mode, operands[1]);
1558 (define_insn "*div<mode>3"
1559 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1560 (div:VHSDF (match_operand:VHSDF 1 "register_operand" "w")
1561 (match_operand:VHSDF 2 "register_operand" "w")))]
1563 "fdiv\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1564 [(set_attr "type" "neon_fp_div_<stype><q>")]
1567 (define_insn "neg<mode>2"
1568 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1569 (neg:VHSDF (match_operand:VHSDF 1 "register_operand" "w")))]
1571 "fneg\\t%0.<Vtype>, %1.<Vtype>"
1572 [(set_attr "type" "neon_fp_neg_<stype><q>")]
1575 (define_insn "abs<mode>2"
1576 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1577 (abs:VHSDF (match_operand:VHSDF 1 "register_operand" "w")))]
1579 "fabs\\t%0.<Vtype>, %1.<Vtype>"
1580 [(set_attr "type" "neon_fp_abs_<stype><q>")]
1583 (define_insn "fma<mode>4"
1584 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1585 (fma:VHSDF (match_operand:VHSDF 1 "register_operand" "w")
1586 (match_operand:VHSDF 2 "register_operand" "w")
1587 (match_operand:VHSDF 3 "register_operand" "0")))]
1589 "fmla\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1590 [(set_attr "type" "neon_fp_mla_<stype><q>")]
1593 (define_insn "*aarch64_fma4_elt<mode>"
1594 [(set (match_operand:VDQF 0 "register_operand" "=w")
1598 (match_operand:VDQF 1 "register_operand" "<h_con>")
1599 (parallel [(match_operand:SI 2 "immediate_operand")])))
1600 (match_operand:VDQF 3 "register_operand" "w")
1601 (match_operand:VDQF 4 "register_operand" "0")))]
1604 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
1605 return "fmla\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1607 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1610 (define_insn "*aarch64_fma4_elt_<vswap_width_name><mode>"
1611 [(set (match_operand:VDQSF 0 "register_operand" "=w")
1613 (vec_duplicate:VDQSF
1615 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
1616 (parallel [(match_operand:SI 2 "immediate_operand")])))
1617 (match_operand:VDQSF 3 "register_operand" "w")
1618 (match_operand:VDQSF 4 "register_operand" "0")))]
1621 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
1622 INTVAL (operands[2])));
1623 return "fmla\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1625 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1628 (define_insn "*aarch64_fma4_elt_from_dup<mode>"
1629 [(set (match_operand:VMUL 0 "register_operand" "=w")
1632 (match_operand:<VEL> 1 "register_operand" "w"))
1633 (match_operand:VMUL 2 "register_operand" "w")
1634 (match_operand:VMUL 3 "register_operand" "0")))]
1636 "fmla\t%0.<Vtype>, %2.<Vtype>, %1.<Vetype>[0]"
1637 [(set_attr "type" "neon<fp>_mla_<stype>_scalar<q>")]
1640 (define_insn "*aarch64_fma4_elt_to_64v2df"
1641 [(set (match_operand:DF 0 "register_operand" "=w")
1644 (match_operand:V2DF 1 "register_operand" "w")
1645 (parallel [(match_operand:SI 2 "immediate_operand")]))
1646 (match_operand:DF 3 "register_operand" "w")
1647 (match_operand:DF 4 "register_operand" "0")))]
1650 operands[2] = GEN_INT (ENDIAN_LANE_N (V2DFmode, INTVAL (operands[2])));
1651 return "fmla\\t%0.2d, %3.2d, %1.2d[%2]";
1653 [(set_attr "type" "neon_fp_mla_d_scalar_q")]
1656 (define_insn "fnma<mode>4"
1657 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1659 (match_operand:VHSDF 1 "register_operand" "w")
1661 (match_operand:VHSDF 2 "register_operand" "w"))
1662 (match_operand:VHSDF 3 "register_operand" "0")))]
1664 "fmls\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1665 [(set_attr "type" "neon_fp_mla_<stype><q>")]
1668 (define_insn "*aarch64_fnma4_elt<mode>"
1669 [(set (match_operand:VDQF 0 "register_operand" "=w")
1672 (match_operand:VDQF 3 "register_operand" "w"))
1675 (match_operand:VDQF 1 "register_operand" "<h_con>")
1676 (parallel [(match_operand:SI 2 "immediate_operand")])))
1677 (match_operand:VDQF 4 "register_operand" "0")))]
1680 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
1681 return "fmls\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1683 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1686 (define_insn "*aarch64_fnma4_elt_<vswap_width_name><mode>"
1687 [(set (match_operand:VDQSF 0 "register_operand" "=w")
1690 (match_operand:VDQSF 3 "register_operand" "w"))
1691 (vec_duplicate:VDQSF
1693 (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>")
1694 (parallel [(match_operand:SI 2 "immediate_operand")])))
1695 (match_operand:VDQSF 4 "register_operand" "0")))]
1698 operands[2] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
1699 INTVAL (operands[2])));
1700 return "fmls\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]";
1702 [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
1705 (define_insn "*aarch64_fnma4_elt_from_dup<mode>"
1706 [(set (match_operand:VMUL 0 "register_operand" "=w")
1709 (match_operand:VMUL 2 "register_operand" "w"))
1711 (match_operand:<VEL> 1 "register_operand" "w"))
1712 (match_operand:VMUL 3 "register_operand" "0")))]
1714 "fmls\t%0.<Vtype>, %2.<Vtype>, %1.<Vetype>[0]"
1715 [(set_attr "type" "neon<fp>_mla_<stype>_scalar<q>")]
1718 (define_insn "*aarch64_fnma4_elt_to_64v2df"
1719 [(set (match_operand:DF 0 "register_operand" "=w")
1722 (match_operand:V2DF 1 "register_operand" "w")
1723 (parallel [(match_operand:SI 2 "immediate_operand")]))
1725 (match_operand:DF 3 "register_operand" "w"))
1726 (match_operand:DF 4 "register_operand" "0")))]
1729 operands[2] = GEN_INT (ENDIAN_LANE_N (V2DFmode, INTVAL (operands[2])));
1730 return "fmls\\t%0.2d, %3.2d, %1.2d[%2]";
1732 [(set_attr "type" "neon_fp_mla_d_scalar_q")]
1735 ;; Vector versions of the floating-point frint patterns.
1736 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
1737 (define_insn "<frint_pattern><mode>2"
1738 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1739 (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")]
1742 "frint<frint_suffix>\\t%0.<Vtype>, %1.<Vtype>"
1743 [(set_attr "type" "neon_fp_round_<stype><q>")]
1746 ;; Vector versions of the fcvt standard patterns.
1747 ;; Expands to lbtrunc, lround, lceil, lfloor
1748 (define_insn "l<fcvt_pattern><su_optab><VHSDF:mode><fcvt_target>2"
1749 [(set (match_operand:<FCVT_TARGET> 0 "register_operand" "=w")
1750 (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
1751 [(match_operand:VHSDF 1 "register_operand" "w")]
1754 "fcvt<frint_suffix><su>\\t%0.<Vtype>, %1.<Vtype>"
1755 [(set_attr "type" "neon_fp_to_int_<stype><q>")]
1758 (define_insn "*aarch64_fcvt<su_optab><VDQF:mode><fcvt_target>2_mult"
1759 [(set (match_operand:<FCVT_TARGET> 0 "register_operand" "=w")
1760 (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
1762 (match_operand:VDQF 1 "register_operand" "w")
1763 (match_operand:VDQF 2 "aarch64_fp_vec_pow2" ""))]
1766 && IN_RANGE (aarch64_vec_fpconst_pow_of_2 (operands[2]), 1,
1767 GET_MODE_BITSIZE (GET_MODE_INNER (<VDQF:MODE>mode)))"
1769 int fbits = aarch64_vec_fpconst_pow_of_2 (operands[2]);
1771 snprintf (buf, 64, "fcvtz<su>\\t%%0.<Vtype>, %%1.<Vtype>, #%d", fbits);
1772 output_asm_insn (buf, operands);
1775 [(set_attr "type" "neon_fp_to_int_<Vetype><q>")]
1778 (define_expand "<optab><VHSDF:mode><fcvt_target>2"
1779 [(set (match_operand:<FCVT_TARGET> 0 "register_operand")
1780 (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
1781 [(match_operand:VHSDF 1 "register_operand")]
1786 (define_expand "<fix_trunc_optab><VHSDF:mode><fcvt_target>2"
1787 [(set (match_operand:<FCVT_TARGET> 0 "register_operand")
1788 (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
1789 [(match_operand:VHSDF 1 "register_operand")]
1794 (define_expand "ftrunc<VHSDF:mode>2"
1795 [(set (match_operand:VHSDF 0 "register_operand")
1796 (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand")]
1801 (define_insn "<optab><fcvt_target><VHSDF:mode>2"
1802 [(set (match_operand:VHSDF 0 "register_operand" "=w")
1804 (match_operand:<FCVT_TARGET> 1 "register_operand" "w")))]
1806 "<su_optab>cvtf\\t%0.<Vtype>, %1.<Vtype>"
1807 [(set_attr "type" "neon_int_to_fp_<stype><q>")]
1810 ;; Conversions between vectors of floats and doubles.
1811 ;; Contains a mix of patterns to match standard pattern names
1812 ;; and those for intrinsics.
1814 ;; Float widening operations.
1816 (define_insn "aarch64_simd_vec_unpacks_lo_<mode>"
1817 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1818 (float_extend:<VWIDE> (vec_select:<VHALF>
1819 (match_operand:VQ_HSF 1 "register_operand" "w")
1820 (match_operand:VQ_HSF 2 "vect_par_cnst_lo_half" "")
1823 "fcvtl\\t%0.<Vwtype>, %1.<Vhalftype>"
1824 [(set_attr "type" "neon_fp_cvt_widen_s")]
1827 ;; Convert between fixed-point and floating-point (vector modes)
1829 (define_insn "<FCVT_F2FIXED:fcvt_fixed_insn><VHSDF:mode>3"
1830 [(set (match_operand:<VHSDF:FCVT_TARGET> 0 "register_operand" "=w")
1831 (unspec:<VHSDF:FCVT_TARGET>
1832 [(match_operand:VHSDF 1 "register_operand" "w")
1833 (match_operand:SI 2 "immediate_operand" "i")]
1836 "<FCVT_F2FIXED:fcvt_fixed_insn>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #%2"
1837 [(set_attr "type" "neon_fp_to_int_<VHSDF:stype><q>")]
1840 (define_insn "<FCVT_FIXED2F:fcvt_fixed_insn><VDQ_HSDI:mode>3"
1841 [(set (match_operand:<VDQ_HSDI:FCVT_TARGET> 0 "register_operand" "=w")
1842 (unspec:<VDQ_HSDI:FCVT_TARGET>
1843 [(match_operand:VDQ_HSDI 1 "register_operand" "w")
1844 (match_operand:SI 2 "immediate_operand" "i")]
1847 "<FCVT_FIXED2F:fcvt_fixed_insn>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #%2"
1848 [(set_attr "type" "neon_int_to_fp_<VDQ_HSDI:stype><q>")]
1851 ;; ??? Note that the vectorizer usage of the vec_unpacks_[lo/hi] patterns
1852 ;; is inconsistent with vector ordering elsewhere in the compiler, in that
1853 ;; the meaning of HI and LO changes depending on the target endianness.
1854 ;; While elsewhere we map the higher numbered elements of a vector to
1855 ;; the lower architectural lanes of the vector, for these patterns we want
1856 ;; to always treat "hi" as referring to the higher architectural lanes.
1857 ;; Consequently, while the patterns below look inconsistent with our
1858 ;; other big-endian patterns their behavior is as required.
1860 (define_expand "vec_unpacks_lo_<mode>"
1861 [(match_operand:<VWIDE> 0 "register_operand" "")
1862 (match_operand:VQ_HSF 1 "register_operand" "")]
1865 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1866 emit_insn (gen_aarch64_simd_vec_unpacks_lo_<mode> (operands[0],
1872 (define_insn "aarch64_simd_vec_unpacks_hi_<mode>"
1873 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1874 (float_extend:<VWIDE> (vec_select:<VHALF>
1875 (match_operand:VQ_HSF 1 "register_operand" "w")
1876 (match_operand:VQ_HSF 2 "vect_par_cnst_hi_half" "")
1879 "fcvtl2\\t%0.<Vwtype>, %1.<Vtype>"
1880 [(set_attr "type" "neon_fp_cvt_widen_s")]
1883 (define_expand "vec_unpacks_hi_<mode>"
1884 [(match_operand:<VWIDE> 0 "register_operand" "")
1885 (match_operand:VQ_HSF 1 "register_operand" "")]
1888 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
1889 emit_insn (gen_aarch64_simd_vec_unpacks_lo_<mode> (operands[0],
1894 (define_insn "aarch64_float_extend_lo_<Vwide>"
1895 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1896 (float_extend:<VWIDE>
1897 (match_operand:VDF 1 "register_operand" "w")))]
1899 "fcvtl\\t%0<Vmwtype>, %1<Vmtype>"
1900 [(set_attr "type" "neon_fp_cvt_widen_s")]
1903 ;; Float narrowing operations.
1905 (define_insn "aarch64_float_truncate_lo_<mode>"
1906 [(set (match_operand:VDF 0 "register_operand" "=w")
1908 (match_operand:<VWIDE> 1 "register_operand" "w")))]
1910 "fcvtn\\t%0.<Vtype>, %1<Vmwtype>"
1911 [(set_attr "type" "neon_fp_cvt_narrow_d_q")]
1914 (define_insn "aarch64_float_truncate_hi_<Vdbl>_le"
1915 [(set (match_operand:<VDBL> 0 "register_operand" "=w")
1917 (match_operand:VDF 1 "register_operand" "0")
1919 (match_operand:<VWIDE> 2 "register_operand" "w"))))]
1920 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
1921 "fcvtn2\\t%0.<Vdtype>, %2<Vmwtype>"
1922 [(set_attr "type" "neon_fp_cvt_narrow_d_q")]
1925 (define_insn "aarch64_float_truncate_hi_<Vdbl>_be"
1926 [(set (match_operand:<VDBL> 0 "register_operand" "=w")
1929 (match_operand:<VWIDE> 2 "register_operand" "w"))
1930 (match_operand:VDF 1 "register_operand" "0")))]
1931 "TARGET_SIMD && BYTES_BIG_ENDIAN"
1932 "fcvtn2\\t%0.<Vdtype>, %2<Vmwtype>"
1933 [(set_attr "type" "neon_fp_cvt_narrow_d_q")]
1936 (define_expand "aarch64_float_truncate_hi_<Vdbl>"
1937 [(match_operand:<VDBL> 0 "register_operand" "=w")
1938 (match_operand:VDF 1 "register_operand" "0")
1939 (match_operand:<VWIDE> 2 "register_operand" "w")]
1942 rtx (*gen) (rtx, rtx, rtx) = BYTES_BIG_ENDIAN
1943 ? gen_aarch64_float_truncate_hi_<Vdbl>_be
1944 : gen_aarch64_float_truncate_hi_<Vdbl>_le;
1945 emit_insn (gen (operands[0], operands[1], operands[2]));
1950 (define_expand "vec_pack_trunc_v2df"
1951 [(set (match_operand:V4SF 0 "register_operand")
1953 (float_truncate:V2SF
1954 (match_operand:V2DF 1 "register_operand"))
1955 (float_truncate:V2SF
1956 (match_operand:V2DF 2 "register_operand"))
1960 rtx tmp = gen_reg_rtx (V2SFmode);
1961 int lo = BYTES_BIG_ENDIAN ? 2 : 1;
1962 int hi = BYTES_BIG_ENDIAN ? 1 : 2;
1964 emit_insn (gen_aarch64_float_truncate_lo_v2sf (tmp, operands[lo]));
1965 emit_insn (gen_aarch64_float_truncate_hi_v4sf (operands[0],
1966 tmp, operands[hi]));
1971 (define_expand "vec_pack_trunc_df"
1972 [(set (match_operand:V2SF 0 "register_operand")
1975 (match_operand:DF 1 "register_operand"))
1977 (match_operand:DF 2 "register_operand"))
1981 rtx tmp = gen_reg_rtx (V2SFmode);
1982 int lo = BYTES_BIG_ENDIAN ? 2 : 1;
1983 int hi = BYTES_BIG_ENDIAN ? 1 : 2;
1985 emit_insn (gen_move_lo_quad_v2df (tmp, operands[lo]));
1986 emit_insn (gen_move_hi_quad_v2df (tmp, operands[hi]));
1987 emit_insn (gen_aarch64_float_truncate_lo_v2sf (operands[0], tmp));
1993 ;; Max/Min are introduced by idiom recognition by GCC's mid-end. An
1995 ;; a = (b < c) ? b : c;
1996 ;; is idiom-matched as MIN_EXPR<b,c> only if -ffinite-math-only is enabled
1997 ;; either explicitly or indirectly via -ffast-math.
1999 ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
2000 ;; The 'smax' and 'smin' RTL standard pattern names do not specify which
2001 ;; operand will be returned when both operands are zero (i.e. they may not
2002 ;; honour signed zeroes), or when either operand is NaN. Therefore GCC
2003 ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
2006 (define_insn "<su><maxmin><mode>3"
2007 [(set (match_operand:VHSDF 0 "register_operand" "=w")
2008 (FMAXMIN:VHSDF (match_operand:VHSDF 1 "register_operand" "w")
2009 (match_operand:VHSDF 2 "register_operand" "w")))]
2011 "f<maxmin>nm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2012 [(set_attr "type" "neon_fp_minmax_<stype><q>")]
2015 (define_insn "<maxmin_uns><mode>3"
2016 [(set (match_operand:VHSDF 0 "register_operand" "=w")
2017 (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")
2018 (match_operand:VHSDF 2 "register_operand" "w")]
2021 "<maxmin_uns_op>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2022 [(set_attr "type" "neon_fp_minmax_<stype><q>")]
2025 ;; Auto-vectorized forms for the IEEE-754 fmax()/fmin() functions
2026 (define_insn "<fmaxmin><mode>3"
2027 [(set (match_operand:VHSDF 0 "register_operand" "=w")
2028 (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")
2029 (match_operand:VHSDF 2 "register_operand" "w")]
2032 "<fmaxmin_op>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2033 [(set_attr "type" "neon_fp_minmax_<stype><q>")]
2036 ;; 'across lanes' add.
2038 (define_expand "reduc_plus_scal_<mode>"
2039 [(match_operand:<VEL> 0 "register_operand" "=w")
2040 (unspec:VDQ_I [(match_operand:VDQ_I 1 "register_operand" "w")]
2044 rtx elt = GEN_INT (ENDIAN_LANE_N (<MODE>mode, 0));
2045 rtx scratch = gen_reg_rtx (<MODE>mode);
2046 emit_insn (gen_aarch64_reduc_plus_internal<mode> (scratch, operands[1]));
2047 emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
2052 (define_insn "aarch64_faddp<mode>"
2053 [(set (match_operand:VHSDF 0 "register_operand" "=w")
2054 (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")
2055 (match_operand:VHSDF 2 "register_operand" "w")]
2058 "faddp\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2059 [(set_attr "type" "neon_fp_reduc_add_<stype><q>")]
2062 (define_insn "aarch64_reduc_plus_internal<mode>"
2063 [(set (match_operand:VDQV 0 "register_operand" "=w")
2064 (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
2067 "add<VDQV:vp>\\t%<Vetype>0, %1.<Vtype>"
2068 [(set_attr "type" "neon_reduc_add<q>")]
2071 (define_insn "aarch64_reduc_plus_internalv2si"
2072 [(set (match_operand:V2SI 0 "register_operand" "=w")
2073 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
2076 "addp\\t%0.2s, %1.2s, %1.2s"
2077 [(set_attr "type" "neon_reduc_add")]
2080 (define_insn "reduc_plus_scal_<mode>"
2081 [(set (match_operand:<VEL> 0 "register_operand" "=w")
2082 (unspec:<VEL> [(match_operand:V2F 1 "register_operand" "w")]
2085 "faddp\\t%<Vetype>0, %1.<Vtype>"
2086 [(set_attr "type" "neon_fp_reduc_add_<Vetype><q>")]
2089 (define_expand "reduc_plus_scal_v4sf"
2090 [(set (match_operand:SF 0 "register_operand")
2091 (unspec:V4SF [(match_operand:V4SF 1 "register_operand")]
2095 rtx elt = GEN_INT (ENDIAN_LANE_N (V4SFmode, 0));
2096 rtx scratch = gen_reg_rtx (V4SFmode);
2097 emit_insn (gen_aarch64_faddpv4sf (scratch, operands[1], operands[1]));
2098 emit_insn (gen_aarch64_faddpv4sf (scratch, scratch, scratch));
2099 emit_insn (gen_aarch64_get_lanev4sf (operands[0], scratch, elt));
2103 (define_insn "clrsb<mode>2"
2104 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
2105 (clrsb:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")))]
2107 "cls\\t%0.<Vtype>, %1.<Vtype>"
2108 [(set_attr "type" "neon_cls<q>")]
2111 (define_insn "clz<mode>2"
2112 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
2113 (clz:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")))]
2115 "clz\\t%0.<Vtype>, %1.<Vtype>"
2116 [(set_attr "type" "neon_cls<q>")]
2119 (define_insn "popcount<mode>2"
2120 [(set (match_operand:VB 0 "register_operand" "=w")
2121 (popcount:VB (match_operand:VB 1 "register_operand" "w")))]
2123 "cnt\\t%0.<Vbtype>, %1.<Vbtype>"
2124 [(set_attr "type" "neon_cnt<q>")]
2127 ;; 'across lanes' max and min ops.
2129 ;; Template for outputting a scalar, so we can create __builtins which can be
2130 ;; gimple_fold'd to the REDUC_(MAX|MIN)_EXPR tree code. (This is FP smax/smin).
2131 (define_expand "reduc_<maxmin_uns>_scal_<mode>"
2132 [(match_operand:<VEL> 0 "register_operand")
2133 (unspec:VDQF [(match_operand:VDQF 1 "register_operand")]
2137 rtx elt = GEN_INT (ENDIAN_LANE_N (<MODE>mode, 0));
2138 rtx scratch = gen_reg_rtx (<MODE>mode);
2139 emit_insn (gen_aarch64_reduc_<maxmin_uns>_internal<mode> (scratch,
2141 emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
2146 ;; Likewise for integer cases, signed and unsigned.
2147 (define_expand "reduc_<maxmin_uns>_scal_<mode>"
2148 [(match_operand:<VEL> 0 "register_operand")
2149 (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand")]
2153 rtx elt = GEN_INT (ENDIAN_LANE_N (<MODE>mode, 0));
2154 rtx scratch = gen_reg_rtx (<MODE>mode);
2155 emit_insn (gen_aarch64_reduc_<maxmin_uns>_internal<mode> (scratch,
2157 emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
2162 (define_insn "aarch64_reduc_<maxmin_uns>_internal<mode>"
2163 [(set (match_operand:VDQV_S 0 "register_operand" "=w")
2164 (unspec:VDQV_S [(match_operand:VDQV_S 1 "register_operand" "w")]
2167 "<maxmin_uns_op>v\\t%<Vetype>0, %1.<Vtype>"
2168 [(set_attr "type" "neon_reduc_minmax<q>")]
2171 (define_insn "aarch64_reduc_<maxmin_uns>_internalv2si"
2172 [(set (match_operand:V2SI 0 "register_operand" "=w")
2173 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
2176 "<maxmin_uns_op>p\\t%0.2s, %1.2s, %1.2s"
2177 [(set_attr "type" "neon_reduc_minmax")]
2180 (define_insn "aarch64_reduc_<maxmin_uns>_internal<mode>"
2181 [(set (match_operand:VDQF 0 "register_operand" "=w")
2182 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")]
2185 "<maxmin_uns_op><vp>\\t%<Vetype>0, %1.<Vtype>"
2186 [(set_attr "type" "neon_fp_reduc_minmax_<Vetype><q>")]
2189 ;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register
2191 ;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which
2194 ;; Thus our BSL is of the form:
2195 ;; op0 = bsl (mask, op2, op3)
2196 ;; We can use any of:
2199 ;; bsl mask, op1, op2
2200 ;; if (op0 = op1) (so 1-bits in mask choose bits from op2, else op0)
2201 ;; bit op0, op2, mask
2202 ;; if (op0 = op2) (so 0-bits in mask choose bits from op1, else op0)
2203 ;; bif op0, op1, mask
2205 ;; This pattern is expanded to by the aarch64_simd_bsl<mode> expander.
2206 ;; Some forms of straight-line code may generate the equivalent form
2207 ;; in *aarch64_simd_bsl<mode>_alt.
2209 (define_insn "aarch64_simd_bsl<mode>_internal"
2210 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w,w,w")
2214 (match_operand:<V_cmp_result> 3 "register_operand" "w,0,w")
2215 (match_operand:VSDQ_I_DI 2 "register_operand" "w,w,0"))
2216 (match_operand:VSDQ_I_DI 1 "register_operand" "0,w,w"))
2217 (match_dup:<V_cmp_result> 3)
2221 bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
2222 bit\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
2223 bif\\t%0.<Vbtype>, %3.<Vbtype>, %1.<Vbtype>"
2224 [(set_attr "type" "neon_bsl<q>")]
2227 ;; We need this form in addition to the above pattern to match the case
2228 ;; when combine tries merging three insns such that the second operand of
2229 ;; the outer XOR matches the second operand of the inner XOR rather than
2230 ;; the first. The two are equivalent but since recog doesn't try all
2231 ;; permutations of commutative operations, we have to have a separate pattern.
2233 (define_insn "*aarch64_simd_bsl<mode>_alt"
2234 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w,w,w")
2238 (match_operand:VSDQ_I_DI 3 "register_operand" "w,w,0")
2239 (match_operand:VSDQ_I_DI 2 "register_operand" "w,0,w"))
2240 (match_operand:VSDQ_I_DI 1 "register_operand" "0,w,w"))
2241 (match_dup:VSDQ_I_DI 2)))]
2244 bsl\\t%0.<Vbtype>, %3.<Vbtype>, %2.<Vbtype>
2245 bit\\t%0.<Vbtype>, %3.<Vbtype>, %1.<Vbtype>
2246 bif\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
2247 [(set_attr "type" "neon_bsl<q>")]
2250 (define_expand "aarch64_simd_bsl<mode>"
2251 [(match_operand:VALLDIF 0 "register_operand")
2252 (match_operand:<V_cmp_result> 1 "register_operand")
2253 (match_operand:VALLDIF 2 "register_operand")
2254 (match_operand:VALLDIF 3 "register_operand")]
2257 /* We can't alias operands together if they have different modes. */
2258 rtx tmp = operands[0];
2259 if (FLOAT_MODE_P (<MODE>mode))
2261 operands[2] = gen_lowpart (<V_cmp_result>mode, operands[2]);
2262 operands[3] = gen_lowpart (<V_cmp_result>mode, operands[3]);
2263 tmp = gen_reg_rtx (<V_cmp_result>mode);
2265 operands[1] = gen_lowpart (<V_cmp_result>mode, operands[1]);
2266 emit_insn (gen_aarch64_simd_bsl<v_cmp_result>_internal (tmp,
2270 if (tmp != operands[0])
2271 emit_move_insn (operands[0], gen_lowpart (<MODE>mode, tmp));
2276 (define_expand "aarch64_vcond_internal<mode><mode>"
2277 [(set (match_operand:VSDQ_I_DI 0 "register_operand")
2278 (if_then_else:VSDQ_I_DI
2279 (match_operator 3 "comparison_operator"
2280 [(match_operand:VSDQ_I_DI 4 "register_operand")
2281 (match_operand:VSDQ_I_DI 5 "nonmemory_operand")])
2282 (match_operand:VSDQ_I_DI 1 "nonmemory_operand")
2283 (match_operand:VSDQ_I_DI 2 "nonmemory_operand")))]
2286 rtx op1 = operands[1];
2287 rtx op2 = operands[2];
2288 rtx mask = gen_reg_rtx (<MODE>mode);
2289 enum rtx_code code = GET_CODE (operands[3]);
2291 /* Switching OP1 and OP2 is necessary for NE (to output a cmeq insn),
2292 and desirable for other comparisons if it results in FOO ? -1 : 0
2293 (this allows direct use of the comparison result without a bsl). */
2296 && op1 == CONST0_RTX (<V_cmp_result>mode)
2297 && op2 == CONSTM1_RTX (<V_cmp_result>mode)))
2303 case LE: code = GT; break;
2304 case LT: code = GE; break;
2305 case GE: code = LT; break;
2306 case GT: code = LE; break;
2308 case NE: code = EQ; break;
2309 case LTU: code = GEU; break;
2310 case LEU: code = GTU; break;
2311 case GTU: code = LEU; break;
2312 case GEU: code = LTU; break;
2313 default: gcc_unreachable ();
2317 /* Make sure we can handle the last operand. */
2321 /* Normalized to EQ above. */
2329 /* These instructions have a form taking an immediate zero. */
2330 if (operands[5] == CONST0_RTX (<MODE>mode))
2332 /* Fall through, as may need to load into register. */
2334 if (!REG_P (operands[5]))
2335 operands[5] = force_reg (<MODE>mode, operands[5]);
2342 emit_insn (gen_aarch64_cmlt<mode> (mask, operands[4], operands[5]));
2346 emit_insn (gen_aarch64_cmge<mode> (mask, operands[4], operands[5]));
2350 emit_insn (gen_aarch64_cmle<mode> (mask, operands[4], operands[5]));
2354 emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
2358 emit_insn (gen_aarch64_cmgtu<mode> (mask, operands[5], operands[4]));
2362 emit_insn (gen_aarch64_cmgeu<mode> (mask, operands[4], operands[5]));
2366 emit_insn (gen_aarch64_cmgeu<mode> (mask, operands[5], operands[4]));
2370 emit_insn (gen_aarch64_cmgtu<mode> (mask, operands[4], operands[5]));
2373 /* NE has been normalized to EQ above. */
2375 emit_insn (gen_aarch64_cmeq<mode> (mask, operands[4], operands[5]));
2382 /* If we have (a = (b CMP c) ? -1 : 0);
2383 Then we can simply move the generated mask. */
2385 if (op1 == CONSTM1_RTX (<V_cmp_result>mode)
2386 && op2 == CONST0_RTX (<V_cmp_result>mode))
2387 emit_move_insn (operands[0], mask);
2391 op1 = force_reg (<MODE>mode, op1);
2393 op2 = force_reg (<MODE>mode, op2);
2394 emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask,
2401 (define_expand "aarch64_vcond_internal<VDQF_COND:mode><VDQF:mode>"
2402 [(set (match_operand:VDQF_COND 0 "register_operand")
2404 (match_operator 3 "comparison_operator"
2405 [(match_operand:VDQF 4 "register_operand")
2406 (match_operand:VDQF 5 "nonmemory_operand")])
2407 (match_operand:VDQF_COND 1 "nonmemory_operand")
2408 (match_operand:VDQF_COND 2 "nonmemory_operand")))]
2412 int use_zero_form = 0;
2413 int swap_bsl_operands = 0;
2414 rtx op1 = operands[1];
2415 rtx op2 = operands[2];
2416 rtx mask = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
2417 rtx tmp = gen_reg_rtx (<VDQF_COND:V_cmp_result>mode);
2419 rtx (*base_comparison) (rtx, rtx, rtx);
2420 rtx (*complimentary_comparison) (rtx, rtx, rtx);
2422 switch (GET_CODE (operands[3]))
2429 if (operands[5] == CONST0_RTX (<MODE>mode))
2436 if (!REG_P (operands[5]))
2437 operands[5] = force_reg (<VDQF:MODE>mode, operands[5]);
2440 switch (GET_CODE (operands[3]))
2450 base_comparison = gen_aarch64_cmge<VDQF:mode>;
2451 complimentary_comparison = gen_aarch64_cmgt<VDQF:mode>;
2459 base_comparison = gen_aarch64_cmgt<VDQF:mode>;
2460 complimentary_comparison = gen_aarch64_cmge<VDQF:mode>;
2465 base_comparison = gen_aarch64_cmeq<VDQF:mode>;
2466 complimentary_comparison = gen_aarch64_cmeq<VDQF:mode>;
2472 switch (GET_CODE (operands[3]))
2479 /* The easy case. Here we emit one of FCMGE, FCMGT or FCMEQ.
2480 As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
2486 Note that there also exist direct comparison against 0 forms,
2487 so catch those as a special case. */
2491 switch (GET_CODE (operands[3]))
2494 base_comparison = gen_aarch64_cmlt<VDQF:mode>;
2497 base_comparison = gen_aarch64_cmle<VDQF:mode>;
2500 /* Do nothing, other zero form cases already have the correct
2507 emit_insn (base_comparison (mask, operands[4], operands[5]));
2509 emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
2516 /* FCM returns false for lanes which are unordered, so if we use
2517 the inverse of the comparison we actually want to emit, then
2518 swap the operands to BSL, we will end up with the correct result.
2519 Note that a NE NaN and NaN NE b are true for all a, b.
2521 Our transformations are:
2526 a NE b -> !(a EQ b) */
2529 emit_insn (base_comparison (mask, operands[4], operands[5]));
2531 emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
2533 swap_bsl_operands = 1;
2536 /* We check (a > b || b > a). combining these comparisons give us
2537 true iff !(a != b && a ORDERED b), swapping the operands to BSL
2538 will then give us (a == b || a UNORDERED b) as intended. */
2540 emit_insn (gen_aarch64_cmgt<VDQF:mode> (mask, operands[4], operands[5]));
2541 emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[5], operands[4]));
2542 emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
2543 swap_bsl_operands = 1;
2546 /* Operands are ORDERED iff (a > b || b >= a).
2547 Swapping the operands to BSL will give the UNORDERED case. */
2548 swap_bsl_operands = 1;
2551 emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[4], operands[5]));
2552 emit_insn (gen_aarch64_cmge<VDQF:mode> (mask, operands[5], operands[4]));
2553 emit_insn (gen_ior<VDQF_COND:v_cmp_result>3 (mask, mask, tmp));
2559 if (swap_bsl_operands)
2565 /* If we have (a = (b CMP c) ? -1 : 0);
2566 Then we can simply move the generated mask. */
2568 if (op1 == CONSTM1_RTX (<VDQF_COND:V_cmp_result>mode)
2569 && op2 == CONST0_RTX (<VDQF_COND:V_cmp_result>mode))
2570 emit_move_insn (operands[0], mask);
2574 op1 = force_reg (<VDQF_COND:MODE>mode, op1);
2576 op2 = force_reg (<VDQF_COND:MODE>mode, op2);
2577 emit_insn (gen_aarch64_simd_bsl<VDQF_COND:mode> (operands[0], mask,
2584 (define_expand "vcond<mode><mode>"
2585 [(set (match_operand:VALLDI 0 "register_operand")
2586 (if_then_else:VALLDI
2587 (match_operator 3 "comparison_operator"
2588 [(match_operand:VALLDI 4 "register_operand")
2589 (match_operand:VALLDI 5 "nonmemory_operand")])
2590 (match_operand:VALLDI 1 "nonmemory_operand")
2591 (match_operand:VALLDI 2 "nonmemory_operand")))]
2594 emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
2595 operands[2], operands[3],
2596 operands[4], operands[5]));
2600 (define_expand "vcond<v_cmp_result><mode>"
2601 [(set (match_operand:<V_cmp_result> 0 "register_operand")
2602 (if_then_else:<V_cmp_result>
2603 (match_operator 3 "comparison_operator"
2604 [(match_operand:VDQF 4 "register_operand")
2605 (match_operand:VDQF 5 "nonmemory_operand")])
2606 (match_operand:<V_cmp_result> 1 "nonmemory_operand")
2607 (match_operand:<V_cmp_result> 2 "nonmemory_operand")))]
2610 emit_insn (gen_aarch64_vcond_internal<v_cmp_result><mode> (
2611 operands[0], operands[1],
2612 operands[2], operands[3],
2613 operands[4], operands[5]));
2617 (define_expand "vcondu<mode><mode>"
2618 [(set (match_operand:VSDQ_I_DI 0 "register_operand")
2619 (if_then_else:VSDQ_I_DI
2620 (match_operator 3 "comparison_operator"
2621 [(match_operand:VSDQ_I_DI 4 "register_operand")
2622 (match_operand:VSDQ_I_DI 5 "nonmemory_operand")])
2623 (match_operand:VSDQ_I_DI 1 "nonmemory_operand")
2624 (match_operand:VSDQ_I_DI 2 "nonmemory_operand")))]
2627 emit_insn (gen_aarch64_vcond_internal<mode><mode> (operands[0], operands[1],
2628 operands[2], operands[3],
2629 operands[4], operands[5]));
2633 ;; Patterns for AArch64 SIMD Intrinsics.
2635 ;; Lane extraction with sign extension to general purpose register.
2636 (define_insn "*aarch64_get_lane_extend<GPI:mode><VDQQH:mode>"
2637 [(set (match_operand:GPI 0 "register_operand" "=r")
2640 (match_operand:VDQQH 1 "register_operand" "w")
2641 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2644 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2645 return "smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]";
2647 [(set_attr "type" "neon_to_gp<q>")]
2650 (define_insn "*aarch64_get_lane_zero_extendsi<mode>"
2651 [(set (match_operand:SI 0 "register_operand" "=r")
2654 (match_operand:VDQQH 1 "register_operand" "w")
2655 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2658 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2659 return "umov\\t%w0, %1.<Vetype>[%2]";
2661 [(set_attr "type" "neon_to_gp<q>")]
2664 ;; Lane extraction of a value, neither sign nor zero extension
2665 ;; is guaranteed so upper bits should be considered undefined.
2666 ;; RTL uses GCC vector extension indices throughout so flip only for assembly.
2667 (define_insn "aarch64_get_lane<mode>"
2668 [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
2670 (match_operand:VALL_F16 1 "register_operand" "w, w, w")
2671 (parallel [(match_operand:SI 2 "immediate_operand" "i, i, i")])))]
2674 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
2675 switch (which_alternative)
2678 return "umov\\t%<vwcore>0, %1.<Vetype>[%2]";
2680 return "dup\\t%<Vetype>0, %1.<Vetype>[%2]";
2682 return "st1\\t{%1.<Vetype>}[%2], %0";
2687 [(set_attr "type" "neon_to_gp<q>, neon_dup<q>, neon_store1_one_lane<q>")]
2690 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2693 (define_insn "*aarch64_combinez<mode>"
2694 [(set (match_operand:<VDBL> 0 "register_operand" "=w,w,w")
2696 (match_operand:VD_BHSI 1 "general_operand" "w,?r,m")
2697 (match_operand:VD_BHSI 2 "aarch64_simd_imm_zero" "Dz,Dz,Dz")))]
2698 "TARGET_SIMD && !BYTES_BIG_ENDIAN"
2703 [(set_attr "type" "neon_move<q>, neon_from_gp, neon_load1_1reg")
2704 (set_attr "simd" "yes,*,yes")
2705 (set_attr "fp" "*,yes,*")]
2708 (define_insn "*aarch64_combinez_be<mode>"
2709 [(set (match_operand:<VDBL> 0 "register_operand" "=w,w,w")
2711 (match_operand:VD_BHSI 2 "aarch64_simd_imm_zero" "Dz,Dz,Dz")
2712 (match_operand:VD_BHSI 1 "general_operand" "w,?r,m")))]
2713 "TARGET_SIMD && BYTES_BIG_ENDIAN"
2718 [(set_attr "type" "neon_move<q>, neon_from_gp, neon_load1_1reg")
2719 (set_attr "simd" "yes,*,yes")
2720 (set_attr "fp" "*,yes,*")]
2723 (define_expand "aarch64_combine<mode>"
2724 [(match_operand:<VDBL> 0 "register_operand")
2725 (match_operand:VDC 1 "register_operand")
2726 (match_operand:VDC 2 "register_operand")]
2730 if (BYTES_BIG_ENDIAN)
2740 emit_insn (gen_aarch64_combine_internal<mode> (operands[0], op1, op2));
2745 (define_insn_and_split "aarch64_combine_internal<mode>"
2746 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2747 (vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
2748 (match_operand:VDC 2 "register_operand" "w")))]
2751 "&& reload_completed"
2754 if (BYTES_BIG_ENDIAN)
2755 aarch64_split_simd_combine (operands[0], operands[2], operands[1]);
2757 aarch64_split_simd_combine (operands[0], operands[1], operands[2]);
2760 [(set_attr "type" "multiple")]
2763 (define_expand "aarch64_simd_combine<mode>"
2764 [(match_operand:<VDBL> 0 "register_operand")
2765 (match_operand:VDC 1 "register_operand")
2766 (match_operand:VDC 2 "register_operand")]
2769 emit_insn (gen_move_lo_quad_<Vdbl> (operands[0], operands[1]));
2770 emit_insn (gen_move_hi_quad_<Vdbl> (operands[0], operands[2]));
2773 [(set_attr "type" "multiple")]
2776 ;; <su><addsub>l<q>.
2778 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>_hi_internal"
2779 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2780 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2781 (match_operand:VQW 1 "register_operand" "w")
2782 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
2783 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2784 (match_operand:VQW 2 "register_operand" "w")
2787 "<ANY_EXTEND:su><ADDSUB:optab>l2\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
2788 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2791 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>_lo_internal"
2792 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2793 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2794 (match_operand:VQW 1 "register_operand" "w")
2795 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
2796 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2797 (match_operand:VQW 2 "register_operand" "w")
2800 "<ANY_EXTEND:su><ADDSUB:optab>l\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
2801 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2805 (define_expand "aarch64_saddl2<mode>"
2806 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2807 (match_operand:VQW 1 "register_operand" "w")
2808 (match_operand:VQW 2 "register_operand" "w")]
2811 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2812 emit_insn (gen_aarch64_saddl<mode>_hi_internal (operands[0], operands[1],
2817 (define_expand "aarch64_uaddl2<mode>"
2818 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2819 (match_operand:VQW 1 "register_operand" "w")
2820 (match_operand:VQW 2 "register_operand" "w")]
2823 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2824 emit_insn (gen_aarch64_uaddl<mode>_hi_internal (operands[0], operands[1],
2829 (define_expand "aarch64_ssubl2<mode>"
2830 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2831 (match_operand:VQW 1 "register_operand" "w")
2832 (match_operand:VQW 2 "register_operand" "w")]
2835 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2836 emit_insn (gen_aarch64_ssubl<mode>_hi_internal (operands[0], operands[1],
2841 (define_expand "aarch64_usubl2<mode>"
2842 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2843 (match_operand:VQW 1 "register_operand" "w")
2844 (match_operand:VQW 2 "register_operand" "w")]
2847 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2848 emit_insn (gen_aarch64_usubl<mode>_hi_internal (operands[0], operands[1],
2853 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>"
2854 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2855 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE>
2856 (match_operand:VD_BHSI 1 "register_operand" "w"))
2858 (match_operand:VD_BHSI 2 "register_operand" "w"))))]
2860 "<ANY_EXTEND:su><ADDSUB:optab>l\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
2861 [(set_attr "type" "neon_<ADDSUB:optab>_long")]
2864 ;; <su><addsub>w<q>.
2866 (define_expand "widen_ssum<mode>3"
2867 [(set (match_operand:<VDBLW> 0 "register_operand" "")
2868 (plus:<VDBLW> (sign_extend:<VDBLW>
2869 (match_operand:VQW 1 "register_operand" ""))
2870 (match_operand:<VDBLW> 2 "register_operand" "")))]
2873 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
2874 rtx temp = gen_reg_rtx (GET_MODE (operands[0]));
2876 emit_insn (gen_aarch64_saddw<mode>_internal (temp, operands[2],
2878 emit_insn (gen_aarch64_saddw2<mode> (operands[0], temp, operands[1]));
2883 (define_expand "widen_ssum<mode>3"
2884 [(set (match_operand:<VWIDE> 0 "register_operand" "")
2885 (plus:<VWIDE> (sign_extend:<VWIDE>
2886 (match_operand:VD_BHSI 1 "register_operand" ""))
2887 (match_operand:<VWIDE> 2 "register_operand" "")))]
2890 emit_insn (gen_aarch64_saddw<mode> (operands[0], operands[2], operands[1]));
2894 (define_expand "widen_usum<mode>3"
2895 [(set (match_operand:<VDBLW> 0 "register_operand" "")
2896 (plus:<VDBLW> (zero_extend:<VDBLW>
2897 (match_operand:VQW 1 "register_operand" ""))
2898 (match_operand:<VDBLW> 2 "register_operand" "")))]
2901 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
2902 rtx temp = gen_reg_rtx (GET_MODE (operands[0]));
2904 emit_insn (gen_aarch64_uaddw<mode>_internal (temp, operands[2],
2906 emit_insn (gen_aarch64_uaddw2<mode> (operands[0], temp, operands[1]));
2911 (define_expand "widen_usum<mode>3"
2912 [(set (match_operand:<VWIDE> 0 "register_operand" "")
2913 (plus:<VWIDE> (zero_extend:<VWIDE>
2914 (match_operand:VD_BHSI 1 "register_operand" ""))
2915 (match_operand:<VWIDE> 2 "register_operand" "")))]
2918 emit_insn (gen_aarch64_uaddw<mode> (operands[0], operands[2], operands[1]));
2922 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w<mode>"
2923 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2924 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2926 (match_operand:VD_BHSI 2 "register_operand" "w"))))]
2928 "<ANY_EXTEND:su><ADDSUB:optab>w\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
2929 [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
2932 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w<mode>_internal"
2933 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2934 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2937 (match_operand:VQW 2 "register_operand" "w")
2938 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))))]
2940 "<ANY_EXTEND:su><ADDSUB:optab>w\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vhalftype>"
2941 [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
2944 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w2<mode>_internal"
2945 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2946 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2949 (match_operand:VQW 2 "register_operand" "w")
2950 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))))]
2952 "<ANY_EXTEND:su><ADDSUB:optab>w2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
2953 [(set_attr "type" "neon_<ADDSUB:optab>_widen")]
2956 (define_expand "aarch64_saddw2<mode>"
2957 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2958 (match_operand:<VWIDE> 1 "register_operand" "w")
2959 (match_operand:VQW 2 "register_operand" "w")]
2962 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2963 emit_insn (gen_aarch64_saddw2<mode>_internal (operands[0], operands[1],
2968 (define_expand "aarch64_uaddw2<mode>"
2969 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2970 (match_operand:<VWIDE> 1 "register_operand" "w")
2971 (match_operand:VQW 2 "register_operand" "w")]
2974 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2975 emit_insn (gen_aarch64_uaddw2<mode>_internal (operands[0], operands[1],
2981 (define_expand "aarch64_ssubw2<mode>"
2982 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2983 (match_operand:<VWIDE> 1 "register_operand" "w")
2984 (match_operand:VQW 2 "register_operand" "w")]
2987 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2988 emit_insn (gen_aarch64_ssubw2<mode>_internal (operands[0], operands[1],
2993 (define_expand "aarch64_usubw2<mode>"
2994 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2995 (match_operand:<VWIDE> 1 "register_operand" "w")
2996 (match_operand:VQW 2 "register_operand" "w")]
2999 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3000 emit_insn (gen_aarch64_usubw2<mode>_internal (operands[0], operands[1],
3005 ;; <su><r>h<addsub>.
3007 (define_insn "aarch64_<sur>h<addsub><mode>"
3008 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
3009 (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand" "w")
3010 (match_operand:VDQ_BHSI 2 "register_operand" "w")]
3013 "<sur>h<addsub>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
3014 [(set_attr "type" "neon_<addsub>_halve<q>")]
3017 ;; <r><addsub>hn<q>.
3019 (define_insn "aarch64_<sur><addsub>hn<mode>"
3020 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
3021 (unspec:<VNARROWQ> [(match_operand:VQN 1 "register_operand" "w")
3022 (match_operand:VQN 2 "register_operand" "w")]
3025 "<sur><addsub>hn\\t%0.<Vntype>, %1.<Vtype>, %2.<Vtype>"
3026 [(set_attr "type" "neon_<addsub>_halve_narrow_q")]
3029 (define_insn "aarch64_<sur><addsub>hn2<mode>"
3030 [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
3031 (unspec:<VNARROWQ2> [(match_operand:<VNARROWQ> 1 "register_operand" "0")
3032 (match_operand:VQN 2 "register_operand" "w")
3033 (match_operand:VQN 3 "register_operand" "w")]
3036 "<sur><addsub>hn2\\t%0.<V2ntype>, %2.<Vtype>, %3.<Vtype>"
3037 [(set_attr "type" "neon_<addsub>_halve_narrow_q")]
3042 (define_insn "aarch64_pmul<mode>"
3043 [(set (match_operand:VB 0 "register_operand" "=w")
3044 (unspec:VB [(match_operand:VB 1 "register_operand" "w")
3045 (match_operand:VB 2 "register_operand" "w")]
3048 "pmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
3049 [(set_attr "type" "neon_mul_<Vetype><q>")]
3054 (define_insn "aarch64_fmulx<mode>"
3055 [(set (match_operand:VHSDF_SDF 0 "register_operand" "=w")
3057 [(match_operand:VHSDF_SDF 1 "register_operand" "w")
3058 (match_operand:VHSDF_SDF 2 "register_operand" "w")]
3061 "fmulx\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3062 [(set_attr "type" "neon_fp_mul_<stype>")]
3065 ;; vmulxq_lane_f32, and vmulx_laneq_f32
3067 (define_insn "*aarch64_mulx_elt_<vswap_width_name><mode>"
3068 [(set (match_operand:VDQSF 0 "register_operand" "=w")
3070 [(match_operand:VDQSF 1 "register_operand" "w")
3071 (vec_duplicate:VDQSF
3073 (match_operand:<VSWAP_WIDTH> 2 "register_operand" "w")
3074 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))]
3078 operands[3] = GEN_INT (ENDIAN_LANE_N (<VSWAP_WIDTH>mode,
3079 INTVAL (operands[3])));
3080 return "fmulx\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3082 [(set_attr "type" "neon_fp_mul_<Vetype>_scalar<q>")]
3085 ;; vmulxq_laneq_f32, vmulxq_laneq_f64, vmulx_lane_f32
3087 (define_insn "*aarch64_mulx_elt<mode>"
3088 [(set (match_operand:VDQF 0 "register_operand" "=w")
3090 [(match_operand:VDQF 1 "register_operand" "w")
3093 (match_operand:VDQF 2 "register_operand" "w")
3094 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))]
3098 operands[3] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[3])));
3099 return "fmulx\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3101 [(set_attr "type" "neon_fp_mul_<Vetype><q>")]
3106 (define_insn "*aarch64_mulx_elt_from_dup<mode>"
3107 [(set (match_operand:VHSDF 0 "register_operand" "=w")
3109 [(match_operand:VHSDF 1 "register_operand" "w")
3110 (vec_duplicate:VHSDF
3111 (match_operand:<VEL> 2 "register_operand" "w"))]
3114 "fmulx\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[0]";
3115 [(set_attr "type" "neon<fp>_mul_<stype>_scalar<q>")]
3118 ;; vmulxs_lane_f32, vmulxs_laneq_f32
3119 ;; vmulxd_lane_f64 == vmulx_lane_f64
3120 ;; vmulxd_laneq_f64 == vmulx_laneq_f64
3122 (define_insn "*aarch64_vgetfmulx<mode>"
3123 [(set (match_operand:<VEL> 0 "register_operand" "=w")
3125 [(match_operand:<VEL> 1 "register_operand" "w")
3127 (match_operand:VDQF_DF 2 "register_operand" "w")
3128 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
3132 operands[3] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[3])));
3133 return "fmulx\t%<Vetype>0, %<Vetype>1, %2.<Vetype>[%3]";
3135 [(set_attr "type" "fmul<Vetype>")]
3139 (define_insn "aarch64_<su_optab><optab><mode>"
3140 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3141 (BINQOPS:VSDQ_I (match_operand:VSDQ_I 1 "register_operand" "w")
3142 (match_operand:VSDQ_I 2 "register_operand" "w")))]
3144 "<su_optab><optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3145 [(set_attr "type" "neon_<optab><q>")]
3148 ;; suqadd and usqadd
3150 (define_insn "aarch64_<sur>qadd<mode>"
3151 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3152 (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "0")
3153 (match_operand:VSDQ_I 2 "register_operand" "w")]
3156 "<sur>qadd\\t%<v>0<Vmtype>, %<v>2<Vmtype>"
3157 [(set_attr "type" "neon_qadd<q>")]
3162 (define_insn "aarch64_sqmovun<mode>"
3163 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
3164 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
3167 "sqxtun\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
3168 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
3171 ;; sqmovn and uqmovn
3173 (define_insn "aarch64_<sur>qmovn<mode>"
3174 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
3175 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
3178 "<sur>qxtn\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
3179 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
3184 (define_insn "aarch64_s<optab><mode>"
3185 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3187 (match_operand:VSDQ_I 1 "register_operand" "w")))]
3189 "s<optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>"
3190 [(set_attr "type" "neon_<optab><q>")]
3195 (define_insn "aarch64_sq<r>dmulh<mode>"
3196 [(set (match_operand:VSDQ_HSI 0 "register_operand" "=w")
3198 [(match_operand:VSDQ_HSI 1 "register_operand" "w")
3199 (match_operand:VSDQ_HSI 2 "register_operand" "w")]
3202 "sq<r>dmulh\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3203 [(set_attr "type" "neon_sat_mul_<Vetype><q>")]
3208 (define_insn "aarch64_sq<r>dmulh_lane<mode>"
3209 [(set (match_operand:VDQHS 0 "register_operand" "=w")
3211 [(match_operand:VDQHS 1 "register_operand" "w")
3213 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3214 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
3218 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3219 return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
3220 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
3223 (define_insn "aarch64_sq<r>dmulh_laneq<mode>"
3224 [(set (match_operand:VDQHS 0 "register_operand" "=w")
3226 [(match_operand:VDQHS 1 "register_operand" "w")
3228 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3229 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
3233 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3234 return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
3235 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
3238 (define_insn "aarch64_sq<r>dmulh_lane<mode>"
3239 [(set (match_operand:SD_HSI 0 "register_operand" "=w")
3241 [(match_operand:SD_HSI 1 "register_operand" "w")
3243 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3244 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
3248 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3249 return \"sq<r>dmulh\\t%<v>0, %<v>1, %2.<v>[%3]\";"
3250 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
3253 (define_insn "aarch64_sq<r>dmulh_laneq<mode>"
3254 [(set (match_operand:SD_HSI 0 "register_operand" "=w")
3256 [(match_operand:SD_HSI 1 "register_operand" "w")
3258 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3259 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
3263 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3264 return \"sq<r>dmulh\\t%<v>0, %<v>1, %2.<v>[%3]\";"
3265 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar<q>")]
3270 (define_insn "aarch64_sqrdml<SQRDMLH_AS:rdma_as>h<mode>"
3271 [(set (match_operand:VSDQ_HSI 0 "register_operand" "=w")
3273 [(match_operand:VSDQ_HSI 1 "register_operand" "0")
3274 (match_operand:VSDQ_HSI 2 "register_operand" "w")
3275 (match_operand:VSDQ_HSI 3 "register_operand" "w")]
3278 "sqrdml<SQRDMLH_AS:rdma_as>h\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
3279 [(set_attr "type" "neon_sat_mla_<Vetype>_long")]
3282 ;; sqrdml[as]h_lane.
3284 (define_insn "aarch64_sqrdml<SQRDMLH_AS:rdma_as>h_lane<mode>"
3285 [(set (match_operand:VDQHS 0 "register_operand" "=w")
3287 [(match_operand:VDQHS 1 "register_operand" "0")
3288 (match_operand:VDQHS 2 "register_operand" "w")
3290 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3291 (parallel [(match_operand:SI 4 "immediate_operand" "i")]))]
3295 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3297 "sqrdml<SQRDMLH_AS:rdma_as>h\\t%0.<Vtype>, %2.<Vtype>, %3.<Vetype>[%4]";
3299 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3302 (define_insn "aarch64_sqrdml<SQRDMLH_AS:rdma_as>h_lane<mode>"
3303 [(set (match_operand:SD_HSI 0 "register_operand" "=w")
3305 [(match_operand:SD_HSI 1 "register_operand" "0")
3306 (match_operand:SD_HSI 2 "register_operand" "w")
3308 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3309 (parallel [(match_operand:SI 4 "immediate_operand" "i")]))]
3313 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3315 "sqrdml<SQRDMLH_AS:rdma_as>h\\t%<v>0, %<v>2, %3.<Vetype>[%4]";
3317 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3320 ;; sqrdml[as]h_laneq.
3322 (define_insn "aarch64_sqrdml<SQRDMLH_AS:rdma_as>h_laneq<mode>"
3323 [(set (match_operand:VDQHS 0 "register_operand" "=w")
3325 [(match_operand:VDQHS 1 "register_operand" "0")
3326 (match_operand:VDQHS 2 "register_operand" "w")
3328 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3329 (parallel [(match_operand:SI 4 "immediate_operand" "i")]))]
3333 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3335 "sqrdml<SQRDMLH_AS:rdma_as>h\\t%0.<Vtype>, %2.<Vtype>, %3.<Vetype>[%4]";
3337 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3340 (define_insn "aarch64_sqrdml<SQRDMLH_AS:rdma_as>h_laneq<mode>"
3341 [(set (match_operand:SD_HSI 0 "register_operand" "=w")
3343 [(match_operand:SD_HSI 1 "register_operand" "0")
3344 (match_operand:SD_HSI 2 "register_operand" "w")
3346 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3347 (parallel [(match_operand:SI 4 "immediate_operand" "i")]))]
3351 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3353 "sqrdml<SQRDMLH_AS:rdma_as>h\\t%<v>0, %<v>2, %3.<v>[%4]";
3355 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3360 (define_insn "aarch64_sqdml<SBINQOPS:as>l<mode>"
3361 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3363 (match_operand:<VWIDE> 1 "register_operand" "0")
3366 (sign_extend:<VWIDE>
3367 (match_operand:VSD_HSI 2 "register_operand" "w"))
3368 (sign_extend:<VWIDE>
3369 (match_operand:VSD_HSI 3 "register_operand" "w")))
3372 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
3373 [(set_attr "type" "neon_sat_mla_<Vetype>_long")]
3378 (define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>"
3379 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3381 (match_operand:<VWIDE> 1 "register_operand" "0")
3384 (sign_extend:<VWIDE>
3385 (match_operand:VD_HSI 2 "register_operand" "w"))
3386 (sign_extend:<VWIDE>
3387 (vec_duplicate:VD_HSI
3389 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3390 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3395 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3397 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3399 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3402 (define_insn "aarch64_sqdml<SBINQOPS:as>l_laneq<mode>"
3403 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3405 (match_operand:<VWIDE> 1 "register_operand" "0")
3408 (sign_extend:<VWIDE>
3409 (match_operand:VD_HSI 2 "register_operand" "w"))
3410 (sign_extend:<VWIDE>
3411 (vec_duplicate:VD_HSI
3413 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3414 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3419 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3421 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3423 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3426 (define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>"
3427 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3429 (match_operand:<VWIDE> 1 "register_operand" "0")
3432 (sign_extend:<VWIDE>
3433 (match_operand:SD_HSI 2 "register_operand" "w"))
3434 (sign_extend:<VWIDE>
3436 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3437 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3442 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3444 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3446 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3449 (define_insn "aarch64_sqdml<SBINQOPS:as>l_laneq<mode>"
3450 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3452 (match_operand:<VWIDE> 1 "register_operand" "0")
3455 (sign_extend:<VWIDE>
3456 (match_operand:SD_HSI 2 "register_operand" "w"))
3457 (sign_extend:<VWIDE>
3459 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3460 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
3465 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3467 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3469 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3474 (define_insn "aarch64_sqdml<SBINQOPS:as>l_n<mode>"
3475 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3477 (match_operand:<VWIDE> 1 "register_operand" "0")
3480 (sign_extend:<VWIDE>
3481 (match_operand:VD_HSI 2 "register_operand" "w"))
3482 (sign_extend:<VWIDE>
3483 (vec_duplicate:VD_HSI
3484 (match_operand:<VEL> 3 "register_operand" "<vwx>"))))
3487 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
3488 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3493 (define_insn "aarch64_sqdml<SBINQOPS:as>l2<mode>_internal"
3494 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3496 (match_operand:<VWIDE> 1 "register_operand" "0")
3499 (sign_extend:<VWIDE>
3501 (match_operand:VQ_HSI 2 "register_operand" "w")
3502 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3503 (sign_extend:<VWIDE>
3505 (match_operand:VQ_HSI 3 "register_operand" "w")
3509 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
3510 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3513 (define_expand "aarch64_sqdmlal2<mode>"
3514 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3515 (match_operand:<VWIDE> 1 "register_operand" "w")
3516 (match_operand:VQ_HSI 2 "register_operand" "w")
3517 (match_operand:VQ_HSI 3 "register_operand" "w")]
3520 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3521 emit_insn (gen_aarch64_sqdmlal2<mode>_internal (operands[0], operands[1],
3522 operands[2], operands[3], p));
3526 (define_expand "aarch64_sqdmlsl2<mode>"
3527 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3528 (match_operand:<VWIDE> 1 "register_operand" "w")
3529 (match_operand:VQ_HSI 2 "register_operand" "w")
3530 (match_operand:VQ_HSI 3 "register_operand" "w")]
3533 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3534 emit_insn (gen_aarch64_sqdmlsl2<mode>_internal (operands[0], operands[1],
3535 operands[2], operands[3], p));
3541 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_lane<mode>_internal"
3542 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3544 (match_operand:<VWIDE> 1 "register_operand" "0")
3547 (sign_extend:<VWIDE>
3549 (match_operand:VQ_HSI 2 "register_operand" "w")
3550 (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" "")))
3551 (sign_extend:<VWIDE>
3552 (vec_duplicate:<VHALF>
3554 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3555 (parallel [(match_operand:SI 4 "immediate_operand" "i")])
3560 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[4])));
3562 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3564 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3567 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_laneq<mode>_internal"
3568 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3570 (match_operand:<VWIDE> 1 "register_operand" "0")
3573 (sign_extend:<VWIDE>
3575 (match_operand:VQ_HSI 2 "register_operand" "w")
3576 (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" "")))
3577 (sign_extend:<VWIDE>
3578 (vec_duplicate:<VHALF>
3580 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3581 (parallel [(match_operand:SI 4 "immediate_operand" "i")])
3586 operands[4] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[4])));
3588 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]";
3590 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3593 (define_expand "aarch64_sqdmlal2_lane<mode>"
3594 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3595 (match_operand:<VWIDE> 1 "register_operand" "w")
3596 (match_operand:VQ_HSI 2 "register_operand" "w")
3597 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3598 (match_operand:SI 4 "immediate_operand" "i")]
3601 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3602 emit_insn (gen_aarch64_sqdmlal2_lane<mode>_internal (operands[0], operands[1],
3603 operands[2], operands[3],
3608 (define_expand "aarch64_sqdmlal2_laneq<mode>"
3609 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3610 (match_operand:<VWIDE> 1 "register_operand" "w")
3611 (match_operand:VQ_HSI 2 "register_operand" "w")
3612 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3613 (match_operand:SI 4 "immediate_operand" "i")]
3616 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3617 emit_insn (gen_aarch64_sqdmlal2_laneq<mode>_internal (operands[0], operands[1],
3618 operands[2], operands[3],
3623 (define_expand "aarch64_sqdmlsl2_lane<mode>"
3624 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3625 (match_operand:<VWIDE> 1 "register_operand" "w")
3626 (match_operand:VQ_HSI 2 "register_operand" "w")
3627 (match_operand:<VCOND> 3 "register_operand" "<vwx>")
3628 (match_operand:SI 4 "immediate_operand" "i")]
3631 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3632 emit_insn (gen_aarch64_sqdmlsl2_lane<mode>_internal (operands[0], operands[1],
3633 operands[2], operands[3],
3638 (define_expand "aarch64_sqdmlsl2_laneq<mode>"
3639 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3640 (match_operand:<VWIDE> 1 "register_operand" "w")
3641 (match_operand:VQ_HSI 2 "register_operand" "w")
3642 (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
3643 (match_operand:SI 4 "immediate_operand" "i")]
3646 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3647 emit_insn (gen_aarch64_sqdmlsl2_laneq<mode>_internal (operands[0], operands[1],
3648 operands[2], operands[3],
3653 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal"
3654 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3656 (match_operand:<VWIDE> 1 "register_operand" "0")
3659 (sign_extend:<VWIDE>
3661 (match_operand:VQ_HSI 2 "register_operand" "w")
3662 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3663 (sign_extend:<VWIDE>
3664 (vec_duplicate:<VHALF>
3665 (match_operand:<VEL> 3 "register_operand" "<vwx>"))))
3668 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
3669 [(set_attr "type" "neon_sat_mla_<Vetype>_scalar_long")]
3672 (define_expand "aarch64_sqdmlal2_n<mode>"
3673 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3674 (match_operand:<VWIDE> 1 "register_operand" "w")
3675 (match_operand:VQ_HSI 2 "register_operand" "w")
3676 (match_operand:<VEL> 3 "register_operand" "w")]
3679 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3680 emit_insn (gen_aarch64_sqdmlal2_n<mode>_internal (operands[0], operands[1],
3681 operands[2], operands[3],
3686 (define_expand "aarch64_sqdmlsl2_n<mode>"
3687 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3688 (match_operand:<VWIDE> 1 "register_operand" "w")
3689 (match_operand:VQ_HSI 2 "register_operand" "w")
3690 (match_operand:<VEL> 3 "register_operand" "w")]
3693 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3694 emit_insn (gen_aarch64_sqdmlsl2_n<mode>_internal (operands[0], operands[1],
3695 operands[2], operands[3],
3702 (define_insn "aarch64_sqdmull<mode>"
3703 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3706 (sign_extend:<VWIDE>
3707 (match_operand:VSD_HSI 1 "register_operand" "w"))
3708 (sign_extend:<VWIDE>
3709 (match_operand:VSD_HSI 2 "register_operand" "w")))
3712 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3713 [(set_attr "type" "neon_sat_mul_<Vetype>_long")]
3718 (define_insn "aarch64_sqdmull_lane<mode>"
3719 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3722 (sign_extend:<VWIDE>
3723 (match_operand:VD_HSI 1 "register_operand" "w"))
3724 (sign_extend:<VWIDE>
3725 (vec_duplicate:VD_HSI
3727 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3728 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3733 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3734 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3736 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3739 (define_insn "aarch64_sqdmull_laneq<mode>"
3740 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3743 (sign_extend:<VWIDE>
3744 (match_operand:VD_HSI 1 "register_operand" "w"))
3745 (sign_extend:<VWIDE>
3746 (vec_duplicate:VD_HSI
3748 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3749 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3754 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3755 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3757 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3760 (define_insn "aarch64_sqdmull_lane<mode>"
3761 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3764 (sign_extend:<VWIDE>
3765 (match_operand:SD_HSI 1 "register_operand" "w"))
3766 (sign_extend:<VWIDE>
3768 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3769 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))
3774 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3775 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3777 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3780 (define_insn "aarch64_sqdmull_laneq<mode>"
3781 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3784 (sign_extend:<VWIDE>
3785 (match_operand:SD_HSI 1 "register_operand" "w"))
3786 (sign_extend:<VWIDE>
3788 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3789 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))
3794 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3795 return "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3797 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3802 (define_insn "aarch64_sqdmull_n<mode>"
3803 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3806 (sign_extend:<VWIDE>
3807 (match_operand:VD_HSI 1 "register_operand" "w"))
3808 (sign_extend:<VWIDE>
3809 (vec_duplicate:VD_HSI
3810 (match_operand:<VEL> 2 "register_operand" "<vwx>")))
3814 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
3815 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3822 (define_insn "aarch64_sqdmull2<mode>_internal"
3823 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3826 (sign_extend:<VWIDE>
3828 (match_operand:VQ_HSI 1 "register_operand" "w")
3829 (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
3830 (sign_extend:<VWIDE>
3832 (match_operand:VQ_HSI 2 "register_operand" "w")
3837 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3838 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3841 (define_expand "aarch64_sqdmull2<mode>"
3842 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3843 (match_operand:VQ_HSI 1 "register_operand" "w")
3844 (match_operand:VQ_HSI 2 "register_operand" "w")]
3847 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3848 emit_insn (gen_aarch64_sqdmull2<mode>_internal (operands[0], operands[1],
3855 (define_insn "aarch64_sqdmull2_lane<mode>_internal"
3856 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3859 (sign_extend:<VWIDE>
3861 (match_operand:VQ_HSI 1 "register_operand" "w")
3862 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3863 (sign_extend:<VWIDE>
3864 (vec_duplicate:<VHALF>
3866 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3867 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3872 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCOND>mode, INTVAL (operands[3])));
3873 return "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3875 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3878 (define_insn "aarch64_sqdmull2_laneq<mode>_internal"
3879 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3882 (sign_extend:<VWIDE>
3884 (match_operand:VQ_HSI 1 "register_operand" "w")
3885 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
3886 (sign_extend:<VWIDE>
3887 (vec_duplicate:<VHALF>
3889 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3890 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
3895 operands[3] = GEN_INT (ENDIAN_LANE_N (<VCONQ>mode, INTVAL (operands[3])));
3896 return "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]";
3898 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3901 (define_expand "aarch64_sqdmull2_lane<mode>"
3902 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3903 (match_operand:VQ_HSI 1 "register_operand" "w")
3904 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
3905 (match_operand:SI 3 "immediate_operand" "i")]
3908 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3909 emit_insn (gen_aarch64_sqdmull2_lane<mode>_internal (operands[0], operands[1],
3910 operands[2], operands[3],
3915 (define_expand "aarch64_sqdmull2_laneq<mode>"
3916 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3917 (match_operand:VQ_HSI 1 "register_operand" "w")
3918 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
3919 (match_operand:SI 3 "immediate_operand" "i")]
3922 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3923 emit_insn (gen_aarch64_sqdmull2_laneq<mode>_internal (operands[0], operands[1],
3924 operands[2], operands[3],
3931 (define_insn "aarch64_sqdmull2_n<mode>_internal"
3932 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3935 (sign_extend:<VWIDE>
3937 (match_operand:VQ_HSI 1 "register_operand" "w")
3938 (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
3939 (sign_extend:<VWIDE>
3940 (vec_duplicate:<VHALF>
3941 (match_operand:<VEL> 2 "register_operand" "<vwx>")))
3945 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
3946 [(set_attr "type" "neon_sat_mul_<Vetype>_scalar_long")]
3949 (define_expand "aarch64_sqdmull2_n<mode>"
3950 [(match_operand:<VWIDE> 0 "register_operand" "=w")
3951 (match_operand:VQ_HSI 1 "register_operand" "w")
3952 (match_operand:<VEL> 2 "register_operand" "w")]
3955 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
3956 emit_insn (gen_aarch64_sqdmull2_n<mode>_internal (operands[0], operands[1],
3963 (define_insn "aarch64_<sur>shl<mode>"
3964 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3966 [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
3967 (match_operand:VSDQ_I_DI 2 "register_operand" "w")]
3970 "<sur>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
3971 [(set_attr "type" "neon_shift_reg<q>")]
3977 (define_insn "aarch64_<sur>q<r>shl<mode>"
3978 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3980 [(match_operand:VSDQ_I 1 "register_operand" "w")
3981 (match_operand:VSDQ_I 2 "register_operand" "w")]
3984 "<sur>q<r>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
3985 [(set_attr "type" "neon_sat_shift_reg<q>")]
3990 (define_insn "aarch64_<sur>shll_n<mode>"
3991 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3992 (unspec:<VWIDE> [(match_operand:VD_BHSI 1 "register_operand" "w")
3994 "aarch64_simd_shift_imm_bitsize_<ve_mode>" "i")]
3998 if (INTVAL (operands[2]) == GET_MODE_UNIT_BITSIZE (<MODE>mode))
3999 return "shll\\t%0.<Vwtype>, %1.<Vtype>, %2";
4001 return "<sur>shll\\t%0.<Vwtype>, %1.<Vtype>, %2";
4003 [(set_attr "type" "neon_shift_imm_long")]
4008 (define_insn "aarch64_<sur>shll2_n<mode>"
4009 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
4010 (unspec:<VWIDE> [(match_operand:VQW 1 "register_operand" "w")
4011 (match_operand:SI 2 "immediate_operand" "i")]
4015 if (INTVAL (operands[2]) == GET_MODE_UNIT_BITSIZE (<MODE>mode))
4016 return "shll2\\t%0.<Vwtype>, %1.<Vtype>, %2";
4018 return "<sur>shll2\\t%0.<Vwtype>, %1.<Vtype>, %2";
4020 [(set_attr "type" "neon_shift_imm_long")]
4025 (define_insn "aarch64_<sur>shr_n<mode>"
4026 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
4027 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
4029 "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
4032 "<sur>shr\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2"
4033 [(set_attr "type" "neon_sat_shift_imm<q>")]
4038 (define_insn "aarch64_<sur>sra_n<mode>"
4039 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
4040 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
4041 (match_operand:VSDQ_I_DI 2 "register_operand" "w")
4043 "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
4046 "<sur>sra\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3"
4047 [(set_attr "type" "neon_shift_acc<q>")]
4052 (define_insn "aarch64_<sur>s<lr>i_n<mode>"
4053 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
4054 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
4055 (match_operand:VSDQ_I_DI 2 "register_operand" "w")
4057 "aarch64_simd_shift_imm_<offsetlr><ve_mode>" "i")]
4060 "s<lr>i\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3"
4061 [(set_attr "type" "neon_shift_imm<q>")]
4066 (define_insn "aarch64_<sur>qshl<u>_n<mode>"
4067 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
4068 (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "w")
4070 "aarch64_simd_shift_imm_<ve_mode>" "i")]
4073 "<sur>qshl<u>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2"
4074 [(set_attr "type" "neon_sat_shift_imm<q>")]
4080 (define_insn "aarch64_<sur>q<r>shr<u>n_n<mode>"
4081 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
4082 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")
4084 "aarch64_simd_shift_imm_offset_<ve_mode>" "i")]
4087 "<sur>q<r>shr<u>n\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2"
4088 [(set_attr "type" "neon_sat_shift_imm_narrow_q")]
4092 ;; cm(eq|ge|gt|lt|le)
4093 ;; Note, we have constraints for Dz and Z as different expanders
4094 ;; have different ideas of what should be passed to this pattern.
4096 (define_insn "aarch64_cm<optab><mode>"
4097 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
4099 (COMPARISONS:<V_cmp_result>
4100 (match_operand:VDQ_I 1 "register_operand" "w,w")
4101 (match_operand:VDQ_I 2 "aarch64_simd_reg_or_zero" "w,ZDz")
4105 cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
4106 cm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #0"
4107 [(set_attr "type" "neon_compare<q>, neon_compare_zero<q>")]
4110 (define_insn_and_split "aarch64_cm<optab>di"
4111 [(set (match_operand:DI 0 "register_operand" "=w,w,r")
4114 (match_operand:DI 1 "register_operand" "w,w,r")
4115 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz,r")
4117 (clobber (reg:CC CC_REGNUM))]
4121 [(set (match_operand:DI 0 "register_operand")
4124 (match_operand:DI 1 "register_operand")
4125 (match_operand:DI 2 "aarch64_simd_reg_or_zero")
4128 /* If we are in the general purpose register file,
4129 we split to a sequence of comparison and store. */
4130 if (GP_REGNUM_P (REGNO (operands[0]))
4131 && GP_REGNUM_P (REGNO (operands[1])))
4133 machine_mode mode = SELECT_CC_MODE (<CMP>, operands[1], operands[2]);
4134 rtx cc_reg = aarch64_gen_compare_reg (<CMP>, operands[1], operands[2]);
4135 rtx comparison = gen_rtx_<CMP> (mode, operands[1], operands[2]);
4136 emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
4139 /* Otherwise, we expand to a similar pattern which does not
4140 clobber CC_REGNUM. */
4142 [(set_attr "type" "neon_compare, neon_compare_zero, multiple")]
4145 (define_insn "*aarch64_cm<optab>di"
4146 [(set (match_operand:DI 0 "register_operand" "=w,w")
4149 (match_operand:DI 1 "register_operand" "w,w")
4150 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,ZDz")
4152 "TARGET_SIMD && reload_completed"
4154 cm<n_optab>\t%d0, %d<cmp_1>, %d<cmp_2>
4155 cm<optab>\t%d0, %d1, #0"
4156 [(set_attr "type" "neon_compare, neon_compare_zero")]
4161 (define_insn "aarch64_cm<optab><mode>"
4162 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
4164 (UCOMPARISONS:<V_cmp_result>
4165 (match_operand:VDQ_I 1 "register_operand" "w")
4166 (match_operand:VDQ_I 2 "register_operand" "w")
4169 "cm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
4170 [(set_attr "type" "neon_compare<q>")]
4173 (define_insn_and_split "aarch64_cm<optab>di"
4174 [(set (match_operand:DI 0 "register_operand" "=w,r")
4177 (match_operand:DI 1 "register_operand" "w,r")
4178 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w,r")
4180 (clobber (reg:CC CC_REGNUM))]
4184 [(set (match_operand:DI 0 "register_operand")
4187 (match_operand:DI 1 "register_operand")
4188 (match_operand:DI 2 "aarch64_simd_reg_or_zero")
4191 /* If we are in the general purpose register file,
4192 we split to a sequence of comparison and store. */
4193 if (GP_REGNUM_P (REGNO (operands[0]))
4194 && GP_REGNUM_P (REGNO (operands[1])))
4196 machine_mode mode = CCmode;
4197 rtx cc_reg = aarch64_gen_compare_reg (<CMP>, operands[1], operands[2]);
4198 rtx comparison = gen_rtx_<CMP> (mode, operands[1], operands[2]);
4199 emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
4202 /* Otherwise, we expand to a similar pattern which does not
4203 clobber CC_REGNUM. */
4205 [(set_attr "type" "neon_compare,multiple")]
4208 (define_insn "*aarch64_cm<optab>di"
4209 [(set (match_operand:DI 0 "register_operand" "=w")
4212 (match_operand:DI 1 "register_operand" "w")
4213 (match_operand:DI 2 "aarch64_simd_reg_or_zero" "w")
4215 "TARGET_SIMD && reload_completed"
4216 "cm<n_optab>\t%d0, %d<cmp_1>, %d<cmp_2>"
4217 [(set_attr "type" "neon_compare")]
4222 ;; Although neg (ne (and x y) 0) is the natural way of expressing a cmtst,
4223 ;; we don't have any insns using ne, and aarch64_vcond_internal outputs
4224 ;; not (neg (eq (and x y) 0))
4225 ;; which is rewritten by simplify_rtx as
4226 ;; plus (eq (and x y) 0) -1.
4228 (define_insn "aarch64_cmtst<mode>"
4229 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
4230 (plus:<V_cmp_result>
4233 (match_operand:VDQ_I 1 "register_operand" "w")
4234 (match_operand:VDQ_I 2 "register_operand" "w"))
4235 (match_operand:VDQ_I 3 "aarch64_simd_imm_zero"))
4236 (match_operand:<V_cmp_result> 4 "aarch64_simd_imm_minus_one")))
4239 "cmtst\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
4240 [(set_attr "type" "neon_tst<q>")]
4243 (define_insn_and_split "aarch64_cmtstdi"
4244 [(set (match_operand:DI 0 "register_operand" "=w,r")
4248 (match_operand:DI 1 "register_operand" "w,r")
4249 (match_operand:DI 2 "register_operand" "w,r"))
4251 (clobber (reg:CC CC_REGNUM))]
4255 [(set (match_operand:DI 0 "register_operand")
4259 (match_operand:DI 1 "register_operand")
4260 (match_operand:DI 2 "register_operand"))
4263 /* If we are in the general purpose register file,
4264 we split to a sequence of comparison and store. */
4265 if (GP_REGNUM_P (REGNO (operands[0]))
4266 && GP_REGNUM_P (REGNO (operands[1])))
4268 rtx and_tree = gen_rtx_AND (DImode, operands[1], operands[2]);
4269 machine_mode mode = SELECT_CC_MODE (NE, and_tree, const0_rtx);
4270 rtx cc_reg = aarch64_gen_compare_reg (NE, and_tree, const0_rtx);
4271 rtx comparison = gen_rtx_NE (mode, and_tree, const0_rtx);
4272 emit_insn (gen_cstoredi_neg (operands[0], comparison, cc_reg));
4275 /* Otherwise, we expand to a similar pattern which does not
4276 clobber CC_REGNUM. */
4278 [(set_attr "type" "neon_tst,multiple")]
4281 (define_insn "*aarch64_cmtstdi"
4282 [(set (match_operand:DI 0 "register_operand" "=w")
4286 (match_operand:DI 1 "register_operand" "w")
4287 (match_operand:DI 2 "register_operand" "w"))
4290 "cmtst\t%d0, %d1, %d2"
4291 [(set_attr "type" "neon_tst")]
4294 ;; fcm(eq|ge|gt|le|lt)
4296 (define_insn "aarch64_cm<optab><mode>"
4297 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
4299 (COMPARISONS:<V_cmp_result>
4300 (match_operand:VHSDF_SDF 1 "register_operand" "w,w")
4301 (match_operand:VHSDF_SDF 2 "aarch64_simd_reg_or_zero" "w,YDz")
4305 fcm<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>
4306 fcm<optab>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
4307 [(set_attr "type" "neon_fp_compare_<stype><q>")]
4311 ;; Note we can also handle what would be fac(le|lt) by
4312 ;; generating fac(ge|gt).
4314 (define_insn "aarch64_fac<optab><mode>"
4315 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
4317 (FAC_COMPARISONS:<V_cmp_result>
4319 (match_operand:VHSDF_SDF 1 "register_operand" "w"))
4321 (match_operand:VHSDF_SDF 2 "register_operand" "w"))
4324 "fac<n_optab>\t%<v>0<Vmtype>, %<v><cmp_1><Vmtype>, %<v><cmp_2><Vmtype>"
4325 [(set_attr "type" "neon_fp_compare_<stype><q>")]
4330 (define_insn "aarch64_addp<mode>"
4331 [(set (match_operand:VD_BHSI 0 "register_operand" "=w")
4333 [(match_operand:VD_BHSI 1 "register_operand" "w")
4334 (match_operand:VD_BHSI 2 "register_operand" "w")]
4337 "addp\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
4338 [(set_attr "type" "neon_reduc_add<q>")]
4341 (define_insn "aarch64_addpdi"
4342 [(set (match_operand:DI 0 "register_operand" "=w")
4344 [(match_operand:V2DI 1 "register_operand" "w")]
4348 [(set_attr "type" "neon_reduc_add")]
4353 (define_expand "sqrt<mode>2"
4354 [(set (match_operand:VHSDF 0 "register_operand" "=w")
4355 (sqrt:VHSDF (match_operand:VHSDF 1 "register_operand" "w")))]
4358 if (aarch64_emit_approx_sqrt (operands[0], operands[1], false))
4362 (define_insn "*sqrt<mode>2"
4363 [(set (match_operand:VHSDF 0 "register_operand" "=w")
4364 (sqrt:VHSDF (match_operand:VHSDF 1 "register_operand" "w")))]
4366 "fsqrt\\t%0.<Vtype>, %1.<Vtype>"
4367 [(set_attr "type" "neon_fp_sqrt_<stype><q>")]
4370 ;; Patterns for vector struct loads and stores.
4372 (define_insn "aarch64_simd_ld2<mode>"
4373 [(set (match_operand:OI 0 "register_operand" "=w")
4374 (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")
4375 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4378 "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4379 [(set_attr "type" "neon_load2_2reg<q>")]
4382 (define_insn "aarch64_simd_ld2r<mode>"
4383 [(set (match_operand:OI 0 "register_operand" "=w")
4384 (unspec:OI [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")
4385 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4388 "ld2r\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4389 [(set_attr "type" "neon_load2_all_lanes<q>")]
4392 (define_insn "aarch64_vec_load_lanesoi_lane<mode>"
4393 [(set (match_operand:OI 0 "register_operand" "=w")
4394 (unspec:OI [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")
4395 (match_operand:OI 2 "register_operand" "0")
4396 (match_operand:SI 3 "immediate_operand" "i")
4397 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4401 operands[3] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[3])));
4402 return "ld2\\t{%S0.<Vetype> - %T0.<Vetype>}[%3], %1";
4404 [(set_attr "type" "neon_load2_one_lane")]
4407 (define_expand "vec_load_lanesoi<mode>"
4408 [(set (match_operand:OI 0 "register_operand" "=w")
4409 (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")
4410 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4414 if (BYTES_BIG_ENDIAN)
4416 rtx tmp = gen_reg_rtx (OImode);
4417 rtx mask = aarch64_reverse_mask (<MODE>mode);
4418 emit_insn (gen_aarch64_simd_ld2<mode> (tmp, operands[1]));
4419 emit_insn (gen_aarch64_rev_reglistoi (operands[0], tmp, mask));
4422 emit_insn (gen_aarch64_simd_ld2<mode> (operands[0], operands[1]));
4426 (define_insn "aarch64_simd_st2<mode>"
4427 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
4428 (unspec:OI [(match_operand:OI 1 "register_operand" "w")
4429 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4432 "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
4433 [(set_attr "type" "neon_store2_2reg<q>")]
4436 ;; RTL uses GCC vector extension indices, so flip only for assembly.
4437 (define_insn "aarch64_vec_store_lanesoi_lane<mode>"
4438 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
4439 (unspec:BLK [(match_operand:OI 1 "register_operand" "w")
4440 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4441 (match_operand:SI 2 "immediate_operand" "i")]
4445 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4446 return "st2\\t{%S1.<Vetype> - %T1.<Vetype>}[%2], %0";
4448 [(set_attr "type" "neon_store2_one_lane<q>")]
4451 (define_expand "vec_store_lanesoi<mode>"
4452 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
4453 (unspec:OI [(match_operand:OI 1 "register_operand" "w")
4454 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4458 if (BYTES_BIG_ENDIAN)
4460 rtx tmp = gen_reg_rtx (OImode);
4461 rtx mask = aarch64_reverse_mask (<MODE>mode);
4462 emit_insn (gen_aarch64_rev_reglistoi (tmp, operands[1], mask));
4463 emit_insn (gen_aarch64_simd_st2<mode> (operands[0], tmp));
4466 emit_insn (gen_aarch64_simd_st2<mode> (operands[0], operands[1]));
4470 (define_insn "aarch64_simd_ld3<mode>"
4471 [(set (match_operand:CI 0 "register_operand" "=w")
4472 (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv")
4473 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4476 "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4477 [(set_attr "type" "neon_load3_3reg<q>")]
4480 (define_insn "aarch64_simd_ld3r<mode>"
4481 [(set (match_operand:CI 0 "register_operand" "=w")
4482 (unspec:CI [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")
4483 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4486 "ld3r\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4487 [(set_attr "type" "neon_load3_all_lanes<q>")]
4490 (define_insn "aarch64_vec_load_lanesci_lane<mode>"
4491 [(set (match_operand:CI 0 "register_operand" "=w")
4492 (unspec:CI [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")
4493 (match_operand:CI 2 "register_operand" "0")
4494 (match_operand:SI 3 "immediate_operand" "i")
4495 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4499 operands[3] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[3])));
4500 return "ld3\\t{%S0.<Vetype> - %U0.<Vetype>}[%3], %1";
4502 [(set_attr "type" "neon_load3_one_lane")]
4505 (define_expand "vec_load_lanesci<mode>"
4506 [(set (match_operand:CI 0 "register_operand" "=w")
4507 (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv")
4508 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4512 if (BYTES_BIG_ENDIAN)
4514 rtx tmp = gen_reg_rtx (CImode);
4515 rtx mask = aarch64_reverse_mask (<MODE>mode);
4516 emit_insn (gen_aarch64_simd_ld3<mode> (tmp, operands[1]));
4517 emit_insn (gen_aarch64_rev_reglistci (operands[0], tmp, mask));
4520 emit_insn (gen_aarch64_simd_ld3<mode> (operands[0], operands[1]));
4524 (define_insn "aarch64_simd_st3<mode>"
4525 [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv")
4526 (unspec:CI [(match_operand:CI 1 "register_operand" "w")
4527 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4530 "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
4531 [(set_attr "type" "neon_store3_3reg<q>")]
4534 ;; RTL uses GCC vector extension indices, so flip only for assembly.
4535 (define_insn "aarch64_vec_store_lanesci_lane<mode>"
4536 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
4537 (unspec:BLK [(match_operand:CI 1 "register_operand" "w")
4538 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4539 (match_operand:SI 2 "immediate_operand" "i")]
4543 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4544 return "st3\\t{%S1.<Vetype> - %U1.<Vetype>}[%2], %0";
4546 [(set_attr "type" "neon_store3_one_lane<q>")]
4549 (define_expand "vec_store_lanesci<mode>"
4550 [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv")
4551 (unspec:CI [(match_operand:CI 1 "register_operand" "w")
4552 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4556 if (BYTES_BIG_ENDIAN)
4558 rtx tmp = gen_reg_rtx (CImode);
4559 rtx mask = aarch64_reverse_mask (<MODE>mode);
4560 emit_insn (gen_aarch64_rev_reglistci (tmp, operands[1], mask));
4561 emit_insn (gen_aarch64_simd_st3<mode> (operands[0], tmp));
4564 emit_insn (gen_aarch64_simd_st3<mode> (operands[0], operands[1]));
4568 (define_insn "aarch64_simd_ld4<mode>"
4569 [(set (match_operand:XI 0 "register_operand" "=w")
4570 (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv")
4571 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4574 "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4575 [(set_attr "type" "neon_load4_4reg<q>")]
4578 (define_insn "aarch64_simd_ld4r<mode>"
4579 [(set (match_operand:XI 0 "register_operand" "=w")
4580 (unspec:XI [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")
4581 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY) ]
4584 "ld4r\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4585 [(set_attr "type" "neon_load4_all_lanes<q>")]
4588 (define_insn "aarch64_vec_load_lanesxi_lane<mode>"
4589 [(set (match_operand:XI 0 "register_operand" "=w")
4590 (unspec:XI [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")
4591 (match_operand:XI 2 "register_operand" "0")
4592 (match_operand:SI 3 "immediate_operand" "i")
4593 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4597 operands[3] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[3])));
4598 return "ld4\\t{%S0.<Vetype> - %V0.<Vetype>}[%3], %1";
4600 [(set_attr "type" "neon_load4_one_lane")]
4603 (define_expand "vec_load_lanesxi<mode>"
4604 [(set (match_operand:XI 0 "register_operand" "=w")
4605 (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv")
4606 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4610 if (BYTES_BIG_ENDIAN)
4612 rtx tmp = gen_reg_rtx (XImode);
4613 rtx mask = aarch64_reverse_mask (<MODE>mode);
4614 emit_insn (gen_aarch64_simd_ld4<mode> (tmp, operands[1]));
4615 emit_insn (gen_aarch64_rev_reglistxi (operands[0], tmp, mask));
4618 emit_insn (gen_aarch64_simd_ld4<mode> (operands[0], operands[1]));
4622 (define_insn "aarch64_simd_st4<mode>"
4623 [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
4624 (unspec:XI [(match_operand:XI 1 "register_operand" "w")
4625 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4628 "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
4629 [(set_attr "type" "neon_store4_4reg<q>")]
4632 ;; RTL uses GCC vector extension indices, so flip only for assembly.
4633 (define_insn "aarch64_vec_store_lanesxi_lane<mode>"
4634 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
4635 (unspec:BLK [(match_operand:XI 1 "register_operand" "w")
4636 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
4637 (match_operand:SI 2 "immediate_operand" "i")]
4641 operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
4642 return "st4\\t{%S1.<Vetype> - %V1.<Vetype>}[%2], %0";
4644 [(set_attr "type" "neon_store4_one_lane<q>")]
4647 (define_expand "vec_store_lanesxi<mode>"
4648 [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
4649 (unspec:XI [(match_operand:XI 1 "register_operand" "w")
4650 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4654 if (BYTES_BIG_ENDIAN)
4656 rtx tmp = gen_reg_rtx (XImode);
4657 rtx mask = aarch64_reverse_mask (<MODE>mode);
4658 emit_insn (gen_aarch64_rev_reglistxi (tmp, operands[1], mask));
4659 emit_insn (gen_aarch64_simd_st4<mode> (operands[0], tmp));
4662 emit_insn (gen_aarch64_simd_st4<mode> (operands[0], operands[1]));
4666 (define_insn_and_split "aarch64_rev_reglist<mode>"
4667 [(set (match_operand:VSTRUCT 0 "register_operand" "=&w")
4669 [(match_operand:VSTRUCT 1 "register_operand" "w")
4670 (match_operand:V16QI 2 "register_operand" "w")]
4671 UNSPEC_REV_REGLIST))]
4674 "&& reload_completed"
4678 int nregs = GET_MODE_SIZE (<MODE>mode) / UNITS_PER_VREG;
4679 for (i = 0; i < nregs; i++)
4681 rtx op0 = gen_rtx_REG (V16QImode, REGNO (operands[0]) + i);
4682 rtx op1 = gen_rtx_REG (V16QImode, REGNO (operands[1]) + i);
4683 emit_insn (gen_aarch64_tbl1v16qi (op0, op1, operands[2]));
4687 [(set_attr "type" "neon_tbl1_q")
4688 (set_attr "length" "<insn_count>")]
4691 ;; Reload patterns for AdvSIMD register list operands.
4693 (define_expand "mov<mode>"
4694 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
4695 (match_operand:VSTRUCT 1 "general_operand" ""))]
4698 if (can_create_pseudo_p ())
4700 if (GET_CODE (operands[0]) != REG)
4701 operands[1] = force_reg (<MODE>mode, operands[1]);
4705 (define_insn "*aarch64_mov<mode>"
4706 [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "=w,Utv,w")
4707 (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" " w,w,Utv"))]
4708 "TARGET_SIMD && !BYTES_BIG_ENDIAN
4709 && (register_operand (operands[0], <MODE>mode)
4710 || register_operand (operands[1], <MODE>mode))"
4713 st1\\t{%S1.16b - %<Vendreg>1.16b}, %0
4714 ld1\\t{%S0.16b - %<Vendreg>0.16b}, %1"
4715 [(set_attr "type" "multiple,neon_store<nregs>_<nregs>reg_q,\
4716 neon_load<nregs>_<nregs>reg_q")
4717 (set_attr "length" "<insn_count>,4,4")]
4720 (define_insn "aarch64_be_ld1<mode>"
4721 [(set (match_operand:VALLDI_F16 0 "register_operand" "=w")
4722 (unspec:VALLDI_F16 [(match_operand:VALLDI_F16 1
4723 "aarch64_simd_struct_operand" "Utv")]
4726 "ld1\\t{%0<Vmtype>}, %1"
4727 [(set_attr "type" "neon_load1_1reg<q>")]
4730 (define_insn "aarch64_be_st1<mode>"
4731 [(set (match_operand:VALLDI_F16 0 "aarch64_simd_struct_operand" "=Utv")
4732 (unspec:VALLDI_F16 [(match_operand:VALLDI_F16 1 "register_operand" "w")]
4735 "st1\\t{%1<Vmtype>}, %0"
4736 [(set_attr "type" "neon_store1_1reg<q>")]
4739 (define_insn "*aarch64_be_movoi"
4740 [(set (match_operand:OI 0 "nonimmediate_operand" "=w,m,w")
4741 (match_operand:OI 1 "general_operand" " w,w,m"))]
4742 "TARGET_SIMD && BYTES_BIG_ENDIAN
4743 && (register_operand (operands[0], OImode)
4744 || register_operand (operands[1], OImode))"
4749 [(set_attr "type" "multiple,neon_stp_q,neon_ldp_q")
4750 (set_attr "length" "8,4,4")]
4753 (define_insn "*aarch64_be_movci"
4754 [(set (match_operand:CI 0 "nonimmediate_operand" "=w,o,w")
4755 (match_operand:CI 1 "general_operand" " w,w,o"))]
4756 "TARGET_SIMD && BYTES_BIG_ENDIAN
4757 && (register_operand (operands[0], CImode)
4758 || register_operand (operands[1], CImode))"
4760 [(set_attr "type" "multiple")
4761 (set_attr "length" "12,4,4")]
4764 (define_insn "*aarch64_be_movxi"
4765 [(set (match_operand:XI 0 "nonimmediate_operand" "=w,o,w")
4766 (match_operand:XI 1 "general_operand" " w,w,o"))]
4767 "TARGET_SIMD && BYTES_BIG_ENDIAN
4768 && (register_operand (operands[0], XImode)
4769 || register_operand (operands[1], XImode))"
4771 [(set_attr "type" "multiple")
4772 (set_attr "length" "16,4,4")]
4776 [(set (match_operand:OI 0 "register_operand")
4777 (match_operand:OI 1 "register_operand"))]
4778 "TARGET_SIMD && reload_completed"
4781 aarch64_simd_emit_reg_reg_move (operands, TImode, 2);
4786 [(set (match_operand:CI 0 "nonimmediate_operand")
4787 (match_operand:CI 1 "general_operand"))]
4788 "TARGET_SIMD && reload_completed"
4791 if (register_operand (operands[0], CImode)
4792 && register_operand (operands[1], CImode))
4794 aarch64_simd_emit_reg_reg_move (operands, TImode, 3);
4797 else if (BYTES_BIG_ENDIAN)
4799 emit_move_insn (simplify_gen_subreg (OImode, operands[0], CImode, 0),
4800 simplify_gen_subreg (OImode, operands[1], CImode, 0));
4801 emit_move_insn (gen_lowpart (V16QImode,
4802 simplify_gen_subreg (TImode, operands[0],
4804 gen_lowpart (V16QImode,
4805 simplify_gen_subreg (TImode, operands[1],
4814 [(set (match_operand:XI 0 "nonimmediate_operand")
4815 (match_operand:XI 1 "general_operand"))]
4816 "TARGET_SIMD && reload_completed"
4819 if (register_operand (operands[0], XImode)
4820 && register_operand (operands[1], XImode))
4822 aarch64_simd_emit_reg_reg_move (operands, TImode, 4);
4825 else if (BYTES_BIG_ENDIAN)
4827 emit_move_insn (simplify_gen_subreg (OImode, operands[0], XImode, 0),
4828 simplify_gen_subreg (OImode, operands[1], XImode, 0));
4829 emit_move_insn (simplify_gen_subreg (OImode, operands[0], XImode, 32),
4830 simplify_gen_subreg (OImode, operands[1], XImode, 32));
4837 (define_expand "aarch64_ld<VSTRUCT:nregs>r<VALLDIF:mode>"
4838 [(match_operand:VSTRUCT 0 "register_operand" "=w")
4839 (match_operand:DI 1 "register_operand" "w")
4840 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4843 rtx mem = gen_rtx_MEM (BLKmode, operands[1]);
4844 set_mem_size (mem, GET_MODE_SIZE (GET_MODE_INNER (<VALLDIF:MODE>mode))
4847 emit_insn (gen_aarch64_simd_ld<VSTRUCT:nregs>r<VALLDIF:mode> (operands[0],
4852 (define_insn "aarch64_ld2<mode>_dreg"
4853 [(set (match_operand:OI 0 "register_operand" "=w")
4858 [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")]
4860 (vec_duplicate:VD (const_int 0)))
4862 (unspec:VD [(match_dup 1)]
4864 (vec_duplicate:VD (const_int 0)))) 0))]
4866 "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
4867 [(set_attr "type" "neon_load2_2reg<q>")]
4870 (define_insn "aarch64_ld2<mode>_dreg"
4871 [(set (match_operand:OI 0 "register_operand" "=w")
4876 [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")]
4880 (unspec:DX [(match_dup 1)]
4882 (const_int 0))) 0))]
4884 "ld1\\t{%S0.1d - %T0.1d}, %1"
4885 [(set_attr "type" "neon_load1_2reg<q>")]
4888 (define_insn "aarch64_ld3<mode>_dreg"
4889 [(set (match_operand:CI 0 "register_operand" "=w")
4895 [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")]
4897 (vec_duplicate:VD (const_int 0)))
4899 (unspec:VD [(match_dup 1)]
4901 (vec_duplicate:VD (const_int 0))))
4903 (unspec:VD [(match_dup 1)]
4905 (vec_duplicate:VD (const_int 0)))) 0))]
4907 "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
4908 [(set_attr "type" "neon_load3_3reg<q>")]
4911 (define_insn "aarch64_ld3<mode>_dreg"
4912 [(set (match_operand:CI 0 "register_operand" "=w")
4918 [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")]
4922 (unspec:DX [(match_dup 1)]
4926 (unspec:DX [(match_dup 1)]
4928 (const_int 0))) 0))]
4930 "ld1\\t{%S0.1d - %U0.1d}, %1"
4931 [(set_attr "type" "neon_load1_3reg<q>")]
4934 (define_insn "aarch64_ld4<mode>_dreg"
4935 [(set (match_operand:XI 0 "register_operand" "=w")
4941 [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")]
4943 (vec_duplicate:VD (const_int 0)))
4945 (unspec:VD [(match_dup 1)]
4947 (vec_duplicate:VD (const_int 0))))
4950 (unspec:VD [(match_dup 1)]
4952 (vec_duplicate:VD (const_int 0)))
4954 (unspec:VD [(match_dup 1)]
4956 (vec_duplicate:VD (const_int 0))))) 0))]
4958 "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
4959 [(set_attr "type" "neon_load4_4reg<q>")]
4962 (define_insn "aarch64_ld4<mode>_dreg"
4963 [(set (match_operand:XI 0 "register_operand" "=w")
4969 [(match_operand:BLK 1 "aarch64_simd_struct_operand" "Utv")]
4973 (unspec:DX [(match_dup 1)]
4978 (unspec:DX [(match_dup 1)]
4982 (unspec:DX [(match_dup 1)]
4984 (const_int 0)))) 0))]
4986 "ld1\\t{%S0.1d - %V0.1d}, %1"
4987 [(set_attr "type" "neon_load1_4reg<q>")]
4990 (define_expand "aarch64_ld<VSTRUCT:nregs><VDC:mode>"
4991 [(match_operand:VSTRUCT 0 "register_operand" "=w")
4992 (match_operand:DI 1 "register_operand" "r")
4993 (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4996 rtx mem = gen_rtx_MEM (BLKmode, operands[1]);
4997 set_mem_size (mem, <VSTRUCT:nregs> * 8);
4999 emit_insn (gen_aarch64_ld<VSTRUCT:nregs><VDC:mode>_dreg (operands[0], mem));
5003 (define_expand "aarch64_ld1<VALL_F16:mode>"
5004 [(match_operand:VALL_F16 0 "register_operand")
5005 (match_operand:DI 1 "register_operand")]
5008 machine_mode mode = <VALL_F16:MODE>mode;
5009 rtx mem = gen_rtx_MEM (mode, operands[1]);
5011 if (BYTES_BIG_ENDIAN)
5012 emit_insn (gen_aarch64_be_ld1<VALL_F16:mode> (operands[0], mem));
5014 emit_move_insn (operands[0], mem);
5018 (define_expand "aarch64_ld<VSTRUCT:nregs><VQ:mode>"
5019 [(match_operand:VSTRUCT 0 "register_operand" "=w")
5020 (match_operand:DI 1 "register_operand" "r")
5021 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5024 machine_mode mode = <VSTRUCT:MODE>mode;
5025 rtx mem = gen_rtx_MEM (mode, operands[1]);
5027 emit_insn (gen_aarch64_simd_ld<VSTRUCT:nregs><VQ:mode> (operands[0], mem));
5031 (define_expand "aarch64_ld<VSTRUCT:nregs>_lane<VALLDIF:mode>"
5032 [(match_operand:VSTRUCT 0 "register_operand" "=w")
5033 (match_operand:DI 1 "register_operand" "w")
5034 (match_operand:VSTRUCT 2 "register_operand" "0")
5035 (match_operand:SI 3 "immediate_operand" "i")
5036 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5039 rtx mem = gen_rtx_MEM (BLKmode, operands[1]);
5040 set_mem_size (mem, GET_MODE_SIZE (GET_MODE_INNER (<VALLDIF:MODE>mode))
5043 aarch64_simd_lane_bounds (operands[3], 0,
5044 GET_MODE_NUNITS (<VALLDIF:MODE>mode),
5046 emit_insn (gen_aarch64_vec_load_lanes<VSTRUCT:mode>_lane<VALLDIF:mode> (
5047 operands[0], mem, operands[2], operands[3]));
5051 ;; Expanders for builtins to extract vector registers from large
5052 ;; opaque integer modes.
5056 (define_expand "aarch64_get_dreg<VSTRUCT:mode><VDC:mode>"
5057 [(match_operand:VDC 0 "register_operand" "=w")
5058 (match_operand:VSTRUCT 1 "register_operand" "w")
5059 (match_operand:SI 2 "immediate_operand" "i")]
5062 int part = INTVAL (operands[2]);
5063 rtx temp = gen_reg_rtx (<VDC:VDBL>mode);
5064 int offset = part * 16;
5066 emit_move_insn (temp, gen_rtx_SUBREG (<VDC:VDBL>mode, operands[1], offset));
5067 emit_move_insn (operands[0], gen_lowpart (<VDC:MODE>mode, temp));
5073 (define_expand "aarch64_get_qreg<VSTRUCT:mode><VQ:mode>"
5074 [(match_operand:VQ 0 "register_operand" "=w")
5075 (match_operand:VSTRUCT 1 "register_operand" "w")
5076 (match_operand:SI 2 "immediate_operand" "i")]
5079 int part = INTVAL (operands[2]);
5080 int offset = part * 16;
5082 emit_move_insn (operands[0],
5083 gen_rtx_SUBREG (<VQ:MODE>mode, operands[1], offset));
5087 ;; Permuted-store expanders for neon intrinsics.
5089 ;; Permute instructions
5093 (define_expand "vec_perm_const<mode>"
5094 [(match_operand:VALL_F16 0 "register_operand")
5095 (match_operand:VALL_F16 1 "register_operand")
5096 (match_operand:VALL_F16 2 "register_operand")
5097 (match_operand:<V_cmp_result> 3)]
5100 if (aarch64_expand_vec_perm_const (operands[0], operands[1],
5101 operands[2], operands[3]))
5107 (define_expand "vec_perm<mode>"
5108 [(match_operand:VB 0 "register_operand")
5109 (match_operand:VB 1 "register_operand")
5110 (match_operand:VB 2 "register_operand")
5111 (match_operand:VB 3 "register_operand")]
5114 aarch64_expand_vec_perm (operands[0], operands[1],
5115 operands[2], operands[3]);
5119 (define_insn "aarch64_tbl1<mode>"
5120 [(set (match_operand:VB 0 "register_operand" "=w")
5121 (unspec:VB [(match_operand:V16QI 1 "register_operand" "w")
5122 (match_operand:VB 2 "register_operand" "w")]
5125 "tbl\\t%0.<Vtype>, {%1.16b}, %2.<Vtype>"
5126 [(set_attr "type" "neon_tbl1<q>")]
5129 ;; Two source registers.
5131 (define_insn "aarch64_tbl2v16qi"
5132 [(set (match_operand:V16QI 0 "register_operand" "=w")
5133 (unspec:V16QI [(match_operand:OI 1 "register_operand" "w")
5134 (match_operand:V16QI 2 "register_operand" "w")]
5137 "tbl\\t%0.16b, {%S1.16b - %T1.16b}, %2.16b"
5138 [(set_attr "type" "neon_tbl2_q")]
5141 (define_insn "aarch64_tbl3<mode>"
5142 [(set (match_operand:VB 0 "register_operand" "=w")
5143 (unspec:VB [(match_operand:OI 1 "register_operand" "w")
5144 (match_operand:VB 2 "register_operand" "w")]
5147 "tbl\\t%S0.<Vbtype>, {%S1.16b - %T1.16b}, %S2.<Vbtype>"
5148 [(set_attr "type" "neon_tbl3")]
5151 (define_insn "aarch64_tbx4<mode>"
5152 [(set (match_operand:VB 0 "register_operand" "=w")
5153 (unspec:VB [(match_operand:VB 1 "register_operand" "0")
5154 (match_operand:OI 2 "register_operand" "w")
5155 (match_operand:VB 3 "register_operand" "w")]
5158 "tbx\\t%S0.<Vbtype>, {%S2.16b - %T2.16b}, %S3.<Vbtype>"
5159 [(set_attr "type" "neon_tbl4")]
5162 ;; Three source registers.
5164 (define_insn "aarch64_qtbl3<mode>"
5165 [(set (match_operand:VB 0 "register_operand" "=w")
5166 (unspec:VB [(match_operand:CI 1 "register_operand" "w")
5167 (match_operand:VB 2 "register_operand" "w")]
5170 "tbl\\t%S0.<Vbtype>, {%S1.16b - %U1.16b}, %S2.<Vbtype>"
5171 [(set_attr "type" "neon_tbl3")]
5174 (define_insn "aarch64_qtbx3<mode>"
5175 [(set (match_operand:VB 0 "register_operand" "=w")
5176 (unspec:VB [(match_operand:VB 1 "register_operand" "0")
5177 (match_operand:CI 2 "register_operand" "w")
5178 (match_operand:VB 3 "register_operand" "w")]
5181 "tbx\\t%S0.<Vbtype>, {%S2.16b - %U2.16b}, %S3.<Vbtype>"
5182 [(set_attr "type" "neon_tbl3")]
5185 ;; Four source registers.
5187 (define_insn "aarch64_qtbl4<mode>"
5188 [(set (match_operand:VB 0 "register_operand" "=w")
5189 (unspec:VB [(match_operand:XI 1 "register_operand" "w")
5190 (match_operand:VB 2 "register_operand" "w")]
5193 "tbl\\t%S0.<Vbtype>, {%S1.16b - %V1.16b}, %S2.<Vbtype>"
5194 [(set_attr "type" "neon_tbl4")]
5197 (define_insn "aarch64_qtbx4<mode>"
5198 [(set (match_operand:VB 0 "register_operand" "=w")
5199 (unspec:VB [(match_operand:VB 1 "register_operand" "0")
5200 (match_operand:XI 2 "register_operand" "w")
5201 (match_operand:VB 3 "register_operand" "w")]
5204 "tbx\\t%S0.<Vbtype>, {%S2.16b - %V2.16b}, %S3.<Vbtype>"
5205 [(set_attr "type" "neon_tbl4")]
5208 (define_insn_and_split "aarch64_combinev16qi"
5209 [(set (match_operand:OI 0 "register_operand" "=w")
5210 (unspec:OI [(match_operand:V16QI 1 "register_operand" "w")
5211 (match_operand:V16QI 2 "register_operand" "w")]
5215 "&& reload_completed"
5218 aarch64_split_combinev16qi (operands);
5221 [(set_attr "type" "multiple")]
5224 (define_insn "aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>"
5225 [(set (match_operand:VALL_F16 0 "register_operand" "=w")
5226 (unspec:VALL_F16 [(match_operand:VALL_F16 1 "register_operand" "w")
5227 (match_operand:VALL_F16 2 "register_operand" "w")]
5230 "<PERMUTE:perm_insn><PERMUTE:perm_hilo>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
5231 [(set_attr "type" "neon_permute<q>")]
5234 ;; Note immediate (third) operand is lane index not byte index.
5235 (define_insn "aarch64_ext<mode>"
5236 [(set (match_operand:VALL_F16 0 "register_operand" "=w")
5237 (unspec:VALL_F16 [(match_operand:VALL_F16 1 "register_operand" "w")
5238 (match_operand:VALL_F16 2 "register_operand" "w")
5239 (match_operand:SI 3 "immediate_operand" "i")]
5243 operands[3] = GEN_INT (INTVAL (operands[3])
5244 * GET_MODE_UNIT_SIZE (<MODE>mode));
5245 return "ext\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>, #%3";
5247 [(set_attr "type" "neon_ext<q>")]
5250 (define_insn "aarch64_rev<REVERSE:rev_op><mode>"
5251 [(set (match_operand:VALL_F16 0 "register_operand" "=w")
5252 (unspec:VALL_F16 [(match_operand:VALL_F16 1 "register_operand" "w")]
5255 "rev<REVERSE:rev_op>\\t%0.<Vtype>, %1.<Vtype>"
5256 [(set_attr "type" "neon_rev<q>")]
5259 (define_insn "aarch64_st2<mode>_dreg"
5260 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
5261 (unspec:BLK [(match_operand:OI 1 "register_operand" "w")
5262 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5265 "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
5266 [(set_attr "type" "neon_store2_2reg")]
5269 (define_insn "aarch64_st2<mode>_dreg"
5270 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
5271 (unspec:BLK [(match_operand:OI 1 "register_operand" "w")
5272 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5275 "st1\\t{%S1.1d - %T1.1d}, %0"
5276 [(set_attr "type" "neon_store1_2reg")]
5279 (define_insn "aarch64_st3<mode>_dreg"
5280 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
5281 (unspec:BLK [(match_operand:CI 1 "register_operand" "w")
5282 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5285 "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
5286 [(set_attr "type" "neon_store3_3reg")]
5289 (define_insn "aarch64_st3<mode>_dreg"
5290 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
5291 (unspec:BLK [(match_operand:CI 1 "register_operand" "w")
5292 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5295 "st1\\t{%S1.1d - %U1.1d}, %0"
5296 [(set_attr "type" "neon_store1_3reg")]
5299 (define_insn "aarch64_st4<mode>_dreg"
5300 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
5301 (unspec:BLK [(match_operand:XI 1 "register_operand" "w")
5302 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5305 "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
5306 [(set_attr "type" "neon_store4_4reg")]
5309 (define_insn "aarch64_st4<mode>_dreg"
5310 [(set (match_operand:BLK 0 "aarch64_simd_struct_operand" "=Utv")
5311 (unspec:BLK [(match_operand:XI 1 "register_operand" "w")
5312 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5315 "st1\\t{%S1.1d - %V1.1d}, %0"
5316 [(set_attr "type" "neon_store1_4reg")]
5319 (define_expand "aarch64_st<VSTRUCT:nregs><VDC:mode>"
5320 [(match_operand:DI 0 "register_operand" "r")
5321 (match_operand:VSTRUCT 1 "register_operand" "w")
5322 (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5325 rtx mem = gen_rtx_MEM (BLKmode, operands[0]);
5326 set_mem_size (mem, <VSTRUCT:nregs> * 8);
5328 emit_insn (gen_aarch64_st<VSTRUCT:nregs><VDC:mode>_dreg (mem, operands[1]));
5332 (define_expand "aarch64_st<VSTRUCT:nregs><VQ:mode>"
5333 [(match_operand:DI 0 "register_operand" "r")
5334 (match_operand:VSTRUCT 1 "register_operand" "w")
5335 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5338 machine_mode mode = <VSTRUCT:MODE>mode;
5339 rtx mem = gen_rtx_MEM (mode, operands[0]);
5341 emit_insn (gen_aarch64_simd_st<VSTRUCT:nregs><VQ:mode> (mem, operands[1]));
5345 (define_expand "aarch64_st<VSTRUCT:nregs>_lane<VALLDIF:mode>"
5346 [(match_operand:DI 0 "register_operand" "r")
5347 (match_operand:VSTRUCT 1 "register_operand" "w")
5348 (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
5349 (match_operand:SI 2 "immediate_operand")]
5352 rtx mem = gen_rtx_MEM (BLKmode, operands[0]);
5353 set_mem_size (mem, GET_MODE_SIZE (GET_MODE_INNER (<VALLDIF:MODE>mode))
5356 emit_insn (gen_aarch64_vec_store_lanes<VSTRUCT:mode>_lane<VALLDIF:mode> (
5357 mem, operands[1], operands[2]));
5361 (define_expand "aarch64_st1<VALL_F16:mode>"
5362 [(match_operand:DI 0 "register_operand")
5363 (match_operand:VALL_F16 1 "register_operand")]
5366 machine_mode mode = <VALL_F16:MODE>mode;
5367 rtx mem = gen_rtx_MEM (mode, operands[0]);
5369 if (BYTES_BIG_ENDIAN)
5370 emit_insn (gen_aarch64_be_st1<VALL_F16:mode> (mem, operands[1]));
5372 emit_move_insn (mem, operands[1]);
5376 ;; Expander for builtins to insert vector registers into large
5377 ;; opaque integer modes.
5379 ;; Q-register list. We don't need a D-reg inserter as we zero
5380 ;; extend them in arm_neon.h and insert the resulting Q-regs.
5382 (define_expand "aarch64_set_qreg<VSTRUCT:mode><VQ:mode>"
5383 [(match_operand:VSTRUCT 0 "register_operand" "+w")
5384 (match_operand:VSTRUCT 1 "register_operand" "0")
5385 (match_operand:VQ 2 "register_operand" "w")
5386 (match_operand:SI 3 "immediate_operand" "i")]
5389 int part = INTVAL (operands[3]);
5390 int offset = part * 16;
5392 emit_move_insn (operands[0], operands[1]);
5393 emit_move_insn (gen_rtx_SUBREG (<VQ:MODE>mode, operands[0], offset),
5398 ;; Standard pattern name vec_init<mode>.
5400 (define_expand "vec_init<mode>"
5401 [(match_operand:VALL_F16 0 "register_operand" "")
5402 (match_operand 1 "" "")]
5405 aarch64_expand_vector_init (operands[0], operands[1]);
5409 (define_insn "*aarch64_simd_ld1r<mode>"
5410 [(set (match_operand:VALL_F16 0 "register_operand" "=w")
5411 (vec_duplicate:VALL_F16
5412 (match_operand:<VEL> 1 "aarch64_simd_struct_operand" "Utv")))]
5414 "ld1r\\t{%0.<Vtype>}, %1"
5415 [(set_attr "type" "neon_load1_all_lanes")]
5418 (define_insn "aarch64_frecpe<mode>"
5419 [(set (match_operand:VHSDF 0 "register_operand" "=w")
5420 (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")]
5423 "frecpe\\t%0.<Vtype>, %1.<Vtype>"
5424 [(set_attr "type" "neon_fp_recpe_<stype><q>")]
5427 (define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
5428 [(set (match_operand:GPF 0 "register_operand" "=w")
5429 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
5432 "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
5433 [(set_attr "type" "neon_fp_recp<FRECP:frecp_suffix>_<GPF:Vetype><GPF:q>")]
5436 (define_insn "aarch64_frecps<mode>"
5437 [(set (match_operand:VHSDF_SDF 0 "register_operand" "=w")
5439 [(match_operand:VHSDF_SDF 1 "register_operand" "w")
5440 (match_operand:VHSDF_SDF 2 "register_operand" "w")]
5443 "frecps\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
5444 [(set_attr "type" "neon_fp_recps_<stype><q>")]
5447 (define_insn "aarch64_urecpe<mode>"
5448 [(set (match_operand:VDQ_SI 0 "register_operand" "=w")
5449 (unspec:VDQ_SI [(match_operand:VDQ_SI 1 "register_operand" "w")]
5452 "urecpe\\t%0.<Vtype>, %1.<Vtype>"
5453 [(set_attr "type" "neon_fp_recpe_<Vetype><q>")])
5455 ;; Standard pattern name vec_extract<mode>.
5457 (define_expand "vec_extract<mode>"
5458 [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "")
5459 (match_operand:VALL_F16 1 "register_operand" "")
5460 (match_operand:SI 2 "immediate_operand" "")]
5464 (gen_aarch64_get_lane<mode> (operands[0], operands[1], operands[2]));
5470 (define_insn "aarch64_crypto_aes<aes_op>v16qi"
5471 [(set (match_operand:V16QI 0 "register_operand" "=w")
5472 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
5473 (match_operand:V16QI 2 "register_operand" "w")]
5475 "TARGET_SIMD && TARGET_CRYPTO"
5476 "aes<aes_op>\\t%0.16b, %2.16b"
5477 [(set_attr "type" "crypto_aese")]
5480 ;; When AES/AESMC fusion is enabled we want the register allocation to
5484 ;; So prefer to tie operand 1 to operand 0 when fusing.
5486 (define_insn "aarch64_crypto_aes<aesmc_op>v16qi"
5487 [(set (match_operand:V16QI 0 "register_operand" "=w,w")
5488 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0,w")]
5490 "TARGET_SIMD && TARGET_CRYPTO"
5491 "aes<aesmc_op>\\t%0.16b, %1.16b"
5492 [(set_attr "type" "crypto_aesmc")
5493 (set_attr_alternative "enabled"
5494 [(if_then_else (match_test
5495 "aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)")
5496 (const_string "yes" )
5497 (const_string "no"))
5498 (const_string "yes")])]
5503 (define_insn "aarch64_crypto_sha1hsi"
5504 [(set (match_operand:SI 0 "register_operand" "=w")
5505 (unspec:SI [(match_operand:SI 1
5506 "register_operand" "w")]
5508 "TARGET_SIMD && TARGET_CRYPTO"
5510 [(set_attr "type" "crypto_sha1_fast")]
5513 (define_insn "aarch64_crypto_sha1su1v4si"
5514 [(set (match_operand:V4SI 0 "register_operand" "=w")
5515 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5516 (match_operand:V4SI 2 "register_operand" "w")]
5518 "TARGET_SIMD && TARGET_CRYPTO"
5519 "sha1su1\\t%0.4s, %2.4s"
5520 [(set_attr "type" "crypto_sha1_fast")]
5523 (define_insn "aarch64_crypto_sha1<sha1_op>v4si"
5524 [(set (match_operand:V4SI 0 "register_operand" "=w")
5525 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5526 (match_operand:SI 2 "register_operand" "w")
5527 (match_operand:V4SI 3 "register_operand" "w")]
5529 "TARGET_SIMD && TARGET_CRYPTO"
5530 "sha1<sha1_op>\\t%q0, %s2, %3.4s"
5531 [(set_attr "type" "crypto_sha1_slow")]
5534 (define_insn "aarch64_crypto_sha1su0v4si"
5535 [(set (match_operand:V4SI 0 "register_operand" "=w")
5536 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5537 (match_operand:V4SI 2 "register_operand" "w")
5538 (match_operand:V4SI 3 "register_operand" "w")]
5540 "TARGET_SIMD && TARGET_CRYPTO"
5541 "sha1su0\\t%0.4s, %2.4s, %3.4s"
5542 [(set_attr "type" "crypto_sha1_xor")]
5547 (define_insn "aarch64_crypto_sha256h<sha256_op>v4si"
5548 [(set (match_operand:V4SI 0 "register_operand" "=w")
5549 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5550 (match_operand:V4SI 2 "register_operand" "w")
5551 (match_operand:V4SI 3 "register_operand" "w")]
5553 "TARGET_SIMD && TARGET_CRYPTO"
5554 "sha256h<sha256_op>\\t%q0, %q2, %3.4s"
5555 [(set_attr "type" "crypto_sha256_slow")]
5558 (define_insn "aarch64_crypto_sha256su0v4si"
5559 [(set (match_operand:V4SI 0 "register_operand" "=w")
5560 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5561 (match_operand:V4SI 2 "register_operand" "w")]
5563 "TARGET_SIMD &&TARGET_CRYPTO"
5564 "sha256su0\\t%0.4s, %2.4s"
5565 [(set_attr "type" "crypto_sha256_fast")]
5568 (define_insn "aarch64_crypto_sha256su1v4si"
5569 [(set (match_operand:V4SI 0 "register_operand" "=w")
5570 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
5571 (match_operand:V4SI 2 "register_operand" "w")
5572 (match_operand:V4SI 3 "register_operand" "w")]
5574 "TARGET_SIMD &&TARGET_CRYPTO"
5575 "sha256su1\\t%0.4s, %2.4s, %3.4s"
5576 [(set_attr "type" "crypto_sha256_slow")]
5581 (define_insn "aarch64_crypto_pmulldi"
5582 [(set (match_operand:TI 0 "register_operand" "=w")
5583 (unspec:TI [(match_operand:DI 1 "register_operand" "w")
5584 (match_operand:DI 2 "register_operand" "w")]
5586 "TARGET_SIMD && TARGET_CRYPTO"
5587 "pmull\\t%0.1q, %1.1d, %2.1d"
5588 [(set_attr "type" "neon_mul_d_long")]
5591 (define_insn "aarch64_crypto_pmullv2di"
5592 [(set (match_operand:TI 0 "register_operand" "=w")
5593 (unspec:TI [(match_operand:V2DI 1 "register_operand" "w")
5594 (match_operand:V2DI 2 "register_operand" "w")]
5596 "TARGET_SIMD && TARGET_CRYPTO"
5597 "pmull2\\t%0.1q, %1.2d, %2.2d"
5598 [(set_attr "type" "neon_mul_d_long")]