1 ;; ARM NEON coprocessor Machine Description
2 ;; Copyright (C) 2006-2013 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/>.
22 ;; Attribute used to permit string comparisons against <VQH_mnem> in
23 ;; neon_type attribute definitions.
24 (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
26 (define_insn "*neon_mov<mode>"
27 [(set (match_operand:VDX 0 "nonimmediate_operand"
28 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
29 (match_operand:VDX 1 "general_operand"
30 " w,w, Dn,Uni, w, r, r, Usi,r"))]
32 && (register_operand (operands[0], <MODE>mode)
33 || register_operand (operands[1], <MODE>mode))"
35 if (which_alternative == 2)
38 static char templ[40];
40 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
41 &operands[1], &width);
43 gcc_assert (is_valid != 0);
46 return "vmov.f32\t%P0, %1 @ <mode>";
48 sprintf (templ, "vmov.i%d\t%%P0, %%x1 @ <mode>", width);
53 switch (which_alternative)
55 case 0: return "vmov\t%P0, %P1 @ <mode>";
56 case 1: case 3: return output_move_neon (operands);
57 case 2: gcc_unreachable ();
58 case 4: return "vmov\t%Q0, %R0, %P1 @ <mode>";
59 case 5: return "vmov\t%P0, %Q1, %R1 @ <mode>";
60 default: return output_move_double (operands, true, NULL);
63 [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
64 (set_attr "type" "*,f_stored,*,f_loadd,*,*,mov_reg,load2,store2")
65 (set_attr "length" "4,4,4,4,4,4,8,8,8")
66 (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*")
67 (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*")
68 (set_attr "neg_pool_range" "*,*,*,1004,*,*,*,1004,*")])
70 (define_insn "*neon_mov<mode>"
71 [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
72 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
73 (match_operand:VQXMOV 1 "general_operand"
74 " w,w, Dn,Uni, w, r, r, Usi, r"))]
76 && (register_operand (operands[0], <MODE>mode)
77 || register_operand (operands[1], <MODE>mode))"
79 if (which_alternative == 2)
82 static char templ[40];
84 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
85 &operands[1], &width);
87 gcc_assert (is_valid != 0);
90 return "vmov.f32\t%q0, %1 @ <mode>";
92 sprintf (templ, "vmov.i%d\t%%q0, %%1 @ <mode>", width);
97 switch (which_alternative)
99 case 0: return "vmov\t%q0, %q1 @ <mode>";
100 case 1: case 3: return output_move_neon (operands);
101 case 2: gcc_unreachable ();
102 case 4: return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1";
103 case 5: return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1";
104 default: return output_move_quad (operands);
107 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
108 neon_mrrc,neon_mcr_2_mcrr,*,*,*")
109 (set_attr "type" "*,*,*,*,*,*,mov_reg,load4,store4")
110 (set_attr "length" "4,8,4,8,8,8,16,8,16")
111 (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*")
112 (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*")
113 (set_attr "neg_pool_range" "*,*,*,996,*,*,*,996,*")])
115 (define_expand "movti"
116 [(set (match_operand:TI 0 "nonimmediate_operand" "")
117 (match_operand:TI 1 "general_operand" ""))]
120 if (can_create_pseudo_p ())
122 if (!REG_P (operands[0]))
123 operands[1] = force_reg (TImode, operands[1]);
127 (define_expand "mov<mode>"
128 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
129 (match_operand:VSTRUCT 1 "general_operand" ""))]
132 if (can_create_pseudo_p ())
134 if (!REG_P (operands[0]))
135 operands[1] = force_reg (<MODE>mode, operands[1]);
139 (define_insn "*neon_mov<mode>"
140 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
141 (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
143 && (register_operand (operands[0], <MODE>mode)
144 || register_operand (operands[1], <MODE>mode))"
146 switch (which_alternative)
149 case 1: case 2: return output_move_neon (operands);
150 default: gcc_unreachable ();
153 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
154 (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))])
157 [(set (match_operand:EI 0 "s_register_operand" "")
158 (match_operand:EI 1 "s_register_operand" ""))]
159 "TARGET_NEON && reload_completed"
160 [(set (match_dup 0) (match_dup 1))
161 (set (match_dup 2) (match_dup 3))]
163 int rdest = REGNO (operands[0]);
164 int rsrc = REGNO (operands[1]);
167 dest[0] = gen_rtx_REG (TImode, rdest);
168 src[0] = gen_rtx_REG (TImode, rsrc);
169 dest[1] = gen_rtx_REG (DImode, rdest + 4);
170 src[1] = gen_rtx_REG (DImode, rsrc + 4);
172 neon_disambiguate_copy (operands, dest, src, 2);
176 [(set (match_operand:OI 0 "s_register_operand" "")
177 (match_operand:OI 1 "s_register_operand" ""))]
178 "TARGET_NEON && reload_completed"
179 [(set (match_dup 0) (match_dup 1))
180 (set (match_dup 2) (match_dup 3))]
182 int rdest = REGNO (operands[0]);
183 int rsrc = REGNO (operands[1]);
186 dest[0] = gen_rtx_REG (TImode, rdest);
187 src[0] = gen_rtx_REG (TImode, rsrc);
188 dest[1] = gen_rtx_REG (TImode, rdest + 4);
189 src[1] = gen_rtx_REG (TImode, rsrc + 4);
191 neon_disambiguate_copy (operands, dest, src, 2);
195 [(set (match_operand:CI 0 "s_register_operand" "")
196 (match_operand:CI 1 "s_register_operand" ""))]
197 "TARGET_NEON && reload_completed"
198 [(set (match_dup 0) (match_dup 1))
199 (set (match_dup 2) (match_dup 3))
200 (set (match_dup 4) (match_dup 5))]
202 int rdest = REGNO (operands[0]);
203 int rsrc = REGNO (operands[1]);
206 dest[0] = gen_rtx_REG (TImode, rdest);
207 src[0] = gen_rtx_REG (TImode, rsrc);
208 dest[1] = gen_rtx_REG (TImode, rdest + 4);
209 src[1] = gen_rtx_REG (TImode, rsrc + 4);
210 dest[2] = gen_rtx_REG (TImode, rdest + 8);
211 src[2] = gen_rtx_REG (TImode, rsrc + 8);
213 neon_disambiguate_copy (operands, dest, src, 3);
217 [(set (match_operand:XI 0 "s_register_operand" "")
218 (match_operand:XI 1 "s_register_operand" ""))]
219 "TARGET_NEON && reload_completed"
220 [(set (match_dup 0) (match_dup 1))
221 (set (match_dup 2) (match_dup 3))
222 (set (match_dup 4) (match_dup 5))
223 (set (match_dup 6) (match_dup 7))]
225 int rdest = REGNO (operands[0]);
226 int rsrc = REGNO (operands[1]);
229 dest[0] = gen_rtx_REG (TImode, rdest);
230 src[0] = gen_rtx_REG (TImode, rsrc);
231 dest[1] = gen_rtx_REG (TImode, rdest + 4);
232 src[1] = gen_rtx_REG (TImode, rsrc + 4);
233 dest[2] = gen_rtx_REG (TImode, rdest + 8);
234 src[2] = gen_rtx_REG (TImode, rsrc + 8);
235 dest[3] = gen_rtx_REG (TImode, rdest + 12);
236 src[3] = gen_rtx_REG (TImode, rsrc + 12);
238 neon_disambiguate_copy (operands, dest, src, 4);
241 (define_expand "movmisalign<mode>"
242 [(set (match_operand:VDQX 0 "neon_perm_struct_or_reg_operand")
243 (unspec:VDQX [(match_operand:VDQX 1 "neon_perm_struct_or_reg_operand")]
244 UNSPEC_MISALIGNED_ACCESS))]
245 "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
247 /* This pattern is not permitted to fail during expansion: if both arguments
248 are non-registers (e.g. memory := constant, which can be created by the
249 auto-vectorizer), force operand 1 into a register. */
250 if (!s_register_operand (operands[0], <MODE>mode)
251 && !s_register_operand (operands[1], <MODE>mode))
252 operands[1] = force_reg (<MODE>mode, operands[1]);
255 (define_insn "*movmisalign<mode>_neon_store"
256 [(set (match_operand:VDX 0 "neon_permissive_struct_operand" "=Um")
257 (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")]
258 UNSPEC_MISALIGNED_ACCESS))]
259 "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
260 "vst1.<V_sz_elem>\t{%P1}, %A0"
261 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
263 (define_insn "*movmisalign<mode>_neon_load"
264 [(set (match_operand:VDX 0 "s_register_operand" "=w")
265 (unspec:VDX [(match_operand:VDX 1 "neon_permissive_struct_operand"
267 UNSPEC_MISALIGNED_ACCESS))]
268 "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
269 "vld1.<V_sz_elem>\t{%P0}, %A1"
270 [(set_attr "neon_type" "neon_vld1_1_2_regs")])
272 (define_insn "*movmisalign<mode>_neon_store"
273 [(set (match_operand:VQX 0 "neon_permissive_struct_operand" "=Um")
274 (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")]
275 UNSPEC_MISALIGNED_ACCESS))]
276 "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
277 "vst1.<V_sz_elem>\t{%q1}, %A0"
278 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
280 (define_insn "*movmisalign<mode>_neon_load"
281 [(set (match_operand:VQX 0 "s_register_operand" "=w")
282 (unspec:VQX [(match_operand:VQX 1 "neon_permissive_struct_operand"
284 UNSPEC_MISALIGNED_ACCESS))]
285 "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
286 "vld1.<V_sz_elem>\t{%q0}, %A1"
287 [(set_attr "neon_type" "neon_vld1_1_2_regs")])
289 (define_insn "vec_set<mode>_internal"
290 [(set (match_operand:VD 0 "s_register_operand" "=w,w")
293 (match_operand:<V_elem> 1 "nonimmediate_operand" "Um,r"))
294 (match_operand:VD 3 "s_register_operand" "0,0")
295 (match_operand:SI 2 "immediate_operand" "i,i")))]
298 int elt = ffs ((int) INTVAL (operands[2])) - 1;
299 if (BYTES_BIG_ENDIAN)
300 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
301 operands[2] = GEN_INT (elt);
303 if (which_alternative == 0)
304 return "vld1.<V_sz_elem>\t{%P0[%c2]}, %A1";
306 return "vmov.<V_sz_elem>\t%P0[%c2], %1";
308 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")])
310 (define_insn "vec_set<mode>_internal"
311 [(set (match_operand:VQ 0 "s_register_operand" "=w,w")
314 (match_operand:<V_elem> 1 "nonimmediate_operand" "Um,r"))
315 (match_operand:VQ 3 "s_register_operand" "0,0")
316 (match_operand:SI 2 "immediate_operand" "i,i")))]
319 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
320 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
321 int elt = elem % half_elts;
322 int hi = (elem / half_elts) * 2;
323 int regno = REGNO (operands[0]);
325 if (BYTES_BIG_ENDIAN)
326 elt = half_elts - 1 - elt;
328 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
329 operands[2] = GEN_INT (elt);
331 if (which_alternative == 0)
332 return "vld1.<V_sz_elem>\t{%P0[%c2]}, %A1";
334 return "vmov.<V_sz_elem>\t%P0[%c2], %1";
336 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
339 (define_insn "vec_setv2di_internal"
340 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
343 (match_operand:DI 1 "nonimmediate_operand" "Um,r"))
344 (match_operand:V2DI 3 "s_register_operand" "0,0")
345 (match_operand:SI 2 "immediate_operand" "i,i")))]
348 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
349 int regno = REGNO (operands[0]) + 2 * elem;
351 operands[0] = gen_rtx_REG (DImode, regno);
353 if (which_alternative == 0)
354 return "vld1.64\t%P0, %A1";
356 return "vmov\t%P0, %Q1, %R1";
358 [(set_attr "neon_type" "neon_vld1_1_2_regs,neon_mcr_2_mcrr")]
361 (define_expand "vec_set<mode>"
362 [(match_operand:VDQ 0 "s_register_operand" "")
363 (match_operand:<V_elem> 1 "s_register_operand" "")
364 (match_operand:SI 2 "immediate_operand" "")]
367 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
368 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
369 GEN_INT (elem), operands[0]));
373 (define_insn "vec_extract<mode>"
374 [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=Um,r")
376 (match_operand:VD 1 "s_register_operand" "w,w")
377 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
380 if (BYTES_BIG_ENDIAN)
382 int elt = INTVAL (operands[2]);
383 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
384 operands[2] = GEN_INT (elt);
387 if (which_alternative == 0)
388 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
390 return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
392 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
395 (define_insn "vec_extract<mode>"
396 [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=Um,r")
398 (match_operand:VQ 1 "s_register_operand" "w,w")
399 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
402 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
403 int elt = INTVAL (operands[2]) % half_elts;
404 int hi = (INTVAL (operands[2]) / half_elts) * 2;
405 int regno = REGNO (operands[1]);
407 if (BYTES_BIG_ENDIAN)
408 elt = half_elts - 1 - elt;
410 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
411 operands[2] = GEN_INT (elt);
413 if (which_alternative == 0)
414 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
416 return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
418 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
421 (define_insn "vec_extractv2di"
422 [(set (match_operand:DI 0 "nonimmediate_operand" "=Um,r")
424 (match_operand:V2DI 1 "s_register_operand" "w,w")
425 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
428 int regno = REGNO (operands[1]) + 2 * INTVAL (operands[2]);
430 operands[1] = gen_rtx_REG (DImode, regno);
432 if (which_alternative == 0)
433 return "vst1.64\t{%P1}, %A0 @ v2di";
435 return "vmov\t%Q0, %R0, %P1 @ v2di";
437 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_int_1")]
440 (define_expand "vec_init<mode>"
441 [(match_operand:VDQ 0 "s_register_operand" "")
442 (match_operand 1 "" "")]
445 neon_expand_vector_init (operands[0], operands[1]);
449 ;; Doubleword and quadword arithmetic.
451 ;; NOTE: some other instructions also support 64-bit integer
452 ;; element size, which we could potentially use for "long long" operations.
454 (define_insn "*add<mode>3_neon"
455 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
456 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
457 (match_operand:VDQ 2 "s_register_operand" "w")))]
458 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
459 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
460 [(set (attr "neon_type")
461 (if_then_else (match_test "<Is_float_mode>")
462 (if_then_else (match_test "<Is_d_reg>")
463 (const_string "neon_fp_vadd_ddd_vabs_dd")
464 (const_string "neon_fp_vadd_qqq_vabs_qq"))
465 (const_string "neon_int_1")))]
468 (define_insn "adddi3_neon"
469 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w,?&r,?&r,?&r")
470 (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,w,r,0,r")
471 (match_operand:DI 2 "arm_adddi_operand" "w,r,0,w,r,Dd,Dd")))
472 (clobber (reg:CC CC_REGNUM))]
475 switch (which_alternative)
477 case 0: /* fall through */
478 case 3: return "vadd.i64\t%P0, %P1, %P2";
484 default: gcc_unreachable ();
487 [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*")
488 (set_attr "conds" "*,clob,clob,*,clob,clob,clob")
489 (set_attr "length" "*,8,8,*,8,8,8")
490 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits,*,*,*")]
493 (define_insn "*sub<mode>3_neon"
494 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
495 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
496 (match_operand:VDQ 2 "s_register_operand" "w")))]
497 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
498 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
499 [(set (attr "neon_type")
500 (if_then_else (match_test "<Is_float_mode>")
501 (if_then_else (match_test "<Is_d_reg>")
502 (const_string "neon_fp_vadd_ddd_vabs_dd")
503 (const_string "neon_fp_vadd_qqq_vabs_qq"))
504 (const_string "neon_int_2")))]
507 (define_insn "subdi3_neon"
508 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r,?w")
509 (minus:DI (match_operand:DI 1 "s_register_operand" "w,0,r,0,w")
510 (match_operand:DI 2 "s_register_operand" "w,r,0,0,w")))
511 (clobber (reg:CC CC_REGNUM))]
514 switch (which_alternative)
516 case 0: /* fall through */
517 case 4: return "vsub.i64\t%P0, %P1, %P2";
518 case 1: /* fall through */
519 case 2: /* fall through */
520 case 3: return "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2";
521 default: gcc_unreachable ();
524 [(set_attr "neon_type" "neon_int_2,*,*,*,neon_int_2")
525 (set_attr "conds" "*,clob,clob,clob,*")
526 (set_attr "length" "*,8,8,8,*")
527 (set_attr "arch" "neon_for_64bits,*,*,*,avoid_neon_for_64bits")]
530 (define_insn "*mul<mode>3_neon"
531 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
532 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
533 (match_operand:VDQ 2 "s_register_operand" "w")))]
534 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
535 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
536 [(set (attr "neon_type")
537 (if_then_else (match_test "<Is_float_mode>")
538 (if_then_else (match_test "<Is_d_reg>")
539 (const_string "neon_fp_vadd_ddd_vabs_dd")
540 (const_string "neon_fp_vadd_qqq_vabs_qq"))
541 (if_then_else (match_test "<Is_d_reg>")
543 (match_test "<Scalar_mul_8_16>")
544 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
545 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
546 (if_then_else (match_test "<Scalar_mul_8_16>")
547 (const_string "neon_mul_qqq_8_16_32_ddd_32")
548 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
551 (define_insn "mul<mode>3add<mode>_neon"
552 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
553 (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
554 (match_operand:VDQ 3 "s_register_operand" "w"))
555 (match_operand:VDQ 1 "s_register_operand" "0")))]
556 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
557 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
558 [(set (attr "neon_type")
559 (if_then_else (match_test "<Is_float_mode>")
560 (if_then_else (match_test "<Is_d_reg>")
561 (const_string "neon_fp_vmla_ddd")
562 (const_string "neon_fp_vmla_qqq"))
563 (if_then_else (match_test "<Is_d_reg>")
565 (match_test "<Scalar_mul_8_16>")
566 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
567 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
568 (if_then_else (match_test "<Scalar_mul_8_16>")
569 (const_string "neon_mla_qqq_8_16")
570 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
573 (define_insn "mul<mode>3neg<mode>add<mode>_neon"
574 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
575 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
576 (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
577 (match_operand:VDQ 3 "s_register_operand" "w"))))]
578 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
579 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
580 [(set (attr "neon_type")
581 (if_then_else (match_test "<Is_float_mode>")
582 (if_then_else (match_test "<Is_d_reg>")
583 (const_string "neon_fp_vmla_ddd")
584 (const_string "neon_fp_vmla_qqq"))
585 (if_then_else (match_test "<Is_d_reg>")
587 (match_test "<Scalar_mul_8_16>")
588 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
589 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
590 (if_then_else (match_test "<Scalar_mul_8_16>")
591 (const_string "neon_mla_qqq_8_16")
592 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
595 ;; Fused multiply-accumulate
596 ;; We define each insn twice here:
597 ;; 1: with flag_unsafe_math_optimizations for the widening multiply phase
598 ;; to be able to use when converting to FMA.
599 ;; 2: without flag_unsafe_math_optimizations for the intrinsics to use.
600 (define_insn "fma<VCVTF:mode>4"
601 [(set (match_operand:VCVTF 0 "register_operand" "=w")
602 (fma:VCVTF (match_operand:VCVTF 1 "register_operand" "w")
603 (match_operand:VCVTF 2 "register_operand" "w")
604 (match_operand:VCVTF 3 "register_operand" "0")))]
605 "TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations"
606 "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
607 [(set (attr "neon_type")
608 (if_then_else (match_test "<Is_d_reg>")
609 (const_string "neon_fp_vmla_ddd")
610 (const_string "neon_fp_vmla_qqq")))]
613 (define_insn "fma<VCVTF:mode>4_intrinsic"
614 [(set (match_operand:VCVTF 0 "register_operand" "=w")
615 (fma:VCVTF (match_operand:VCVTF 1 "register_operand" "w")
616 (match_operand:VCVTF 2 "register_operand" "w")
617 (match_operand:VCVTF 3 "register_operand" "0")))]
618 "TARGET_NEON && TARGET_FMA"
619 "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
620 [(set (attr "neon_type")
621 (if_then_else (match_test "<Is_d_reg>")
622 (const_string "neon_fp_vmla_ddd")
623 (const_string "neon_fp_vmla_qqq")))]
626 (define_insn "*fmsub<VCVTF:mode>4"
627 [(set (match_operand:VCVTF 0 "register_operand" "=w")
628 (fma:VCVTF (neg:VCVTF (match_operand:VCVTF 1 "register_operand" "w"))
629 (match_operand:VCVTF 2 "register_operand" "w")
630 (match_operand:VCVTF 3 "register_operand" "0")))]
631 "TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations"
632 "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
633 [(set (attr "neon_type")
634 (if_then_else (match_test "<Is_d_reg>")
635 (const_string "neon_fp_vmla_ddd")
636 (const_string "neon_fp_vmla_qqq")))]
639 (define_insn "fmsub<VCVTF:mode>4_intrinsic"
640 [(set (match_operand:VCVTF 0 "register_operand" "=w")
641 (fma:VCVTF (neg:VCVTF (match_operand:VCVTF 1 "register_operand" "w"))
642 (match_operand:VCVTF 2 "register_operand" "w")
643 (match_operand:VCVTF 3 "register_operand" "0")))]
644 "TARGET_NEON && TARGET_FMA"
645 "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
646 [(set (attr "neon_type")
647 (if_then_else (match_test "<Is_d_reg>")
648 (const_string "neon_fp_vmla_ddd")
649 (const_string "neon_fp_vmla_qqq")))]
652 (define_insn "neon_vrint<NEON_VRINT:nvrint_variant><VCVTF:mode>"
653 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
654 (unspec:VCVTF [(match_operand:VCVTF 1
655 "s_register_operand" "w")]
657 "TARGET_NEON && TARGET_FPU_ARMV8"
658 "vrint<nvrint_variant>%?.f32\\t%<V_reg>0, %<V_reg>1"
659 [(set (attr "neon_type")
660 (if_then_else (match_test "<Is_d_reg>")
661 (const_string "neon_fp_vadd_ddd_vabs_dd")
662 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
665 (define_insn "ior<mode>3"
666 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
667 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
668 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
671 switch (which_alternative)
673 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
674 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
675 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
676 default: gcc_unreachable ();
679 [(set_attr "neon_type" "neon_int_1")]
682 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
683 ;; vorr. We support the pseudo-instruction vand instead, because that
684 ;; corresponds to the canonical form the middle-end expects to use for
685 ;; immediate bitwise-ANDs.
687 (define_insn "and<mode>3"
688 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
689 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
690 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
693 switch (which_alternative)
695 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
696 case 1: return neon_output_logic_immediate ("vand", &operands[2],
697 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
698 default: gcc_unreachable ();
701 [(set_attr "neon_type" "neon_int_1")]
704 (define_insn "orn<mode>3_neon"
705 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
706 (ior:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
707 (match_operand:VDQ 1 "s_register_operand" "w")))]
709 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
710 [(set_attr "neon_type" "neon_int_1")]
713 ;; TODO: investigate whether we should disable
714 ;; this and bicdi3_neon for the A8 in line with the other
716 (define_insn_and_split "orndi3_neon"
717 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
718 (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
719 (match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
727 (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
728 [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
729 (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
734 operands[3] = gen_highpart (SImode, operands[0]);
735 operands[0] = gen_lowpart (SImode, operands[0]);
736 operands[4] = gen_highpart (SImode, operands[2]);
737 operands[2] = gen_lowpart (SImode, operands[2]);
738 operands[5] = gen_highpart (SImode, operands[1]);
739 operands[1] = gen_lowpart (SImode, operands[1]);
743 emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
744 emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
748 [(set_attr "neon_type" "neon_int_1,*,*,*")
749 (set_attr "length" "*,16,8,8")
750 (set_attr "arch" "any,a,t2,t2")]
753 (define_insn "bic<mode>3_neon"
754 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
755 (and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
756 (match_operand:VDQ 1 "s_register_operand" "w")))]
758 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
759 [(set_attr "neon_type" "neon_int_1")]
762 ;; Compare to *anddi_notdi_di.
763 (define_insn "bicdi3_neon"
764 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
765 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
766 (match_operand:DI 1 "s_register_operand" "w,0,r")))]
772 [(set_attr "neon_type" "neon_int_1,*,*")
773 (set_attr "length" "*,8,8")]
776 (define_insn "xor<mode>3"
777 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
778 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
779 (match_operand:VDQ 2 "s_register_operand" "w")))]
781 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
782 [(set_attr "neon_type" "neon_int_1")]
785 (define_insn "one_cmpl<mode>2"
786 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
787 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
789 "vmvn\t%<V_reg>0, %<V_reg>1"
790 [(set_attr "neon_type" "neon_int_1")]
793 (define_insn "abs<mode>2"
794 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
795 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
797 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
798 [(set (attr "neon_type")
799 (if_then_else (match_test "<Is_float_mode>")
800 (if_then_else (match_test "<Is_d_reg>")
801 (const_string "neon_fp_vadd_ddd_vabs_dd")
802 (const_string "neon_fp_vadd_qqq_vabs_qq"))
803 (const_string "neon_int_3")))]
806 (define_insn "neg<mode>2"
807 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
808 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
810 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
811 [(set (attr "neon_type")
812 (if_then_else (match_test "<Is_float_mode>")
813 (if_then_else (match_test "<Is_d_reg>")
814 (const_string "neon_fp_vadd_ddd_vabs_dd")
815 (const_string "neon_fp_vadd_qqq_vabs_qq"))
816 (const_string "neon_int_3")))]
819 (define_insn "negdi2_neon"
820 [(set (match_operand:DI 0 "s_register_operand" "=&w, w,r,&r")
821 (neg:DI (match_operand:DI 1 "s_register_operand" " w, w,0, r")))
822 (clobber (match_scratch:DI 2 "= X,&w,X, X"))
823 (clobber (reg:CC CC_REGNUM))]
826 [(set_attr "length" "8")]
829 ; Split negdi2_neon for vfp registers
831 [(set (match_operand:DI 0 "s_register_operand" "")
832 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
833 (clobber (match_scratch:DI 2 ""))
834 (clobber (reg:CC CC_REGNUM))]
835 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
836 [(set (match_dup 2) (const_int 0))
837 (parallel [(set (match_dup 0) (minus:DI (match_dup 2) (match_dup 1)))
838 (clobber (reg:CC CC_REGNUM))])]
840 if (!REG_P (operands[2]))
841 operands[2] = operands[0];
845 ; Split negdi2_neon for core registers
847 [(set (match_operand:DI 0 "s_register_operand" "")
848 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
849 (clobber (match_scratch:DI 2 ""))
850 (clobber (reg:CC CC_REGNUM))]
851 "TARGET_32BIT && reload_completed
852 && arm_general_register_operand (operands[0], DImode)"
853 [(parallel [(set (match_dup 0) (neg:DI (match_dup 1)))
854 (clobber (reg:CC CC_REGNUM))])]
858 (define_insn "*umin<mode>3_neon"
859 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
860 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
861 (match_operand:VDQIW 2 "s_register_operand" "w")))]
863 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
864 [(set_attr "neon_type" "neon_int_5")]
867 (define_insn "*umax<mode>3_neon"
868 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
869 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
870 (match_operand:VDQIW 2 "s_register_operand" "w")))]
872 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
873 [(set_attr "neon_type" "neon_int_5")]
876 (define_insn "*smin<mode>3_neon"
877 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
878 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
879 (match_operand:VDQW 2 "s_register_operand" "w")))]
881 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
882 [(set (attr "neon_type")
883 (if_then_else (match_test "<Is_float_mode>")
884 (const_string "neon_fp_vadd_ddd_vabs_dd")
885 (const_string "neon_int_5")))]
888 (define_insn "*smax<mode>3_neon"
889 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
890 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
891 (match_operand:VDQW 2 "s_register_operand" "w")))]
893 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
894 [(set (attr "neon_type")
895 (if_then_else (match_test "<Is_float_mode>")
896 (const_string "neon_fp_vadd_ddd_vabs_dd")
897 (const_string "neon_int_5")))]
900 ; TODO: V2DI shifts are current disabled because there are bugs in the
901 ; generic vectorizer code. It ends up creating a V2DI constructor with
904 (define_insn "vashl<mode>3"
905 [(set (match_operand:VDQIW 0 "s_register_operand" "=w,w")
906 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w,w")
907 (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" "w,Dn")))]
910 switch (which_alternative)
912 case 0: return "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
913 case 1: return neon_output_shift_immediate ("vshl", 'i', &operands[2],
915 VALID_NEON_QREG_MODE (<MODE>mode),
917 default: gcc_unreachable ();
920 [(set (attr "neon_type")
921 (if_then_else (match_test "<Is_d_reg>")
922 (const_string "neon_vshl_ddd")
923 (const_string "neon_shift_3")))]
926 (define_insn "vashr<mode>3_imm"
927 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
928 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
929 (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))]
932 return neon_output_shift_immediate ("vshr", 's', &operands[2],
933 <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
936 [(set (attr "neon_type")
937 (if_then_else (match_test "<Is_d_reg>")
938 (const_string "neon_vshl_ddd")
939 (const_string "neon_shift_3")))]
942 (define_insn "vlshr<mode>3_imm"
943 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
944 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
945 (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))]
948 return neon_output_shift_immediate ("vshr", 'u', &operands[2],
949 <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
952 [(set (attr "neon_type")
953 (if_then_else (match_test "<Is_d_reg>")
954 (const_string "neon_vshl_ddd")
955 (const_string "neon_shift_3")))]
958 ; Used for implementing logical shift-right, which is a left-shift by a negative
959 ; amount, with signed operands. This is essentially the same as ashl<mode>3
960 ; above, but using an unspec in case GCC tries anything tricky with negative
963 (define_insn "ashl<mode>3_signed"
964 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
965 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
966 (match_operand:VDQI 2 "s_register_operand" "w")]
967 UNSPEC_ASHIFT_SIGNED))]
969 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
970 [(set (attr "neon_type")
971 (if_then_else (match_test "<Is_d_reg>")
972 (const_string "neon_vshl_ddd")
973 (const_string "neon_shift_3")))]
976 ; Used for implementing logical shift-right, which is a left-shift by a negative
977 ; amount, with unsigned operands.
979 (define_insn "ashl<mode>3_unsigned"
980 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
981 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
982 (match_operand:VDQI 2 "s_register_operand" "w")]
983 UNSPEC_ASHIFT_UNSIGNED))]
985 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
986 [(set (attr "neon_type")
987 (if_then_else (match_test "<Is_d_reg>")
988 (const_string "neon_vshl_ddd")
989 (const_string "neon_shift_3")))]
992 (define_expand "vashr<mode>3"
993 [(set (match_operand:VDQIW 0 "s_register_operand" "")
994 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
995 (match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
998 if (s_register_operand (operands[2], <MODE>mode))
1000 rtx neg = gen_reg_rtx (<MODE>mode);
1001 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1002 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
1005 emit_insn (gen_vashr<mode>3_imm (operands[0], operands[1], operands[2]));
1009 (define_expand "vlshr<mode>3"
1010 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1011 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1012 (match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
1015 if (s_register_operand (operands[2], <MODE>mode))
1017 rtx neg = gen_reg_rtx (<MODE>mode);
1018 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1019 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1022 emit_insn (gen_vlshr<mode>3_imm (operands[0], operands[1], operands[2]));
1028 ;; This pattern loads a 32-bit shift count into a 64-bit NEON register,
1029 ;; leaving the upper half uninitalized. This is OK since the shift
1030 ;; instruction only looks at the low 8 bits anyway. To avoid confusing
1031 ;; data flow analysis however, we pretend the full register is set
1033 (define_insn "neon_load_count"
1034 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
1035 (unspec:DI [(match_operand:SI 1 "nonimmediate_operand" "Um,r")]
1036 UNSPEC_LOAD_COUNT))]
1039 vld1.32\t{%P0[0]}, %A1
1040 vmov.32\t%P0[0], %1"
1041 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
1044 (define_insn "ashldi3_neon_noclobber"
1045 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
1046 (ashift:DI (match_operand:DI 1 "s_register_operand" " w,w")
1047 (match_operand:DI 2 "reg_or_int_operand" " i,w")))]
1048 "TARGET_NEON && reload_completed
1049 && (!CONST_INT_P (operands[2])
1050 || (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 64))"
1052 vshl.u64\t%P0, %P1, %2
1053 vshl.u64\t%P0, %P1, %P2"
1054 [(set_attr "neon_type" "neon_vshl_ddd,neon_vshl_ddd")]
1057 (define_insn_and_split "ashldi3_neon"
1058 [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r, ?w,w")
1059 (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, r, 0w,w")
1060 (match_operand:SI 2 "general_operand" "rUm, i, r, i,rUm,i")))
1061 (clobber (match_scratch:SI 3 "= X, X,?&r, X, X,X"))
1062 (clobber (match_scratch:SI 4 "= X, X,?&r, X, X,X"))
1063 (clobber (match_scratch:DI 5 "=&w, X, X, X, &w,X"))
1064 (clobber (reg:CC_C CC_REGNUM))]
1067 "TARGET_NEON && reload_completed"
1071 if (IS_VFP_REGNUM (REGNO (operands[0])))
1073 if (CONST_INT_P (operands[2]))
1075 if (INTVAL (operands[2]) < 1)
1077 emit_insn (gen_movdi (operands[0], operands[1]));
1080 else if (INTVAL (operands[2]) > 63)
1081 operands[2] = gen_rtx_CONST_INT (VOIDmode, 63);
1085 emit_insn (gen_neon_load_count (operands[5], operands[2]));
1086 operands[2] = operands[5];
1089 /* Ditch the unnecessary clobbers. */
1090 emit_insn (gen_ashldi3_neon_noclobber (operands[0], operands[1],
1095 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
1096 /* This clobbers CC. */
1097 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
1099 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
1100 operands[2], operands[3], operands[4]);
1104 [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")
1105 (set_attr "opt" "*,*,speed,speed,*,*")]
1108 ; The shift amount needs to be negated for right-shifts
1109 (define_insn "signed_shift_di3_neon"
1110 [(set (match_operand:DI 0 "s_register_operand" "=w")
1111 (unspec:DI [(match_operand:DI 1 "s_register_operand" " w")
1112 (match_operand:DI 2 "s_register_operand" " w")]
1113 UNSPEC_ASHIFT_SIGNED))]
1114 "TARGET_NEON && reload_completed"
1115 "vshl.s64\t%P0, %P1, %P2"
1116 [(set_attr "neon_type" "neon_vshl_ddd")]
1119 ; The shift amount needs to be negated for right-shifts
1120 (define_insn "unsigned_shift_di3_neon"
1121 [(set (match_operand:DI 0 "s_register_operand" "=w")
1122 (unspec:DI [(match_operand:DI 1 "s_register_operand" " w")
1123 (match_operand:DI 2 "s_register_operand" " w")]
1124 UNSPEC_ASHIFT_UNSIGNED))]
1125 "TARGET_NEON && reload_completed"
1126 "vshl.u64\t%P0, %P1, %P2"
1127 [(set_attr "neon_type" "neon_vshl_ddd")]
1130 (define_insn "ashrdi3_neon_imm_noclobber"
1131 [(set (match_operand:DI 0 "s_register_operand" "=w")
1132 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" " w")
1133 (match_operand:DI 2 "const_int_operand" " i")))]
1134 "TARGET_NEON && reload_completed
1135 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
1136 "vshr.s64\t%P0, %P1, %2"
1137 [(set_attr "neon_type" "neon_vshl_ddd")]
1140 (define_insn "lshrdi3_neon_imm_noclobber"
1141 [(set (match_operand:DI 0 "s_register_operand" "=w")
1142 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" " w")
1143 (match_operand:DI 2 "const_int_operand" " i")))]
1144 "TARGET_NEON && reload_completed
1145 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
1146 "vshr.u64\t%P0, %P1, %2"
1147 [(set_attr "neon_type" "neon_vshl_ddd")]
1152 (define_insn_and_split "<shift>di3_neon"
1153 [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r,?w,?w")
1154 (rshifts:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, r,0w, w")
1155 (match_operand:SI 2 "reg_or_int_operand" " r, i, r, i, r, i")))
1156 (clobber (match_scratch:SI 3 "=2r, X, &r, X,2r, X"))
1157 (clobber (match_scratch:SI 4 "= X, X, &r, X, X, X"))
1158 (clobber (match_scratch:DI 5 "=&w, X, X, X,&w, X"))
1159 (clobber (reg:CC CC_REGNUM))]
1162 "TARGET_NEON && reload_completed"
1166 if (IS_VFP_REGNUM (REGNO (operands[0])))
1168 if (CONST_INT_P (operands[2]))
1170 if (INTVAL (operands[2]) < 1)
1172 emit_insn (gen_movdi (operands[0], operands[1]));
1175 else if (INTVAL (operands[2]) > 64)
1176 operands[2] = gen_rtx_CONST_INT (VOIDmode, 64);
1178 /* Ditch the unnecessary clobbers. */
1179 emit_insn (gen_<shift>di3_neon_imm_noclobber (operands[0],
1185 /* We must use a negative left-shift. */
1186 emit_insn (gen_negsi2 (operands[3], operands[2]));
1187 emit_insn (gen_neon_load_count (operands[5], operands[3]));
1188 emit_insn (gen_<shifttype>_shift_di3_neon (operands[0], operands[1],
1194 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
1195 /* This clobbers CC. */
1196 emit_insn (gen_arm_<shift>di3_1bit (operands[0], operands[1]));
1198 /* This clobbers CC (ASHIFTRT by register only). */
1199 arm_emit_coreregs_64bit_shift (<CODE>, operands[0], operands[1],
1200 operands[2], operands[3], operands[4]);
1205 [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")
1206 (set_attr "opt" "*,*,speed,speed,*,*")]
1209 ;; Widening operations
1211 (define_insn "widen_ssum<mode>3"
1212 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1213 (plus:<V_widen> (sign_extend:<V_widen>
1214 (match_operand:VW 1 "s_register_operand" "%w"))
1215 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1217 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1218 [(set_attr "neon_type" "neon_int_3")]
1221 (define_insn "widen_usum<mode>3"
1222 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1223 (plus:<V_widen> (zero_extend:<V_widen>
1224 (match_operand:VW 1 "s_register_operand" "%w"))
1225 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1227 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1228 [(set_attr "neon_type" "neon_int_3")]
1231 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1232 ;; shift-count granularity. That's good enough for the middle-end's current
1235 ;; Note that it's not safe to perform such an operation in big-endian mode,
1236 ;; due to element-ordering issues.
1238 (define_expand "vec_shr_<mode>"
1239 [(match_operand:VDQ 0 "s_register_operand" "")
1240 (match_operand:VDQ 1 "s_register_operand" "")
1241 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1242 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1245 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1246 const int width = GET_MODE_BITSIZE (<MODE>mode);
1247 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1248 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1249 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1251 if (num_bits == width)
1253 emit_move_insn (operands[0], operands[1]);
1257 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1258 operands[0] = gen_lowpart (bvecmode, operands[0]);
1259 operands[1] = gen_lowpart (bvecmode, operands[1]);
1261 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1262 GEN_INT (num_bits / BITS_PER_UNIT)));
1266 (define_expand "vec_shl_<mode>"
1267 [(match_operand:VDQ 0 "s_register_operand" "")
1268 (match_operand:VDQ 1 "s_register_operand" "")
1269 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1270 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1273 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1274 const int width = GET_MODE_BITSIZE (<MODE>mode);
1275 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1276 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1277 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1281 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1285 num_bits = width - num_bits;
1287 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1288 operands[0] = gen_lowpart (bvecmode, operands[0]);
1289 operands[1] = gen_lowpart (bvecmode, operands[1]);
1291 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1292 GEN_INT (num_bits / BITS_PER_UNIT)));
1296 ;; Helpers for quad-word reduction operations
1298 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1299 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1300 ; N/2-element vector.
1302 (define_insn "quad_halves_<code>v4si"
1303 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1305 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1306 (parallel [(const_int 0) (const_int 1)]))
1307 (vec_select:V2SI (match_dup 1)
1308 (parallel [(const_int 2) (const_int 3)]))))]
1310 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1311 [(set_attr "vqh_mnem" "<VQH_mnem>")
1312 (set (attr "neon_type")
1313 (if_then_else (eq_attr "vqh_mnem" "vadd")
1314 (const_string "neon_int_1") (const_string "neon_int_5")))]
1317 (define_insn "quad_halves_<code>v4sf"
1318 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1320 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1321 (parallel [(const_int 0) (const_int 1)]))
1322 (vec_select:V2SF (match_dup 1)
1323 (parallel [(const_int 2) (const_int 3)]))))]
1324 "TARGET_NEON && flag_unsafe_math_optimizations"
1325 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1326 [(set_attr "vqh_mnem" "<VQH_mnem>")
1327 (set (attr "neon_type")
1328 (if_then_else (eq_attr "vqh_mnem" "vadd")
1329 (const_string "neon_int_1") (const_string "neon_int_5")))]
1332 (define_insn "quad_halves_<code>v8hi"
1333 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1335 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1336 (parallel [(const_int 0) (const_int 1)
1337 (const_int 2) (const_int 3)]))
1338 (vec_select:V4HI (match_dup 1)
1339 (parallel [(const_int 4) (const_int 5)
1340 (const_int 6) (const_int 7)]))))]
1342 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1343 [(set_attr "vqh_mnem" "<VQH_mnem>")
1344 (set (attr "neon_type")
1345 (if_then_else (eq_attr "vqh_mnem" "vadd")
1346 (const_string "neon_int_1") (const_string "neon_int_5")))]
1349 (define_insn "quad_halves_<code>v16qi"
1350 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1352 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1353 (parallel [(const_int 0) (const_int 1)
1354 (const_int 2) (const_int 3)
1355 (const_int 4) (const_int 5)
1356 (const_int 6) (const_int 7)]))
1357 (vec_select:V8QI (match_dup 1)
1358 (parallel [(const_int 8) (const_int 9)
1359 (const_int 10) (const_int 11)
1360 (const_int 12) (const_int 13)
1361 (const_int 14) (const_int 15)]))))]
1363 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1364 [(set_attr "vqh_mnem" "<VQH_mnem>")
1365 (set (attr "neon_type")
1366 (if_then_else (eq_attr "vqh_mnem" "vadd")
1367 (const_string "neon_int_1") (const_string "neon_int_5")))]
1370 (define_expand "move_hi_quad_<mode>"
1371 [(match_operand:ANY128 0 "s_register_operand" "")
1372 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1375 emit_move_insn (simplify_gen_subreg (<V_HALF>mode, operands[0], <MODE>mode,
1376 GET_MODE_SIZE (<V_HALF>mode)),
1381 (define_expand "move_lo_quad_<mode>"
1382 [(match_operand:ANY128 0 "s_register_operand" "")
1383 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1386 emit_move_insn (simplify_gen_subreg (<V_HALF>mode, operands[0],
1392 ;; Reduction operations
1394 (define_expand "reduc_splus_<mode>"
1395 [(match_operand:VD 0 "s_register_operand" "")
1396 (match_operand:VD 1 "s_register_operand" "")]
1397 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1399 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1400 &gen_neon_vpadd_internal<mode>);
1404 (define_expand "reduc_splus_<mode>"
1405 [(match_operand:VQ 0 "s_register_operand" "")
1406 (match_operand:VQ 1 "s_register_operand" "")]
1407 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1408 && !BYTES_BIG_ENDIAN"
1410 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1411 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1413 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1414 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1415 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1420 (define_insn "reduc_splus_v2di"
1421 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1422 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1424 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1425 "vadd.i64\t%e0, %e1, %f1"
1426 [(set_attr "neon_type" "neon_int_1")]
1429 ;; NEON does not distinguish between signed and unsigned addition except on
1430 ;; widening operations.
1431 (define_expand "reduc_uplus_<mode>"
1432 [(match_operand:VDQI 0 "s_register_operand" "")
1433 (match_operand:VDQI 1 "s_register_operand" "")]
1434 "TARGET_NEON && (<Is_d_reg> || !BYTES_BIG_ENDIAN)"
1436 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1440 (define_expand "reduc_smin_<mode>"
1441 [(match_operand:VD 0 "s_register_operand" "")
1442 (match_operand:VD 1 "s_register_operand" "")]
1443 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1445 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1446 &gen_neon_vpsmin<mode>);
1450 (define_expand "reduc_smin_<mode>"
1451 [(match_operand:VQ 0 "s_register_operand" "")
1452 (match_operand:VQ 1 "s_register_operand" "")]
1453 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1454 && !BYTES_BIG_ENDIAN"
1456 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1457 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1459 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1460 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1461 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1466 (define_expand "reduc_smax_<mode>"
1467 [(match_operand:VD 0 "s_register_operand" "")
1468 (match_operand:VD 1 "s_register_operand" "")]
1469 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1471 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1472 &gen_neon_vpsmax<mode>);
1476 (define_expand "reduc_smax_<mode>"
1477 [(match_operand:VQ 0 "s_register_operand" "")
1478 (match_operand:VQ 1 "s_register_operand" "")]
1479 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1480 && !BYTES_BIG_ENDIAN"
1482 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1483 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1485 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1486 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1487 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1492 (define_expand "reduc_umin_<mode>"
1493 [(match_operand:VDI 0 "s_register_operand" "")
1494 (match_operand:VDI 1 "s_register_operand" "")]
1497 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1498 &gen_neon_vpumin<mode>);
1502 (define_expand "reduc_umin_<mode>"
1503 [(match_operand:VQI 0 "s_register_operand" "")
1504 (match_operand:VQI 1 "s_register_operand" "")]
1505 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1507 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1508 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1510 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1511 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1512 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1517 (define_expand "reduc_umax_<mode>"
1518 [(match_operand:VDI 0 "s_register_operand" "")
1519 (match_operand:VDI 1 "s_register_operand" "")]
1522 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1523 &gen_neon_vpumax<mode>);
1527 (define_expand "reduc_umax_<mode>"
1528 [(match_operand:VQI 0 "s_register_operand" "")
1529 (match_operand:VQI 1 "s_register_operand" "")]
1530 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1532 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1533 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1535 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1536 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1537 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1542 (define_insn "neon_vpadd_internal<mode>"
1543 [(set (match_operand:VD 0 "s_register_operand" "=w")
1544 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1545 (match_operand:VD 2 "s_register_operand" "w")]
1548 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1549 ;; Assume this schedules like vadd.
1550 [(set (attr "neon_type")
1551 (if_then_else (match_test "<Is_float_mode>")
1552 (if_then_else (match_test "<Is_d_reg>")
1553 (const_string "neon_fp_vadd_ddd_vabs_dd")
1554 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1555 (const_string "neon_int_1")))]
1558 (define_insn "neon_vpsmin<mode>"
1559 [(set (match_operand:VD 0 "s_register_operand" "=w")
1560 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1561 (match_operand:VD 2 "s_register_operand" "w")]
1564 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1565 ;; Assume this schedules like vmin.
1566 [(set (attr "neon_type")
1567 (if_then_else (match_test "<Is_float_mode>")
1568 (const_string "neon_fp_vadd_ddd_vabs_dd")
1569 (const_string "neon_int_5")))]
1572 (define_insn "neon_vpsmax<mode>"
1573 [(set (match_operand:VD 0 "s_register_operand" "=w")
1574 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1575 (match_operand:VD 2 "s_register_operand" "w")]
1578 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1579 ;; Assume this schedules like vmax.
1580 [(set (attr "neon_type")
1581 (if_then_else (match_test "<Is_float_mode>")
1582 (const_string "neon_fp_vadd_ddd_vabs_dd")
1583 (const_string "neon_int_5")))]
1586 (define_insn "neon_vpumin<mode>"
1587 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1588 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1589 (match_operand:VDI 2 "s_register_operand" "w")]
1592 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1593 ;; Assume this schedules like umin.
1594 [(set_attr "neon_type" "neon_int_5")]
1597 (define_insn "neon_vpumax<mode>"
1598 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1599 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1600 (match_operand:VDI 2 "s_register_operand" "w")]
1603 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1604 ;; Assume this schedules like umax.
1605 [(set_attr "neon_type" "neon_int_5")]
1608 ;; Saturating arithmetic
1610 ; NOTE: Neon supports many more saturating variants of instructions than the
1611 ; following, but these are all GCC currently understands.
1612 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1613 ; yet either, although these patterns may be used by intrinsics when they're
1616 (define_insn "*ss_add<mode>_neon"
1617 [(set (match_operand:VD 0 "s_register_operand" "=w")
1618 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1619 (match_operand:VD 2 "s_register_operand" "w")))]
1621 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1622 [(set_attr "neon_type" "neon_int_4")]
1625 (define_insn "*us_add<mode>_neon"
1626 [(set (match_operand:VD 0 "s_register_operand" "=w")
1627 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1628 (match_operand:VD 2 "s_register_operand" "w")))]
1630 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1631 [(set_attr "neon_type" "neon_int_4")]
1634 (define_insn "*ss_sub<mode>_neon"
1635 [(set (match_operand:VD 0 "s_register_operand" "=w")
1636 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1637 (match_operand:VD 2 "s_register_operand" "w")))]
1639 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1640 [(set_attr "neon_type" "neon_int_5")]
1643 (define_insn "*us_sub<mode>_neon"
1644 [(set (match_operand:VD 0 "s_register_operand" "=w")
1645 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1646 (match_operand:VD 2 "s_register_operand" "w")))]
1648 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1649 [(set_attr "neon_type" "neon_int_5")]
1652 ;; Conditional instructions. These are comparisons with conditional moves for
1653 ;; vectors. They perform the assignment:
1655 ;; Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2;
1657 ;; where op3 is <, <=, ==, !=, >= or >. Operations are performed
1660 (define_expand "vcond<mode><mode>"
1661 [(set (match_operand:VDQW 0 "s_register_operand" "")
1663 (match_operator 3 "comparison_operator"
1664 [(match_operand:VDQW 4 "s_register_operand" "")
1665 (match_operand:VDQW 5 "nonmemory_operand" "")])
1666 (match_operand:VDQW 1 "s_register_operand" "")
1667 (match_operand:VDQW 2 "s_register_operand" "")))]
1668 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1670 HOST_WIDE_INT magic_word = (<MODE>mode == V2SFmode || <MODE>mode == V4SFmode)
1672 rtx magic_rtx = GEN_INT (magic_word);
1674 int swap_bsl_operands = 0;
1675 rtx mask = gen_reg_rtx (<V_cmp_result>mode);
1676 rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
1678 rtx (*base_comparison) (rtx, rtx, rtx, rtx);
1679 rtx (*complimentary_comparison) (rtx, rtx, rtx, rtx);
1681 switch (GET_CODE (operands[3]))
1686 if (!REG_P (operands[5])
1687 && (operands[5] != CONST0_RTX (<MODE>mode)))
1688 operands[5] = force_reg (<MODE>mode, operands[5]);
1691 if (!REG_P (operands[5]))
1692 operands[5] = force_reg (<MODE>mode, operands[5]);
1695 switch (GET_CODE (operands[3]))
1705 base_comparison = gen_neon_vcge<mode>;
1706 complimentary_comparison = gen_neon_vcgt<mode>;
1714 base_comparison = gen_neon_vcgt<mode>;
1715 complimentary_comparison = gen_neon_vcge<mode>;
1720 base_comparison = gen_neon_vceq<mode>;
1721 complimentary_comparison = gen_neon_vceq<mode>;
1727 switch (GET_CODE (operands[3]))
1734 /* The easy case. Here we emit one of vcge, vcgt or vceq.
1735 As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
1743 emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1745 emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1752 /* Vector compare returns false for lanes which are unordered, so if we use
1753 the inverse of the comparison we actually want to emit, then
1754 swap the operands to BSL, we will end up with the correct result.
1755 Note that a NE NaN and NaN NE b are true for all a, b.
1757 Our transformations are:
1762 a NE b -> !(a EQ b) */
1765 emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1767 emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1769 swap_bsl_operands = 1;
1772 /* We check (a > b || b > a). combining these comparisons give us
1773 true iff !(a != b && a ORDERED b), swapping the operands to BSL
1774 will then give us (a == b || a UNORDERED b) as intended. */
1776 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5], magic_rtx));
1777 emit_insn (gen_neon_vcgt<mode> (tmp, operands[5], operands[4], magic_rtx));
1778 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1779 swap_bsl_operands = 1;
1782 /* Operands are ORDERED iff (a > b || b >= a).
1783 Swapping the operands to BSL will give the UNORDERED case. */
1784 swap_bsl_operands = 1;
1787 emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5], magic_rtx));
1788 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4], magic_rtx));
1789 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1795 if (swap_bsl_operands)
1796 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1799 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1804 (define_expand "vcondu<mode><mode>"
1805 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1807 (match_operator 3 "arm_comparison_operator"
1808 [(match_operand:VDQIW 4 "s_register_operand" "")
1809 (match_operand:VDQIW 5 "s_register_operand" "")])
1810 (match_operand:VDQIW 1 "s_register_operand" "")
1811 (match_operand:VDQIW 2 "s_register_operand" "")))]
1815 int inverse = 0, immediate_zero = 0;
1817 mask = gen_reg_rtx (<V_cmp_result>mode);
1819 if (operands[5] == CONST0_RTX (<MODE>mode))
1821 else if (!REG_P (operands[5]))
1822 operands[5] = force_reg (<MODE>mode, operands[5]);
1824 switch (GET_CODE (operands[3]))
1827 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1832 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1837 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1843 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1846 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1852 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1855 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1860 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1870 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1873 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1879 ;; Patterns for builtins.
1881 ; good for plain vadd, vaddq.
1883 (define_expand "neon_vadd<mode>"
1884 [(match_operand:VDQX 0 "s_register_operand" "=w")
1885 (match_operand:VDQX 1 "s_register_operand" "w")
1886 (match_operand:VDQX 2 "s_register_operand" "w")
1887 (match_operand:SI 3 "immediate_operand" "i")]
1890 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1891 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
1893 emit_insn (gen_neon_vadd<mode>_unspec (operands[0], operands[1],
1898 ; Note that NEON operations don't support the full IEEE 754 standard: in
1899 ; particular, denormal values are flushed to zero. This means that GCC cannot
1900 ; use those instructions for autovectorization, etc. unless
1901 ; -funsafe-math-optimizations is in effect (in which case flush-to-zero
1902 ; behaviour is permissible). Intrinsic operations (provided by the arm_neon.h
1903 ; header) must work in either case: if -funsafe-math-optimizations is given,
1904 ; intrinsics expand to "canonical" RTL where possible, otherwise intrinsics
1905 ; expand to unspecs (which may potentially limit the extent to which they might
1906 ; be optimized by generic code).
1908 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1910 (define_insn "neon_vadd<mode>_unspec"
1911 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1912 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1913 (match_operand:VDQX 2 "s_register_operand" "w")]
1916 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1917 [(set (attr "neon_type")
1918 (if_then_else (match_test "<Is_float_mode>")
1919 (if_then_else (match_test "<Is_d_reg>")
1920 (const_string "neon_fp_vadd_ddd_vabs_dd")
1921 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1922 (const_string "neon_int_1")))]
1925 ; operand 3 represents in bits:
1926 ; bit 0: signed (vs unsigned).
1927 ; bit 1: rounding (vs none).
1929 (define_insn "neon_vaddl<mode>"
1930 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1931 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1932 (match_operand:VDI 2 "s_register_operand" "w")
1933 (match_operand:SI 3 "immediate_operand" "i")]
1936 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1937 [(set_attr "neon_type" "neon_int_3")]
1940 (define_insn "neon_vaddw<mode>"
1941 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1942 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1943 (match_operand:VDI 2 "s_register_operand" "w")
1944 (match_operand:SI 3 "immediate_operand" "i")]
1947 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1948 [(set_attr "neon_type" "neon_int_2")]
1953 (define_insn "neon_vhadd<mode>"
1954 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1955 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1956 (match_operand:VDQIW 2 "s_register_operand" "w")
1957 (match_operand:SI 3 "immediate_operand" "i")]
1960 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1961 [(set_attr "neon_type" "neon_int_4")]
1964 (define_insn "neon_vqadd<mode>"
1965 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1966 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1967 (match_operand:VDQIX 2 "s_register_operand" "w")
1968 (match_operand:SI 3 "immediate_operand" "i")]
1971 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1972 [(set_attr "neon_type" "neon_int_4")]
1975 (define_insn "neon_vaddhn<mode>"
1976 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1977 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1978 (match_operand:VN 2 "s_register_operand" "w")
1979 (match_operand:SI 3 "immediate_operand" "i")]
1982 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
1983 [(set_attr "neon_type" "neon_int_4")]
1986 ;; We cannot replace this unspec with mul<mode>3 because of the odd
1987 ;; polynomial multiplication case that can specified by operand 3.
1988 (define_insn "neon_vmul<mode>"
1989 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1990 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1991 (match_operand:VDQW 2 "s_register_operand" "w")
1992 (match_operand:SI 3 "immediate_operand" "i")]
1995 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1996 [(set (attr "neon_type")
1997 (if_then_else (match_test "<Is_float_mode>")
1998 (if_then_else (match_test "<Is_d_reg>")
1999 (const_string "neon_fp_vadd_ddd_vabs_dd")
2000 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2001 (if_then_else (match_test "<Is_d_reg>")
2003 (match_test "<Scalar_mul_8_16>")
2004 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2005 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2006 (if_then_else (match_test "<Scalar_mul_8_16>")
2007 (const_string "neon_mul_qqq_8_16_32_ddd_32")
2008 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
2011 (define_expand "neon_vmla<mode>"
2012 [(match_operand:VDQW 0 "s_register_operand" "=w")
2013 (match_operand:VDQW 1 "s_register_operand" "0")
2014 (match_operand:VDQW 2 "s_register_operand" "w")
2015 (match_operand:VDQW 3 "s_register_operand" "w")
2016 (match_operand:SI 4 "immediate_operand" "i")]
2019 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2020 emit_insn (gen_mul<mode>3add<mode>_neon (operands[0], operands[1],
2021 operands[2], operands[3]));
2023 emit_insn (gen_neon_vmla<mode>_unspec (operands[0], operands[1],
2024 operands[2], operands[3]));
2028 (define_expand "neon_vfma<VCVTF:mode>"
2029 [(match_operand:VCVTF 0 "s_register_operand")
2030 (match_operand:VCVTF 1 "s_register_operand")
2031 (match_operand:VCVTF 2 "s_register_operand")
2032 (match_operand:VCVTF 3 "s_register_operand")
2033 (match_operand:SI 4 "immediate_operand")]
2034 "TARGET_NEON && TARGET_FMA"
2036 emit_insn (gen_fma<mode>4_intrinsic (operands[0], operands[2], operands[3],
2041 (define_expand "neon_vfms<VCVTF:mode>"
2042 [(match_operand:VCVTF 0 "s_register_operand")
2043 (match_operand:VCVTF 1 "s_register_operand")
2044 (match_operand:VCVTF 2 "s_register_operand")
2045 (match_operand:VCVTF 3 "s_register_operand")
2046 (match_operand:SI 4 "immediate_operand")]
2047 "TARGET_NEON && TARGET_FMA"
2049 emit_insn (gen_fmsub<mode>4_intrinsic (operands[0], operands[2], operands[3],
2054 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2056 (define_insn "neon_vmla<mode>_unspec"
2057 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2058 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2059 (match_operand:VDQ 2 "s_register_operand" "w")
2060 (match_operand:VDQ 3 "s_register_operand" "w")]
2063 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2064 [(set (attr "neon_type")
2065 (if_then_else (match_test "<Is_float_mode>")
2066 (if_then_else (match_test "<Is_d_reg>")
2067 (const_string "neon_fp_vmla_ddd")
2068 (const_string "neon_fp_vmla_qqq"))
2069 (if_then_else (match_test "<Is_d_reg>")
2071 (match_test "<Scalar_mul_8_16>")
2072 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2073 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2074 (if_then_else (match_test "<Scalar_mul_8_16>")
2075 (const_string "neon_mla_qqq_8_16")
2076 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2079 (define_insn "neon_vmlal<mode>"
2080 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2081 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2082 (match_operand:VW 2 "s_register_operand" "w")
2083 (match_operand:VW 3 "s_register_operand" "w")
2084 (match_operand:SI 4 "immediate_operand" "i")]
2087 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2088 [(set (attr "neon_type")
2089 (if_then_else (match_test "<Scalar_mul_8_16>")
2090 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2091 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2094 (define_expand "neon_vmls<mode>"
2095 [(match_operand:VDQW 0 "s_register_operand" "=w")
2096 (match_operand:VDQW 1 "s_register_operand" "0")
2097 (match_operand:VDQW 2 "s_register_operand" "w")
2098 (match_operand:VDQW 3 "s_register_operand" "w")
2099 (match_operand:SI 4 "immediate_operand" "i")]
2102 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2103 emit_insn (gen_mul<mode>3neg<mode>add<mode>_neon (operands[0],
2104 operands[1], operands[2], operands[3]));
2106 emit_insn (gen_neon_vmls<mode>_unspec (operands[0], operands[1],
2107 operands[2], operands[3]));
2111 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2113 (define_insn "neon_vmls<mode>_unspec"
2114 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2115 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2116 (match_operand:VDQ 2 "s_register_operand" "w")
2117 (match_operand:VDQ 3 "s_register_operand" "w")]
2120 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2121 [(set (attr "neon_type")
2122 (if_then_else (match_test "<Is_float_mode>")
2123 (if_then_else (match_test "<Is_d_reg>")
2124 (const_string "neon_fp_vmla_ddd")
2125 (const_string "neon_fp_vmla_qqq"))
2126 (if_then_else (match_test "<Is_d_reg>")
2128 (match_test "<Scalar_mul_8_16>")
2129 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2130 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2132 (match_test "<Scalar_mul_8_16>")
2133 (const_string "neon_mla_qqq_8_16")
2134 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2137 (define_insn "neon_vmlsl<mode>"
2138 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2139 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2140 (match_operand:VW 2 "s_register_operand" "w")
2141 (match_operand:VW 3 "s_register_operand" "w")
2142 (match_operand:SI 4 "immediate_operand" "i")]
2145 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2146 [(set (attr "neon_type")
2147 (if_then_else (match_test "<Scalar_mul_8_16>")
2148 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2149 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2152 (define_insn "neon_vqdmulh<mode>"
2153 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
2154 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
2155 (match_operand:VMDQI 2 "s_register_operand" "w")
2156 (match_operand:SI 3 "immediate_operand" "i")]
2159 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2160 [(set (attr "neon_type")
2161 (if_then_else (match_test "<Is_d_reg>")
2162 (if_then_else (match_test "<Scalar_mul_8_16>")
2163 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2164 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2165 (if_then_else (match_test "<Scalar_mul_8_16>")
2166 (const_string "neon_mul_qqq_8_16_32_ddd_32")
2167 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
2170 (define_insn "neon_vqdmlal<mode>"
2171 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2172 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2173 (match_operand:VMDI 2 "s_register_operand" "w")
2174 (match_operand:VMDI 3 "s_register_operand" "w")
2175 (match_operand:SI 4 "immediate_operand" "i")]
2178 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
2179 [(set (attr "neon_type")
2180 (if_then_else (match_test "<Scalar_mul_8_16>")
2181 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2182 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2185 (define_insn "neon_vqdmlsl<mode>"
2186 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2187 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2188 (match_operand:VMDI 2 "s_register_operand" "w")
2189 (match_operand:VMDI 3 "s_register_operand" "w")
2190 (match_operand:SI 4 "immediate_operand" "i")]
2193 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
2194 [(set (attr "neon_type")
2195 (if_then_else (match_test "<Scalar_mul_8_16>")
2196 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2197 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2200 (define_insn "neon_vmull<mode>"
2201 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2202 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2203 (match_operand:VW 2 "s_register_operand" "w")
2204 (match_operand:SI 3 "immediate_operand" "i")]
2207 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2208 [(set (attr "neon_type")
2209 (if_then_else (match_test "<Scalar_mul_8_16>")
2210 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2211 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2214 (define_insn "neon_vqdmull<mode>"
2215 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2216 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2217 (match_operand:VMDI 2 "s_register_operand" "w")
2218 (match_operand:SI 3 "immediate_operand" "i")]
2221 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
2222 [(set (attr "neon_type")
2223 (if_then_else (match_test "<Scalar_mul_8_16>")
2224 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2225 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2228 (define_expand "neon_vsub<mode>"
2229 [(match_operand:VDQX 0 "s_register_operand" "=w")
2230 (match_operand:VDQX 1 "s_register_operand" "w")
2231 (match_operand:VDQX 2 "s_register_operand" "w")
2232 (match_operand:SI 3 "immediate_operand" "i")]
2235 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2236 emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
2238 emit_insn (gen_neon_vsub<mode>_unspec (operands[0], operands[1],
2243 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2245 (define_insn "neon_vsub<mode>_unspec"
2246 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2247 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2248 (match_operand:VDQX 2 "s_register_operand" "w")]
2251 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2252 [(set (attr "neon_type")
2253 (if_then_else (match_test "<Is_float_mode>")
2254 (if_then_else (match_test "<Is_d_reg>")
2255 (const_string "neon_fp_vadd_ddd_vabs_dd")
2256 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2257 (const_string "neon_int_2")))]
2260 (define_insn "neon_vsubl<mode>"
2261 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2262 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
2263 (match_operand:VDI 2 "s_register_operand" "w")
2264 (match_operand:SI 3 "immediate_operand" "i")]
2267 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2268 [(set_attr "neon_type" "neon_int_2")]
2271 (define_insn "neon_vsubw<mode>"
2272 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2273 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2274 (match_operand:VDI 2 "s_register_operand" "w")
2275 (match_operand:SI 3 "immediate_operand" "i")]
2278 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2279 [(set_attr "neon_type" "neon_int_2")]
2282 (define_insn "neon_vqsub<mode>"
2283 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2284 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2285 (match_operand:VDQIX 2 "s_register_operand" "w")
2286 (match_operand:SI 3 "immediate_operand" "i")]
2289 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2290 [(set_attr "neon_type" "neon_int_5")]
2293 (define_insn "neon_vhsub<mode>"
2294 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2295 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2296 (match_operand:VDQIW 2 "s_register_operand" "w")
2297 (match_operand:SI 3 "immediate_operand" "i")]
2300 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2301 [(set_attr "neon_type" "neon_int_5")]
2304 (define_insn "neon_vsubhn<mode>"
2305 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2306 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2307 (match_operand:VN 2 "s_register_operand" "w")
2308 (match_operand:SI 3 "immediate_operand" "i")]
2311 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2312 [(set_attr "neon_type" "neon_int_4")]
2315 (define_insn "neon_vceq<mode>"
2316 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2317 (unspec:<V_cmp_result>
2318 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2319 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2320 (match_operand:SI 3 "immediate_operand" "i,i")]
2324 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2325 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
2326 [(set (attr "neon_type")
2327 (if_then_else (match_test "<Is_float_mode>")
2328 (if_then_else (match_test "<Is_d_reg>")
2329 (const_string "neon_fp_vadd_ddd_vabs_dd")
2330 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2331 (const_string "neon_int_5")))]
2334 (define_insn "neon_vcge<mode>"
2335 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2336 (unspec:<V_cmp_result>
2337 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2338 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2339 (match_operand:SI 3 "immediate_operand" "i,i")]
2343 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2344 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2345 [(set (attr "neon_type")
2346 (if_then_else (match_test "<Is_float_mode>")
2347 (if_then_else (match_test "<Is_d_reg>")
2348 (const_string "neon_fp_vadd_ddd_vabs_dd")
2349 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2350 (const_string "neon_int_5")))]
2353 (define_insn "neon_vcgeu<mode>"
2354 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2355 (unspec:<V_cmp_result>
2356 [(match_operand:VDQIW 1 "s_register_operand" "w")
2357 (match_operand:VDQIW 2 "s_register_operand" "w")
2358 (match_operand:SI 3 "immediate_operand" "i")]
2361 "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2362 [(set_attr "neon_type" "neon_int_5")]
2365 (define_insn "neon_vcgt<mode>"
2366 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2367 (unspec:<V_cmp_result>
2368 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2369 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2370 (match_operand:SI 3 "immediate_operand" "i,i")]
2374 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2375 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2376 [(set (attr "neon_type")
2377 (if_then_else (match_test "<Is_float_mode>")
2378 (if_then_else (match_test "<Is_d_reg>")
2379 (const_string "neon_fp_vadd_ddd_vabs_dd")
2380 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2381 (const_string "neon_int_5")))]
2384 (define_insn "neon_vcgtu<mode>"
2385 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2386 (unspec:<V_cmp_result>
2387 [(match_operand:VDQIW 1 "s_register_operand" "w")
2388 (match_operand:VDQIW 2 "s_register_operand" "w")
2389 (match_operand:SI 3 "immediate_operand" "i")]
2392 "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2393 [(set_attr "neon_type" "neon_int_5")]
2396 ;; VCLE and VCLT only support comparisons with immediate zero (register
2397 ;; variants are VCGE and VCGT with operands reversed).
2399 (define_insn "neon_vcle<mode>"
2400 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2401 (unspec:<V_cmp_result>
2402 [(match_operand:VDQW 1 "s_register_operand" "w")
2403 (match_operand:VDQW 2 "zero_operand" "Dz")
2404 (match_operand:SI 3 "immediate_operand" "i")]
2407 "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2408 [(set (attr "neon_type")
2409 (if_then_else (match_test "<Is_float_mode>")
2410 (if_then_else (match_test "<Is_d_reg>")
2411 (const_string "neon_fp_vadd_ddd_vabs_dd")
2412 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2413 (const_string "neon_int_5")))]
2416 (define_insn "neon_vclt<mode>"
2417 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2418 (unspec:<V_cmp_result>
2419 [(match_operand:VDQW 1 "s_register_operand" "w")
2420 (match_operand:VDQW 2 "zero_operand" "Dz")
2421 (match_operand:SI 3 "immediate_operand" "i")]
2424 "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2425 [(set (attr "neon_type")
2426 (if_then_else (match_test "<Is_float_mode>")
2427 (if_then_else (match_test "<Is_d_reg>")
2428 (const_string "neon_fp_vadd_ddd_vabs_dd")
2429 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2430 (const_string "neon_int_5")))]
2433 (define_insn "neon_vcage<mode>"
2434 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2435 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2436 (match_operand:VCVTF 2 "s_register_operand" "w")
2437 (match_operand:SI 3 "immediate_operand" "i")]
2440 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2441 [(set (attr "neon_type")
2442 (if_then_else (match_test "<Is_d_reg>")
2443 (const_string "neon_fp_vadd_ddd_vabs_dd")
2444 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2447 (define_insn "neon_vcagt<mode>"
2448 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2449 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2450 (match_operand:VCVTF 2 "s_register_operand" "w")
2451 (match_operand:SI 3 "immediate_operand" "i")]
2454 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2455 [(set (attr "neon_type")
2456 (if_then_else (match_test "<Is_d_reg>")
2457 (const_string "neon_fp_vadd_ddd_vabs_dd")
2458 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2461 (define_insn "neon_vtst<mode>"
2462 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2463 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2464 (match_operand:VDQIW 2 "s_register_operand" "w")
2465 (match_operand:SI 3 "immediate_operand" "i")]
2468 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2469 [(set_attr "neon_type" "neon_int_4")]
2472 (define_insn "neon_vabd<mode>"
2473 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2474 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2475 (match_operand:VDQW 2 "s_register_operand" "w")
2476 (match_operand:SI 3 "immediate_operand" "i")]
2479 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2480 [(set (attr "neon_type")
2481 (if_then_else (match_test "<Is_float_mode>")
2482 (if_then_else (match_test "<Is_d_reg>")
2483 (const_string "neon_fp_vadd_ddd_vabs_dd")
2484 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2485 (const_string "neon_int_5")))]
2488 (define_insn "neon_vabdl<mode>"
2489 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2490 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2491 (match_operand:VW 2 "s_register_operand" "w")
2492 (match_operand:SI 3 "immediate_operand" "i")]
2495 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2496 [(set_attr "neon_type" "neon_int_5")]
2499 (define_insn "neon_vaba<mode>"
2500 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2501 (plus:VDQIW (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w")
2502 (match_operand:VDQIW 3 "s_register_operand" "w")
2503 (match_operand:SI 4 "immediate_operand" "i")]
2505 (match_operand:VDQIW 1 "s_register_operand" "0")))]
2507 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2508 [(set (attr "neon_type")
2509 (if_then_else (match_test "<Is_d_reg>")
2510 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2513 (define_insn "neon_vabal<mode>"
2514 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2515 (plus:<V_widen> (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w")
2516 (match_operand:VW 3 "s_register_operand" "w")
2517 (match_operand:SI 4 "immediate_operand" "i")]
2519 (match_operand:<V_widen> 1 "s_register_operand" "0")))]
2521 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2522 [(set_attr "neon_type" "neon_vaba")]
2525 (define_insn "neon_vmax<mode>"
2526 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2527 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2528 (match_operand:VDQW 2 "s_register_operand" "w")
2529 (match_operand:SI 3 "immediate_operand" "i")]
2532 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2533 [(set (attr "neon_type")
2534 (if_then_else (match_test "<Is_float_mode>")
2535 (if_then_else (match_test "<Is_d_reg>")
2536 (const_string "neon_fp_vadd_ddd_vabs_dd")
2537 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2538 (const_string "neon_int_5")))]
2541 (define_insn "neon_vmin<mode>"
2542 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2543 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2544 (match_operand:VDQW 2 "s_register_operand" "w")
2545 (match_operand:SI 3 "immediate_operand" "i")]
2548 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2549 [(set (attr "neon_type")
2550 (if_then_else (match_test "<Is_float_mode>")
2551 (if_then_else (match_test "<Is_d_reg>")
2552 (const_string "neon_fp_vadd_ddd_vabs_dd")
2553 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2554 (const_string "neon_int_5")))]
2557 (define_expand "neon_vpadd<mode>"
2558 [(match_operand:VD 0 "s_register_operand" "=w")
2559 (match_operand:VD 1 "s_register_operand" "w")
2560 (match_operand:VD 2 "s_register_operand" "w")
2561 (match_operand:SI 3 "immediate_operand" "i")]
2564 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2569 (define_insn "neon_vpaddl<mode>"
2570 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2571 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2572 (match_operand:SI 2 "immediate_operand" "i")]
2575 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2576 ;; Assume this schedules like vaddl.
2577 [(set_attr "neon_type" "neon_int_3")]
2580 (define_insn "neon_vpadal<mode>"
2581 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2582 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2583 (match_operand:VDQIW 2 "s_register_operand" "w")
2584 (match_operand:SI 3 "immediate_operand" "i")]
2587 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2588 ;; Assume this schedules like vpadd.
2589 [(set_attr "neon_type" "neon_int_1")]
2592 (define_insn "neon_vpmax<mode>"
2593 [(set (match_operand:VD 0 "s_register_operand" "=w")
2594 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2595 (match_operand:VD 2 "s_register_operand" "w")
2596 (match_operand:SI 3 "immediate_operand" "i")]
2599 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2600 ;; Assume this schedules like vmax.
2601 [(set (attr "neon_type")
2602 (if_then_else (match_test "<Is_float_mode>")
2603 (const_string "neon_fp_vadd_ddd_vabs_dd")
2604 (const_string "neon_int_5")))]
2607 (define_insn "neon_vpmin<mode>"
2608 [(set (match_operand:VD 0 "s_register_operand" "=w")
2609 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2610 (match_operand:VD 2 "s_register_operand" "w")
2611 (match_operand:SI 3 "immediate_operand" "i")]
2614 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2615 ;; Assume this schedules like vmin.
2616 [(set (attr "neon_type")
2617 (if_then_else (match_test "<Is_float_mode>")
2618 (const_string "neon_fp_vadd_ddd_vabs_dd")
2619 (const_string "neon_int_5")))]
2622 (define_insn "neon_vrecps<mode>"
2623 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2624 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2625 (match_operand:VCVTF 2 "s_register_operand" "w")
2626 (match_operand:SI 3 "immediate_operand" "i")]
2629 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2630 [(set (attr "neon_type")
2631 (if_then_else (match_test "<Is_d_reg>")
2632 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2633 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2636 (define_insn "neon_vrsqrts<mode>"
2637 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2638 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2639 (match_operand:VCVTF 2 "s_register_operand" "w")
2640 (match_operand:SI 3 "immediate_operand" "i")]
2643 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2644 [(set (attr "neon_type")
2645 (if_then_else (match_test "<Is_d_reg>")
2646 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2647 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2650 (define_expand "neon_vabs<mode>"
2651 [(match_operand:VDQW 0 "s_register_operand" "")
2652 (match_operand:VDQW 1 "s_register_operand" "")
2653 (match_operand:SI 2 "immediate_operand" "")]
2656 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
2660 (define_insn "neon_vqabs<mode>"
2661 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2662 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2663 (match_operand:SI 2 "immediate_operand" "i")]
2666 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2667 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2670 (define_expand "neon_vneg<mode>"
2671 [(match_operand:VDQW 0 "s_register_operand" "")
2672 (match_operand:VDQW 1 "s_register_operand" "")
2673 (match_operand:SI 2 "immediate_operand" "")]
2676 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2680 (define_insn "neon_vqneg<mode>"
2681 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2682 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2683 (match_operand:SI 2 "immediate_operand" "i")]
2686 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2687 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2690 (define_insn "neon_vcls<mode>"
2691 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2692 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2693 (match_operand:SI 2 "immediate_operand" "i")]
2696 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2697 [(set_attr "neon_type" "neon_int_1")]
2700 (define_insn "clz<mode>2"
2701 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2702 (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
2704 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2705 [(set_attr "neon_type" "neon_int_1")]
2708 (define_expand "neon_vclz<mode>"
2709 [(match_operand:VDQIW 0 "s_register_operand" "")
2710 (match_operand:VDQIW 1 "s_register_operand" "")
2711 (match_operand:SI 2 "immediate_operand" "")]
2714 emit_insn (gen_clz<mode>2 (operands[0], operands[1]));
2718 (define_insn "popcount<mode>2"
2719 [(set (match_operand:VE 0 "s_register_operand" "=w")
2720 (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
2722 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2723 [(set_attr "neon_type" "neon_int_1")]
2726 (define_expand "neon_vcnt<mode>"
2727 [(match_operand:VE 0 "s_register_operand" "=w")
2728 (match_operand:VE 1 "s_register_operand" "w")
2729 (match_operand:SI 2 "immediate_operand" "i")]
2732 emit_insn (gen_popcount<mode>2 (operands[0], operands[1]));
2736 (define_insn "neon_vrecpe<mode>"
2737 [(set (match_operand:V32 0 "s_register_operand" "=w")
2738 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2739 (match_operand:SI 2 "immediate_operand" "i")]
2742 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2743 [(set (attr "neon_type")
2744 (if_then_else (match_test "<Is_d_reg>")
2745 (const_string "neon_fp_vadd_ddd_vabs_dd")
2746 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2749 (define_insn "neon_vrsqrte<mode>"
2750 [(set (match_operand:V32 0 "s_register_operand" "=w")
2751 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2752 (match_operand:SI 2 "immediate_operand" "i")]
2755 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2756 [(set (attr "neon_type")
2757 (if_then_else (match_test "<Is_d_reg>")
2758 (const_string "neon_fp_vadd_ddd_vabs_dd")
2759 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2762 (define_expand "neon_vmvn<mode>"
2763 [(match_operand:VDQIW 0 "s_register_operand" "")
2764 (match_operand:VDQIW 1 "s_register_operand" "")
2765 (match_operand:SI 2 "immediate_operand" "")]
2768 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2772 (define_insn "neon_vget_lane<mode>_sext_internal"
2773 [(set (match_operand:SI 0 "s_register_operand" "=r")
2775 (vec_select:<V_elem>
2776 (match_operand:VD 1 "s_register_operand" "w")
2777 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2780 if (BYTES_BIG_ENDIAN)
2782 int elt = INTVAL (operands[2]);
2783 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2784 operands[2] = GEN_INT (elt);
2786 return "vmov.s<V_sz_elem>\t%0, %P1[%c2]";
2788 [(set_attr "neon_type" "neon_bp_simple")]
2791 (define_insn "neon_vget_lane<mode>_zext_internal"
2792 [(set (match_operand:SI 0 "s_register_operand" "=r")
2794 (vec_select:<V_elem>
2795 (match_operand:VD 1 "s_register_operand" "w")
2796 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2799 if (BYTES_BIG_ENDIAN)
2801 int elt = INTVAL (operands[2]);
2802 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2803 operands[2] = GEN_INT (elt);
2805 return "vmov.u<V_sz_elem>\t%0, %P1[%c2]";
2807 [(set_attr "neon_type" "neon_bp_simple")]
2810 (define_insn "neon_vget_lane<mode>_sext_internal"
2811 [(set (match_operand:SI 0 "s_register_operand" "=r")
2813 (vec_select:<V_elem>
2814 (match_operand:VQ 1 "s_register_operand" "w")
2815 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2819 int regno = REGNO (operands[1]);
2820 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2821 unsigned int elt = INTVAL (operands[2]);
2822 unsigned int elt_adj = elt % halfelts;
2824 if (BYTES_BIG_ENDIAN)
2825 elt_adj = halfelts - 1 - elt_adj;
2827 ops[0] = operands[0];
2828 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2829 ops[2] = GEN_INT (elt_adj);
2830 output_asm_insn ("vmov.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2834 [(set_attr "neon_type" "neon_bp_simple")]
2837 (define_insn "neon_vget_lane<mode>_zext_internal"
2838 [(set (match_operand:SI 0 "s_register_operand" "=r")
2840 (vec_select:<V_elem>
2841 (match_operand:VQ 1 "s_register_operand" "w")
2842 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2846 int regno = REGNO (operands[1]);
2847 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2848 unsigned int elt = INTVAL (operands[2]);
2849 unsigned int elt_adj = elt % halfelts;
2851 if (BYTES_BIG_ENDIAN)
2852 elt_adj = halfelts - 1 - elt_adj;
2854 ops[0] = operands[0];
2855 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2856 ops[2] = GEN_INT (elt_adj);
2857 output_asm_insn ("vmov.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2861 [(set_attr "neon_type" "neon_bp_simple")]
2864 (define_expand "neon_vget_lane<mode>"
2865 [(match_operand:<V_ext> 0 "s_register_operand" "")
2866 (match_operand:VDQW 1 "s_register_operand" "")
2867 (match_operand:SI 2 "immediate_operand" "")
2868 (match_operand:SI 3 "immediate_operand" "")]
2871 HOST_WIDE_INT magic = INTVAL (operands[3]);
2874 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2876 if (BYTES_BIG_ENDIAN)
2878 /* The intrinsics are defined in terms of a model where the
2879 element ordering in memory is vldm order, whereas the generic
2880 RTL is defined in terms of a model where the element ordering
2881 in memory is array order. Convert the lane number to conform
2883 unsigned int elt = INTVAL (operands[2]);
2884 unsigned int reg_nelts
2885 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2886 elt ^= reg_nelts - 1;
2887 operands[2] = GEN_INT (elt);
2890 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2891 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2894 if ((magic & 1) != 0)
2895 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2898 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2905 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2908 (define_expand "neon_vget_lanedi"
2909 [(match_operand:DI 0 "s_register_operand" "=r")
2910 (match_operand:DI 1 "s_register_operand" "w")
2911 (match_operand:SI 2 "immediate_operand" "i")
2912 (match_operand:SI 3 "immediate_operand" "i")]
2915 neon_lane_bounds (operands[2], 0, 1);
2916 emit_move_insn (operands[0], operands[1]);
2920 (define_expand "neon_vget_lanev2di"
2921 [(match_operand:DI 0 "s_register_operand" "")
2922 (match_operand:V2DI 1 "s_register_operand" "")
2923 (match_operand:SI 2 "immediate_operand" "")
2924 (match_operand:SI 3 "immediate_operand" "")]
2927 switch (INTVAL (operands[2]))
2930 emit_move_insn (operands[0], gen_lowpart (DImode, operands[1]));
2933 emit_move_insn (operands[0], gen_highpart (DImode, operands[1]));
2936 neon_lane_bounds (operands[2], 0, 1);
2942 (define_expand "neon_vset_lane<mode>"
2943 [(match_operand:VDQ 0 "s_register_operand" "=w")
2944 (match_operand:<V_elem> 1 "s_register_operand" "r")
2945 (match_operand:VDQ 2 "s_register_operand" "0")
2946 (match_operand:SI 3 "immediate_operand" "i")]
2949 unsigned int elt = INTVAL (operands[3]);
2950 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2952 if (BYTES_BIG_ENDIAN)
2954 unsigned int reg_nelts
2955 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2956 elt ^= reg_nelts - 1;
2959 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
2960 GEN_INT (1 << elt), operands[2]));
2964 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2966 (define_expand "neon_vset_lanedi"
2967 [(match_operand:DI 0 "s_register_operand" "=w")
2968 (match_operand:DI 1 "s_register_operand" "r")
2969 (match_operand:DI 2 "s_register_operand" "0")
2970 (match_operand:SI 3 "immediate_operand" "i")]
2973 neon_lane_bounds (operands[3], 0, 1);
2974 emit_move_insn (operands[0], operands[1]);
2978 (define_expand "neon_vcreate<mode>"
2979 [(match_operand:VDX 0 "s_register_operand" "")
2980 (match_operand:DI 1 "general_operand" "")]
2983 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2984 emit_move_insn (operands[0], src);
2988 (define_insn "neon_vdup_n<mode>"
2989 [(set (match_operand:VX 0 "s_register_operand" "=w")
2990 (vec_duplicate:VX (match_operand:<V_elem> 1 "s_register_operand" "r")))]
2992 "vdup.<V_sz_elem>\t%<V_reg>0, %1"
2993 ;; Assume this schedules like vmov.
2994 [(set_attr "neon_type" "neon_bp_simple")]
2997 (define_insn "neon_vdup_n<mode>"
2998 [(set (match_operand:V32 0 "s_register_operand" "=w,w")
2999 (vec_duplicate:V32 (match_operand:<V_elem> 1 "s_register_operand" "r,t")))]
3002 vdup.<V_sz_elem>\t%<V_reg>0, %1
3003 vdup.<V_sz_elem>\t%<V_reg>0, %y1"
3004 ;; Assume this schedules like vmov.
3005 [(set_attr "neon_type" "neon_bp_simple")]
3008 (define_expand "neon_vdup_ndi"
3009 [(match_operand:DI 0 "s_register_operand" "=w")
3010 (match_operand:DI 1 "s_register_operand" "r")]
3013 emit_move_insn (operands[0], operands[1]);
3018 (define_insn "neon_vdup_nv2di"
3019 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
3020 (vec_duplicate:V2DI (match_operand:DI 1 "s_register_operand" "r,w")))]
3023 vmov\t%e0, %Q1, %R1\;vmov\t%f0, %Q1, %R1
3024 vmov\t%e0, %P1\;vmov\t%f0, %P1"
3025 [(set_attr "length" "8")
3026 (set_attr "neon_type" "neon_bp_simple")]
3029 (define_insn "neon_vdup_lane<mode>_internal"
3030 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3032 (vec_select:<V_elem>
3033 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3034 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
3037 if (BYTES_BIG_ENDIAN)
3039 int elt = INTVAL (operands[2]);
3040 elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
3041 operands[2] = GEN_INT (elt);
3044 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
3046 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
3048 ;; Assume this schedules like vmov.
3049 [(set_attr "neon_type" "neon_bp_simple")]
3052 (define_expand "neon_vdup_lane<mode>"
3053 [(match_operand:VDQW 0 "s_register_operand" "=w")
3054 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3055 (match_operand:SI 2 "immediate_operand" "i")]
3058 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_double_vector_mode>mode));
3059 if (BYTES_BIG_ENDIAN)
3061 unsigned int elt = INTVAL (operands[2]);
3062 unsigned int reg_nelts
3063 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<V_double_vector_mode>mode));
3064 elt ^= reg_nelts - 1;
3065 operands[2] = GEN_INT (elt);
3067 emit_insn (gen_neon_vdup_lane<mode>_internal (operands[0], operands[1],
3072 ; Scalar index is ignored, since only zero is valid here.
3073 (define_expand "neon_vdup_lanedi"
3074 [(match_operand:DI 0 "s_register_operand" "=w")
3075 (match_operand:DI 1 "s_register_operand" "w")
3076 (match_operand:SI 2 "immediate_operand" "i")]
3079 neon_lane_bounds (operands[2], 0, 1);
3080 emit_move_insn (operands[0], operands[1]);
3084 ; Likewise for v2di, as the DImode second operand has only a single element.
3085 (define_expand "neon_vdup_lanev2di"
3086 [(match_operand:V2DI 0 "s_register_operand" "=w")
3087 (match_operand:DI 1 "s_register_operand" "w")
3088 (match_operand:SI 2 "immediate_operand" "i")]
3091 neon_lane_bounds (operands[2], 0, 1);
3092 emit_insn (gen_neon_vdup_nv2di (operands[0], operands[1]));
3096 ; Disabled before reload because we don't want combine doing something silly,
3097 ; but used by the post-reload expansion of neon_vcombine.
3098 (define_insn "*neon_vswp<mode>"
3099 [(set (match_operand:VDQX 0 "s_register_operand" "+w")
3100 (match_operand:VDQX 1 "s_register_operand" "+w"))
3101 (set (match_dup 1) (match_dup 0))]
3102 "TARGET_NEON && reload_completed"
3103 "vswp\t%<V_reg>0, %<V_reg>1"
3104 [(set (attr "neon_type")
3105 (if_then_else (match_test "<Is_d_reg>")
3106 (const_string "neon_bp_simple")
3107 (const_string "neon_bp_2cycle")))]
3110 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
3112 ;; FIXME: A different implementation of this builtin could make it much
3113 ;; more likely that we wouldn't actually need to output anything (we could make
3114 ;; it so that the reg allocator puts things in the right places magically
3115 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
3117 (define_insn_and_split "neon_vcombine<mode>"
3118 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
3119 (vec_concat:<V_DOUBLE>
3120 (match_operand:VDX 1 "s_register_operand" "w")
3121 (match_operand:VDX 2 "s_register_operand" "w")))]
3124 "&& reload_completed"
3127 neon_split_vcombine (operands);
3131 (define_expand "neon_vget_high<mode>"
3132 [(match_operand:<V_HALF> 0 "s_register_operand")
3133 (match_operand:VQX 1 "s_register_operand")]
3136 emit_move_insn (operands[0],
3137 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
3138 GET_MODE_SIZE (<V_HALF>mode)));
3142 (define_expand "neon_vget_low<mode>"
3143 [(match_operand:<V_HALF> 0 "s_register_operand")
3144 (match_operand:VQX 1 "s_register_operand")]
3147 emit_move_insn (operands[0],
3148 simplify_gen_subreg (<V_HALF>mode, operands[1],
3153 (define_insn "float<mode><V_cvtto>2"
3154 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3155 (float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3156 "TARGET_NEON && !flag_rounding_math"
3157 "vcvt.f32.s32\t%<V_reg>0, %<V_reg>1"
3158 [(set (attr "neon_type")
3159 (if_then_else (match_test "<Is_d_reg>")
3160 (const_string "neon_fp_vadd_ddd_vabs_dd")
3161 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3164 (define_insn "floatuns<mode><V_cvtto>2"
3165 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3166 (unsigned_float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3167 "TARGET_NEON && !flag_rounding_math"
3168 "vcvt.f32.u32\t%<V_reg>0, %<V_reg>1"
3169 [(set (attr "neon_type")
3170 (if_then_else (match_test "<Is_d_reg>")
3171 (const_string "neon_fp_vadd_ddd_vabs_dd")
3172 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3175 (define_insn "fix_trunc<mode><V_cvtto>2"
3176 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3177 (fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3179 "vcvt.s32.f32\t%<V_reg>0, %<V_reg>1"
3180 [(set (attr "neon_type")
3181 (if_then_else (match_test "<Is_d_reg>")
3182 (const_string "neon_fp_vadd_ddd_vabs_dd")
3183 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3186 (define_insn "fixuns_trunc<mode><V_cvtto>2"
3187 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3188 (unsigned_fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3190 "vcvt.u32.f32\t%<V_reg>0, %<V_reg>1"
3191 [(set (attr "neon_type")
3192 (if_then_else (match_test "<Is_d_reg>")
3193 (const_string "neon_fp_vadd_ddd_vabs_dd")
3194 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3197 (define_insn "neon_vcvt<mode>"
3198 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3199 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3200 (match_operand:SI 2 "immediate_operand" "i")]
3203 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
3204 [(set (attr "neon_type")
3205 (if_then_else (match_test "<Is_d_reg>")
3206 (const_string "neon_fp_vadd_ddd_vabs_dd")
3207 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3210 (define_insn "neon_vcvt<mode>"
3211 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3212 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3213 (match_operand:SI 2 "immediate_operand" "i")]
3216 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
3217 [(set (attr "neon_type")
3218 (if_then_else (match_test "<Is_d_reg>")
3219 (const_string "neon_fp_vadd_ddd_vabs_dd")
3220 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3223 (define_insn "neon_vcvtv4sfv4hf"
3224 [(set (match_operand:V4SF 0 "s_register_operand" "=w")
3225 (unspec:V4SF [(match_operand:V4HF 1 "s_register_operand" "w")]
3227 "TARGET_NEON && TARGET_FP16"
3228 "vcvt.f32.f16\t%q0, %P1"
3229 [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")]
3232 (define_insn "neon_vcvtv4hfv4sf"
3233 [(set (match_operand:V4HF 0 "s_register_operand" "=w")
3234 (unspec:V4HF [(match_operand:V4SF 1 "s_register_operand" "w")]
3236 "TARGET_NEON && TARGET_FP16"
3237 "vcvt.f16.f32\t%P0, %q1"
3238 [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")]
3241 (define_insn "neon_vcvt_n<mode>"
3242 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3243 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3244 (match_operand:SI 2 "immediate_operand" "i")
3245 (match_operand:SI 3 "immediate_operand" "i")]
3249 neon_const_bounds (operands[2], 1, 33);
3250 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
3252 [(set (attr "neon_type")
3253 (if_then_else (match_test "<Is_d_reg>")
3254 (const_string "neon_fp_vadd_ddd_vabs_dd")
3255 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3258 (define_insn "neon_vcvt_n<mode>"
3259 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3260 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3261 (match_operand:SI 2 "immediate_operand" "i")
3262 (match_operand:SI 3 "immediate_operand" "i")]
3266 neon_const_bounds (operands[2], 1, 33);
3267 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
3269 [(set (attr "neon_type")
3270 (if_then_else (match_test "<Is_d_reg>")
3271 (const_string "neon_fp_vadd_ddd_vabs_dd")
3272 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3275 (define_insn "neon_vmovn<mode>"
3276 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3277 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3278 (match_operand:SI 2 "immediate_operand" "i")]
3281 "vmovn.<V_if_elem>\t%P0, %q1"
3282 [(set_attr "neon_type" "neon_bp_simple")]
3285 (define_insn "neon_vqmovn<mode>"
3286 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3287 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3288 (match_operand:SI 2 "immediate_operand" "i")]
3291 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
3292 [(set_attr "neon_type" "neon_shift_2")]
3295 (define_insn "neon_vqmovun<mode>"
3296 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3297 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3298 (match_operand:SI 2 "immediate_operand" "i")]
3301 "vqmovun.<V_s_elem>\t%P0, %q1"
3302 [(set_attr "neon_type" "neon_shift_2")]
3305 (define_insn "neon_vmovl<mode>"
3306 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3307 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3308 (match_operand:SI 2 "immediate_operand" "i")]
3311 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
3312 [(set_attr "neon_type" "neon_shift_1")]
3315 (define_insn "neon_vmul_lane<mode>"
3316 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3317 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
3318 (match_operand:VMD 2 "s_register_operand"
3319 "<scalar_mul_constraint>")
3320 (match_operand:SI 3 "immediate_operand" "i")
3321 (match_operand:SI 4 "immediate_operand" "i")]
3325 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3326 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
3328 [(set (attr "neon_type")
3329 (if_then_else (match_test "<Is_float_mode>")
3330 (const_string "neon_fp_vmul_ddd")
3331 (if_then_else (match_test "<Scalar_mul_8_16>")
3332 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3333 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
3336 (define_insn "neon_vmul_lane<mode>"
3337 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3338 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
3339 (match_operand:<V_HALF> 2 "s_register_operand"
3340 "<scalar_mul_constraint>")
3341 (match_operand:SI 3 "immediate_operand" "i")
3342 (match_operand:SI 4 "immediate_operand" "i")]
3346 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3347 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3349 [(set (attr "neon_type")
3350 (if_then_else (match_test "<Is_float_mode>")
3351 (const_string "neon_fp_vmul_qqd")
3352 (if_then_else (match_test "<Scalar_mul_8_16>")
3353 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3354 (const_string "neon_mul_qqd_32_scalar"))))]
3357 (define_insn "neon_vmull_lane<mode>"
3358 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3359 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3360 (match_operand:VMDI 2 "s_register_operand"
3361 "<scalar_mul_constraint>")
3362 (match_operand:SI 3 "immediate_operand" "i")
3363 (match_operand:SI 4 "immediate_operand" "i")]
3364 UNSPEC_VMULL_LANE))]
3367 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3368 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3370 [(set (attr "neon_type")
3371 (if_then_else (match_test "<Scalar_mul_8_16>")
3372 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3373 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3376 (define_insn "neon_vqdmull_lane<mode>"
3377 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3378 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3379 (match_operand:VMDI 2 "s_register_operand"
3380 "<scalar_mul_constraint>")
3381 (match_operand:SI 3 "immediate_operand" "i")
3382 (match_operand:SI 4 "immediate_operand" "i")]
3383 UNSPEC_VQDMULL_LANE))]
3386 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3387 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3389 [(set (attr "neon_type")
3390 (if_then_else (match_test "<Scalar_mul_8_16>")
3391 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3392 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3395 (define_insn "neon_vqdmulh_lane<mode>"
3396 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3397 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3398 (match_operand:<V_HALF> 2 "s_register_operand"
3399 "<scalar_mul_constraint>")
3400 (match_operand:SI 3 "immediate_operand" "i")
3401 (match_operand:SI 4 "immediate_operand" "i")]
3402 UNSPEC_VQDMULH_LANE))]
3405 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3406 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3408 [(set (attr "neon_type")
3409 (if_then_else (match_test "<Scalar_mul_8_16>")
3410 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3411 (const_string "neon_mul_qqd_32_scalar")))]
3414 (define_insn "neon_vqdmulh_lane<mode>"
3415 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3416 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3417 (match_operand:VMDI 2 "s_register_operand"
3418 "<scalar_mul_constraint>")
3419 (match_operand:SI 3 "immediate_operand" "i")
3420 (match_operand:SI 4 "immediate_operand" "i")]
3421 UNSPEC_VQDMULH_LANE))]
3424 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3425 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3427 [(set (attr "neon_type")
3428 (if_then_else (match_test "<Scalar_mul_8_16>")
3429 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3430 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3433 (define_insn "neon_vmla_lane<mode>"
3434 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3435 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3436 (match_operand:VMD 2 "s_register_operand" "w")
3437 (match_operand:VMD 3 "s_register_operand"
3438 "<scalar_mul_constraint>")
3439 (match_operand:SI 4 "immediate_operand" "i")
3440 (match_operand:SI 5 "immediate_operand" "i")]
3444 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3445 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3447 [(set (attr "neon_type")
3448 (if_then_else (match_test "<Is_float_mode>")
3449 (const_string "neon_fp_vmla_ddd_scalar")
3450 (if_then_else (match_test "<Scalar_mul_8_16>")
3451 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3452 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3455 (define_insn "neon_vmla_lane<mode>"
3456 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3457 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3458 (match_operand:VMQ 2 "s_register_operand" "w")
3459 (match_operand:<V_HALF> 3 "s_register_operand"
3460 "<scalar_mul_constraint>")
3461 (match_operand:SI 4 "immediate_operand" "i")
3462 (match_operand:SI 5 "immediate_operand" "i")]
3466 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3467 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3469 [(set (attr "neon_type")
3470 (if_then_else (match_test "<Is_float_mode>")
3471 (const_string "neon_fp_vmla_qqq_scalar")
3472 (if_then_else (match_test "<Scalar_mul_8_16>")
3473 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3474 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3477 (define_insn "neon_vmlal_lane<mode>"
3478 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3479 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3480 (match_operand:VMDI 2 "s_register_operand" "w")
3481 (match_operand:VMDI 3 "s_register_operand"
3482 "<scalar_mul_constraint>")
3483 (match_operand:SI 4 "immediate_operand" "i")
3484 (match_operand:SI 5 "immediate_operand" "i")]
3485 UNSPEC_VMLAL_LANE))]
3488 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3489 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3491 [(set (attr "neon_type")
3492 (if_then_else (match_test "<Scalar_mul_8_16>")
3493 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3494 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3497 (define_insn "neon_vqdmlal_lane<mode>"
3498 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3499 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3500 (match_operand:VMDI 2 "s_register_operand" "w")
3501 (match_operand:VMDI 3 "s_register_operand"
3502 "<scalar_mul_constraint>")
3503 (match_operand:SI 4 "immediate_operand" "i")
3504 (match_operand:SI 5 "immediate_operand" "i")]
3505 UNSPEC_VQDMLAL_LANE))]
3508 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3509 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3511 [(set (attr "neon_type")
3512 (if_then_else (match_test "<Scalar_mul_8_16>")
3513 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3514 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3517 (define_insn "neon_vmls_lane<mode>"
3518 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3519 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3520 (match_operand:VMD 2 "s_register_operand" "w")
3521 (match_operand:VMD 3 "s_register_operand"
3522 "<scalar_mul_constraint>")
3523 (match_operand:SI 4 "immediate_operand" "i")
3524 (match_operand:SI 5 "immediate_operand" "i")]
3528 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3529 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3531 [(set (attr "neon_type")
3532 (if_then_else (match_test "<Is_float_mode>")
3533 (const_string "neon_fp_vmla_ddd_scalar")
3534 (if_then_else (match_test "<Scalar_mul_8_16>")
3535 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3536 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3539 (define_insn "neon_vmls_lane<mode>"
3540 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3541 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3542 (match_operand:VMQ 2 "s_register_operand" "w")
3543 (match_operand:<V_HALF> 3 "s_register_operand"
3544 "<scalar_mul_constraint>")
3545 (match_operand:SI 4 "immediate_operand" "i")
3546 (match_operand:SI 5 "immediate_operand" "i")]
3550 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3551 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3553 [(set (attr "neon_type")
3554 (if_then_else (match_test "<Is_float_mode>")
3555 (const_string "neon_fp_vmla_qqq_scalar")
3556 (if_then_else (match_test "<Scalar_mul_8_16>")
3557 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3558 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3561 (define_insn "neon_vmlsl_lane<mode>"
3562 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3563 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3564 (match_operand:VMDI 2 "s_register_operand" "w")
3565 (match_operand:VMDI 3 "s_register_operand"
3566 "<scalar_mul_constraint>")
3567 (match_operand:SI 4 "immediate_operand" "i")
3568 (match_operand:SI 5 "immediate_operand" "i")]
3569 UNSPEC_VMLSL_LANE))]
3572 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3573 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3575 [(set (attr "neon_type")
3576 (if_then_else (match_test "<Scalar_mul_8_16>")
3577 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3578 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3581 (define_insn "neon_vqdmlsl_lane<mode>"
3582 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3583 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3584 (match_operand:VMDI 2 "s_register_operand" "w")
3585 (match_operand:VMDI 3 "s_register_operand"
3586 "<scalar_mul_constraint>")
3587 (match_operand:SI 4 "immediate_operand" "i")
3588 (match_operand:SI 5 "immediate_operand" "i")]
3589 UNSPEC_VQDMLSL_LANE))]
3592 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3593 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3595 [(set (attr "neon_type")
3596 (if_then_else (match_test "<Scalar_mul_8_16>")
3597 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3598 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3601 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3602 ; core register into a temp register, then use a scalar taken from that. This
3603 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3604 ; or extracted from another vector. The latter case it's currently better to
3605 ; use the "_lane" variant, and the former case can probably be implemented
3606 ; using vld1_lane, but that hasn't been done yet.
3608 (define_expand "neon_vmul_n<mode>"
3609 [(match_operand:VMD 0 "s_register_operand" "")
3610 (match_operand:VMD 1 "s_register_operand" "")
3611 (match_operand:<V_elem> 2 "s_register_operand" "")
3612 (match_operand:SI 3 "immediate_operand" "")]
3615 rtx tmp = gen_reg_rtx (<MODE>mode);
3616 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3617 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3618 const0_rtx, const0_rtx));
3622 (define_expand "neon_vmul_n<mode>"
3623 [(match_operand:VMQ 0 "s_register_operand" "")
3624 (match_operand:VMQ 1 "s_register_operand" "")
3625 (match_operand:<V_elem> 2 "s_register_operand" "")
3626 (match_operand:SI 3 "immediate_operand" "")]
3629 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3630 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3631 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3632 const0_rtx, const0_rtx));
3636 (define_expand "neon_vmull_n<mode>"
3637 [(match_operand:<V_widen> 0 "s_register_operand" "")
3638 (match_operand:VMDI 1 "s_register_operand" "")
3639 (match_operand:<V_elem> 2 "s_register_operand" "")
3640 (match_operand:SI 3 "immediate_operand" "")]
3643 rtx tmp = gen_reg_rtx (<MODE>mode);
3644 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3645 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3646 const0_rtx, operands[3]));
3650 (define_expand "neon_vqdmull_n<mode>"
3651 [(match_operand:<V_widen> 0 "s_register_operand" "")
3652 (match_operand:VMDI 1 "s_register_operand" "")
3653 (match_operand:<V_elem> 2 "s_register_operand" "")
3654 (match_operand:SI 3 "immediate_operand" "")]
3657 rtx tmp = gen_reg_rtx (<MODE>mode);
3658 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3659 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3660 const0_rtx, const0_rtx));
3664 (define_expand "neon_vqdmulh_n<mode>"
3665 [(match_operand:VMDI 0 "s_register_operand" "")
3666 (match_operand:VMDI 1 "s_register_operand" "")
3667 (match_operand:<V_elem> 2 "s_register_operand" "")
3668 (match_operand:SI 3 "immediate_operand" "")]
3671 rtx tmp = gen_reg_rtx (<MODE>mode);
3672 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3673 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3674 const0_rtx, operands[3]));
3678 (define_expand "neon_vqdmulh_n<mode>"
3679 [(match_operand:VMQI 0 "s_register_operand" "")
3680 (match_operand:VMQI 1 "s_register_operand" "")
3681 (match_operand:<V_elem> 2 "s_register_operand" "")
3682 (match_operand:SI 3 "immediate_operand" "")]
3685 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3686 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3687 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3688 const0_rtx, operands[3]));
3692 (define_expand "neon_vmla_n<mode>"
3693 [(match_operand:VMD 0 "s_register_operand" "")
3694 (match_operand:VMD 1 "s_register_operand" "")
3695 (match_operand:VMD 2 "s_register_operand" "")
3696 (match_operand:<V_elem> 3 "s_register_operand" "")
3697 (match_operand:SI 4 "immediate_operand" "")]
3700 rtx tmp = gen_reg_rtx (<MODE>mode);
3701 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3702 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3703 tmp, const0_rtx, operands[4]));
3707 (define_expand "neon_vmla_n<mode>"
3708 [(match_operand:VMQ 0 "s_register_operand" "")
3709 (match_operand:VMQ 1 "s_register_operand" "")
3710 (match_operand:VMQ 2 "s_register_operand" "")
3711 (match_operand:<V_elem> 3 "s_register_operand" "")
3712 (match_operand:SI 4 "immediate_operand" "")]
3715 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3716 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3717 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3718 tmp, const0_rtx, operands[4]));
3722 (define_expand "neon_vmlal_n<mode>"
3723 [(match_operand:<V_widen> 0 "s_register_operand" "")
3724 (match_operand:<V_widen> 1 "s_register_operand" "")
3725 (match_operand:VMDI 2 "s_register_operand" "")
3726 (match_operand:<V_elem> 3 "s_register_operand" "")
3727 (match_operand:SI 4 "immediate_operand" "")]
3730 rtx tmp = gen_reg_rtx (<MODE>mode);
3731 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3732 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3733 tmp, const0_rtx, operands[4]));
3737 (define_expand "neon_vqdmlal_n<mode>"
3738 [(match_operand:<V_widen> 0 "s_register_operand" "")
3739 (match_operand:<V_widen> 1 "s_register_operand" "")
3740 (match_operand:VMDI 2 "s_register_operand" "")
3741 (match_operand:<V_elem> 3 "s_register_operand" "")
3742 (match_operand:SI 4 "immediate_operand" "")]
3745 rtx tmp = gen_reg_rtx (<MODE>mode);
3746 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3747 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3748 tmp, const0_rtx, operands[4]));
3752 (define_expand "neon_vmls_n<mode>"
3753 [(match_operand:VMD 0 "s_register_operand" "")
3754 (match_operand:VMD 1 "s_register_operand" "")
3755 (match_operand:VMD 2 "s_register_operand" "")
3756 (match_operand:<V_elem> 3 "s_register_operand" "")
3757 (match_operand:SI 4 "immediate_operand" "")]
3760 rtx tmp = gen_reg_rtx (<MODE>mode);
3761 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3762 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3763 tmp, const0_rtx, operands[4]));
3767 (define_expand "neon_vmls_n<mode>"
3768 [(match_operand:VMQ 0 "s_register_operand" "")
3769 (match_operand:VMQ 1 "s_register_operand" "")
3770 (match_operand:VMQ 2 "s_register_operand" "")
3771 (match_operand:<V_elem> 3 "s_register_operand" "")
3772 (match_operand:SI 4 "immediate_operand" "")]
3775 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3776 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3777 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3778 tmp, const0_rtx, operands[4]));
3782 (define_expand "neon_vmlsl_n<mode>"
3783 [(match_operand:<V_widen> 0 "s_register_operand" "")
3784 (match_operand:<V_widen> 1 "s_register_operand" "")
3785 (match_operand:VMDI 2 "s_register_operand" "")
3786 (match_operand:<V_elem> 3 "s_register_operand" "")
3787 (match_operand:SI 4 "immediate_operand" "")]
3790 rtx tmp = gen_reg_rtx (<MODE>mode);
3791 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3792 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3793 tmp, const0_rtx, operands[4]));
3797 (define_expand "neon_vqdmlsl_n<mode>"
3798 [(match_operand:<V_widen> 0 "s_register_operand" "")
3799 (match_operand:<V_widen> 1 "s_register_operand" "")
3800 (match_operand:VMDI 2 "s_register_operand" "")
3801 (match_operand:<V_elem> 3 "s_register_operand" "")
3802 (match_operand:SI 4 "immediate_operand" "")]
3805 rtx tmp = gen_reg_rtx (<MODE>mode);
3806 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3807 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3808 tmp, const0_rtx, operands[4]));
3812 (define_insn "neon_vext<mode>"
3813 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3814 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3815 (match_operand:VDQX 2 "s_register_operand" "w")
3816 (match_operand:SI 3 "immediate_operand" "i")]
3820 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3821 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3823 [(set (attr "neon_type")
3824 (if_then_else (match_test "<Is_d_reg>")
3825 (const_string "neon_bp_simple")
3826 (const_string "neon_bp_2cycle")))]
3829 (define_insn "neon_vrev64<mode>"
3830 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3831 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3832 (match_operand:SI 2 "immediate_operand" "i")]
3835 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3836 [(set_attr "neon_type" "neon_bp_simple")]
3839 (define_insn "neon_vrev32<mode>"
3840 [(set (match_operand:VX 0 "s_register_operand" "=w")
3841 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3842 (match_operand:SI 2 "immediate_operand" "i")]
3845 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3846 [(set_attr "neon_type" "neon_bp_simple")]
3849 (define_insn "neon_vrev16<mode>"
3850 [(set (match_operand:VE 0 "s_register_operand" "=w")
3851 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3852 (match_operand:SI 2 "immediate_operand" "i")]
3855 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3856 [(set_attr "neon_type" "neon_bp_simple")]
3859 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3860 ; allocation. For an intrinsic of form:
3861 ; rD = vbsl_* (rS, rN, rM)
3862 ; We can use any of:
3863 ; vbsl rS, rN, rM (if D = S)
3864 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3865 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3867 (define_insn "neon_vbsl<mode>_internal"
3868 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3869 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3870 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3871 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3875 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3876 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3877 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3878 [(set_attr "neon_type" "neon_int_1")]
3881 (define_expand "neon_vbsl<mode>"
3882 [(set (match_operand:VDQX 0 "s_register_operand" "")
3883 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3884 (match_operand:VDQX 2 "s_register_operand" "")
3885 (match_operand:VDQX 3 "s_register_operand" "")]
3889 /* We can't alias operands together if they have different modes. */
3890 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3893 (define_insn "neon_vshl<mode>"
3894 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3895 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3896 (match_operand:VDQIX 2 "s_register_operand" "w")
3897 (match_operand:SI 3 "immediate_operand" "i")]
3900 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3901 [(set (attr "neon_type")
3902 (if_then_else (match_test "<Is_d_reg>")
3903 (const_string "neon_vshl_ddd")
3904 (const_string "neon_shift_3")))]
3907 (define_insn "neon_vqshl<mode>"
3908 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3909 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3910 (match_operand:VDQIX 2 "s_register_operand" "w")
3911 (match_operand:SI 3 "immediate_operand" "i")]
3914 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3915 [(set (attr "neon_type")
3916 (if_then_else (match_test "<Is_d_reg>")
3917 (const_string "neon_shift_2")
3918 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3921 (define_insn "neon_vshr_n<mode>"
3922 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3923 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3924 (match_operand:SI 2 "immediate_operand" "i")
3925 (match_operand:SI 3 "immediate_operand" "i")]
3929 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3930 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3932 [(set_attr "neon_type" "neon_shift_1")]
3935 (define_insn "neon_vshrn_n<mode>"
3936 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3937 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3938 (match_operand:SI 2 "immediate_operand" "i")
3939 (match_operand:SI 3 "immediate_operand" "i")]
3943 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3944 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3946 [(set_attr "neon_type" "neon_shift_1")]
3949 (define_insn "neon_vqshrn_n<mode>"
3950 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3951 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3952 (match_operand:SI 2 "immediate_operand" "i")
3953 (match_operand:SI 3 "immediate_operand" "i")]
3957 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3958 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3960 [(set_attr "neon_type" "neon_shift_2")]
3963 (define_insn "neon_vqshrun_n<mode>"
3964 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3965 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3966 (match_operand:SI 2 "immediate_operand" "i")
3967 (match_operand:SI 3 "immediate_operand" "i")]
3971 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3972 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3974 [(set_attr "neon_type" "neon_shift_2")]
3977 (define_insn "neon_vshl_n<mode>"
3978 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3979 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3980 (match_operand:SI 2 "immediate_operand" "i")
3981 (match_operand:SI 3 "immediate_operand" "i")]
3985 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3986 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
3988 [(set_attr "neon_type" "neon_shift_1")]
3991 (define_insn "neon_vqshl_n<mode>"
3992 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3993 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3994 (match_operand:SI 2 "immediate_operand" "i")
3995 (match_operand:SI 3 "immediate_operand" "i")]
3999 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4000 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4002 [(set_attr "neon_type" "neon_shift_2")]
4005 (define_insn "neon_vqshlu_n<mode>"
4006 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4007 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4008 (match_operand:SI 2 "immediate_operand" "i")
4009 (match_operand:SI 3 "immediate_operand" "i")]
4013 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4014 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4016 [(set_attr "neon_type" "neon_shift_2")]
4019 (define_insn "neon_vshll_n<mode>"
4020 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
4021 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
4022 (match_operand:SI 2 "immediate_operand" "i")
4023 (match_operand:SI 3 "immediate_operand" "i")]
4027 /* The boundaries are: 0 < imm <= size. */
4028 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
4029 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
4031 [(set_attr "neon_type" "neon_shift_1")]
4034 (define_insn "neon_vsra_n<mode>"
4035 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4036 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4037 (match_operand:VDQIX 2 "s_register_operand" "w")
4038 (match_operand:SI 3 "immediate_operand" "i")
4039 (match_operand:SI 4 "immediate_operand" "i")]
4043 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4044 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4046 [(set_attr "neon_type" "neon_vsra_vrsra")]
4049 (define_insn "neon_vsri_n<mode>"
4050 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4051 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4052 (match_operand:VDQIX 2 "s_register_operand" "w")
4053 (match_operand:SI 3 "immediate_operand" "i")]
4057 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4058 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4060 [(set (attr "neon_type")
4061 (if_then_else (match_test "<Is_d_reg>")
4062 (const_string "neon_shift_1")
4063 (const_string "neon_shift_3")))]
4066 (define_insn "neon_vsli_n<mode>"
4067 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4068 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4069 (match_operand:VDQIX 2 "s_register_operand" "w")
4070 (match_operand:SI 3 "immediate_operand" "i")]
4074 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
4075 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4077 [(set (attr "neon_type")
4078 (if_then_else (match_test "<Is_d_reg>")
4079 (const_string "neon_shift_1")
4080 (const_string "neon_shift_3")))]
4083 (define_insn "neon_vtbl1v8qi"
4084 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4085 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
4086 (match_operand:V8QI 2 "s_register_operand" "w")]
4089 "vtbl.8\t%P0, {%P1}, %P2"
4090 [(set_attr "neon_type" "neon_bp_2cycle")]
4093 (define_insn "neon_vtbl2v8qi"
4094 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4095 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
4096 (match_operand:V8QI 2 "s_register_operand" "w")]
4101 int tabbase = REGNO (operands[1]);
4103 ops[0] = operands[0];
4104 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4105 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4106 ops[3] = operands[2];
4107 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
4111 [(set_attr "neon_type" "neon_bp_2cycle")]
4114 (define_insn "neon_vtbl3v8qi"
4115 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4116 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
4117 (match_operand:V8QI 2 "s_register_operand" "w")]
4122 int tabbase = REGNO (operands[1]);
4124 ops[0] = operands[0];
4125 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4126 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4127 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4128 ops[4] = operands[2];
4129 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4133 [(set_attr "neon_type" "neon_bp_3cycle")]
4136 (define_insn "neon_vtbl4v8qi"
4137 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4138 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
4139 (match_operand:V8QI 2 "s_register_operand" "w")]
4144 int tabbase = REGNO (operands[1]);
4146 ops[0] = operands[0];
4147 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4148 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4149 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4150 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4151 ops[5] = operands[2];
4152 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4156 [(set_attr "neon_type" "neon_bp_3cycle")]
4159 ;; These three are used by the vec_perm infrastructure for V16QImode.
4160 (define_insn_and_split "neon_vtbl1v16qi"
4161 [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4162 (unspec:V16QI [(match_operand:V16QI 1 "s_register_operand" "w")
4163 (match_operand:V16QI 2 "s_register_operand" "w")]
4167 "&& reload_completed"
4170 rtx op0, op1, op2, part0, part2;
4174 op1 = gen_lowpart (TImode, operands[1]);
4177 ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4178 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4179 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4180 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4182 ofs = subreg_highpart_offset (V8QImode, V16QImode);
4183 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4184 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4185 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4189 (define_insn_and_split "neon_vtbl2v16qi"
4190 [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4191 (unspec:V16QI [(match_operand:OI 1 "s_register_operand" "w")
4192 (match_operand:V16QI 2 "s_register_operand" "w")]
4196 "&& reload_completed"
4199 rtx op0, op1, op2, part0, part2;
4206 ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4207 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4208 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4209 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4211 ofs = subreg_highpart_offset (V8QImode, V16QImode);
4212 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4213 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4214 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4218 ;; ??? Logically we should extend the regular neon_vcombine pattern to
4219 ;; handle quad-word input modes, producing octa-word output modes. But
4220 ;; that requires us to add support for octa-word vector modes in moves.
4221 ;; That seems overkill for this one use in vec_perm.
4222 (define_insn_and_split "neon_vcombinev16qi"
4223 [(set (match_operand:OI 0 "s_register_operand" "=w")
4224 (unspec:OI [(match_operand:V16QI 1 "s_register_operand" "w")
4225 (match_operand:V16QI 2 "s_register_operand" "w")]
4229 "&& reload_completed"
4232 neon_split_vcombine (operands);
4236 (define_insn "neon_vtbx1v8qi"
4237 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4238 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4239 (match_operand:V8QI 2 "s_register_operand" "w")
4240 (match_operand:V8QI 3 "s_register_operand" "w")]
4243 "vtbx.8\t%P0, {%P2}, %P3"
4244 [(set_attr "neon_type" "neon_bp_2cycle")]
4247 (define_insn "neon_vtbx2v8qi"
4248 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4249 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4250 (match_operand:TI 2 "s_register_operand" "w")
4251 (match_operand:V8QI 3 "s_register_operand" "w")]
4256 int tabbase = REGNO (operands[2]);
4258 ops[0] = operands[0];
4259 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4260 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4261 ops[3] = operands[3];
4262 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
4266 [(set_attr "neon_type" "neon_bp_2cycle")]
4269 (define_insn "neon_vtbx3v8qi"
4270 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4271 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4272 (match_operand:EI 2 "s_register_operand" "w")
4273 (match_operand:V8QI 3 "s_register_operand" "w")]
4278 int tabbase = REGNO (operands[2]);
4280 ops[0] = operands[0];
4281 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4282 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4283 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4284 ops[4] = operands[3];
4285 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4289 [(set_attr "neon_type" "neon_bp_3cycle")]
4292 (define_insn "neon_vtbx4v8qi"
4293 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4294 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4295 (match_operand:OI 2 "s_register_operand" "w")
4296 (match_operand:V8QI 3 "s_register_operand" "w")]
4301 int tabbase = REGNO (operands[2]);
4303 ops[0] = operands[0];
4304 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4305 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4306 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4307 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4308 ops[5] = operands[3];
4309 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4313 [(set_attr "neon_type" "neon_bp_3cycle")]
4316 (define_expand "neon_vtrn<mode>_internal"
4318 [(set (match_operand:VDQW 0 "s_register_operand" "")
4319 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4320 (match_operand:VDQW 2 "s_register_operand" "")]
4322 (set (match_operand:VDQW 3 "s_register_operand" "")
4323 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VTRN2))])]
4328 ;; Note: Different operand numbering to handle tied registers correctly.
4329 (define_insn "*neon_vtrn<mode>_insn"
4330 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4331 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4332 (match_operand:VDQW 3 "s_register_operand" "2")]
4334 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4335 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4338 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4339 [(set (attr "neon_type")
4340 (if_then_else (match_test "<Is_d_reg>")
4341 (const_string "neon_bp_simple")
4342 (const_string "neon_bp_3cycle")))]
4345 (define_expand "neon_vtrn<mode>"
4346 [(match_operand:SI 0 "s_register_operand" "r")
4347 (match_operand:VDQW 1 "s_register_operand" "w")
4348 (match_operand:VDQW 2 "s_register_operand" "w")]
4351 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
4352 operands[0], operands[1], operands[2]);
4356 (define_expand "neon_vzip<mode>_internal"
4358 [(set (match_operand:VDQW 0 "s_register_operand" "")
4359 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4360 (match_operand:VDQW 2 "s_register_operand" "")]
4362 (set (match_operand:VDQW 3 "s_register_operand" "")
4363 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VZIP2))])]
4368 ;; Note: Different operand numbering to handle tied registers correctly.
4369 (define_insn "*neon_vzip<mode>_insn"
4370 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4371 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4372 (match_operand:VDQW 3 "s_register_operand" "2")]
4374 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4375 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4378 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4379 [(set (attr "neon_type")
4380 (if_then_else (match_test "<Is_d_reg>")
4381 (const_string "neon_bp_simple")
4382 (const_string "neon_bp_3cycle")))]
4385 (define_expand "neon_vzip<mode>"
4386 [(match_operand:SI 0 "s_register_operand" "r")
4387 (match_operand:VDQW 1 "s_register_operand" "w")
4388 (match_operand:VDQW 2 "s_register_operand" "w")]
4391 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
4392 operands[0], operands[1], operands[2]);
4396 (define_expand "neon_vuzp<mode>_internal"
4398 [(set (match_operand:VDQW 0 "s_register_operand" "")
4399 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4400 (match_operand:VDQW 2 "s_register_operand" "")]
4402 (set (match_operand:VDQW 3 "s_register_operand" "")
4403 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VUZP2))])]
4408 ;; Note: Different operand numbering to handle tied registers correctly.
4409 (define_insn "*neon_vuzp<mode>_insn"
4410 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4411 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4412 (match_operand:VDQW 3 "s_register_operand" "2")]
4414 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4415 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4418 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4419 [(set (attr "neon_type")
4420 (if_then_else (match_test "<Is_d_reg>")
4421 (const_string "neon_bp_simple")
4422 (const_string "neon_bp_3cycle")))]
4425 (define_expand "neon_vuzp<mode>"
4426 [(match_operand:SI 0 "s_register_operand" "r")
4427 (match_operand:VDQW 1 "s_register_operand" "w")
4428 (match_operand:VDQW 2 "s_register_operand" "w")]
4431 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
4432 operands[0], operands[1], operands[2]);
4436 (define_expand "neon_vreinterpretv8qi<mode>"
4437 [(match_operand:V8QI 0 "s_register_operand" "")
4438 (match_operand:VDX 1 "s_register_operand" "")]
4441 neon_reinterpret (operands[0], operands[1]);
4445 (define_expand "neon_vreinterpretv4hi<mode>"
4446 [(match_operand:V4HI 0 "s_register_operand" "")
4447 (match_operand:VDX 1 "s_register_operand" "")]
4450 neon_reinterpret (operands[0], operands[1]);
4454 (define_expand "neon_vreinterpretv2si<mode>"
4455 [(match_operand:V2SI 0 "s_register_operand" "")
4456 (match_operand:VDX 1 "s_register_operand" "")]
4459 neon_reinterpret (operands[0], operands[1]);
4463 (define_expand "neon_vreinterpretv2sf<mode>"
4464 [(match_operand:V2SF 0 "s_register_operand" "")
4465 (match_operand:VDX 1 "s_register_operand" "")]
4468 neon_reinterpret (operands[0], operands[1]);
4472 (define_expand "neon_vreinterpretdi<mode>"
4473 [(match_operand:DI 0 "s_register_operand" "")
4474 (match_operand:VDX 1 "s_register_operand" "")]
4477 neon_reinterpret (operands[0], operands[1]);
4481 (define_expand "neon_vreinterpretv16qi<mode>"
4482 [(match_operand:V16QI 0 "s_register_operand" "")
4483 (match_operand:VQX 1 "s_register_operand" "")]
4486 neon_reinterpret (operands[0], operands[1]);
4490 (define_expand "neon_vreinterpretv8hi<mode>"
4491 [(match_operand:V8HI 0 "s_register_operand" "")
4492 (match_operand:VQX 1 "s_register_operand" "")]
4495 neon_reinterpret (operands[0], operands[1]);
4499 (define_expand "neon_vreinterpretv4si<mode>"
4500 [(match_operand:V4SI 0 "s_register_operand" "")
4501 (match_operand:VQX 1 "s_register_operand" "")]
4504 neon_reinterpret (operands[0], operands[1]);
4508 (define_expand "neon_vreinterpretv4sf<mode>"
4509 [(match_operand:V4SF 0 "s_register_operand" "")
4510 (match_operand:VQX 1 "s_register_operand" "")]
4513 neon_reinterpret (operands[0], operands[1]);
4517 (define_expand "neon_vreinterpretv2di<mode>"
4518 [(match_operand:V2DI 0 "s_register_operand" "")
4519 (match_operand:VQX 1 "s_register_operand" "")]
4522 neon_reinterpret (operands[0], operands[1]);
4526 (define_expand "vec_load_lanes<mode><mode>"
4527 [(set (match_operand:VDQX 0 "s_register_operand")
4528 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand")]
4532 (define_insn "neon_vld1<mode>"
4533 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4534 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand" "Um")]
4537 "vld1.<V_sz_elem>\t%h0, %A1"
4538 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4541 (define_insn "neon_vld1_lane<mode>"
4542 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4543 (unspec:VDX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4544 (match_operand:VDX 2 "s_register_operand" "0")
4545 (match_operand:SI 3 "immediate_operand" "i")]
4549 HOST_WIDE_INT lane = INTVAL (operands[3]);
4550 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4551 if (lane < 0 || lane >= max)
4552 error ("lane out of range");
4554 return "vld1.<V_sz_elem>\t%P0, %A1";
4556 return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4558 [(set (attr "neon_type")
4559 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4560 (const_string "neon_vld1_1_2_regs")
4561 (const_string "neon_vld1_vld2_lane")))]
4564 (define_insn "neon_vld1_lane<mode>"
4565 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4566 (unspec:VQX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4567 (match_operand:VQX 2 "s_register_operand" "0")
4568 (match_operand:SI 3 "immediate_operand" "i")]
4572 HOST_WIDE_INT lane = INTVAL (operands[3]);
4573 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4574 int regno = REGNO (operands[0]);
4575 if (lane < 0 || lane >= max)
4576 error ("lane out of range");
4577 else if (lane >= max / 2)
4581 operands[3] = GEN_INT (lane);
4583 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4585 return "vld1.<V_sz_elem>\t%P0, %A1";
4587 return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4589 [(set (attr "neon_type")
4590 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4591 (const_string "neon_vld1_1_2_regs")
4592 (const_string "neon_vld1_vld2_lane")))]
4595 (define_insn "neon_vld1_dup<mode>"
4596 [(set (match_operand:VD 0 "s_register_operand" "=w")
4597 (vec_duplicate:VD (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4599 "vld1.<V_sz_elem>\t{%P0[]}, %A1"
4600 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4603 ;; Special case for DImode. Treat it exactly like a simple load.
4604 (define_expand "neon_vld1_dupdi"
4605 [(set (match_operand:DI 0 "s_register_operand" "")
4606 (unspec:DI [(match_operand:DI 1 "neon_struct_operand" "")]
4612 (define_insn "neon_vld1_dup<mode>"
4613 [(set (match_operand:VQ 0 "s_register_operand" "=w")
4614 (vec_duplicate:VQ (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4617 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4619 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4622 (define_insn_and_split "neon_vld1_dupv2di"
4623 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
4624 (vec_duplicate:V2DI (match_operand:DI 1 "neon_struct_operand" "Um")))]
4627 "&& reload_completed"
4630 rtx tmprtx = gen_lowpart (DImode, operands[0]);
4631 emit_insn (gen_neon_vld1_dupdi (tmprtx, operands[1]));
4632 emit_move_insn (gen_highpart (DImode, operands[0]), tmprtx );
4635 [(set_attr "length" "8")
4636 (set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4639 (define_expand "vec_store_lanes<mode><mode>"
4640 [(set (match_operand:VDQX 0 "neon_struct_operand")
4641 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand")]
4645 (define_insn "neon_vst1<mode>"
4646 [(set (match_operand:VDQX 0 "neon_struct_operand" "=Um")
4647 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4650 "vst1.<V_sz_elem>\t%h1, %A0"
4651 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4653 (define_insn "neon_vst1_lane<mode>"
4654 [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4656 [(match_operand:VDX 1 "s_register_operand" "w")
4657 (match_operand:SI 2 "immediate_operand" "i")]
4661 HOST_WIDE_INT lane = INTVAL (operands[2]);
4662 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4663 if (lane < 0 || lane >= max)
4664 error ("lane out of range");
4666 return "vst1.<V_sz_elem>\t{%P1}, %A0";
4668 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4670 [(set (attr "neon_type")
4671 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4672 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4673 (const_string "neon_vst1_vst2_lane")))])
4675 (define_insn "neon_vst1_lane<mode>"
4676 [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4678 [(match_operand:VQX 1 "s_register_operand" "w")
4679 (match_operand:SI 2 "immediate_operand" "i")]
4683 HOST_WIDE_INT lane = INTVAL (operands[2]);
4684 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4685 int regno = REGNO (operands[1]);
4686 if (lane < 0 || lane >= max)
4687 error ("lane out of range");
4688 else if (lane >= max / 2)
4692 operands[2] = GEN_INT (lane);
4694 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4696 return "vst1.<V_sz_elem>\t{%P1}, %A0";
4698 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4700 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4703 (define_expand "vec_load_lanesti<mode>"
4704 [(set (match_operand:TI 0 "s_register_operand")
4705 (unspec:TI [(match_operand:TI 1 "neon_struct_operand")
4706 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4710 (define_insn "neon_vld2<mode>"
4711 [(set (match_operand:TI 0 "s_register_operand" "=w")
4712 (unspec:TI [(match_operand:TI 1 "neon_struct_operand" "Um")
4713 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4717 if (<V_sz_elem> == 64)
4718 return "vld1.64\t%h0, %A1";
4720 return "vld2.<V_sz_elem>\t%h0, %A1";
4722 [(set (attr "neon_type")
4723 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4724 (const_string "neon_vld1_1_2_regs")
4725 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4728 (define_expand "vec_load_lanesoi<mode>"
4729 [(set (match_operand:OI 0 "s_register_operand")
4730 (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
4731 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4735 (define_insn "neon_vld2<mode>"
4736 [(set (match_operand:OI 0 "s_register_operand" "=w")
4737 (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
4738 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4741 "vld2.<V_sz_elem>\t%h0, %A1"
4742 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4744 (define_insn "neon_vld2_lane<mode>"
4745 [(set (match_operand:TI 0 "s_register_operand" "=w")
4746 (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4747 (match_operand:TI 2 "s_register_operand" "0")
4748 (match_operand:SI 3 "immediate_operand" "i")
4749 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4753 HOST_WIDE_INT lane = INTVAL (operands[3]);
4754 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4755 int regno = REGNO (operands[0]);
4757 if (lane < 0 || lane >= max)
4758 error ("lane out of range");
4759 ops[0] = gen_rtx_REG (DImode, regno);
4760 ops[1] = gen_rtx_REG (DImode, regno + 2);
4761 ops[2] = operands[1];
4762 ops[3] = operands[3];
4763 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4766 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4769 (define_insn "neon_vld2_lane<mode>"
4770 [(set (match_operand:OI 0 "s_register_operand" "=w")
4771 (unspec:OI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4772 (match_operand:OI 2 "s_register_operand" "0")
4773 (match_operand:SI 3 "immediate_operand" "i")
4774 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4778 HOST_WIDE_INT lane = INTVAL (operands[3]);
4779 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4780 int regno = REGNO (operands[0]);
4782 if (lane < 0 || lane >= max)
4783 error ("lane out of range");
4784 else if (lane >= max / 2)
4789 ops[0] = gen_rtx_REG (DImode, regno);
4790 ops[1] = gen_rtx_REG (DImode, regno + 4);
4791 ops[2] = operands[1];
4792 ops[3] = GEN_INT (lane);
4793 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4796 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4799 (define_insn "neon_vld2_dup<mode>"
4800 [(set (match_operand:TI 0 "s_register_operand" "=w")
4801 (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4802 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4806 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4807 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4809 return "vld1.<V_sz_elem>\t%h0, %A1";
4811 [(set (attr "neon_type")
4812 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4813 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4814 (const_string "neon_vld1_1_2_regs")))]
4817 (define_expand "vec_store_lanesti<mode>"
4818 [(set (match_operand:TI 0 "neon_struct_operand")
4819 (unspec:TI [(match_operand:TI 1 "s_register_operand")
4820 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4824 (define_insn "neon_vst2<mode>"
4825 [(set (match_operand:TI 0 "neon_struct_operand" "=Um")
4826 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4827 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4831 if (<V_sz_elem> == 64)
4832 return "vst1.64\t%h1, %A0";
4834 return "vst2.<V_sz_elem>\t%h1, %A0";
4836 [(set (attr "neon_type")
4837 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4838 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4839 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4842 (define_expand "vec_store_lanesoi<mode>"
4843 [(set (match_operand:OI 0 "neon_struct_operand")
4844 (unspec:OI [(match_operand:OI 1 "s_register_operand")
4845 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4849 (define_insn "neon_vst2<mode>"
4850 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
4851 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4852 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4855 "vst2.<V_sz_elem>\t%h1, %A0"
4856 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4859 (define_insn "neon_vst2_lane<mode>"
4860 [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4861 (unspec:<V_two_elem>
4862 [(match_operand:TI 1 "s_register_operand" "w")
4863 (match_operand:SI 2 "immediate_operand" "i")
4864 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4868 HOST_WIDE_INT lane = INTVAL (operands[2]);
4869 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4870 int regno = REGNO (operands[1]);
4872 if (lane < 0 || lane >= max)
4873 error ("lane out of range");
4874 ops[0] = operands[0];
4875 ops[1] = gen_rtx_REG (DImode, regno);
4876 ops[2] = gen_rtx_REG (DImode, regno + 2);
4877 ops[3] = operands[2];
4878 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4881 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4884 (define_insn "neon_vst2_lane<mode>"
4885 [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4886 (unspec:<V_two_elem>
4887 [(match_operand:OI 1 "s_register_operand" "w")
4888 (match_operand:SI 2 "immediate_operand" "i")
4889 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4893 HOST_WIDE_INT lane = INTVAL (operands[2]);
4894 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4895 int regno = REGNO (operands[1]);
4897 if (lane < 0 || lane >= max)
4898 error ("lane out of range");
4899 else if (lane >= max / 2)
4904 ops[0] = operands[0];
4905 ops[1] = gen_rtx_REG (DImode, regno);
4906 ops[2] = gen_rtx_REG (DImode, regno + 4);
4907 ops[3] = GEN_INT (lane);
4908 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4911 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4914 (define_expand "vec_load_lanesei<mode>"
4915 [(set (match_operand:EI 0 "s_register_operand")
4916 (unspec:EI [(match_operand:EI 1 "neon_struct_operand")
4917 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4921 (define_insn "neon_vld3<mode>"
4922 [(set (match_operand:EI 0 "s_register_operand" "=w")
4923 (unspec:EI [(match_operand:EI 1 "neon_struct_operand" "Um")
4924 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4928 if (<V_sz_elem> == 64)
4929 return "vld1.64\t%h0, %A1";
4931 return "vld3.<V_sz_elem>\t%h0, %A1";
4933 [(set (attr "neon_type")
4934 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4935 (const_string "neon_vld1_1_2_regs")
4936 (const_string "neon_vld3_vld4")))]
4939 (define_expand "vec_load_lanesci<mode>"
4940 [(match_operand:CI 0 "s_register_operand")
4941 (match_operand:CI 1 "neon_struct_operand")
4942 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4945 emit_insn (gen_neon_vld3<mode> (operands[0], operands[1]));
4949 (define_expand "neon_vld3<mode>"
4950 [(match_operand:CI 0 "s_register_operand")
4951 (match_operand:CI 1 "neon_struct_operand")
4952 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4957 mem = adjust_address (operands[1], EImode, 0);
4958 emit_insn (gen_neon_vld3qa<mode> (operands[0], mem));
4959 mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
4960 emit_insn (gen_neon_vld3qb<mode> (operands[0], mem, operands[0]));
4964 (define_insn "neon_vld3qa<mode>"
4965 [(set (match_operand:CI 0 "s_register_operand" "=w")
4966 (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
4967 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4971 int regno = REGNO (operands[0]);
4973 ops[0] = gen_rtx_REG (DImode, regno);
4974 ops[1] = gen_rtx_REG (DImode, regno + 4);
4975 ops[2] = gen_rtx_REG (DImode, regno + 8);
4976 ops[3] = operands[1];
4977 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
4980 [(set_attr "neon_type" "neon_vld3_vld4")]
4983 (define_insn "neon_vld3qb<mode>"
4984 [(set (match_operand:CI 0 "s_register_operand" "=w")
4985 (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
4986 (match_operand:CI 2 "s_register_operand" "0")
4987 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4991 int regno = REGNO (operands[0]);
4993 ops[0] = gen_rtx_REG (DImode, regno + 2);
4994 ops[1] = gen_rtx_REG (DImode, regno + 6);
4995 ops[2] = gen_rtx_REG (DImode, regno + 10);
4996 ops[3] = operands[1];
4997 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
5000 [(set_attr "neon_type" "neon_vld3_vld4")]
5003 (define_insn "neon_vld3_lane<mode>"
5004 [(set (match_operand:EI 0 "s_register_operand" "=w")
5005 (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5006 (match_operand:EI 2 "s_register_operand" "0")
5007 (match_operand:SI 3 "immediate_operand" "i")
5008 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5012 HOST_WIDE_INT lane = INTVAL (operands[3]);
5013 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5014 int regno = REGNO (operands[0]);
5016 if (lane < 0 || lane >= max)
5017 error ("lane out of range");
5018 ops[0] = gen_rtx_REG (DImode, regno);
5019 ops[1] = gen_rtx_REG (DImode, regno + 2);
5020 ops[2] = gen_rtx_REG (DImode, regno + 4);
5021 ops[3] = operands[1];
5022 ops[4] = operands[3];
5023 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5027 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5030 (define_insn "neon_vld3_lane<mode>"
5031 [(set (match_operand:CI 0 "s_register_operand" "=w")
5032 (unspec:CI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5033 (match_operand:CI 2 "s_register_operand" "0")
5034 (match_operand:SI 3 "immediate_operand" "i")
5035 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5039 HOST_WIDE_INT lane = INTVAL (operands[3]);
5040 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5041 int regno = REGNO (operands[0]);
5043 if (lane < 0 || lane >= max)
5044 error ("lane out of range");
5045 else if (lane >= max / 2)
5050 ops[0] = gen_rtx_REG (DImode, regno);
5051 ops[1] = gen_rtx_REG (DImode, regno + 4);
5052 ops[2] = gen_rtx_REG (DImode, regno + 8);
5053 ops[3] = operands[1];
5054 ops[4] = GEN_INT (lane);
5055 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5059 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5062 (define_insn "neon_vld3_dup<mode>"
5063 [(set (match_operand:EI 0 "s_register_operand" "=w")
5064 (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5065 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5069 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5071 int regno = REGNO (operands[0]);
5073 ops[0] = gen_rtx_REG (DImode, regno);
5074 ops[1] = gen_rtx_REG (DImode, regno + 2);
5075 ops[2] = gen_rtx_REG (DImode, regno + 4);
5076 ops[3] = operands[1];
5077 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, %3", ops);
5081 return "vld1.<V_sz_elem>\t%h0, %A1";
5083 [(set (attr "neon_type")
5084 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5085 (const_string "neon_vld3_vld4_all_lanes")
5086 (const_string "neon_vld1_1_2_regs")))])
5088 (define_expand "vec_store_lanesei<mode>"
5089 [(set (match_operand:EI 0 "neon_struct_operand")
5090 (unspec:EI [(match_operand:EI 1 "s_register_operand")
5091 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5095 (define_insn "neon_vst3<mode>"
5096 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5097 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
5098 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5102 if (<V_sz_elem> == 64)
5103 return "vst1.64\t%h1, %A0";
5105 return "vst3.<V_sz_elem>\t%h1, %A0";
5107 [(set (attr "neon_type")
5108 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5109 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5110 (const_string "neon_vst2_4_regs_vst3_vst4")))])
5112 (define_expand "vec_store_lanesci<mode>"
5113 [(match_operand:CI 0 "neon_struct_operand")
5114 (match_operand:CI 1 "s_register_operand")
5115 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5118 emit_insn (gen_neon_vst3<mode> (operands[0], operands[1]));
5122 (define_expand "neon_vst3<mode>"
5123 [(match_operand:CI 0 "neon_struct_operand")
5124 (match_operand:CI 1 "s_register_operand")
5125 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5130 mem = adjust_address (operands[0], EImode, 0);
5131 emit_insn (gen_neon_vst3qa<mode> (mem, operands[1]));
5132 mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
5133 emit_insn (gen_neon_vst3qb<mode> (mem, operands[1]));
5137 (define_insn "neon_vst3qa<mode>"
5138 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5139 (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5140 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5144 int regno = REGNO (operands[1]);
5146 ops[0] = operands[0];
5147 ops[1] = gen_rtx_REG (DImode, regno);
5148 ops[2] = gen_rtx_REG (DImode, regno + 4);
5149 ops[3] = gen_rtx_REG (DImode, regno + 8);
5150 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5153 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5156 (define_insn "neon_vst3qb<mode>"
5157 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5158 (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5159 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5163 int regno = REGNO (operands[1]);
5165 ops[0] = operands[0];
5166 ops[1] = gen_rtx_REG (DImode, regno + 2);
5167 ops[2] = gen_rtx_REG (DImode, regno + 6);
5168 ops[3] = gen_rtx_REG (DImode, regno + 10);
5169 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5172 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5175 (define_insn "neon_vst3_lane<mode>"
5176 [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5177 (unspec:<V_three_elem>
5178 [(match_operand:EI 1 "s_register_operand" "w")
5179 (match_operand:SI 2 "immediate_operand" "i")
5180 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5184 HOST_WIDE_INT lane = INTVAL (operands[2]);
5185 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5186 int regno = REGNO (operands[1]);
5188 if (lane < 0 || lane >= max)
5189 error ("lane out of range");
5190 ops[0] = operands[0];
5191 ops[1] = gen_rtx_REG (DImode, regno);
5192 ops[2] = gen_rtx_REG (DImode, regno + 2);
5193 ops[3] = gen_rtx_REG (DImode, regno + 4);
5194 ops[4] = operands[2];
5195 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5199 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5202 (define_insn "neon_vst3_lane<mode>"
5203 [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5204 (unspec:<V_three_elem>
5205 [(match_operand:CI 1 "s_register_operand" "w")
5206 (match_operand:SI 2 "immediate_operand" "i")
5207 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5211 HOST_WIDE_INT lane = INTVAL (operands[2]);
5212 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5213 int regno = REGNO (operands[1]);
5215 if (lane < 0 || lane >= max)
5216 error ("lane out of range");
5217 else if (lane >= max / 2)
5222 ops[0] = operands[0];
5223 ops[1] = gen_rtx_REG (DImode, regno);
5224 ops[2] = gen_rtx_REG (DImode, regno + 4);
5225 ops[3] = gen_rtx_REG (DImode, regno + 8);
5226 ops[4] = GEN_INT (lane);
5227 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5231 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
5233 (define_expand "vec_load_lanesoi<mode>"
5234 [(set (match_operand:OI 0 "s_register_operand")
5235 (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
5236 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5240 (define_insn "neon_vld4<mode>"
5241 [(set (match_operand:OI 0 "s_register_operand" "=w")
5242 (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
5243 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5247 if (<V_sz_elem> == 64)
5248 return "vld1.64\t%h0, %A1";
5250 return "vld4.<V_sz_elem>\t%h0, %A1";
5252 [(set (attr "neon_type")
5253 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5254 (const_string "neon_vld1_1_2_regs")
5255 (const_string "neon_vld3_vld4")))]
5258 (define_expand "vec_load_lanesxi<mode>"
5259 [(match_operand:XI 0 "s_register_operand")
5260 (match_operand:XI 1 "neon_struct_operand")
5261 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5264 emit_insn (gen_neon_vld4<mode> (operands[0], operands[1]));
5268 (define_expand "neon_vld4<mode>"
5269 [(match_operand:XI 0 "s_register_operand")
5270 (match_operand:XI 1 "neon_struct_operand")
5271 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5276 mem = adjust_address (operands[1], OImode, 0);
5277 emit_insn (gen_neon_vld4qa<mode> (operands[0], mem));
5278 mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5279 emit_insn (gen_neon_vld4qb<mode> (operands[0], mem, operands[0]));
5283 (define_insn "neon_vld4qa<mode>"
5284 [(set (match_operand:XI 0 "s_register_operand" "=w")
5285 (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5286 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5290 int regno = REGNO (operands[0]);
5292 ops[0] = gen_rtx_REG (DImode, regno);
5293 ops[1] = gen_rtx_REG (DImode, regno + 4);
5294 ops[2] = gen_rtx_REG (DImode, regno + 8);
5295 ops[3] = gen_rtx_REG (DImode, regno + 12);
5296 ops[4] = operands[1];
5297 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5300 [(set_attr "neon_type" "neon_vld3_vld4")]
5303 (define_insn "neon_vld4qb<mode>"
5304 [(set (match_operand:XI 0 "s_register_operand" "=w")
5305 (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5306 (match_operand:XI 2 "s_register_operand" "0")
5307 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5311 int regno = REGNO (operands[0]);
5313 ops[0] = gen_rtx_REG (DImode, regno + 2);
5314 ops[1] = gen_rtx_REG (DImode, regno + 6);
5315 ops[2] = gen_rtx_REG (DImode, regno + 10);
5316 ops[3] = gen_rtx_REG (DImode, regno + 14);
5317 ops[4] = operands[1];
5318 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5321 [(set_attr "neon_type" "neon_vld3_vld4")]
5324 (define_insn "neon_vld4_lane<mode>"
5325 [(set (match_operand:OI 0 "s_register_operand" "=w")
5326 (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5327 (match_operand:OI 2 "s_register_operand" "0")
5328 (match_operand:SI 3 "immediate_operand" "i")
5329 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5333 HOST_WIDE_INT lane = INTVAL (operands[3]);
5334 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5335 int regno = REGNO (operands[0]);
5337 if (lane < 0 || lane >= max)
5338 error ("lane out of range");
5339 ops[0] = gen_rtx_REG (DImode, regno);
5340 ops[1] = gen_rtx_REG (DImode, regno + 2);
5341 ops[2] = gen_rtx_REG (DImode, regno + 4);
5342 ops[3] = gen_rtx_REG (DImode, regno + 6);
5343 ops[4] = operands[1];
5344 ops[5] = operands[3];
5345 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5349 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5352 (define_insn "neon_vld4_lane<mode>"
5353 [(set (match_operand:XI 0 "s_register_operand" "=w")
5354 (unspec:XI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5355 (match_operand:XI 2 "s_register_operand" "0")
5356 (match_operand:SI 3 "immediate_operand" "i")
5357 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5361 HOST_WIDE_INT lane = INTVAL (operands[3]);
5362 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5363 int regno = REGNO (operands[0]);
5365 if (lane < 0 || lane >= max)
5366 error ("lane out of range");
5367 else if (lane >= max / 2)
5372 ops[0] = gen_rtx_REG (DImode, regno);
5373 ops[1] = gen_rtx_REG (DImode, regno + 4);
5374 ops[2] = gen_rtx_REG (DImode, regno + 8);
5375 ops[3] = gen_rtx_REG (DImode, regno + 12);
5376 ops[4] = operands[1];
5377 ops[5] = GEN_INT (lane);
5378 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5382 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5385 (define_insn "neon_vld4_dup<mode>"
5386 [(set (match_operand:OI 0 "s_register_operand" "=w")
5387 (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5388 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5392 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5394 int regno = REGNO (operands[0]);
5396 ops[0] = gen_rtx_REG (DImode, regno);
5397 ops[1] = gen_rtx_REG (DImode, regno + 2);
5398 ops[2] = gen_rtx_REG (DImode, regno + 4);
5399 ops[3] = gen_rtx_REG (DImode, regno + 6);
5400 ops[4] = operands[1];
5401 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, %A4",
5406 return "vld1.<V_sz_elem>\t%h0, %A1";
5408 [(set (attr "neon_type")
5409 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5410 (const_string "neon_vld3_vld4_all_lanes")
5411 (const_string "neon_vld1_1_2_regs")))]
5414 (define_expand "vec_store_lanesoi<mode>"
5415 [(set (match_operand:OI 0 "neon_struct_operand")
5416 (unspec:OI [(match_operand:OI 1 "s_register_operand")
5417 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5421 (define_insn "neon_vst4<mode>"
5422 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5423 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
5424 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5428 if (<V_sz_elem> == 64)
5429 return "vst1.64\t%h1, %A0";
5431 return "vst4.<V_sz_elem>\t%h1, %A0";
5433 [(set (attr "neon_type")
5434 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5435 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5436 (const_string "neon_vst2_4_regs_vst3_vst4")))]
5439 (define_expand "vec_store_lanesxi<mode>"
5440 [(match_operand:XI 0 "neon_struct_operand")
5441 (match_operand:XI 1 "s_register_operand")
5442 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5445 emit_insn (gen_neon_vst4<mode> (operands[0], operands[1]));
5449 (define_expand "neon_vst4<mode>"
5450 [(match_operand:XI 0 "neon_struct_operand")
5451 (match_operand:XI 1 "s_register_operand")
5452 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5457 mem = adjust_address (operands[0], OImode, 0);
5458 emit_insn (gen_neon_vst4qa<mode> (mem, operands[1]));
5459 mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5460 emit_insn (gen_neon_vst4qb<mode> (mem, operands[1]));
5464 (define_insn "neon_vst4qa<mode>"
5465 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5466 (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5467 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5471 int regno = REGNO (operands[1]);
5473 ops[0] = operands[0];
5474 ops[1] = gen_rtx_REG (DImode, regno);
5475 ops[2] = gen_rtx_REG (DImode, regno + 4);
5476 ops[3] = gen_rtx_REG (DImode, regno + 8);
5477 ops[4] = gen_rtx_REG (DImode, regno + 12);
5478 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5481 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5484 (define_insn "neon_vst4qb<mode>"
5485 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5486 (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5487 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5491 int regno = REGNO (operands[1]);
5493 ops[0] = operands[0];
5494 ops[1] = gen_rtx_REG (DImode, regno + 2);
5495 ops[2] = gen_rtx_REG (DImode, regno + 6);
5496 ops[3] = gen_rtx_REG (DImode, regno + 10);
5497 ops[4] = gen_rtx_REG (DImode, regno + 14);
5498 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5501 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5504 (define_insn "neon_vst4_lane<mode>"
5505 [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5506 (unspec:<V_four_elem>
5507 [(match_operand:OI 1 "s_register_operand" "w")
5508 (match_operand:SI 2 "immediate_operand" "i")
5509 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5513 HOST_WIDE_INT lane = INTVAL (operands[2]);
5514 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5515 int regno = REGNO (operands[1]);
5517 if (lane < 0 || lane >= max)
5518 error ("lane out of range");
5519 ops[0] = operands[0];
5520 ops[1] = gen_rtx_REG (DImode, regno);
5521 ops[2] = gen_rtx_REG (DImode, regno + 2);
5522 ops[3] = gen_rtx_REG (DImode, regno + 4);
5523 ops[4] = gen_rtx_REG (DImode, regno + 6);
5524 ops[5] = operands[2];
5525 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5529 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5532 (define_insn "neon_vst4_lane<mode>"
5533 [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5534 (unspec:<V_four_elem>
5535 [(match_operand:XI 1 "s_register_operand" "w")
5536 (match_operand:SI 2 "immediate_operand" "i")
5537 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5541 HOST_WIDE_INT lane = INTVAL (operands[2]);
5542 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5543 int regno = REGNO (operands[1]);
5545 if (lane < 0 || lane >= max)
5546 error ("lane out of range");
5547 else if (lane >= max / 2)
5552 ops[0] = operands[0];
5553 ops[1] = gen_rtx_REG (DImode, regno);
5554 ops[2] = gen_rtx_REG (DImode, regno + 4);
5555 ops[3] = gen_rtx_REG (DImode, regno + 8);
5556 ops[4] = gen_rtx_REG (DImode, regno + 12);
5557 ops[5] = GEN_INT (lane);
5558 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5562 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5565 (define_expand "neon_vand<mode>"
5566 [(match_operand:VDQX 0 "s_register_operand" "")
5567 (match_operand:VDQX 1 "s_register_operand" "")
5568 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5569 (match_operand:SI 3 "immediate_operand" "")]
5572 emit_insn (gen_and<mode>3 (operands[0], operands[1], operands[2]));
5576 (define_expand "neon_vorr<mode>"
5577 [(match_operand:VDQX 0 "s_register_operand" "")
5578 (match_operand:VDQX 1 "s_register_operand" "")
5579 (match_operand:VDQX 2 "neon_logic_op2" "")
5580 (match_operand:SI 3 "immediate_operand" "")]
5583 emit_insn (gen_ior<mode>3 (operands[0], operands[1], operands[2]));
5587 (define_expand "neon_veor<mode>"
5588 [(match_operand:VDQX 0 "s_register_operand" "")
5589 (match_operand:VDQX 1 "s_register_operand" "")
5590 (match_operand:VDQX 2 "s_register_operand" "")
5591 (match_operand:SI 3 "immediate_operand" "")]
5594 emit_insn (gen_xor<mode>3 (operands[0], operands[1], operands[2]));
5598 (define_expand "neon_vbic<mode>"
5599 [(match_operand:VDQX 0 "s_register_operand" "")
5600 (match_operand:VDQX 1 "s_register_operand" "")
5601 (match_operand:VDQX 2 "neon_logic_op2" "")
5602 (match_operand:SI 3 "immediate_operand" "")]
5605 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5609 (define_expand "neon_vorn<mode>"
5610 [(match_operand:VDQX 0 "s_register_operand" "")
5611 (match_operand:VDQX 1 "s_register_operand" "")
5612 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5613 (match_operand:SI 3 "immediate_operand" "")]
5616 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));
5620 (define_insn "neon_vec_unpack<US>_lo_<mode>"
5621 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5622 (SE:<V_unpack> (vec_select:<V_HALF>
5623 (match_operand:VU 1 "register_operand" "w")
5624 (match_operand:VU 2 "vect_par_constant_low" ""))))]
5625 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5626 "vmovl.<US><V_sz_elem> %q0, %e1"
5627 [(set_attr "neon_type" "neon_shift_1")]
5630 (define_insn "neon_vec_unpack<US>_hi_<mode>"
5631 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5632 (SE:<V_unpack> (vec_select:<V_HALF>
5633 (match_operand:VU 1 "register_operand" "w")
5634 (match_operand:VU 2 "vect_par_constant_high" ""))))]
5635 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5636 "vmovl.<US><V_sz_elem> %q0, %f1"
5637 [(set_attr "neon_type" "neon_shift_1")]
5640 (define_expand "vec_unpack<US>_hi_<mode>"
5641 [(match_operand:<V_unpack> 0 "register_operand" "")
5642 (SE:<V_unpack> (match_operand:VU 1 "register_operand"))]
5643 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5645 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5648 for (i = 0; i < (<V_mode_nunits>/2); i++)
5649 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
5651 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5652 emit_insn (gen_neon_vec_unpack<US>_hi_<mode> (operands[0],
5659 (define_expand "vec_unpack<US>_lo_<mode>"
5660 [(match_operand:<V_unpack> 0 "register_operand" "")
5661 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))]
5662 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5664 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5667 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5668 RTVEC_ELT (v, i) = GEN_INT (i);
5669 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5670 emit_insn (gen_neon_vec_unpack<US>_lo_<mode> (operands[0],
5677 (define_insn "neon_vec_<US>mult_lo_<mode>"
5678 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5679 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5680 (match_operand:VU 1 "register_operand" "w")
5681 (match_operand:VU 2 "vect_par_constant_low" "")))
5682 (SE:<V_unpack> (vec_select:<V_HALF>
5683 (match_operand:VU 3 "register_operand" "w")
5685 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5686 "vmull.<US><V_sz_elem> %q0, %e1, %e3"
5687 [(set_attr "neon_type" "neon_shift_1")]
5690 (define_expand "vec_widen_<US>mult_lo_<mode>"
5691 [(match_operand:<V_unpack> 0 "register_operand" "")
5692 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5693 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5694 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5696 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5699 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5700 RTVEC_ELT (v, i) = GEN_INT (i);
5701 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5703 emit_insn (gen_neon_vec_<US>mult_lo_<mode> (operands[0],
5711 (define_insn "neon_vec_<US>mult_hi_<mode>"
5712 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5713 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5714 (match_operand:VU 1 "register_operand" "w")
5715 (match_operand:VU 2 "vect_par_constant_high" "")))
5716 (SE:<V_unpack> (vec_select:<V_HALF>
5717 (match_operand:VU 3 "register_operand" "w")
5719 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5720 "vmull.<US><V_sz_elem> %q0, %f1, %f3"
5721 [(set_attr "neon_type" "neon_shift_1")]
5724 (define_expand "vec_widen_<US>mult_hi_<mode>"
5725 [(match_operand:<V_unpack> 0 "register_operand" "")
5726 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5727 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5728 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5730 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5733 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5734 RTVEC_ELT (v, i) = GEN_INT (<V_mode_nunits>/2 + i);
5735 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5737 emit_insn (gen_neon_vec_<US>mult_hi_<mode> (operands[0],
5746 (define_insn "neon_vec_<US>shiftl_<mode>"
5747 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5748 (SE:<V_widen> (ashift:VW (match_operand:VW 1 "register_operand" "w")
5749 (match_operand:<V_innermode> 2 "const_neon_scalar_shift_amount_operand" ""))))]
5752 return "vshll.<US><V_sz_elem> %q0, %P1, %2";
5754 [(set_attr "neon_type" "neon_shift_1")]
5757 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5758 [(match_operand:<V_unpack> 0 "register_operand" "")
5759 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5760 (match_operand:SI 2 "immediate_operand" "i")]
5761 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5763 emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5764 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode, 0),
5770 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5771 [(match_operand:<V_unpack> 0 "register_operand" "")
5772 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5773 (match_operand:SI 2 "immediate_operand" "i")]
5774 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5776 emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5777 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
5778 GET_MODE_SIZE (<V_HALF>mode)),
5784 ;; Vectorize for non-neon-quad case
5785 (define_insn "neon_unpack<US>_<mode>"
5786 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5787 (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
5789 "vmovl.<US><V_sz_elem> %q0, %P1"
5790 [(set_attr "neon_type" "neon_shift_1")]
5793 (define_expand "vec_unpack<US>_lo_<mode>"
5794 [(match_operand:<V_double_width> 0 "register_operand" "")
5795 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5798 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5799 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5800 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5806 (define_expand "vec_unpack<US>_hi_<mode>"
5807 [(match_operand:<V_double_width> 0 "register_operand" "")
5808 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5811 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5812 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5813 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5819 (define_insn "neon_vec_<US>mult_<mode>"
5820 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5821 (mult:<V_widen> (SE:<V_widen>
5822 (match_operand:VDI 1 "register_operand" "w"))
5824 (match_operand:VDI 2 "register_operand" "w"))))]
5826 "vmull.<US><V_sz_elem> %q0, %P1, %P2"
5827 [(set_attr "neon_type" "neon_shift_1")]
5830 (define_expand "vec_widen_<US>mult_hi_<mode>"
5831 [(match_operand:<V_double_width> 0 "register_operand" "")
5832 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5833 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5836 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5837 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5838 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5845 (define_expand "vec_widen_<US>mult_lo_<mode>"
5846 [(match_operand:<V_double_width> 0 "register_operand" "")
5847 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5848 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5851 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5852 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5853 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5860 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5861 [(match_operand:<V_double_width> 0 "register_operand" "")
5862 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5863 (match_operand:SI 2 "immediate_operand" "i")]
5866 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5867 emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5868 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5874 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5875 [(match_operand:<V_double_width> 0 "register_operand" "")
5876 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5877 (match_operand:SI 2 "immediate_operand" "i")]
5880 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5881 emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5882 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5888 ; FIXME: These instruction patterns can't be used safely in big-endian mode
5889 ; because the ordering of vector elements in Q registers is different from what
5890 ; the semantics of the instructions require.
5892 (define_insn "vec_pack_trunc_<mode>"
5893 [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w")
5894 (vec_concat:<V_narrow_pack>
5895 (truncate:<V_narrow>
5896 (match_operand:VN 1 "register_operand" "w"))
5897 (truncate:<V_narrow>
5898 (match_operand:VN 2 "register_operand" "w"))))]
5899 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5900 "vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2"
5901 [(set_attr "neon_type" "neon_shift_1")
5902 (set_attr "length" "8")]
5905 ;; For the non-quad case.
5906 (define_insn "neon_vec_pack_trunc_<mode>"
5907 [(set (match_operand:<V_narrow> 0 "register_operand" "=w")
5908 (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))]
5909 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5910 "vmovn.i<V_sz_elem>\t%P0, %q1"
5911 [(set_attr "neon_type" "neon_shift_1")]
5914 (define_expand "vec_pack_trunc_<mode>"
5915 [(match_operand:<V_narrow_pack> 0 "register_operand" "")
5916 (match_operand:VSHFT 1 "register_operand" "")
5917 (match_operand:VSHFT 2 "register_operand")]
5918 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5920 rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode);
5922 emit_insn (gen_move_lo_quad_<V_double> (tempreg, operands[1]));
5923 emit_insn (gen_move_hi_quad_<V_double> (tempreg, operands[2]));
5924 emit_insn (gen_neon_vec_pack_trunc_<V_double> (operands[0], tempreg));
5928 (define_insn "neon_vabd<mode>_2"
5929 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5930 (abs:VDQ (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
5931 (match_operand:VDQ 2 "s_register_operand" "w"))))]
5932 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5933 "vabd.<V_s_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
5934 [(set (attr "neon_type")
5935 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
5936 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
5937 (const_string "neon_fp_vadd_ddd_vabs_dd")
5938 (const_string "neon_fp_vadd_qqq_vabs_qq"))
5939 (const_string "neon_int_5")))]
5942 (define_insn "neon_vabd<mode>_3"
5943 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5944 (abs:VDQ (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
5945 (match_operand:VDQ 2 "s_register_operand" "w")]
5947 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5948 "vabd.<V_if_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
5949 [(set (attr "neon_type")
5950 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
5951 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
5952 (const_string "neon_fp_vadd_ddd_vabs_dd")
5953 (const_string "neon_fp_vadd_qqq_vabs_qq"))
5954 (const_string "neon_int_5")))]
5957 ;; Copy from core-to-neon regs, then extend, not vice-versa
5960 [(set (match_operand:DI 0 "s_register_operand" "")
5961 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
5962 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
5963 [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
5964 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 32)))]
5966 operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
5970 [(set (match_operand:DI 0 "s_register_operand" "")
5971 (sign_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
5972 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
5973 [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
5974 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
5976 operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
5980 [(set (match_operand:DI 0 "s_register_operand" "")
5981 (sign_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
5982 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
5983 [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
5984 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
5986 operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));
5990 [(set (match_operand:DI 0 "s_register_operand" "")
5991 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
5992 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
5993 [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
5994 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))]
5996 operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
6000 [(set (match_operand:DI 0 "s_register_operand" "")
6001 (zero_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
6002 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6003 [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
6004 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
6006 operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
6010 [(set (match_operand:DI 0 "s_register_operand" "")
6011 (zero_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
6012 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6013 [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
6014 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
6016 operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));