1 ;; ARM NEON coprocessor Machine Description
2 ;; Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery.
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 ;; Constants for unspecs.
23 [(UNSPEC_ASHIFT_SIGNED 65)
24 (UNSPEC_ASHIFT_UNSIGNED 66)
45 (UNSPEC_VLD1_LANE 101)
48 (UNSPEC_VLD2_LANE 104)
53 (UNSPEC_VLD3_LANE 109)
58 (UNSPEC_VLD4_LANE 114)
63 (UNSPEC_VMLA_LANE 119)
64 (UNSPEC_VMLAL_LANE 120)
67 (UNSPEC_VMLS_LANE 123)
68 (UNSPEC_VMLSL_LANE 124)
73 (UNSPEC_VMUL_LANE 129)
74 (UNSPEC_VMULL_LANE 130)
87 (UNSPEC_VQDMLAL_LANE 147)
89 (UNSPEC_VQDMLSL_LANE 149)
91 (UNSPEC_VQDMULH_LANE 151)
93 (UNSPEC_VQDMULL_LANE 153)
100 (UNSPEC_VQSHRN_N 160)
101 (UNSPEC_VQSHRUN_N 161)
119 (UNSPEC_VST1_LANE 180)
121 (UNSPEC_VST2_LANE 182)
125 (UNSPEC_VST3_LANE 186)
129 (UNSPEC_VST4_LANE 190)
130 (UNSPEC_VSTRUCTDUMMY 191)
144 (UNSPEC_MISALIGNED_ACCESS 205)
149 ;; Attribute used to permit string comparisons against <VQH_mnem> in
150 ;; neon_type attribute definitions.
151 (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
153 (define_insn "*neon_mov<mode>"
154 [(set (match_operand:VD 0 "nonimmediate_operand"
155 "=w,Uv,w, w, ?r,?w,?r,?r, ?Us")
156 (match_operand:VD 1 "general_operand"
157 " w,w, Dn,Uvi, w, r, r, Usi,r"))]
159 && (register_operand (operands[0], <MODE>mode)
160 || register_operand (operands[1], <MODE>mode))"
162 if (which_alternative == 2)
165 static char templ[40];
167 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
168 &operands[1], &width);
170 gcc_assert (is_valid != 0);
173 return "vmov.f32\t%P0, %1 @ <mode>";
175 sprintf (templ, "vmov.i%d\t%%P0, %%1 @ <mode>", width);
180 /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
181 below must be changed to output_move_neon (which will use the
182 element/structure loads/stores), and the constraint changed to 'Um' instead
185 switch (which_alternative)
187 case 0: return "vmov\t%P0, %P1 @ <mode>";
188 case 1: case 3: return output_move_vfp (operands);
189 case 2: gcc_unreachable ();
190 case 4: return "vmov\t%Q0, %R0, %P1 @ <mode>";
191 case 5: return "vmov\t%P0, %Q1, %R1 @ <mode>";
192 default: return output_move_double (operands);
195 [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
196 (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu,load2,store2")
197 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
198 (set_attr "length" "4,4,4,4,4,4,8,8,8")
199 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
200 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
202 (define_insn "*neon_mov<mode>"
203 [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
204 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
205 (match_operand:VQXMOV 1 "general_operand"
206 " w,w, Dn,Uni, w, r, r, Usi, r"))]
208 && (register_operand (operands[0], <MODE>mode)
209 || register_operand (operands[1], <MODE>mode))"
211 if (which_alternative == 2)
214 static char templ[40];
216 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
217 &operands[1], &width);
219 gcc_assert (is_valid != 0);
222 return "vmov.f32\t%q0, %1 @ <mode>";
224 sprintf (templ, "vmov.i%d\t%%q0, %%1 @ <mode>", width);
229 switch (which_alternative)
231 case 0: return "vmov\t%q0, %q1 @ <mode>";
232 case 1: case 3: return output_move_neon (operands);
233 case 2: gcc_unreachable ();
234 case 4: return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1";
235 case 5: return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1";
236 default: return output_move_quad (operands);
239 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
240 neon_mrrc,neon_mcr_2_mcrr,*,*,*")
241 (set_attr "type" "*,*,*,*,*,*,alu,load4,store4")
242 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
243 (set_attr "length" "4,8,4,8,8,8,16,8,16")
244 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
245 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
247 (define_expand "movti"
248 [(set (match_operand:TI 0 "nonimmediate_operand" "")
249 (match_operand:TI 1 "general_operand" ""))]
252 if (can_create_pseudo_p ())
254 if (GET_CODE (operands[0]) != REG)
255 operands[1] = force_reg (TImode, operands[1]);
259 (define_expand "mov<mode>"
260 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
261 (match_operand:VSTRUCT 1 "general_operand" ""))]
264 if (can_create_pseudo_p ())
266 if (GET_CODE (operands[0]) != REG)
267 operands[1] = force_reg (<MODE>mode, operands[1]);
271 (define_insn "*neon_mov<mode>"
272 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
273 (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
275 && (register_operand (operands[0], <MODE>mode)
276 || register_operand (operands[1], <MODE>mode))"
278 switch (which_alternative)
281 case 1: case 2: return output_move_neon (operands);
282 default: gcc_unreachable ();
285 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
286 (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))])
289 [(set (match_operand:EI 0 "s_register_operand" "")
290 (match_operand:EI 1 "s_register_operand" ""))]
291 "TARGET_NEON && reload_completed"
292 [(set (match_dup 0) (match_dup 1))
293 (set (match_dup 2) (match_dup 3))]
295 int rdest = REGNO (operands[0]);
296 int rsrc = REGNO (operands[1]);
299 dest[0] = gen_rtx_REG (TImode, rdest);
300 src[0] = gen_rtx_REG (TImode, rsrc);
301 dest[1] = gen_rtx_REG (DImode, rdest + 4);
302 src[1] = gen_rtx_REG (DImode, rsrc + 4);
304 neon_disambiguate_copy (operands, dest, src, 2);
308 [(set (match_operand:OI 0 "s_register_operand" "")
309 (match_operand:OI 1 "s_register_operand" ""))]
310 "TARGET_NEON && reload_completed"
311 [(set (match_dup 0) (match_dup 1))
312 (set (match_dup 2) (match_dup 3))]
314 int rdest = REGNO (operands[0]);
315 int rsrc = REGNO (operands[1]);
318 dest[0] = gen_rtx_REG (TImode, rdest);
319 src[0] = gen_rtx_REG (TImode, rsrc);
320 dest[1] = gen_rtx_REG (TImode, rdest + 4);
321 src[1] = gen_rtx_REG (TImode, rsrc + 4);
323 neon_disambiguate_copy (operands, dest, src, 2);
327 [(set (match_operand:CI 0 "s_register_operand" "")
328 (match_operand:CI 1 "s_register_operand" ""))]
329 "TARGET_NEON && reload_completed"
330 [(set (match_dup 0) (match_dup 1))
331 (set (match_dup 2) (match_dup 3))
332 (set (match_dup 4) (match_dup 5))]
334 int rdest = REGNO (operands[0]);
335 int rsrc = REGNO (operands[1]);
338 dest[0] = gen_rtx_REG (TImode, rdest);
339 src[0] = gen_rtx_REG (TImode, rsrc);
340 dest[1] = gen_rtx_REG (TImode, rdest + 4);
341 src[1] = gen_rtx_REG (TImode, rsrc + 4);
342 dest[2] = gen_rtx_REG (TImode, rdest + 8);
343 src[2] = gen_rtx_REG (TImode, rsrc + 8);
345 neon_disambiguate_copy (operands, dest, src, 3);
349 [(set (match_operand:XI 0 "s_register_operand" "")
350 (match_operand:XI 1 "s_register_operand" ""))]
351 "TARGET_NEON && reload_completed"
352 [(set (match_dup 0) (match_dup 1))
353 (set (match_dup 2) (match_dup 3))
354 (set (match_dup 4) (match_dup 5))
355 (set (match_dup 6) (match_dup 7))]
357 int rdest = REGNO (operands[0]);
358 int rsrc = REGNO (operands[1]);
361 dest[0] = gen_rtx_REG (TImode, rdest);
362 src[0] = gen_rtx_REG (TImode, rsrc);
363 dest[1] = gen_rtx_REG (TImode, rdest + 4);
364 src[1] = gen_rtx_REG (TImode, rsrc + 4);
365 dest[2] = gen_rtx_REG (TImode, rdest + 8);
366 src[2] = gen_rtx_REG (TImode, rsrc + 8);
367 dest[3] = gen_rtx_REG (TImode, rdest + 12);
368 src[3] = gen_rtx_REG (TImode, rsrc + 12);
370 neon_disambiguate_copy (operands, dest, src, 4);
373 (define_expand "movmisalign<mode>"
374 [(set (match_operand:VDQX 0 "nonimmediate_operand" "")
375 (unspec:VDQX [(match_operand:VDQX 1 "general_operand" "")]
376 UNSPEC_MISALIGNED_ACCESS))]
377 "TARGET_NEON && !BYTES_BIG_ENDIAN"
379 /* This pattern is not permitted to fail during expansion: if both arguments
380 are non-registers (e.g. memory := constant, which can be created by the
381 auto-vectorizer), force operand 1 into a register. */
382 if (!s_register_operand (operands[0], <MODE>mode)
383 && !s_register_operand (operands[1], <MODE>mode))
384 operands[1] = force_reg (<MODE>mode, operands[1]);
387 (define_insn "*movmisalign<mode>_neon_store"
388 [(set (match_operand:VDX 0 "memory_operand" "=Um")
389 (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")]
390 UNSPEC_MISALIGNED_ACCESS))]
391 "TARGET_NEON && !BYTES_BIG_ENDIAN"
392 "vst1.<V_sz_elem>\t{%P1}, %A0"
393 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
395 (define_insn "*movmisalign<mode>_neon_load"
396 [(set (match_operand:VDX 0 "s_register_operand" "=w")
397 (unspec:VDX [(match_operand:VDX 1 "memory_operand" " Um")]
398 UNSPEC_MISALIGNED_ACCESS))]
399 "TARGET_NEON && !BYTES_BIG_ENDIAN"
400 "vld1.<V_sz_elem>\t{%P0}, %A1"
401 [(set_attr "neon_type" "neon_vld1_1_2_regs")])
403 (define_insn "*movmisalign<mode>_neon_store"
404 [(set (match_operand:VQX 0 "memory_operand" "=Um")
405 (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")]
406 UNSPEC_MISALIGNED_ACCESS))]
407 "TARGET_NEON && !BYTES_BIG_ENDIAN"
408 "vst1.<V_sz_elem>\t{%q1}, %A0"
409 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
411 (define_insn "*movmisalign<mode>_neon_load"
412 [(set (match_operand:VQX 0 "s_register_operand" "=w")
413 (unspec:VQX [(match_operand:VQX 1 "memory_operand" " Um")]
414 UNSPEC_MISALIGNED_ACCESS))]
415 "TARGET_NEON && !BYTES_BIG_ENDIAN"
416 "vld1.<V_sz_elem>\t{%q0}, %A1"
417 [(set_attr "neon_type" "neon_vld1_1_2_regs")])
419 (define_insn "vec_set<mode>_internal"
420 [(set (match_operand:VD 0 "s_register_operand" "=w")
423 (match_operand:<V_elem> 1 "s_register_operand" "r"))
424 (match_operand:VD 3 "s_register_operand" "0")
425 (match_operand:SI 2 "immediate_operand" "i")))]
428 int elt = ffs ((int) INTVAL (operands[2]) - 1);
429 if (BYTES_BIG_ENDIAN)
430 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
431 operands[2] = GEN_INT (elt);
433 return "vmov%?.<V_sz_elem>\t%P0[%c2], %1";
435 [(set_attr "predicable" "yes")
436 (set_attr "neon_type" "neon_mcr")])
438 (define_insn "vec_set<mode>_internal"
439 [(set (match_operand:VQ 0 "s_register_operand" "=w")
442 (match_operand:<V_elem> 1 "s_register_operand" "r"))
443 (match_operand:VQ 3 "s_register_operand" "0")
444 (match_operand:SI 2 "immediate_operand" "i")))]
447 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
448 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
449 int elt = elem % half_elts;
450 int hi = (elem / half_elts) * 2;
451 int regno = REGNO (operands[0]);
453 if (BYTES_BIG_ENDIAN)
454 elt = half_elts - 1 - elt;
456 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
457 operands[2] = GEN_INT (elt);
459 return "vmov%?.<V_sz_elem>\t%P0[%c2], %1";
461 [(set_attr "predicable" "yes")
462 (set_attr "neon_type" "neon_mcr")]
465 (define_insn "vec_setv2di_internal"
466 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
469 (match_operand:DI 1 "s_register_operand" "r"))
470 (match_operand:V2DI 3 "s_register_operand" "0")
471 (match_operand:SI 2 "immediate_operand" "i")))]
474 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
475 int regno = REGNO (operands[0]) + 2 * elem;
477 operands[0] = gen_rtx_REG (DImode, regno);
479 return "vmov%?\t%P0, %Q1, %R1";
481 [(set_attr "predicable" "yes")
482 (set_attr "neon_type" "neon_mcr_2_mcrr")]
485 (define_expand "vec_set<mode>"
486 [(match_operand:VDQ 0 "s_register_operand" "")
487 (match_operand:<V_elem> 1 "s_register_operand" "")
488 (match_operand:SI 2 "immediate_operand" "")]
491 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
492 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
493 GEN_INT (elem), operands[0]));
497 (define_insn "vec_extract<mode>"
498 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
500 (match_operand:VD 1 "s_register_operand" "w")
501 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
504 if (BYTES_BIG_ENDIAN)
506 int elt = INTVAL (operands[2]);
507 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
508 operands[2] = GEN_INT (elt);
510 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
512 [(set_attr "predicable" "yes")
513 (set_attr "neon_type" "neon_bp_simple")]
516 (define_insn "vec_extract<mode>"
517 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
519 (match_operand:VQ 1 "s_register_operand" "w")
520 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
523 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
524 int elt = INTVAL (operands[2]) % half_elts;
525 int hi = (INTVAL (operands[2]) / half_elts) * 2;
526 int regno = REGNO (operands[1]);
528 if (BYTES_BIG_ENDIAN)
529 elt = half_elts - 1 - elt;
531 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
532 operands[2] = GEN_INT (elt);
534 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
536 [(set_attr "predicable" "yes")
537 (set_attr "neon_type" "neon_bp_simple")]
540 (define_insn "vec_extractv2di"
541 [(set (match_operand:DI 0 "s_register_operand" "=r")
543 (match_operand:V2DI 1 "s_register_operand" "w")
544 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
547 int regno = REGNO (operands[1]) + 2 * INTVAL (operands[2]);
549 operands[1] = gen_rtx_REG (DImode, regno);
551 return "vmov%?\t%Q0, %R0, %P1 @ v2di";
553 [(set_attr "predicable" "yes")
554 (set_attr "neon_type" "neon_int_1")]
557 (define_expand "vec_init<mode>"
558 [(match_operand:VDQ 0 "s_register_operand" "")
559 (match_operand 1 "" "")]
562 neon_expand_vector_init (operands[0], operands[1]);
566 ;; Doubleword and quadword arithmetic.
568 ;; NOTE: some other instructions also support 64-bit integer
569 ;; element size, which we could potentially use for "long long" operations.
571 (define_insn "*add<mode>3_neon"
572 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
573 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
574 (match_operand:VDQ 2 "s_register_operand" "w")))]
575 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
576 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
577 [(set (attr "neon_type")
578 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
579 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
580 (const_string "neon_fp_vadd_ddd_vabs_dd")
581 (const_string "neon_fp_vadd_qqq_vabs_qq"))
582 (const_string "neon_int_1")))]
585 (define_insn "adddi3_neon"
586 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w")
587 (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,w")
588 (match_operand:DI 2 "s_register_operand" "w,r,0,w")))
589 (clobber (reg:CC CC_REGNUM))]
592 switch (which_alternative)
594 case 0: /* fall through */
595 case 3: return "vadd.i64\t%P0, %P1, %P2";
598 default: gcc_unreachable ();
601 [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1")
602 (set_attr "conds" "*,clob,clob,*")
603 (set_attr "length" "*,8,8,*")
604 (set_attr "arch" "nota8,*,*,onlya8")]
607 (define_insn "*sub<mode>3_neon"
608 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
609 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
610 (match_operand:VDQ 2 "s_register_operand" "w")))]
611 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
612 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
613 [(set (attr "neon_type")
614 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
615 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
616 (const_string "neon_fp_vadd_ddd_vabs_dd")
617 (const_string "neon_fp_vadd_qqq_vabs_qq"))
618 (const_string "neon_int_2")))]
621 (define_insn "subdi3_neon"
622 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r,?w")
623 (minus:DI (match_operand:DI 1 "s_register_operand" "w,0,r,0,w")
624 (match_operand:DI 2 "s_register_operand" "w,r,0,0,w")))
625 (clobber (reg:CC CC_REGNUM))]
628 switch (which_alternative)
630 case 0: /* fall through */
631 case 4: return "vsub.i64\t%P0, %P1, %P2";
632 case 1: /* fall through */
633 case 2: /* fall through */
634 case 3: return "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2";
635 default: gcc_unreachable ();
638 [(set_attr "neon_type" "neon_int_2,*,*,*,neon_int_2")
639 (set_attr "conds" "*,clob,clob,clob,*")
640 (set_attr "length" "*,8,8,8,*")
641 (set_attr "arch" "nota8,*,*,*,onlya8")]
644 (define_insn "*mul<mode>3_neon"
645 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
646 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
647 (match_operand:VDQ 2 "s_register_operand" "w")))]
648 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
649 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
650 [(set (attr "neon_type")
651 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
652 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
653 (const_string "neon_fp_vadd_ddd_vabs_dd")
654 (const_string "neon_fp_vadd_qqq_vabs_qq"))
655 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
657 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
658 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
659 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
660 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
661 (const_string "neon_mul_qqq_8_16_32_ddd_32")
662 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
665 (define_insn "mul<mode>3add<mode>_neon"
666 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
667 (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
668 (match_operand:VDQ 3 "s_register_operand" "w"))
669 (match_operand:VDQ 1 "s_register_operand" "0")))]
670 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
671 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
672 [(set (attr "neon_type")
673 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
674 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
675 (const_string "neon_fp_vmla_ddd")
676 (const_string "neon_fp_vmla_qqq"))
677 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
679 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
680 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
681 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
682 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
683 (const_string "neon_mla_qqq_8_16")
684 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
687 (define_insn "mul<mode>3neg<mode>add<mode>_neon"
688 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
689 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
690 (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
691 (match_operand:VDQ 3 "s_register_operand" "w"))))]
692 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
693 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
694 [(set (attr "neon_type")
695 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
696 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
697 (const_string "neon_fp_vmla_ddd")
698 (const_string "neon_fp_vmla_qqq"))
699 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
701 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
702 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
703 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
704 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
705 (const_string "neon_mla_qqq_8_16")
706 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
709 (define_insn "ior<mode>3"
710 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
711 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
712 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
715 switch (which_alternative)
717 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
718 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
719 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
720 default: gcc_unreachable ();
723 [(set_attr "neon_type" "neon_int_1")]
726 (define_insn "iordi3_neon"
727 [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w")
728 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0")
729 (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r,w,Dl")))]
732 switch (which_alternative)
734 case 0: /* fall through */
735 case 4: return "vorr\t%P0, %P1, %P2";
736 case 1: /* fall through */
737 case 5: return neon_output_logic_immediate ("vorr", &operands[2],
738 DImode, 0, VALID_NEON_QREG_MODE (DImode));
741 default: gcc_unreachable ();
744 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1")
745 (set_attr "length" "*,*,8,8,*,*")
746 (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")]
749 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
750 ;; vorr. We support the pseudo-instruction vand instead, because that
751 ;; corresponds to the canonical form the middle-end expects to use for
752 ;; immediate bitwise-ANDs.
754 (define_insn "and<mode>3"
755 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
756 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
757 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
760 switch (which_alternative)
762 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
763 case 1: return neon_output_logic_immediate ("vand", &operands[2],
764 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
765 default: gcc_unreachable ();
768 [(set_attr "neon_type" "neon_int_1")]
771 (define_insn "anddi3_neon"
772 [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w")
773 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0")
774 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL,r,r,w,DL")))]
777 switch (which_alternative)
779 case 0: /* fall through */
780 case 4: return "vand\t%P0, %P1, %P2";
781 case 1: /* fall through */
782 case 5: return neon_output_logic_immediate ("vand", &operands[2],
783 DImode, 1, VALID_NEON_QREG_MODE (DImode));
786 default: gcc_unreachable ();
789 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1")
790 (set_attr "length" "*,*,8,8,*,*")
791 (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")]
794 (define_insn "orn<mode>3_neon"
795 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
796 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
797 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
799 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
800 [(set_attr "neon_type" "neon_int_1")]
803 (define_insn "orndi3_neon"
804 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
805 (ior:DI (match_operand:DI 1 "s_register_operand" "w,r,0")
806 (not:DI (match_operand:DI 2 "s_register_operand" "w,0,r"))))]
812 [(set_attr "neon_type" "neon_int_1,*,*")
813 (set_attr "length" "*,8,8")]
816 (define_insn "bic<mode>3_neon"
817 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
818 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
819 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
821 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
822 [(set_attr "neon_type" "neon_int_1")]
825 ;; Compare to *anddi_notdi_di.
826 (define_insn "bicdi3_neon"
827 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
828 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
829 (match_operand:DI 1 "s_register_operand" "w,0,r")))]
835 [(set_attr "neon_type" "neon_int_1,*,*")
836 (set_attr "length" "*,8,8")]
839 (define_insn "xor<mode>3"
840 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
841 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
842 (match_operand:VDQ 2 "s_register_operand" "w")))]
844 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
845 [(set_attr "neon_type" "neon_int_1")]
848 (define_insn "xordi3_neon"
849 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w")
850 (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r,w")
851 (match_operand:DI 2 "s_register_operand" "w,r,r,w")))]
858 [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1")
859 (set_attr "length" "*,8,8,*")
860 (set_attr "arch" "nota8,*,*,onlya8")]
863 (define_insn "one_cmpl<mode>2"
864 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
865 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
867 "vmvn\t%<V_reg>0, %<V_reg>1"
868 [(set_attr "neon_type" "neon_int_1")]
871 (define_insn "abs<mode>2"
872 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
873 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
875 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
876 [(set (attr "neon_type")
877 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
878 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
879 (const_string "neon_fp_vadd_ddd_vabs_dd")
880 (const_string "neon_fp_vadd_qqq_vabs_qq"))
881 (const_string "neon_int_3")))]
884 (define_insn "neg<mode>2"
885 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
886 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
888 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
889 [(set (attr "neon_type")
890 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
891 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
892 (const_string "neon_fp_vadd_ddd_vabs_dd")
893 (const_string "neon_fp_vadd_qqq_vabs_qq"))
894 (const_string "neon_int_3")))]
897 (define_insn "*umin<mode>3_neon"
898 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
899 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
900 (match_operand:VDQIW 2 "s_register_operand" "w")))]
902 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
903 [(set_attr "neon_type" "neon_int_5")]
906 (define_insn "*umax<mode>3_neon"
907 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
908 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
909 (match_operand:VDQIW 2 "s_register_operand" "w")))]
911 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
912 [(set_attr "neon_type" "neon_int_5")]
915 (define_insn "*smin<mode>3_neon"
916 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
917 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
918 (match_operand:VDQW 2 "s_register_operand" "w")))]
920 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
921 [(set (attr "neon_type")
922 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
923 (const_string "neon_fp_vadd_ddd_vabs_dd")
924 (const_string "neon_int_5")))]
927 (define_insn "*smax<mode>3_neon"
928 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
929 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
930 (match_operand:VDQW 2 "s_register_operand" "w")))]
932 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
933 [(set (attr "neon_type")
934 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
935 (const_string "neon_fp_vadd_ddd_vabs_dd")
936 (const_string "neon_int_5")))]
939 ; TODO: V2DI shifts are current disabled because there are bugs in the
940 ; generic vectorizer code. It ends up creating a V2DI constructor with
943 (define_insn "vashl<mode>3"
944 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
945 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
946 (match_operand:VDQIW 2 "s_register_operand" "w")))]
948 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
949 [(set (attr "neon_type")
950 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
951 (const_string "neon_vshl_ddd")
952 (const_string "neon_shift_3")))]
955 ; Used for implementing logical shift-right, which is a left-shift by a negative
956 ; amount, with signed operands. This is essentially the same as ashl<mode>3
957 ; above, but using an unspec in case GCC tries anything tricky with negative
960 (define_insn "ashl<mode>3_signed"
961 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
962 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
963 (match_operand:VDQI 2 "s_register_operand" "w")]
964 UNSPEC_ASHIFT_SIGNED))]
966 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
967 [(set (attr "neon_type")
968 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
969 (const_string "neon_vshl_ddd")
970 (const_string "neon_shift_3")))]
973 ; Used for implementing logical shift-right, which is a left-shift by a negative
974 ; amount, with unsigned operands.
976 (define_insn "ashl<mode>3_unsigned"
977 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
978 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
979 (match_operand:VDQI 2 "s_register_operand" "w")]
980 UNSPEC_ASHIFT_UNSIGNED))]
982 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
983 [(set (attr "neon_type")
984 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
985 (const_string "neon_vshl_ddd")
986 (const_string "neon_shift_3")))]
989 (define_expand "vashr<mode>3"
990 [(set (match_operand:VDQIW 0 "s_register_operand" "")
991 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
992 (match_operand:VDQIW 2 "s_register_operand" "")))]
995 rtx neg = gen_reg_rtx (<MODE>mode);
997 emit_insn (gen_neg<mode>2 (neg, operands[2]));
998 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
1003 (define_expand "vlshr<mode>3"
1004 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1005 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1006 (match_operand:VDQIW 2 "s_register_operand" "")))]
1009 rtx neg = gen_reg_rtx (<MODE>mode);
1011 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1012 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1017 ;; Widening operations
1019 (define_insn "widen_ssum<mode>3"
1020 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1021 (plus:<V_widen> (sign_extend:<V_widen>
1022 (match_operand:VW 1 "s_register_operand" "%w"))
1023 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1025 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1026 [(set_attr "neon_type" "neon_int_3")]
1029 (define_insn "widen_usum<mode>3"
1030 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1031 (plus:<V_widen> (zero_extend:<V_widen>
1032 (match_operand:VW 1 "s_register_operand" "%w"))
1033 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1035 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1036 [(set_attr "neon_type" "neon_int_3")]
1039 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1040 ;; shift-count granularity. That's good enough for the middle-end's current
1043 (define_expand "vec_shr_<mode>"
1044 [(match_operand:VDQ 0 "s_register_operand" "")
1045 (match_operand:VDQ 1 "s_register_operand" "")
1046 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1050 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1051 const int width = GET_MODE_BITSIZE (<MODE>mode);
1052 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1053 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1054 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1056 if (num_bits == width)
1058 emit_move_insn (operands[0], operands[1]);
1062 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1063 operands[0] = gen_lowpart (bvecmode, operands[0]);
1064 operands[1] = gen_lowpart (bvecmode, operands[1]);
1066 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1067 GEN_INT (num_bits / BITS_PER_UNIT)));
1071 (define_expand "vec_shl_<mode>"
1072 [(match_operand:VDQ 0 "s_register_operand" "")
1073 (match_operand:VDQ 1 "s_register_operand" "")
1074 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1078 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1079 const int width = GET_MODE_BITSIZE (<MODE>mode);
1080 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1081 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1082 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1086 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1090 num_bits = width - num_bits;
1092 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1093 operands[0] = gen_lowpart (bvecmode, operands[0]);
1094 operands[1] = gen_lowpart (bvecmode, operands[1]);
1096 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1097 GEN_INT (num_bits / BITS_PER_UNIT)));
1101 ;; Helpers for quad-word reduction operations
1103 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1104 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1105 ; N/2-element vector.
1107 (define_insn "quad_halves_<code>v4si"
1108 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1110 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1111 (parallel [(const_int 0) (const_int 1)]))
1112 (vec_select:V2SI (match_dup 1)
1113 (parallel [(const_int 2) (const_int 3)]))))]
1115 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1116 [(set_attr "vqh_mnem" "<VQH_mnem>")
1117 (set (attr "neon_type")
1118 (if_then_else (eq_attr "vqh_mnem" "vadd")
1119 (const_string "neon_int_1") (const_string "neon_int_5")))]
1122 (define_insn "quad_halves_<code>v4sf"
1123 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1125 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1126 (parallel [(const_int 0) (const_int 1)]))
1127 (vec_select:V2SF (match_dup 1)
1128 (parallel [(const_int 2) (const_int 3)]))))]
1129 "TARGET_NEON && flag_unsafe_math_optimizations"
1130 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1131 [(set_attr "vqh_mnem" "<VQH_mnem>")
1132 (set (attr "neon_type")
1133 (if_then_else (eq_attr "vqh_mnem" "vadd")
1134 (const_string "neon_int_1") (const_string "neon_int_5")))]
1137 (define_insn "quad_halves_<code>v8hi"
1138 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1140 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1141 (parallel [(const_int 0) (const_int 1)
1142 (const_int 2) (const_int 3)]))
1143 (vec_select:V4HI (match_dup 1)
1144 (parallel [(const_int 4) (const_int 5)
1145 (const_int 6) (const_int 7)]))))]
1147 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1148 [(set_attr "vqh_mnem" "<VQH_mnem>")
1149 (set (attr "neon_type")
1150 (if_then_else (eq_attr "vqh_mnem" "vadd")
1151 (const_string "neon_int_1") (const_string "neon_int_5")))]
1154 (define_insn "quad_halves_<code>v16qi"
1155 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1157 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1158 (parallel [(const_int 0) (const_int 1)
1159 (const_int 2) (const_int 3)
1160 (const_int 4) (const_int 5)
1161 (const_int 6) (const_int 7)]))
1162 (vec_select:V8QI (match_dup 1)
1163 (parallel [(const_int 8) (const_int 9)
1164 (const_int 10) (const_int 11)
1165 (const_int 12) (const_int 13)
1166 (const_int 14) (const_int 15)]))))]
1168 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1169 [(set_attr "vqh_mnem" "<VQH_mnem>")
1170 (set (attr "neon_type")
1171 (if_then_else (eq_attr "vqh_mnem" "vadd")
1172 (const_string "neon_int_1") (const_string "neon_int_5")))]
1175 ; FIXME: We wouldn't need the following insns if we could write subregs of
1176 ; vector registers. Make an attempt at removing unnecessary moves, though
1177 ; we're really at the mercy of the register allocator.
1179 (define_insn "neon_move_lo_quad_<mode>"
1180 [(set (match_operand:ANY128 0 "s_register_operand" "+w")
1182 (match_operand:<V_HALF> 1 "s_register_operand" "w")
1183 (vec_select:<V_HALF>
1185 (match_operand:ANY128 2 "vect_par_constant_high" ""))))]
1188 int dest = REGNO (operands[0]);
1189 int src = REGNO (operands[1]);
1192 return "vmov\t%e0, %P1";
1196 [(set_attr "neon_type" "neon_bp_simple")]
1199 (define_insn "neon_move_hi_quad_<mode>"
1200 [(set (match_operand:ANY128 0 "s_register_operand" "+w")
1202 (vec_select:<V_HALF>
1204 (match_operand:ANY128 2 "vect_par_constant_low" ""))
1205 (match_operand:<V_HALF> 1 "s_register_operand" "w")))]
1209 int dest = REGNO (operands[0]);
1210 int src = REGNO (operands[1]);
1213 return "vmov\t%f0, %P1";
1217 [(set_attr "neon_type" "neon_bp_simple")]
1220 (define_expand "move_hi_quad_<mode>"
1221 [(match_operand:ANY128 0 "s_register_operand" "")
1222 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1225 rtvec v = rtvec_alloc (<V_mode_nunits>/2);
1229 for (i=0; i < (<V_mode_nunits>/2); i++)
1230 RTVEC_ELT (v, i) = GEN_INT (i);
1232 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
1233 emit_insn (gen_neon_move_hi_quad_<mode> (operands[0], operands[1], t1));
1238 (define_expand "move_lo_quad_<mode>"
1239 [(match_operand:ANY128 0 "s_register_operand" "")
1240 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1243 rtvec v = rtvec_alloc (<V_mode_nunits>/2);
1247 for (i=0; i < (<V_mode_nunits>/2); i++)
1248 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
1250 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
1251 emit_insn (gen_neon_move_lo_quad_<mode> (operands[0], operands[1], t1));
1256 ;; Reduction operations
1258 (define_expand "reduc_splus_<mode>"
1259 [(match_operand:VD 0 "s_register_operand" "")
1260 (match_operand:VD 1 "s_register_operand" "")]
1261 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1263 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1264 &gen_neon_vpadd_internal<mode>);
1268 (define_expand "reduc_splus_<mode>"
1269 [(match_operand:VQ 0 "s_register_operand" "")
1270 (match_operand:VQ 1 "s_register_operand" "")]
1271 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1273 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1274 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1276 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1277 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1278 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1283 (define_insn "reduc_splus_v2di"
1284 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1285 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1288 "vadd.i64\t%e0, %e1, %f1"
1289 [(set_attr "neon_type" "neon_int_1")]
1292 ;; NEON does not distinguish between signed and unsigned addition except on
1293 ;; widening operations.
1294 (define_expand "reduc_uplus_<mode>"
1295 [(match_operand:VDQI 0 "s_register_operand" "")
1296 (match_operand:VDQI 1 "s_register_operand" "")]
1299 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1303 (define_expand "reduc_smin_<mode>"
1304 [(match_operand:VD 0 "s_register_operand" "")
1305 (match_operand:VD 1 "s_register_operand" "")]
1306 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1308 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1309 &gen_neon_vpsmin<mode>);
1313 (define_expand "reduc_smin_<mode>"
1314 [(match_operand:VQ 0 "s_register_operand" "")
1315 (match_operand:VQ 1 "s_register_operand" "")]
1316 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1318 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1319 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1321 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1322 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1323 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1328 (define_expand "reduc_smax_<mode>"
1329 [(match_operand:VD 0 "s_register_operand" "")
1330 (match_operand:VD 1 "s_register_operand" "")]
1331 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1333 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1334 &gen_neon_vpsmax<mode>);
1338 (define_expand "reduc_smax_<mode>"
1339 [(match_operand:VQ 0 "s_register_operand" "")
1340 (match_operand:VQ 1 "s_register_operand" "")]
1341 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1343 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1344 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1346 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1347 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1348 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1353 (define_expand "reduc_umin_<mode>"
1354 [(match_operand:VDI 0 "s_register_operand" "")
1355 (match_operand:VDI 1 "s_register_operand" "")]
1358 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1359 &gen_neon_vpumin<mode>);
1363 (define_expand "reduc_umin_<mode>"
1364 [(match_operand:VQI 0 "s_register_operand" "")
1365 (match_operand:VQI 1 "s_register_operand" "")]
1368 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1369 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1371 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1372 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1373 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1378 (define_expand "reduc_umax_<mode>"
1379 [(match_operand:VDI 0 "s_register_operand" "")
1380 (match_operand:VDI 1 "s_register_operand" "")]
1383 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1384 &gen_neon_vpumax<mode>);
1388 (define_expand "reduc_umax_<mode>"
1389 [(match_operand:VQI 0 "s_register_operand" "")
1390 (match_operand:VQI 1 "s_register_operand" "")]
1393 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1394 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1396 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1397 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1398 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1403 (define_insn "neon_vpadd_internal<mode>"
1404 [(set (match_operand:VD 0 "s_register_operand" "=w")
1405 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1406 (match_operand:VD 2 "s_register_operand" "w")]
1409 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1410 ;; Assume this schedules like vadd.
1411 [(set (attr "neon_type")
1412 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1413 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1414 (const_string "neon_fp_vadd_ddd_vabs_dd")
1415 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1416 (const_string "neon_int_1")))]
1419 (define_insn "neon_vpsmin<mode>"
1420 [(set (match_operand:VD 0 "s_register_operand" "=w")
1421 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1422 (match_operand:VD 2 "s_register_operand" "w")]
1425 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1426 ;; Assume this schedules like vmin.
1427 [(set (attr "neon_type")
1428 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1429 (const_string "neon_fp_vadd_ddd_vabs_dd")
1430 (const_string "neon_int_5")))]
1433 (define_insn "neon_vpsmax<mode>"
1434 [(set (match_operand:VD 0 "s_register_operand" "=w")
1435 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1436 (match_operand:VD 2 "s_register_operand" "w")]
1439 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1440 ;; Assume this schedules like vmax.
1441 [(set (attr "neon_type")
1442 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1443 (const_string "neon_fp_vadd_ddd_vabs_dd")
1444 (const_string "neon_int_5")))]
1447 (define_insn "neon_vpumin<mode>"
1448 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1449 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1450 (match_operand:VDI 2 "s_register_operand" "w")]
1453 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1454 ;; Assume this schedules like umin.
1455 [(set_attr "neon_type" "neon_int_5")]
1458 (define_insn "neon_vpumax<mode>"
1459 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1460 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1461 (match_operand:VDI 2 "s_register_operand" "w")]
1464 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1465 ;; Assume this schedules like umax.
1466 [(set_attr "neon_type" "neon_int_5")]
1469 ;; Saturating arithmetic
1471 ; NOTE: Neon supports many more saturating variants of instructions than the
1472 ; following, but these are all GCC currently understands.
1473 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1474 ; yet either, although these patterns may be used by intrinsics when they're
1477 (define_insn "*ss_add<mode>_neon"
1478 [(set (match_operand:VD 0 "s_register_operand" "=w")
1479 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1480 (match_operand:VD 2 "s_register_operand" "w")))]
1482 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1483 [(set_attr "neon_type" "neon_int_4")]
1486 (define_insn "*us_add<mode>_neon"
1487 [(set (match_operand:VD 0 "s_register_operand" "=w")
1488 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1489 (match_operand:VD 2 "s_register_operand" "w")))]
1491 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1492 [(set_attr "neon_type" "neon_int_4")]
1495 (define_insn "*ss_sub<mode>_neon"
1496 [(set (match_operand:VD 0 "s_register_operand" "=w")
1497 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1498 (match_operand:VD 2 "s_register_operand" "w")))]
1500 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1501 [(set_attr "neon_type" "neon_int_5")]
1504 (define_insn "*us_sub<mode>_neon"
1505 [(set (match_operand:VD 0 "s_register_operand" "=w")
1506 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1507 (match_operand:VD 2 "s_register_operand" "w")))]
1509 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1510 [(set_attr "neon_type" "neon_int_5")]
1513 ;; Conditional instructions. These are comparisons with conditional moves for
1514 ;; vectors. They perform the assignment:
1516 ;; Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2;
1518 ;; where op3 is <, <=, ==, !=, >= or >. Operations are performed
1521 (define_expand "vcond<mode>"
1522 [(set (match_operand:VDQW 0 "s_register_operand" "")
1524 (match_operator 3 "arm_comparison_operator"
1525 [(match_operand:VDQW 4 "s_register_operand" "")
1526 (match_operand:VDQW 5 "nonmemory_operand" "")])
1527 (match_operand:VDQW 1 "s_register_operand" "")
1528 (match_operand:VDQW 2 "s_register_operand" "")))]
1529 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1532 int inverse = 0, immediate_zero = 0;
1533 /* See the description of "magic" bits in the 'T' case of
1534 arm_print_operand. */
1535 HOST_WIDE_INT magic_word = (<MODE>mode == V2SFmode || <MODE>mode == V4SFmode)
1537 rtx magic_rtx = GEN_INT (magic_word);
1539 mask = gen_reg_rtx (<V_cmp_result>mode);
1541 if (operands[5] == CONST0_RTX (<MODE>mode))
1543 else if (!REG_P (operands[5]))
1544 operands[5] = force_reg (<MODE>mode, operands[5]);
1546 switch (GET_CODE (operands[3]))
1549 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1554 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1559 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1565 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1568 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1574 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1577 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1582 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1592 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1595 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1601 (define_expand "vcondu<mode>"
1602 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1604 (match_operator 3 "arm_comparison_operator"
1605 [(match_operand:VDQIW 4 "s_register_operand" "")
1606 (match_operand:VDQIW 5 "s_register_operand" "")])
1607 (match_operand:VDQIW 1 "s_register_operand" "")
1608 (match_operand:VDQIW 2 "s_register_operand" "")))]
1612 int inverse = 0, immediate_zero = 0;
1614 mask = gen_reg_rtx (<V_cmp_result>mode);
1616 if (operands[5] == CONST0_RTX (<MODE>mode))
1618 else if (!REG_P (operands[5]))
1619 operands[5] = force_reg (<MODE>mode, operands[5]);
1621 switch (GET_CODE (operands[3]))
1624 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1629 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1634 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1640 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1643 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1649 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1652 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1657 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1667 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1670 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1676 ;; Patterns for builtins.
1678 ; good for plain vadd, vaddq.
1680 (define_expand "neon_vadd<mode>"
1681 [(match_operand:VDQX 0 "s_register_operand" "=w")
1682 (match_operand:VDQX 1 "s_register_operand" "w")
1683 (match_operand:VDQX 2 "s_register_operand" "w")
1684 (match_operand:SI 3 "immediate_operand" "i")]
1687 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1688 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
1690 emit_insn (gen_neon_vadd<mode>_unspec (operands[0], operands[1],
1695 ; Note that NEON operations don't support the full IEEE 754 standard: in
1696 ; particular, denormal values are flushed to zero. This means that GCC cannot
1697 ; use those instructions for autovectorization, etc. unless
1698 ; -funsafe-math-optimizations is in effect (in which case flush-to-zero
1699 ; behaviour is permissible). Intrinsic operations (provided by the arm_neon.h
1700 ; header) must work in either case: if -funsafe-math-optimizations is given,
1701 ; intrinsics expand to "canonical" RTL where possible, otherwise intrinsics
1702 ; expand to unspecs (which may potentially limit the extent to which they might
1703 ; be optimized by generic code).
1705 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1707 (define_insn "neon_vadd<mode>_unspec"
1708 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1709 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1710 (match_operand:VDQX 2 "s_register_operand" "w")]
1713 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1714 [(set (attr "neon_type")
1715 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1716 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1717 (const_string "neon_fp_vadd_ddd_vabs_dd")
1718 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1719 (const_string "neon_int_1")))]
1722 ; operand 3 represents in bits:
1723 ; bit 0: signed (vs unsigned).
1724 ; bit 1: rounding (vs none).
1726 (define_insn "neon_vaddl<mode>"
1727 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1728 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1729 (match_operand:VDI 2 "s_register_operand" "w")
1730 (match_operand:SI 3 "immediate_operand" "i")]
1733 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1734 [(set_attr "neon_type" "neon_int_3")]
1737 (define_insn "neon_vaddw<mode>"
1738 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1739 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1740 (match_operand:VDI 2 "s_register_operand" "w")
1741 (match_operand:SI 3 "immediate_operand" "i")]
1744 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1745 [(set_attr "neon_type" "neon_int_2")]
1750 (define_insn "neon_vhadd<mode>"
1751 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1752 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1753 (match_operand:VDQIW 2 "s_register_operand" "w")
1754 (match_operand:SI 3 "immediate_operand" "i")]
1757 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1758 [(set_attr "neon_type" "neon_int_4")]
1761 (define_insn "neon_vqadd<mode>"
1762 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1763 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1764 (match_operand:VDQIX 2 "s_register_operand" "w")
1765 (match_operand:SI 3 "immediate_operand" "i")]
1768 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1769 [(set_attr "neon_type" "neon_int_4")]
1772 (define_insn "neon_vaddhn<mode>"
1773 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1774 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1775 (match_operand:VN 2 "s_register_operand" "w")
1776 (match_operand:SI 3 "immediate_operand" "i")]
1779 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
1780 [(set_attr "neon_type" "neon_int_4")]
1783 ;; We cannot replace this unspec with mul<mode>3 because of the odd
1784 ;; polynomial multiplication case that can specified by operand 3.
1785 (define_insn "neon_vmul<mode>"
1786 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1787 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1788 (match_operand:VDQW 2 "s_register_operand" "w")
1789 (match_operand:SI 3 "immediate_operand" "i")]
1792 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1793 [(set (attr "neon_type")
1794 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1795 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1796 (const_string "neon_fp_vadd_ddd_vabs_dd")
1797 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1798 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1800 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1801 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1802 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1803 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1804 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1805 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
1808 (define_expand "neon_vmla<mode>"
1809 [(match_operand:VDQW 0 "s_register_operand" "=w")
1810 (match_operand:VDQW 1 "s_register_operand" "0")
1811 (match_operand:VDQW 2 "s_register_operand" "w")
1812 (match_operand:VDQW 3 "s_register_operand" "w")
1813 (match_operand:SI 4 "immediate_operand" "i")]
1816 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1817 emit_insn (gen_mul<mode>3add<mode>_neon (operands[0], operands[1],
1818 operands[2], operands[3]));
1820 emit_insn (gen_neon_vmla<mode>_unspec (operands[0], operands[1],
1821 operands[2], operands[3]));
1825 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1827 (define_insn "neon_vmla<mode>_unspec"
1828 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1829 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
1830 (match_operand:VDQ 2 "s_register_operand" "w")
1831 (match_operand:VDQ 3 "s_register_operand" "w")]
1834 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1835 [(set (attr "neon_type")
1836 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1837 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1838 (const_string "neon_fp_vmla_ddd")
1839 (const_string "neon_fp_vmla_qqq"))
1840 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1842 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1843 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1844 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1845 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1846 (const_string "neon_mla_qqq_8_16")
1847 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1850 (define_insn "neon_vmlal<mode>"
1851 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1852 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1853 (match_operand:VW 2 "s_register_operand" "w")
1854 (match_operand:VW 3 "s_register_operand" "w")
1855 (match_operand:SI 4 "immediate_operand" "i")]
1858 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1859 [(set (attr "neon_type")
1860 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1861 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1862 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1865 (define_expand "neon_vmls<mode>"
1866 [(match_operand:VDQW 0 "s_register_operand" "=w")
1867 (match_operand:VDQW 1 "s_register_operand" "0")
1868 (match_operand:VDQW 2 "s_register_operand" "w")
1869 (match_operand:VDQW 3 "s_register_operand" "w")
1870 (match_operand:SI 4 "immediate_operand" "i")]
1873 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1874 emit_insn (gen_mul<mode>3neg<mode>add<mode>_neon (operands[0],
1875 operands[1], operands[2], operands[3]));
1877 emit_insn (gen_neon_vmls<mode>_unspec (operands[0], operands[1],
1878 operands[2], operands[3]));
1882 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1884 (define_insn "neon_vmls<mode>_unspec"
1885 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1886 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
1887 (match_operand:VDQ 2 "s_register_operand" "w")
1888 (match_operand:VDQ 3 "s_register_operand" "w")]
1891 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1892 [(set (attr "neon_type")
1893 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1894 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1895 (const_string "neon_fp_vmla_ddd")
1896 (const_string "neon_fp_vmla_qqq"))
1897 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1899 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1900 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1901 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1903 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1904 (const_string "neon_mla_qqq_8_16")
1905 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1908 (define_insn "neon_vmlsl<mode>"
1909 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1910 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1911 (match_operand:VW 2 "s_register_operand" "w")
1912 (match_operand:VW 3 "s_register_operand" "w")
1913 (match_operand:SI 4 "immediate_operand" "i")]
1916 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1917 [(set (attr "neon_type")
1918 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1919 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1920 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1923 (define_insn "neon_vqdmulh<mode>"
1924 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1925 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1926 (match_operand:VMDQI 2 "s_register_operand" "w")
1927 (match_operand:SI 3 "immediate_operand" "i")]
1930 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1931 [(set (attr "neon_type")
1932 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1933 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1934 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1935 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1936 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1937 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1938 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
1941 (define_insn "neon_vqdmlal<mode>"
1942 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1943 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1944 (match_operand:VMDI 2 "s_register_operand" "w")
1945 (match_operand:VMDI 3 "s_register_operand" "w")
1946 (match_operand:SI 4 "immediate_operand" "i")]
1949 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
1950 [(set (attr "neon_type")
1951 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1952 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1953 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1956 (define_insn "neon_vqdmlsl<mode>"
1957 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1958 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1959 (match_operand:VMDI 2 "s_register_operand" "w")
1960 (match_operand:VMDI 3 "s_register_operand" "w")
1961 (match_operand:SI 4 "immediate_operand" "i")]
1964 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
1965 [(set (attr "neon_type")
1966 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1967 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1968 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1971 (define_insn "neon_vmull<mode>"
1972 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1973 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1974 (match_operand:VW 2 "s_register_operand" "w")
1975 (match_operand:SI 3 "immediate_operand" "i")]
1978 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1979 [(set (attr "neon_type")
1980 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1981 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1982 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1985 (define_insn "neon_vqdmull<mode>"
1986 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1987 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
1988 (match_operand:VMDI 2 "s_register_operand" "w")
1989 (match_operand:SI 3 "immediate_operand" "i")]
1992 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
1993 [(set (attr "neon_type")
1994 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1995 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1996 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1999 (define_expand "neon_vsub<mode>"
2000 [(match_operand:VDQX 0 "s_register_operand" "=w")
2001 (match_operand:VDQX 1 "s_register_operand" "w")
2002 (match_operand:VDQX 2 "s_register_operand" "w")
2003 (match_operand:SI 3 "immediate_operand" "i")]
2006 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2007 emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
2009 emit_insn (gen_neon_vsub<mode>_unspec (operands[0], operands[1],
2014 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2016 (define_insn "neon_vsub<mode>_unspec"
2017 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2018 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2019 (match_operand:VDQX 2 "s_register_operand" "w")]
2022 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2023 [(set (attr "neon_type")
2024 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2025 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2026 (const_string "neon_fp_vadd_ddd_vabs_dd")
2027 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2028 (const_string "neon_int_2")))]
2031 (define_insn "neon_vsubl<mode>"
2032 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2033 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
2034 (match_operand:VDI 2 "s_register_operand" "w")
2035 (match_operand:SI 3 "immediate_operand" "i")]
2038 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2039 [(set_attr "neon_type" "neon_int_2")]
2042 (define_insn "neon_vsubw<mode>"
2043 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2044 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2045 (match_operand:VDI 2 "s_register_operand" "w")
2046 (match_operand:SI 3 "immediate_operand" "i")]
2049 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2050 [(set_attr "neon_type" "neon_int_2")]
2053 (define_insn "neon_vqsub<mode>"
2054 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2055 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2056 (match_operand:VDQIX 2 "s_register_operand" "w")
2057 (match_operand:SI 3 "immediate_operand" "i")]
2060 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2061 [(set_attr "neon_type" "neon_int_5")]
2064 (define_insn "neon_vhsub<mode>"
2065 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2066 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2067 (match_operand:VDQIW 2 "s_register_operand" "w")
2068 (match_operand:SI 3 "immediate_operand" "i")]
2071 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2072 [(set_attr "neon_type" "neon_int_5")]
2075 (define_insn "neon_vsubhn<mode>"
2076 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2077 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2078 (match_operand:VN 2 "s_register_operand" "w")
2079 (match_operand:SI 3 "immediate_operand" "i")]
2082 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2083 [(set_attr "neon_type" "neon_int_4")]
2086 (define_insn "neon_vceq<mode>"
2087 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2088 (unspec:<V_cmp_result>
2089 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2090 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2091 (match_operand:SI 3 "immediate_operand" "i,i")]
2095 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2096 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
2097 [(set (attr "neon_type")
2098 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2099 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2100 (const_string "neon_fp_vadd_ddd_vabs_dd")
2101 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2102 (const_string "neon_int_5")))]
2105 (define_insn "neon_vcge<mode>"
2106 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2107 (unspec:<V_cmp_result>
2108 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2109 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2110 (match_operand:SI 3 "immediate_operand" "i,i")]
2114 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2115 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2116 [(set (attr "neon_type")
2117 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2118 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2119 (const_string "neon_fp_vadd_ddd_vabs_dd")
2120 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2121 (const_string "neon_int_5")))]
2124 (define_insn "neon_vcgt<mode>"
2125 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2126 (unspec:<V_cmp_result>
2127 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2128 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2129 (match_operand:SI 3 "immediate_operand" "i,i")]
2133 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2134 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2135 [(set (attr "neon_type")
2136 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2137 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2138 (const_string "neon_fp_vadd_ddd_vabs_dd")
2139 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2140 (const_string "neon_int_5")))]
2143 ;; VCLE and VCLT only support comparisons with immediate zero (register
2144 ;; variants are VCGE and VCGT with operands reversed).
2146 (define_insn "neon_vcle<mode>"
2147 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2148 (unspec:<V_cmp_result>
2149 [(match_operand:VDQW 1 "s_register_operand" "w")
2150 (match_operand:VDQW 2 "nonmemory_operand" "Dz")
2151 (match_operand:SI 3 "immediate_operand" "i")]
2154 "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2155 [(set (attr "neon_type")
2156 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2157 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2158 (const_string "neon_fp_vadd_ddd_vabs_dd")
2159 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2160 (const_string "neon_int_5")))]
2163 (define_insn "neon_vclt<mode>"
2164 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2165 (unspec:<V_cmp_result>
2166 [(match_operand:VDQW 1 "s_register_operand" "w")
2167 (match_operand:VDQW 2 "nonmemory_operand" "Dz")
2168 (match_operand:SI 3 "immediate_operand" "i")]
2171 "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2172 [(set (attr "neon_type")
2173 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2174 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2175 (const_string "neon_fp_vadd_ddd_vabs_dd")
2176 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2177 (const_string "neon_int_5")))]
2180 (define_insn "neon_vcage<mode>"
2181 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2182 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2183 (match_operand:VCVTF 2 "s_register_operand" "w")
2184 (match_operand:SI 3 "immediate_operand" "i")]
2187 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2188 [(set (attr "neon_type")
2189 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2190 (const_string "neon_fp_vadd_ddd_vabs_dd")
2191 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2194 (define_insn "neon_vcagt<mode>"
2195 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2196 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2197 (match_operand:VCVTF 2 "s_register_operand" "w")
2198 (match_operand:SI 3 "immediate_operand" "i")]
2201 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2202 [(set (attr "neon_type")
2203 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2204 (const_string "neon_fp_vadd_ddd_vabs_dd")
2205 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2208 (define_insn "neon_vtst<mode>"
2209 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2210 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2211 (match_operand:VDQIW 2 "s_register_operand" "w")
2212 (match_operand:SI 3 "immediate_operand" "i")]
2215 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2216 [(set_attr "neon_type" "neon_int_4")]
2219 (define_insn "neon_vabd<mode>"
2220 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2221 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2222 (match_operand:VDQW 2 "s_register_operand" "w")
2223 (match_operand:SI 3 "immediate_operand" "i")]
2226 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2227 [(set (attr "neon_type")
2228 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2229 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2230 (const_string "neon_fp_vadd_ddd_vabs_dd")
2231 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2232 (const_string "neon_int_5")))]
2235 (define_insn "neon_vabdl<mode>"
2236 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2237 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2238 (match_operand:VW 2 "s_register_operand" "w")
2239 (match_operand:SI 3 "immediate_operand" "i")]
2242 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2243 [(set_attr "neon_type" "neon_int_5")]
2246 (define_insn "neon_vaba<mode>"
2247 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2248 (plus:VDQIW (match_operand:VDQIW 1 "s_register_operand" "0")
2249 (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w")
2250 (match_operand:VDQIW 3 "s_register_operand" "w")
2251 (match_operand:SI 4 "immediate_operand" "i")]
2254 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2255 [(set (attr "neon_type")
2256 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2257 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2260 (define_insn "neon_vabal<mode>"
2261 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2262 (plus:<V_widen> (match_operand:<V_widen> 1 "s_register_operand" "0")
2263 (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w")
2264 (match_operand:VW 3 "s_register_operand" "w")
2265 (match_operand:SI 4 "immediate_operand" "i")]
2268 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2269 [(set_attr "neon_type" "neon_vaba")]
2272 (define_insn "neon_vmax<mode>"
2273 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2274 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2275 (match_operand:VDQW 2 "s_register_operand" "w")
2276 (match_operand:SI 3 "immediate_operand" "i")]
2279 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2280 [(set (attr "neon_type")
2281 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2282 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2283 (const_string "neon_fp_vadd_ddd_vabs_dd")
2284 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2285 (const_string "neon_int_5")))]
2288 (define_insn "neon_vmin<mode>"
2289 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2290 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2291 (match_operand:VDQW 2 "s_register_operand" "w")
2292 (match_operand:SI 3 "immediate_operand" "i")]
2295 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2296 [(set (attr "neon_type")
2297 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2298 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2299 (const_string "neon_fp_vadd_ddd_vabs_dd")
2300 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2301 (const_string "neon_int_5")))]
2304 (define_expand "neon_vpadd<mode>"
2305 [(match_operand:VD 0 "s_register_operand" "=w")
2306 (match_operand:VD 1 "s_register_operand" "w")
2307 (match_operand:VD 2 "s_register_operand" "w")
2308 (match_operand:SI 3 "immediate_operand" "i")]
2311 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2316 (define_insn "neon_vpaddl<mode>"
2317 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2318 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2319 (match_operand:SI 2 "immediate_operand" "i")]
2322 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2323 ;; Assume this schedules like vaddl.
2324 [(set_attr "neon_type" "neon_int_3")]
2327 (define_insn "neon_vpadal<mode>"
2328 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2329 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2330 (match_operand:VDQIW 2 "s_register_operand" "w")
2331 (match_operand:SI 3 "immediate_operand" "i")]
2334 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2335 ;; Assume this schedules like vpadd.
2336 [(set_attr "neon_type" "neon_int_1")]
2339 (define_insn "neon_vpmax<mode>"
2340 [(set (match_operand:VD 0 "s_register_operand" "=w")
2341 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2342 (match_operand:VD 2 "s_register_operand" "w")
2343 (match_operand:SI 3 "immediate_operand" "i")]
2346 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2347 ;; Assume this schedules like vmax.
2348 [(set (attr "neon_type")
2349 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2350 (const_string "neon_fp_vadd_ddd_vabs_dd")
2351 (const_string "neon_int_5")))]
2354 (define_insn "neon_vpmin<mode>"
2355 [(set (match_operand:VD 0 "s_register_operand" "=w")
2356 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2357 (match_operand:VD 2 "s_register_operand" "w")
2358 (match_operand:SI 3 "immediate_operand" "i")]
2361 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2362 ;; Assume this schedules like vmin.
2363 [(set (attr "neon_type")
2364 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2365 (const_string "neon_fp_vadd_ddd_vabs_dd")
2366 (const_string "neon_int_5")))]
2369 (define_insn "neon_vrecps<mode>"
2370 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2371 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2372 (match_operand:VCVTF 2 "s_register_operand" "w")
2373 (match_operand:SI 3 "immediate_operand" "i")]
2376 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2377 [(set (attr "neon_type")
2378 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2379 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2380 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2383 (define_insn "neon_vrsqrts<mode>"
2384 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2385 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2386 (match_operand:VCVTF 2 "s_register_operand" "w")
2387 (match_operand:SI 3 "immediate_operand" "i")]
2390 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2391 [(set (attr "neon_type")
2392 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2393 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2394 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2397 (define_expand "neon_vabs<mode>"
2398 [(match_operand:VDQW 0 "s_register_operand" "")
2399 (match_operand:VDQW 1 "s_register_operand" "")
2400 (match_operand:SI 2 "immediate_operand" "")]
2403 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
2407 (define_insn "neon_vqabs<mode>"
2408 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2409 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2410 (match_operand:SI 2 "immediate_operand" "i")]
2413 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2414 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2417 (define_expand "neon_vneg<mode>"
2418 [(match_operand:VDQW 0 "s_register_operand" "")
2419 (match_operand:VDQW 1 "s_register_operand" "")
2420 (match_operand:SI 2 "immediate_operand" "")]
2423 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2427 (define_insn "neon_vqneg<mode>"
2428 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2429 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2430 (match_operand:SI 2 "immediate_operand" "i")]
2433 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2434 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2437 (define_insn "neon_vcls<mode>"
2438 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2439 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2440 (match_operand:SI 2 "immediate_operand" "i")]
2443 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2444 [(set_attr "neon_type" "neon_int_1")]
2447 (define_insn "clz<mode>2"
2448 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2449 (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
2451 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2452 [(set_attr "neon_type" "neon_int_1")]
2455 (define_expand "neon_vclz<mode>"
2456 [(match_operand:VDQIW 0 "s_register_operand" "")
2457 (match_operand:VDQIW 1 "s_register_operand" "")
2458 (match_operand:SI 2 "immediate_operand" "")]
2461 emit_insn (gen_clz<mode>2 (operands[0], operands[1]));
2465 (define_insn "popcount<mode>2"
2466 [(set (match_operand:VE 0 "s_register_operand" "=w")
2467 (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
2469 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2470 [(set_attr "neon_type" "neon_int_1")]
2473 (define_expand "neon_vcnt<mode>"
2474 [(match_operand:VE 0 "s_register_operand" "=w")
2475 (match_operand:VE 1 "s_register_operand" "w")
2476 (match_operand:SI 2 "immediate_operand" "i")]
2479 emit_insn (gen_popcount<mode>2 (operands[0], operands[1]));
2483 (define_insn "neon_vrecpe<mode>"
2484 [(set (match_operand:V32 0 "s_register_operand" "=w")
2485 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2486 (match_operand:SI 2 "immediate_operand" "i")]
2489 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2490 [(set (attr "neon_type")
2491 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2492 (const_string "neon_fp_vadd_ddd_vabs_dd")
2493 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2496 (define_insn "neon_vrsqrte<mode>"
2497 [(set (match_operand:V32 0 "s_register_operand" "=w")
2498 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2499 (match_operand:SI 2 "immediate_operand" "i")]
2502 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2503 [(set (attr "neon_type")
2504 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2505 (const_string "neon_fp_vadd_ddd_vabs_dd")
2506 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2509 (define_expand "neon_vmvn<mode>"
2510 [(match_operand:VDQIW 0 "s_register_operand" "")
2511 (match_operand:VDQIW 1 "s_register_operand" "")
2512 (match_operand:SI 2 "immediate_operand" "")]
2515 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2519 (define_insn "neon_vget_lane<mode>_sext_internal"
2520 [(set (match_operand:SI 0 "s_register_operand" "=r")
2522 (vec_select:<V_elem>
2523 (match_operand:VD 1 "s_register_operand" "w")
2524 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2527 if (BYTES_BIG_ENDIAN)
2529 int elt = INTVAL (operands[2]);
2530 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2531 operands[2] = GEN_INT (elt);
2533 return "vmov%?.s<V_sz_elem>\t%0, %P1[%c2]";
2535 [(set_attr "predicable" "yes")
2536 (set_attr "neon_type" "neon_bp_simple")]
2539 (define_insn "neon_vget_lane<mode>_zext_internal"
2540 [(set (match_operand:SI 0 "s_register_operand" "=r")
2542 (vec_select:<V_elem>
2543 (match_operand:VD 1 "s_register_operand" "w")
2544 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2547 if (BYTES_BIG_ENDIAN)
2549 int elt = INTVAL (operands[2]);
2550 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2551 operands[2] = GEN_INT (elt);
2553 return "vmov%?.u<V_sz_elem>\t%0, %P1[%c2]";
2555 [(set_attr "predicable" "yes")
2556 (set_attr "neon_type" "neon_bp_simple")]
2559 (define_insn "neon_vget_lane<mode>_sext_internal"
2560 [(set (match_operand:SI 0 "s_register_operand" "=r")
2562 (vec_select:<V_elem>
2563 (match_operand:VQ 1 "s_register_operand" "w")
2564 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2568 int regno = REGNO (operands[1]);
2569 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2570 unsigned int elt = INTVAL (operands[2]);
2571 unsigned int elt_adj = elt % halfelts;
2573 if (BYTES_BIG_ENDIAN)
2574 elt_adj = halfelts - 1 - elt_adj;
2576 ops[0] = operands[0];
2577 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2578 ops[2] = GEN_INT (elt_adj);
2579 output_asm_insn ("vmov%?.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2583 [(set_attr "predicable" "yes")
2584 (set_attr "neon_type" "neon_bp_simple")]
2587 (define_insn "neon_vget_lane<mode>_zext_internal"
2588 [(set (match_operand:SI 0 "s_register_operand" "=r")
2590 (vec_select:<V_elem>
2591 (match_operand:VQ 1 "s_register_operand" "w")
2592 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2596 int regno = REGNO (operands[1]);
2597 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2598 unsigned int elt = INTVAL (operands[2]);
2599 unsigned int elt_adj = elt % halfelts;
2601 if (BYTES_BIG_ENDIAN)
2602 elt_adj = halfelts - 1 - elt_adj;
2604 ops[0] = operands[0];
2605 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2606 ops[2] = GEN_INT (elt_adj);
2607 output_asm_insn ("vmov%?.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2611 [(set_attr "predicable" "yes")
2612 (set_attr "neon_type" "neon_bp_simple")]
2615 (define_expand "neon_vget_lane<mode>"
2616 [(match_operand:<V_ext> 0 "s_register_operand" "")
2617 (match_operand:VDQW 1 "s_register_operand" "")
2618 (match_operand:SI 2 "immediate_operand" "")
2619 (match_operand:SI 3 "immediate_operand" "")]
2622 HOST_WIDE_INT magic = INTVAL (operands[3]);
2625 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2627 if (BYTES_BIG_ENDIAN)
2629 /* The intrinsics are defined in terms of a model where the
2630 element ordering in memory is vldm order, whereas the generic
2631 RTL is defined in terms of a model where the element ordering
2632 in memory is array order. Convert the lane number to conform
2634 unsigned int elt = INTVAL (operands[2]);
2635 unsigned int reg_nelts
2636 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2637 elt ^= reg_nelts - 1;
2638 operands[2] = GEN_INT (elt);
2641 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2642 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2645 if ((magic & 1) != 0)
2646 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2649 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2656 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2659 (define_expand "neon_vget_lanedi"
2660 [(match_operand:DI 0 "s_register_operand" "=r")
2661 (match_operand:DI 1 "s_register_operand" "w")
2662 (match_operand:SI 2 "immediate_operand" "i")
2663 (match_operand:SI 3 "immediate_operand" "i")]
2666 neon_lane_bounds (operands[2], 0, 1);
2667 emit_move_insn (operands[0], operands[1]);
2671 (define_expand "neon_vget_lanev2di"
2672 [(match_operand:DI 0 "s_register_operand" "=r")
2673 (match_operand:V2DI 1 "s_register_operand" "w")
2674 (match_operand:SI 2 "immediate_operand" "i")
2675 (match_operand:SI 3 "immediate_operand" "i")]
2678 neon_lane_bounds (operands[2], 0, 2);
2679 emit_insn (gen_vec_extractv2di (operands[0], operands[1], operands[2]));
2683 (define_expand "neon_vset_lane<mode>"
2684 [(match_operand:VDQ 0 "s_register_operand" "=w")
2685 (match_operand:<V_elem> 1 "s_register_operand" "r")
2686 (match_operand:VDQ 2 "s_register_operand" "0")
2687 (match_operand:SI 3 "immediate_operand" "i")]
2690 unsigned int elt = INTVAL (operands[3]);
2691 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2693 if (BYTES_BIG_ENDIAN)
2695 unsigned int reg_nelts
2696 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2697 elt ^= reg_nelts - 1;
2700 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
2701 GEN_INT (1 << elt), operands[2]));
2705 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2707 (define_expand "neon_vset_lanedi"
2708 [(match_operand:DI 0 "s_register_operand" "=w")
2709 (match_operand:DI 1 "s_register_operand" "r")
2710 (match_operand:DI 2 "s_register_operand" "0")
2711 (match_operand:SI 3 "immediate_operand" "i")]
2714 neon_lane_bounds (operands[3], 0, 1);
2715 emit_move_insn (operands[0], operands[1]);
2719 (define_expand "neon_vcreate<mode>"
2720 [(match_operand:VDX 0 "s_register_operand" "")
2721 (match_operand:DI 1 "general_operand" "")]
2724 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2725 emit_move_insn (operands[0], src);
2729 (define_insn "neon_vdup_n<mode>"
2730 [(set (match_operand:VX 0 "s_register_operand" "=w")
2731 (vec_duplicate:VX (match_operand:<V_elem> 1 "s_register_operand" "r")))]
2733 "vdup%?.<V_sz_elem>\t%<V_reg>0, %1"
2734 ;; Assume this schedules like vmov.
2735 [(set_attr "predicable" "yes")
2736 (set_attr "neon_type" "neon_bp_simple")]
2739 (define_insn "neon_vdup_n<mode>"
2740 [(set (match_operand:V32 0 "s_register_operand" "=w,w")
2741 (vec_duplicate:V32 (match_operand:<V_elem> 1 "s_register_operand" "r,t")))]
2744 vdup%?.<V_sz_elem>\t%<V_reg>0, %1
2745 vdup%?.<V_sz_elem>\t%<V_reg>0, %y1"
2746 ;; Assume this schedules like vmov.
2747 [(set_attr "predicable" "yes")
2748 (set_attr "neon_type" "neon_bp_simple")]
2751 (define_expand "neon_vdup_ndi"
2752 [(match_operand:DI 0 "s_register_operand" "=w")
2753 (match_operand:DI 1 "s_register_operand" "r")]
2756 emit_move_insn (operands[0], operands[1]);
2761 (define_insn "neon_vdup_nv2di"
2762 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
2763 (vec_duplicate:V2DI (match_operand:DI 1 "s_register_operand" "r,w")))]
2766 vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1
2767 vmov%?\t%e0, %P1\;vmov%?\t%f0, %P1"
2768 [(set_attr "predicable" "yes")
2769 (set_attr "length" "8")
2770 (set_attr "neon_type" "neon_bp_simple")]
2773 (define_insn "neon_vdup_lane<mode>_internal"
2774 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2776 (vec_select:<V_elem>
2777 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
2778 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2781 if (BYTES_BIG_ENDIAN)
2783 int elt = INTVAL (operands[2]);
2784 elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
2785 operands[2] = GEN_INT (elt);
2788 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
2790 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
2792 ;; Assume this schedules like vmov.
2793 [(set_attr "neon_type" "neon_bp_simple")]
2796 (define_expand "neon_vdup_lane<mode>"
2797 [(match_operand:VDQW 0 "s_register_operand" "=w")
2798 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
2799 (match_operand:SI 2 "immediate_operand" "i")]
2802 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_double_vector_mode>mode));
2803 if (BYTES_BIG_ENDIAN)
2805 unsigned int elt = INTVAL (operands[2]);
2806 unsigned int reg_nelts
2807 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<V_double_vector_mode>mode));
2808 elt ^= reg_nelts - 1;
2809 operands[2] = GEN_INT (elt);
2811 emit_insn (gen_neon_vdup_lane<mode>_internal (operands[0], operands[1],
2816 ; Scalar index is ignored, since only zero is valid here.
2817 (define_expand "neon_vdup_lanedi"
2818 [(match_operand:DI 0 "s_register_operand" "=w")
2819 (match_operand:DI 1 "s_register_operand" "w")
2820 (match_operand:SI 2 "immediate_operand" "i")]
2823 neon_lane_bounds (operands[2], 0, 1);
2824 emit_move_insn (operands[0], operands[1]);
2828 ; Likewise for v2di, as the DImode second operand has only a single element.
2829 (define_expand "neon_vdup_lanev2di"
2830 [(match_operand:V2DI 0 "s_register_operand" "=w")
2831 (match_operand:DI 1 "s_register_operand" "w")
2832 (match_operand:SI 2 "immediate_operand" "i")]
2835 neon_lane_bounds (operands[2], 0, 1);
2836 emit_insn (gen_neon_vdup_nv2di (operands[0], operands[1]));
2840 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2842 ;; FIXME: A different implementation of this builtin could make it much
2843 ;; more likely that we wouldn't actually need to output anything (we could make
2844 ;; it so that the reg allocator puts things in the right places magically
2845 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
2847 (define_insn "neon_vcombine<mode>"
2848 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
2849 (vec_concat:<V_DOUBLE> (match_operand:VDX 1 "s_register_operand" "w")
2850 (match_operand:VDX 2 "s_register_operand" "w")))]
2853 int dest = REGNO (operands[0]);
2854 int src1 = REGNO (operands[1]);
2855 int src2 = REGNO (operands[2]);
2858 if (src1 == dest && src2 == dest + 2)
2860 else if (src2 == dest && src1 == dest + 2)
2861 /* Special case of reversed high/low parts. */
2862 return "vswp\t%P1, %P2";
2864 destlo = gen_rtx_REG (<MODE>mode, dest);
2866 if (!reg_overlap_mentioned_p (operands[2], destlo))
2868 /* Try to avoid unnecessary moves if part of the result is in the right
2871 output_asm_insn ("vmov\t%e0, %P1", operands);
2872 if (src2 != dest + 2)
2873 output_asm_insn ("vmov\t%f0, %P2", operands);
2877 if (src2 != dest + 2)
2878 output_asm_insn ("vmov\t%f0, %P2", operands);
2880 output_asm_insn ("vmov\t%e0, %P1", operands);
2885 ;; We set the neon_type attribute based on the vmov instructions above.
2886 [(set_attr "length" "8")
2887 (set_attr "neon_type" "neon_bp_simple")]
2890 (define_insn "neon_vget_highv16qi"
2891 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2892 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
2893 (parallel [(const_int 8) (const_int 9)
2894 (const_int 10) (const_int 11)
2895 (const_int 12) (const_int 13)
2896 (const_int 14) (const_int 15)])))]
2899 int dest = REGNO (operands[0]);
2900 int src = REGNO (operands[1]);
2902 if (dest != src + 2)
2903 return "vmov\t%P0, %f1";
2907 [(set_attr "neon_type" "neon_bp_simple")]
2910 (define_insn "neon_vget_highv8hi"
2911 [(set (match_operand:V4HI 0 "s_register_operand" "=w")
2912 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
2913 (parallel [(const_int 4) (const_int 5)
2914 (const_int 6) (const_int 7)])))]
2917 int dest = REGNO (operands[0]);
2918 int src = REGNO (operands[1]);
2920 if (dest != src + 2)
2921 return "vmov\t%P0, %f1";
2925 [(set_attr "neon_type" "neon_bp_simple")]
2928 (define_insn "neon_vget_highv4si"
2929 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
2930 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
2931 (parallel [(const_int 2) (const_int 3)])))]
2934 int dest = REGNO (operands[0]);
2935 int src = REGNO (operands[1]);
2937 if (dest != src + 2)
2938 return "vmov\t%P0, %f1";
2942 [(set_attr "neon_type" "neon_bp_simple")]
2945 (define_insn "neon_vget_highv4sf"
2946 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
2947 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
2948 (parallel [(const_int 2) (const_int 3)])))]
2951 int dest = REGNO (operands[0]);
2952 int src = REGNO (operands[1]);
2954 if (dest != src + 2)
2955 return "vmov\t%P0, %f1";
2959 [(set_attr "neon_type" "neon_bp_simple")]
2962 (define_insn "neon_vget_highv2di"
2963 [(set (match_operand:DI 0 "s_register_operand" "=w")
2964 (vec_select:DI (match_operand:V2DI 1 "s_register_operand" "w")
2965 (parallel [(const_int 1)])))]
2968 int dest = REGNO (operands[0]);
2969 int src = REGNO (operands[1]);
2971 if (dest != src + 2)
2972 return "vmov\t%P0, %f1";
2976 [(set_attr "neon_type" "neon_bp_simple")]
2979 (define_insn "neon_vget_lowv16qi"
2980 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2981 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
2982 (parallel [(const_int 0) (const_int 1)
2983 (const_int 2) (const_int 3)
2984 (const_int 4) (const_int 5)
2985 (const_int 6) (const_int 7)])))]
2988 int dest = REGNO (operands[0]);
2989 int src = REGNO (operands[1]);
2992 return "vmov\t%P0, %e1";
2996 [(set_attr "neon_type" "neon_bp_simple")]
2999 (define_insn "neon_vget_lowv8hi"
3000 [(set (match_operand:V4HI 0 "s_register_operand" "=w")
3001 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
3002 (parallel [(const_int 0) (const_int 1)
3003 (const_int 2) (const_int 3)])))]
3006 int dest = REGNO (operands[0]);
3007 int src = REGNO (operands[1]);
3010 return "vmov\t%P0, %e1";
3014 [(set_attr "neon_type" "neon_bp_simple")]
3017 (define_insn "neon_vget_lowv4si"
3018 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
3019 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
3020 (parallel [(const_int 0) (const_int 1)])))]
3023 int dest = REGNO (operands[0]);
3024 int src = REGNO (operands[1]);
3027 return "vmov\t%P0, %e1";
3031 [(set_attr "neon_type" "neon_bp_simple")]
3034 (define_insn "neon_vget_lowv4sf"
3035 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
3036 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
3037 (parallel [(const_int 0) (const_int 1)])))]
3040 int dest = REGNO (operands[0]);
3041 int src = REGNO (operands[1]);
3044 return "vmov\t%P0, %e1";
3048 [(set_attr "neon_type" "neon_bp_simple")]
3051 (define_insn "neon_vget_lowv2di"
3052 [(set (match_operand:DI 0 "s_register_operand" "=w")
3053 (vec_select:DI (match_operand:V2DI 1 "s_register_operand" "w")
3054 (parallel [(const_int 0)])))]
3057 int dest = REGNO (operands[0]);
3058 int src = REGNO (operands[1]);
3061 return "vmov\t%P0, %e1";
3065 [(set_attr "neon_type" "neon_bp_simple")]
3068 (define_insn "neon_vcvt<mode>"
3069 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3070 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3071 (match_operand:SI 2 "immediate_operand" "i")]
3074 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
3075 [(set (attr "neon_type")
3076 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3077 (const_string "neon_fp_vadd_ddd_vabs_dd")
3078 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3081 (define_insn "neon_vcvt<mode>"
3082 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3083 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3084 (match_operand:SI 2 "immediate_operand" "i")]
3087 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
3088 [(set (attr "neon_type")
3089 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3090 (const_string "neon_fp_vadd_ddd_vabs_dd")
3091 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3094 (define_insn "neon_vcvt_n<mode>"
3095 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3096 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3097 (match_operand:SI 2 "immediate_operand" "i")
3098 (match_operand:SI 3 "immediate_operand" "i")]
3102 neon_const_bounds (operands[2], 1, 33);
3103 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
3105 [(set (attr "neon_type")
3106 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3107 (const_string "neon_fp_vadd_ddd_vabs_dd")
3108 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3111 (define_insn "neon_vcvt_n<mode>"
3112 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3113 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3114 (match_operand:SI 2 "immediate_operand" "i")
3115 (match_operand:SI 3 "immediate_operand" "i")]
3119 neon_const_bounds (operands[2], 1, 33);
3120 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
3122 [(set (attr "neon_type")
3123 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3124 (const_string "neon_fp_vadd_ddd_vabs_dd")
3125 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3128 (define_insn "neon_vmovn<mode>"
3129 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3130 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3131 (match_operand:SI 2 "immediate_operand" "i")]
3134 "vmovn.<V_if_elem>\t%P0, %q1"
3135 [(set_attr "neon_type" "neon_bp_simple")]
3138 (define_insn "neon_vqmovn<mode>"
3139 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3140 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3141 (match_operand:SI 2 "immediate_operand" "i")]
3144 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
3145 [(set_attr "neon_type" "neon_shift_2")]
3148 (define_insn "neon_vqmovun<mode>"
3149 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3150 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3151 (match_operand:SI 2 "immediate_operand" "i")]
3154 "vqmovun.<V_s_elem>\t%P0, %q1"
3155 [(set_attr "neon_type" "neon_shift_2")]
3158 (define_insn "neon_vmovl<mode>"
3159 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3160 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3161 (match_operand:SI 2 "immediate_operand" "i")]
3164 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
3165 [(set_attr "neon_type" "neon_shift_1")]
3168 (define_insn "neon_vmul_lane<mode>"
3169 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3170 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
3171 (match_operand:VMD 2 "s_register_operand"
3172 "<scalar_mul_constraint>")
3173 (match_operand:SI 3 "immediate_operand" "i")
3174 (match_operand:SI 4 "immediate_operand" "i")]
3178 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3179 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
3181 [(set (attr "neon_type")
3182 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3183 (const_string "neon_fp_vmul_ddd")
3184 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3185 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3186 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
3189 (define_insn "neon_vmul_lane<mode>"
3190 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3191 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
3192 (match_operand:<V_HALF> 2 "s_register_operand"
3193 "<scalar_mul_constraint>")
3194 (match_operand:SI 3 "immediate_operand" "i")
3195 (match_operand:SI 4 "immediate_operand" "i")]
3199 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3200 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3202 [(set (attr "neon_type")
3203 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3204 (const_string "neon_fp_vmul_qqd")
3205 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3206 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3207 (const_string "neon_mul_qqd_32_scalar"))))]
3210 (define_insn "neon_vmull_lane<mode>"
3211 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3212 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3213 (match_operand:VMDI 2 "s_register_operand"
3214 "<scalar_mul_constraint>")
3215 (match_operand:SI 3 "immediate_operand" "i")
3216 (match_operand:SI 4 "immediate_operand" "i")]
3217 UNSPEC_VMULL_LANE))]
3220 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3221 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3223 [(set (attr "neon_type")
3224 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3225 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3226 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3229 (define_insn "neon_vqdmull_lane<mode>"
3230 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3231 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3232 (match_operand:VMDI 2 "s_register_operand"
3233 "<scalar_mul_constraint>")
3234 (match_operand:SI 3 "immediate_operand" "i")
3235 (match_operand:SI 4 "immediate_operand" "i")]
3236 UNSPEC_VQDMULL_LANE))]
3239 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3240 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3242 [(set (attr "neon_type")
3243 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3244 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3245 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3248 (define_insn "neon_vqdmulh_lane<mode>"
3249 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3250 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3251 (match_operand:<V_HALF> 2 "s_register_operand"
3252 "<scalar_mul_constraint>")
3253 (match_operand:SI 3 "immediate_operand" "i")
3254 (match_operand:SI 4 "immediate_operand" "i")]
3255 UNSPEC_VQDMULH_LANE))]
3258 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3259 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3261 [(set (attr "neon_type")
3262 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3263 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3264 (const_string "neon_mul_qqd_32_scalar")))]
3267 (define_insn "neon_vqdmulh_lane<mode>"
3268 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3269 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3270 (match_operand:VMDI 2 "s_register_operand"
3271 "<scalar_mul_constraint>")
3272 (match_operand:SI 3 "immediate_operand" "i")
3273 (match_operand:SI 4 "immediate_operand" "i")]
3274 UNSPEC_VQDMULH_LANE))]
3277 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3278 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3280 [(set (attr "neon_type")
3281 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3282 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3283 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3286 (define_insn "neon_vmla_lane<mode>"
3287 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3288 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3289 (match_operand:VMD 2 "s_register_operand" "w")
3290 (match_operand:VMD 3 "s_register_operand"
3291 "<scalar_mul_constraint>")
3292 (match_operand:SI 4 "immediate_operand" "i")
3293 (match_operand:SI 5 "immediate_operand" "i")]
3297 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3298 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3300 [(set (attr "neon_type")
3301 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3302 (const_string "neon_fp_vmla_ddd_scalar")
3303 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3304 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3305 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3308 (define_insn "neon_vmla_lane<mode>"
3309 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3310 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3311 (match_operand:VMQ 2 "s_register_operand" "w")
3312 (match_operand:<V_HALF> 3 "s_register_operand"
3313 "<scalar_mul_constraint>")
3314 (match_operand:SI 4 "immediate_operand" "i")
3315 (match_operand:SI 5 "immediate_operand" "i")]
3319 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3320 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3322 [(set (attr "neon_type")
3323 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3324 (const_string "neon_fp_vmla_qqq_scalar")
3325 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3326 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3327 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3330 (define_insn "neon_vmlal_lane<mode>"
3331 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3332 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3333 (match_operand:VMDI 2 "s_register_operand" "w")
3334 (match_operand:VMDI 3 "s_register_operand"
3335 "<scalar_mul_constraint>")
3336 (match_operand:SI 4 "immediate_operand" "i")
3337 (match_operand:SI 5 "immediate_operand" "i")]
3338 UNSPEC_VMLAL_LANE))]
3341 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3342 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3344 [(set (attr "neon_type")
3345 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3346 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3347 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3350 (define_insn "neon_vqdmlal_lane<mode>"
3351 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3352 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3353 (match_operand:VMDI 2 "s_register_operand" "w")
3354 (match_operand:VMDI 3 "s_register_operand"
3355 "<scalar_mul_constraint>")
3356 (match_operand:SI 4 "immediate_operand" "i")
3357 (match_operand:SI 5 "immediate_operand" "i")]
3358 UNSPEC_VQDMLAL_LANE))]
3361 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3362 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3364 [(set (attr "neon_type")
3365 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3366 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3367 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3370 (define_insn "neon_vmls_lane<mode>"
3371 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3372 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3373 (match_operand:VMD 2 "s_register_operand" "w")
3374 (match_operand:VMD 3 "s_register_operand"
3375 "<scalar_mul_constraint>")
3376 (match_operand:SI 4 "immediate_operand" "i")
3377 (match_operand:SI 5 "immediate_operand" "i")]
3381 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3382 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3384 [(set (attr "neon_type")
3385 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3386 (const_string "neon_fp_vmla_ddd_scalar")
3387 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3388 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3389 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3392 (define_insn "neon_vmls_lane<mode>"
3393 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3394 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3395 (match_operand:VMQ 2 "s_register_operand" "w")
3396 (match_operand:<V_HALF> 3 "s_register_operand"
3397 "<scalar_mul_constraint>")
3398 (match_operand:SI 4 "immediate_operand" "i")
3399 (match_operand:SI 5 "immediate_operand" "i")]
3403 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3404 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3406 [(set (attr "neon_type")
3407 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3408 (const_string "neon_fp_vmla_qqq_scalar")
3409 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3410 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3411 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3414 (define_insn "neon_vmlsl_lane<mode>"
3415 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3416 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3417 (match_operand:VMDI 2 "s_register_operand" "w")
3418 (match_operand:VMDI 3 "s_register_operand"
3419 "<scalar_mul_constraint>")
3420 (match_operand:SI 4 "immediate_operand" "i")
3421 (match_operand:SI 5 "immediate_operand" "i")]
3422 UNSPEC_VMLSL_LANE))]
3425 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3426 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3428 [(set (attr "neon_type")
3429 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3430 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3431 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3434 (define_insn "neon_vqdmlsl_lane<mode>"
3435 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3436 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3437 (match_operand:VMDI 2 "s_register_operand" "w")
3438 (match_operand:VMDI 3 "s_register_operand"
3439 "<scalar_mul_constraint>")
3440 (match_operand:SI 4 "immediate_operand" "i")
3441 (match_operand:SI 5 "immediate_operand" "i")]
3442 UNSPEC_VQDMLSL_LANE))]
3445 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3446 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3448 [(set (attr "neon_type")
3449 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3450 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3451 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3454 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3455 ; core register into a temp register, then use a scalar taken from that. This
3456 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3457 ; or extracted from another vector. The latter case it's currently better to
3458 ; use the "_lane" variant, and the former case can probably be implemented
3459 ; using vld1_lane, but that hasn't been done yet.
3461 (define_expand "neon_vmul_n<mode>"
3462 [(match_operand:VMD 0 "s_register_operand" "")
3463 (match_operand:VMD 1 "s_register_operand" "")
3464 (match_operand:<V_elem> 2 "s_register_operand" "")
3465 (match_operand:SI 3 "immediate_operand" "")]
3468 rtx tmp = gen_reg_rtx (<MODE>mode);
3469 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3470 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3471 const0_rtx, const0_rtx));
3475 (define_expand "neon_vmul_n<mode>"
3476 [(match_operand:VMQ 0 "s_register_operand" "")
3477 (match_operand:VMQ 1 "s_register_operand" "")
3478 (match_operand:<V_elem> 2 "s_register_operand" "")
3479 (match_operand:SI 3 "immediate_operand" "")]
3482 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3483 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3484 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3485 const0_rtx, const0_rtx));
3489 (define_expand "neon_vmull_n<mode>"
3490 [(match_operand:<V_widen> 0 "s_register_operand" "")
3491 (match_operand:VMDI 1 "s_register_operand" "")
3492 (match_operand:<V_elem> 2 "s_register_operand" "")
3493 (match_operand:SI 3 "immediate_operand" "")]
3496 rtx tmp = gen_reg_rtx (<MODE>mode);
3497 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3498 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3499 const0_rtx, operands[3]));
3503 (define_expand "neon_vqdmull_n<mode>"
3504 [(match_operand:<V_widen> 0 "s_register_operand" "")
3505 (match_operand:VMDI 1 "s_register_operand" "")
3506 (match_operand:<V_elem> 2 "s_register_operand" "")
3507 (match_operand:SI 3 "immediate_operand" "")]
3510 rtx tmp = gen_reg_rtx (<MODE>mode);
3511 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3512 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3513 const0_rtx, const0_rtx));
3517 (define_expand "neon_vqdmulh_n<mode>"
3518 [(match_operand:VMDI 0 "s_register_operand" "")
3519 (match_operand:VMDI 1 "s_register_operand" "")
3520 (match_operand:<V_elem> 2 "s_register_operand" "")
3521 (match_operand:SI 3 "immediate_operand" "")]
3524 rtx tmp = gen_reg_rtx (<MODE>mode);
3525 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3526 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3527 const0_rtx, operands[3]));
3531 (define_expand "neon_vqdmulh_n<mode>"
3532 [(match_operand:VMQI 0 "s_register_operand" "")
3533 (match_operand:VMQI 1 "s_register_operand" "")
3534 (match_operand:<V_elem> 2 "s_register_operand" "")
3535 (match_operand:SI 3 "immediate_operand" "")]
3538 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3539 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3540 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3541 const0_rtx, operands[3]));
3545 (define_expand "neon_vmla_n<mode>"
3546 [(match_operand:VMD 0 "s_register_operand" "")
3547 (match_operand:VMD 1 "s_register_operand" "")
3548 (match_operand:VMD 2 "s_register_operand" "")
3549 (match_operand:<V_elem> 3 "s_register_operand" "")
3550 (match_operand:SI 4 "immediate_operand" "")]
3553 rtx tmp = gen_reg_rtx (<MODE>mode);
3554 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3555 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3556 tmp, const0_rtx, operands[4]));
3560 (define_expand "neon_vmla_n<mode>"
3561 [(match_operand:VMQ 0 "s_register_operand" "")
3562 (match_operand:VMQ 1 "s_register_operand" "")
3563 (match_operand:VMQ 2 "s_register_operand" "")
3564 (match_operand:<V_elem> 3 "s_register_operand" "")
3565 (match_operand:SI 4 "immediate_operand" "")]
3568 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3569 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3570 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3571 tmp, const0_rtx, operands[4]));
3575 (define_expand "neon_vmlal_n<mode>"
3576 [(match_operand:<V_widen> 0 "s_register_operand" "")
3577 (match_operand:<V_widen> 1 "s_register_operand" "")
3578 (match_operand:VMDI 2 "s_register_operand" "")
3579 (match_operand:<V_elem> 3 "s_register_operand" "")
3580 (match_operand:SI 4 "immediate_operand" "")]
3583 rtx tmp = gen_reg_rtx (<MODE>mode);
3584 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3585 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3586 tmp, const0_rtx, operands[4]));
3590 (define_expand "neon_vqdmlal_n<mode>"
3591 [(match_operand:<V_widen> 0 "s_register_operand" "")
3592 (match_operand:<V_widen> 1 "s_register_operand" "")
3593 (match_operand:VMDI 2 "s_register_operand" "")
3594 (match_operand:<V_elem> 3 "s_register_operand" "")
3595 (match_operand:SI 4 "immediate_operand" "")]
3598 rtx tmp = gen_reg_rtx (<MODE>mode);
3599 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3600 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3601 tmp, const0_rtx, operands[4]));
3605 (define_expand "neon_vmls_n<mode>"
3606 [(match_operand:VMD 0 "s_register_operand" "")
3607 (match_operand:VMD 1 "s_register_operand" "")
3608 (match_operand:VMD 2 "s_register_operand" "")
3609 (match_operand:<V_elem> 3 "s_register_operand" "")
3610 (match_operand:SI 4 "immediate_operand" "")]
3613 rtx tmp = gen_reg_rtx (<MODE>mode);
3614 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3615 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3616 tmp, const0_rtx, operands[4]));
3620 (define_expand "neon_vmls_n<mode>"
3621 [(match_operand:VMQ 0 "s_register_operand" "")
3622 (match_operand:VMQ 1 "s_register_operand" "")
3623 (match_operand:VMQ 2 "s_register_operand" "")
3624 (match_operand:<V_elem> 3 "s_register_operand" "")
3625 (match_operand:SI 4 "immediate_operand" "")]
3628 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3629 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3630 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3631 tmp, const0_rtx, operands[4]));
3635 (define_expand "neon_vmlsl_n<mode>"
3636 [(match_operand:<V_widen> 0 "s_register_operand" "")
3637 (match_operand:<V_widen> 1 "s_register_operand" "")
3638 (match_operand:VMDI 2 "s_register_operand" "")
3639 (match_operand:<V_elem> 3 "s_register_operand" "")
3640 (match_operand:SI 4 "immediate_operand" "")]
3643 rtx tmp = gen_reg_rtx (<MODE>mode);
3644 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3645 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3646 tmp, const0_rtx, operands[4]));
3650 (define_expand "neon_vqdmlsl_n<mode>"
3651 [(match_operand:<V_widen> 0 "s_register_operand" "")
3652 (match_operand:<V_widen> 1 "s_register_operand" "")
3653 (match_operand:VMDI 2 "s_register_operand" "")
3654 (match_operand:<V_elem> 3 "s_register_operand" "")
3655 (match_operand:SI 4 "immediate_operand" "")]
3658 rtx tmp = gen_reg_rtx (<MODE>mode);
3659 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3660 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3661 tmp, const0_rtx, operands[4]));
3665 (define_insn "neon_vext<mode>"
3666 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3667 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3668 (match_operand:VDQX 2 "s_register_operand" "w")
3669 (match_operand:SI 3 "immediate_operand" "i")]
3673 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3674 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3676 [(set (attr "neon_type")
3677 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3678 (const_string "neon_bp_simple")
3679 (const_string "neon_bp_2cycle")))]
3682 (define_insn "neon_vrev64<mode>"
3683 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3684 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3685 (match_operand:SI 2 "immediate_operand" "i")]
3688 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3689 [(set_attr "neon_type" "neon_bp_simple")]
3692 (define_insn "neon_vrev32<mode>"
3693 [(set (match_operand:VX 0 "s_register_operand" "=w")
3694 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3695 (match_operand:SI 2 "immediate_operand" "i")]
3698 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3699 [(set_attr "neon_type" "neon_bp_simple")]
3702 (define_insn "neon_vrev16<mode>"
3703 [(set (match_operand:VE 0 "s_register_operand" "=w")
3704 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3705 (match_operand:SI 2 "immediate_operand" "i")]
3708 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3709 [(set_attr "neon_type" "neon_bp_simple")]
3712 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3713 ; allocation. For an intrinsic of form:
3714 ; rD = vbsl_* (rS, rN, rM)
3715 ; We can use any of:
3716 ; vbsl rS, rN, rM (if D = S)
3717 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3718 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3720 (define_insn "neon_vbsl<mode>_internal"
3721 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3722 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3723 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3724 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3728 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3729 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3730 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3731 [(set_attr "neon_type" "neon_int_1")]
3734 (define_expand "neon_vbsl<mode>"
3735 [(set (match_operand:VDQX 0 "s_register_operand" "")
3736 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3737 (match_operand:VDQX 2 "s_register_operand" "")
3738 (match_operand:VDQX 3 "s_register_operand" "")]
3742 /* We can't alias operands together if they have different modes. */
3743 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3746 (define_insn "neon_vshl<mode>"
3747 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3748 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3749 (match_operand:VDQIX 2 "s_register_operand" "w")
3750 (match_operand:SI 3 "immediate_operand" "i")]
3753 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3754 [(set (attr "neon_type")
3755 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3756 (const_string "neon_vshl_ddd")
3757 (const_string "neon_shift_3")))]
3760 (define_insn "neon_vqshl<mode>"
3761 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3762 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3763 (match_operand:VDQIX 2 "s_register_operand" "w")
3764 (match_operand:SI 3 "immediate_operand" "i")]
3767 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3768 [(set (attr "neon_type")
3769 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3770 (const_string "neon_shift_2")
3771 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3774 (define_insn "neon_vshr_n<mode>"
3775 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3776 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3777 (match_operand:SI 2 "immediate_operand" "i")
3778 (match_operand:SI 3 "immediate_operand" "i")]
3782 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3783 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3785 [(set_attr "neon_type" "neon_shift_1")]
3788 (define_insn "neon_vshrn_n<mode>"
3789 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3790 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3791 (match_operand:SI 2 "immediate_operand" "i")
3792 (match_operand:SI 3 "immediate_operand" "i")]
3796 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3797 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3799 [(set_attr "neon_type" "neon_shift_1")]
3802 (define_insn "neon_vqshrn_n<mode>"
3803 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3804 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3805 (match_operand:SI 2 "immediate_operand" "i")
3806 (match_operand:SI 3 "immediate_operand" "i")]
3810 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3811 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3813 [(set_attr "neon_type" "neon_shift_2")]
3816 (define_insn "neon_vqshrun_n<mode>"
3817 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3818 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3819 (match_operand:SI 2 "immediate_operand" "i")
3820 (match_operand:SI 3 "immediate_operand" "i")]
3824 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3825 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3827 [(set_attr "neon_type" "neon_shift_2")]
3830 (define_insn "neon_vshl_n<mode>"
3831 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3832 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3833 (match_operand:SI 2 "immediate_operand" "i")
3834 (match_operand:SI 3 "immediate_operand" "i")]
3838 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3839 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
3841 [(set_attr "neon_type" "neon_shift_1")]
3844 (define_insn "neon_vqshl_n<mode>"
3845 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3846 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3847 (match_operand:SI 2 "immediate_operand" "i")
3848 (match_operand:SI 3 "immediate_operand" "i")]
3852 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3853 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3855 [(set_attr "neon_type" "neon_shift_2")]
3858 (define_insn "neon_vqshlu_n<mode>"
3859 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3860 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3861 (match_operand:SI 2 "immediate_operand" "i")
3862 (match_operand:SI 3 "immediate_operand" "i")]
3866 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3867 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3869 [(set_attr "neon_type" "neon_shift_2")]
3872 (define_insn "neon_vshll_n<mode>"
3873 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3874 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3875 (match_operand:SI 2 "immediate_operand" "i")
3876 (match_operand:SI 3 "immediate_operand" "i")]
3880 /* The boundaries are: 0 < imm <= size. */
3881 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
3882 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
3884 [(set_attr "neon_type" "neon_shift_1")]
3887 (define_insn "neon_vsra_n<mode>"
3888 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3889 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3890 (match_operand:VDQIX 2 "s_register_operand" "w")
3891 (match_operand:SI 3 "immediate_operand" "i")
3892 (match_operand:SI 4 "immediate_operand" "i")]
3896 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3897 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3899 [(set_attr "neon_type" "neon_vsra_vrsra")]
3902 (define_insn "neon_vsri_n<mode>"
3903 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3904 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3905 (match_operand:VDQIX 2 "s_register_operand" "w")
3906 (match_operand:SI 3 "immediate_operand" "i")]
3910 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3911 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3913 [(set (attr "neon_type")
3914 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3915 (const_string "neon_shift_1")
3916 (const_string "neon_shift_3")))]
3919 (define_insn "neon_vsli_n<mode>"
3920 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3921 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3922 (match_operand:VDQIX 2 "s_register_operand" "w")
3923 (match_operand:SI 3 "immediate_operand" "i")]
3927 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
3928 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3930 [(set (attr "neon_type")
3931 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3932 (const_string "neon_shift_1")
3933 (const_string "neon_shift_3")))]
3936 (define_insn "neon_vtbl1v8qi"
3937 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3938 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
3939 (match_operand:V8QI 2 "s_register_operand" "w")]
3942 "vtbl.8\t%P0, {%P1}, %P2"
3943 [(set_attr "neon_type" "neon_bp_2cycle")]
3946 (define_insn "neon_vtbl2v8qi"
3947 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3948 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
3949 (match_operand:V8QI 2 "s_register_operand" "w")]
3954 int tabbase = REGNO (operands[1]);
3956 ops[0] = operands[0];
3957 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3958 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3959 ops[3] = operands[2];
3960 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
3964 [(set_attr "neon_type" "neon_bp_2cycle")]
3967 (define_insn "neon_vtbl3v8qi"
3968 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3969 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
3970 (match_operand:V8QI 2 "s_register_operand" "w")]
3975 int tabbase = REGNO (operands[1]);
3977 ops[0] = operands[0];
3978 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3979 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3980 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3981 ops[4] = operands[2];
3982 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3986 [(set_attr "neon_type" "neon_bp_3cycle")]
3989 (define_insn "neon_vtbl4v8qi"
3990 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3991 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
3992 (match_operand:V8QI 2 "s_register_operand" "w")]
3997 int tabbase = REGNO (operands[1]);
3999 ops[0] = operands[0];
4000 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4001 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4002 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4003 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4004 ops[5] = operands[2];
4005 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4009 [(set_attr "neon_type" "neon_bp_3cycle")]
4012 (define_insn "neon_vtbx1v8qi"
4013 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4014 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4015 (match_operand:V8QI 2 "s_register_operand" "w")
4016 (match_operand:V8QI 3 "s_register_operand" "w")]
4019 "vtbx.8\t%P0, {%P2}, %P3"
4020 [(set_attr "neon_type" "neon_bp_2cycle")]
4023 (define_insn "neon_vtbx2v8qi"
4024 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4025 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4026 (match_operand:TI 2 "s_register_operand" "w")
4027 (match_operand:V8QI 3 "s_register_operand" "w")]
4032 int tabbase = REGNO (operands[2]);
4034 ops[0] = operands[0];
4035 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4036 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4037 ops[3] = operands[3];
4038 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
4042 [(set_attr "neon_type" "neon_bp_2cycle")]
4045 (define_insn "neon_vtbx3v8qi"
4046 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4047 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4048 (match_operand:EI 2 "s_register_operand" "w")
4049 (match_operand:V8QI 3 "s_register_operand" "w")]
4054 int tabbase = REGNO (operands[2]);
4056 ops[0] = operands[0];
4057 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4058 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4059 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4060 ops[4] = operands[3];
4061 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4065 [(set_attr "neon_type" "neon_bp_3cycle")]
4068 (define_insn "neon_vtbx4v8qi"
4069 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4070 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4071 (match_operand:OI 2 "s_register_operand" "w")
4072 (match_operand:V8QI 3 "s_register_operand" "w")]
4077 int tabbase = REGNO (operands[2]);
4079 ops[0] = operands[0];
4080 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4081 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4082 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4083 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4084 ops[5] = operands[3];
4085 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4089 [(set_attr "neon_type" "neon_bp_3cycle")]
4092 (define_insn "neon_vtrn<mode>_internal"
4093 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4094 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4096 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4097 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4100 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4101 [(set (attr "neon_type")
4102 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4103 (const_string "neon_bp_simple")
4104 (const_string "neon_bp_3cycle")))]
4107 (define_expand "neon_vtrn<mode>"
4108 [(match_operand:SI 0 "s_register_operand" "r")
4109 (match_operand:VDQW 1 "s_register_operand" "w")
4110 (match_operand:VDQW 2 "s_register_operand" "w")]
4113 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
4114 operands[0], operands[1], operands[2]);
4118 (define_insn "neon_vzip<mode>_internal"
4119 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4120 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4122 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4123 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4126 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4127 [(set (attr "neon_type")
4128 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4129 (const_string "neon_bp_simple")
4130 (const_string "neon_bp_3cycle")))]
4133 (define_expand "neon_vzip<mode>"
4134 [(match_operand:SI 0 "s_register_operand" "r")
4135 (match_operand:VDQW 1 "s_register_operand" "w")
4136 (match_operand:VDQW 2 "s_register_operand" "w")]
4139 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
4140 operands[0], operands[1], operands[2]);
4144 (define_insn "neon_vuzp<mode>_internal"
4145 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4146 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4148 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4149 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4152 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4153 [(set (attr "neon_type")
4154 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4155 (const_string "neon_bp_simple")
4156 (const_string "neon_bp_3cycle")))]
4159 (define_expand "neon_vuzp<mode>"
4160 [(match_operand:SI 0 "s_register_operand" "r")
4161 (match_operand:VDQW 1 "s_register_operand" "w")
4162 (match_operand:VDQW 2 "s_register_operand" "w")]
4165 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
4166 operands[0], operands[1], operands[2]);
4170 (define_expand "neon_vreinterpretv8qi<mode>"
4171 [(match_operand:V8QI 0 "s_register_operand" "")
4172 (match_operand:VDX 1 "s_register_operand" "")]
4175 neon_reinterpret (operands[0], operands[1]);
4179 (define_expand "neon_vreinterpretv4hi<mode>"
4180 [(match_operand:V4HI 0 "s_register_operand" "")
4181 (match_operand:VDX 1 "s_register_operand" "")]
4184 neon_reinterpret (operands[0], operands[1]);
4188 (define_expand "neon_vreinterpretv2si<mode>"
4189 [(match_operand:V2SI 0 "s_register_operand" "")
4190 (match_operand:VDX 1 "s_register_operand" "")]
4193 neon_reinterpret (operands[0], operands[1]);
4197 (define_expand "neon_vreinterpretv2sf<mode>"
4198 [(match_operand:V2SF 0 "s_register_operand" "")
4199 (match_operand:VDX 1 "s_register_operand" "")]
4202 neon_reinterpret (operands[0], operands[1]);
4206 (define_expand "neon_vreinterpretdi<mode>"
4207 [(match_operand:DI 0 "s_register_operand" "")
4208 (match_operand:VDX 1 "s_register_operand" "")]
4211 neon_reinterpret (operands[0], operands[1]);
4215 (define_expand "neon_vreinterpretv16qi<mode>"
4216 [(match_operand:V16QI 0 "s_register_operand" "")
4217 (match_operand:VQX 1 "s_register_operand" "")]
4220 neon_reinterpret (operands[0], operands[1]);
4224 (define_expand "neon_vreinterpretv8hi<mode>"
4225 [(match_operand:V8HI 0 "s_register_operand" "")
4226 (match_operand:VQX 1 "s_register_operand" "")]
4229 neon_reinterpret (operands[0], operands[1]);
4233 (define_expand "neon_vreinterpretv4si<mode>"
4234 [(match_operand:V4SI 0 "s_register_operand" "")
4235 (match_operand:VQX 1 "s_register_operand" "")]
4238 neon_reinterpret (operands[0], operands[1]);
4242 (define_expand "neon_vreinterpretv4sf<mode>"
4243 [(match_operand:V4SF 0 "s_register_operand" "")
4244 (match_operand:VQX 1 "s_register_operand" "")]
4247 neon_reinterpret (operands[0], operands[1]);
4251 (define_expand "neon_vreinterpretv2di<mode>"
4252 [(match_operand:V2DI 0 "s_register_operand" "")
4253 (match_operand:VQX 1 "s_register_operand" "")]
4256 neon_reinterpret (operands[0], operands[1]);
4260 (define_insn "neon_vld1<mode>"
4261 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4262 (unspec:VDQX [(mem:VDQX (match_operand:SI 1 "s_register_operand" "r"))]
4265 "vld1.<V_sz_elem>\t%h0, [%1]"
4266 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4269 (define_insn "neon_vld1_lane<mode>"
4270 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4271 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4272 (match_operand:VDX 2 "s_register_operand" "0")
4273 (match_operand:SI 3 "immediate_operand" "i")]
4277 HOST_WIDE_INT lane = INTVAL (operands[3]);
4278 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4279 if (lane < 0 || lane >= max)
4280 error ("lane out of range");
4282 return "vld1.<V_sz_elem>\t%P0, [%1]";
4284 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4286 [(set (attr "neon_type")
4287 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4288 (const_string "neon_vld1_1_2_regs")
4289 (const_string "neon_vld1_vld2_lane")))]
4292 (define_insn "neon_vld1_lane<mode>"
4293 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4294 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4295 (match_operand:VQX 2 "s_register_operand" "0")
4296 (match_operand:SI 3 "immediate_operand" "i")]
4300 HOST_WIDE_INT lane = INTVAL (operands[3]);
4301 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4302 int regno = REGNO (operands[0]);
4303 if (lane < 0 || lane >= max)
4304 error ("lane out of range");
4305 else if (lane >= max / 2)
4309 operands[3] = GEN_INT (lane);
4311 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4313 return "vld1.<V_sz_elem>\t%P0, [%1]";
4315 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4317 [(set (attr "neon_type")
4318 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4319 (const_string "neon_vld1_1_2_regs")
4320 (const_string "neon_vld1_vld2_lane")))]
4323 (define_insn "neon_vld1_dup<mode>"
4324 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4325 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4329 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4330 return "vld1.<V_sz_elem>\t{%P0[]}, [%1]";
4332 return "vld1.<V_sz_elem>\t%h0, [%1]";
4334 [(set (attr "neon_type")
4335 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4336 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4337 (const_string "neon_vld1_1_2_regs")))]
4340 (define_insn "neon_vld1_dup<mode>"
4341 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4342 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4346 if (GET_MODE_NUNITS (<MODE>mode) > 2)
4347 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4349 return "vld1.<V_sz_elem>\t%h0, [%1]";
4351 [(set (attr "neon_type")
4352 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4353 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4354 (const_string "neon_vld1_1_2_regs")))]
4357 (define_insn "neon_vst1<mode>"
4358 [(set (mem:VDQX (match_operand:SI 0 "s_register_operand" "r"))
4359 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4362 "vst1.<V_sz_elem>\t%h1, [%0]"
4363 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4365 (define_insn "neon_vst1_lane<mode>"
4366 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4367 (vec_select:<V_elem>
4368 (match_operand:VDX 1 "s_register_operand" "w")
4369 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4372 HOST_WIDE_INT lane = INTVAL (operands[2]);
4373 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4374 if (lane < 0 || lane >= max)
4375 error ("lane out of range");
4377 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4379 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4381 [(set (attr "neon_type")
4382 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4383 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4384 (const_string "neon_vst1_vst2_lane")))])
4386 (define_insn "neon_vst1_lane<mode>"
4387 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4388 (vec_select:<V_elem>
4389 (match_operand:VQX 1 "s_register_operand" "w")
4390 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4393 HOST_WIDE_INT lane = INTVAL (operands[2]);
4394 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4395 int regno = REGNO (operands[1]);
4396 if (lane < 0 || lane >= max)
4397 error ("lane out of range");
4398 else if (lane >= max / 2)
4402 operands[2] = GEN_INT (lane);
4404 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4406 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4408 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4410 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4413 (define_insn "neon_vld2<mode>"
4414 [(set (match_operand:TI 0 "s_register_operand" "=w")
4415 (unspec:TI [(mem:TI (match_operand:SI 1 "s_register_operand" "r"))
4416 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4420 if (<V_sz_elem> == 64)
4421 return "vld1.64\t%h0, [%1]";
4423 return "vld2.<V_sz_elem>\t%h0, [%1]";
4425 [(set (attr "neon_type")
4426 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4427 (const_string "neon_vld1_1_2_regs")
4428 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4431 (define_insn "neon_vld2<mode>"
4432 [(set (match_operand:OI 0 "s_register_operand" "=w")
4433 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4434 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4437 "vld2.<V_sz_elem>\t%h0, [%1]"
4438 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4440 (define_insn "neon_vld2_lane<mode>"
4441 [(set (match_operand:TI 0 "s_register_operand" "=w")
4442 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4443 (match_operand:TI 2 "s_register_operand" "0")
4444 (match_operand:SI 3 "immediate_operand" "i")
4445 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4449 HOST_WIDE_INT lane = INTVAL (operands[3]);
4450 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4451 int regno = REGNO (operands[0]);
4453 if (lane < 0 || lane >= max)
4454 error ("lane out of range");
4455 ops[0] = gen_rtx_REG (DImode, regno);
4456 ops[1] = gen_rtx_REG (DImode, regno + 2);
4457 ops[2] = operands[1];
4458 ops[3] = operands[3];
4459 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4462 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4465 (define_insn "neon_vld2_lane<mode>"
4466 [(set (match_operand:OI 0 "s_register_operand" "=w")
4467 (unspec:OI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4468 (match_operand:OI 2 "s_register_operand" "0")
4469 (match_operand:SI 3 "immediate_operand" "i")
4470 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4474 HOST_WIDE_INT lane = INTVAL (operands[3]);
4475 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4476 int regno = REGNO (operands[0]);
4478 if (lane < 0 || lane >= max)
4479 error ("lane out of range");
4480 else if (lane >= max / 2)
4485 ops[0] = gen_rtx_REG (DImode, regno);
4486 ops[1] = gen_rtx_REG (DImode, regno + 4);
4487 ops[2] = operands[1];
4488 ops[3] = GEN_INT (lane);
4489 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4492 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4495 (define_insn "neon_vld2_dup<mode>"
4496 [(set (match_operand:TI 0 "s_register_operand" "=w")
4497 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4498 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4502 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4503 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4505 return "vld1.<V_sz_elem>\t%h0, [%1]";
4507 [(set (attr "neon_type")
4508 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4509 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4510 (const_string "neon_vld1_1_2_regs")))]
4513 (define_insn "neon_vst2<mode>"
4514 [(set (mem:TI (match_operand:SI 0 "s_register_operand" "r"))
4515 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4516 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4520 if (<V_sz_elem> == 64)
4521 return "vst1.64\t%h1, [%0]";
4523 return "vst2.<V_sz_elem>\t%h1, [%0]";
4525 [(set (attr "neon_type")
4526 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4527 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4528 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4531 (define_insn "neon_vst2<mode>"
4532 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4533 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4534 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4537 "vst2.<V_sz_elem>\t%h1, [%0]"
4538 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4541 (define_insn "neon_vst2_lane<mode>"
4542 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4543 (unspec:<V_two_elem>
4544 [(match_operand:TI 1 "s_register_operand" "w")
4545 (match_operand:SI 2 "immediate_operand" "i")
4546 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4550 HOST_WIDE_INT lane = INTVAL (operands[2]);
4551 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4552 int regno = REGNO (operands[1]);
4554 if (lane < 0 || lane >= max)
4555 error ("lane out of range");
4556 ops[0] = operands[0];
4557 ops[1] = gen_rtx_REG (DImode, regno);
4558 ops[2] = gen_rtx_REG (DImode, regno + 2);
4559 ops[3] = operands[2];
4560 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4563 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4566 (define_insn "neon_vst2_lane<mode>"
4567 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4568 (unspec:<V_two_elem>
4569 [(match_operand:OI 1 "s_register_operand" "w")
4570 (match_operand:SI 2 "immediate_operand" "i")
4571 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4575 HOST_WIDE_INT lane = INTVAL (operands[2]);
4576 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4577 int regno = REGNO (operands[1]);
4579 if (lane < 0 || lane >= max)
4580 error ("lane out of range");
4581 else if (lane >= max / 2)
4586 ops[0] = operands[0];
4587 ops[1] = gen_rtx_REG (DImode, regno);
4588 ops[2] = gen_rtx_REG (DImode, regno + 4);
4589 ops[3] = GEN_INT (lane);
4590 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4593 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4596 (define_insn "neon_vld3<mode>"
4597 [(set (match_operand:EI 0 "s_register_operand" "=w")
4598 (unspec:EI [(mem:EI (match_operand:SI 1 "s_register_operand" "r"))
4599 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4603 if (<V_sz_elem> == 64)
4604 return "vld1.64\t%h0, [%1]";
4606 return "vld3.<V_sz_elem>\t%h0, [%1]";
4608 [(set (attr "neon_type")
4609 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4610 (const_string "neon_vld1_1_2_regs")
4611 (const_string "neon_vld3_vld4")))]
4614 (define_expand "neon_vld3<mode>"
4615 [(match_operand:CI 0 "s_register_operand" "=w")
4616 (match_operand:SI 1 "s_register_operand" "+r")
4617 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4620 emit_insn (gen_neon_vld3qa<mode> (operands[0], operands[0],
4621 operands[1], operands[1]));
4622 emit_insn (gen_neon_vld3qb<mode> (operands[0], operands[0],
4623 operands[1], operands[1]));
4627 (define_insn "neon_vld3qa<mode>"
4628 [(set (match_operand:CI 0 "s_register_operand" "=w")
4629 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4630 (match_operand:CI 1 "s_register_operand" "0")
4631 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4633 (set (match_operand:SI 2 "s_register_operand" "=r")
4634 (plus:SI (match_dup 3)
4638 int regno = REGNO (operands[0]);
4640 ops[0] = gen_rtx_REG (DImode, regno);
4641 ops[1] = gen_rtx_REG (DImode, regno + 4);
4642 ops[2] = gen_rtx_REG (DImode, regno + 8);
4643 ops[3] = operands[2];
4644 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4647 [(set_attr "neon_type" "neon_vld3_vld4")]
4650 (define_insn "neon_vld3qb<mode>"
4651 [(set (match_operand:CI 0 "s_register_operand" "=w")
4652 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4653 (match_operand:CI 1 "s_register_operand" "0")
4654 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4656 (set (match_operand:SI 2 "s_register_operand" "=r")
4657 (plus:SI (match_dup 3)
4661 int regno = REGNO (operands[0]);
4663 ops[0] = gen_rtx_REG (DImode, regno + 2);
4664 ops[1] = gen_rtx_REG (DImode, regno + 6);
4665 ops[2] = gen_rtx_REG (DImode, regno + 10);
4666 ops[3] = operands[2];
4667 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4670 [(set_attr "neon_type" "neon_vld3_vld4")]
4673 (define_insn "neon_vld3_lane<mode>"
4674 [(set (match_operand:EI 0 "s_register_operand" "=w")
4675 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4676 (match_operand:EI 2 "s_register_operand" "0")
4677 (match_operand:SI 3 "immediate_operand" "i")
4678 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4682 HOST_WIDE_INT lane = INTVAL (operands[3]);
4683 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4684 int regno = REGNO (operands[0]);
4686 if (lane < 0 || lane >= max)
4687 error ("lane out of range");
4688 ops[0] = gen_rtx_REG (DImode, regno);
4689 ops[1] = gen_rtx_REG (DImode, regno + 2);
4690 ops[2] = gen_rtx_REG (DImode, regno + 4);
4691 ops[3] = operands[1];
4692 ops[4] = operands[3];
4693 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4697 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4700 (define_insn "neon_vld3_lane<mode>"
4701 [(set (match_operand:CI 0 "s_register_operand" "=w")
4702 (unspec:CI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4703 (match_operand:CI 2 "s_register_operand" "0")
4704 (match_operand:SI 3 "immediate_operand" "i")
4705 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4709 HOST_WIDE_INT lane = INTVAL (operands[3]);
4710 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4711 int regno = REGNO (operands[0]);
4713 if (lane < 0 || lane >= max)
4714 error ("lane out of range");
4715 else if (lane >= max / 2)
4720 ops[0] = gen_rtx_REG (DImode, regno);
4721 ops[1] = gen_rtx_REG (DImode, regno + 4);
4722 ops[2] = gen_rtx_REG (DImode, regno + 8);
4723 ops[3] = operands[1];
4724 ops[4] = GEN_INT (lane);
4725 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4729 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4732 (define_insn "neon_vld3_dup<mode>"
4733 [(set (match_operand:EI 0 "s_register_operand" "=w")
4734 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4735 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4739 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4741 int regno = REGNO (operands[0]);
4743 ops[0] = gen_rtx_REG (DImode, regno);
4744 ops[1] = gen_rtx_REG (DImode, regno + 2);
4745 ops[2] = gen_rtx_REG (DImode, regno + 4);
4746 ops[3] = operands[1];
4747 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, [%3]", ops);
4751 return "vld1.<V_sz_elem>\t%h0, [%1]";
4753 [(set (attr "neon_type")
4754 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4755 (const_string "neon_vld3_vld4_all_lanes")
4756 (const_string "neon_vld1_1_2_regs")))])
4758 (define_insn "neon_vst3<mode>"
4759 [(set (mem:EI (match_operand:SI 0 "s_register_operand" "r"))
4760 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
4761 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4765 if (<V_sz_elem> == 64)
4766 return "vst1.64\t%h1, [%0]";
4768 return "vst3.<V_sz_elem>\t%h1, [%0]";
4770 [(set (attr "neon_type")
4771 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4772 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4773 (const_string "neon_vst2_4_regs_vst3_vst4")))])
4775 (define_expand "neon_vst3<mode>"
4776 [(match_operand:SI 0 "s_register_operand" "+r")
4777 (match_operand:CI 1 "s_register_operand" "w")
4778 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4781 emit_insn (gen_neon_vst3qa<mode> (operands[0], operands[0], operands[1]));
4782 emit_insn (gen_neon_vst3qb<mode> (operands[0], operands[0], operands[1]));
4786 (define_insn "neon_vst3qa<mode>"
4787 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4788 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4789 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4791 (set (match_operand:SI 0 "s_register_operand" "=r")
4792 (plus:SI (match_dup 1)
4796 int regno = REGNO (operands[2]);
4798 ops[0] = operands[0];
4799 ops[1] = gen_rtx_REG (DImode, regno);
4800 ops[2] = gen_rtx_REG (DImode, regno + 4);
4801 ops[3] = gen_rtx_REG (DImode, regno + 8);
4802 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4805 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4808 (define_insn "neon_vst3qb<mode>"
4809 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4810 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4811 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4813 (set (match_operand:SI 0 "s_register_operand" "=r")
4814 (plus:SI (match_dup 1)
4818 int regno = REGNO (operands[2]);
4820 ops[0] = operands[0];
4821 ops[1] = gen_rtx_REG (DImode, regno + 2);
4822 ops[2] = gen_rtx_REG (DImode, regno + 6);
4823 ops[3] = gen_rtx_REG (DImode, regno + 10);
4824 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4827 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4830 (define_insn "neon_vst3_lane<mode>"
4831 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4832 (unspec:<V_three_elem>
4833 [(match_operand:EI 1 "s_register_operand" "w")
4834 (match_operand:SI 2 "immediate_operand" "i")
4835 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4839 HOST_WIDE_INT lane = INTVAL (operands[2]);
4840 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4841 int regno = REGNO (operands[1]);
4843 if (lane < 0 || lane >= max)
4844 error ("lane out of range");
4845 ops[0] = operands[0];
4846 ops[1] = gen_rtx_REG (DImode, regno);
4847 ops[2] = gen_rtx_REG (DImode, regno + 2);
4848 ops[3] = gen_rtx_REG (DImode, regno + 4);
4849 ops[4] = operands[2];
4850 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4854 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4857 (define_insn "neon_vst3_lane<mode>"
4858 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4859 (unspec:<V_three_elem>
4860 [(match_operand:CI 1 "s_register_operand" "w")
4861 (match_operand:SI 2 "immediate_operand" "i")
4862 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4866 HOST_WIDE_INT lane = INTVAL (operands[2]);
4867 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4868 int regno = REGNO (operands[1]);
4870 if (lane < 0 || lane >= max)
4871 error ("lane out of range");
4872 else if (lane >= max / 2)
4877 ops[0] = operands[0];
4878 ops[1] = gen_rtx_REG (DImode, regno);
4879 ops[2] = gen_rtx_REG (DImode, regno + 4);
4880 ops[3] = gen_rtx_REG (DImode, regno + 8);
4881 ops[4] = GEN_INT (lane);
4882 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4886 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
4888 (define_insn "neon_vld4<mode>"
4889 [(set (match_operand:OI 0 "s_register_operand" "=w")
4890 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4891 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4895 if (<V_sz_elem> == 64)
4896 return "vld1.64\t%h0, [%1]";
4898 return "vld4.<V_sz_elem>\t%h0, [%1]";
4900 [(set (attr "neon_type")
4901 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4902 (const_string "neon_vld1_1_2_regs")
4903 (const_string "neon_vld3_vld4")))]
4906 (define_expand "neon_vld4<mode>"
4907 [(match_operand:XI 0 "s_register_operand" "=w")
4908 (match_operand:SI 1 "s_register_operand" "+r")
4909 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4912 emit_insn (gen_neon_vld4qa<mode> (operands[0], operands[0],
4913 operands[1], operands[1]));
4914 emit_insn (gen_neon_vld4qb<mode> (operands[0], operands[0],
4915 operands[1], operands[1]));
4919 (define_insn "neon_vld4qa<mode>"
4920 [(set (match_operand:XI 0 "s_register_operand" "=w")
4921 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4922 (match_operand:XI 1 "s_register_operand" "0")
4923 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4925 (set (match_operand:SI 2 "s_register_operand" "=r")
4926 (plus:SI (match_dup 3)
4930 int regno = REGNO (operands[0]);
4932 ops[0] = gen_rtx_REG (DImode, regno);
4933 ops[1] = gen_rtx_REG (DImode, regno + 4);
4934 ops[2] = gen_rtx_REG (DImode, regno + 8);
4935 ops[3] = gen_rtx_REG (DImode, regno + 12);
4936 ops[4] = operands[2];
4937 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4940 [(set_attr "neon_type" "neon_vld3_vld4")]
4943 (define_insn "neon_vld4qb<mode>"
4944 [(set (match_operand:XI 0 "s_register_operand" "=w")
4945 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4946 (match_operand:XI 1 "s_register_operand" "0")
4947 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4949 (set (match_operand:SI 2 "s_register_operand" "=r")
4950 (plus:SI (match_dup 3)
4954 int regno = REGNO (operands[0]);
4956 ops[0] = gen_rtx_REG (DImode, regno + 2);
4957 ops[1] = gen_rtx_REG (DImode, regno + 6);
4958 ops[2] = gen_rtx_REG (DImode, regno + 10);
4959 ops[3] = gen_rtx_REG (DImode, regno + 14);
4960 ops[4] = operands[2];
4961 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4964 [(set_attr "neon_type" "neon_vld3_vld4")]
4967 (define_insn "neon_vld4_lane<mode>"
4968 [(set (match_operand:OI 0 "s_register_operand" "=w")
4969 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4970 (match_operand:OI 2 "s_register_operand" "0")
4971 (match_operand:SI 3 "immediate_operand" "i")
4972 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4976 HOST_WIDE_INT lane = INTVAL (operands[3]);
4977 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4978 int regno = REGNO (operands[0]);
4980 if (lane < 0 || lane >= max)
4981 error ("lane out of range");
4982 ops[0] = gen_rtx_REG (DImode, regno);
4983 ops[1] = gen_rtx_REG (DImode, regno + 2);
4984 ops[2] = gen_rtx_REG (DImode, regno + 4);
4985 ops[3] = gen_rtx_REG (DImode, regno + 6);
4986 ops[4] = operands[1];
4987 ops[5] = operands[3];
4988 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4992 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4995 (define_insn "neon_vld4_lane<mode>"
4996 [(set (match_operand:XI 0 "s_register_operand" "=w")
4997 (unspec:XI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4998 (match_operand:XI 2 "s_register_operand" "0")
4999 (match_operand:SI 3 "immediate_operand" "i")
5000 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5004 HOST_WIDE_INT lane = INTVAL (operands[3]);
5005 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5006 int regno = REGNO (operands[0]);
5008 if (lane < 0 || lane >= max)
5009 error ("lane out of range");
5010 else if (lane >= max / 2)
5015 ops[0] = gen_rtx_REG (DImode, regno);
5016 ops[1] = gen_rtx_REG (DImode, regno + 4);
5017 ops[2] = gen_rtx_REG (DImode, regno + 8);
5018 ops[3] = gen_rtx_REG (DImode, regno + 12);
5019 ops[4] = operands[1];
5020 ops[5] = GEN_INT (lane);
5021 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
5025 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5028 (define_insn "neon_vld4_dup<mode>"
5029 [(set (match_operand:OI 0 "s_register_operand" "=w")
5030 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
5031 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5035 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5037 int regno = REGNO (operands[0]);
5039 ops[0] = gen_rtx_REG (DImode, regno);
5040 ops[1] = gen_rtx_REG (DImode, regno + 2);
5041 ops[2] = gen_rtx_REG (DImode, regno + 4);
5042 ops[3] = gen_rtx_REG (DImode, regno + 6);
5043 ops[4] = operands[1];
5044 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, [%4]",
5049 return "vld1.<V_sz_elem>\t%h0, [%1]";
5051 [(set (attr "neon_type")
5052 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5053 (const_string "neon_vld3_vld4_all_lanes")
5054 (const_string "neon_vld1_1_2_regs")))]
5057 (define_insn "neon_vst4<mode>"
5058 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
5059 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
5060 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5064 if (<V_sz_elem> == 64)
5065 return "vst1.64\t%h1, [%0]";
5067 return "vst4.<V_sz_elem>\t%h1, [%0]";
5069 [(set (attr "neon_type")
5070 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5071 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5072 (const_string "neon_vst2_4_regs_vst3_vst4")))]
5075 (define_expand "neon_vst4<mode>"
5076 [(match_operand:SI 0 "s_register_operand" "+r")
5077 (match_operand:XI 1 "s_register_operand" "w")
5078 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5081 emit_insn (gen_neon_vst4qa<mode> (operands[0], operands[0], operands[1]));
5082 emit_insn (gen_neon_vst4qb<mode> (operands[0], operands[0], operands[1]));
5086 (define_insn "neon_vst4qa<mode>"
5087 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
5088 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
5089 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5091 (set (match_operand:SI 0 "s_register_operand" "=r")
5092 (plus:SI (match_dup 1)
5096 int regno = REGNO (operands[2]);
5098 ops[0] = operands[0];
5099 ops[1] = gen_rtx_REG (DImode, regno);
5100 ops[2] = gen_rtx_REG (DImode, regno + 4);
5101 ops[3] = gen_rtx_REG (DImode, regno + 8);
5102 ops[4] = gen_rtx_REG (DImode, regno + 12);
5103 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
5106 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5109 (define_insn "neon_vst4qb<mode>"
5110 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
5111 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
5112 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5114 (set (match_operand:SI 0 "s_register_operand" "=r")
5115 (plus:SI (match_dup 1)
5119 int regno = REGNO (operands[2]);
5121 ops[0] = operands[0];
5122 ops[1] = gen_rtx_REG (DImode, regno + 2);
5123 ops[2] = gen_rtx_REG (DImode, regno + 6);
5124 ops[3] = gen_rtx_REG (DImode, regno + 10);
5125 ops[4] = gen_rtx_REG (DImode, regno + 14);
5126 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
5129 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5132 (define_insn "neon_vst4_lane<mode>"
5133 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
5134 (unspec:<V_four_elem>
5135 [(match_operand:OI 1 "s_register_operand" "w")
5136 (match_operand:SI 2 "immediate_operand" "i")
5137 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5141 HOST_WIDE_INT lane = INTVAL (operands[2]);
5142 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5143 int regno = REGNO (operands[1]);
5145 if (lane < 0 || lane >= max)
5146 error ("lane out of range");
5147 ops[0] = operands[0];
5148 ops[1] = gen_rtx_REG (DImode, regno);
5149 ops[2] = gen_rtx_REG (DImode, regno + 2);
5150 ops[3] = gen_rtx_REG (DImode, regno + 4);
5151 ops[4] = gen_rtx_REG (DImode, regno + 6);
5152 ops[5] = operands[2];
5153 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
5157 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5160 (define_insn "neon_vst4_lane<mode>"
5161 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
5162 (unspec:<V_four_elem>
5163 [(match_operand:XI 1 "s_register_operand" "w")
5164 (match_operand:SI 2 "immediate_operand" "i")
5165 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5169 HOST_WIDE_INT lane = INTVAL (operands[2]);
5170 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5171 int regno = REGNO (operands[1]);
5173 if (lane < 0 || lane >= max)
5174 error ("lane out of range");
5175 else if (lane >= max / 2)
5180 ops[0] = operands[0];
5181 ops[1] = gen_rtx_REG (DImode, regno);
5182 ops[2] = gen_rtx_REG (DImode, regno + 4);
5183 ops[3] = gen_rtx_REG (DImode, regno + 8);
5184 ops[4] = gen_rtx_REG (DImode, regno + 12);
5185 ops[5] = GEN_INT (lane);
5186 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
5190 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5193 (define_expand "neon_vand<mode>"
5194 [(match_operand:VDQX 0 "s_register_operand" "")
5195 (match_operand:VDQX 1 "s_register_operand" "")
5196 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5197 (match_operand:SI 3 "immediate_operand" "")]
5200 emit_insn (gen_and<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5204 (define_expand "neon_vorr<mode>"
5205 [(match_operand:VDQX 0 "s_register_operand" "")
5206 (match_operand:VDQX 1 "s_register_operand" "")
5207 (match_operand:VDQX 2 "neon_logic_op2" "")
5208 (match_operand:SI 3 "immediate_operand" "")]
5211 emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5215 (define_expand "neon_veor<mode>"
5216 [(match_operand:VDQX 0 "s_register_operand" "")
5217 (match_operand:VDQX 1 "s_register_operand" "")
5218 (match_operand:VDQX 2 "s_register_operand" "")
5219 (match_operand:SI 3 "immediate_operand" "")]
5222 emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5226 (define_expand "neon_vbic<mode>"
5227 [(match_operand:VDQX 0 "s_register_operand" "")
5228 (match_operand:VDQX 1 "s_register_operand" "")
5229 (match_operand:VDQX 2 "neon_logic_op2" "")
5230 (match_operand:SI 3 "immediate_operand" "")]
5233 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5237 (define_expand "neon_vorn<mode>"
5238 [(match_operand:VDQX 0 "s_register_operand" "")
5239 (match_operand:VDQX 1 "s_register_operand" "")
5240 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5241 (match_operand:SI 3 "immediate_operand" "")]
5244 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));
5248 (define_insn "neon_vec_unpack<US>_lo_<mode>"
5249 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5250 (SE:<V_unpack> (vec_select:<V_HALF>
5251 (match_operand:VU 1 "register_operand" "w")
5252 (match_operand:VU 2 "vect_par_constant_low" ""))))]
5254 "vmovl.<US><V_sz_elem> %q0, %e1"
5255 [(set_attr "neon_type" "neon_shift_1")]
5258 (define_insn "neon_vec_unpack<US>_hi_<mode>"
5259 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5260 (SE:<V_unpack> (vec_select:<V_HALF>
5261 (match_operand:VU 1 "register_operand" "w")
5262 (match_operand:VU 2 "vect_par_constant_high" ""))))]
5264 "vmovl.<US><V_sz_elem> %q0, %f1"
5265 [(set_attr "neon_type" "neon_shift_1")]
5268 (define_expand "vec_unpack<US>_hi_<mode>"
5269 [(match_operand:<V_unpack> 0 "register_operand" "")
5270 (SE:<V_unpack> (match_operand:VU 1 "register_operand"))]
5273 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5276 for (i = 0; i < (<V_mode_nunits>/2); i++)
5277 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
5279 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5280 emit_insn (gen_neon_vec_unpack<US>_hi_<mode> (operands[0],
5287 (define_expand "vec_unpack<US>_lo_<mode>"
5288 [(match_operand:<V_unpack> 0 "register_operand" "")
5289 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))]
5292 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5295 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5296 RTVEC_ELT (v, i) = GEN_INT (i);
5297 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5298 emit_insn (gen_neon_vec_unpack<US>_lo_<mode> (operands[0],
5305 (define_insn "neon_vec_<US>mult_lo_<mode>"
5306 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5307 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5308 (match_operand:VU 1 "register_operand" "w")
5309 (match_operand:VU 2 "vect_par_constant_low" "")))
5310 (SE:<V_unpack> (vec_select:<V_HALF>
5311 (match_operand:VU 3 "register_operand" "w")
5314 "vmull.<US><V_sz_elem> %q0, %e1, %e3"
5315 [(set_attr "neon_type" "neon_shift_1")]
5318 (define_expand "vec_widen_<US>mult_lo_<mode>"
5319 [(match_operand:<V_unpack> 0 "register_operand" "")
5320 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5321 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5324 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5327 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5328 RTVEC_ELT (v, i) = GEN_INT (i);
5329 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5331 emit_insn (gen_neon_vec_<US>mult_lo_<mode> (operands[0],
5339 (define_insn "neon_vec_<US>mult_hi_<mode>"
5340 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5341 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5342 (match_operand:VU 1 "register_operand" "w")
5343 (match_operand:VU 2 "vect_par_constant_high" "")))
5344 (SE:<V_unpack> (vec_select:<V_HALF>
5345 (match_operand:VU 3 "register_operand" "w")
5348 "vmull.<US><V_sz_elem> %q0, %f1, %f3"
5349 [(set_attr "neon_type" "neon_shift_1")]
5352 (define_expand "vec_widen_<US>mult_hi_<mode>"
5353 [(match_operand:<V_unpack> 0 "register_operand" "")
5354 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5355 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5358 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5361 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5362 RTVEC_ELT (v, i) = GEN_INT (<V_mode_nunits>/2 + i);
5363 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5365 emit_insn (gen_neon_vec_<US>mult_hi_<mode> (operands[0],
5374 ;; Vectorize for non-neon-quad case
5375 (define_insn "neon_unpack<US>_<mode>"
5376 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5377 (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
5379 "vmovl.<US><V_sz_elem> %q0, %P1"
5380 [(set_attr "neon_type" "neon_shift_1")]
5383 (define_expand "vec_unpack<US>_lo_<mode>"
5384 [(match_operand:<V_double_width> 0 "register_operand" "")
5385 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5388 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5389 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5390 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5396 (define_expand "vec_unpack<US>_hi_<mode>"
5397 [(match_operand:<V_double_width> 0 "register_operand" "")
5398 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5401 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5402 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5403 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5409 (define_insn "neon_vec_<US>mult_<mode>"
5410 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5411 (mult:<V_widen> (SE:<V_widen>
5412 (match_operand:VDI 1 "register_operand" "w"))
5414 (match_operand:VDI 2 "register_operand" "w"))))]
5416 "vmull.<US><V_sz_elem> %q0, %P1, %P2"
5417 [(set_attr "neon_type" "neon_shift_1")]
5420 (define_expand "vec_widen_<US>mult_hi_<mode>"
5421 [(match_operand:<V_double_width> 0 "register_operand" "")
5422 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5423 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5426 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5427 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5428 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5435 (define_expand "vec_widen_<US>mult_lo_<mode>"
5436 [(match_operand:<V_double_width> 0 "register_operand" "")
5437 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5438 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5441 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5442 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5443 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5450 (define_insn "vec_pack_trunc_<mode>"
5451 [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w")
5452 (vec_concat:<V_narrow_pack>
5453 (truncate:<V_narrow>
5454 (match_operand:VN 1 "register_operand" "w"))
5455 (truncate:<V_narrow>
5456 (match_operand:VN 2 "register_operand" "w"))))]
5458 "vmovn.i<V_sz_elem>\t%e0, %q1\n\tvmovn.i<V_sz_elem>\t%f0, %q2"
5459 [(set_attr "neon_type" "neon_shift_1")]
5462 ;; For the non-quad case.
5463 (define_insn "neon_vec_pack_trunc_<mode>"
5464 [(set (match_operand:<V_narrow> 0 "register_operand" "=w")
5465 (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))]
5467 "vmovn.i<V_sz_elem>\t%P0, %q1"
5468 [(set_attr "neon_type" "neon_shift_1")]
5471 (define_expand "vec_pack_trunc_<mode>"
5472 [(match_operand:<V_narrow_pack> 0 "register_operand" "")
5473 (match_operand:VSHFT 1 "register_operand" "")
5474 (match_operand:VSHFT 2 "register_operand")]
5477 rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode);
5479 emit_insn (gen_move_lo_quad_<V_double> (tempreg, operands[1]));
5480 emit_insn (gen_move_hi_quad_<V_double> (tempreg, operands[2]));
5481 emit_insn (gen_neon_vec_pack_trunc_<V_double> (operands[0], tempreg));