1 ;; ARM NEON coprocessor Machine Description
2 ;; Copyright (C) 2006, 2007, 2008, 2009 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)
148 ;; Attribute used to permit string comparisons against <VQH_mnem> in
149 ;; neon_type attribute definitions.
150 (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
152 (define_insn "*neon_mov<mode>"
153 [(set (match_operand:VD 0 "nonimmediate_operand"
154 "=w,Uv,w, w, ?r,?w,?r,?r, ?Us")
155 (match_operand:VD 1 "general_operand"
156 " w,w, Dn,Uvi, w, r, r, Usi,r"))]
158 && (register_operand (operands[0], <MODE>mode)
159 || register_operand (operands[1], <MODE>mode))"
161 if (which_alternative == 2)
164 static char templ[40];
166 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
167 &operands[1], &width);
169 gcc_assert (is_valid != 0);
172 return "vmov.f32\t%P0, %1 @ <mode>";
174 sprintf (templ, "vmov.i%d\t%%P0, %%1 @ <mode>", width);
179 /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
180 below must be changed to output_move_neon (which will use the
181 element/structure loads/stores), and the constraint changed to 'Um' instead
184 switch (which_alternative)
186 case 0: return "vmov\t%P0, %P1 @ <mode>";
187 case 1: case 3: return output_move_vfp (operands);
188 case 2: gcc_unreachable ();
189 case 4: return "vmov\t%Q0, %R0, %P1 @ <mode>";
190 case 5: return "vmov\t%P0, %Q1, %R1 @ <mode>";
191 default: return output_move_double (operands);
194 [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
195 (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu,load2,store2")
196 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
197 (set_attr "length" "4,4,4,4,4,4,8,8,8")
198 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
199 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
201 (define_insn "*neon_mov<mode>"
202 [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
203 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
204 (match_operand:VQXMOV 1 "general_operand"
205 " w,w, Dn,Uni, w, r, r, Usi, r"))]
207 && (register_operand (operands[0], <MODE>mode)
208 || register_operand (operands[1], <MODE>mode))"
210 if (which_alternative == 2)
213 static char templ[40];
215 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
216 &operands[1], &width);
218 gcc_assert (is_valid != 0);
221 return "vmov.f32\t%q0, %1 @ <mode>";
223 sprintf (templ, "vmov.i%d\t%%q0, %%1 @ <mode>", width);
228 switch (which_alternative)
230 case 0: return "vmov\t%q0, %q1 @ <mode>";
231 case 1: case 3: return output_move_neon (operands);
232 case 2: gcc_unreachable ();
233 case 4: return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1";
234 case 5: return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1";
235 default: return output_move_quad (operands);
238 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
239 neon_mrrc,neon_mcr_2_mcrr,*,*,*")
240 (set_attr "type" "*,*,*,*,*,*,alu,load4,store4")
241 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
242 (set_attr "length" "4,8,4,8,8,8,16,8,16")
243 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
244 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
246 (define_expand "movti"
247 [(set (match_operand:TI 0 "nonimmediate_operand" "")
248 (match_operand:TI 1 "general_operand" ""))]
251 if (can_create_pseudo_p ())
253 if (GET_CODE (operands[0]) != REG)
254 operands[1] = force_reg (TImode, operands[1]);
258 (define_expand "mov<mode>"
259 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
260 (match_operand:VSTRUCT 1 "general_operand" ""))]
263 if (can_create_pseudo_p ())
265 if (GET_CODE (operands[0]) != REG)
266 operands[1] = force_reg (<MODE>mode, operands[1]);
270 (define_insn "*neon_mov<mode>"
271 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
272 (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
274 && (register_operand (operands[0], <MODE>mode)
275 || register_operand (operands[1], <MODE>mode))"
277 switch (which_alternative)
280 case 1: case 2: return output_move_neon (operands);
281 default: gcc_unreachable ();
284 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
285 (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))])
288 [(set (match_operand:EI 0 "s_register_operand" "")
289 (match_operand:EI 1 "s_register_operand" ""))]
290 "TARGET_NEON && reload_completed"
291 [(set (match_dup 0) (match_dup 1))
292 (set (match_dup 2) (match_dup 3))]
294 int rdest = REGNO (operands[0]);
295 int rsrc = REGNO (operands[1]);
298 dest[0] = gen_rtx_REG (TImode, rdest);
299 src[0] = gen_rtx_REG (TImode, rsrc);
300 dest[1] = gen_rtx_REG (DImode, rdest + 4);
301 src[1] = gen_rtx_REG (DImode, rsrc + 4);
303 neon_disambiguate_copy (operands, dest, src, 2);
307 [(set (match_operand:OI 0 "s_register_operand" "")
308 (match_operand:OI 1 "s_register_operand" ""))]
309 "TARGET_NEON && reload_completed"
310 [(set (match_dup 0) (match_dup 1))
311 (set (match_dup 2) (match_dup 3))]
313 int rdest = REGNO (operands[0]);
314 int rsrc = REGNO (operands[1]);
317 dest[0] = gen_rtx_REG (TImode, rdest);
318 src[0] = gen_rtx_REG (TImode, rsrc);
319 dest[1] = gen_rtx_REG (TImode, rdest + 4);
320 src[1] = gen_rtx_REG (TImode, rsrc + 4);
322 neon_disambiguate_copy (operands, dest, src, 2);
326 [(set (match_operand:CI 0 "s_register_operand" "")
327 (match_operand:CI 1 "s_register_operand" ""))]
328 "TARGET_NEON && reload_completed"
329 [(set (match_dup 0) (match_dup 1))
330 (set (match_dup 2) (match_dup 3))
331 (set (match_dup 4) (match_dup 5))]
333 int rdest = REGNO (operands[0]);
334 int rsrc = REGNO (operands[1]);
337 dest[0] = gen_rtx_REG (TImode, rdest);
338 src[0] = gen_rtx_REG (TImode, rsrc);
339 dest[1] = gen_rtx_REG (TImode, rdest + 4);
340 src[1] = gen_rtx_REG (TImode, rsrc + 4);
341 dest[2] = gen_rtx_REG (TImode, rdest + 8);
342 src[2] = gen_rtx_REG (TImode, rsrc + 8);
344 neon_disambiguate_copy (operands, dest, src, 3);
348 [(set (match_operand:XI 0 "s_register_operand" "")
349 (match_operand:XI 1 "s_register_operand" ""))]
350 "TARGET_NEON && reload_completed"
351 [(set (match_dup 0) (match_dup 1))
352 (set (match_dup 2) (match_dup 3))
353 (set (match_dup 4) (match_dup 5))
354 (set (match_dup 6) (match_dup 7))]
356 int rdest = REGNO (operands[0]);
357 int rsrc = REGNO (operands[1]);
360 dest[0] = gen_rtx_REG (TImode, rdest);
361 src[0] = gen_rtx_REG (TImode, rsrc);
362 dest[1] = gen_rtx_REG (TImode, rdest + 4);
363 src[1] = gen_rtx_REG (TImode, rsrc + 4);
364 dest[2] = gen_rtx_REG (TImode, rdest + 8);
365 src[2] = gen_rtx_REG (TImode, rsrc + 8);
366 dest[3] = gen_rtx_REG (TImode, rdest + 12);
367 src[3] = gen_rtx_REG (TImode, rsrc + 12);
369 neon_disambiguate_copy (operands, dest, src, 4);
372 (define_insn "vec_set<mode>_internal"
373 [(set (match_operand:VD 0 "s_register_operand" "=w")
376 (match_operand:<V_elem> 1 "s_register_operand" "r"))
377 (match_operand:VD 3 "s_register_operand" "0")
378 (match_operand:SI 2 "immediate_operand" "i")))]
381 int elt = ffs ((int) INTVAL (operands[2]) - 1);
382 if (BYTES_BIG_ENDIAN)
383 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
384 operands[2] = GEN_INT (elt);
386 return "vmov%?.<V_sz_elem>\t%P0[%c2], %1";
388 [(set_attr "predicable" "yes")
389 (set_attr "neon_type" "neon_mcr")])
391 (define_insn "vec_set<mode>_internal"
392 [(set (match_operand:VQ 0 "s_register_operand" "=w")
395 (match_operand:<V_elem> 1 "s_register_operand" "r"))
396 (match_operand:VQ 3 "s_register_operand" "0")
397 (match_operand:SI 2 "immediate_operand" "i")))]
400 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
401 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
402 int elt = elem % half_elts;
403 int hi = (elem / half_elts) * 2;
404 int regno = REGNO (operands[0]);
406 if (BYTES_BIG_ENDIAN)
407 elt = half_elts - 1 - elt;
409 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
410 operands[2] = GEN_INT (elt);
412 return "vmov%?.<V_sz_elem>\t%P0[%c2], %1";
414 [(set_attr "predicable" "yes")
415 (set_attr "neon_type" "neon_mcr")]
418 (define_insn "vec_setv2di_internal"
419 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
422 (match_operand:DI 1 "s_register_operand" "r"))
423 (match_operand:V2DI 3 "s_register_operand" "0")
424 (match_operand:SI 2 "immediate_operand" "i")))]
427 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
428 int regno = REGNO (operands[0]) + 2 * elem;
430 operands[0] = gen_rtx_REG (DImode, regno);
432 return "vmov%?\t%P0, %Q1, %R1";
434 [(set_attr "predicable" "yes")
435 (set_attr "neon_type" "neon_mcr_2_mcrr")]
438 (define_expand "vec_set<mode>"
439 [(match_operand:VDQ 0 "s_register_operand" "")
440 (match_operand:<V_elem> 1 "s_register_operand" "")
441 (match_operand:SI 2 "immediate_operand" "")]
444 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
445 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
446 GEN_INT (elem), operands[0]));
450 (define_insn "vec_extract<mode>"
451 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
453 (match_operand:VD 1 "s_register_operand" "w")
454 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
457 if (BYTES_BIG_ENDIAN)
459 int elt = INTVAL (operands[2]);
460 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
461 operands[2] = GEN_INT (elt);
463 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
465 [(set_attr "predicable" "yes")
466 (set_attr "neon_type" "neon_bp_simple")]
469 (define_insn "vec_extract<mode>"
470 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
472 (match_operand:VQ 1 "s_register_operand" "w")
473 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
476 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
477 int elt = INTVAL (operands[2]) % half_elts;
478 int hi = (INTVAL (operands[2]) / half_elts) * 2;
479 int regno = REGNO (operands[1]);
481 if (BYTES_BIG_ENDIAN)
482 elt = half_elts - 1 - elt;
484 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
485 operands[2] = GEN_INT (elt);
487 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
489 [(set_attr "predicable" "yes")
490 (set_attr "neon_type" "neon_bp_simple")]
493 (define_insn "vec_extractv2di"
494 [(set (match_operand:DI 0 "s_register_operand" "=r")
496 (match_operand:V2DI 1 "s_register_operand" "w")
497 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
500 int regno = REGNO (operands[1]) + 2 * INTVAL (operands[2]);
502 operands[1] = gen_rtx_REG (DImode, regno);
504 return "vmov%?\t%Q0, %R0, %P1 @ v2di";
506 [(set_attr "predicable" "yes")
507 (set_attr "neon_type" "neon_int_1")]
510 (define_expand "vec_init<mode>"
511 [(match_operand:VDQ 0 "s_register_operand" "")
512 (match_operand 1 "" "")]
515 neon_expand_vector_init (operands[0], operands[1]);
519 ;; Doubleword and quadword arithmetic.
521 ;; NOTE: some other instructions also support 64-bit integer
522 ;; element size, which we could potentially use for "long long" operations.
524 (define_insn "*add<mode>3_neon"
525 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
526 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
527 (match_operand:VDQ 2 "s_register_operand" "w")))]
528 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
529 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
530 [(set (attr "neon_type")
531 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
532 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
533 (const_string "neon_fp_vadd_ddd_vabs_dd")
534 (const_string "neon_fp_vadd_qqq_vabs_qq"))
535 (const_string "neon_int_1")))]
538 (define_insn "adddi3_neon"
539 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
540 (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0")
541 (match_operand:DI 2 "s_register_operand" "w,r,0")))
542 (clobber (reg:CC CC_REGNUM))]
545 switch (which_alternative)
547 case 0: return "vadd.i64\t%P0, %P1, %P2";
550 default: gcc_unreachable ();
553 [(set_attr "neon_type" "neon_int_1,*,*")
554 (set_attr "conds" "*,clob,clob")
555 (set_attr "length" "*,8,8")]
558 (define_insn "*sub<mode>3_neon"
559 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
560 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
561 (match_operand:VDQ 2 "s_register_operand" "w")))]
562 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
563 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
564 [(set (attr "neon_type")
565 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
566 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
567 (const_string "neon_fp_vadd_ddd_vabs_dd")
568 (const_string "neon_fp_vadd_qqq_vabs_qq"))
569 (const_string "neon_int_2")))]
572 (define_insn "subdi3_neon"
573 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
574 (minus:DI (match_operand:DI 1 "s_register_operand" "w,0,r,0")
575 (match_operand:DI 2 "s_register_operand" "w,r,0,0")))
576 (clobber (reg:CC CC_REGNUM))]
579 switch (which_alternative)
581 case 0: return "vsub.i64\t%P0, %P1, %P2";
582 case 1: /* fall through */
583 case 2: /* fall through */
584 case 3: return "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2";
585 default: gcc_unreachable ();
588 [(set_attr "neon_type" "neon_int_2,*,*,*")
589 (set_attr "conds" "*,clob,clob,clob")
590 (set_attr "length" "*,8,8,8")]
593 (define_insn "*mul<mode>3_neon"
594 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
595 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
596 (match_operand:VDQ 2 "s_register_operand" "w")))]
597 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
598 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
599 [(set (attr "neon_type")
600 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
601 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
602 (const_string "neon_fp_vadd_ddd_vabs_dd")
603 (const_string "neon_fp_vadd_qqq_vabs_qq"))
604 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
606 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
607 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
608 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
609 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
610 (const_string "neon_mul_qqq_8_16_32_ddd_32")
611 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
614 (define_insn "mul<mode>3add<mode>_neon"
615 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
616 (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
617 (match_operand:VDQ 3 "s_register_operand" "w"))
618 (match_operand:VDQ 1 "s_register_operand" "0")))]
619 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
620 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
621 [(set (attr "neon_type")
622 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
623 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
624 (const_string "neon_fp_vmla_ddd")
625 (const_string "neon_fp_vmla_qqq"))
626 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
628 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
629 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
630 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
631 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
632 (const_string "neon_mla_qqq_8_16")
633 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
636 (define_insn "mul<mode>3neg<mode>add<mode>_neon"
637 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
638 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
639 (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
640 (match_operand:VDQ 3 "s_register_operand" "w"))))]
641 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
642 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
643 [(set (attr "neon_type")
644 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
645 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
646 (const_string "neon_fp_vmla_ddd")
647 (const_string "neon_fp_vmla_qqq"))
648 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
650 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
651 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
652 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
653 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
654 (const_string "neon_mla_qqq_8_16")
655 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
658 (define_insn "ior<mode>3"
659 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
660 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
661 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
664 switch (which_alternative)
666 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
667 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
668 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
669 default: gcc_unreachable ();
672 [(set_attr "neon_type" "neon_int_1")]
675 (define_insn "iordi3_neon"
676 [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r")
677 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r")
678 (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r")))]
681 switch (which_alternative)
683 case 0: return "vorr\t%P0, %P1, %P2";
684 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
685 DImode, 0, VALID_NEON_QREG_MODE (DImode));
688 default: gcc_unreachable ();
691 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*")
692 (set_attr "length" "*,*,8,8")]
695 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
696 ;; vorr. We support the pseudo-instruction vand instead, because that
697 ;; corresponds to the canonical form the middle-end expects to use for
698 ;; immediate bitwise-ANDs.
700 (define_insn "and<mode>3"
701 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
702 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
703 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
706 switch (which_alternative)
708 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
709 case 1: return neon_output_logic_immediate ("vand", &operands[2],
710 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
711 default: gcc_unreachable ();
714 [(set_attr "neon_type" "neon_int_1")]
717 (define_insn "anddi3_neon"
718 [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r")
719 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r")
720 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL,r,r")))]
723 switch (which_alternative)
725 case 0: return "vand\t%P0, %P1, %P2";
726 case 1: return neon_output_logic_immediate ("vand", &operands[2],
727 DImode, 1, VALID_NEON_QREG_MODE (DImode));
730 default: gcc_unreachable ();
733 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*")
734 (set_attr "length" "*,*,8,8")]
737 (define_insn "orn<mode>3_neon"
738 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
739 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
740 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
742 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
743 [(set_attr "neon_type" "neon_int_1")]
746 (define_insn "orndi3_neon"
747 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
748 (ior:DI (match_operand:DI 1 "s_register_operand" "w,r,0")
749 (not:DI (match_operand:DI 2 "s_register_operand" "w,0,r"))))]
755 [(set_attr "neon_type" "neon_int_1,*,*")
756 (set_attr "length" "*,8,8")]
759 (define_insn "bic<mode>3_neon"
760 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
761 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
762 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
764 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
765 [(set_attr "neon_type" "neon_int_1")]
768 ;; Compare to *anddi_notdi_di.
769 (define_insn "bicdi3_neon"
770 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
771 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
772 (match_operand:DI 1 "s_register_operand" "w,0,r")))]
778 [(set_attr "neon_type" "neon_int_1,*,*")
779 (set_attr "length" "*,8,8")]
782 (define_insn "xor<mode>3"
783 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
784 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
785 (match_operand:VDQ 2 "s_register_operand" "w")))]
787 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
788 [(set_attr "neon_type" "neon_int_1")]
791 (define_insn "xordi3_neon"
792 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
793 (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r")
794 (match_operand:DI 2 "s_register_operand" "w,r,r")))]
800 [(set_attr "neon_type" "neon_int_1,*,*")
801 (set_attr "length" "*,8,8")]
804 (define_insn "one_cmpl<mode>2"
805 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
806 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
808 "vmvn\t%<V_reg>0, %<V_reg>1"
809 [(set_attr "neon_type" "neon_int_1")]
812 (define_insn "abs<mode>2"
813 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
814 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
816 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
817 [(set (attr "neon_type")
818 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
819 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
820 (const_string "neon_fp_vadd_ddd_vabs_dd")
821 (const_string "neon_fp_vadd_qqq_vabs_qq"))
822 (const_string "neon_int_3")))]
825 (define_insn "neg<mode>2"
826 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
827 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
829 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
830 [(set (attr "neon_type")
831 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
832 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
833 (const_string "neon_fp_vadd_ddd_vabs_dd")
834 (const_string "neon_fp_vadd_qqq_vabs_qq"))
835 (const_string "neon_int_3")))]
838 (define_insn "*umin<mode>3_neon"
839 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
840 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
841 (match_operand:VDQIW 2 "s_register_operand" "w")))]
843 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
844 [(set_attr "neon_type" "neon_int_5")]
847 (define_insn "*umax<mode>3_neon"
848 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
849 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
850 (match_operand:VDQIW 2 "s_register_operand" "w")))]
852 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
853 [(set_attr "neon_type" "neon_int_5")]
856 (define_insn "*smin<mode>3_neon"
857 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
858 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
859 (match_operand:VDQW 2 "s_register_operand" "w")))]
861 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
862 [(set (attr "neon_type")
863 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
864 (const_string "neon_fp_vadd_ddd_vabs_dd")
865 (const_string "neon_int_5")))]
868 (define_insn "*smax<mode>3_neon"
869 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
870 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
871 (match_operand:VDQW 2 "s_register_operand" "w")))]
873 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
874 [(set (attr "neon_type")
875 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
876 (const_string "neon_fp_vadd_ddd_vabs_dd")
877 (const_string "neon_int_5")))]
880 ; TODO: V2DI shifts are current disabled because there are bugs in the
881 ; generic vectorizer code. It ends up creating a V2DI constructor with
884 (define_insn "vashl<mode>3"
885 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
886 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
887 (match_operand:VDQIW 2 "s_register_operand" "w")))]
889 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
890 [(set (attr "neon_type")
891 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
892 (const_string "neon_vshl_ddd")
893 (const_string "neon_shift_3")))]
896 ; Used for implementing logical shift-right, which is a left-shift by a negative
897 ; amount, with signed operands. This is essentially the same as ashl<mode>3
898 ; above, but using an unspec in case GCC tries anything tricky with negative
901 (define_insn "ashl<mode>3_signed"
902 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
903 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
904 (match_operand:VDQI 2 "s_register_operand" "w")]
905 UNSPEC_ASHIFT_SIGNED))]
907 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
908 [(set (attr "neon_type")
909 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
910 (const_string "neon_vshl_ddd")
911 (const_string "neon_shift_3")))]
914 ; Used for implementing logical shift-right, which is a left-shift by a negative
915 ; amount, with unsigned operands.
917 (define_insn "ashl<mode>3_unsigned"
918 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
919 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
920 (match_operand:VDQI 2 "s_register_operand" "w")]
921 UNSPEC_ASHIFT_UNSIGNED))]
923 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
924 [(set (attr "neon_type")
925 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
926 (const_string "neon_vshl_ddd")
927 (const_string "neon_shift_3")))]
930 (define_expand "vashr<mode>3"
931 [(set (match_operand:VDQIW 0 "s_register_operand" "")
932 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
933 (match_operand:VDQIW 2 "s_register_operand" "")))]
936 rtx neg = gen_reg_rtx (<MODE>mode);
938 emit_insn (gen_neg<mode>2 (neg, operands[2]));
939 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
944 (define_expand "vlshr<mode>3"
945 [(set (match_operand:VDQIW 0 "s_register_operand" "")
946 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
947 (match_operand:VDQIW 2 "s_register_operand" "")))]
950 rtx neg = gen_reg_rtx (<MODE>mode);
952 emit_insn (gen_neg<mode>2 (neg, operands[2]));
953 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
958 ;; Widening operations
960 (define_insn "widen_ssum<mode>3"
961 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
962 (plus:<V_widen> (sign_extend:<V_widen>
963 (match_operand:VW 1 "s_register_operand" "%w"))
964 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
966 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
967 [(set_attr "neon_type" "neon_int_3")]
970 (define_insn "widen_usum<mode>3"
971 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
972 (plus:<V_widen> (zero_extend:<V_widen>
973 (match_operand:VW 1 "s_register_operand" "%w"))
974 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
976 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
977 [(set_attr "neon_type" "neon_int_3")]
980 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
981 ;; shift-count granularity. That's good enough for the middle-end's current
984 (define_expand "vec_shr_<mode>"
985 [(match_operand:VDQ 0 "s_register_operand" "")
986 (match_operand:VDQ 1 "s_register_operand" "")
987 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
991 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
992 const int width = GET_MODE_BITSIZE (<MODE>mode);
993 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
994 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
995 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
997 if (num_bits == width)
999 emit_move_insn (operands[0], operands[1]);
1003 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1004 operands[0] = gen_lowpart (bvecmode, operands[0]);
1005 operands[1] = gen_lowpart (bvecmode, operands[1]);
1007 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1008 GEN_INT (num_bits / BITS_PER_UNIT)));
1012 (define_expand "vec_shl_<mode>"
1013 [(match_operand:VDQ 0 "s_register_operand" "")
1014 (match_operand:VDQ 1 "s_register_operand" "")
1015 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1019 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1020 const int width = GET_MODE_BITSIZE (<MODE>mode);
1021 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1022 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1023 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1027 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1031 num_bits = width - num_bits;
1033 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1034 operands[0] = gen_lowpart (bvecmode, operands[0]);
1035 operands[1] = gen_lowpart (bvecmode, operands[1]);
1037 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1038 GEN_INT (num_bits / BITS_PER_UNIT)));
1042 ;; Helpers for quad-word reduction operations
1044 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1045 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1046 ; N/2-element vector.
1048 (define_insn "quad_halves_<code>v4si"
1049 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1051 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1052 (parallel [(const_int 0) (const_int 1)]))
1053 (vec_select:V2SI (match_dup 1)
1054 (parallel [(const_int 2) (const_int 3)]))))]
1056 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1057 [(set_attr "vqh_mnem" "<VQH_mnem>")
1058 (set (attr "neon_type")
1059 (if_then_else (eq_attr "vqh_mnem" "vadd")
1060 (const_string "neon_int_1") (const_string "neon_int_5")))]
1063 (define_insn "quad_halves_<code>v4sf"
1064 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1066 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1067 (parallel [(const_int 0) (const_int 1)]))
1068 (vec_select:V2SF (match_dup 1)
1069 (parallel [(const_int 2) (const_int 3)]))))]
1070 "TARGET_NEON && flag_unsafe_math_optimizations"
1071 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1072 [(set_attr "vqh_mnem" "<VQH_mnem>")
1073 (set (attr "neon_type")
1074 (if_then_else (eq_attr "vqh_mnem" "vadd")
1075 (const_string "neon_int_1") (const_string "neon_int_5")))]
1078 (define_insn "quad_halves_<code>v8hi"
1079 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1081 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1082 (parallel [(const_int 0) (const_int 1)
1083 (const_int 2) (const_int 3)]))
1084 (vec_select:V4HI (match_dup 1)
1085 (parallel [(const_int 4) (const_int 5)
1086 (const_int 6) (const_int 7)]))))]
1088 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1089 [(set_attr "vqh_mnem" "<VQH_mnem>")
1090 (set (attr "neon_type")
1091 (if_then_else (eq_attr "vqh_mnem" "vadd")
1092 (const_string "neon_int_1") (const_string "neon_int_5")))]
1095 (define_insn "quad_halves_<code>v16qi"
1096 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1098 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1099 (parallel [(const_int 0) (const_int 1)
1100 (const_int 2) (const_int 3)
1101 (const_int 4) (const_int 5)
1102 (const_int 6) (const_int 7)]))
1103 (vec_select:V8QI (match_dup 1)
1104 (parallel [(const_int 8) (const_int 9)
1105 (const_int 10) (const_int 11)
1106 (const_int 12) (const_int 13)
1107 (const_int 14) (const_int 15)]))))]
1109 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1110 [(set_attr "vqh_mnem" "<VQH_mnem>")
1111 (set (attr "neon_type")
1112 (if_then_else (eq_attr "vqh_mnem" "vadd")
1113 (const_string "neon_int_1") (const_string "neon_int_5")))]
1116 ; FIXME: We wouldn't need the following insns if we could write subregs of
1117 ; vector registers. Make an attempt at removing unnecessary moves, though
1118 ; we're really at the mercy of the register allocator.
1120 (define_insn "neon_move_lo_quad_<mode>"
1121 [(set (match_operand:ANY128 0 "s_register_operand" "+w")
1123 (match_operand:<V_HALF> 1 "s_register_operand" "w")
1124 (vec_select:<V_HALF>
1126 (match_operand:ANY128 2 "vect_par_constant_high" ""))))]
1129 int dest = REGNO (operands[0]);
1130 int src = REGNO (operands[1]);
1133 return "vmov\t%e0, %P1";
1137 [(set_attr "neon_type" "neon_bp_simple")]
1140 (define_insn "neon_move_hi_quad_<mode>"
1141 [(set (match_operand:ANY128 0 "s_register_operand" "+w")
1143 (match_operand:<V_HALF> 1 "s_register_operand" "w")
1144 (vec_select:<V_HALF>
1146 (match_operand:ANY128 2 "vect_par_constant_low" ""))))]
1149 int dest = REGNO (operands[0]);
1150 int src = REGNO (operands[1]);
1153 return "vmov\t%f0, %P1";
1157 [(set_attr "neon_type" "neon_bp_simple")]
1160 (define_expand "move_hi_quad_<mode>"
1161 [(match_operand:ANY128 0 "s_register_operand" "")
1162 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1165 rtvec v = rtvec_alloc (<V_mode_nunits>/2);
1169 for (i=0; i < (<V_mode_nunits>/2); i++)
1170 RTVEC_ELT (v, i) = GEN_INT (i);
1172 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
1173 emit_insn (gen_neon_move_hi_quad_<mode> (operands[0], operands[1], t1));
1178 (define_expand "move_lo_quad_<mode>"
1179 [(match_operand:ANY128 0 "s_register_operand" "")
1180 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1183 rtvec v = rtvec_alloc (<V_mode_nunits>/2);
1187 for (i=0; i < (<V_mode_nunits>/2); i++)
1188 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
1190 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
1191 emit_insn (gen_neon_move_lo_quad_<mode> (operands[0], operands[1], t1));
1196 ;; Reduction operations
1198 (define_expand "reduc_splus_<mode>"
1199 [(match_operand:VD 0 "s_register_operand" "")
1200 (match_operand:VD 1 "s_register_operand" "")]
1201 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1203 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1204 &gen_neon_vpadd_internal<mode>);
1208 (define_expand "reduc_splus_<mode>"
1209 [(match_operand:VQ 0 "s_register_operand" "")
1210 (match_operand:VQ 1 "s_register_operand" "")]
1211 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1213 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1214 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1216 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1217 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1218 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1223 (define_insn "reduc_splus_v2di"
1224 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1225 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1228 "vadd.i64\t%e0, %e1, %f1"
1229 [(set_attr "neon_type" "neon_int_1")]
1232 ;; NEON does not distinguish between signed and unsigned addition except on
1233 ;; widening operations.
1234 (define_expand "reduc_uplus_<mode>"
1235 [(match_operand:VDQI 0 "s_register_operand" "")
1236 (match_operand:VDQI 1 "s_register_operand" "")]
1239 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1243 (define_expand "reduc_smin_<mode>"
1244 [(match_operand:VD 0 "s_register_operand" "")
1245 (match_operand:VD 1 "s_register_operand" "")]
1246 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1248 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1249 &gen_neon_vpsmin<mode>);
1253 (define_expand "reduc_smin_<mode>"
1254 [(match_operand:VQ 0 "s_register_operand" "")
1255 (match_operand:VQ 1 "s_register_operand" "")]
1256 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1258 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1259 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1261 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1262 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1263 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1268 (define_expand "reduc_smax_<mode>"
1269 [(match_operand:VD 0 "s_register_operand" "")
1270 (match_operand:VD 1 "s_register_operand" "")]
1271 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1273 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1274 &gen_neon_vpsmax<mode>);
1278 (define_expand "reduc_smax_<mode>"
1279 [(match_operand:VQ 0 "s_register_operand" "")
1280 (match_operand:VQ 1 "s_register_operand" "")]
1281 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1283 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1284 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1286 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1287 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1288 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1293 (define_expand "reduc_umin_<mode>"
1294 [(match_operand:VDI 0 "s_register_operand" "")
1295 (match_operand:VDI 1 "s_register_operand" "")]
1298 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1299 &gen_neon_vpumin<mode>);
1303 (define_expand "reduc_umin_<mode>"
1304 [(match_operand:VQI 0 "s_register_operand" "")
1305 (match_operand:VQI 1 "s_register_operand" "")]
1308 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1309 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1311 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1312 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1313 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1318 (define_expand "reduc_umax_<mode>"
1319 [(match_operand:VDI 0 "s_register_operand" "")
1320 (match_operand:VDI 1 "s_register_operand" "")]
1323 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1324 &gen_neon_vpumax<mode>);
1328 (define_expand "reduc_umax_<mode>"
1329 [(match_operand:VQI 0 "s_register_operand" "")
1330 (match_operand:VQI 1 "s_register_operand" "")]
1333 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1334 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1336 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1337 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1338 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1343 (define_insn "neon_vpadd_internal<mode>"
1344 [(set (match_operand:VD 0 "s_register_operand" "=w")
1345 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1346 (match_operand:VD 2 "s_register_operand" "w")]
1349 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1350 ;; Assume this schedules like vadd.
1351 [(set (attr "neon_type")
1352 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1353 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1354 (const_string "neon_fp_vadd_ddd_vabs_dd")
1355 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1356 (const_string "neon_int_1")))]
1359 (define_insn "neon_vpsmin<mode>"
1360 [(set (match_operand:VD 0 "s_register_operand" "=w")
1361 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1362 (match_operand:VD 2 "s_register_operand" "w")]
1365 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1366 ;; Assume this schedules like vmin.
1367 [(set (attr "neon_type")
1368 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1369 (const_string "neon_fp_vadd_ddd_vabs_dd")
1370 (const_string "neon_int_5")))]
1373 (define_insn "neon_vpsmax<mode>"
1374 [(set (match_operand:VD 0 "s_register_operand" "=w")
1375 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1376 (match_operand:VD 2 "s_register_operand" "w")]
1379 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1380 ;; Assume this schedules like vmax.
1381 [(set (attr "neon_type")
1382 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1383 (const_string "neon_fp_vadd_ddd_vabs_dd")
1384 (const_string "neon_int_5")))]
1387 (define_insn "neon_vpumin<mode>"
1388 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1389 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1390 (match_operand:VDI 2 "s_register_operand" "w")]
1393 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1394 ;; Assume this schedules like umin.
1395 [(set_attr "neon_type" "neon_int_5")]
1398 (define_insn "neon_vpumax<mode>"
1399 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1400 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1401 (match_operand:VDI 2 "s_register_operand" "w")]
1404 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1405 ;; Assume this schedules like umax.
1406 [(set_attr "neon_type" "neon_int_5")]
1409 ;; Saturating arithmetic
1411 ; NOTE: Neon supports many more saturating variants of instructions than the
1412 ; following, but these are all GCC currently understands.
1413 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1414 ; yet either, although these patterns may be used by intrinsics when they're
1417 (define_insn "*ss_add<mode>_neon"
1418 [(set (match_operand:VD 0 "s_register_operand" "=w")
1419 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1420 (match_operand:VD 2 "s_register_operand" "w")))]
1422 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1423 [(set_attr "neon_type" "neon_int_4")]
1426 (define_insn "*us_add<mode>_neon"
1427 [(set (match_operand:VD 0 "s_register_operand" "=w")
1428 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1429 (match_operand:VD 2 "s_register_operand" "w")))]
1431 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1432 [(set_attr "neon_type" "neon_int_4")]
1435 (define_insn "*ss_sub<mode>_neon"
1436 [(set (match_operand:VD 0 "s_register_operand" "=w")
1437 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1438 (match_operand:VD 2 "s_register_operand" "w")))]
1440 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1441 [(set_attr "neon_type" "neon_int_5")]
1444 (define_insn "*us_sub<mode>_neon"
1445 [(set (match_operand:VD 0 "s_register_operand" "=w")
1446 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1447 (match_operand:VD 2 "s_register_operand" "w")))]
1449 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1450 [(set_attr "neon_type" "neon_int_5")]
1453 ;; Conditional instructions. These are comparisons with conditional moves for
1454 ;; vectors. They perform the assignment:
1456 ;; Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2;
1458 ;; where op3 is <, <=, ==, !=, >= or >. Operations are performed
1461 (define_expand "vcond<mode>"
1462 [(set (match_operand:VDQW 0 "s_register_operand" "")
1464 (match_operator 3 "arm_comparison_operator"
1465 [(match_operand:VDQW 4 "s_register_operand" "")
1466 (match_operand:VDQW 5 "nonmemory_operand" "")])
1467 (match_operand:VDQW 1 "s_register_operand" "")
1468 (match_operand:VDQW 2 "s_register_operand" "")))]
1469 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1472 int inverse = 0, immediate_zero = 0;
1473 /* See the description of "magic" bits in the 'T' case of
1474 arm_print_operand. */
1475 HOST_WIDE_INT magic_word = (<MODE>mode == V2SFmode || <MODE>mode == V4SFmode)
1477 rtx magic_rtx = GEN_INT (magic_word);
1479 mask = gen_reg_rtx (<V_cmp_result>mode);
1481 if (operands[5] == CONST0_RTX (<MODE>mode))
1483 else if (!REG_P (operands[5]))
1484 operands[5] = force_reg (<MODE>mode, operands[5]);
1486 switch (GET_CODE (operands[3]))
1489 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1494 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1499 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1505 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1508 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1514 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1517 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1522 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1532 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1535 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1541 (define_expand "vcondu<mode>"
1542 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1544 (match_operator 3 "arm_comparison_operator"
1545 [(match_operand:VDQIW 4 "s_register_operand" "")
1546 (match_operand:VDQIW 5 "s_register_operand" "")])
1547 (match_operand:VDQIW 1 "s_register_operand" "")
1548 (match_operand:VDQIW 2 "s_register_operand" "")))]
1552 int inverse = 0, immediate_zero = 0;
1554 mask = gen_reg_rtx (<V_cmp_result>mode);
1556 if (operands[5] == CONST0_RTX (<MODE>mode))
1558 else if (!REG_P (operands[5]))
1559 operands[5] = force_reg (<MODE>mode, operands[5]);
1561 switch (GET_CODE (operands[3]))
1564 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1569 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1574 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1580 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1583 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1589 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1592 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1597 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1607 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1610 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1616 ;; Patterns for builtins.
1618 ; good for plain vadd, vaddq.
1620 (define_expand "neon_vadd<mode>"
1621 [(match_operand:VDQX 0 "s_register_operand" "=w")
1622 (match_operand:VDQX 1 "s_register_operand" "w")
1623 (match_operand:VDQX 2 "s_register_operand" "w")
1624 (match_operand:SI 3 "immediate_operand" "i")]
1627 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1628 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
1630 emit_insn (gen_neon_vadd<mode>_unspec (operands[0], operands[1],
1635 ; Note that NEON operations don't support the full IEEE 754 standard: in
1636 ; particular, denormal values are flushed to zero. This means that GCC cannot
1637 ; use those instructions for autovectorization, etc. unless
1638 ; -funsafe-math-optimizations is in effect (in which case flush-to-zero
1639 ; behaviour is permissible). Intrinsic operations (provided by the arm_neon.h
1640 ; header) must work in either case: if -funsafe-math-optimizations is given,
1641 ; intrinsics expand to "canonical" RTL where possible, otherwise intrinsics
1642 ; expand to unspecs (which may potentially limit the extent to which they might
1643 ; be optimized by generic code).
1645 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1647 (define_insn "neon_vadd<mode>_unspec"
1648 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1649 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1650 (match_operand:VDQX 2 "s_register_operand" "w")]
1653 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1654 [(set (attr "neon_type")
1655 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1656 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1657 (const_string "neon_fp_vadd_ddd_vabs_dd")
1658 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1659 (const_string "neon_int_1")))]
1662 ; operand 3 represents in bits:
1663 ; bit 0: signed (vs unsigned).
1664 ; bit 1: rounding (vs none).
1666 (define_insn "neon_vaddl<mode>"
1667 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1668 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1669 (match_operand:VDI 2 "s_register_operand" "w")
1670 (match_operand:SI 3 "immediate_operand" "i")]
1673 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1674 [(set_attr "neon_type" "neon_int_3")]
1677 (define_insn "neon_vaddw<mode>"
1678 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1679 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1680 (match_operand:VDI 2 "s_register_operand" "w")
1681 (match_operand:SI 3 "immediate_operand" "i")]
1684 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1685 [(set_attr "neon_type" "neon_int_2")]
1690 (define_insn "neon_vhadd<mode>"
1691 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1692 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1693 (match_operand:VDQIW 2 "s_register_operand" "w")
1694 (match_operand:SI 3 "immediate_operand" "i")]
1697 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1698 [(set_attr "neon_type" "neon_int_4")]
1701 (define_insn "neon_vqadd<mode>"
1702 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1703 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1704 (match_operand:VDQIX 2 "s_register_operand" "w")
1705 (match_operand:SI 3 "immediate_operand" "i")]
1708 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1709 [(set_attr "neon_type" "neon_int_4")]
1712 (define_insn "neon_vaddhn<mode>"
1713 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1714 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1715 (match_operand:VN 2 "s_register_operand" "w")
1716 (match_operand:SI 3 "immediate_operand" "i")]
1719 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
1720 [(set_attr "neon_type" "neon_int_4")]
1723 ;; We cannot replace this unspec with mul<mode>3 because of the odd
1724 ;; polynomial multiplication case that can specified by operand 3.
1725 (define_insn "neon_vmul<mode>"
1726 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1727 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1728 (match_operand:VDQW 2 "s_register_operand" "w")
1729 (match_operand:SI 3 "immediate_operand" "i")]
1732 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1733 [(set (attr "neon_type")
1734 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1735 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1736 (const_string "neon_fp_vadd_ddd_vabs_dd")
1737 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1738 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1740 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1741 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1742 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1743 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1744 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1745 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
1748 (define_expand "neon_vmla<mode>"
1749 [(match_operand:VDQW 0 "s_register_operand" "=w")
1750 (match_operand:VDQW 1 "s_register_operand" "0")
1751 (match_operand:VDQW 2 "s_register_operand" "w")
1752 (match_operand:VDQW 3 "s_register_operand" "w")
1753 (match_operand:SI 4 "immediate_operand" "i")]
1756 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1757 emit_insn (gen_mul<mode>3add<mode>_neon (operands[0], operands[1],
1758 operands[2], operands[3]));
1760 emit_insn (gen_neon_vmla<mode>_unspec (operands[0], operands[1],
1761 operands[2], operands[3]));
1765 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1767 (define_insn "neon_vmla<mode>_unspec"
1768 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1769 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
1770 (match_operand:VDQ 2 "s_register_operand" "w")
1771 (match_operand:VDQ 3 "s_register_operand" "w")]
1774 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1775 [(set (attr "neon_type")
1776 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1777 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1778 (const_string "neon_fp_vmla_ddd")
1779 (const_string "neon_fp_vmla_qqq"))
1780 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1782 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1783 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1784 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1785 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1786 (const_string "neon_mla_qqq_8_16")
1787 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1790 (define_insn "neon_vmlal<mode>"
1791 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1792 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1793 (match_operand:VW 2 "s_register_operand" "w")
1794 (match_operand:VW 3 "s_register_operand" "w")
1795 (match_operand:SI 4 "immediate_operand" "i")]
1798 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1799 [(set (attr "neon_type")
1800 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1801 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1802 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1805 (define_expand "neon_vmls<mode>"
1806 [(match_operand:VDQW 0 "s_register_operand" "=w")
1807 (match_operand:VDQW 1 "s_register_operand" "0")
1808 (match_operand:VDQW 2 "s_register_operand" "w")
1809 (match_operand:VDQW 3 "s_register_operand" "w")
1810 (match_operand:SI 4 "immediate_operand" "i")]
1813 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1814 emit_insn (gen_mul<mode>3neg<mode>add<mode>_neon (operands[0],
1815 operands[1], operands[2], operands[3]));
1817 emit_insn (gen_neon_vmls<mode>_unspec (operands[0], operands[1],
1818 operands[2], operands[3]));
1822 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1824 (define_insn "neon_vmls<mode>_unspec"
1825 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1826 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
1827 (match_operand:VDQ 2 "s_register_operand" "w")
1828 (match_operand:VDQ 3 "s_register_operand" "w")]
1831 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1832 [(set (attr "neon_type")
1833 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1834 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1835 (const_string "neon_fp_vmla_ddd")
1836 (const_string "neon_fp_vmla_qqq"))
1837 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1839 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1840 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1841 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1843 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1844 (const_string "neon_mla_qqq_8_16")
1845 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1848 (define_insn "neon_vmlsl<mode>"
1849 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1850 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1851 (match_operand:VW 2 "s_register_operand" "w")
1852 (match_operand:VW 3 "s_register_operand" "w")
1853 (match_operand:SI 4 "immediate_operand" "i")]
1856 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1857 [(set (attr "neon_type")
1858 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1859 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1860 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1863 (define_insn "neon_vqdmulh<mode>"
1864 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1865 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1866 (match_operand:VMDQI 2 "s_register_operand" "w")
1867 (match_operand:SI 3 "immediate_operand" "i")]
1870 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1871 [(set (attr "neon_type")
1872 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1873 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1874 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1875 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1876 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1877 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1878 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
1881 (define_insn "neon_vqdmlal<mode>"
1882 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1883 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1884 (match_operand:VMDI 2 "s_register_operand" "w")
1885 (match_operand:VMDI 3 "s_register_operand" "w")
1886 (match_operand:SI 4 "immediate_operand" "i")]
1889 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
1890 [(set (attr "neon_type")
1891 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1892 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1893 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1896 (define_insn "neon_vqdmlsl<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:VMDI 2 "s_register_operand" "w")
1900 (match_operand:VMDI 3 "s_register_operand" "w")
1901 (match_operand:SI 4 "immediate_operand" "i")]
1904 "vqdmlsl.<V_s_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_vmull<mode>"
1912 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1913 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1914 (match_operand:VW 2 "s_register_operand" "w")
1915 (match_operand:SI 3 "immediate_operand" "i")]
1918 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1919 [(set (attr "neon_type")
1920 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1921 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1922 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1925 (define_insn "neon_vqdmull<mode>"
1926 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1927 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
1928 (match_operand:VMDI 2 "s_register_operand" "w")
1929 (match_operand:SI 3 "immediate_operand" "i")]
1932 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
1933 [(set (attr "neon_type")
1934 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1935 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1936 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1939 (define_expand "neon_vsub<mode>"
1940 [(match_operand:VDQX 0 "s_register_operand" "=w")
1941 (match_operand:VDQX 1 "s_register_operand" "w")
1942 (match_operand:VDQX 2 "s_register_operand" "w")
1943 (match_operand:SI 3 "immediate_operand" "i")]
1946 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1947 emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
1949 emit_insn (gen_neon_vsub<mode>_unspec (operands[0], operands[1],
1954 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1956 (define_insn "neon_vsub<mode>_unspec"
1957 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1958 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1959 (match_operand:VDQX 2 "s_register_operand" "w")]
1962 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1963 [(set (attr "neon_type")
1964 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1965 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1966 (const_string "neon_fp_vadd_ddd_vabs_dd")
1967 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1968 (const_string "neon_int_2")))]
1971 (define_insn "neon_vsubl<mode>"
1972 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1973 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1974 (match_operand:VDI 2 "s_register_operand" "w")
1975 (match_operand:SI 3 "immediate_operand" "i")]
1978 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1979 [(set_attr "neon_type" "neon_int_2")]
1982 (define_insn "neon_vsubw<mode>"
1983 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1984 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1985 (match_operand:VDI 2 "s_register_operand" "w")
1986 (match_operand:SI 3 "immediate_operand" "i")]
1989 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1990 [(set_attr "neon_type" "neon_int_2")]
1993 (define_insn "neon_vqsub<mode>"
1994 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1995 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1996 (match_operand:VDQIX 2 "s_register_operand" "w")
1997 (match_operand:SI 3 "immediate_operand" "i")]
2000 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2001 [(set_attr "neon_type" "neon_int_5")]
2004 (define_insn "neon_vhsub<mode>"
2005 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2006 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2007 (match_operand:VDQIW 2 "s_register_operand" "w")
2008 (match_operand:SI 3 "immediate_operand" "i")]
2011 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2012 [(set_attr "neon_type" "neon_int_5")]
2015 (define_insn "neon_vsubhn<mode>"
2016 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2017 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2018 (match_operand:VN 2 "s_register_operand" "w")
2019 (match_operand:SI 3 "immediate_operand" "i")]
2022 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2023 [(set_attr "neon_type" "neon_int_4")]
2026 (define_insn "neon_vceq<mode>"
2027 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2028 (unspec:<V_cmp_result>
2029 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2030 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2031 (match_operand:SI 3 "immediate_operand" "i,i")]
2035 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2036 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
2037 [(set (attr "neon_type")
2038 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2039 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2040 (const_string "neon_fp_vadd_ddd_vabs_dd")
2041 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2042 (const_string "neon_int_5")))]
2045 (define_insn "neon_vcge<mode>"
2046 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2047 (unspec:<V_cmp_result>
2048 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2049 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2050 (match_operand:SI 3 "immediate_operand" "i,i")]
2054 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2055 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2056 [(set (attr "neon_type")
2057 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2058 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2059 (const_string "neon_fp_vadd_ddd_vabs_dd")
2060 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2061 (const_string "neon_int_5")))]
2064 (define_insn "neon_vcgt<mode>"
2065 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2066 (unspec:<V_cmp_result>
2067 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2068 (match_operand:VDQW 2 "nonmemory_operand" "w,Dz")
2069 (match_operand:SI 3 "immediate_operand" "i,i")]
2073 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2074 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2075 [(set (attr "neon_type")
2076 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2077 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2078 (const_string "neon_fp_vadd_ddd_vabs_dd")
2079 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2080 (const_string "neon_int_5")))]
2083 ;; VCLE and VCLT only support comparisons with immediate zero (register
2084 ;; variants are VCGE and VCGT with operands reversed).
2086 (define_insn "neon_vcle<mode>"
2087 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2088 (unspec:<V_cmp_result>
2089 [(match_operand:VDQW 1 "s_register_operand" "w")
2090 (match_operand:VDQW 2 "nonmemory_operand" "Dz")
2091 (match_operand:SI 3 "immediate_operand" "i")]
2094 "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2095 [(set (attr "neon_type")
2096 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2097 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2098 (const_string "neon_fp_vadd_ddd_vabs_dd")
2099 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2100 (const_string "neon_int_5")))]
2103 (define_insn "neon_vclt<mode>"
2104 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2105 (unspec:<V_cmp_result>
2106 [(match_operand:VDQW 1 "s_register_operand" "w")
2107 (match_operand:VDQW 2 "nonmemory_operand" "Dz")
2108 (match_operand:SI 3 "immediate_operand" "i")]
2111 "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2112 [(set (attr "neon_type")
2113 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2114 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2115 (const_string "neon_fp_vadd_ddd_vabs_dd")
2116 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2117 (const_string "neon_int_5")))]
2120 (define_insn "neon_vcage<mode>"
2121 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2122 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2123 (match_operand:VCVTF 2 "s_register_operand" "w")
2124 (match_operand:SI 3 "immediate_operand" "i")]
2127 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2128 [(set (attr "neon_type")
2129 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2130 (const_string "neon_fp_vadd_ddd_vabs_dd")
2131 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2134 (define_insn "neon_vcagt<mode>"
2135 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2136 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2137 (match_operand:VCVTF 2 "s_register_operand" "w")
2138 (match_operand:SI 3 "immediate_operand" "i")]
2141 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2142 [(set (attr "neon_type")
2143 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2144 (const_string "neon_fp_vadd_ddd_vabs_dd")
2145 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2148 (define_insn "neon_vtst<mode>"
2149 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2150 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2151 (match_operand:VDQIW 2 "s_register_operand" "w")
2152 (match_operand:SI 3 "immediate_operand" "i")]
2155 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2156 [(set_attr "neon_type" "neon_int_4")]
2159 (define_insn "neon_vabd<mode>"
2160 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2161 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2162 (match_operand:VDQW 2 "s_register_operand" "w")
2163 (match_operand:SI 3 "immediate_operand" "i")]
2166 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2167 [(set (attr "neon_type")
2168 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2169 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2170 (const_string "neon_fp_vadd_ddd_vabs_dd")
2171 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2172 (const_string "neon_int_5")))]
2175 (define_insn "neon_vabdl<mode>"
2176 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2177 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2178 (match_operand:VW 2 "s_register_operand" "w")
2179 (match_operand:SI 3 "immediate_operand" "i")]
2182 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2183 [(set_attr "neon_type" "neon_int_5")]
2186 (define_insn "neon_vaba<mode>"
2187 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2188 (plus:VDQIW (match_operand:VDQIW 1 "s_register_operand" "0")
2189 (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w")
2190 (match_operand:VDQIW 3 "s_register_operand" "w")
2191 (match_operand:SI 4 "immediate_operand" "i")]
2194 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2195 [(set (attr "neon_type")
2196 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2197 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2200 (define_insn "neon_vabal<mode>"
2201 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2202 (plus:<V_widen> (match_operand:<V_widen> 1 "s_register_operand" "0")
2203 (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w")
2204 (match_operand:VW 3 "s_register_operand" "w")
2205 (match_operand:SI 4 "immediate_operand" "i")]
2208 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2209 [(set_attr "neon_type" "neon_vaba")]
2212 (define_insn "neon_vmax<mode>"
2213 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2214 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2215 (match_operand:VDQW 2 "s_register_operand" "w")
2216 (match_operand:SI 3 "immediate_operand" "i")]
2219 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2220 [(set (attr "neon_type")
2221 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2222 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2223 (const_string "neon_fp_vadd_ddd_vabs_dd")
2224 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2225 (const_string "neon_int_5")))]
2228 (define_insn "neon_vmin<mode>"
2229 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2230 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2231 (match_operand:VDQW 2 "s_register_operand" "w")
2232 (match_operand:SI 3 "immediate_operand" "i")]
2235 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2236 [(set (attr "neon_type")
2237 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2238 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2239 (const_string "neon_fp_vadd_ddd_vabs_dd")
2240 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2241 (const_string "neon_int_5")))]
2244 (define_expand "neon_vpadd<mode>"
2245 [(match_operand:VD 0 "s_register_operand" "=w")
2246 (match_operand:VD 1 "s_register_operand" "w")
2247 (match_operand:VD 2 "s_register_operand" "w")
2248 (match_operand:SI 3 "immediate_operand" "i")]
2251 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2256 (define_insn "neon_vpaddl<mode>"
2257 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2258 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2259 (match_operand:SI 2 "immediate_operand" "i")]
2262 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2263 ;; Assume this schedules like vaddl.
2264 [(set_attr "neon_type" "neon_int_3")]
2267 (define_insn "neon_vpadal<mode>"
2268 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2269 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2270 (match_operand:VDQIW 2 "s_register_operand" "w")
2271 (match_operand:SI 3 "immediate_operand" "i")]
2274 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2275 ;; Assume this schedules like vpadd.
2276 [(set_attr "neon_type" "neon_int_1")]
2279 (define_insn "neon_vpmax<mode>"
2280 [(set (match_operand:VD 0 "s_register_operand" "=w")
2281 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2282 (match_operand:VD 2 "s_register_operand" "w")
2283 (match_operand:SI 3 "immediate_operand" "i")]
2286 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2287 ;; Assume this schedules like vmax.
2288 [(set (attr "neon_type")
2289 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2290 (const_string "neon_fp_vadd_ddd_vabs_dd")
2291 (const_string "neon_int_5")))]
2294 (define_insn "neon_vpmin<mode>"
2295 [(set (match_operand:VD 0 "s_register_operand" "=w")
2296 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2297 (match_operand:VD 2 "s_register_operand" "w")
2298 (match_operand:SI 3 "immediate_operand" "i")]
2301 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2302 ;; Assume this schedules like vmin.
2303 [(set (attr "neon_type")
2304 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2305 (const_string "neon_fp_vadd_ddd_vabs_dd")
2306 (const_string "neon_int_5")))]
2309 (define_insn "neon_vrecps<mode>"
2310 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2311 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2312 (match_operand:VCVTF 2 "s_register_operand" "w")
2313 (match_operand:SI 3 "immediate_operand" "i")]
2316 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2317 [(set (attr "neon_type")
2318 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2319 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2320 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2323 (define_insn "neon_vrsqrts<mode>"
2324 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2325 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2326 (match_operand:VCVTF 2 "s_register_operand" "w")
2327 (match_operand:SI 3 "immediate_operand" "i")]
2330 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2331 [(set (attr "neon_type")
2332 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2333 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2334 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2337 (define_expand "neon_vabs<mode>"
2338 [(match_operand:VDQW 0 "s_register_operand" "")
2339 (match_operand:VDQW 1 "s_register_operand" "")
2340 (match_operand:SI 2 "immediate_operand" "")]
2343 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
2347 (define_insn "neon_vqabs<mode>"
2348 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2349 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2350 (match_operand:SI 2 "immediate_operand" "i")]
2353 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2354 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2357 (define_expand "neon_vneg<mode>"
2358 [(match_operand:VDQW 0 "s_register_operand" "")
2359 (match_operand:VDQW 1 "s_register_operand" "")
2360 (match_operand:SI 2 "immediate_operand" "")]
2363 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2367 (define_insn "neon_vqneg<mode>"
2368 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2369 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2370 (match_operand:SI 2 "immediate_operand" "i")]
2373 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2374 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2377 (define_insn "neon_vcls<mode>"
2378 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2379 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2380 (match_operand:SI 2 "immediate_operand" "i")]
2383 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2384 [(set_attr "neon_type" "neon_int_1")]
2387 (define_insn "clz<mode>2"
2388 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2389 (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
2391 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2392 [(set_attr "neon_type" "neon_int_1")]
2395 (define_expand "neon_vclz<mode>"
2396 [(match_operand:VDQIW 0 "s_register_operand" "")
2397 (match_operand:VDQIW 1 "s_register_operand" "")
2398 (match_operand:SI 2 "immediate_operand" "")]
2401 emit_insn (gen_clz<mode>2 (operands[0], operands[1]));
2405 (define_insn "popcount<mode>2"
2406 [(set (match_operand:VE 0 "s_register_operand" "=w")
2407 (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
2409 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2410 [(set_attr "neon_type" "neon_int_1")]
2413 (define_expand "neon_vcnt<mode>"
2414 [(match_operand:VE 0 "s_register_operand" "=w")
2415 (match_operand:VE 1 "s_register_operand" "w")
2416 (match_operand:SI 2 "immediate_operand" "i")]
2419 emit_insn (gen_popcount<mode>2 (operands[0], operands[1]));
2423 (define_insn "neon_vrecpe<mode>"
2424 [(set (match_operand:V32 0 "s_register_operand" "=w")
2425 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2426 (match_operand:SI 2 "immediate_operand" "i")]
2429 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2430 [(set (attr "neon_type")
2431 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2432 (const_string "neon_fp_vadd_ddd_vabs_dd")
2433 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2436 (define_insn "neon_vrsqrte<mode>"
2437 [(set (match_operand:V32 0 "s_register_operand" "=w")
2438 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2439 (match_operand:SI 2 "immediate_operand" "i")]
2442 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2443 [(set (attr "neon_type")
2444 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2445 (const_string "neon_fp_vadd_ddd_vabs_dd")
2446 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2449 (define_expand "neon_vmvn<mode>"
2450 [(match_operand:VDQIW 0 "s_register_operand" "")
2451 (match_operand:VDQIW 1 "s_register_operand" "")
2452 (match_operand:SI 2 "immediate_operand" "")]
2455 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2459 (define_insn "neon_vget_lane<mode>_sext_internal"
2460 [(set (match_operand:SI 0 "s_register_operand" "=r")
2462 (vec_select:<V_elem>
2463 (match_operand:VD 1 "s_register_operand" "w")
2464 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2467 if (BYTES_BIG_ENDIAN)
2469 int elt = INTVAL (operands[2]);
2470 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2471 operands[2] = GEN_INT (elt);
2473 return "vmov%?.s<V_sz_elem>\t%0, %P1[%c2]";
2475 [(set_attr "predicable" "yes")
2476 (set_attr "neon_type" "neon_bp_simple")]
2479 (define_insn "neon_vget_lane<mode>_zext_internal"
2480 [(set (match_operand:SI 0 "s_register_operand" "=r")
2482 (vec_select:<V_elem>
2483 (match_operand:VD 1 "s_register_operand" "w")
2484 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2487 if (BYTES_BIG_ENDIAN)
2489 int elt = INTVAL (operands[2]);
2490 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2491 operands[2] = GEN_INT (elt);
2493 return "vmov%?.u<V_sz_elem>\t%0, %P1[%c2]";
2495 [(set_attr "predicable" "yes")
2496 (set_attr "neon_type" "neon_bp_simple")]
2499 (define_insn "neon_vget_lane<mode>_sext_internal"
2500 [(set (match_operand:SI 0 "s_register_operand" "=r")
2502 (vec_select:<V_elem>
2503 (match_operand:VQ 1 "s_register_operand" "w")
2504 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2508 int regno = REGNO (operands[1]);
2509 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2510 unsigned int elt = INTVAL (operands[2]);
2511 unsigned int elt_adj = elt % halfelts;
2513 if (BYTES_BIG_ENDIAN)
2514 elt_adj = halfelts - 1 - elt_adj;
2516 ops[0] = operands[0];
2517 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2518 ops[2] = GEN_INT (elt_adj);
2519 output_asm_insn ("vmov%?.s<V_sz_elem>\t%0, %P1[%c2]", ops);
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:VQ 1 "s_register_operand" "w")
2532 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2536 int regno = REGNO (operands[1]);
2537 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2538 unsigned int elt = INTVAL (operands[2]);
2539 unsigned int elt_adj = elt % halfelts;
2541 if (BYTES_BIG_ENDIAN)
2542 elt_adj = halfelts - 1 - elt_adj;
2544 ops[0] = operands[0];
2545 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2546 ops[2] = GEN_INT (elt_adj);
2547 output_asm_insn ("vmov%?.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2551 [(set_attr "predicable" "yes")
2552 (set_attr "neon_type" "neon_bp_simple")]
2555 (define_expand "neon_vget_lane<mode>"
2556 [(match_operand:<V_ext> 0 "s_register_operand" "")
2557 (match_operand:VDQW 1 "s_register_operand" "")
2558 (match_operand:SI 2 "immediate_operand" "")
2559 (match_operand:SI 3 "immediate_operand" "")]
2562 HOST_WIDE_INT magic = INTVAL (operands[3]);
2565 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2567 if (BYTES_BIG_ENDIAN)
2569 /* The intrinsics are defined in terms of a model where the
2570 element ordering in memory is vldm order, whereas the generic
2571 RTL is defined in terms of a model where the element ordering
2572 in memory is array order. Convert the lane number to conform
2574 unsigned int elt = INTVAL (operands[2]);
2575 unsigned int reg_nelts
2576 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2577 elt ^= reg_nelts - 1;
2578 operands[2] = GEN_INT (elt);
2581 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2582 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2585 if ((magic & 1) != 0)
2586 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2589 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2596 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2599 (define_expand "neon_vget_lanedi"
2600 [(match_operand:DI 0 "s_register_operand" "=r")
2601 (match_operand:DI 1 "s_register_operand" "w")
2602 (match_operand:SI 2 "immediate_operand" "i")
2603 (match_operand:SI 3 "immediate_operand" "i")]
2606 neon_lane_bounds (operands[2], 0, 1);
2607 emit_move_insn (operands[0], operands[1]);
2611 (define_expand "neon_vget_lanev2di"
2612 [(match_operand:DI 0 "s_register_operand" "=r")
2613 (match_operand:V2DI 1 "s_register_operand" "w")
2614 (match_operand:SI 2 "immediate_operand" "i")
2615 (match_operand:SI 3 "immediate_operand" "i")]
2618 neon_lane_bounds (operands[2], 0, 2);
2619 emit_insn (gen_vec_extractv2di (operands[0], operands[1], operands[2]));
2623 (define_expand "neon_vset_lane<mode>"
2624 [(match_operand:VDQ 0 "s_register_operand" "=w")
2625 (match_operand:<V_elem> 1 "s_register_operand" "r")
2626 (match_operand:VDQ 2 "s_register_operand" "0")
2627 (match_operand:SI 3 "immediate_operand" "i")]
2630 unsigned int elt = INTVAL (operands[3]);
2631 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2633 if (BYTES_BIG_ENDIAN)
2635 unsigned int reg_nelts
2636 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2637 elt ^= reg_nelts - 1;
2640 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
2641 GEN_INT (1 << elt), operands[2]));
2645 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2647 (define_expand "neon_vset_lanedi"
2648 [(match_operand:DI 0 "s_register_operand" "=w")
2649 (match_operand:DI 1 "s_register_operand" "r")
2650 (match_operand:DI 2 "s_register_operand" "0")
2651 (match_operand:SI 3 "immediate_operand" "i")]
2654 neon_lane_bounds (operands[3], 0, 1);
2655 emit_move_insn (operands[0], operands[1]);
2659 (define_expand "neon_vcreate<mode>"
2660 [(match_operand:VDX 0 "s_register_operand" "")
2661 (match_operand:DI 1 "general_operand" "")]
2664 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2665 emit_move_insn (operands[0], src);
2669 (define_insn "neon_vdup_n<mode>"
2670 [(set (match_operand:VX 0 "s_register_operand" "=w")
2671 (vec_duplicate:VX (match_operand:<V_elem> 1 "s_register_operand" "r")))]
2673 "vdup%?.<V_sz_elem>\t%<V_reg>0, %1"
2674 ;; Assume this schedules like vmov.
2675 [(set_attr "predicable" "yes")
2676 (set_attr "neon_type" "neon_bp_simple")]
2679 (define_insn "neon_vdup_n<mode>"
2680 [(set (match_operand:V32 0 "s_register_operand" "=w,w")
2681 (vec_duplicate:V32 (match_operand:<V_elem> 1 "s_register_operand" "r,t")))]
2684 vdup%?.<V_sz_elem>\t%<V_reg>0, %1
2685 vdup%?.<V_sz_elem>\t%<V_reg>0, %y1"
2686 ;; Assume this schedules like vmov.
2687 [(set_attr "predicable" "yes")
2688 (set_attr "neon_type" "neon_bp_simple")]
2691 (define_expand "neon_vdup_ndi"
2692 [(match_operand:DI 0 "s_register_operand" "=w")
2693 (match_operand:DI 1 "s_register_operand" "r")]
2696 emit_move_insn (operands[0], operands[1]);
2701 (define_insn "neon_vdup_nv2di"
2702 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
2703 (vec_duplicate:V2DI (match_operand:DI 1 "s_register_operand" "r,w")))]
2706 vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1
2707 vmov%?\t%e0, %P1\;vmov%?\t%f0, %P1"
2708 [(set_attr "predicable" "yes")
2709 (set_attr "length" "8")
2710 (set_attr "neon_type" "neon_bp_simple")]
2713 (define_insn "neon_vdup_lane<mode>_internal"
2714 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2716 (vec_select:<V_elem>
2717 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
2718 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2721 if (BYTES_BIG_ENDIAN)
2723 int elt = INTVAL (operands[2]);
2724 elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
2725 operands[2] = GEN_INT (elt);
2728 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
2730 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
2732 ;; Assume this schedules like vmov.
2733 [(set_attr "neon_type" "neon_bp_simple")]
2736 (define_expand "neon_vdup_lane<mode>"
2737 [(match_operand:VDQW 0 "s_register_operand" "=w")
2738 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
2739 (match_operand:SI 2 "immediate_operand" "i")]
2742 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_double_vector_mode>mode));
2743 if (BYTES_BIG_ENDIAN)
2745 unsigned int elt = INTVAL (operands[2]);
2746 unsigned int reg_nelts
2747 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<V_double_vector_mode>mode));
2748 elt ^= reg_nelts - 1;
2749 operands[2] = GEN_INT (elt);
2751 emit_insn (gen_neon_vdup_lane<mode>_internal (operands[0], operands[1],
2756 ; Scalar index is ignored, since only zero is valid here.
2757 (define_expand "neon_vdup_lanedi"
2758 [(match_operand:DI 0 "s_register_operand" "=w")
2759 (match_operand:DI 1 "s_register_operand" "w")
2760 (match_operand:SI 2 "immediate_operand" "i")]
2763 neon_lane_bounds (operands[2], 0, 1);
2764 emit_move_insn (operands[0], operands[1]);
2768 ; Likewise for v2di, as the DImode second operand has only a single element.
2769 (define_expand "neon_vdup_lanev2di"
2770 [(match_operand:V2DI 0 "s_register_operand" "=w")
2771 (match_operand:DI 1 "s_register_operand" "w")
2772 (match_operand:SI 2 "immediate_operand" "i")]
2775 neon_lane_bounds (operands[2], 0, 1);
2776 emit_insn (gen_neon_vdup_nv2di (operands[0], operands[1]));
2780 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2782 ;; FIXME: A different implementation of this builtin could make it much
2783 ;; more likely that we wouldn't actually need to output anything (we could make
2784 ;; it so that the reg allocator puts things in the right places magically
2785 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
2787 (define_insn "neon_vcombine<mode>"
2788 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
2789 (vec_concat:<V_DOUBLE> (match_operand:VDX 1 "s_register_operand" "w")
2790 (match_operand:VDX 2 "s_register_operand" "w")))]
2793 int dest = REGNO (operands[0]);
2794 int src1 = REGNO (operands[1]);
2795 int src2 = REGNO (operands[2]);
2798 if (src1 == dest && src2 == dest + 2)
2800 else if (src2 == dest && src1 == dest + 2)
2801 /* Special case of reversed high/low parts. */
2802 return "vswp\t%P1, %P2";
2804 destlo = gen_rtx_REG (<MODE>mode, dest);
2806 if (!reg_overlap_mentioned_p (operands[2], destlo))
2808 /* Try to avoid unnecessary moves if part of the result is in the right
2811 output_asm_insn ("vmov\t%e0, %P1", operands);
2812 if (src2 != dest + 2)
2813 output_asm_insn ("vmov\t%f0, %P2", operands);
2817 if (src2 != dest + 2)
2818 output_asm_insn ("vmov\t%f0, %P2", operands);
2820 output_asm_insn ("vmov\t%e0, %P1", operands);
2825 ;; We set the neon_type attribute based on the vmov instructions above.
2826 [(set_attr "length" "8")
2827 (set_attr "neon_type" "neon_bp_simple")]
2830 (define_insn "neon_vget_highv16qi"
2831 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2832 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
2833 (parallel [(const_int 8) (const_int 9)
2834 (const_int 10) (const_int 11)
2835 (const_int 12) (const_int 13)
2836 (const_int 14) (const_int 15)])))]
2839 int dest = REGNO (operands[0]);
2840 int src = REGNO (operands[1]);
2842 if (dest != src + 2)
2843 return "vmov\t%P0, %f1";
2847 [(set_attr "neon_type" "neon_bp_simple")]
2850 (define_insn "neon_vget_highv8hi"
2851 [(set (match_operand:V4HI 0 "s_register_operand" "=w")
2852 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
2853 (parallel [(const_int 4) (const_int 5)
2854 (const_int 6) (const_int 7)])))]
2857 int dest = REGNO (operands[0]);
2858 int src = REGNO (operands[1]);
2860 if (dest != src + 2)
2861 return "vmov\t%P0, %f1";
2865 [(set_attr "neon_type" "neon_bp_simple")]
2868 (define_insn "neon_vget_highv4si"
2869 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
2870 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
2871 (parallel [(const_int 2) (const_int 3)])))]
2874 int dest = REGNO (operands[0]);
2875 int src = REGNO (operands[1]);
2877 if (dest != src + 2)
2878 return "vmov\t%P0, %f1";
2882 [(set_attr "neon_type" "neon_bp_simple")]
2885 (define_insn "neon_vget_highv4sf"
2886 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
2887 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
2888 (parallel [(const_int 2) (const_int 3)])))]
2891 int dest = REGNO (operands[0]);
2892 int src = REGNO (operands[1]);
2894 if (dest != src + 2)
2895 return "vmov\t%P0, %f1";
2899 [(set_attr "neon_type" "neon_bp_simple")]
2902 (define_insn "neon_vget_highv2di"
2903 [(set (match_operand:DI 0 "s_register_operand" "=w")
2904 (vec_select:DI (match_operand:V2DI 1 "s_register_operand" "w")
2905 (parallel [(const_int 1)])))]
2908 int dest = REGNO (operands[0]);
2909 int src = REGNO (operands[1]);
2911 if (dest != src + 2)
2912 return "vmov\t%P0, %f1";
2916 [(set_attr "neon_type" "neon_bp_simple")]
2919 (define_insn "neon_vget_lowv16qi"
2920 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2921 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
2922 (parallel [(const_int 0) (const_int 1)
2923 (const_int 2) (const_int 3)
2924 (const_int 4) (const_int 5)
2925 (const_int 6) (const_int 7)])))]
2928 int dest = REGNO (operands[0]);
2929 int src = REGNO (operands[1]);
2932 return "vmov\t%P0, %e1";
2936 [(set_attr "neon_type" "neon_bp_simple")]
2939 (define_insn "neon_vget_lowv8hi"
2940 [(set (match_operand:V4HI 0 "s_register_operand" "=w")
2941 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
2942 (parallel [(const_int 0) (const_int 1)
2943 (const_int 2) (const_int 3)])))]
2946 int dest = REGNO (operands[0]);
2947 int src = REGNO (operands[1]);
2950 return "vmov\t%P0, %e1";
2954 [(set_attr "neon_type" "neon_bp_simple")]
2957 (define_insn "neon_vget_lowv4si"
2958 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
2959 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
2960 (parallel [(const_int 0) (const_int 1)])))]
2963 int dest = REGNO (operands[0]);
2964 int src = REGNO (operands[1]);
2967 return "vmov\t%P0, %e1";
2971 [(set_attr "neon_type" "neon_bp_simple")]
2974 (define_insn "neon_vget_lowv4sf"
2975 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
2976 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
2977 (parallel [(const_int 0) (const_int 1)])))]
2980 int dest = REGNO (operands[0]);
2981 int src = REGNO (operands[1]);
2984 return "vmov\t%P0, %e1";
2988 [(set_attr "neon_type" "neon_bp_simple")]
2991 (define_insn "neon_vget_lowv2di"
2992 [(set (match_operand:DI 0 "s_register_operand" "=w")
2993 (vec_select:DI (match_operand:V2DI 1 "s_register_operand" "w")
2994 (parallel [(const_int 0)])))]
2997 int dest = REGNO (operands[0]);
2998 int src = REGNO (operands[1]);
3001 return "vmov\t%P0, %e1";
3005 [(set_attr "neon_type" "neon_bp_simple")]
3008 (define_insn "neon_vcvt<mode>"
3009 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3010 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3011 (match_operand:SI 2 "immediate_operand" "i")]
3014 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
3015 [(set (attr "neon_type")
3016 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3017 (const_string "neon_fp_vadd_ddd_vabs_dd")
3018 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3021 (define_insn "neon_vcvt<mode>"
3022 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3023 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3024 (match_operand:SI 2 "immediate_operand" "i")]
3027 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
3028 [(set (attr "neon_type")
3029 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3030 (const_string "neon_fp_vadd_ddd_vabs_dd")
3031 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3034 (define_insn "neon_vcvt_n<mode>"
3035 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3036 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3037 (match_operand:SI 2 "immediate_operand" "i")
3038 (match_operand:SI 3 "immediate_operand" "i")]
3042 neon_const_bounds (operands[2], 1, 33);
3043 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
3045 [(set (attr "neon_type")
3046 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3047 (const_string "neon_fp_vadd_ddd_vabs_dd")
3048 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3051 (define_insn "neon_vcvt_n<mode>"
3052 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3053 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3054 (match_operand:SI 2 "immediate_operand" "i")
3055 (match_operand:SI 3 "immediate_operand" "i")]
3059 neon_const_bounds (operands[2], 1, 33);
3060 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
3062 [(set (attr "neon_type")
3063 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3064 (const_string "neon_fp_vadd_ddd_vabs_dd")
3065 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3068 (define_insn "neon_vmovn<mode>"
3069 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3070 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3071 (match_operand:SI 2 "immediate_operand" "i")]
3074 "vmovn.<V_if_elem>\t%P0, %q1"
3075 [(set_attr "neon_type" "neon_bp_simple")]
3078 (define_insn "neon_vqmovn<mode>"
3079 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3080 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3081 (match_operand:SI 2 "immediate_operand" "i")]
3084 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
3085 [(set_attr "neon_type" "neon_shift_2")]
3088 (define_insn "neon_vqmovun<mode>"
3089 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3090 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3091 (match_operand:SI 2 "immediate_operand" "i")]
3094 "vqmovun.<V_s_elem>\t%P0, %q1"
3095 [(set_attr "neon_type" "neon_shift_2")]
3098 (define_insn "neon_vmovl<mode>"
3099 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3100 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3101 (match_operand:SI 2 "immediate_operand" "i")]
3104 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
3105 [(set_attr "neon_type" "neon_shift_1")]
3108 (define_insn "neon_vmul_lane<mode>"
3109 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3110 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
3111 (match_operand:VMD 2 "s_register_operand"
3112 "<scalar_mul_constraint>")
3113 (match_operand:SI 3 "immediate_operand" "i")
3114 (match_operand:SI 4 "immediate_operand" "i")]
3118 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3119 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
3121 [(set (attr "neon_type")
3122 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3123 (const_string "neon_fp_vmul_ddd")
3124 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3125 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3126 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
3129 (define_insn "neon_vmul_lane<mode>"
3130 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3131 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
3132 (match_operand:<V_HALF> 2 "s_register_operand"
3133 "<scalar_mul_constraint>")
3134 (match_operand:SI 3 "immediate_operand" "i")
3135 (match_operand:SI 4 "immediate_operand" "i")]
3139 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3140 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3142 [(set (attr "neon_type")
3143 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3144 (const_string "neon_fp_vmul_qqd")
3145 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3146 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3147 (const_string "neon_mul_qqd_32_scalar"))))]
3150 (define_insn "neon_vmull_lane<mode>"
3151 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3152 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3153 (match_operand:VMDI 2 "s_register_operand"
3154 "<scalar_mul_constraint>")
3155 (match_operand:SI 3 "immediate_operand" "i")
3156 (match_operand:SI 4 "immediate_operand" "i")]
3157 UNSPEC_VMULL_LANE))]
3160 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3161 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3163 [(set (attr "neon_type")
3164 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3165 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3166 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3169 (define_insn "neon_vqdmull_lane<mode>"
3170 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3171 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3172 (match_operand:VMDI 2 "s_register_operand"
3173 "<scalar_mul_constraint>")
3174 (match_operand:SI 3 "immediate_operand" "i")
3175 (match_operand:SI 4 "immediate_operand" "i")]
3176 UNSPEC_VQDMULL_LANE))]
3179 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3180 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3182 [(set (attr "neon_type")
3183 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3184 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3185 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3188 (define_insn "neon_vqdmulh_lane<mode>"
3189 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3190 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3191 (match_operand:<V_HALF> 2 "s_register_operand"
3192 "<scalar_mul_constraint>")
3193 (match_operand:SI 3 "immediate_operand" "i")
3194 (match_operand:SI 4 "immediate_operand" "i")]
3195 UNSPEC_VQDMULH_LANE))]
3198 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3199 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3201 [(set (attr "neon_type")
3202 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3203 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3204 (const_string "neon_mul_qqd_32_scalar")))]
3207 (define_insn "neon_vqdmulh_lane<mode>"
3208 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3209 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3210 (match_operand:VMDI 2 "s_register_operand"
3211 "<scalar_mul_constraint>")
3212 (match_operand:SI 3 "immediate_operand" "i")
3213 (match_operand:SI 4 "immediate_operand" "i")]
3214 UNSPEC_VQDMULH_LANE))]
3217 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3218 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3220 [(set (attr "neon_type")
3221 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3222 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3223 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3226 (define_insn "neon_vmla_lane<mode>"
3227 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3228 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3229 (match_operand:VMD 2 "s_register_operand" "w")
3230 (match_operand:VMD 3 "s_register_operand"
3231 "<scalar_mul_constraint>")
3232 (match_operand:SI 4 "immediate_operand" "i")
3233 (match_operand:SI 5 "immediate_operand" "i")]
3237 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3238 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3240 [(set (attr "neon_type")
3241 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3242 (const_string "neon_fp_vmla_ddd_scalar")
3243 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3244 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3245 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3248 (define_insn "neon_vmla_lane<mode>"
3249 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3250 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3251 (match_operand:VMQ 2 "s_register_operand" "w")
3252 (match_operand:<V_HALF> 3 "s_register_operand"
3253 "<scalar_mul_constraint>")
3254 (match_operand:SI 4 "immediate_operand" "i")
3255 (match_operand:SI 5 "immediate_operand" "i")]
3259 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3260 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3262 [(set (attr "neon_type")
3263 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3264 (const_string "neon_fp_vmla_qqq_scalar")
3265 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3266 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3267 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3270 (define_insn "neon_vmlal_lane<mode>"
3271 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3272 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3273 (match_operand:VMDI 2 "s_register_operand" "w")
3274 (match_operand:VMDI 3 "s_register_operand"
3275 "<scalar_mul_constraint>")
3276 (match_operand:SI 4 "immediate_operand" "i")
3277 (match_operand:SI 5 "immediate_operand" "i")]
3278 UNSPEC_VMLAL_LANE))]
3281 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3282 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3284 [(set (attr "neon_type")
3285 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3286 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3287 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3290 (define_insn "neon_vqdmlal_lane<mode>"
3291 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3292 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3293 (match_operand:VMDI 2 "s_register_operand" "w")
3294 (match_operand:VMDI 3 "s_register_operand"
3295 "<scalar_mul_constraint>")
3296 (match_operand:SI 4 "immediate_operand" "i")
3297 (match_operand:SI 5 "immediate_operand" "i")]
3298 UNSPEC_VQDMLAL_LANE))]
3301 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3302 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3304 [(set (attr "neon_type")
3305 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3306 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3307 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3310 (define_insn "neon_vmls_lane<mode>"
3311 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3312 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3313 (match_operand:VMD 2 "s_register_operand" "w")
3314 (match_operand:VMD 3 "s_register_operand"
3315 "<scalar_mul_constraint>")
3316 (match_operand:SI 4 "immediate_operand" "i")
3317 (match_operand:SI 5 "immediate_operand" "i")]
3321 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3322 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3324 [(set (attr "neon_type")
3325 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3326 (const_string "neon_fp_vmla_ddd_scalar")
3327 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3328 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3329 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3332 (define_insn "neon_vmls_lane<mode>"
3333 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3334 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3335 (match_operand:VMQ 2 "s_register_operand" "w")
3336 (match_operand:<V_HALF> 3 "s_register_operand"
3337 "<scalar_mul_constraint>")
3338 (match_operand:SI 4 "immediate_operand" "i")
3339 (match_operand:SI 5 "immediate_operand" "i")]
3343 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3344 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3346 [(set (attr "neon_type")
3347 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3348 (const_string "neon_fp_vmla_qqq_scalar")
3349 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3350 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3351 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3354 (define_insn "neon_vmlsl_lane<mode>"
3355 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3356 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3357 (match_operand:VMDI 2 "s_register_operand" "w")
3358 (match_operand:VMDI 3 "s_register_operand"
3359 "<scalar_mul_constraint>")
3360 (match_operand:SI 4 "immediate_operand" "i")
3361 (match_operand:SI 5 "immediate_operand" "i")]
3362 UNSPEC_VMLSL_LANE))]
3365 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3366 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3368 [(set (attr "neon_type")
3369 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3370 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3371 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3374 (define_insn "neon_vqdmlsl_lane<mode>"
3375 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3376 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3377 (match_operand:VMDI 2 "s_register_operand" "w")
3378 (match_operand:VMDI 3 "s_register_operand"
3379 "<scalar_mul_constraint>")
3380 (match_operand:SI 4 "immediate_operand" "i")
3381 (match_operand:SI 5 "immediate_operand" "i")]
3382 UNSPEC_VQDMLSL_LANE))]
3385 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3386 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3388 [(set (attr "neon_type")
3389 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3390 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3391 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3394 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3395 ; core register into a temp register, then use a scalar taken from that. This
3396 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3397 ; or extracted from another vector. The latter case it's currently better to
3398 ; use the "_lane" variant, and the former case can probably be implemented
3399 ; using vld1_lane, but that hasn't been done yet.
3401 (define_expand "neon_vmul_n<mode>"
3402 [(match_operand:VMD 0 "s_register_operand" "")
3403 (match_operand:VMD 1 "s_register_operand" "")
3404 (match_operand:<V_elem> 2 "s_register_operand" "")
3405 (match_operand:SI 3 "immediate_operand" "")]
3408 rtx tmp = gen_reg_rtx (<MODE>mode);
3409 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3410 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3411 const0_rtx, const0_rtx));
3415 (define_expand "neon_vmul_n<mode>"
3416 [(match_operand:VMQ 0 "s_register_operand" "")
3417 (match_operand:VMQ 1 "s_register_operand" "")
3418 (match_operand:<V_elem> 2 "s_register_operand" "")
3419 (match_operand:SI 3 "immediate_operand" "")]
3422 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3423 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3424 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3425 const0_rtx, const0_rtx));
3429 (define_expand "neon_vmull_n<mode>"
3430 [(match_operand:<V_widen> 0 "s_register_operand" "")
3431 (match_operand:VMDI 1 "s_register_operand" "")
3432 (match_operand:<V_elem> 2 "s_register_operand" "")
3433 (match_operand:SI 3 "immediate_operand" "")]
3436 rtx tmp = gen_reg_rtx (<MODE>mode);
3437 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3438 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3439 const0_rtx, operands[3]));
3443 (define_expand "neon_vqdmull_n<mode>"
3444 [(match_operand:<V_widen> 0 "s_register_operand" "")
3445 (match_operand:VMDI 1 "s_register_operand" "")
3446 (match_operand:<V_elem> 2 "s_register_operand" "")
3447 (match_operand:SI 3 "immediate_operand" "")]
3450 rtx tmp = gen_reg_rtx (<MODE>mode);
3451 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3452 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3453 const0_rtx, const0_rtx));
3457 (define_expand "neon_vqdmulh_n<mode>"
3458 [(match_operand:VMDI 0 "s_register_operand" "")
3459 (match_operand:VMDI 1 "s_register_operand" "")
3460 (match_operand:<V_elem> 2 "s_register_operand" "")
3461 (match_operand:SI 3 "immediate_operand" "")]
3464 rtx tmp = gen_reg_rtx (<MODE>mode);
3465 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3466 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3467 const0_rtx, operands[3]));
3471 (define_expand "neon_vqdmulh_n<mode>"
3472 [(match_operand:VMQI 0 "s_register_operand" "")
3473 (match_operand:VMQI 1 "s_register_operand" "")
3474 (match_operand:<V_elem> 2 "s_register_operand" "")
3475 (match_operand:SI 3 "immediate_operand" "")]
3478 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3479 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3480 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3481 const0_rtx, operands[3]));
3485 (define_expand "neon_vmla_n<mode>"
3486 [(match_operand:VMD 0 "s_register_operand" "")
3487 (match_operand:VMD 1 "s_register_operand" "")
3488 (match_operand:VMD 2 "s_register_operand" "")
3489 (match_operand:<V_elem> 3 "s_register_operand" "")
3490 (match_operand:SI 4 "immediate_operand" "")]
3493 rtx tmp = gen_reg_rtx (<MODE>mode);
3494 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3495 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3496 tmp, const0_rtx, operands[4]));
3500 (define_expand "neon_vmla_n<mode>"
3501 [(match_operand:VMQ 0 "s_register_operand" "")
3502 (match_operand:VMQ 1 "s_register_operand" "")
3503 (match_operand:VMQ 2 "s_register_operand" "")
3504 (match_operand:<V_elem> 3 "s_register_operand" "")
3505 (match_operand:SI 4 "immediate_operand" "")]
3508 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3509 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3510 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3511 tmp, const0_rtx, operands[4]));
3515 (define_expand "neon_vmlal_n<mode>"
3516 [(match_operand:<V_widen> 0 "s_register_operand" "")
3517 (match_operand:<V_widen> 1 "s_register_operand" "")
3518 (match_operand:VMDI 2 "s_register_operand" "")
3519 (match_operand:<V_elem> 3 "s_register_operand" "")
3520 (match_operand:SI 4 "immediate_operand" "")]
3523 rtx tmp = gen_reg_rtx (<MODE>mode);
3524 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3525 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3526 tmp, const0_rtx, operands[4]));
3530 (define_expand "neon_vqdmlal_n<mode>"
3531 [(match_operand:<V_widen> 0 "s_register_operand" "")
3532 (match_operand:<V_widen> 1 "s_register_operand" "")
3533 (match_operand:VMDI 2 "s_register_operand" "")
3534 (match_operand:<V_elem> 3 "s_register_operand" "")
3535 (match_operand:SI 4 "immediate_operand" "")]
3538 rtx tmp = gen_reg_rtx (<MODE>mode);
3539 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3540 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3541 tmp, const0_rtx, operands[4]));
3545 (define_expand "neon_vmls_n<mode>"
3546 [(match_operand:VMD 0 "s_register_operand" "")
3547 (match_operand:VMD 1 "s_register_operand" "")
3548 (match_operand:VMD 2 "s_register_operand" "")
3549 (match_operand:<V_elem> 3 "s_register_operand" "")
3550 (match_operand:SI 4 "immediate_operand" "")]
3553 rtx tmp = gen_reg_rtx (<MODE>mode);
3554 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3555 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3556 tmp, const0_rtx, operands[4]));
3560 (define_expand "neon_vmls_n<mode>"
3561 [(match_operand:VMQ 0 "s_register_operand" "")
3562 (match_operand:VMQ 1 "s_register_operand" "")
3563 (match_operand:VMQ 2 "s_register_operand" "")
3564 (match_operand:<V_elem> 3 "s_register_operand" "")
3565 (match_operand:SI 4 "immediate_operand" "")]
3568 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3569 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3570 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3571 tmp, const0_rtx, operands[4]));
3575 (define_expand "neon_vmlsl_n<mode>"
3576 [(match_operand:<V_widen> 0 "s_register_operand" "")
3577 (match_operand:<V_widen> 1 "s_register_operand" "")
3578 (match_operand:VMDI 2 "s_register_operand" "")
3579 (match_operand:<V_elem> 3 "s_register_operand" "")
3580 (match_operand:SI 4 "immediate_operand" "")]
3583 rtx tmp = gen_reg_rtx (<MODE>mode);
3584 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3585 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3586 tmp, const0_rtx, operands[4]));
3590 (define_expand "neon_vqdmlsl_n<mode>"
3591 [(match_operand:<V_widen> 0 "s_register_operand" "")
3592 (match_operand:<V_widen> 1 "s_register_operand" "")
3593 (match_operand:VMDI 2 "s_register_operand" "")
3594 (match_operand:<V_elem> 3 "s_register_operand" "")
3595 (match_operand:SI 4 "immediate_operand" "")]
3598 rtx tmp = gen_reg_rtx (<MODE>mode);
3599 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3600 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3601 tmp, const0_rtx, operands[4]));
3605 (define_insn "neon_vext<mode>"
3606 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3607 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3608 (match_operand:VDQX 2 "s_register_operand" "w")
3609 (match_operand:SI 3 "immediate_operand" "i")]
3613 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3614 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3616 [(set (attr "neon_type")
3617 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3618 (const_string "neon_bp_simple")
3619 (const_string "neon_bp_2cycle")))]
3622 (define_insn "neon_vrev64<mode>"
3623 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3624 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3625 (match_operand:SI 2 "immediate_operand" "i")]
3628 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3629 [(set_attr "neon_type" "neon_bp_simple")]
3632 (define_insn "neon_vrev32<mode>"
3633 [(set (match_operand:VX 0 "s_register_operand" "=w")
3634 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3635 (match_operand:SI 2 "immediate_operand" "i")]
3638 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3639 [(set_attr "neon_type" "neon_bp_simple")]
3642 (define_insn "neon_vrev16<mode>"
3643 [(set (match_operand:VE 0 "s_register_operand" "=w")
3644 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3645 (match_operand:SI 2 "immediate_operand" "i")]
3648 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3649 [(set_attr "neon_type" "neon_bp_simple")]
3652 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3653 ; allocation. For an intrinsic of form:
3654 ; rD = vbsl_* (rS, rN, rM)
3655 ; We can use any of:
3656 ; vbsl rS, rN, rM (if D = S)
3657 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3658 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3660 (define_insn "neon_vbsl<mode>_internal"
3661 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3662 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3663 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3664 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3668 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3669 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3670 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3671 [(set_attr "neon_type" "neon_int_1")]
3674 (define_expand "neon_vbsl<mode>"
3675 [(set (match_operand:VDQX 0 "s_register_operand" "")
3676 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3677 (match_operand:VDQX 2 "s_register_operand" "")
3678 (match_operand:VDQX 3 "s_register_operand" "")]
3682 /* We can't alias operands together if they have different modes. */
3683 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3686 (define_insn "neon_vshl<mode>"
3687 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3688 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3689 (match_operand:VDQIX 2 "s_register_operand" "w")
3690 (match_operand:SI 3 "immediate_operand" "i")]
3693 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3694 [(set (attr "neon_type")
3695 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3696 (const_string "neon_vshl_ddd")
3697 (const_string "neon_shift_3")))]
3700 (define_insn "neon_vqshl<mode>"
3701 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3702 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3703 (match_operand:VDQIX 2 "s_register_operand" "w")
3704 (match_operand:SI 3 "immediate_operand" "i")]
3707 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3708 [(set (attr "neon_type")
3709 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3710 (const_string "neon_shift_2")
3711 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3714 (define_insn "neon_vshr_n<mode>"
3715 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3716 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3717 (match_operand:SI 2 "immediate_operand" "i")
3718 (match_operand:SI 3 "immediate_operand" "i")]
3722 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3723 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3725 [(set_attr "neon_type" "neon_shift_1")]
3728 (define_insn "neon_vshrn_n<mode>"
3729 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3730 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3731 (match_operand:SI 2 "immediate_operand" "i")
3732 (match_operand:SI 3 "immediate_operand" "i")]
3736 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3737 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3739 [(set_attr "neon_type" "neon_shift_1")]
3742 (define_insn "neon_vqshrn_n<mode>"
3743 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3744 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3745 (match_operand:SI 2 "immediate_operand" "i")
3746 (match_operand:SI 3 "immediate_operand" "i")]
3750 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3751 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3753 [(set_attr "neon_type" "neon_shift_2")]
3756 (define_insn "neon_vqshrun_n<mode>"
3757 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3758 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3759 (match_operand:SI 2 "immediate_operand" "i")
3760 (match_operand:SI 3 "immediate_operand" "i")]
3764 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3765 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3767 [(set_attr "neon_type" "neon_shift_2")]
3770 (define_insn "neon_vshl_n<mode>"
3771 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3772 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3773 (match_operand:SI 2 "immediate_operand" "i")
3774 (match_operand:SI 3 "immediate_operand" "i")]
3778 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3779 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
3781 [(set_attr "neon_type" "neon_shift_1")]
3784 (define_insn "neon_vqshl_n<mode>"
3785 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3786 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3787 (match_operand:SI 2 "immediate_operand" "i")
3788 (match_operand:SI 3 "immediate_operand" "i")]
3792 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3793 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3795 [(set_attr "neon_type" "neon_shift_2")]
3798 (define_insn "neon_vqshlu_n<mode>"
3799 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3800 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3801 (match_operand:SI 2 "immediate_operand" "i")
3802 (match_operand:SI 3 "immediate_operand" "i")]
3806 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3807 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3809 [(set_attr "neon_type" "neon_shift_2")]
3812 (define_insn "neon_vshll_n<mode>"
3813 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3814 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3815 (match_operand:SI 2 "immediate_operand" "i")
3816 (match_operand:SI 3 "immediate_operand" "i")]
3820 /* The boundaries are: 0 < imm <= size. */
3821 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
3822 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
3824 [(set_attr "neon_type" "neon_shift_1")]
3827 (define_insn "neon_vsra_n<mode>"
3828 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3829 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3830 (match_operand:VDQIX 2 "s_register_operand" "w")
3831 (match_operand:SI 3 "immediate_operand" "i")
3832 (match_operand:SI 4 "immediate_operand" "i")]
3836 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3837 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3839 [(set_attr "neon_type" "neon_vsra_vrsra")]
3842 (define_insn "neon_vsri_n<mode>"
3843 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3844 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3845 (match_operand:VDQIX 2 "s_register_operand" "w")
3846 (match_operand:SI 3 "immediate_operand" "i")]
3850 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3851 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3853 [(set (attr "neon_type")
3854 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3855 (const_string "neon_shift_1")
3856 (const_string "neon_shift_3")))]
3859 (define_insn "neon_vsli_n<mode>"
3860 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3861 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3862 (match_operand:VDQIX 2 "s_register_operand" "w")
3863 (match_operand:SI 3 "immediate_operand" "i")]
3867 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
3868 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3870 [(set (attr "neon_type")
3871 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3872 (const_string "neon_shift_1")
3873 (const_string "neon_shift_3")))]
3876 (define_insn "neon_vtbl1v8qi"
3877 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3878 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
3879 (match_operand:V8QI 2 "s_register_operand" "w")]
3882 "vtbl.8\t%P0, {%P1}, %P2"
3883 [(set_attr "neon_type" "neon_bp_2cycle")]
3886 (define_insn "neon_vtbl2v8qi"
3887 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3888 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
3889 (match_operand:V8QI 2 "s_register_operand" "w")]
3894 int tabbase = REGNO (operands[1]);
3896 ops[0] = operands[0];
3897 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3898 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3899 ops[3] = operands[2];
3900 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
3904 [(set_attr "neon_type" "neon_bp_2cycle")]
3907 (define_insn "neon_vtbl3v8qi"
3908 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3909 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
3910 (match_operand:V8QI 2 "s_register_operand" "w")]
3915 int tabbase = REGNO (operands[1]);
3917 ops[0] = operands[0];
3918 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3919 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3920 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3921 ops[4] = operands[2];
3922 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3926 [(set_attr "neon_type" "neon_bp_3cycle")]
3929 (define_insn "neon_vtbl4v8qi"
3930 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3931 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
3932 (match_operand:V8QI 2 "s_register_operand" "w")]
3937 int tabbase = REGNO (operands[1]);
3939 ops[0] = operands[0];
3940 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3941 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3942 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3943 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
3944 ops[5] = operands[2];
3945 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
3949 [(set_attr "neon_type" "neon_bp_3cycle")]
3952 (define_insn "neon_vtbx1v8qi"
3953 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3954 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3955 (match_operand:V8QI 2 "s_register_operand" "w")
3956 (match_operand:V8QI 3 "s_register_operand" "w")]
3959 "vtbx.8\t%P0, {%P2}, %P3"
3960 [(set_attr "neon_type" "neon_bp_2cycle")]
3963 (define_insn "neon_vtbx2v8qi"
3964 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3965 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3966 (match_operand:TI 2 "s_register_operand" "w")
3967 (match_operand:V8QI 3 "s_register_operand" "w")]
3972 int tabbase = REGNO (operands[2]);
3974 ops[0] = operands[0];
3975 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3976 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3977 ops[3] = operands[3];
3978 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
3982 [(set_attr "neon_type" "neon_bp_2cycle")]
3985 (define_insn "neon_vtbx3v8qi"
3986 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3987 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3988 (match_operand:EI 2 "s_register_operand" "w")
3989 (match_operand:V8QI 3 "s_register_operand" "w")]
3994 int tabbase = REGNO (operands[2]);
3996 ops[0] = operands[0];
3997 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3998 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3999 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4000 ops[4] = operands[3];
4001 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4005 [(set_attr "neon_type" "neon_bp_3cycle")]
4008 (define_insn "neon_vtbx4v8qi"
4009 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4010 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4011 (match_operand:OI 2 "s_register_operand" "w")
4012 (match_operand:V8QI 3 "s_register_operand" "w")]
4017 int tabbase = REGNO (operands[2]);
4019 ops[0] = operands[0];
4020 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4021 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4022 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4023 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4024 ops[5] = operands[3];
4025 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4029 [(set_attr "neon_type" "neon_bp_3cycle")]
4032 (define_insn "neon_vtrn<mode>_internal"
4033 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4034 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4036 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4037 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4040 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4041 [(set (attr "neon_type")
4042 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4043 (const_string "neon_bp_simple")
4044 (const_string "neon_bp_3cycle")))]
4047 (define_expand "neon_vtrn<mode>"
4048 [(match_operand:SI 0 "s_register_operand" "r")
4049 (match_operand:VDQW 1 "s_register_operand" "w")
4050 (match_operand:VDQW 2 "s_register_operand" "w")]
4053 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
4054 operands[0], operands[1], operands[2]);
4058 (define_insn "neon_vzip<mode>_internal"
4059 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4060 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4062 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4063 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4066 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4067 [(set (attr "neon_type")
4068 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4069 (const_string "neon_bp_simple")
4070 (const_string "neon_bp_3cycle")))]
4073 (define_expand "neon_vzip<mode>"
4074 [(match_operand:SI 0 "s_register_operand" "r")
4075 (match_operand:VDQW 1 "s_register_operand" "w")
4076 (match_operand:VDQW 2 "s_register_operand" "w")]
4079 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
4080 operands[0], operands[1], operands[2]);
4084 (define_insn "neon_vuzp<mode>_internal"
4085 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4086 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
4088 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4089 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
4092 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4093 [(set (attr "neon_type")
4094 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
4095 (const_string "neon_bp_simple")
4096 (const_string "neon_bp_3cycle")))]
4099 (define_expand "neon_vuzp<mode>"
4100 [(match_operand:SI 0 "s_register_operand" "r")
4101 (match_operand:VDQW 1 "s_register_operand" "w")
4102 (match_operand:VDQW 2 "s_register_operand" "w")]
4105 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
4106 operands[0], operands[1], operands[2]);
4110 (define_expand "neon_vreinterpretv8qi<mode>"
4111 [(match_operand:V8QI 0 "s_register_operand" "")
4112 (match_operand:VDX 1 "s_register_operand" "")]
4115 neon_reinterpret (operands[0], operands[1]);
4119 (define_expand "neon_vreinterpretv4hi<mode>"
4120 [(match_operand:V4HI 0 "s_register_operand" "")
4121 (match_operand:VDX 1 "s_register_operand" "")]
4124 neon_reinterpret (operands[0], operands[1]);
4128 (define_expand "neon_vreinterpretv2si<mode>"
4129 [(match_operand:V2SI 0 "s_register_operand" "")
4130 (match_operand:VDX 1 "s_register_operand" "")]
4133 neon_reinterpret (operands[0], operands[1]);
4137 (define_expand "neon_vreinterpretv2sf<mode>"
4138 [(match_operand:V2SF 0 "s_register_operand" "")
4139 (match_operand:VDX 1 "s_register_operand" "")]
4142 neon_reinterpret (operands[0], operands[1]);
4146 (define_expand "neon_vreinterpretdi<mode>"
4147 [(match_operand:DI 0 "s_register_operand" "")
4148 (match_operand:VDX 1 "s_register_operand" "")]
4151 neon_reinterpret (operands[0], operands[1]);
4155 (define_expand "neon_vreinterpretv16qi<mode>"
4156 [(match_operand:V16QI 0 "s_register_operand" "")
4157 (match_operand:VQX 1 "s_register_operand" "")]
4160 neon_reinterpret (operands[0], operands[1]);
4164 (define_expand "neon_vreinterpretv8hi<mode>"
4165 [(match_operand:V8HI 0 "s_register_operand" "")
4166 (match_operand:VQX 1 "s_register_operand" "")]
4169 neon_reinterpret (operands[0], operands[1]);
4173 (define_expand "neon_vreinterpretv4si<mode>"
4174 [(match_operand:V4SI 0 "s_register_operand" "")
4175 (match_operand:VQX 1 "s_register_operand" "")]
4178 neon_reinterpret (operands[0], operands[1]);
4182 (define_expand "neon_vreinterpretv4sf<mode>"
4183 [(match_operand:V4SF 0 "s_register_operand" "")
4184 (match_operand:VQX 1 "s_register_operand" "")]
4187 neon_reinterpret (operands[0], operands[1]);
4191 (define_expand "neon_vreinterpretv2di<mode>"
4192 [(match_operand:V2DI 0 "s_register_operand" "")
4193 (match_operand:VQX 1 "s_register_operand" "")]
4196 neon_reinterpret (operands[0], operands[1]);
4200 (define_insn "neon_vld1<mode>"
4201 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4202 (unspec:VDQX [(mem:VDQX (match_operand:SI 1 "s_register_operand" "r"))]
4205 "vld1.<V_sz_elem>\t%h0, [%1]"
4206 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4209 (define_insn "neon_vld1_lane<mode>"
4210 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4211 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4212 (match_operand:VDX 2 "s_register_operand" "0")
4213 (match_operand:SI 3 "immediate_operand" "i")]
4217 HOST_WIDE_INT lane = INTVAL (operands[3]);
4218 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4219 if (lane < 0 || lane >= max)
4220 error ("lane out of range");
4222 return "vld1.<V_sz_elem>\t%P0, [%1]";
4224 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4226 [(set (attr "neon_type")
4227 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4228 (const_string "neon_vld1_1_2_regs")
4229 (const_string "neon_vld1_vld2_lane")))]
4232 (define_insn "neon_vld1_lane<mode>"
4233 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4234 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4235 (match_operand:VQX 2 "s_register_operand" "0")
4236 (match_operand:SI 3 "immediate_operand" "i")]
4240 HOST_WIDE_INT lane = INTVAL (operands[3]);
4241 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4242 int regno = REGNO (operands[0]);
4243 if (lane < 0 || lane >= max)
4244 error ("lane out of range");
4245 else if (lane >= max / 2)
4249 operands[3] = GEN_INT (lane);
4251 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4253 return "vld1.<V_sz_elem>\t%P0, [%1]";
4255 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4257 [(set (attr "neon_type")
4258 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4259 (const_string "neon_vld1_1_2_regs")
4260 (const_string "neon_vld1_vld2_lane")))]
4263 (define_insn "neon_vld1_dup<mode>"
4264 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4265 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4269 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4270 return "vld1.<V_sz_elem>\t{%P0[]}, [%1]";
4272 return "vld1.<V_sz_elem>\t%h0, [%1]";
4274 [(set (attr "neon_type")
4275 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4276 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4277 (const_string "neon_vld1_1_2_regs")))]
4280 (define_insn "neon_vld1_dup<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"))]
4286 if (GET_MODE_NUNITS (<MODE>mode) > 2)
4287 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4289 return "vld1.<V_sz_elem>\t%h0, [%1]";
4291 [(set (attr "neon_type")
4292 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4293 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4294 (const_string "neon_vld1_1_2_regs")))]
4297 (define_insn "neon_vst1<mode>"
4298 [(set (mem:VDQX (match_operand:SI 0 "s_register_operand" "r"))
4299 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4302 "vst1.<V_sz_elem>\t%h1, [%0]"
4303 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4305 (define_insn "neon_vst1_lane<mode>"
4306 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4307 (vec_select:<V_elem>
4308 (match_operand:VDX 1 "s_register_operand" "w")
4309 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4312 HOST_WIDE_INT lane = INTVAL (operands[2]);
4313 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4314 if (lane < 0 || lane >= max)
4315 error ("lane out of range");
4317 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4319 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4321 [(set (attr "neon_type")
4322 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4323 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4324 (const_string "neon_vst1_vst2_lane")))])
4326 (define_insn "neon_vst1_lane<mode>"
4327 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4328 (vec_select:<V_elem>
4329 (match_operand:VQX 1 "s_register_operand" "w")
4330 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4333 HOST_WIDE_INT lane = INTVAL (operands[2]);
4334 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4335 int regno = REGNO (operands[1]);
4336 if (lane < 0 || lane >= max)
4337 error ("lane out of range");
4338 else if (lane >= max / 2)
4342 operands[2] = GEN_INT (lane);
4344 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4346 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4348 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4350 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4353 (define_insn "neon_vld2<mode>"
4354 [(set (match_operand:TI 0 "s_register_operand" "=w")
4355 (unspec:TI [(mem:TI (match_operand:SI 1 "s_register_operand" "r"))
4356 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4360 if (<V_sz_elem> == 64)
4361 return "vld1.64\t%h0, [%1]";
4363 return "vld2.<V_sz_elem>\t%h0, [%1]";
4365 [(set (attr "neon_type")
4366 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4367 (const_string "neon_vld1_1_2_regs")
4368 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4371 (define_insn "neon_vld2<mode>"
4372 [(set (match_operand:OI 0 "s_register_operand" "=w")
4373 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4374 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4377 "vld2.<V_sz_elem>\t%h0, [%1]"
4378 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4380 (define_insn "neon_vld2_lane<mode>"
4381 [(set (match_operand:TI 0 "s_register_operand" "=w")
4382 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4383 (match_operand:TI 2 "s_register_operand" "0")
4384 (match_operand:SI 3 "immediate_operand" "i")
4385 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4389 HOST_WIDE_INT lane = INTVAL (operands[3]);
4390 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4391 int regno = REGNO (operands[0]);
4393 if (lane < 0 || lane >= max)
4394 error ("lane out of range");
4395 ops[0] = gen_rtx_REG (DImode, regno);
4396 ops[1] = gen_rtx_REG (DImode, regno + 2);
4397 ops[2] = operands[1];
4398 ops[3] = operands[3];
4399 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4402 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4405 (define_insn "neon_vld2_lane<mode>"
4406 [(set (match_operand:OI 0 "s_register_operand" "=w")
4407 (unspec:OI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4408 (match_operand:OI 2 "s_register_operand" "0")
4409 (match_operand:SI 3 "immediate_operand" "i")
4410 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4414 HOST_WIDE_INT lane = INTVAL (operands[3]);
4415 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4416 int regno = REGNO (operands[0]);
4418 if (lane < 0 || lane >= max)
4419 error ("lane out of range");
4420 else if (lane >= max / 2)
4425 ops[0] = gen_rtx_REG (DImode, regno);
4426 ops[1] = gen_rtx_REG (DImode, regno + 4);
4427 ops[2] = operands[1];
4428 ops[3] = GEN_INT (lane);
4429 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4432 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4435 (define_insn "neon_vld2_dup<mode>"
4436 [(set (match_operand:TI 0 "s_register_operand" "=w")
4437 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4438 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4442 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4443 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4445 return "vld1.<V_sz_elem>\t%h0, [%1]";
4447 [(set (attr "neon_type")
4448 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4449 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4450 (const_string "neon_vld1_1_2_regs")))]
4453 (define_insn "neon_vst2<mode>"
4454 [(set (mem:TI (match_operand:SI 0 "s_register_operand" "r"))
4455 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4456 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4460 if (<V_sz_elem> == 64)
4461 return "vst1.64\t%h1, [%0]";
4463 return "vst2.<V_sz_elem>\t%h1, [%0]";
4465 [(set (attr "neon_type")
4466 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4467 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4468 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4471 (define_insn "neon_vst2<mode>"
4472 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4473 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4474 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4477 "vst2.<V_sz_elem>\t%h1, [%0]"
4478 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4481 (define_insn "neon_vst2_lane<mode>"
4482 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4483 (unspec:<V_two_elem>
4484 [(match_operand:TI 1 "s_register_operand" "w")
4485 (match_operand:SI 2 "immediate_operand" "i")
4486 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4490 HOST_WIDE_INT lane = INTVAL (operands[2]);
4491 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4492 int regno = REGNO (operands[1]);
4494 if (lane < 0 || lane >= max)
4495 error ("lane out of range");
4496 ops[0] = operands[0];
4497 ops[1] = gen_rtx_REG (DImode, regno);
4498 ops[2] = gen_rtx_REG (DImode, regno + 2);
4499 ops[3] = operands[2];
4500 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4503 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4506 (define_insn "neon_vst2_lane<mode>"
4507 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4508 (unspec:<V_two_elem>
4509 [(match_operand:OI 1 "s_register_operand" "w")
4510 (match_operand:SI 2 "immediate_operand" "i")
4511 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4515 HOST_WIDE_INT lane = INTVAL (operands[2]);
4516 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4517 int regno = REGNO (operands[1]);
4519 if (lane < 0 || lane >= max)
4520 error ("lane out of range");
4521 else if (lane >= max / 2)
4526 ops[0] = operands[0];
4527 ops[1] = gen_rtx_REG (DImode, regno);
4528 ops[2] = gen_rtx_REG (DImode, regno + 4);
4529 ops[3] = GEN_INT (lane);
4530 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4533 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4536 (define_insn "neon_vld3<mode>"
4537 [(set (match_operand:EI 0 "s_register_operand" "=w")
4538 (unspec:EI [(mem:EI (match_operand:SI 1 "s_register_operand" "r"))
4539 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4543 if (<V_sz_elem> == 64)
4544 return "vld1.64\t%h0, [%1]";
4546 return "vld3.<V_sz_elem>\t%h0, [%1]";
4548 [(set (attr "neon_type")
4549 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4550 (const_string "neon_vld1_1_2_regs")
4551 (const_string "neon_vld3_vld4")))]
4554 (define_expand "neon_vld3<mode>"
4555 [(match_operand:CI 0 "s_register_operand" "=w")
4556 (match_operand:SI 1 "s_register_operand" "+r")
4557 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4560 emit_insn (gen_neon_vld3qa<mode> (operands[0], operands[0],
4561 operands[1], operands[1]));
4562 emit_insn (gen_neon_vld3qb<mode> (operands[0], operands[0],
4563 operands[1], operands[1]));
4567 (define_insn "neon_vld3qa<mode>"
4568 [(set (match_operand:CI 0 "s_register_operand" "=w")
4569 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4570 (match_operand:CI 1 "s_register_operand" "0")
4571 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4573 (set (match_operand:SI 2 "s_register_operand" "=r")
4574 (plus:SI (match_dup 3)
4578 int regno = REGNO (operands[0]);
4580 ops[0] = gen_rtx_REG (DImode, regno);
4581 ops[1] = gen_rtx_REG (DImode, regno + 4);
4582 ops[2] = gen_rtx_REG (DImode, regno + 8);
4583 ops[3] = operands[2];
4584 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4587 [(set_attr "neon_type" "neon_vld3_vld4")]
4590 (define_insn "neon_vld3qb<mode>"
4591 [(set (match_operand:CI 0 "s_register_operand" "=w")
4592 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4593 (match_operand:CI 1 "s_register_operand" "0")
4594 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4596 (set (match_operand:SI 2 "s_register_operand" "=r")
4597 (plus:SI (match_dup 3)
4601 int regno = REGNO (operands[0]);
4603 ops[0] = gen_rtx_REG (DImode, regno + 2);
4604 ops[1] = gen_rtx_REG (DImode, regno + 6);
4605 ops[2] = gen_rtx_REG (DImode, regno + 10);
4606 ops[3] = operands[2];
4607 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4610 [(set_attr "neon_type" "neon_vld3_vld4")]
4613 (define_insn "neon_vld3_lane<mode>"
4614 [(set (match_operand:EI 0 "s_register_operand" "=w")
4615 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4616 (match_operand:EI 2 "s_register_operand" "0")
4617 (match_operand:SI 3 "immediate_operand" "i")
4618 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4622 HOST_WIDE_INT lane = INTVAL (operands[3]);
4623 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4624 int regno = REGNO (operands[0]);
4626 if (lane < 0 || lane >= max)
4627 error ("lane out of range");
4628 ops[0] = gen_rtx_REG (DImode, regno);
4629 ops[1] = gen_rtx_REG (DImode, regno + 2);
4630 ops[2] = gen_rtx_REG (DImode, regno + 4);
4631 ops[3] = operands[1];
4632 ops[4] = operands[3];
4633 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4637 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4640 (define_insn "neon_vld3_lane<mode>"
4641 [(set (match_operand:CI 0 "s_register_operand" "=w")
4642 (unspec:CI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4643 (match_operand:CI 2 "s_register_operand" "0")
4644 (match_operand:SI 3 "immediate_operand" "i")
4645 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4649 HOST_WIDE_INT lane = INTVAL (operands[3]);
4650 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4651 int regno = REGNO (operands[0]);
4653 if (lane < 0 || lane >= max)
4654 error ("lane out of range");
4655 else if (lane >= max / 2)
4660 ops[0] = gen_rtx_REG (DImode, regno);
4661 ops[1] = gen_rtx_REG (DImode, regno + 4);
4662 ops[2] = gen_rtx_REG (DImode, regno + 8);
4663 ops[3] = operands[1];
4664 ops[4] = GEN_INT (lane);
4665 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4669 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4672 (define_insn "neon_vld3_dup<mode>"
4673 [(set (match_operand:EI 0 "s_register_operand" "=w")
4674 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4675 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4679 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4681 int regno = REGNO (operands[0]);
4683 ops[0] = gen_rtx_REG (DImode, regno);
4684 ops[1] = gen_rtx_REG (DImode, regno + 2);
4685 ops[2] = gen_rtx_REG (DImode, regno + 4);
4686 ops[3] = operands[1];
4687 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, [%3]", ops);
4691 return "vld1.<V_sz_elem>\t%h0, [%1]";
4693 [(set (attr "neon_type")
4694 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4695 (const_string "neon_vld3_vld4_all_lanes")
4696 (const_string "neon_vld1_1_2_regs")))])
4698 (define_insn "neon_vst3<mode>"
4699 [(set (mem:EI (match_operand:SI 0 "s_register_operand" "r"))
4700 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
4701 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4705 if (<V_sz_elem> == 64)
4706 return "vst1.64\t%h1, [%0]";
4708 return "vst3.<V_sz_elem>\t%h1, [%0]";
4710 [(set (attr "neon_type")
4711 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4712 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4713 (const_string "neon_vst2_4_regs_vst3_vst4")))])
4715 (define_expand "neon_vst3<mode>"
4716 [(match_operand:SI 0 "s_register_operand" "+r")
4717 (match_operand:CI 1 "s_register_operand" "w")
4718 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4721 emit_insn (gen_neon_vst3qa<mode> (operands[0], operands[0], operands[1]));
4722 emit_insn (gen_neon_vst3qb<mode> (operands[0], operands[0], operands[1]));
4726 (define_insn "neon_vst3qa<mode>"
4727 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4728 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4729 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4731 (set (match_operand:SI 0 "s_register_operand" "=r")
4732 (plus:SI (match_dup 1)
4736 int regno = REGNO (operands[2]);
4738 ops[0] = operands[0];
4739 ops[1] = gen_rtx_REG (DImode, regno);
4740 ops[2] = gen_rtx_REG (DImode, regno + 4);
4741 ops[3] = gen_rtx_REG (DImode, regno + 8);
4742 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4745 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4748 (define_insn "neon_vst3qb<mode>"
4749 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4750 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4751 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4753 (set (match_operand:SI 0 "s_register_operand" "=r")
4754 (plus:SI (match_dup 1)
4758 int regno = REGNO (operands[2]);
4760 ops[0] = operands[0];
4761 ops[1] = gen_rtx_REG (DImode, regno + 2);
4762 ops[2] = gen_rtx_REG (DImode, regno + 6);
4763 ops[3] = gen_rtx_REG (DImode, regno + 10);
4764 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4767 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4770 (define_insn "neon_vst3_lane<mode>"
4771 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4772 (unspec:<V_three_elem>
4773 [(match_operand:EI 1 "s_register_operand" "w")
4774 (match_operand:SI 2 "immediate_operand" "i")
4775 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4779 HOST_WIDE_INT lane = INTVAL (operands[2]);
4780 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4781 int regno = REGNO (operands[1]);
4783 if (lane < 0 || lane >= max)
4784 error ("lane out of range");
4785 ops[0] = operands[0];
4786 ops[1] = gen_rtx_REG (DImode, regno);
4787 ops[2] = gen_rtx_REG (DImode, regno + 2);
4788 ops[3] = gen_rtx_REG (DImode, regno + 4);
4789 ops[4] = operands[2];
4790 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4794 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4797 (define_insn "neon_vst3_lane<mode>"
4798 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4799 (unspec:<V_three_elem>
4800 [(match_operand:CI 1 "s_register_operand" "w")
4801 (match_operand:SI 2 "immediate_operand" "i")
4802 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4806 HOST_WIDE_INT lane = INTVAL (operands[2]);
4807 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4808 int regno = REGNO (operands[1]);
4810 if (lane < 0 || lane >= max)
4811 error ("lane out of range");
4812 else if (lane >= max / 2)
4817 ops[0] = operands[0];
4818 ops[1] = gen_rtx_REG (DImode, regno);
4819 ops[2] = gen_rtx_REG (DImode, regno + 4);
4820 ops[3] = gen_rtx_REG (DImode, regno + 8);
4821 ops[4] = GEN_INT (lane);
4822 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4826 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
4828 (define_insn "neon_vld4<mode>"
4829 [(set (match_operand:OI 0 "s_register_operand" "=w")
4830 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4831 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4835 if (<V_sz_elem> == 64)
4836 return "vld1.64\t%h0, [%1]";
4838 return "vld4.<V_sz_elem>\t%h0, [%1]";
4840 [(set (attr "neon_type")
4841 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4842 (const_string "neon_vld1_1_2_regs")
4843 (const_string "neon_vld3_vld4")))]
4846 (define_expand "neon_vld4<mode>"
4847 [(match_operand:XI 0 "s_register_operand" "=w")
4848 (match_operand:SI 1 "s_register_operand" "+r")
4849 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4852 emit_insn (gen_neon_vld4qa<mode> (operands[0], operands[0],
4853 operands[1], operands[1]));
4854 emit_insn (gen_neon_vld4qb<mode> (operands[0], operands[0],
4855 operands[1], operands[1]));
4859 (define_insn "neon_vld4qa<mode>"
4860 [(set (match_operand:XI 0 "s_register_operand" "=w")
4861 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4862 (match_operand:XI 1 "s_register_operand" "0")
4863 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4865 (set (match_operand:SI 2 "s_register_operand" "=r")
4866 (plus:SI (match_dup 3)
4870 int regno = REGNO (operands[0]);
4872 ops[0] = gen_rtx_REG (DImode, regno);
4873 ops[1] = gen_rtx_REG (DImode, regno + 4);
4874 ops[2] = gen_rtx_REG (DImode, regno + 8);
4875 ops[3] = gen_rtx_REG (DImode, regno + 12);
4876 ops[4] = operands[2];
4877 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4880 [(set_attr "neon_type" "neon_vld3_vld4")]
4883 (define_insn "neon_vld4qb<mode>"
4884 [(set (match_operand:XI 0 "s_register_operand" "=w")
4885 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4886 (match_operand:XI 1 "s_register_operand" "0")
4887 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4889 (set (match_operand:SI 2 "s_register_operand" "=r")
4890 (plus:SI (match_dup 3)
4894 int regno = REGNO (operands[0]);
4896 ops[0] = gen_rtx_REG (DImode, regno + 2);
4897 ops[1] = gen_rtx_REG (DImode, regno + 6);
4898 ops[2] = gen_rtx_REG (DImode, regno + 10);
4899 ops[3] = gen_rtx_REG (DImode, regno + 14);
4900 ops[4] = operands[2];
4901 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4904 [(set_attr "neon_type" "neon_vld3_vld4")]
4907 (define_insn "neon_vld4_lane<mode>"
4908 [(set (match_operand:OI 0 "s_register_operand" "=w")
4909 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4910 (match_operand:OI 2 "s_register_operand" "0")
4911 (match_operand:SI 3 "immediate_operand" "i")
4912 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4916 HOST_WIDE_INT lane = INTVAL (operands[3]);
4917 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4918 int regno = REGNO (operands[0]);
4920 if (lane < 0 || lane >= max)
4921 error ("lane out of range");
4922 ops[0] = gen_rtx_REG (DImode, regno);
4923 ops[1] = gen_rtx_REG (DImode, regno + 2);
4924 ops[2] = gen_rtx_REG (DImode, regno + 4);
4925 ops[3] = gen_rtx_REG (DImode, regno + 6);
4926 ops[4] = operands[1];
4927 ops[5] = operands[3];
4928 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4932 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4935 (define_insn "neon_vld4_lane<mode>"
4936 [(set (match_operand:XI 0 "s_register_operand" "=w")
4937 (unspec:XI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4938 (match_operand:XI 2 "s_register_operand" "0")
4939 (match_operand:SI 3 "immediate_operand" "i")
4940 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4944 HOST_WIDE_INT lane = INTVAL (operands[3]);
4945 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4946 int regno = REGNO (operands[0]);
4948 if (lane < 0 || lane >= max)
4949 error ("lane out of range");
4950 else if (lane >= max / 2)
4955 ops[0] = gen_rtx_REG (DImode, regno);
4956 ops[1] = gen_rtx_REG (DImode, regno + 4);
4957 ops[2] = gen_rtx_REG (DImode, regno + 8);
4958 ops[3] = gen_rtx_REG (DImode, regno + 12);
4959 ops[4] = operands[1];
4960 ops[5] = GEN_INT (lane);
4961 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4965 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4968 (define_insn "neon_vld4_dup<mode>"
4969 [(set (match_operand:OI 0 "s_register_operand" "=w")
4970 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4971 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4975 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4977 int regno = REGNO (operands[0]);
4979 ops[0] = gen_rtx_REG (DImode, regno);
4980 ops[1] = gen_rtx_REG (DImode, regno + 2);
4981 ops[2] = gen_rtx_REG (DImode, regno + 4);
4982 ops[3] = gen_rtx_REG (DImode, regno + 6);
4983 ops[4] = operands[1];
4984 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, [%4]",
4989 return "vld1.<V_sz_elem>\t%h0, [%1]";
4991 [(set (attr "neon_type")
4992 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4993 (const_string "neon_vld3_vld4_all_lanes")
4994 (const_string "neon_vld1_1_2_regs")))]
4997 (define_insn "neon_vst4<mode>"
4998 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4999 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
5000 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5004 if (<V_sz_elem> == 64)
5005 return "vst1.64\t%h1, [%0]";
5007 return "vst4.<V_sz_elem>\t%h1, [%0]";
5009 [(set (attr "neon_type")
5010 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5011 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5012 (const_string "neon_vst2_4_regs_vst3_vst4")))]
5015 (define_expand "neon_vst4<mode>"
5016 [(match_operand:SI 0 "s_register_operand" "+r")
5017 (match_operand:XI 1 "s_register_operand" "w")
5018 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5021 emit_insn (gen_neon_vst4qa<mode> (operands[0], operands[0], operands[1]));
5022 emit_insn (gen_neon_vst4qb<mode> (operands[0], operands[0], operands[1]));
5026 (define_insn "neon_vst4qa<mode>"
5027 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
5028 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
5029 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5031 (set (match_operand:SI 0 "s_register_operand" "=r")
5032 (plus:SI (match_dup 1)
5036 int regno = REGNO (operands[2]);
5038 ops[0] = operands[0];
5039 ops[1] = gen_rtx_REG (DImode, regno);
5040 ops[2] = gen_rtx_REG (DImode, regno + 4);
5041 ops[3] = gen_rtx_REG (DImode, regno + 8);
5042 ops[4] = gen_rtx_REG (DImode, regno + 12);
5043 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
5046 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5049 (define_insn "neon_vst4qb<mode>"
5050 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
5051 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
5052 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5054 (set (match_operand:SI 0 "s_register_operand" "=r")
5055 (plus:SI (match_dup 1)
5059 int regno = REGNO (operands[2]);
5061 ops[0] = operands[0];
5062 ops[1] = gen_rtx_REG (DImode, regno + 2);
5063 ops[2] = gen_rtx_REG (DImode, regno + 6);
5064 ops[3] = gen_rtx_REG (DImode, regno + 10);
5065 ops[4] = gen_rtx_REG (DImode, regno + 14);
5066 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
5069 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5072 (define_insn "neon_vst4_lane<mode>"
5073 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
5074 (unspec:<V_four_elem>
5075 [(match_operand:OI 1 "s_register_operand" "w")
5076 (match_operand:SI 2 "immediate_operand" "i")
5077 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5081 HOST_WIDE_INT lane = INTVAL (operands[2]);
5082 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5083 int regno = REGNO (operands[1]);
5085 if (lane < 0 || lane >= max)
5086 error ("lane out of range");
5087 ops[0] = operands[0];
5088 ops[1] = gen_rtx_REG (DImode, regno);
5089 ops[2] = gen_rtx_REG (DImode, regno + 2);
5090 ops[3] = gen_rtx_REG (DImode, regno + 4);
5091 ops[4] = gen_rtx_REG (DImode, regno + 6);
5092 ops[5] = operands[2];
5093 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
5097 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5100 (define_insn "neon_vst4_lane<mode>"
5101 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
5102 (unspec:<V_four_elem>
5103 [(match_operand:XI 1 "s_register_operand" "w")
5104 (match_operand:SI 2 "immediate_operand" "i")
5105 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5109 HOST_WIDE_INT lane = INTVAL (operands[2]);
5110 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5111 int regno = REGNO (operands[1]);
5113 if (lane < 0 || lane >= max)
5114 error ("lane out of range");
5115 else if (lane >= max / 2)
5120 ops[0] = operands[0];
5121 ops[1] = gen_rtx_REG (DImode, regno);
5122 ops[2] = gen_rtx_REG (DImode, regno + 4);
5123 ops[3] = gen_rtx_REG (DImode, regno + 8);
5124 ops[4] = gen_rtx_REG (DImode, regno + 12);
5125 ops[5] = GEN_INT (lane);
5126 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
5130 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5133 (define_expand "neon_vand<mode>"
5134 [(match_operand:VDQX 0 "s_register_operand" "")
5135 (match_operand:VDQX 1 "s_register_operand" "")
5136 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5137 (match_operand:SI 3 "immediate_operand" "")]
5140 emit_insn (gen_and<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5144 (define_expand "neon_vorr<mode>"
5145 [(match_operand:VDQX 0 "s_register_operand" "")
5146 (match_operand:VDQX 1 "s_register_operand" "")
5147 (match_operand:VDQX 2 "neon_logic_op2" "")
5148 (match_operand:SI 3 "immediate_operand" "")]
5151 emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5155 (define_expand "neon_veor<mode>"
5156 [(match_operand:VDQX 0 "s_register_operand" "")
5157 (match_operand:VDQX 1 "s_register_operand" "")
5158 (match_operand:VDQX 2 "s_register_operand" "")
5159 (match_operand:SI 3 "immediate_operand" "")]
5162 emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5166 (define_expand "neon_vbic<mode>"
5167 [(match_operand:VDQX 0 "s_register_operand" "")
5168 (match_operand:VDQX 1 "s_register_operand" "")
5169 (match_operand:VDQX 2 "neon_logic_op2" "")
5170 (match_operand:SI 3 "immediate_operand" "")]
5173 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5177 (define_expand "neon_vorn<mode>"
5178 [(match_operand:VDQX 0 "s_register_operand" "")
5179 (match_operand:VDQX 1 "s_register_operand" "")
5180 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5181 (match_operand:SI 3 "immediate_operand" "")]
5184 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));
5188 (define_insn "neon_vec_unpack<US>_lo_<mode>"
5189 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5190 (SE:<V_unpack> (vec_select:<V_HALF>
5191 (match_operand:VU 1 "register_operand" "w")
5192 (match_operand:VU 2 "vect_par_constant_low" ""))))]
5194 "vmovl.<US><V_sz_elem> %q0, %e1"
5195 [(set_attr "neon_type" "neon_shift_1")]
5198 (define_insn "neon_vec_unpack<US>_hi_<mode>"
5199 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5200 (SE:<V_unpack> (vec_select:<V_HALF>
5201 (match_operand:VU 1 "register_operand" "w")
5202 (match_operand:VU 2 "vect_par_constant_high" ""))))]
5204 "vmovl.<US><V_sz_elem> %q0, %f1"
5205 [(set_attr "neon_type" "neon_shift_1")]
5208 (define_expand "vec_unpack<US>_hi_<mode>"
5209 [(match_operand:<V_unpack> 0 "register_operand" "")
5210 (SE:<V_unpack> (match_operand:VU 1 "register_operand"))]
5213 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5216 for (i = 0; i < (<V_mode_nunits>/2); i++)
5217 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
5219 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5220 emit_insn (gen_neon_vec_unpack<US>_hi_<mode> (operands[0],
5227 (define_expand "vec_unpack<US>_lo_<mode>"
5228 [(match_operand:<V_unpack> 0 "register_operand" "")
5229 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))]
5232 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5235 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5236 RTVEC_ELT (v, i) = GEN_INT (i);
5237 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5238 emit_insn (gen_neon_vec_unpack<US>_lo_<mode> (operands[0],
5245 (define_insn "neon_vec_<US>mult_lo_<mode>"
5246 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5247 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5248 (match_operand:VU 1 "register_operand" "w")
5249 (match_operand:VU 2 "vect_par_constant_low" "")))
5250 (SE:<V_unpack> (vec_select:<V_HALF>
5251 (match_operand:VU 3 "register_operand" "w")
5254 "vmull.<US><V_sz_elem> %q0, %e1, %e3"
5255 [(set_attr "neon_type" "neon_shift_1")]
5258 (define_expand "vec_widen_<US>mult_lo_<mode>"
5259 [(match_operand:<V_unpack> 0 "register_operand" "")
5260 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5261 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5264 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5267 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5268 RTVEC_ELT (v, i) = GEN_INT (i);
5269 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5271 emit_insn (gen_neon_vec_<US>mult_lo_<mode> (operands[0],
5279 (define_insn "neon_vec_<US>mult_hi_<mode>"
5280 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5281 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5282 (match_operand:VU 1 "register_operand" "w")
5283 (match_operand:VU 2 "vect_par_constant_high" "")))
5284 (SE:<V_unpack> (vec_select:<V_HALF>
5285 (match_operand:VU 3 "register_operand" "w")
5288 "vmull.<US><V_sz_elem> %q0, %f1, %f3"
5289 [(set_attr "neon_type" "neon_shift_1")]
5292 (define_expand "vec_widen_<US>mult_hi_<mode>"
5293 [(match_operand:<V_unpack> 0 "register_operand" "")
5294 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5295 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5298 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5301 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5302 RTVEC_ELT (v, i) = GEN_INT (<V_mode_nunits>/2 + i);
5303 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5305 emit_insn (gen_neon_vec_<US>mult_hi_<mode> (operands[0],
5314 ;; Vectorize for non-neon-quad case
5315 (define_insn "neon_unpack<US>_<mode>"
5316 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5317 (SE:<V_widen> (match_operand:VDI 1 "register_operand" "")))]
5319 "vmovl.<US><V_sz_elem> %q0, %1"
5320 [(set_attr "neon_type" "neon_shift_1")]
5323 (define_expand "vec_unpack<US>_lo_<mode>"
5324 [(match_operand:<V_double_width> 0 "register_operand" "")
5325 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5328 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5329 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5330 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5336 (define_expand "vec_unpack<US>_hi_<mode>"
5337 [(match_operand:<V_double_width> 0 "register_operand" "")
5338 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5341 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5342 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5343 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5349 (define_insn "neon_vec_<US>mult_<mode>"
5350 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5351 (mult:<V_widen> (SE:<V_widen>
5352 (match_operand:VDI 1 "register_operand" "w"))
5354 (match_operand:VDI 2 "register_operand" "w"))))]
5356 "vmull.<US><V_sz_elem> %q0, %1, %2"
5357 [(set_attr "neon_type" "neon_shift_1")]
5360 (define_expand "vec_widen_<US>mult_hi_<mode>"
5361 [(match_operand:<V_double_width> 0 "register_operand" "")
5362 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5363 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5366 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5367 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5368 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5375 (define_expand "vec_widen_<US>mult_lo_<mode>"
5376 [(match_operand:<V_double_width> 0 "register_operand" "")
5377 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5378 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5381 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5382 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5383 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5390 (define_insn "vec_pack_trunc_<mode>"
5391 [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w")
5392 (vec_concat:<V_narrow_pack>
5393 (truncate:<V_narrow>
5394 (match_operand:VN 1 "register_operand" "w"))
5395 (truncate:<V_narrow>
5396 (match_operand:VN 2 "register_operand" "w"))))]
5398 "vmovn.i<V_sz_elem>\t%e0, %q1\n\tvmovn.i<V_sz_elem>\t%f0, %q2"
5399 [(set_attr "neon_type" "neon_shift_1")]
5402 ;; For the non-quad case.
5403 (define_insn "neon_vec_pack_trunc_<mode>"
5404 [(set (match_operand:<V_narrow> 0 "register_operand" "=w")
5405 (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "")))]
5407 "vmovn.i<V_sz_elem>\t%0, %q1"
5408 [(set_attr "neon_type" "neon_shift_1")]
5411 (define_expand "vec_pack_trunc_<mode>"
5412 [(match_operand:<V_narrow_pack> 0 "register_operand" "")
5413 (match_operand:VSHFT 1 "register_operand" "")
5414 (match_operand:VSHFT 2 "register_operand")]
5417 rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode);
5419 emit_insn (gen_move_lo_quad_<V_double> (tempreg, operands[1]));
5420 emit_insn (gen_move_hi_quad_<V_double> (tempreg, operands[2]));
5421 emit_insn (gen_neon_vec_pack_trunc_<V_double> (operands[0], tempreg));