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")
587 (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0")
588 (match_operand:DI 2 "s_register_operand" "w,r,0")))
589 (clobber (reg:CC CC_REGNUM))]
592 switch (which_alternative)
594 case 0: return "vadd.i64\t%P0, %P1, %P2";
597 default: gcc_unreachable ();
600 [(set_attr "neon_type" "neon_int_1,*,*")
601 (set_attr "conds" "*,clob,clob")
602 (set_attr "length" "*,8,8")]
605 (define_insn "*sub<mode>3_neon"
606 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
607 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
608 (match_operand:VDQ 2 "s_register_operand" "w")))]
609 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
610 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
611 [(set (attr "neon_type")
612 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
613 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
614 (const_string "neon_fp_vadd_ddd_vabs_dd")
615 (const_string "neon_fp_vadd_qqq_vabs_qq"))
616 (const_string "neon_int_2")))]
619 (define_insn "subdi3_neon"
620 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
621 (minus:DI (match_operand:DI 1 "s_register_operand" "w,0,r,0")
622 (match_operand:DI 2 "s_register_operand" "w,r,0,0")))
623 (clobber (reg:CC CC_REGNUM))]
626 switch (which_alternative)
628 case 0: return "vsub.i64\t%P0, %P1, %P2";
629 case 1: /* fall through */
630 case 2: /* fall through */
631 case 3: return "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2";
632 default: gcc_unreachable ();
635 [(set_attr "neon_type" "neon_int_2,*,*,*")
636 (set_attr "conds" "*,clob,clob,clob")
637 (set_attr "length" "*,8,8,8")]
640 (define_insn "*mul<mode>3_neon"
641 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
642 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
643 (match_operand:VDQ 2 "s_register_operand" "w")))]
644 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
645 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
646 [(set (attr "neon_type")
647 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
648 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
649 (const_string "neon_fp_vadd_ddd_vabs_dd")
650 (const_string "neon_fp_vadd_qqq_vabs_qq"))
651 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
653 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
654 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
655 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
656 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
657 (const_string "neon_mul_qqq_8_16_32_ddd_32")
658 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
661 (define_insn "mul<mode>3add<mode>_neon"
662 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
663 (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
664 (match_operand:VDQ 3 "s_register_operand" "w"))
665 (match_operand:VDQ 1 "s_register_operand" "0")))]
666 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
667 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
668 [(set (attr "neon_type")
669 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
670 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
671 (const_string "neon_fp_vmla_ddd")
672 (const_string "neon_fp_vmla_qqq"))
673 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
675 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
676 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
677 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
678 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
679 (const_string "neon_mla_qqq_8_16")
680 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
683 (define_insn "mul<mode>3neg<mode>add<mode>_neon"
684 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
685 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
686 (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
687 (match_operand:VDQ 3 "s_register_operand" "w"))))]
688 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
689 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
690 [(set (attr "neon_type")
691 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
692 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
693 (const_string "neon_fp_vmla_ddd")
694 (const_string "neon_fp_vmla_qqq"))
695 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
697 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
698 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
699 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
700 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
701 (const_string "neon_mla_qqq_8_16")
702 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
705 (define_insn "ior<mode>3"
706 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
707 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
708 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
711 switch (which_alternative)
713 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
714 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
715 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
716 default: gcc_unreachable ();
719 [(set_attr "neon_type" "neon_int_1")]
722 (define_insn "iordi3_neon"
723 [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r")
724 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r")
725 (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r")))]
728 switch (which_alternative)
730 case 0: return "vorr\t%P0, %P1, %P2";
731 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
732 DImode, 0, VALID_NEON_QREG_MODE (DImode));
735 default: gcc_unreachable ();
738 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*")
739 (set_attr "length" "*,*,8,8")]
742 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
743 ;; vorr. We support the pseudo-instruction vand instead, because that
744 ;; corresponds to the canonical form the middle-end expects to use for
745 ;; immediate bitwise-ANDs.
747 (define_insn "and<mode>3"
748 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
749 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
750 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
753 switch (which_alternative)
755 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
756 case 1: return neon_output_logic_immediate ("vand", &operands[2],
757 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
758 default: gcc_unreachable ();
761 [(set_attr "neon_type" "neon_int_1")]
764 (define_insn "anddi3_neon"
765 [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r")
766 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r")
767 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL,r,r")))]
770 switch (which_alternative)
772 case 0: return "vand\t%P0, %P1, %P2";
773 case 1: return neon_output_logic_immediate ("vand", &operands[2],
774 DImode, 1, VALID_NEON_QREG_MODE (DImode));
777 default: gcc_unreachable ();
780 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*")
781 (set_attr "length" "*,*,8,8")]
784 (define_insn "orn<mode>3_neon"
785 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
786 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
787 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
789 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
790 [(set_attr "neon_type" "neon_int_1")]
793 (define_insn "orndi3_neon"
794 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
795 (ior:DI (match_operand:DI 1 "s_register_operand" "w,r,0")
796 (not:DI (match_operand:DI 2 "s_register_operand" "w,0,r"))))]
802 [(set_attr "neon_type" "neon_int_1,*,*")
803 (set_attr "length" "*,8,8")]
806 (define_insn "bic<mode>3_neon"
807 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
808 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
809 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
811 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
812 [(set_attr "neon_type" "neon_int_1")]
815 ;; Compare to *anddi_notdi_di.
816 (define_insn "bicdi3_neon"
817 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
818 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
819 (match_operand:DI 1 "s_register_operand" "w,0,r")))]
825 [(set_attr "neon_type" "neon_int_1,*,*")
826 (set_attr "length" "*,8,8")]
829 (define_insn "xor<mode>3"
830 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
831 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
832 (match_operand:VDQ 2 "s_register_operand" "w")))]
834 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
835 [(set_attr "neon_type" "neon_int_1")]
838 (define_insn "xordi3_neon"
839 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
840 (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r")
841 (match_operand:DI 2 "s_register_operand" "w,r,r")))]
847 [(set_attr "neon_type" "neon_int_1,*,*")
848 (set_attr "length" "*,8,8")]
851 (define_insn "one_cmpl<mode>2"
852 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
853 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
855 "vmvn\t%<V_reg>0, %<V_reg>1"
856 [(set_attr "neon_type" "neon_int_1")]
859 (define_insn "abs<mode>2"
860 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
861 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
863 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
864 [(set (attr "neon_type")
865 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
866 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
867 (const_string "neon_fp_vadd_ddd_vabs_dd")
868 (const_string "neon_fp_vadd_qqq_vabs_qq"))
869 (const_string "neon_int_3")))]
872 (define_insn "neg<mode>2"
873 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
874 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
876 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
877 [(set (attr "neon_type")
878 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
879 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
880 (const_string "neon_fp_vadd_ddd_vabs_dd")
881 (const_string "neon_fp_vadd_qqq_vabs_qq"))
882 (const_string "neon_int_3")))]
885 (define_insn "*umin<mode>3_neon"
886 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
887 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
888 (match_operand:VDQIW 2 "s_register_operand" "w")))]
890 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
891 [(set_attr "neon_type" "neon_int_5")]
894 (define_insn "*umax<mode>3_neon"
895 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
896 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
897 (match_operand:VDQIW 2 "s_register_operand" "w")))]
899 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
900 [(set_attr "neon_type" "neon_int_5")]
903 (define_insn "*smin<mode>3_neon"
904 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
905 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
906 (match_operand:VDQW 2 "s_register_operand" "w")))]
908 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
909 [(set (attr "neon_type")
910 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
911 (const_string "neon_fp_vadd_ddd_vabs_dd")
912 (const_string "neon_int_5")))]
915 (define_insn "*smax<mode>3_neon"
916 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
917 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
918 (match_operand:VDQW 2 "s_register_operand" "w")))]
920 "vmax.<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 ; TODO: V2DI shifts are current disabled because there are bugs in the
928 ; generic vectorizer code. It ends up creating a V2DI constructor with
931 (define_insn "vashl<mode>3"
932 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
933 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
934 (match_operand:VDQIW 2 "s_register_operand" "w")))]
936 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
937 [(set (attr "neon_type")
938 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
939 (const_string "neon_vshl_ddd")
940 (const_string "neon_shift_3")))]
943 ; Used for implementing logical shift-right, which is a left-shift by a negative
944 ; amount, with signed operands. This is essentially the same as ashl<mode>3
945 ; above, but using an unspec in case GCC tries anything tricky with negative
948 (define_insn "ashl<mode>3_signed"
949 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
950 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
951 (match_operand:VDQI 2 "s_register_operand" "w")]
952 UNSPEC_ASHIFT_SIGNED))]
954 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
955 [(set (attr "neon_type")
956 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
957 (const_string "neon_vshl_ddd")
958 (const_string "neon_shift_3")))]
961 ; Used for implementing logical shift-right, which is a left-shift by a negative
962 ; amount, with unsigned operands.
964 (define_insn "ashl<mode>3_unsigned"
965 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
966 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
967 (match_operand:VDQI 2 "s_register_operand" "w")]
968 UNSPEC_ASHIFT_UNSIGNED))]
970 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
971 [(set (attr "neon_type")
972 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
973 (const_string "neon_vshl_ddd")
974 (const_string "neon_shift_3")))]
977 (define_expand "vashr<mode>3"
978 [(set (match_operand:VDQIW 0 "s_register_operand" "")
979 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
980 (match_operand:VDQIW 2 "s_register_operand" "")))]
983 rtx neg = gen_reg_rtx (<MODE>mode);
985 emit_insn (gen_neg<mode>2 (neg, operands[2]));
986 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
991 (define_expand "vlshr<mode>3"
992 [(set (match_operand:VDQIW 0 "s_register_operand" "")
993 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
994 (match_operand:VDQIW 2 "s_register_operand" "")))]
997 rtx neg = gen_reg_rtx (<MODE>mode);
999 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1000 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1005 ;; Widening operations
1007 (define_insn "widen_ssum<mode>3"
1008 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1009 (plus:<V_widen> (sign_extend:<V_widen>
1010 (match_operand:VW 1 "s_register_operand" "%w"))
1011 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1013 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1014 [(set_attr "neon_type" "neon_int_3")]
1017 (define_insn "widen_usum<mode>3"
1018 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1019 (plus:<V_widen> (zero_extend:<V_widen>
1020 (match_operand:VW 1 "s_register_operand" "%w"))
1021 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1023 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1024 [(set_attr "neon_type" "neon_int_3")]
1027 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1028 ;; shift-count granularity. That's good enough for the middle-end's current
1031 (define_expand "vec_shr_<mode>"
1032 [(match_operand:VDQ 0 "s_register_operand" "")
1033 (match_operand:VDQ 1 "s_register_operand" "")
1034 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1038 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1039 const int width = GET_MODE_BITSIZE (<MODE>mode);
1040 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1041 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1042 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1044 if (num_bits == width)
1046 emit_move_insn (operands[0], operands[1]);
1050 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1051 operands[0] = gen_lowpart (bvecmode, operands[0]);
1052 operands[1] = gen_lowpart (bvecmode, operands[1]);
1054 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1055 GEN_INT (num_bits / BITS_PER_UNIT)));
1059 (define_expand "vec_shl_<mode>"
1060 [(match_operand:VDQ 0 "s_register_operand" "")
1061 (match_operand:VDQ 1 "s_register_operand" "")
1062 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1066 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1067 const int width = GET_MODE_BITSIZE (<MODE>mode);
1068 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1069 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1070 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1074 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1078 num_bits = width - num_bits;
1080 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1081 operands[0] = gen_lowpart (bvecmode, operands[0]);
1082 operands[1] = gen_lowpart (bvecmode, operands[1]);
1084 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1085 GEN_INT (num_bits / BITS_PER_UNIT)));
1089 ;; Helpers for quad-word reduction operations
1091 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1092 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1093 ; N/2-element vector.
1095 (define_insn "quad_halves_<code>v4si"
1096 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1098 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1099 (parallel [(const_int 0) (const_int 1)]))
1100 (vec_select:V2SI (match_dup 1)
1101 (parallel [(const_int 2) (const_int 3)]))))]
1103 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1104 [(set_attr "vqh_mnem" "<VQH_mnem>")
1105 (set (attr "neon_type")
1106 (if_then_else (eq_attr "vqh_mnem" "vadd")
1107 (const_string "neon_int_1") (const_string "neon_int_5")))]
1110 (define_insn "quad_halves_<code>v4sf"
1111 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1113 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1114 (parallel [(const_int 0) (const_int 1)]))
1115 (vec_select:V2SF (match_dup 1)
1116 (parallel [(const_int 2) (const_int 3)]))))]
1117 "TARGET_NEON && flag_unsafe_math_optimizations"
1118 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1119 [(set_attr "vqh_mnem" "<VQH_mnem>")
1120 (set (attr "neon_type")
1121 (if_then_else (eq_attr "vqh_mnem" "vadd")
1122 (const_string "neon_int_1") (const_string "neon_int_5")))]
1125 (define_insn "quad_halves_<code>v8hi"
1126 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1128 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1129 (parallel [(const_int 0) (const_int 1)
1130 (const_int 2) (const_int 3)]))
1131 (vec_select:V4HI (match_dup 1)
1132 (parallel [(const_int 4) (const_int 5)
1133 (const_int 6) (const_int 7)]))))]
1135 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1136 [(set_attr "vqh_mnem" "<VQH_mnem>")
1137 (set (attr "neon_type")
1138 (if_then_else (eq_attr "vqh_mnem" "vadd")
1139 (const_string "neon_int_1") (const_string "neon_int_5")))]
1142 (define_insn "quad_halves_<code>v16qi"
1143 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1145 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1146 (parallel [(const_int 0) (const_int 1)
1147 (const_int 2) (const_int 3)
1148 (const_int 4) (const_int 5)
1149 (const_int 6) (const_int 7)]))
1150 (vec_select:V8QI (match_dup 1)
1151 (parallel [(const_int 8) (const_int 9)
1152 (const_int 10) (const_int 11)
1153 (const_int 12) (const_int 13)
1154 (const_int 14) (const_int 15)]))))]
1156 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1157 [(set_attr "vqh_mnem" "<VQH_mnem>")
1158 (set (attr "neon_type")
1159 (if_then_else (eq_attr "vqh_mnem" "vadd")
1160 (const_string "neon_int_1") (const_string "neon_int_5")))]
1163 ; FIXME: We wouldn't need the following insns if we could write subregs of
1164 ; vector registers. Make an attempt at removing unnecessary moves, though
1165 ; we're really at the mercy of the register allocator.
1167 (define_insn "neon_move_lo_quad_<mode>"
1168 [(set (match_operand:ANY128 0 "s_register_operand" "+w")
1170 (match_operand:<V_HALF> 1 "s_register_operand" "w")
1171 (vec_select:<V_HALF>
1173 (match_operand:ANY128 2 "vect_par_constant_high" ""))))]
1176 int dest = REGNO (operands[0]);
1177 int src = REGNO (operands[1]);
1180 return "vmov\t%e0, %P1";
1184 [(set_attr "neon_type" "neon_bp_simple")]
1187 (define_insn "neon_move_hi_quad_<mode>"
1188 [(set (match_operand:ANY128 0 "s_register_operand" "+w")
1190 (vec_select:<V_HALF>
1192 (match_operand:ANY128 2 "vect_par_constant_low" ""))
1193 (match_operand:<V_HALF> 1 "s_register_operand" "w")))]
1197 int dest = REGNO (operands[0]);
1198 int src = REGNO (operands[1]);
1201 return "vmov\t%f0, %P1";
1205 [(set_attr "neon_type" "neon_bp_simple")]
1208 (define_expand "move_hi_quad_<mode>"
1209 [(match_operand:ANY128 0 "s_register_operand" "")
1210 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1213 rtvec v = rtvec_alloc (<V_mode_nunits>/2);
1217 for (i=0; i < (<V_mode_nunits>/2); i++)
1218 RTVEC_ELT (v, i) = GEN_INT (i);
1220 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
1221 emit_insn (gen_neon_move_hi_quad_<mode> (operands[0], operands[1], t1));
1226 (define_expand "move_lo_quad_<mode>"
1227 [(match_operand:ANY128 0 "s_register_operand" "")
1228 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1231 rtvec v = rtvec_alloc (<V_mode_nunits>/2);
1235 for (i=0; i < (<V_mode_nunits>/2); i++)
1236 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
1238 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
1239 emit_insn (gen_neon_move_lo_quad_<mode> (operands[0], operands[1], t1));
1244 ;; Reduction operations
1246 (define_expand "reduc_splus_<mode>"
1247 [(match_operand:VD 0 "s_register_operand" "")
1248 (match_operand:VD 1 "s_register_operand" "")]
1249 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1251 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1252 &gen_neon_vpadd_internal<mode>);
1256 (define_expand "reduc_splus_<mode>"
1257 [(match_operand:VQ 0 "s_register_operand" "")
1258 (match_operand:VQ 1 "s_register_operand" "")]
1259 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1261 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1262 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1264 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1265 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1266 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1271 (define_insn "reduc_splus_v2di"
1272 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1273 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1276 "vadd.i64\t%e0, %e1, %f1"
1277 [(set_attr "neon_type" "neon_int_1")]
1280 ;; NEON does not distinguish between signed and unsigned addition except on
1281 ;; widening operations.
1282 (define_expand "reduc_uplus_<mode>"
1283 [(match_operand:VDQI 0 "s_register_operand" "")
1284 (match_operand:VDQI 1 "s_register_operand" "")]
1287 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1291 (define_expand "reduc_smin_<mode>"
1292 [(match_operand:VD 0 "s_register_operand" "")
1293 (match_operand:VD 1 "s_register_operand" "")]
1294 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1296 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1297 &gen_neon_vpsmin<mode>);
1301 (define_expand "reduc_smin_<mode>"
1302 [(match_operand:VQ 0 "s_register_operand" "")
1303 (match_operand:VQ 1 "s_register_operand" "")]
1304 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1306 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1307 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1309 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1310 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1311 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1316 (define_expand "reduc_smax_<mode>"
1317 [(match_operand:VD 0 "s_register_operand" "")
1318 (match_operand:VD 1 "s_register_operand" "")]
1319 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1321 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1322 &gen_neon_vpsmax<mode>);
1326 (define_expand "reduc_smax_<mode>"
1327 [(match_operand:VQ 0 "s_register_operand" "")
1328 (match_operand:VQ 1 "s_register_operand" "")]
1329 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1331 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1332 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1334 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1335 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1336 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1341 (define_expand "reduc_umin_<mode>"
1342 [(match_operand:VDI 0 "s_register_operand" "")
1343 (match_operand:VDI 1 "s_register_operand" "")]
1346 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1347 &gen_neon_vpumin<mode>);
1351 (define_expand "reduc_umin_<mode>"
1352 [(match_operand:VQI 0 "s_register_operand" "")
1353 (match_operand:VQI 1 "s_register_operand" "")]
1356 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1357 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1359 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1360 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1361 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1366 (define_expand "reduc_umax_<mode>"
1367 [(match_operand:VDI 0 "s_register_operand" "")
1368 (match_operand:VDI 1 "s_register_operand" "")]
1371 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1372 &gen_neon_vpumax<mode>);
1376 (define_expand "reduc_umax_<mode>"
1377 [(match_operand:VQI 0 "s_register_operand" "")
1378 (match_operand:VQI 1 "s_register_operand" "")]
1381 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1382 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1384 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1385 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1386 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1391 (define_insn "neon_vpadd_internal<mode>"
1392 [(set (match_operand:VD 0 "s_register_operand" "=w")
1393 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1394 (match_operand:VD 2 "s_register_operand" "w")]
1397 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1398 ;; Assume this schedules like vadd.
1399 [(set (attr "neon_type")
1400 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1401 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1402 (const_string "neon_fp_vadd_ddd_vabs_dd")
1403 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1404 (const_string "neon_int_1")))]
1407 (define_insn "neon_vpsmin<mode>"
1408 [(set (match_operand:VD 0 "s_register_operand" "=w")
1409 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1410 (match_operand:VD 2 "s_register_operand" "w")]
1413 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1414 ;; Assume this schedules like vmin.
1415 [(set (attr "neon_type")
1416 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1417 (const_string "neon_fp_vadd_ddd_vabs_dd")
1418 (const_string "neon_int_5")))]
1421 (define_insn "neon_vpsmax<mode>"
1422 [(set (match_operand:VD 0 "s_register_operand" "=w")
1423 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1424 (match_operand:VD 2 "s_register_operand" "w")]
1427 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1428 ;; Assume this schedules like vmax.
1429 [(set (attr "neon_type")
1430 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1431 (const_string "neon_fp_vadd_ddd_vabs_dd")
1432 (const_string "neon_int_5")))]
1435 (define_insn "neon_vpumin<mode>"
1436 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1437 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1438 (match_operand:VDI 2 "s_register_operand" "w")]
1441 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1442 ;; Assume this schedules like umin.
1443 [(set_attr "neon_type" "neon_int_5")]
1446 (define_insn "neon_vpumax<mode>"
1447 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1448 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1449 (match_operand:VDI 2 "s_register_operand" "w")]
1452 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1453 ;; Assume this schedules like umax.
1454 [(set_attr "neon_type" "neon_int_5")]
1457 ;; Saturating arithmetic
1459 ; NOTE: Neon supports many more saturating variants of instructions than the
1460 ; following, but these are all GCC currently understands.
1461 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1462 ; yet either, although these patterns may be used by intrinsics when they're
1465 (define_insn "*ss_add<mode>_neon"
1466 [(set (match_operand:VD 0 "s_register_operand" "=w")
1467 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1468 (match_operand:VD 2 "s_register_operand" "w")))]
1470 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1471 [(set_attr "neon_type" "neon_int_4")]
1474 (define_insn "*us_add<mode>_neon"
1475 [(set (match_operand:VD 0 "s_register_operand" "=w")
1476 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1477 (match_operand:VD 2 "s_register_operand" "w")))]
1479 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1480 [(set_attr "neon_type" "neon_int_4")]
1483 (define_insn "*ss_sub<mode>_neon"
1484 [(set (match_operand:VD 0 "s_register_operand" "=w")
1485 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1486 (match_operand:VD 2 "s_register_operand" "w")))]
1488 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1489 [(set_attr "neon_type" "neon_int_5")]
1492 (define_insn "*us_sub<mode>_neon"
1493 [(set (match_operand:VD 0 "s_register_operand" "=w")
1494 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1495 (match_operand:VD 2 "s_register_operand" "w")))]
1497 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1498 [(set_attr "neon_type" "neon_int_5")]
1501 ;; Conditional instructions. These are comparisons with conditional moves for
1502 ;; vectors. They perform the assignment:
1504 ;; Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2;
1506 ;; where op3 is <, <=, ==, !=, >= or >. Operations are performed
1509 (define_expand "vcond<mode>"
1510 [(set (match_operand:VDQW 0 "s_register_operand" "")
1512 (match_operator 3 "arm_comparison_operator"
1513 [(match_operand:VDQW 4 "s_register_operand" "")
1514 (match_operand:VDQW 5 "nonmemory_operand" "")])
1515 (match_operand:VDQW 1 "s_register_operand" "")
1516 (match_operand:VDQW 2 "s_register_operand" "")))]
1517 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1520 int inverse = 0, immediate_zero = 0;
1521 /* See the description of "magic" bits in the 'T' case of
1522 arm_print_operand. */
1523 HOST_WIDE_INT magic_word = (<MODE>mode == V2SFmode || <MODE>mode == V4SFmode)
1525 rtx magic_rtx = GEN_INT (magic_word);
1527 mask = gen_reg_rtx (<V_cmp_result>mode);
1529 if (operands[5] == CONST0_RTX (<MODE>mode))
1531 else if (!REG_P (operands[5]))
1532 operands[5] = force_reg (<MODE>mode, operands[5]);
1534 switch (GET_CODE (operands[3]))
1537 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1542 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1547 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1553 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1556 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1562 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1565 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1570 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1580 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1583 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1589 (define_expand "vcondu<mode>"
1590 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1592 (match_operator 3 "arm_comparison_operator"
1593 [(match_operand:VDQIW 4 "s_register_operand" "")
1594 (match_operand:VDQIW 5 "s_register_operand" "")])
1595 (match_operand:VDQIW 1 "s_register_operand" "")
1596 (match_operand:VDQIW 2 "s_register_operand" "")))]
1600 int inverse = 0, immediate_zero = 0;
1602 mask = gen_reg_rtx (<V_cmp_result>mode);
1604 if (operands[5] == CONST0_RTX (<MODE>mode))
1606 else if (!REG_P (operands[5]))
1607 operands[5] = force_reg (<MODE>mode, operands[5]);
1609 switch (GET_CODE (operands[3]))
1612 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1617 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1622 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1628 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1631 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1637 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1640 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1645 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1655 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1658 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1664 ;; Patterns for builtins.
1666 ; good for plain vadd, vaddq.
1668 (define_expand "neon_vadd<mode>"
1669 [(match_operand:VDQX 0 "s_register_operand" "=w")
1670 (match_operand:VDQX 1 "s_register_operand" "w")
1671 (match_operand:VDQX 2 "s_register_operand" "w")
1672 (match_operand:SI 3 "immediate_operand" "i")]
1675 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1676 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
1678 emit_insn (gen_neon_vadd<mode>_unspec (operands[0], operands[1],
1683 ; Note that NEON operations don't support the full IEEE 754 standard: in
1684 ; particular, denormal values are flushed to zero. This means that GCC cannot
1685 ; use those instructions for autovectorization, etc. unless
1686 ; -funsafe-math-optimizations is in effect (in which case flush-to-zero
1687 ; behaviour is permissible). Intrinsic operations (provided by the arm_neon.h
1688 ; header) must work in either case: if -funsafe-math-optimizations is given,
1689 ; intrinsics expand to "canonical" RTL where possible, otherwise intrinsics
1690 ; expand to unspecs (which may potentially limit the extent to which they might
1691 ; be optimized by generic code).
1693 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1695 (define_insn "neon_vadd<mode>_unspec"
1696 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1697 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1698 (match_operand:VDQX 2 "s_register_operand" "w")]
1701 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1702 [(set (attr "neon_type")
1703 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1704 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1705 (const_string "neon_fp_vadd_ddd_vabs_dd")
1706 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1707 (const_string "neon_int_1")))]
1710 ; operand 3 represents in bits:
1711 ; bit 0: signed (vs unsigned).
1712 ; bit 1: rounding (vs none).
1714 (define_insn "neon_vaddl<mode>"
1715 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1716 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1717 (match_operand:VDI 2 "s_register_operand" "w")
1718 (match_operand:SI 3 "immediate_operand" "i")]
1721 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1722 [(set_attr "neon_type" "neon_int_3")]
1725 (define_insn "neon_vaddw<mode>"
1726 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1727 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1728 (match_operand:VDI 2 "s_register_operand" "w")
1729 (match_operand:SI 3 "immediate_operand" "i")]
1732 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1733 [(set_attr "neon_type" "neon_int_2")]
1738 (define_insn "neon_vhadd<mode>"
1739 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1740 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1741 (match_operand:VDQIW 2 "s_register_operand" "w")
1742 (match_operand:SI 3 "immediate_operand" "i")]
1745 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1746 [(set_attr "neon_type" "neon_int_4")]
1749 (define_insn "neon_vqadd<mode>"
1750 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1751 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1752 (match_operand:VDQIX 2 "s_register_operand" "w")
1753 (match_operand:SI 3 "immediate_operand" "i")]
1756 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1757 [(set_attr "neon_type" "neon_int_4")]
1760 (define_insn "neon_vaddhn<mode>"
1761 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1762 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1763 (match_operand:VN 2 "s_register_operand" "w")
1764 (match_operand:SI 3 "immediate_operand" "i")]
1767 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
1768 [(set_attr "neon_type" "neon_int_4")]
1771 ;; We cannot replace this unspec with mul<mode>3 because of the odd
1772 ;; polynomial multiplication case that can specified by operand 3.
1773 (define_insn "neon_vmul<mode>"
1774 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1775 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1776 (match_operand:VDQW 2 "s_register_operand" "w")
1777 (match_operand:SI 3 "immediate_operand" "i")]
1780 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1781 [(set (attr "neon_type")
1782 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1783 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1784 (const_string "neon_fp_vadd_ddd_vabs_dd")
1785 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1786 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1788 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1789 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1790 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1791 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1792 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1793 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
1796 (define_expand "neon_vmla<mode>"
1797 [(match_operand:VDQW 0 "s_register_operand" "=w")
1798 (match_operand:VDQW 1 "s_register_operand" "0")
1799 (match_operand:VDQW 2 "s_register_operand" "w")
1800 (match_operand:VDQW 3 "s_register_operand" "w")
1801 (match_operand:SI 4 "immediate_operand" "i")]
1804 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1805 emit_insn (gen_mul<mode>3add<mode>_neon (operands[0], operands[1],
1806 operands[2], operands[3]));
1808 emit_insn (gen_neon_vmla<mode>_unspec (operands[0], operands[1],
1809 operands[2], operands[3]));
1813 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1815 (define_insn "neon_vmla<mode>_unspec"
1816 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1817 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
1818 (match_operand:VDQ 2 "s_register_operand" "w")
1819 (match_operand:VDQ 3 "s_register_operand" "w")]
1822 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1823 [(set (attr "neon_type")
1824 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1825 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1826 (const_string "neon_fp_vmla_ddd")
1827 (const_string "neon_fp_vmla_qqq"))
1828 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1830 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1831 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1832 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1833 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1834 (const_string "neon_mla_qqq_8_16")
1835 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1838 (define_insn "neon_vmlal<mode>"
1839 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1840 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1841 (match_operand:VW 2 "s_register_operand" "w")
1842 (match_operand:VW 3 "s_register_operand" "w")
1843 (match_operand:SI 4 "immediate_operand" "i")]
1846 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1847 [(set (attr "neon_type")
1848 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1849 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1850 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1853 (define_expand "neon_vmls<mode>"
1854 [(match_operand:VDQW 0 "s_register_operand" "=w")
1855 (match_operand:VDQW 1 "s_register_operand" "0")
1856 (match_operand:VDQW 2 "s_register_operand" "w")
1857 (match_operand:VDQW 3 "s_register_operand" "w")
1858 (match_operand:SI 4 "immediate_operand" "i")]
1861 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1862 emit_insn (gen_mul<mode>3neg<mode>add<mode>_neon (operands[0],
1863 operands[1], operands[2], operands[3]));
1865 emit_insn (gen_neon_vmls<mode>_unspec (operands[0], operands[1],
1866 operands[2], operands[3]));
1870 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1872 (define_insn "neon_vmls<mode>_unspec"
1873 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1874 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
1875 (match_operand:VDQ 2 "s_register_operand" "w")
1876 (match_operand:VDQ 3 "s_register_operand" "w")]
1879 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1880 [(set (attr "neon_type")
1881 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1882 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1883 (const_string "neon_fp_vmla_ddd")
1884 (const_string "neon_fp_vmla_qqq"))
1885 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1887 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1888 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1889 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1891 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1892 (const_string "neon_mla_qqq_8_16")
1893 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1896 (define_insn "neon_vmlsl<mode>"
1897 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1898 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1899 (match_operand:VW 2 "s_register_operand" "w")
1900 (match_operand:VW 3 "s_register_operand" "w")
1901 (match_operand:SI 4 "immediate_operand" "i")]
1904 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1905 [(set (attr "neon_type")
1906 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1907 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1908 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1911 (define_insn "neon_vqdmulh<mode>"
1912 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1913 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1914 (match_operand:VMDQI 2 "s_register_operand" "w")
1915 (match_operand:SI 3 "immediate_operand" "i")]
1918 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1919 [(set (attr "neon_type")
1920 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1921 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1922 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1923 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1924 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1925 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1926 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
1929 (define_insn "neon_vqdmlal<mode>"
1930 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1931 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1932 (match_operand:VMDI 2 "s_register_operand" "w")
1933 (match_operand:VMDI 3 "s_register_operand" "w")
1934 (match_operand:SI 4 "immediate_operand" "i")]
1937 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
1938 [(set (attr "neon_type")
1939 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1940 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1941 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1944 (define_insn "neon_vqdmlsl<mode>"
1945 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1946 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1947 (match_operand:VMDI 2 "s_register_operand" "w")
1948 (match_operand:VMDI 3 "s_register_operand" "w")
1949 (match_operand:SI 4 "immediate_operand" "i")]
1952 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
1953 [(set (attr "neon_type")
1954 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1955 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1956 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1959 (define_insn "neon_vmull<mode>"
1960 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1961 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1962 (match_operand:VW 2 "s_register_operand" "w")
1963 (match_operand:SI 3 "immediate_operand" "i")]
1966 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1967 [(set (attr "neon_type")
1968 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1969 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1970 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1973 (define_insn "neon_vqdmull<mode>"
1974 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1975 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
1976 (match_operand:VMDI 2 "s_register_operand" "w")
1977 (match_operand:SI 3 "immediate_operand" "i")]
1980 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
1981 [(set (attr "neon_type")
1982 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1983 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1984 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1987 (define_expand "neon_vsub<mode>"
1988 [(match_operand:VDQX 0 "s_register_operand" "=w")
1989 (match_operand:VDQX 1 "s_register_operand" "w")
1990 (match_operand:VDQX 2 "s_register_operand" "w")
1991 (match_operand:SI 3 "immediate_operand" "i")]
1994 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1995 emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
1997 emit_insn (gen_neon_vsub<mode>_unspec (operands[0], operands[1],
2002 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2004 (define_insn "neon_vsub<mode>_unspec"
2005 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2006 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2007 (match_operand:VDQX 2 "s_register_operand" "w")]
2010 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2011 [(set (attr "neon_type")
2012 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2013 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2014 (const_string "neon_fp_vadd_ddd_vabs_dd")
2015 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2016 (const_string "neon_int_2")))]
2019 (define_insn "neon_vsubl<mode>"
2020 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2021 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
2022 (match_operand:VDI 2 "s_register_operand" "w")
2023 (match_operand:SI 3 "immediate_operand" "i")]
2026 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2027 [(set_attr "neon_type" "neon_int_2")]
2030 (define_insn "neon_vsubw<mode>"
2031 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2032 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2033 (match_operand:VDI 2 "s_register_operand" "w")
2034 (match_operand:SI 3 "immediate_operand" "i")]
2037 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2038 [(set_attr "neon_type" "neon_int_2")]
2041 (define_insn "neon_vqsub<mode>"
2042 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2043 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2044 (match_operand:VDQIX 2 "s_register_operand" "w")
2045 (match_operand:SI 3 "immediate_operand" "i")]
2048 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2049 [(set_attr "neon_type" "neon_int_5")]
2052 (define_insn "neon_vhsub<mode>"
2053 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2054 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2055 (match_operand:VDQIW 2 "s_register_operand" "w")
2056 (match_operand:SI 3 "immediate_operand" "i")]
2059 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2060 [(set_attr "neon_type" "neon_int_5")]
2063 (define_insn "neon_vsubhn<mode>"
2064 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2065 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2066 (match_operand:VN 2 "s_register_operand" "w")
2067 (match_operand:SI 3 "immediate_operand" "i")]
2070 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2071 [(set_attr "neon_type" "neon_int_4")]
2074 (define_insn "neon_vceq<mode>"
2075 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2076 (unspec:<V_cmp_result>
2077 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2078 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2079 (match_operand:SI 3 "immediate_operand" "i,i")]
2083 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2084 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
2085 [(set (attr "neon_type")
2086 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2087 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2088 (const_string "neon_fp_vadd_ddd_vabs_dd")
2089 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2090 (const_string "neon_int_5")))]
2093 (define_insn "neon_vcge<mode>"
2094 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2095 (unspec:<V_cmp_result>
2096 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2097 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2098 (match_operand:SI 3 "immediate_operand" "i,i")]
2102 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2103 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2104 [(set (attr "neon_type")
2105 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2106 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2107 (const_string "neon_fp_vadd_ddd_vabs_dd")
2108 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2109 (const_string "neon_int_5")))]
2112 (define_insn "neon_vcgt<mode>"
2113 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2114 (unspec:<V_cmp_result>
2115 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2116 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2117 (match_operand:SI 3 "immediate_operand" "i,i")]
2121 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2122 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2123 [(set (attr "neon_type")
2124 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2125 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2126 (const_string "neon_fp_vadd_ddd_vabs_dd")
2127 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2128 (const_string "neon_int_5")))]
2131 ;; VCLE and VCLT only support comparisons with immediate zero (register
2132 ;; variants are VCGE and VCGT with operands reversed).
2134 (define_insn "neon_vcle<mode>"
2135 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2136 (unspec:<V_cmp_result>
2137 [(match_operand:VDQW 1 "s_register_operand" "w")
2138 (match_operand:VDQW 2 "nonmemory_operand" "Dz")
2139 (match_operand:SI 3 "immediate_operand" "i")]
2142 "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2143 [(set (attr "neon_type")
2144 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2145 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2146 (const_string "neon_fp_vadd_ddd_vabs_dd")
2147 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2148 (const_string "neon_int_5")))]
2151 (define_insn "neon_vclt<mode>"
2152 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2153 (unspec:<V_cmp_result>
2154 [(match_operand:VDQW 1 "s_register_operand" "w")
2155 (match_operand:VDQW 2 "nonmemory_operand" "Dz")
2156 (match_operand:SI 3 "immediate_operand" "i")]
2159 "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2160 [(set (attr "neon_type")
2161 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2162 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2163 (const_string "neon_fp_vadd_ddd_vabs_dd")
2164 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2165 (const_string "neon_int_5")))]
2168 (define_insn "neon_vcage<mode>"
2169 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2170 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2171 (match_operand:VCVTF 2 "s_register_operand" "w")
2172 (match_operand:SI 3 "immediate_operand" "i")]
2175 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2176 [(set (attr "neon_type")
2177 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2178 (const_string "neon_fp_vadd_ddd_vabs_dd")
2179 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2182 (define_insn "neon_vcagt<mode>"
2183 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2184 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2185 (match_operand:VCVTF 2 "s_register_operand" "w")
2186 (match_operand:SI 3 "immediate_operand" "i")]
2189 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2190 [(set (attr "neon_type")
2191 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2192 (const_string "neon_fp_vadd_ddd_vabs_dd")
2193 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2196 (define_insn "neon_vtst<mode>"
2197 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2198 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2199 (match_operand:VDQIW 2 "s_register_operand" "w")
2200 (match_operand:SI 3 "immediate_operand" "i")]
2203 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2204 [(set_attr "neon_type" "neon_int_4")]
2207 (define_insn "neon_vabd<mode>"
2208 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2209 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2210 (match_operand:VDQW 2 "s_register_operand" "w")
2211 (match_operand:SI 3 "immediate_operand" "i")]
2214 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2215 [(set (attr "neon_type")
2216 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2217 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2218 (const_string "neon_fp_vadd_ddd_vabs_dd")
2219 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2220 (const_string "neon_int_5")))]
2223 (define_insn "neon_vabdl<mode>"
2224 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2225 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2226 (match_operand:VW 2 "s_register_operand" "w")
2227 (match_operand:SI 3 "immediate_operand" "i")]
2230 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2231 [(set_attr "neon_type" "neon_int_5")]
2234 (define_insn "neon_vaba<mode>"
2235 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2236 (plus:VDQIW (match_operand:VDQIW 1 "s_register_operand" "0")
2237 (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w")
2238 (match_operand:VDQIW 3 "s_register_operand" "w")
2239 (match_operand:SI 4 "immediate_operand" "i")]
2242 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2243 [(set (attr "neon_type")
2244 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2245 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2248 (define_insn "neon_vabal<mode>"
2249 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2250 (plus:<V_widen> (match_operand:<V_widen> 1 "s_register_operand" "0")
2251 (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w")
2252 (match_operand:VW 3 "s_register_operand" "w")
2253 (match_operand:SI 4 "immediate_operand" "i")]
2256 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2257 [(set_attr "neon_type" "neon_vaba")]
2260 (define_insn "neon_vmax<mode>"
2261 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2262 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2263 (match_operand:VDQW 2 "s_register_operand" "w")
2264 (match_operand:SI 3 "immediate_operand" "i")]
2267 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2268 [(set (attr "neon_type")
2269 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2270 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2271 (const_string "neon_fp_vadd_ddd_vabs_dd")
2272 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2273 (const_string "neon_int_5")))]
2276 (define_insn "neon_vmin<mode>"
2277 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2278 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2279 (match_operand:VDQW 2 "s_register_operand" "w")
2280 (match_operand:SI 3 "immediate_operand" "i")]
2283 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2284 [(set (attr "neon_type")
2285 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2286 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2287 (const_string "neon_fp_vadd_ddd_vabs_dd")
2288 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2289 (const_string "neon_int_5")))]
2292 (define_expand "neon_vpadd<mode>"
2293 [(match_operand:VD 0 "s_register_operand" "=w")
2294 (match_operand:VD 1 "s_register_operand" "w")
2295 (match_operand:VD 2 "s_register_operand" "w")
2296 (match_operand:SI 3 "immediate_operand" "i")]
2299 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2304 (define_insn "neon_vpaddl<mode>"
2305 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2306 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2307 (match_operand:SI 2 "immediate_operand" "i")]
2310 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2311 ;; Assume this schedules like vaddl.
2312 [(set_attr "neon_type" "neon_int_3")]
2315 (define_insn "neon_vpadal<mode>"
2316 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2317 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2318 (match_operand:VDQIW 2 "s_register_operand" "w")
2319 (match_operand:SI 3 "immediate_operand" "i")]
2322 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2323 ;; Assume this schedules like vpadd.
2324 [(set_attr "neon_type" "neon_int_1")]
2327 (define_insn "neon_vpmax<mode>"
2328 [(set (match_operand:VD 0 "s_register_operand" "=w")
2329 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2330 (match_operand:VD 2 "s_register_operand" "w")
2331 (match_operand:SI 3 "immediate_operand" "i")]
2334 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2335 ;; Assume this schedules like vmax.
2336 [(set (attr "neon_type")
2337 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2338 (const_string "neon_fp_vadd_ddd_vabs_dd")
2339 (const_string "neon_int_5")))]
2342 (define_insn "neon_vpmin<mode>"
2343 [(set (match_operand:VD 0 "s_register_operand" "=w")
2344 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2345 (match_operand:VD 2 "s_register_operand" "w")
2346 (match_operand:SI 3 "immediate_operand" "i")]
2349 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2350 ;; Assume this schedules like vmin.
2351 [(set (attr "neon_type")
2352 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2353 (const_string "neon_fp_vadd_ddd_vabs_dd")
2354 (const_string "neon_int_5")))]
2357 (define_insn "neon_vrecps<mode>"
2358 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2359 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2360 (match_operand:VCVTF 2 "s_register_operand" "w")
2361 (match_operand:SI 3 "immediate_operand" "i")]
2364 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2365 [(set (attr "neon_type")
2366 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2367 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2368 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2371 (define_insn "neon_vrsqrts<mode>"
2372 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2373 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2374 (match_operand:VCVTF 2 "s_register_operand" "w")
2375 (match_operand:SI 3 "immediate_operand" "i")]
2378 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2379 [(set (attr "neon_type")
2380 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2381 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2382 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2385 (define_expand "neon_vabs<mode>"
2386 [(match_operand:VDQW 0 "s_register_operand" "")
2387 (match_operand:VDQW 1 "s_register_operand" "")
2388 (match_operand:SI 2 "immediate_operand" "")]
2391 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
2395 (define_insn "neon_vqabs<mode>"
2396 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2397 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2398 (match_operand:SI 2 "immediate_operand" "i")]
2401 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2402 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2405 (define_expand "neon_vneg<mode>"
2406 [(match_operand:VDQW 0 "s_register_operand" "")
2407 (match_operand:VDQW 1 "s_register_operand" "")
2408 (match_operand:SI 2 "immediate_operand" "")]
2411 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2415 (define_insn "neon_vqneg<mode>"
2416 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2417 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2418 (match_operand:SI 2 "immediate_operand" "i")]
2421 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2422 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2425 (define_insn "neon_vcls<mode>"
2426 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2427 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2428 (match_operand:SI 2 "immediate_operand" "i")]
2431 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2432 [(set_attr "neon_type" "neon_int_1")]
2435 (define_insn "clz<mode>2"
2436 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2437 (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
2439 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2440 [(set_attr "neon_type" "neon_int_1")]
2443 (define_expand "neon_vclz<mode>"
2444 [(match_operand:VDQIW 0 "s_register_operand" "")
2445 (match_operand:VDQIW 1 "s_register_operand" "")
2446 (match_operand:SI 2 "immediate_operand" "")]
2449 emit_insn (gen_clz<mode>2 (operands[0], operands[1]));
2453 (define_insn "popcount<mode>2"
2454 [(set (match_operand:VE 0 "s_register_operand" "=w")
2455 (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
2457 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2458 [(set_attr "neon_type" "neon_int_1")]
2461 (define_expand "neon_vcnt<mode>"
2462 [(match_operand:VE 0 "s_register_operand" "=w")
2463 (match_operand:VE 1 "s_register_operand" "w")
2464 (match_operand:SI 2 "immediate_operand" "i")]
2467 emit_insn (gen_popcount<mode>2 (operands[0], operands[1]));
2471 (define_insn "neon_vrecpe<mode>"
2472 [(set (match_operand:V32 0 "s_register_operand" "=w")
2473 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2474 (match_operand:SI 2 "immediate_operand" "i")]
2477 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2478 [(set (attr "neon_type")
2479 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2480 (const_string "neon_fp_vadd_ddd_vabs_dd")
2481 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2484 (define_insn "neon_vrsqrte<mode>"
2485 [(set (match_operand:V32 0 "s_register_operand" "=w")
2486 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2487 (match_operand:SI 2 "immediate_operand" "i")]
2490 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2491 [(set (attr "neon_type")
2492 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2493 (const_string "neon_fp_vadd_ddd_vabs_dd")
2494 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2497 (define_expand "neon_vmvn<mode>"
2498 [(match_operand:VDQIW 0 "s_register_operand" "")
2499 (match_operand:VDQIW 1 "s_register_operand" "")
2500 (match_operand:SI 2 "immediate_operand" "")]
2503 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2507 (define_insn "neon_vget_lane<mode>_sext_internal"
2508 [(set (match_operand:SI 0 "s_register_operand" "=r")
2510 (vec_select:<V_elem>
2511 (match_operand:VD 1 "s_register_operand" "w")
2512 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2515 if (BYTES_BIG_ENDIAN)
2517 int elt = INTVAL (operands[2]);
2518 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2519 operands[2] = GEN_INT (elt);
2521 return "vmov%?.s<V_sz_elem>\t%0, %P1[%c2]";
2523 [(set_attr "predicable" "yes")
2524 (set_attr "neon_type" "neon_bp_simple")]
2527 (define_insn "neon_vget_lane<mode>_zext_internal"
2528 [(set (match_operand:SI 0 "s_register_operand" "=r")
2530 (vec_select:<V_elem>
2531 (match_operand:VD 1 "s_register_operand" "w")
2532 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2535 if (BYTES_BIG_ENDIAN)
2537 int elt = INTVAL (operands[2]);
2538 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2539 operands[2] = GEN_INT (elt);
2541 return "vmov%?.u<V_sz_elem>\t%0, %P1[%c2]";
2543 [(set_attr "predicable" "yes")
2544 (set_attr "neon_type" "neon_bp_simple")]
2547 (define_insn "neon_vget_lane<mode>_sext_internal"
2548 [(set (match_operand:SI 0 "s_register_operand" "=r")
2550 (vec_select:<V_elem>
2551 (match_operand:VQ 1 "s_register_operand" "w")
2552 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2556 int regno = REGNO (operands[1]);
2557 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2558 unsigned int elt = INTVAL (operands[2]);
2559 unsigned int elt_adj = elt % halfelts;
2561 if (BYTES_BIG_ENDIAN)
2562 elt_adj = halfelts - 1 - elt_adj;
2564 ops[0] = operands[0];
2565 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2566 ops[2] = GEN_INT (elt_adj);
2567 output_asm_insn ("vmov%?.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2571 [(set_attr "predicable" "yes")
2572 (set_attr "neon_type" "neon_bp_simple")]
2575 (define_insn "neon_vget_lane<mode>_zext_internal"
2576 [(set (match_operand:SI 0 "s_register_operand" "=r")
2578 (vec_select:<V_elem>
2579 (match_operand:VQ 1 "s_register_operand" "w")
2580 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2584 int regno = REGNO (operands[1]);
2585 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2586 unsigned int elt = INTVAL (operands[2]);
2587 unsigned int elt_adj = elt % halfelts;
2589 if (BYTES_BIG_ENDIAN)
2590 elt_adj = halfelts - 1 - elt_adj;
2592 ops[0] = operands[0];
2593 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2594 ops[2] = GEN_INT (elt_adj);
2595 output_asm_insn ("vmov%?.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2599 [(set_attr "predicable" "yes")
2600 (set_attr "neon_type" "neon_bp_simple")]
2603 (define_expand "neon_vget_lane<mode>"
2604 [(match_operand:<V_ext> 0 "s_register_operand" "")
2605 (match_operand:VDQW 1 "s_register_operand" "")
2606 (match_operand:SI 2 "immediate_operand" "")
2607 (match_operand:SI 3 "immediate_operand" "")]
2610 HOST_WIDE_INT magic = INTVAL (operands[3]);
2613 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2615 if (BYTES_BIG_ENDIAN)
2617 /* The intrinsics are defined in terms of a model where the
2618 element ordering in memory is vldm order, whereas the generic
2619 RTL is defined in terms of a model where the element ordering
2620 in memory is array order. Convert the lane number to conform
2622 unsigned int elt = INTVAL (operands[2]);
2623 unsigned int reg_nelts
2624 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2625 elt ^= reg_nelts - 1;
2626 operands[2] = GEN_INT (elt);
2629 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2630 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2633 if ((magic & 1) != 0)
2634 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2637 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2644 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2647 (define_expand "neon_vget_lanedi"
2648 [(match_operand:DI 0 "s_register_operand" "=r")
2649 (match_operand:DI 1 "s_register_operand" "w")
2650 (match_operand:SI 2 "immediate_operand" "i")
2651 (match_operand:SI 3 "immediate_operand" "i")]
2654 neon_lane_bounds (operands[2], 0, 1);
2655 emit_move_insn (operands[0], operands[1]);
2659 (define_expand "neon_vget_lanev2di"
2660 [(match_operand:DI 0 "s_register_operand" "=r")
2661 (match_operand:V2DI 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, 2);
2667 emit_insn (gen_vec_extractv2di (operands[0], operands[1], operands[2]));
2671 (define_expand "neon_vset_lane<mode>"
2672 [(match_operand:VDQ 0 "s_register_operand" "=w")
2673 (match_operand:<V_elem> 1 "s_register_operand" "r")
2674 (match_operand:VDQ 2 "s_register_operand" "0")
2675 (match_operand:SI 3 "immediate_operand" "i")]
2678 unsigned int elt = INTVAL (operands[3]);
2679 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2681 if (BYTES_BIG_ENDIAN)
2683 unsigned int reg_nelts
2684 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2685 elt ^= reg_nelts - 1;
2688 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
2689 GEN_INT (1 << elt), operands[2]));
2693 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2695 (define_expand "neon_vset_lanedi"
2696 [(match_operand:DI 0 "s_register_operand" "=w")
2697 (match_operand:DI 1 "s_register_operand" "r")
2698 (match_operand:DI 2 "s_register_operand" "0")
2699 (match_operand:SI 3 "immediate_operand" "i")]
2702 neon_lane_bounds (operands[3], 0, 1);
2703 emit_move_insn (operands[0], operands[1]);
2707 (define_expand "neon_vcreate<mode>"
2708 [(match_operand:VDX 0 "s_register_operand" "")
2709 (match_operand:DI 1 "general_operand" "")]
2712 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2713 emit_move_insn (operands[0], src);
2717 (define_insn "neon_vdup_n<mode>"
2718 [(set (match_operand:VX 0 "s_register_operand" "=w")
2719 (vec_duplicate:VX (match_operand:<V_elem> 1 "s_register_operand" "r")))]
2721 "vdup%?.<V_sz_elem>\t%<V_reg>0, %1"
2722 ;; Assume this schedules like vmov.
2723 [(set_attr "predicable" "yes")
2724 (set_attr "neon_type" "neon_bp_simple")]
2727 (define_insn "neon_vdup_n<mode>"
2728 [(set (match_operand:V32 0 "s_register_operand" "=w,w")
2729 (vec_duplicate:V32 (match_operand:<V_elem> 1 "s_register_operand" "r,t")))]
2732 vdup%?.<V_sz_elem>\t%<V_reg>0, %1
2733 vdup%?.<V_sz_elem>\t%<V_reg>0, %y1"
2734 ;; Assume this schedules like vmov.
2735 [(set_attr "predicable" "yes")
2736 (set_attr "neon_type" "neon_bp_simple")]
2739 (define_expand "neon_vdup_ndi"
2740 [(match_operand:DI 0 "s_register_operand" "=w")
2741 (match_operand:DI 1 "s_register_operand" "r")]
2744 emit_move_insn (operands[0], operands[1]);
2749 (define_insn "neon_vdup_nv2di"
2750 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
2751 (vec_duplicate:V2DI (match_operand:DI 1 "s_register_operand" "r,w")))]
2754 vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1
2755 vmov%?\t%e0, %P1\;vmov%?\t%f0, %P1"
2756 [(set_attr "predicable" "yes")
2757 (set_attr "length" "8")
2758 (set_attr "neon_type" "neon_bp_simple")]
2761 (define_insn "neon_vdup_lane<mode>_internal"
2762 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2764 (vec_select:<V_elem>
2765 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
2766 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2769 if (BYTES_BIG_ENDIAN)
2771 int elt = INTVAL (operands[2]);
2772 elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
2773 operands[2] = GEN_INT (elt);
2776 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
2778 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
2780 ;; Assume this schedules like vmov.
2781 [(set_attr "neon_type" "neon_bp_simple")]
2784 (define_expand "neon_vdup_lane<mode>"
2785 [(match_operand:VDQW 0 "s_register_operand" "=w")
2786 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
2787 (match_operand:SI 2 "immediate_operand" "i")]
2790 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_double_vector_mode>mode));
2791 if (BYTES_BIG_ENDIAN)
2793 unsigned int elt = INTVAL (operands[2]);
2794 unsigned int reg_nelts
2795 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<V_double_vector_mode>mode));
2796 elt ^= reg_nelts - 1;
2797 operands[2] = GEN_INT (elt);
2799 emit_insn (gen_neon_vdup_lane<mode>_internal (operands[0], operands[1],
2804 ; Scalar index is ignored, since only zero is valid here.
2805 (define_expand "neon_vdup_lanedi"
2806 [(match_operand:DI 0 "s_register_operand" "=w")
2807 (match_operand:DI 1 "s_register_operand" "w")
2808 (match_operand:SI 2 "immediate_operand" "i")]
2811 neon_lane_bounds (operands[2], 0, 1);
2812 emit_move_insn (operands[0], operands[1]);
2816 ; Likewise for v2di, as the DImode second operand has only a single element.
2817 (define_expand "neon_vdup_lanev2di"
2818 [(match_operand:V2DI 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_insn (gen_neon_vdup_nv2di (operands[0], operands[1]));
2828 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2830 ;; FIXME: A different implementation of this builtin could make it much
2831 ;; more likely that we wouldn't actually need to output anything (we could make
2832 ;; it so that the reg allocator puts things in the right places magically
2833 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
2835 (define_insn "neon_vcombine<mode>"
2836 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
2837 (vec_concat:<V_DOUBLE> (match_operand:VDX 1 "s_register_operand" "w")
2838 (match_operand:VDX 2 "s_register_operand" "w")))]
2841 int dest = REGNO (operands[0]);
2842 int src1 = REGNO (operands[1]);
2843 int src2 = REGNO (operands[2]);
2846 if (src1 == dest && src2 == dest + 2)
2848 else if (src2 == dest && src1 == dest + 2)
2849 /* Special case of reversed high/low parts. */
2850 return "vswp\t%P1, %P2";
2852 destlo = gen_rtx_REG (<MODE>mode, dest);
2854 if (!reg_overlap_mentioned_p (operands[2], destlo))
2856 /* Try to avoid unnecessary moves if part of the result is in the right
2859 output_asm_insn ("vmov\t%e0, %P1", operands);
2860 if (src2 != dest + 2)
2861 output_asm_insn ("vmov\t%f0, %P2", operands);
2865 if (src2 != dest + 2)
2866 output_asm_insn ("vmov\t%f0, %P2", operands);
2868 output_asm_insn ("vmov\t%e0, %P1", operands);
2873 ;; We set the neon_type attribute based on the vmov instructions above.
2874 [(set_attr "length" "8")
2875 (set_attr "neon_type" "neon_bp_simple")]
2878 (define_insn "neon_vget_highv16qi"
2879 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2880 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
2881 (parallel [(const_int 8) (const_int 9)
2882 (const_int 10) (const_int 11)
2883 (const_int 12) (const_int 13)
2884 (const_int 14) (const_int 15)])))]
2887 int dest = REGNO (operands[0]);
2888 int src = REGNO (operands[1]);
2890 if (dest != src + 2)
2891 return "vmov\t%P0, %f1";
2895 [(set_attr "neon_type" "neon_bp_simple")]
2898 (define_insn "neon_vget_highv8hi"
2899 [(set (match_operand:V4HI 0 "s_register_operand" "=w")
2900 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
2901 (parallel [(const_int 4) (const_int 5)
2902 (const_int 6) (const_int 7)])))]
2905 int dest = REGNO (operands[0]);
2906 int src = REGNO (operands[1]);
2908 if (dest != src + 2)
2909 return "vmov\t%P0, %f1";
2913 [(set_attr "neon_type" "neon_bp_simple")]
2916 (define_insn "neon_vget_highv4si"
2917 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
2918 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
2919 (parallel [(const_int 2) (const_int 3)])))]
2922 int dest = REGNO (operands[0]);
2923 int src = REGNO (operands[1]);
2925 if (dest != src + 2)
2926 return "vmov\t%P0, %f1";
2930 [(set_attr "neon_type" "neon_bp_simple")]
2933 (define_insn "neon_vget_highv4sf"
2934 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
2935 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
2936 (parallel [(const_int 2) (const_int 3)])))]
2939 int dest = REGNO (operands[0]);
2940 int src = REGNO (operands[1]);
2942 if (dest != src + 2)
2943 return "vmov\t%P0, %f1";
2947 [(set_attr "neon_type" "neon_bp_simple")]
2950 (define_insn "neon_vget_highv2di"
2951 [(set (match_operand:DI 0 "s_register_operand" "=w")
2952 (vec_select:DI (match_operand:V2DI 1 "s_register_operand" "w")
2953 (parallel [(const_int 1)])))]
2956 int dest = REGNO (operands[0]);
2957 int src = REGNO (operands[1]);
2959 if (dest != src + 2)
2960 return "vmov\t%P0, %f1";
2964 [(set_attr "neon_type" "neon_bp_simple")]
2967 (define_insn "neon_vget_lowv16qi"
2968 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2969 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
2970 (parallel [(const_int 0) (const_int 1)
2971 (const_int 2) (const_int 3)
2972 (const_int 4) (const_int 5)
2973 (const_int 6) (const_int 7)])))]
2976 int dest = REGNO (operands[0]);
2977 int src = REGNO (operands[1]);
2980 return "vmov\t%P0, %e1";
2984 [(set_attr "neon_type" "neon_bp_simple")]
2987 (define_insn "neon_vget_lowv8hi"
2988 [(set (match_operand:V4HI 0 "s_register_operand" "=w")
2989 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
2990 (parallel [(const_int 0) (const_int 1)
2991 (const_int 2) (const_int 3)])))]
2994 int dest = REGNO (operands[0]);
2995 int src = REGNO (operands[1]);
2998 return "vmov\t%P0, %e1";
3002 [(set_attr "neon_type" "neon_bp_simple")]
3005 (define_insn "neon_vget_lowv4si"
3006 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
3007 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
3008 (parallel [(const_int 0) (const_int 1)])))]
3011 int dest = REGNO (operands[0]);
3012 int src = REGNO (operands[1]);
3015 return "vmov\t%P0, %e1";
3019 [(set_attr "neon_type" "neon_bp_simple")]
3022 (define_insn "neon_vget_lowv4sf"
3023 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
3024 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
3025 (parallel [(const_int 0) (const_int 1)])))]
3028 int dest = REGNO (operands[0]);
3029 int src = REGNO (operands[1]);
3032 return "vmov\t%P0, %e1";
3036 [(set_attr "neon_type" "neon_bp_simple")]
3039 (define_insn "neon_vget_lowv2di"
3040 [(set (match_operand:DI 0 "s_register_operand" "=w")
3041 (vec_select:DI (match_operand:V2DI 1 "s_register_operand" "w")
3042 (parallel [(const_int 0)])))]
3045 int dest = REGNO (operands[0]);
3046 int src = REGNO (operands[1]);
3049 return "vmov\t%P0, %e1";
3053 [(set_attr "neon_type" "neon_bp_simple")]
3056 (define_insn "neon_vcvt<mode>"
3057 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3058 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3059 (match_operand:SI 2 "immediate_operand" "i")]
3062 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
3063 [(set (attr "neon_type")
3064 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3065 (const_string "neon_fp_vadd_ddd_vabs_dd")
3066 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3069 (define_insn "neon_vcvt<mode>"
3070 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3071 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3072 (match_operand:SI 2 "immediate_operand" "i")]
3075 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
3076 [(set (attr "neon_type")
3077 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3078 (const_string "neon_fp_vadd_ddd_vabs_dd")
3079 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3082 (define_insn "neon_vcvt_n<mode>"
3083 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3084 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3085 (match_operand:SI 2 "immediate_operand" "i")
3086 (match_operand:SI 3 "immediate_operand" "i")]
3090 neon_const_bounds (operands[2], 1, 33);
3091 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
3093 [(set (attr "neon_type")
3094 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3095 (const_string "neon_fp_vadd_ddd_vabs_dd")
3096 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3099 (define_insn "neon_vcvt_n<mode>"
3100 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3101 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3102 (match_operand:SI 2 "immediate_operand" "i")
3103 (match_operand:SI 3 "immediate_operand" "i")]
3107 neon_const_bounds (operands[2], 1, 33);
3108 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
3110 [(set (attr "neon_type")
3111 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3112 (const_string "neon_fp_vadd_ddd_vabs_dd")
3113 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3116 (define_insn "neon_vmovn<mode>"
3117 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3118 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3119 (match_operand:SI 2 "immediate_operand" "i")]
3122 "vmovn.<V_if_elem>\t%P0, %q1"
3123 [(set_attr "neon_type" "neon_bp_simple")]
3126 (define_insn "neon_vqmovn<mode>"
3127 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3128 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3129 (match_operand:SI 2 "immediate_operand" "i")]
3132 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
3133 [(set_attr "neon_type" "neon_shift_2")]
3136 (define_insn "neon_vqmovun<mode>"
3137 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3138 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3139 (match_operand:SI 2 "immediate_operand" "i")]
3142 "vqmovun.<V_s_elem>\t%P0, %q1"
3143 [(set_attr "neon_type" "neon_shift_2")]
3146 (define_insn "neon_vmovl<mode>"
3147 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3148 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3149 (match_operand:SI 2 "immediate_operand" "i")]
3152 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
3153 [(set_attr "neon_type" "neon_shift_1")]
3156 (define_insn "neon_vmul_lane<mode>"
3157 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3158 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
3159 (match_operand:VMD 2 "s_register_operand"
3160 "<scalar_mul_constraint>")
3161 (match_operand:SI 3 "immediate_operand" "i")
3162 (match_operand:SI 4 "immediate_operand" "i")]
3166 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3167 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
3169 [(set (attr "neon_type")
3170 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3171 (const_string "neon_fp_vmul_ddd")
3172 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3173 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3174 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
3177 (define_insn "neon_vmul_lane<mode>"
3178 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3179 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
3180 (match_operand:<V_HALF> 2 "s_register_operand"
3181 "<scalar_mul_constraint>")
3182 (match_operand:SI 3 "immediate_operand" "i")
3183 (match_operand:SI 4 "immediate_operand" "i")]
3187 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3188 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3190 [(set (attr "neon_type")
3191 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3192 (const_string "neon_fp_vmul_qqd")
3193 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3194 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3195 (const_string "neon_mul_qqd_32_scalar"))))]
3198 (define_insn "neon_vmull_lane<mode>"
3199 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3200 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3201 (match_operand:VMDI 2 "s_register_operand"
3202 "<scalar_mul_constraint>")
3203 (match_operand:SI 3 "immediate_operand" "i")
3204 (match_operand:SI 4 "immediate_operand" "i")]
3205 UNSPEC_VMULL_LANE))]
3208 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3209 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3211 [(set (attr "neon_type")
3212 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3213 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3214 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3217 (define_insn "neon_vqdmull_lane<mode>"
3218 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3219 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3220 (match_operand:VMDI 2 "s_register_operand"
3221 "<scalar_mul_constraint>")
3222 (match_operand:SI 3 "immediate_operand" "i")
3223 (match_operand:SI 4 "immediate_operand" "i")]
3224 UNSPEC_VQDMULL_LANE))]
3227 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3228 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3230 [(set (attr "neon_type")
3231 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3232 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3233 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3236 (define_insn "neon_vqdmulh_lane<mode>"
3237 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3238 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3239 (match_operand:<V_HALF> 2 "s_register_operand"
3240 "<scalar_mul_constraint>")
3241 (match_operand:SI 3 "immediate_operand" "i")
3242 (match_operand:SI 4 "immediate_operand" "i")]
3243 UNSPEC_VQDMULH_LANE))]
3246 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3247 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3249 [(set (attr "neon_type")
3250 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3251 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3252 (const_string "neon_mul_qqd_32_scalar")))]
3255 (define_insn "neon_vqdmulh_lane<mode>"
3256 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3257 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3258 (match_operand:VMDI 2 "s_register_operand"
3259 "<scalar_mul_constraint>")
3260 (match_operand:SI 3 "immediate_operand" "i")
3261 (match_operand:SI 4 "immediate_operand" "i")]
3262 UNSPEC_VQDMULH_LANE))]
3265 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3266 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3268 [(set (attr "neon_type")
3269 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3270 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3271 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3274 (define_insn "neon_vmla_lane<mode>"
3275 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3276 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3277 (match_operand:VMD 2 "s_register_operand" "w")
3278 (match_operand:VMD 3 "s_register_operand"
3279 "<scalar_mul_constraint>")
3280 (match_operand:SI 4 "immediate_operand" "i")
3281 (match_operand:SI 5 "immediate_operand" "i")]
3285 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3286 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3288 [(set (attr "neon_type")
3289 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3290 (const_string "neon_fp_vmla_ddd_scalar")
3291 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3292 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3293 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3296 (define_insn "neon_vmla_lane<mode>"
3297 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3298 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3299 (match_operand:VMQ 2 "s_register_operand" "w")
3300 (match_operand:<V_HALF> 3 "s_register_operand"
3301 "<scalar_mul_constraint>")
3302 (match_operand:SI 4 "immediate_operand" "i")
3303 (match_operand:SI 5 "immediate_operand" "i")]
3307 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3308 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3310 [(set (attr "neon_type")
3311 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3312 (const_string "neon_fp_vmla_qqq_scalar")
3313 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3314 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3315 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3318 (define_insn "neon_vmlal_lane<mode>"
3319 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3320 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3321 (match_operand:VMDI 2 "s_register_operand" "w")
3322 (match_operand:VMDI 3 "s_register_operand"
3323 "<scalar_mul_constraint>")
3324 (match_operand:SI 4 "immediate_operand" "i")
3325 (match_operand:SI 5 "immediate_operand" "i")]
3326 UNSPEC_VMLAL_LANE))]
3329 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3330 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3332 [(set (attr "neon_type")
3333 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3334 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3335 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3338 (define_insn "neon_vqdmlal_lane<mode>"
3339 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3340 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3341 (match_operand:VMDI 2 "s_register_operand" "w")
3342 (match_operand:VMDI 3 "s_register_operand"
3343 "<scalar_mul_constraint>")
3344 (match_operand:SI 4 "immediate_operand" "i")
3345 (match_operand:SI 5 "immediate_operand" "i")]
3346 UNSPEC_VQDMLAL_LANE))]
3349 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3350 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3352 [(set (attr "neon_type")
3353 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3354 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3355 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3358 (define_insn "neon_vmls_lane<mode>"
3359 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3360 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3361 (match_operand:VMD 2 "s_register_operand" "w")
3362 (match_operand:VMD 3 "s_register_operand"
3363 "<scalar_mul_constraint>")
3364 (match_operand:SI 4 "immediate_operand" "i")
3365 (match_operand:SI 5 "immediate_operand" "i")]
3369 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3370 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3372 [(set (attr "neon_type")
3373 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3374 (const_string "neon_fp_vmla_ddd_scalar")
3375 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3376 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3377 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3380 (define_insn "neon_vmls_lane<mode>"
3381 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3382 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3383 (match_operand:VMQ 2 "s_register_operand" "w")
3384 (match_operand:<V_HALF> 3 "s_register_operand"
3385 "<scalar_mul_constraint>")
3386 (match_operand:SI 4 "immediate_operand" "i")
3387 (match_operand:SI 5 "immediate_operand" "i")]
3391 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3392 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3394 [(set (attr "neon_type")
3395 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3396 (const_string "neon_fp_vmla_qqq_scalar")
3397 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3398 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3399 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3402 (define_insn "neon_vmlsl_lane<mode>"
3403 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3404 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3405 (match_operand:VMDI 2 "s_register_operand" "w")
3406 (match_operand:VMDI 3 "s_register_operand"
3407 "<scalar_mul_constraint>")
3408 (match_operand:SI 4 "immediate_operand" "i")
3409 (match_operand:SI 5 "immediate_operand" "i")]
3410 UNSPEC_VMLSL_LANE))]
3413 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3414 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3416 [(set (attr "neon_type")
3417 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3418 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3419 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3422 (define_insn "neon_vqdmlsl_lane<mode>"
3423 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3424 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3425 (match_operand:VMDI 2 "s_register_operand" "w")
3426 (match_operand:VMDI 3 "s_register_operand"
3427 "<scalar_mul_constraint>")
3428 (match_operand:SI 4 "immediate_operand" "i")
3429 (match_operand:SI 5 "immediate_operand" "i")]
3430 UNSPEC_VQDMLSL_LANE))]
3433 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3434 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3436 [(set (attr "neon_type")
3437 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3438 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3439 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3442 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3443 ; core register into a temp register, then use a scalar taken from that. This
3444 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3445 ; or extracted from another vector. The latter case it's currently better to
3446 ; use the "_lane" variant, and the former case can probably be implemented
3447 ; using vld1_lane, but that hasn't been done yet.
3449 (define_expand "neon_vmul_n<mode>"
3450 [(match_operand:VMD 0 "s_register_operand" "")
3451 (match_operand:VMD 1 "s_register_operand" "")
3452 (match_operand:<V_elem> 2 "s_register_operand" "")
3453 (match_operand:SI 3 "immediate_operand" "")]
3456 rtx tmp = gen_reg_rtx (<MODE>mode);
3457 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3458 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3459 const0_rtx, const0_rtx));
3463 (define_expand "neon_vmul_n<mode>"
3464 [(match_operand:VMQ 0 "s_register_operand" "")
3465 (match_operand:VMQ 1 "s_register_operand" "")
3466 (match_operand:<V_elem> 2 "s_register_operand" "")
3467 (match_operand:SI 3 "immediate_operand" "")]
3470 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3471 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3472 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3473 const0_rtx, const0_rtx));
3477 (define_expand "neon_vmull_n<mode>"
3478 [(match_operand:<V_widen> 0 "s_register_operand" "")
3479 (match_operand:VMDI 1 "s_register_operand" "")
3480 (match_operand:<V_elem> 2 "s_register_operand" "")
3481 (match_operand:SI 3 "immediate_operand" "")]
3484 rtx tmp = gen_reg_rtx (<MODE>mode);
3485 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3486 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3487 const0_rtx, operands[3]));
3491 (define_expand "neon_vqdmull_n<mode>"
3492 [(match_operand:<V_widen> 0 "s_register_operand" "")
3493 (match_operand:VMDI 1 "s_register_operand" "")
3494 (match_operand:<V_elem> 2 "s_register_operand" "")
3495 (match_operand:SI 3 "immediate_operand" "")]
3498 rtx tmp = gen_reg_rtx (<MODE>mode);
3499 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3500 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3501 const0_rtx, const0_rtx));
3505 (define_expand "neon_vqdmulh_n<mode>"
3506 [(match_operand:VMDI 0 "s_register_operand" "")
3507 (match_operand:VMDI 1 "s_register_operand" "")
3508 (match_operand:<V_elem> 2 "s_register_operand" "")
3509 (match_operand:SI 3 "immediate_operand" "")]
3512 rtx tmp = gen_reg_rtx (<MODE>mode);
3513 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3514 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3515 const0_rtx, operands[3]));
3519 (define_expand "neon_vqdmulh_n<mode>"
3520 [(match_operand:VMQI 0 "s_register_operand" "")
3521 (match_operand:VMQI 1 "s_register_operand" "")
3522 (match_operand:<V_elem> 2 "s_register_operand" "")
3523 (match_operand:SI 3 "immediate_operand" "")]
3526 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3527 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3528 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3529 const0_rtx, operands[3]));
3533 (define_expand "neon_vmla_n<mode>"
3534 [(match_operand:VMD 0 "s_register_operand" "")
3535 (match_operand:VMD 1 "s_register_operand" "")
3536 (match_operand:VMD 2 "s_register_operand" "")
3537 (match_operand:<V_elem> 3 "s_register_operand" "")
3538 (match_operand:SI 4 "immediate_operand" "")]
3541 rtx tmp = gen_reg_rtx (<MODE>mode);
3542 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3543 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3544 tmp, const0_rtx, operands[4]));
3548 (define_expand "neon_vmla_n<mode>"
3549 [(match_operand:VMQ 0 "s_register_operand" "")
3550 (match_operand:VMQ 1 "s_register_operand" "")
3551 (match_operand:VMQ 2 "s_register_operand" "")
3552 (match_operand:<V_elem> 3 "s_register_operand" "")
3553 (match_operand:SI 4 "immediate_operand" "")]
3556 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3557 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3558 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3559 tmp, const0_rtx, operands[4]));
3563 (define_expand "neon_vmlal_n<mode>"
3564 [(match_operand:<V_widen> 0 "s_register_operand" "")
3565 (match_operand:<V_widen> 1 "s_register_operand" "")
3566 (match_operand:VMDI 2 "s_register_operand" "")
3567 (match_operand:<V_elem> 3 "s_register_operand" "")
3568 (match_operand:SI 4 "immediate_operand" "")]
3571 rtx tmp = gen_reg_rtx (<MODE>mode);
3572 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3573 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3574 tmp, const0_rtx, operands[4]));
3578 (define_expand "neon_vqdmlal_n<mode>"
3579 [(match_operand:<V_widen> 0 "s_register_operand" "")
3580 (match_operand:<V_widen> 1 "s_register_operand" "")
3581 (match_operand:VMDI 2 "s_register_operand" "")
3582 (match_operand:<V_elem> 3 "s_register_operand" "")
3583 (match_operand:SI 4 "immediate_operand" "")]
3586 rtx tmp = gen_reg_rtx (<MODE>mode);
3587 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3588 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3589 tmp, const0_rtx, operands[4]));
3593 (define_expand "neon_vmls_n<mode>"
3594 [(match_operand:VMD 0 "s_register_operand" "")
3595 (match_operand:VMD 1 "s_register_operand" "")
3596 (match_operand:VMD 2 "s_register_operand" "")
3597 (match_operand:<V_elem> 3 "s_register_operand" "")
3598 (match_operand:SI 4 "immediate_operand" "")]
3601 rtx tmp = gen_reg_rtx (<MODE>mode);
3602 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3603 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3604 tmp, const0_rtx, operands[4]));
3608 (define_expand "neon_vmls_n<mode>"
3609 [(match_operand:VMQ 0 "s_register_operand" "")
3610 (match_operand:VMQ 1 "s_register_operand" "")
3611 (match_operand:VMQ 2 "s_register_operand" "")
3612 (match_operand:<V_elem> 3 "s_register_operand" "")
3613 (match_operand:SI 4 "immediate_operand" "")]
3616 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3617 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3618 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3619 tmp, const0_rtx, operands[4]));
3623 (define_expand "neon_vmlsl_n<mode>"
3624 [(match_operand:<V_widen> 0 "s_register_operand" "")
3625 (match_operand:<V_widen> 1 "s_register_operand" "")
3626 (match_operand:VMDI 2 "s_register_operand" "")
3627 (match_operand:<V_elem> 3 "s_register_operand" "")
3628 (match_operand:SI 4 "immediate_operand" "")]
3631 rtx tmp = gen_reg_rtx (<MODE>mode);
3632 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3633 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3634 tmp, const0_rtx, operands[4]));
3638 (define_expand "neon_vqdmlsl_n<mode>"
3639 [(match_operand:<V_widen> 0 "s_register_operand" "")
3640 (match_operand:<V_widen> 1 "s_register_operand" "")
3641 (match_operand:VMDI 2 "s_register_operand" "")
3642 (match_operand:<V_elem> 3 "s_register_operand" "")
3643 (match_operand:SI 4 "immediate_operand" "")]
3646 rtx tmp = gen_reg_rtx (<MODE>mode);
3647 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3648 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3649 tmp, const0_rtx, operands[4]));
3653 (define_insn "neon_vext<mode>"
3654 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3655 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3656 (match_operand:VDQX 2 "s_register_operand" "w")
3657 (match_operand:SI 3 "immediate_operand" "i")]
3661 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3662 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3664 [(set (attr "neon_type")
3665 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3666 (const_string "neon_bp_simple")
3667 (const_string "neon_bp_2cycle")))]
3670 (define_insn "neon_vrev64<mode>"
3671 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3672 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3673 (match_operand:SI 2 "immediate_operand" "i")]
3676 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3677 [(set_attr "neon_type" "neon_bp_simple")]
3680 (define_insn "neon_vrev32<mode>"
3681 [(set (match_operand:VX 0 "s_register_operand" "=w")
3682 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3683 (match_operand:SI 2 "immediate_operand" "i")]
3686 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3687 [(set_attr "neon_type" "neon_bp_simple")]
3690 (define_insn "neon_vrev16<mode>"
3691 [(set (match_operand:VE 0 "s_register_operand" "=w")
3692 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3693 (match_operand:SI 2 "immediate_operand" "i")]
3696 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3697 [(set_attr "neon_type" "neon_bp_simple")]
3700 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3701 ; allocation. For an intrinsic of form:
3702 ; rD = vbsl_* (rS, rN, rM)
3703 ; We can use any of:
3704 ; vbsl rS, rN, rM (if D = S)
3705 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3706 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3708 (define_insn "neon_vbsl<mode>_internal"
3709 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3710 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3711 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3712 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3716 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3717 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3718 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3719 [(set_attr "neon_type" "neon_int_1")]
3722 (define_expand "neon_vbsl<mode>"
3723 [(set (match_operand:VDQX 0 "s_register_operand" "")
3724 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3725 (match_operand:VDQX 2 "s_register_operand" "")
3726 (match_operand:VDQX 3 "s_register_operand" "")]
3730 /* We can't alias operands together if they have different modes. */
3731 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3734 (define_insn "neon_vshl<mode>"
3735 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3736 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3737 (match_operand:VDQIX 2 "s_register_operand" "w")
3738 (match_operand:SI 3 "immediate_operand" "i")]
3741 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3742 [(set (attr "neon_type")
3743 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3744 (const_string "neon_vshl_ddd")
3745 (const_string "neon_shift_3")))]
3748 (define_insn "neon_vqshl<mode>"
3749 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3750 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3751 (match_operand:VDQIX 2 "s_register_operand" "w")
3752 (match_operand:SI 3 "immediate_operand" "i")]
3755 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3756 [(set (attr "neon_type")
3757 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3758 (const_string "neon_shift_2")
3759 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3762 (define_insn "neon_vshr_n<mode>"
3763 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3764 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3765 (match_operand:SI 2 "immediate_operand" "i")
3766 (match_operand:SI 3 "immediate_operand" "i")]
3770 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3771 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3773 [(set_attr "neon_type" "neon_shift_1")]
3776 (define_insn "neon_vshrn_n<mode>"
3777 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3778 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3779 (match_operand:SI 2 "immediate_operand" "i")
3780 (match_operand:SI 3 "immediate_operand" "i")]
3784 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3785 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3787 [(set_attr "neon_type" "neon_shift_1")]
3790 (define_insn "neon_vqshrn_n<mode>"
3791 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3792 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3793 (match_operand:SI 2 "immediate_operand" "i")
3794 (match_operand:SI 3 "immediate_operand" "i")]
3798 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3799 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3801 [(set_attr "neon_type" "neon_shift_2")]
3804 (define_insn "neon_vqshrun_n<mode>"
3805 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3806 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3807 (match_operand:SI 2 "immediate_operand" "i")
3808 (match_operand:SI 3 "immediate_operand" "i")]
3812 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3813 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3815 [(set_attr "neon_type" "neon_shift_2")]
3818 (define_insn "neon_vshl_n<mode>"
3819 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3820 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3821 (match_operand:SI 2 "immediate_operand" "i")
3822 (match_operand:SI 3 "immediate_operand" "i")]
3826 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3827 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
3829 [(set_attr "neon_type" "neon_shift_1")]
3832 (define_insn "neon_vqshl_n<mode>"
3833 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3834 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3835 (match_operand:SI 2 "immediate_operand" "i")
3836 (match_operand:SI 3 "immediate_operand" "i")]
3840 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3841 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3843 [(set_attr "neon_type" "neon_shift_2")]
3846 (define_insn "neon_vqshlu_n<mode>"
3847 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3848 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3849 (match_operand:SI 2 "immediate_operand" "i")
3850 (match_operand:SI 3 "immediate_operand" "i")]
3854 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3855 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3857 [(set_attr "neon_type" "neon_shift_2")]
3860 (define_insn "neon_vshll_n<mode>"
3861 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3862 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3863 (match_operand:SI 2 "immediate_operand" "i")
3864 (match_operand:SI 3 "immediate_operand" "i")]
3868 /* The boundaries are: 0 < imm <= size. */
3869 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
3870 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
3872 [(set_attr "neon_type" "neon_shift_1")]
3875 (define_insn "neon_vsra_n<mode>"
3876 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3877 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3878 (match_operand:VDQIX 2 "s_register_operand" "w")
3879 (match_operand:SI 3 "immediate_operand" "i")
3880 (match_operand:SI 4 "immediate_operand" "i")]
3884 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3885 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3887 [(set_attr "neon_type" "neon_vsra_vrsra")]
3890 (define_insn "neon_vsri_n<mode>"
3891 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3892 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3893 (match_operand:VDQIX 2 "s_register_operand" "w")
3894 (match_operand:SI 3 "immediate_operand" "i")]
3898 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3899 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3901 [(set (attr "neon_type")
3902 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3903 (const_string "neon_shift_1")
3904 (const_string "neon_shift_3")))]
3907 (define_insn "neon_vsli_n<mode>"
3908 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3909 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3910 (match_operand:VDQIX 2 "s_register_operand" "w")
3911 (match_operand:SI 3 "immediate_operand" "i")]
3915 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
3916 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3918 [(set (attr "neon_type")
3919 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3920 (const_string "neon_shift_1")
3921 (const_string "neon_shift_3")))]
3924 (define_insn "neon_vtbl1v8qi"
3925 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3926 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
3927 (match_operand:V8QI 2 "s_register_operand" "w")]
3930 "vtbl.8\t%P0, {%P1}, %P2"
3931 [(set_attr "neon_type" "neon_bp_2cycle")]
3934 (define_insn "neon_vtbl2v8qi"
3935 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3936 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
3937 (match_operand:V8QI 2 "s_register_operand" "w")]
3942 int tabbase = REGNO (operands[1]);
3944 ops[0] = operands[0];
3945 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3946 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3947 ops[3] = operands[2];
3948 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
3952 [(set_attr "neon_type" "neon_bp_2cycle")]
3955 (define_insn "neon_vtbl3v8qi"
3956 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3957 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
3958 (match_operand:V8QI 2 "s_register_operand" "w")]
3963 int tabbase = REGNO (operands[1]);
3965 ops[0] = operands[0];
3966 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3967 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3968 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3969 ops[4] = operands[2];
3970 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3974 [(set_attr "neon_type" "neon_bp_3cycle")]
3977 (define_insn "neon_vtbl4v8qi"
3978 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3979 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
3980 (match_operand:V8QI 2 "s_register_operand" "w")]
3985 int tabbase = REGNO (operands[1]);
3987 ops[0] = operands[0];
3988 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3989 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3990 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3991 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
3992 ops[5] = operands[2];
3993 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
3997 [(set_attr "neon_type" "neon_bp_3cycle")]
4000 (define_insn "neon_vtbx1v8qi"
4001 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4002 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4003 (match_operand:V8QI 2 "s_register_operand" "w")
4004 (match_operand:V8QI 3 "s_register_operand" "w")]
4007 "vtbx.8\t%P0, {%P2}, %P3"
4008 [(set_attr "neon_type" "neon_bp_2cycle")]
4011 (define_insn "neon_vtbx2v8qi"
4012 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4013 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4014 (match_operand:TI 2 "s_register_operand" "w")
4015 (match_operand:V8QI 3 "s_register_operand" "w")]
4020 int tabbase = REGNO (operands[2]);
4022 ops[0] = operands[0];
4023 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4024 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4025 ops[3] = operands[3];
4026 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
4030 [(set_attr "neon_type" "neon_bp_2cycle")]
4033 (define_insn "neon_vtbx3v8qi"
4034 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4035 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4036 (match_operand:EI 2 "s_register_operand" "w")
4037 (match_operand:V8QI 3 "s_register_operand" "w")]
4042 int tabbase = REGNO (operands[2]);
4044 ops[0] = operands[0];
4045 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4046 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4047 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4048 ops[4] = operands[3];
4049 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4053 [(set_attr "neon_type" "neon_bp_3cycle")]
4056 (define_insn "neon_vtbx4v8qi"
4057 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4058 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4059 (match_operand:OI 2 "s_register_operand" "w")
4060 (match_operand:V8QI 3 "s_register_operand" "w")]
4065 int tabbase = REGNO (operands[2]);
4067 ops[0] = operands[0];
4068 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4069 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4070 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4071 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4072 ops[5] = operands[3];
4073 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4077 [(set_attr "neon_type" "neon_bp_3cycle")]
4080 (define_insn "neon_vtrn<mode>_internal"
4081 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4082 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4084 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4085 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4088 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4089 [(set (attr "neon_type")
4090 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4091 (const_string "neon_bp_simple")
4092 (const_string "neon_bp_3cycle")))]
4095 (define_expand "neon_vtrn<mode>"
4096 [(match_operand:SI 0 "s_register_operand" "r")
4097 (match_operand:VDQW 1 "s_register_operand" "w")
4098 (match_operand:VDQW 2 "s_register_operand" "w")]
4101 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
4102 operands[0], operands[1], operands[2]);
4106 (define_insn "neon_vzip<mode>_internal"
4107 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4108 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4110 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4111 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4114 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4115 [(set (attr "neon_type")
4116 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4117 (const_string "neon_bp_simple")
4118 (const_string "neon_bp_3cycle")))]
4121 (define_expand "neon_vzip<mode>"
4122 [(match_operand:SI 0 "s_register_operand" "r")
4123 (match_operand:VDQW 1 "s_register_operand" "w")
4124 (match_operand:VDQW 2 "s_register_operand" "w")]
4127 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
4128 operands[0], operands[1], operands[2]);
4132 (define_insn "neon_vuzp<mode>_internal"
4133 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4134 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4136 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4137 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4140 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4141 [(set (attr "neon_type")
4142 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4143 (const_string "neon_bp_simple")
4144 (const_string "neon_bp_3cycle")))]
4147 (define_expand "neon_vuzp<mode>"
4148 [(match_operand:SI 0 "s_register_operand" "r")
4149 (match_operand:VDQW 1 "s_register_operand" "w")
4150 (match_operand:VDQW 2 "s_register_operand" "w")]
4153 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
4154 operands[0], operands[1], operands[2]);
4158 (define_expand "neon_vreinterpretv8qi<mode>"
4159 [(match_operand:V8QI 0 "s_register_operand" "")
4160 (match_operand:VDX 1 "s_register_operand" "")]
4163 neon_reinterpret (operands[0], operands[1]);
4167 (define_expand "neon_vreinterpretv4hi<mode>"
4168 [(match_operand:V4HI 0 "s_register_operand" "")
4169 (match_operand:VDX 1 "s_register_operand" "")]
4172 neon_reinterpret (operands[0], operands[1]);
4176 (define_expand "neon_vreinterpretv2si<mode>"
4177 [(match_operand:V2SI 0 "s_register_operand" "")
4178 (match_operand:VDX 1 "s_register_operand" "")]
4181 neon_reinterpret (operands[0], operands[1]);
4185 (define_expand "neon_vreinterpretv2sf<mode>"
4186 [(match_operand:V2SF 0 "s_register_operand" "")
4187 (match_operand:VDX 1 "s_register_operand" "")]
4190 neon_reinterpret (operands[0], operands[1]);
4194 (define_expand "neon_vreinterpretdi<mode>"
4195 [(match_operand:DI 0 "s_register_operand" "")
4196 (match_operand:VDX 1 "s_register_operand" "")]
4199 neon_reinterpret (operands[0], operands[1]);
4203 (define_expand "neon_vreinterpretv16qi<mode>"
4204 [(match_operand:V16QI 0 "s_register_operand" "")
4205 (match_operand:VQX 1 "s_register_operand" "")]
4208 neon_reinterpret (operands[0], operands[1]);
4212 (define_expand "neon_vreinterpretv8hi<mode>"
4213 [(match_operand:V8HI 0 "s_register_operand" "")
4214 (match_operand:VQX 1 "s_register_operand" "")]
4217 neon_reinterpret (operands[0], operands[1]);
4221 (define_expand "neon_vreinterpretv4si<mode>"
4222 [(match_operand:V4SI 0 "s_register_operand" "")
4223 (match_operand:VQX 1 "s_register_operand" "")]
4226 neon_reinterpret (operands[0], operands[1]);
4230 (define_expand "neon_vreinterpretv4sf<mode>"
4231 [(match_operand:V4SF 0 "s_register_operand" "")
4232 (match_operand:VQX 1 "s_register_operand" "")]
4235 neon_reinterpret (operands[0], operands[1]);
4239 (define_expand "neon_vreinterpretv2di<mode>"
4240 [(match_operand:V2DI 0 "s_register_operand" "")
4241 (match_operand:VQX 1 "s_register_operand" "")]
4244 neon_reinterpret (operands[0], operands[1]);
4248 (define_insn "neon_vld1<mode>"
4249 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4250 (unspec:VDQX [(mem:VDQX (match_operand:SI 1 "s_register_operand" "r"))]
4253 "vld1.<V_sz_elem>\t%h0, [%1]"
4254 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4257 (define_insn "neon_vld1_lane<mode>"
4258 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4259 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4260 (match_operand:VDX 2 "s_register_operand" "0")
4261 (match_operand:SI 3 "immediate_operand" "i")]
4265 HOST_WIDE_INT lane = INTVAL (operands[3]);
4266 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4267 if (lane < 0 || lane >= max)
4268 error ("lane out of range");
4270 return "vld1.<V_sz_elem>\t%P0, [%1]";
4272 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4274 [(set (attr "neon_type")
4275 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4276 (const_string "neon_vld1_1_2_regs")
4277 (const_string "neon_vld1_vld2_lane")))]
4280 (define_insn "neon_vld1_lane<mode>"
4281 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4282 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4283 (match_operand:VQX 2 "s_register_operand" "0")
4284 (match_operand:SI 3 "immediate_operand" "i")]
4288 HOST_WIDE_INT lane = INTVAL (operands[3]);
4289 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4290 int regno = REGNO (operands[0]);
4291 if (lane < 0 || lane >= max)
4292 error ("lane out of range");
4293 else if (lane >= max / 2)
4297 operands[3] = GEN_INT (lane);
4299 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4301 return "vld1.<V_sz_elem>\t%P0, [%1]";
4303 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4305 [(set (attr "neon_type")
4306 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4307 (const_string "neon_vld1_1_2_regs")
4308 (const_string "neon_vld1_vld2_lane")))]
4311 (define_insn "neon_vld1_dup<mode>"
4312 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4313 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4317 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4318 return "vld1.<V_sz_elem>\t{%P0[]}, [%1]";
4320 return "vld1.<V_sz_elem>\t%h0, [%1]";
4322 [(set (attr "neon_type")
4323 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4324 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4325 (const_string "neon_vld1_1_2_regs")))]
4328 (define_insn "neon_vld1_dup<mode>"
4329 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4330 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4334 if (GET_MODE_NUNITS (<MODE>mode) > 2)
4335 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4337 return "vld1.<V_sz_elem>\t%h0, [%1]";
4339 [(set (attr "neon_type")
4340 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4341 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4342 (const_string "neon_vld1_1_2_regs")))]
4345 (define_insn "neon_vst1<mode>"
4346 [(set (mem:VDQX (match_operand:SI 0 "s_register_operand" "r"))
4347 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4350 "vst1.<V_sz_elem>\t%h1, [%0]"
4351 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4353 (define_insn "neon_vst1_lane<mode>"
4354 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4355 (vec_select:<V_elem>
4356 (match_operand:VDX 1 "s_register_operand" "w")
4357 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4360 HOST_WIDE_INT lane = INTVAL (operands[2]);
4361 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4362 if (lane < 0 || lane >= max)
4363 error ("lane out of range");
4365 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4367 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4369 [(set (attr "neon_type")
4370 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4371 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4372 (const_string "neon_vst1_vst2_lane")))])
4374 (define_insn "neon_vst1_lane<mode>"
4375 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4376 (vec_select:<V_elem>
4377 (match_operand:VQX 1 "s_register_operand" "w")
4378 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4381 HOST_WIDE_INT lane = INTVAL (operands[2]);
4382 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4383 int regno = REGNO (operands[1]);
4384 if (lane < 0 || lane >= max)
4385 error ("lane out of range");
4386 else if (lane >= max / 2)
4390 operands[2] = GEN_INT (lane);
4392 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4394 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4396 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4398 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4401 (define_insn "neon_vld2<mode>"
4402 [(set (match_operand:TI 0 "s_register_operand" "=w")
4403 (unspec:TI [(mem:TI (match_operand:SI 1 "s_register_operand" "r"))
4404 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4408 if (<V_sz_elem> == 64)
4409 return "vld1.64\t%h0, [%1]";
4411 return "vld2.<V_sz_elem>\t%h0, [%1]";
4413 [(set (attr "neon_type")
4414 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4415 (const_string "neon_vld1_1_2_regs")
4416 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4419 (define_insn "neon_vld2<mode>"
4420 [(set (match_operand:OI 0 "s_register_operand" "=w")
4421 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4422 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4425 "vld2.<V_sz_elem>\t%h0, [%1]"
4426 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4428 (define_insn "neon_vld2_lane<mode>"
4429 [(set (match_operand:TI 0 "s_register_operand" "=w")
4430 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4431 (match_operand:TI 2 "s_register_operand" "0")
4432 (match_operand:SI 3 "immediate_operand" "i")
4433 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4437 HOST_WIDE_INT lane = INTVAL (operands[3]);
4438 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4439 int regno = REGNO (operands[0]);
4441 if (lane < 0 || lane >= max)
4442 error ("lane out of range");
4443 ops[0] = gen_rtx_REG (DImode, regno);
4444 ops[1] = gen_rtx_REG (DImode, regno + 2);
4445 ops[2] = operands[1];
4446 ops[3] = operands[3];
4447 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4450 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4453 (define_insn "neon_vld2_lane<mode>"
4454 [(set (match_operand:OI 0 "s_register_operand" "=w")
4455 (unspec:OI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4456 (match_operand:OI 2 "s_register_operand" "0")
4457 (match_operand:SI 3 "immediate_operand" "i")
4458 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4462 HOST_WIDE_INT lane = INTVAL (operands[3]);
4463 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4464 int regno = REGNO (operands[0]);
4466 if (lane < 0 || lane >= max)
4467 error ("lane out of range");
4468 else if (lane >= max / 2)
4473 ops[0] = gen_rtx_REG (DImode, regno);
4474 ops[1] = gen_rtx_REG (DImode, regno + 4);
4475 ops[2] = operands[1];
4476 ops[3] = GEN_INT (lane);
4477 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4480 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4483 (define_insn "neon_vld2_dup<mode>"
4484 [(set (match_operand:TI 0 "s_register_operand" "=w")
4485 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4486 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4490 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4491 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4493 return "vld1.<V_sz_elem>\t%h0, [%1]";
4495 [(set (attr "neon_type")
4496 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4497 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4498 (const_string "neon_vld1_1_2_regs")))]
4501 (define_insn "neon_vst2<mode>"
4502 [(set (mem:TI (match_operand:SI 0 "s_register_operand" "r"))
4503 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4504 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4508 if (<V_sz_elem> == 64)
4509 return "vst1.64\t%h1, [%0]";
4511 return "vst2.<V_sz_elem>\t%h1, [%0]";
4513 [(set (attr "neon_type")
4514 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4515 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4516 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4519 (define_insn "neon_vst2<mode>"
4520 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4521 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4522 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4525 "vst2.<V_sz_elem>\t%h1, [%0]"
4526 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4529 (define_insn "neon_vst2_lane<mode>"
4530 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4531 (unspec:<V_two_elem>
4532 [(match_operand:TI 1 "s_register_operand" "w")
4533 (match_operand:SI 2 "immediate_operand" "i")
4534 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4538 HOST_WIDE_INT lane = INTVAL (operands[2]);
4539 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4540 int regno = REGNO (operands[1]);
4542 if (lane < 0 || lane >= max)
4543 error ("lane out of range");
4544 ops[0] = operands[0];
4545 ops[1] = gen_rtx_REG (DImode, regno);
4546 ops[2] = gen_rtx_REG (DImode, regno + 2);
4547 ops[3] = operands[2];
4548 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4551 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4554 (define_insn "neon_vst2_lane<mode>"
4555 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4556 (unspec:<V_two_elem>
4557 [(match_operand:OI 1 "s_register_operand" "w")
4558 (match_operand:SI 2 "immediate_operand" "i")
4559 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4563 HOST_WIDE_INT lane = INTVAL (operands[2]);
4564 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4565 int regno = REGNO (operands[1]);
4567 if (lane < 0 || lane >= max)
4568 error ("lane out of range");
4569 else if (lane >= max / 2)
4574 ops[0] = operands[0];
4575 ops[1] = gen_rtx_REG (DImode, regno);
4576 ops[2] = gen_rtx_REG (DImode, regno + 4);
4577 ops[3] = GEN_INT (lane);
4578 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4581 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4584 (define_insn "neon_vld3<mode>"
4585 [(set (match_operand:EI 0 "s_register_operand" "=w")
4586 (unspec:EI [(mem:EI (match_operand:SI 1 "s_register_operand" "r"))
4587 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4591 if (<V_sz_elem> == 64)
4592 return "vld1.64\t%h0, [%1]";
4594 return "vld3.<V_sz_elem>\t%h0, [%1]";
4596 [(set (attr "neon_type")
4597 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4598 (const_string "neon_vld1_1_2_regs")
4599 (const_string "neon_vld3_vld4")))]
4602 (define_expand "neon_vld3<mode>"
4603 [(match_operand:CI 0 "s_register_operand" "=w")
4604 (match_operand:SI 1 "s_register_operand" "+r")
4605 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4608 emit_insn (gen_neon_vld3qa<mode> (operands[0], operands[0],
4609 operands[1], operands[1]));
4610 emit_insn (gen_neon_vld3qb<mode> (operands[0], operands[0],
4611 operands[1], operands[1]));
4615 (define_insn "neon_vld3qa<mode>"
4616 [(set (match_operand:CI 0 "s_register_operand" "=w")
4617 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4618 (match_operand:CI 1 "s_register_operand" "0")
4619 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4621 (set (match_operand:SI 2 "s_register_operand" "=r")
4622 (plus:SI (match_dup 3)
4626 int regno = REGNO (operands[0]);
4628 ops[0] = gen_rtx_REG (DImode, regno);
4629 ops[1] = gen_rtx_REG (DImode, regno + 4);
4630 ops[2] = gen_rtx_REG (DImode, regno + 8);
4631 ops[3] = operands[2];
4632 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4635 [(set_attr "neon_type" "neon_vld3_vld4")]
4638 (define_insn "neon_vld3qb<mode>"
4639 [(set (match_operand:CI 0 "s_register_operand" "=w")
4640 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4641 (match_operand:CI 1 "s_register_operand" "0")
4642 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4644 (set (match_operand:SI 2 "s_register_operand" "=r")
4645 (plus:SI (match_dup 3)
4649 int regno = REGNO (operands[0]);
4651 ops[0] = gen_rtx_REG (DImode, regno + 2);
4652 ops[1] = gen_rtx_REG (DImode, regno + 6);
4653 ops[2] = gen_rtx_REG (DImode, regno + 10);
4654 ops[3] = operands[2];
4655 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4658 [(set_attr "neon_type" "neon_vld3_vld4")]
4661 (define_insn "neon_vld3_lane<mode>"
4662 [(set (match_operand:EI 0 "s_register_operand" "=w")
4663 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4664 (match_operand:EI 2 "s_register_operand" "0")
4665 (match_operand:SI 3 "immediate_operand" "i")
4666 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4670 HOST_WIDE_INT lane = INTVAL (operands[3]);
4671 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4672 int regno = REGNO (operands[0]);
4674 if (lane < 0 || lane >= max)
4675 error ("lane out of range");
4676 ops[0] = gen_rtx_REG (DImode, regno);
4677 ops[1] = gen_rtx_REG (DImode, regno + 2);
4678 ops[2] = gen_rtx_REG (DImode, regno + 4);
4679 ops[3] = operands[1];
4680 ops[4] = operands[3];
4681 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4685 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4688 (define_insn "neon_vld3_lane<mode>"
4689 [(set (match_operand:CI 0 "s_register_operand" "=w")
4690 (unspec:CI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4691 (match_operand:CI 2 "s_register_operand" "0")
4692 (match_operand:SI 3 "immediate_operand" "i")
4693 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4697 HOST_WIDE_INT lane = INTVAL (operands[3]);
4698 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4699 int regno = REGNO (operands[0]);
4701 if (lane < 0 || lane >= max)
4702 error ("lane out of range");
4703 else if (lane >= max / 2)
4708 ops[0] = gen_rtx_REG (DImode, regno);
4709 ops[1] = gen_rtx_REG (DImode, regno + 4);
4710 ops[2] = gen_rtx_REG (DImode, regno + 8);
4711 ops[3] = operands[1];
4712 ops[4] = GEN_INT (lane);
4713 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4717 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4720 (define_insn "neon_vld3_dup<mode>"
4721 [(set (match_operand:EI 0 "s_register_operand" "=w")
4722 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4723 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4727 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4729 int regno = REGNO (operands[0]);
4731 ops[0] = gen_rtx_REG (DImode, regno);
4732 ops[1] = gen_rtx_REG (DImode, regno + 2);
4733 ops[2] = gen_rtx_REG (DImode, regno + 4);
4734 ops[3] = operands[1];
4735 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, [%3]", ops);
4739 return "vld1.<V_sz_elem>\t%h0, [%1]";
4741 [(set (attr "neon_type")
4742 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4743 (const_string "neon_vld3_vld4_all_lanes")
4744 (const_string "neon_vld1_1_2_regs")))])
4746 (define_insn "neon_vst3<mode>"
4747 [(set (mem:EI (match_operand:SI 0 "s_register_operand" "r"))
4748 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
4749 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4753 if (<V_sz_elem> == 64)
4754 return "vst1.64\t%h1, [%0]";
4756 return "vst3.<V_sz_elem>\t%h1, [%0]";
4758 [(set (attr "neon_type")
4759 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4760 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4761 (const_string "neon_vst2_4_regs_vst3_vst4")))])
4763 (define_expand "neon_vst3<mode>"
4764 [(match_operand:SI 0 "s_register_operand" "+r")
4765 (match_operand:CI 1 "s_register_operand" "w")
4766 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4769 emit_insn (gen_neon_vst3qa<mode> (operands[0], operands[0], operands[1]));
4770 emit_insn (gen_neon_vst3qb<mode> (operands[0], operands[0], operands[1]));
4774 (define_insn "neon_vst3qa<mode>"
4775 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4776 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4777 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4779 (set (match_operand:SI 0 "s_register_operand" "=r")
4780 (plus:SI (match_dup 1)
4784 int regno = REGNO (operands[2]);
4786 ops[0] = operands[0];
4787 ops[1] = gen_rtx_REG (DImode, regno);
4788 ops[2] = gen_rtx_REG (DImode, regno + 4);
4789 ops[3] = gen_rtx_REG (DImode, regno + 8);
4790 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4793 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4796 (define_insn "neon_vst3qb<mode>"
4797 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4798 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4799 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4801 (set (match_operand:SI 0 "s_register_operand" "=r")
4802 (plus:SI (match_dup 1)
4806 int regno = REGNO (operands[2]);
4808 ops[0] = operands[0];
4809 ops[1] = gen_rtx_REG (DImode, regno + 2);
4810 ops[2] = gen_rtx_REG (DImode, regno + 6);
4811 ops[3] = gen_rtx_REG (DImode, regno + 10);
4812 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4815 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4818 (define_insn "neon_vst3_lane<mode>"
4819 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4820 (unspec:<V_three_elem>
4821 [(match_operand:EI 1 "s_register_operand" "w")
4822 (match_operand:SI 2 "immediate_operand" "i")
4823 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4827 HOST_WIDE_INT lane = INTVAL (operands[2]);
4828 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4829 int regno = REGNO (operands[1]);
4831 if (lane < 0 || lane >= max)
4832 error ("lane out of range");
4833 ops[0] = operands[0];
4834 ops[1] = gen_rtx_REG (DImode, regno);
4835 ops[2] = gen_rtx_REG (DImode, regno + 2);
4836 ops[3] = gen_rtx_REG (DImode, regno + 4);
4837 ops[4] = operands[2];
4838 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4842 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4845 (define_insn "neon_vst3_lane<mode>"
4846 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4847 (unspec:<V_three_elem>
4848 [(match_operand:CI 1 "s_register_operand" "w")
4849 (match_operand:SI 2 "immediate_operand" "i")
4850 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4854 HOST_WIDE_INT lane = INTVAL (operands[2]);
4855 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4856 int regno = REGNO (operands[1]);
4858 if (lane < 0 || lane >= max)
4859 error ("lane out of range");
4860 else if (lane >= max / 2)
4865 ops[0] = operands[0];
4866 ops[1] = gen_rtx_REG (DImode, regno);
4867 ops[2] = gen_rtx_REG (DImode, regno + 4);
4868 ops[3] = gen_rtx_REG (DImode, regno + 8);
4869 ops[4] = GEN_INT (lane);
4870 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4874 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
4876 (define_insn "neon_vld4<mode>"
4877 [(set (match_operand:OI 0 "s_register_operand" "=w")
4878 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4879 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4883 if (<V_sz_elem> == 64)
4884 return "vld1.64\t%h0, [%1]";
4886 return "vld4.<V_sz_elem>\t%h0, [%1]";
4888 [(set (attr "neon_type")
4889 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4890 (const_string "neon_vld1_1_2_regs")
4891 (const_string "neon_vld3_vld4")))]
4894 (define_expand "neon_vld4<mode>"
4895 [(match_operand:XI 0 "s_register_operand" "=w")
4896 (match_operand:SI 1 "s_register_operand" "+r")
4897 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4900 emit_insn (gen_neon_vld4qa<mode> (operands[0], operands[0],
4901 operands[1], operands[1]));
4902 emit_insn (gen_neon_vld4qb<mode> (operands[0], operands[0],
4903 operands[1], operands[1]));
4907 (define_insn "neon_vld4qa<mode>"
4908 [(set (match_operand:XI 0 "s_register_operand" "=w")
4909 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4910 (match_operand:XI 1 "s_register_operand" "0")
4911 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4913 (set (match_operand:SI 2 "s_register_operand" "=r")
4914 (plus:SI (match_dup 3)
4918 int regno = REGNO (operands[0]);
4920 ops[0] = gen_rtx_REG (DImode, regno);
4921 ops[1] = gen_rtx_REG (DImode, regno + 4);
4922 ops[2] = gen_rtx_REG (DImode, regno + 8);
4923 ops[3] = gen_rtx_REG (DImode, regno + 12);
4924 ops[4] = operands[2];
4925 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4928 [(set_attr "neon_type" "neon_vld3_vld4")]
4931 (define_insn "neon_vld4qb<mode>"
4932 [(set (match_operand:XI 0 "s_register_operand" "=w")
4933 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4934 (match_operand:XI 1 "s_register_operand" "0")
4935 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4937 (set (match_operand:SI 2 "s_register_operand" "=r")
4938 (plus:SI (match_dup 3)
4942 int regno = REGNO (operands[0]);
4944 ops[0] = gen_rtx_REG (DImode, regno + 2);
4945 ops[1] = gen_rtx_REG (DImode, regno + 6);
4946 ops[2] = gen_rtx_REG (DImode, regno + 10);
4947 ops[3] = gen_rtx_REG (DImode, regno + 14);
4948 ops[4] = operands[2];
4949 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4952 [(set_attr "neon_type" "neon_vld3_vld4")]
4955 (define_insn "neon_vld4_lane<mode>"
4956 [(set (match_operand:OI 0 "s_register_operand" "=w")
4957 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4958 (match_operand:OI 2 "s_register_operand" "0")
4959 (match_operand:SI 3 "immediate_operand" "i")
4960 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4964 HOST_WIDE_INT lane = INTVAL (operands[3]);
4965 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4966 int regno = REGNO (operands[0]);
4968 if (lane < 0 || lane >= max)
4969 error ("lane out of range");
4970 ops[0] = gen_rtx_REG (DImode, regno);
4971 ops[1] = gen_rtx_REG (DImode, regno + 2);
4972 ops[2] = gen_rtx_REG (DImode, regno + 4);
4973 ops[3] = gen_rtx_REG (DImode, regno + 6);
4974 ops[4] = operands[1];
4975 ops[5] = operands[3];
4976 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4980 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4983 (define_insn "neon_vld4_lane<mode>"
4984 [(set (match_operand:XI 0 "s_register_operand" "=w")
4985 (unspec:XI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4986 (match_operand:XI 2 "s_register_operand" "0")
4987 (match_operand:SI 3 "immediate_operand" "i")
4988 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4992 HOST_WIDE_INT lane = INTVAL (operands[3]);
4993 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4994 int regno = REGNO (operands[0]);
4996 if (lane < 0 || lane >= max)
4997 error ("lane out of range");
4998 else if (lane >= max / 2)
5003 ops[0] = gen_rtx_REG (DImode, regno);
5004 ops[1] = gen_rtx_REG (DImode, regno + 4);
5005 ops[2] = gen_rtx_REG (DImode, regno + 8);
5006 ops[3] = gen_rtx_REG (DImode, regno + 12);
5007 ops[4] = operands[1];
5008 ops[5] = GEN_INT (lane);
5009 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
5013 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5016 (define_insn "neon_vld4_dup<mode>"
5017 [(set (match_operand:OI 0 "s_register_operand" "=w")
5018 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
5019 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5023 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5025 int regno = REGNO (operands[0]);
5027 ops[0] = gen_rtx_REG (DImode, regno);
5028 ops[1] = gen_rtx_REG (DImode, regno + 2);
5029 ops[2] = gen_rtx_REG (DImode, regno + 4);
5030 ops[3] = gen_rtx_REG (DImode, regno + 6);
5031 ops[4] = operands[1];
5032 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, [%4]",
5037 return "vld1.<V_sz_elem>\t%h0, [%1]";
5039 [(set (attr "neon_type")
5040 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5041 (const_string "neon_vld3_vld4_all_lanes")
5042 (const_string "neon_vld1_1_2_regs")))]
5045 (define_insn "neon_vst4<mode>"
5046 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
5047 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
5048 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5052 if (<V_sz_elem> == 64)
5053 return "vst1.64\t%h1, [%0]";
5055 return "vst4.<V_sz_elem>\t%h1, [%0]";
5057 [(set (attr "neon_type")
5058 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5059 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5060 (const_string "neon_vst2_4_regs_vst3_vst4")))]
5063 (define_expand "neon_vst4<mode>"
5064 [(match_operand:SI 0 "s_register_operand" "+r")
5065 (match_operand:XI 1 "s_register_operand" "w")
5066 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5069 emit_insn (gen_neon_vst4qa<mode> (operands[0], operands[0], operands[1]));
5070 emit_insn (gen_neon_vst4qb<mode> (operands[0], operands[0], operands[1]));
5074 (define_insn "neon_vst4qa<mode>"
5075 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
5076 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
5077 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5079 (set (match_operand:SI 0 "s_register_operand" "=r")
5080 (plus:SI (match_dup 1)
5084 int regno = REGNO (operands[2]);
5086 ops[0] = operands[0];
5087 ops[1] = gen_rtx_REG (DImode, regno);
5088 ops[2] = gen_rtx_REG (DImode, regno + 4);
5089 ops[3] = gen_rtx_REG (DImode, regno + 8);
5090 ops[4] = gen_rtx_REG (DImode, regno + 12);
5091 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
5094 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5097 (define_insn "neon_vst4qb<mode>"
5098 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
5099 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
5100 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5102 (set (match_operand:SI 0 "s_register_operand" "=r")
5103 (plus:SI (match_dup 1)
5107 int regno = REGNO (operands[2]);
5109 ops[0] = operands[0];
5110 ops[1] = gen_rtx_REG (DImode, regno + 2);
5111 ops[2] = gen_rtx_REG (DImode, regno + 6);
5112 ops[3] = gen_rtx_REG (DImode, regno + 10);
5113 ops[4] = gen_rtx_REG (DImode, regno + 14);
5114 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
5117 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5120 (define_insn "neon_vst4_lane<mode>"
5121 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
5122 (unspec:<V_four_elem>
5123 [(match_operand:OI 1 "s_register_operand" "w")
5124 (match_operand:SI 2 "immediate_operand" "i")
5125 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5129 HOST_WIDE_INT lane = INTVAL (operands[2]);
5130 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5131 int regno = REGNO (operands[1]);
5133 if (lane < 0 || lane >= max)
5134 error ("lane out of range");
5135 ops[0] = operands[0];
5136 ops[1] = gen_rtx_REG (DImode, regno);
5137 ops[2] = gen_rtx_REG (DImode, regno + 2);
5138 ops[3] = gen_rtx_REG (DImode, regno + 4);
5139 ops[4] = gen_rtx_REG (DImode, regno + 6);
5140 ops[5] = operands[2];
5141 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
5145 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5148 (define_insn "neon_vst4_lane<mode>"
5149 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
5150 (unspec:<V_four_elem>
5151 [(match_operand:XI 1 "s_register_operand" "w")
5152 (match_operand:SI 2 "immediate_operand" "i")
5153 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5157 HOST_WIDE_INT lane = INTVAL (operands[2]);
5158 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5159 int regno = REGNO (operands[1]);
5161 if (lane < 0 || lane >= max)
5162 error ("lane out of range");
5163 else if (lane >= max / 2)
5168 ops[0] = operands[0];
5169 ops[1] = gen_rtx_REG (DImode, regno);
5170 ops[2] = gen_rtx_REG (DImode, regno + 4);
5171 ops[3] = gen_rtx_REG (DImode, regno + 8);
5172 ops[4] = gen_rtx_REG (DImode, regno + 12);
5173 ops[5] = GEN_INT (lane);
5174 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
5178 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5181 (define_expand "neon_vand<mode>"
5182 [(match_operand:VDQX 0 "s_register_operand" "")
5183 (match_operand:VDQX 1 "s_register_operand" "")
5184 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5185 (match_operand:SI 3 "immediate_operand" "")]
5188 emit_insn (gen_and<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5192 (define_expand "neon_vorr<mode>"
5193 [(match_operand:VDQX 0 "s_register_operand" "")
5194 (match_operand:VDQX 1 "s_register_operand" "")
5195 (match_operand:VDQX 2 "neon_logic_op2" "")
5196 (match_operand:SI 3 "immediate_operand" "")]
5199 emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5203 (define_expand "neon_veor<mode>"
5204 [(match_operand:VDQX 0 "s_register_operand" "")
5205 (match_operand:VDQX 1 "s_register_operand" "")
5206 (match_operand:VDQX 2 "s_register_operand" "")
5207 (match_operand:SI 3 "immediate_operand" "")]
5210 emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5214 (define_expand "neon_vbic<mode>"
5215 [(match_operand:VDQX 0 "s_register_operand" "")
5216 (match_operand:VDQX 1 "s_register_operand" "")
5217 (match_operand:VDQX 2 "neon_logic_op2" "")
5218 (match_operand:SI 3 "immediate_operand" "")]
5221 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5225 (define_expand "neon_vorn<mode>"
5226 [(match_operand:VDQX 0 "s_register_operand" "")
5227 (match_operand:VDQX 1 "s_register_operand" "")
5228 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5229 (match_operand:SI 3 "immediate_operand" "")]
5232 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));
5236 (define_insn "neon_vec_unpack<US>_lo_<mode>"
5237 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5238 (SE:<V_unpack> (vec_select:<V_HALF>
5239 (match_operand:VU 1 "register_operand" "w")
5240 (match_operand:VU 2 "vect_par_constant_low" ""))))]
5242 "vmovl.<US><V_sz_elem> %q0, %e1"
5243 [(set_attr "neon_type" "neon_shift_1")]
5246 (define_insn "neon_vec_unpack<US>_hi_<mode>"
5247 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5248 (SE:<V_unpack> (vec_select:<V_HALF>
5249 (match_operand:VU 1 "register_operand" "w")
5250 (match_operand:VU 2 "vect_par_constant_high" ""))))]
5252 "vmovl.<US><V_sz_elem> %q0, %f1"
5253 [(set_attr "neon_type" "neon_shift_1")]
5256 (define_expand "vec_unpack<US>_hi_<mode>"
5257 [(match_operand:<V_unpack> 0 "register_operand" "")
5258 (SE:<V_unpack> (match_operand:VU 1 "register_operand"))]
5261 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5264 for (i = 0; i < (<V_mode_nunits>/2); i++)
5265 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
5267 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5268 emit_insn (gen_neon_vec_unpack<US>_hi_<mode> (operands[0],
5275 (define_expand "vec_unpack<US>_lo_<mode>"
5276 [(match_operand:<V_unpack> 0 "register_operand" "")
5277 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))]
5280 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5283 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5284 RTVEC_ELT (v, i) = GEN_INT (i);
5285 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5286 emit_insn (gen_neon_vec_unpack<US>_lo_<mode> (operands[0],
5293 (define_insn "neon_vec_<US>mult_lo_<mode>"
5294 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5295 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5296 (match_operand:VU 1 "register_operand" "w")
5297 (match_operand:VU 2 "vect_par_constant_low" "")))
5298 (SE:<V_unpack> (vec_select:<V_HALF>
5299 (match_operand:VU 3 "register_operand" "w")
5302 "vmull.<US><V_sz_elem> %q0, %e1, %e3"
5303 [(set_attr "neon_type" "neon_shift_1")]
5306 (define_expand "vec_widen_<US>mult_lo_<mode>"
5307 [(match_operand:<V_unpack> 0 "register_operand" "")
5308 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5309 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5312 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5315 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5316 RTVEC_ELT (v, i) = GEN_INT (i);
5317 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5319 emit_insn (gen_neon_vec_<US>mult_lo_<mode> (operands[0],
5327 (define_insn "neon_vec_<US>mult_hi_<mode>"
5328 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5329 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5330 (match_operand:VU 1 "register_operand" "w")
5331 (match_operand:VU 2 "vect_par_constant_high" "")))
5332 (SE:<V_unpack> (vec_select:<V_HALF>
5333 (match_operand:VU 3 "register_operand" "w")
5336 "vmull.<US><V_sz_elem> %q0, %f1, %f3"
5337 [(set_attr "neon_type" "neon_shift_1")]
5340 (define_expand "vec_widen_<US>mult_hi_<mode>"
5341 [(match_operand:<V_unpack> 0 "register_operand" "")
5342 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5343 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5346 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5349 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5350 RTVEC_ELT (v, i) = GEN_INT (<V_mode_nunits>/2 + i);
5351 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5353 emit_insn (gen_neon_vec_<US>mult_hi_<mode> (operands[0],
5362 ;; Vectorize for non-neon-quad case
5363 (define_insn "neon_unpack<US>_<mode>"
5364 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5365 (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
5367 "vmovl.<US><V_sz_elem> %q0, %P1"
5368 [(set_attr "neon_type" "neon_shift_1")]
5371 (define_expand "vec_unpack<US>_lo_<mode>"
5372 [(match_operand:<V_double_width> 0 "register_operand" "")
5373 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5376 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5377 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5378 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5384 (define_expand "vec_unpack<US>_hi_<mode>"
5385 [(match_operand:<V_double_width> 0 "register_operand" "")
5386 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5389 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5390 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5391 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5397 (define_insn "neon_vec_<US>mult_<mode>"
5398 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5399 (mult:<V_widen> (SE:<V_widen>
5400 (match_operand:VDI 1 "register_operand" "w"))
5402 (match_operand:VDI 2 "register_operand" "w"))))]
5404 "vmull.<US><V_sz_elem> %q0, %P1, %P2"
5405 [(set_attr "neon_type" "neon_shift_1")]
5408 (define_expand "vec_widen_<US>mult_hi_<mode>"
5409 [(match_operand:<V_double_width> 0 "register_operand" "")
5410 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5411 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5414 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5415 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5416 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5423 (define_expand "vec_widen_<US>mult_lo_<mode>"
5424 [(match_operand:<V_double_width> 0 "register_operand" "")
5425 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5426 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5429 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5430 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5431 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5438 (define_insn "vec_pack_trunc_<mode>"
5439 [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w")
5440 (vec_concat:<V_narrow_pack>
5441 (truncate:<V_narrow>
5442 (match_operand:VN 1 "register_operand" "w"))
5443 (truncate:<V_narrow>
5444 (match_operand:VN 2 "register_operand" "w"))))]
5446 "vmovn.i<V_sz_elem>\t%e0, %q1\n\tvmovn.i<V_sz_elem>\t%f0, %q2"
5447 [(set_attr "neon_type" "neon_shift_1")]
5450 ;; For the non-quad case.
5451 (define_insn "neon_vec_pack_trunc_<mode>"
5452 [(set (match_operand:<V_narrow> 0 "register_operand" "=w")
5453 (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))]
5455 "vmovn.i<V_sz_elem>\t%P0, %q1"
5456 [(set_attr "neon_type" "neon_shift_1")]
5459 (define_expand "vec_pack_trunc_<mode>"
5460 [(match_operand:<V_narrow_pack> 0 "register_operand" "")
5461 (match_operand:VSHFT 1 "register_operand" "")
5462 (match_operand:VSHFT 2 "register_operand")]
5465 rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode);
5467 emit_insn (gen_move_lo_quad_<V_double> (tempreg, operands[1]));
5468 emit_insn (gen_move_hi_quad_<V_double> (tempreg, operands[2]));
5469 emit_insn (gen_neon_vec_pack_trunc_<V_double> (operands[0], tempreg));